1 /*****************************************************************************
2 * audio_output.c : audio output thread
3 *****************************************************************************
4 * Copyright (C) 1999, 2000 VideoLAN
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
21 *****************************************************************************/
25 * - Passer un certain nombre de "fonctions" (genre add_samples) en macro ou
27 * - Faire les optimisations dans les fonctions threads :
28 * = Stocker les "petits calculs" dans des variables au lieu de les refaire
30 * = Utiliser des tables pour les gros calculs
31 * - Faire une structure différente pour intf/adec fifo
35 /*****************************************************************************
37 *****************************************************************************/
40 #include <unistd.h> /* getpid() */
42 #include <stdio.h> /* "intf_msg.h" */
43 #include <stdlib.h> /* calloc(), malloc(), free() */
48 #include "mtime.h" /* mtime_t, mdate(), msleep() */
51 #include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
53 #include "audio_output.h"
56 /*****************************************************************************
58 *****************************************************************************/
60 static int aout_SpawnThread( aout_thread_t * p_aout );
62 /* Creating as much aout_Thread functions as configurations is one solution,
63 * examining the different cases in the Thread loop of an unique function is
64 * another. I chose the first solution. */
65 void aout_Thread_S8_Mono ( aout_thread_t * p_aout );
66 void aout_Thread_U8_Mono ( aout_thread_t * p_aout );
67 void aout_Thread_S16_Mono ( aout_thread_t * p_aout );
68 void aout_Thread_U16_Mono ( aout_thread_t * p_aout );
69 void aout_Thread_S8_Stereo ( aout_thread_t * p_aout );
70 void aout_Thread_U8_Stereo ( aout_thread_t * p_aout );
71 void aout_Thread_S16_Stereo ( aout_thread_t * p_aout );
72 void aout_Thread_U16_Stereo ( aout_thread_t * p_aout );
74 static __inline__ void InitializeIncrement( aout_increment_t * p_increment, long l_numerator, long l_denominator );
75 static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo, mtime_t aout_date );
77 /*****************************************************************************
79 *****************************************************************************/
80 static __inline__ void InitializeIncrement( aout_increment_t * p_increment, long l_numerator, long l_denominator )
82 p_increment->l_remainder = -l_denominator;
84 p_increment->l_euclidean_integer = 0;
85 while ( l_numerator >= l_denominator )
87 p_increment->l_euclidean_integer++;
88 l_numerator -= l_denominator;
91 p_increment->l_euclidean_remainder = l_numerator;
93 p_increment->l_euclidean_denominator = l_denominator;
96 /*****************************************************************************
97 * aout_CreateThread: initialize audio thread
98 *****************************************************************************/
99 aout_thread_t *aout_CreateThread( int *pi_status )
101 aout_thread_t * p_aout; /* thread descriptor */
102 typedef void ( aout_getplugin_t ) ( aout_thread_t * p_aout );
104 int i_best_index = 0, i_best_score = 0;
106 int i_status; /* thread status */
109 /* Allocate descriptor */
110 p_aout = (aout_thread_t *) malloc( sizeof(aout_thread_t) );
116 /* Get a suitable audio plugin */
117 for( i_index = 0 ; i_index < p_main->p_bank->i_plugin_count ; i_index++ )
119 /* If there's a plugin in p_info ... */
120 if( p_main->p_bank->p_info[ i_index ] != NULL )
122 /* ... and if this plugin provides the functions we want ... */
123 if( p_main->p_bank->p_info[ i_index ]->aout_GetPlugin != NULL )
125 /* ... and if this plugin has a good score ... */
126 if( p_main->p_bank->p_info[ i_index ]->i_score > i_best_score )
128 /* ... then take it */
129 i_best_score = p_main->p_bank->p_info[ i_index ]->i_score;
130 i_best_index = i_index;
136 if( i_best_score == 0 )
142 /* Get the plugin functions */
143 ( (aout_getplugin_t *)
144 p_main->p_bank->p_info[ i_best_index ]->aout_GetPlugin )( p_aout );
147 * Initialize audio device
149 if ( p_aout->p_sys_open( p_aout ) )
155 p_aout->b_stereo = ( p_aout->i_channels == 2 ) ? 1 : 0; /* FIXME: only works
156 for i_channels == 1 or 2 ??*/
158 if ( p_aout->p_sys_reset( p_aout ) )
160 p_aout->p_sys_close( p_aout );
164 if ( p_aout->p_sys_setformat( p_aout ) )
166 p_aout->p_sys_close( p_aout );
170 if ( p_aout->p_sys_setchannels( p_aout ) )
172 p_aout->p_sys_close( p_aout );
176 if ( p_aout->p_sys_setrate( p_aout ) )
178 p_aout->p_sys_close( p_aout );
183 /* Initialize the vomue level */
186 /* FIXME: maybe it would be cleaner to change SpawnThread prototype
187 * see vout to handle status correctly ?? however, it is not critical since
188 * this thread is only called in main and all calls are blocking */
189 if( aout_SpawnThread( p_aout ) )
191 p_aout->p_sys_close( p_aout );
199 /*****************************************************************************
201 *****************************************************************************/
202 static int aout_SpawnThread( aout_thread_t * p_aout )
206 void * aout_thread = NULL;
208 intf_DbgMsg("aout debug: spawning audio output thread (%p)\n", p_aout);
210 /* We want the audio output thread to live */
212 p_aout->b_active = 1;
214 /* Initialize the fifos lock */
215 vlc_mutex_init( &p_aout->fifos_lock );
216 /* Initialize audio fifos : set all fifos as empty and initialize locks */
217 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
219 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
220 vlc_mutex_init( &p_aout->fifo[i_fifo].data_lock );
221 vlc_cond_init( &p_aout->fifo[i_fifo].data_wait );
224 /* Compute the size (in audio units) of the audio output buffer. Although
225 * AOUT_BUFFER_DURATION is given in microseconds, the output rate is given
226 * in Hz, that's why we need to divide by 10^6 microseconds (1 second) */
227 p_aout->l_units = (long)( ((s64)p_aout->l_rate * AOUT_BUFFER_DURATION) / 1000000 );
228 p_aout->l_msleep = (long)( ((s64)p_aout->l_units * 1000000) / (s64)p_aout->l_rate );
230 /* Make aout_thread point to the right thread function, and compute the
231 * byte size of the audio output buffer */
232 switch ( p_aout->i_channels )
234 /* Audio output is mono */
236 switch ( p_aout->i_format )
239 l_bytes = 1 * sizeof(u8) * p_aout->l_units;
240 aout_thread = (void *)aout_Thread_U8_Mono;
244 l_bytes = 1 * sizeof(s8) * p_aout->l_units;
245 aout_thread = (void *)aout_Thread_S8_Mono;
248 case AOUT_FMT_U16_LE:
249 case AOUT_FMT_U16_BE:
250 l_bytes = 1 * sizeof(u16) * p_aout->l_units;
251 aout_thread = (void *)aout_Thread_U16_Mono;
254 case AOUT_FMT_S16_LE:
255 case AOUT_FMT_S16_BE:
256 l_bytes = 1 * sizeof(s16) * p_aout->l_units;
257 aout_thread = (void *)aout_Thread_S16_Mono;
261 intf_ErrMsg( "aout error: unknown audio output format (%i)\n",
267 /* Audio output is stereo */
269 switch ( p_aout->i_format )
272 l_bytes = 2 * sizeof(u8) * p_aout->l_units;
273 aout_thread = (void *)aout_Thread_U8_Stereo;
277 l_bytes = 2 * sizeof(s8) * p_aout->l_units;
278 aout_thread = (void *)aout_Thread_S8_Stereo;
281 case AOUT_FMT_U16_LE:
282 case AOUT_FMT_U16_BE:
283 l_bytes = 2 * sizeof(u16) * p_aout->l_units;
284 aout_thread = (void *)aout_Thread_U16_Stereo;
287 case AOUT_FMT_S16_LE:
288 case AOUT_FMT_S16_BE:
289 l_bytes = 2 * sizeof(s16) * p_aout->l_units;
290 aout_thread = (void *)aout_Thread_S16_Stereo;
294 intf_ErrMsg("aout error: unknown audio output format (%i)\n",
301 intf_ErrMsg("aout error: unknown number of audio channels (%i)\n",
302 p_aout->i_channels );
306 /* Allocate the memory needed by the audio output buffers, and set to zero
307 * the s32 buffer's memory */
308 if ( (p_aout->buffer = malloc(l_bytes)) == NULL )
310 intf_ErrMsg("aout error: not enough memory to create the output buffer\n");
313 if ( (p_aout->s32_buffer = (s32 *)calloc(p_aout->l_units, sizeof(s32) << ( p_aout->b_stereo))) == NULL )
315 intf_ErrMsg("aout error: not enough memory to create the s32 output buffer\n");
316 free( p_aout->buffer );
320 /* Before launching the thread, we try to predict the date of the first
321 * audio unit in the first output buffer */
322 p_aout->date = mdate() - 1000000;
324 /* Launch the thread */
325 if ( vlc_thread_create( &p_aout->thread_id, "audio output", (vlc_thread_func_t)aout_thread, p_aout ) )
327 intf_ErrMsg("aout error: can't spawn audio output thread (%p)\n", p_aout);
328 free( p_aout->buffer );
329 free( p_aout->s32_buffer );
333 intf_DbgMsg("aout debug: audio output thread (%p) spawned\n", p_aout);
337 /*****************************************************************************
339 *****************************************************************************/
340 void aout_DestroyThread( aout_thread_t * p_aout, int *pi_status )
342 /* FIXME: pi_status is not handled correctly: check vout how to do!?? */
344 intf_DbgMsg("aout debug: requesting termination of audio output thread (%p)\n", p_aout);
346 /* Ask thread to kill itself and wait until it's done */
348 vlc_thread_join( p_aout->thread_id ); /* only if pi_status is NULL */
350 /* Free the allocated memory */
351 free( p_aout->buffer );
352 free( p_aout->s32_buffer );
354 /* Free the structure */
355 p_aout->p_sys_close( p_aout );
356 intf_DbgMsg("aout debug: audio device (%s) closed\n", p_aout->psz_device);
362 /*****************************************************************************
364 *****************************************************************************/
365 aout_fifo_t * aout_CreateFifo( aout_thread_t * p_aout, aout_fifo_t * p_fifo )
369 /* Take the fifos lock */
370 vlc_mutex_lock( &p_aout->fifos_lock );
372 /* Looking for a free fifo structure */
373 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
375 if ( p_aout->fifo[i_fifo].i_type == AOUT_EMPTY_FIFO)
380 if ( i_fifo == AOUT_MAX_FIFOS )
382 intf_ErrMsg("aout error: no empty fifo available\n");
383 vlc_mutex_unlock( &p_aout->fifos_lock );
387 /* Initialize the new fifo structure */
388 switch ( p_aout->fifo[i_fifo].i_type = p_fifo->i_type )
390 case AOUT_INTF_MONO_FIFO:
391 case AOUT_INTF_STEREO_FIFO:
392 p_aout->fifo[i_fifo].b_die = 0;
394 p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels;
395 p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo;
396 p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate;
398 p_aout->fifo[i_fifo].buffer = p_fifo->buffer;
400 p_aout->fifo[i_fifo].l_unit = 0;
401 InitializeIncrement( &p_aout->fifo[i_fifo].unit_increment, p_fifo->l_rate, p_aout->l_rate );
402 p_aout->fifo[i_fifo].l_units = p_fifo->l_units;
405 case AOUT_ADEC_MONO_FIFO:
406 case AOUT_ADEC_STEREO_FIFO:
407 p_aout->fifo[i_fifo].b_die = 0;
409 p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels;
410 p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo;
411 p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate;
413 p_aout->fifo[i_fifo].l_frame_size = p_fifo->l_frame_size;
414 /* Allocate the memory needed to store the audio frames. As the
415 * fifo is a rotative fifo, we must be able to find out whether the
416 * fifo is full or empty, that's why we must in fact allocate memory
417 * for (AOUT_FIFO_SIZE+1) audio frames. */
418 if ( (p_aout->fifo[i_fifo].buffer = malloc( sizeof(s16)*(AOUT_FIFO_SIZE+1)*p_fifo->l_frame_size )) == NULL )
420 intf_ErrMsg("aout error: not enough memory to create the frames buffer\n");
421 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
422 vlc_mutex_unlock( &p_aout->fifos_lock );
426 /* Allocate the memory needed to store the dates of the frames */
427 if ( (p_aout->fifo[i_fifo].date = (mtime_t *)malloc( sizeof(mtime_t)*(AOUT_FIFO_SIZE+1) )) == NULL )
429 intf_ErrMsg("aout error: not enough memory to create the dates buffer\n");
430 free( p_aout->fifo[i_fifo].buffer );
431 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
432 vlc_mutex_unlock( &p_aout->fifos_lock );
436 /* Set the fifo's buffer as empty (the first frame that is to be
437 * played is also the first frame that is not to be played) */
438 p_aout->fifo[i_fifo].l_start_frame = 0;
439 /* p_aout->fifo[i_fifo].l_next_frame = 0; */
440 p_aout->fifo[i_fifo].l_end_frame = 0;
442 /* Waiting for the audio decoder to compute enough frames to work
443 * out the fifo's current rate (as soon as the decoder has decoded
444 * enough frames, the members of the fifo structure that are not
445 * initialized now will be calculated) */
446 p_aout->fifo[i_fifo].b_start_frame = 0;
447 p_aout->fifo[i_fifo].b_next_frame = 0;
451 intf_ErrMsg("aout error: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
452 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
453 vlc_mutex_unlock( &p_aout->fifos_lock );
457 /* Release the fifos lock */
458 vlc_mutex_unlock( &p_aout->fifos_lock );
460 /* Return the pointer to the fifo structure */
461 intf_DbgMsg("aout debug: audio output fifo (%p) allocated\n", &p_aout->fifo[i_fifo]);
462 return( &p_aout->fifo[i_fifo] );
465 /*****************************************************************************
467 *****************************************************************************/
468 void aout_DestroyFifo( aout_fifo_t * p_fifo )
470 intf_DbgMsg("aout debug: requesting destruction of audio output fifo (%p)\n", p_fifo);
474 /* Here are the local macros */
476 #define UPDATE_INCREMENT( increment, integer ) \
477 if ( ((increment).l_remainder += (increment).l_euclidean_remainder) >= 0 )\
479 (integer) += (increment).l_euclidean_integer + 1; \
480 (increment).l_remainder -= (increment).l_euclidean_denominator; \
484 (integer) += (increment).l_euclidean_integer; \
487 /* Following functions are local */
489 /*****************************************************************************
491 *****************************************************************************/
492 static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo, mtime_t aout_date )
494 long l_units, l_rate;
496 /* We take the lock */
497 vlc_mutex_lock( &p_fifo->data_lock );
499 /* Are we looking for a dated start frame ? */
500 if ( !p_fifo->b_start_frame )
502 while ( p_fifo->l_start_frame != p_fifo->l_end_frame )
504 if ( p_fifo->date[p_fifo->l_start_frame] != LAST_MDATE )
506 p_fifo->b_start_frame = 1;
507 p_fifo->l_next_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE;
508 p_fifo->l_unit = p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo));
511 p_fifo->l_start_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE;
514 if ( p_fifo->l_start_frame == p_fifo->l_end_frame )
516 vlc_mutex_unlock( &p_fifo->data_lock );
521 /* We are looking for the next dated frame */
522 /* FIXME : is the output fifo full ?? */
523 while ( !p_fifo->b_next_frame )
525 while ( p_fifo->l_next_frame != p_fifo->l_end_frame )
527 if ( p_fifo->date[p_fifo->l_next_frame] != LAST_MDATE )
529 p_fifo->b_next_frame = 1;
532 p_fifo->l_next_frame = (p_fifo->l_next_frame + 1) & AOUT_FIFO_SIZE;
535 while ( p_fifo->l_next_frame == p_fifo->l_end_frame )
537 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
540 vlc_mutex_unlock( &p_fifo->data_lock );
546 l_units = ((p_fifo->l_next_frame - p_fifo->l_start_frame) & AOUT_FIFO_SIZE) * (p_fifo->l_frame_size >> (p_fifo->b_stereo));
548 l_rate = p_fifo->l_rate + ((aout_date - p_fifo->date[p_fifo->l_start_frame]) / 256);
549 // intf_DbgMsg( "aout debug: %lli (%li);\n", aout_date - p_fifo->date[p_fifo->l_start_frame], l_rate );
551 InitializeIncrement( &p_fifo->unit_increment, l_rate, p_aout->l_rate );
553 p_fifo->l_units = (((l_units - (p_fifo->l_unit -
554 (p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo)))))
555 * p_aout->l_rate) / l_rate) + 1;
557 /* We release the lock before leaving */
558 vlc_mutex_unlock( &p_fifo->data_lock );
562 void aout_Thread_S8_Mono( aout_thread_t * p_aout )
566 void aout_Thread_S8_Stereo( aout_thread_t * p_aout )
570 void aout_Thread_U8_Mono( aout_thread_t * p_aout )
573 long l_buffer, l_buffer_limit;
574 long l_units, l_bytes;
576 intf_DbgMsg("adec debug: ********aout_Thread_U8_Mono********\n");
577 intf_DbgMsg("adec debug: running audio output thread (%p) (pid == %i)\n", p_aout, getpid());
579 /* As the s32_buffer was created with calloc(), we don't have to set this
580 * memory to zero and we can immediately jump into the thread's loop */
581 while ( !p_aout->b_die )
583 vlc_mutex_lock( &p_aout->fifos_lock );
584 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
586 switch ( p_aout->fifo[i_fifo].i_type )
588 case AOUT_EMPTY_FIFO:
591 case AOUT_INTF_MONO_FIFO:
592 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
595 while ( l_buffer < (p_aout->l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
597 p_aout->s32_buffer[l_buffer++] +=
598 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
599 p_aout->s32_buffer[l_buffer++] +=
600 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
601 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
603 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
608 while ( l_buffer < (p_aout->fifo[i_fifo].l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
610 p_aout->s32_buffer[l_buffer++] +=
611 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
612 p_aout->s32_buffer[l_buffer++] +=
613 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
614 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
616 free( p_aout->fifo[i_fifo].buffer ); /* !! */
617 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
618 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
622 case AOUT_INTF_STEREO_FIFO:
623 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
626 while ( l_buffer < (p_aout->l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
628 p_aout->s32_buffer[l_buffer++] +=
629 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
630 p_aout->s32_buffer[l_buffer++] +=
631 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
632 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
634 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
639 while ( l_buffer < (p_aout->fifo[i_fifo].l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
641 p_aout->s32_buffer[l_buffer++] +=
642 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
643 p_aout->s32_buffer[l_buffer++] +=
644 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
645 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
647 free( p_aout->fifo[i_fifo].buffer ); /* !! */
648 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
649 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
653 case AOUT_ADEC_MONO_FIFO:
654 if ( p_aout->fifo[i_fifo].b_die )
656 free( p_aout->fifo[i_fifo].buffer );
657 free( p_aout->fifo[i_fifo].date );
658 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
659 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
663 l_units = p_aout->l_units;
665 while ( l_units > 0 )
667 if ( !p_aout->fifo[i_fifo].b_next_frame )
669 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
675 if ( p_aout->fifo[i_fifo].l_units > l_units )
677 l_buffer_limit = p_aout->l_units /*<< 1*/; /* p_aout->b_stereo == 1 */
678 while ( l_buffer < l_buffer_limit )
680 p_aout->s32_buffer[l_buffer++] +=
681 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
682 p_aout->s32_buffer[l_buffer++] +=
683 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
685 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
686 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
687 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
689 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
690 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
693 p_aout->fifo[i_fifo].l_units -= l_units;
698 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
699 /* p_aout->b_stereo == 1 */
700 while ( l_buffer < l_buffer_limit )
702 p_aout->s32_buffer[l_buffer++] +=
703 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
704 p_aout->s32_buffer[l_buffer++] +=
705 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
707 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
708 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
709 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
711 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
712 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
715 l_units -= p_aout->fifo[i_fifo].l_units;
717 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
718 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
719 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
720 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
722 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
723 p_aout->fifo[i_fifo].l_next_frame += 1;
724 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
725 p_aout->fifo[i_fifo].b_next_frame = 0;
730 case AOUT_ADEC_STEREO_FIFO:
731 if ( p_aout->fifo[i_fifo].b_die )
733 free( p_aout->fifo[i_fifo].buffer );
734 free( p_aout->fifo[i_fifo].date );
735 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
736 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
740 l_units = p_aout->l_units;
742 while ( l_units > 0 )
744 if ( !p_aout->fifo[i_fifo].b_next_frame )
746 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
754 if ( p_aout->fifo[i_fifo].l_units > l_units )
756 l_buffer_limit = p_aout->l_units /*<< 1*/; /* p_aout->b_stereo == 1 */
757 //intf_DbgMsg( "l_buffer_limit:%d\n",l_buffer_limit );
758 while ( l_buffer < l_buffer_limit )
762 p_aout->s32_buffer[l_buffer++] +=
763 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] );
764 p_aout->s32_buffer[l_buffer++] +=
765 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] );
768 //intf_DbgMsg( "1deb " );
770 p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] ) / 2;
771 p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
773 //intf_DbgMsg( "1fin" );
778 //intf_DbgMsg( "p_aout->s32_buffer[l_buffer] 11 : %x (%d)",p_aout->s32_buffer[l_buffer-1],p_aout->s32_buffer[l_buffer-1] );
779 intf_DbgMsg( "p_aout->fifo %ld\n",COEFF*p_aout->fifo[i_fifo].l_unit );
780 intf_DbgMsg( "%d - p_aout->s32b %ld\n", l_buffer, (s32) ( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] ) );
781 //intf_DbgMsg( "p_aout->s32_buffer[l_buffer] 12 : %x (%d)\n",p_aout->s32_buffer[l_buffer-1],p_aout->s32_buffer[l_buffer-1] );
784 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
785 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
786 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/)) )
788 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
789 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/));
792 p_aout->fifo[i_fifo].l_units -= l_units;
798 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units /*<< 1*/);
799 //intf_DbgMsg( "l_buffer_limit:%d\n",l_buffer_limit );
800 /* p_aout->b_stereo == 1 */
801 while ( l_buffer < l_buffer_limit )
805 p_aout->s32_buffer[l_buffer++] +=
806 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] );
807 p_aout->s32_buffer[l_buffer++] +=
808 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] );
811 //intf_DbgMsg( "2deb " );
813 //intf_DbgMsg( "793 ");
814 // !!!!!! Seg Fault !!!!!!!
815 //intf_DbgMsg( "\n p->aout_buffer : %d\t%d\n",p_aout->s32_buffer[l_buffer],COEFF*p_aout->fifo[i_fifo].l_unit );
816 if( COEFF*p_aout->fifo[i_fifo].l_unit < 60000 )
818 p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] ) / 2;
819 // intf_DbgMsg( "795 ");
820 p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
821 //intf_DbgMsg( "797 ");
824 //intf_DbgMsg( "2fin " );
829 //intf_DbgMsg( "p_aout->s32_buffer[l_buffer] 21 : %x (%d)",p_aout->s32_buffer[l_buffer-1],p_aout->s32_buffer[l_buffer-1] );
830 intf_DbgMsg( "p_aout->fifo %ld\n",COEFF*p_aout->fifo[i_fifo].l_unit );
831 intf_DbgMsg( "%d - p_aout->s32b %ld\n", l_buffer, (s32) ( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] ) );
832 //intf_DbgMsg( "p_aout->s32_buffer[l_buffer] 22 : %x (%d)\n",p_aout->s32_buffer[l_buffer-1],p_aout->s32_buffer[l_buffer-1] );
835 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
836 //intf_DbgMsg( "807 ");
837 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
838 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/)) )
840 //intf_DbgMsg( "811 ");
841 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
842 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/));
845 //intf_DbgMsg( "816 ");
846 l_units -= p_aout->fifo[i_fifo].l_units;
847 //intf_DbgMsg( "818 ");
848 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
849 //intf_DbgMsg( "820 ");
850 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
851 //intf_DbgMsg( "822 ");
852 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
853 //intf_DbgMsg( "824 ");
854 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
855 //intf_DbgMsg( "826 ");
856 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
857 p_aout->fifo[i_fifo].l_next_frame += 1;
858 //intf_DbgMsg( "829 ");
859 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
860 //intf_DbgMsg( "831 ");
861 p_aout->fifo[i_fifo].b_next_frame = 0;
863 //intf_DbgMsg( "837 ");
865 //intf_DbgMsg( "838 ");
866 /* !!!!!!!!!!!!! Seg Fault !!!!!!!!!!!!!!!!! */
868 //intf_DbgMsg( "839 ");
872 //intf_DbgMsg( "841 ");
873 intf_DbgMsg("aout debug: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
874 //intf_DbgMsg( "842 ");
878 //intf_DbgMsg( "843 ");
879 vlc_mutex_unlock( &p_aout->fifos_lock );
880 //intf_DbgMsg( "845 ");
881 l_buffer_limit = p_aout->l_units /*<< 1*/ ; /* p_aout->b_stereo == 1 */
882 //intf_DbgMsg( "\nici commence l'envoi sur sb\n" );
883 for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
885 //intf_DbgMsg( "3deb ");
886 //intf_DbgMsg( "p_aout->s_32_buffer[l_buffer] : %x (%d)\n",p_aout->s32_buffer[l_buffer],p_aout->s32_buffer[l_buffer] );
887 ((u8 *)p_aout->buffer)[l_buffer] = (u8)( (p_aout->s32_buffer[/*2 **/ l_buffer] / 256) + 128 );
888 //intf_DbgMsg( "p_aout->buffer[l_buffer] : %x (%d)\n", ((u8 *)p_aout->buffer)[l_buffer], ((u8 *)p_aout->buffer)[l_buffer] );
889 p_aout->s32_buffer[/*2 **/ l_buffer] = 0;
890 // p_aout->s32_buffer[2 * l_buffer + 1] = 0;
891 //intf_DbgMsg( "3fin ");
893 l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
894 p_aout->date = mdate() + ((((mtime_t)(l_bytes / 2 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 2 */
895 p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
896 if ( l_bytes > (l_buffer_limit * sizeof(u8)) )
898 msleep( p_aout->l_msleep );
902 vlc_mutex_lock( &p_aout->fifos_lock );
903 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
905 switch ( p_aout->fifo[i_fifo].i_type )
907 case AOUT_EMPTY_FIFO:
910 case AOUT_INTF_MONO_FIFO:
911 case AOUT_INTF_STEREO_FIFO:
912 free( p_aout->fifo[i_fifo].buffer ); /* !! */
913 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
914 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
917 case AOUT_ADEC_MONO_FIFO:
918 case AOUT_ADEC_STEREO_FIFO:
919 free( p_aout->fifo[i_fifo].buffer );
920 free( p_aout->fifo[i_fifo].date );
921 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
922 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
929 vlc_mutex_unlock( &p_aout->fifos_lock );
933 void aout_Thread_U8_Stereo( aout_thread_t * p_aout )
936 long l_buffer, l_buffer_limit;
937 long l_units, l_bytes;
939 intf_DbgMsg("adec debug: ********aout_Thread_U8_Stereo********\n");
940 intf_DbgMsg("adec debug: running audio output thread (%p) (pid == %i)\n", p_aout, getpid());
942 /* As the s32_buffer was created with calloc(), we don't have to set this
943 * memory to zero and we can immediately jump into the thread's loop */
944 while ( !p_aout->b_die )
946 vlc_mutex_lock( &p_aout->fifos_lock );
947 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
949 switch ( p_aout->fifo[i_fifo].i_type )
951 case AOUT_EMPTY_FIFO:
954 case AOUT_INTF_MONO_FIFO:
955 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
958 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
960 p_aout->s32_buffer[l_buffer++] +=
961 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
962 p_aout->s32_buffer[l_buffer++] +=
963 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
964 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
966 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
971 while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
973 p_aout->s32_buffer[l_buffer++] +=
974 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
975 p_aout->s32_buffer[l_buffer++] +=
976 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
977 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
979 free( p_aout->fifo[i_fifo].buffer ); /* !! */
980 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
981 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
985 case AOUT_INTF_STEREO_FIFO:
986 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
989 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
991 p_aout->s32_buffer[l_buffer++] +=
992 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
993 p_aout->s32_buffer[l_buffer++] +=
994 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
995 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
997 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
1002 while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
1004 p_aout->s32_buffer[l_buffer++] +=
1005 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1006 p_aout->s32_buffer[l_buffer++] +=
1007 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1008 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1010 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1011 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1012 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
1016 case AOUT_ADEC_MONO_FIFO:
1017 if ( p_aout->fifo[i_fifo].b_die )
1019 free( p_aout->fifo[i_fifo].buffer );
1020 free( p_aout->fifo[i_fifo].date );
1021 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1022 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1026 l_units = p_aout->l_units;
1028 while ( l_units > 0 )
1030 if ( !p_aout->fifo[i_fifo].b_next_frame )
1032 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1038 if ( p_aout->fifo[i_fifo].l_units > l_units )
1040 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1041 while ( l_buffer < l_buffer_limit )
1043 p_aout->s32_buffer[l_buffer++] +=
1044 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1045 p_aout->s32_buffer[l_buffer++] +=
1046 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1048 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1049 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1050 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1052 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1053 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1056 p_aout->fifo[i_fifo].l_units -= l_units;
1061 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1062 /* p_aout->b_stereo == 1 */
1063 while ( l_buffer < l_buffer_limit )
1065 p_aout->s32_buffer[l_buffer++] +=
1066 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1067 p_aout->s32_buffer[l_buffer++] +=
1068 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1070 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1071 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1072 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1074 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1075 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1078 l_units -= p_aout->fifo[i_fifo].l_units;
1080 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1081 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1082 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1083 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1085 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1086 p_aout->fifo[i_fifo].l_next_frame += 1;
1087 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1088 p_aout->fifo[i_fifo].b_next_frame = 0;
1093 case AOUT_ADEC_STEREO_FIFO:
1094 if ( p_aout->fifo[i_fifo].b_die )
1096 free( p_aout->fifo[i_fifo].buffer );
1097 free( p_aout->fifo[i_fifo].date );
1098 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1099 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1103 l_units = p_aout->l_units;
1105 while ( l_units > 0 )
1107 if ( !p_aout->fifo[i_fifo].b_next_frame )
1109 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1115 if ( p_aout->fifo[i_fifo].l_units > l_units )
1117 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1118 while ( l_buffer < l_buffer_limit )
1120 p_aout->s32_buffer[l_buffer++] +=
1121 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1122 p_aout->s32_buffer[l_buffer++] +=
1123 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1125 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1126 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1127 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1129 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1130 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1133 p_aout->fifo[i_fifo].l_units -= l_units;
1138 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1139 /* p_aout->b_stereo == 1 */
1140 while ( l_buffer < l_buffer_limit )
1142 p_aout->s32_buffer[l_buffer++] +=
1143 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1144 p_aout->s32_buffer[l_buffer++] +=
1145 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1147 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1148 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1149 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1151 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1152 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1155 l_units -= p_aout->fifo[i_fifo].l_units;
1157 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1158 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1159 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1160 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1162 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1163 p_aout->fifo[i_fifo].l_next_frame += 1;
1164 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1165 p_aout->fifo[i_fifo].b_next_frame = 0;
1171 intf_DbgMsg("aout debug: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
1175 vlc_mutex_unlock( &p_aout->fifos_lock );
1177 l_buffer_limit = p_aout->l_units << 1 ; /* p_aout->b_stereo == 1 */
1179 for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
1181 ((u8 *)p_aout->buffer)[l_buffer] = (u8)( ( (p_aout->s32_buffer[l_buffer] / 256) + 128 ) * \
1182 ((float) p_aout->vol / 100 ) );
1183 p_aout->s32_buffer[l_buffer] = 0;
1185 l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
1186 p_aout->date = mdate() + ((((mtime_t)(l_bytes / 2 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 2 */
1187 p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
1188 if ( l_bytes > (l_buffer_limit * sizeof(u8)) )
1190 msleep( p_aout->l_msleep );
1194 vlc_mutex_lock( &p_aout->fifos_lock );
1195 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1197 switch ( p_aout->fifo[i_fifo].i_type )
1199 case AOUT_EMPTY_FIFO:
1202 case AOUT_INTF_MONO_FIFO:
1203 case AOUT_INTF_STEREO_FIFO:
1204 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1205 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1206 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1209 case AOUT_ADEC_MONO_FIFO:
1210 case AOUT_ADEC_STEREO_FIFO:
1211 free( p_aout->fifo[i_fifo].buffer );
1212 free( p_aout->fifo[i_fifo].date );
1213 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1214 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1221 vlc_mutex_unlock( &p_aout->fifos_lock );
1225 void aout_Thread_S16_Mono( aout_thread_t * p_aout )
1229 void aout_Thread_S16_Stereo( aout_thread_t * p_aout )
1232 long l_buffer, l_buffer_limit;
1233 long l_units, l_bytes;
1235 intf_DbgMsg("adec debug: ********aout_Thread_S16_Stereo********\n");
1236 intf_DbgMsg("adec debug: running audio output thread (%p) (pid == %i)\n", p_aout, getpid());
1238 /* As the s32_buffer was created with calloc(), we don't have to set this
1239 * memory to zero and we can immediately jump into the thread's loop */
1240 while ( !p_aout->b_die )
1242 vlc_mutex_lock( &p_aout->fifos_lock );
1243 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1245 switch ( p_aout->fifo[i_fifo].i_type )
1247 case AOUT_EMPTY_FIFO:
1250 case AOUT_INTF_MONO_FIFO:
1251 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
1254 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
1256 p_aout->s32_buffer[l_buffer++] +=
1257 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1258 p_aout->s32_buffer[l_buffer++] +=
1259 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1260 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1262 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
1267 while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
1269 p_aout->s32_buffer[l_buffer++] +=
1270 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1271 p_aout->s32_buffer[l_buffer++] +=
1272 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1273 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1275 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1276 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1277 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
1281 case AOUT_INTF_STEREO_FIFO:
1282 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
1285 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
1287 p_aout->s32_buffer[l_buffer++] +=
1288 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1289 p_aout->s32_buffer[l_buffer++] +=
1290 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1291 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1293 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
1298 while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
1300 p_aout->s32_buffer[l_buffer++] +=
1301 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1302 p_aout->s32_buffer[l_buffer++] +=
1303 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1304 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1306 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1307 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1308 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
1312 case AOUT_ADEC_MONO_FIFO:
1313 if ( p_aout->fifo[i_fifo].b_die )
1315 free( p_aout->fifo[i_fifo].buffer );
1316 free( p_aout->fifo[i_fifo].date );
1317 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1318 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1322 l_units = p_aout->l_units;
1324 while ( l_units > 0 )
1326 if ( !p_aout->fifo[i_fifo].b_next_frame )
1328 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1334 if ( p_aout->fifo[i_fifo].l_units > l_units )
1336 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1337 while ( l_buffer < l_buffer_limit )
1339 p_aout->s32_buffer[l_buffer++] +=
1340 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1341 p_aout->s32_buffer[l_buffer++] +=
1342 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1344 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1345 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1346 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1348 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1349 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1352 p_aout->fifo[i_fifo].l_units -= l_units;
1357 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1358 /* p_aout->b_stereo == 1 */
1359 while ( l_buffer < l_buffer_limit )
1361 p_aout->s32_buffer[l_buffer++] +=
1362 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1363 p_aout->s32_buffer[l_buffer++] +=
1364 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1366 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1367 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1368 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1370 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1371 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1374 l_units -= p_aout->fifo[i_fifo].l_units;
1376 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1377 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1378 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1379 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1381 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1382 p_aout->fifo[i_fifo].l_next_frame += 1;
1383 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1384 p_aout->fifo[i_fifo].b_next_frame = 0;
1389 case AOUT_ADEC_STEREO_FIFO:
1390 if ( p_aout->fifo[i_fifo].b_die )
1392 free( p_aout->fifo[i_fifo].buffer );
1393 free( p_aout->fifo[i_fifo].date );
1394 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1395 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1399 l_units = p_aout->l_units;
1401 while ( l_units > 0 )
1403 if ( !p_aout->fifo[i_fifo].b_next_frame )
1405 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1411 if ( p_aout->fifo[i_fifo].l_units > l_units )
1413 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1414 while ( l_buffer < l_buffer_limit )
1416 p_aout->s32_buffer[l_buffer++] +=
1417 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1418 p_aout->s32_buffer[l_buffer++] +=
1419 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1421 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1422 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1423 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1425 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1426 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1429 p_aout->fifo[i_fifo].l_units -= l_units;
1434 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1435 /* p_aout->b_stereo == 1 */
1436 while ( l_buffer < l_buffer_limit )
1438 p_aout->s32_buffer[l_buffer++] +=
1439 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1440 p_aout->s32_buffer[l_buffer++] +=
1441 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1443 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1444 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1445 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1447 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1448 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1451 l_units -= p_aout->fifo[i_fifo].l_units;
1453 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1454 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1455 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1456 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1458 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1459 p_aout->fifo[i_fifo].l_next_frame += 1;
1460 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1461 p_aout->fifo[i_fifo].b_next_frame = 0;
1467 intf_DbgMsg("aout debug: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
1471 vlc_mutex_unlock( &p_aout->fifos_lock );
1473 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1475 for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
1477 ((s16 *)p_aout->buffer)[l_buffer] = (s16)( ( p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS ) * \
1478 ((float) p_aout->vol / 100 ) ) ;
1479 p_aout->s32_buffer[l_buffer] = 0;
1482 l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
1483 p_aout->date = mdate() + ((((mtime_t)(l_bytes / 4)) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(s16) << (p_aout->b_stereo) == 4 */
1484 p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(s16) );
1485 if ( l_bytes > (l_buffer_limit * sizeof(s16)) )
1487 msleep( p_aout->l_msleep );
1491 vlc_mutex_lock( &p_aout->fifos_lock );
1492 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1494 switch ( p_aout->fifo[i_fifo].i_type )
1496 case AOUT_EMPTY_FIFO:
1499 case AOUT_INTF_MONO_FIFO:
1500 case AOUT_INTF_STEREO_FIFO:
1501 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1502 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1503 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1506 case AOUT_ADEC_MONO_FIFO:
1507 case AOUT_ADEC_STEREO_FIFO:
1508 free( p_aout->fifo[i_fifo].buffer );
1509 free( p_aout->fifo[i_fifo].date );
1510 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1511 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1518 vlc_mutex_unlock( &p_aout->fifos_lock );
1521 void aout_Thread_U16_Mono( aout_thread_t * p_aout )
1525 void aout_Thread_U16_Stereo( aout_thread_t * p_aout )