1 /*****************************************************************************
2 * audio_output.c : audio output thread
4 *****************************************************************************/
8 * - Passer un certain nombre de "fonctions" (genre add_samples) en macro ou
10 * - Faire les optimisations dans les fonctions threads :
11 * = Stocker les "petits calculs" dans des variables au lieu de les refaire
13 * = Utiliser des tables pour les gros calculs
14 * - Faire une structure différente pour intf/adec fifo
18 /*****************************************************************************
20 *****************************************************************************/
23 #include <stdio.h> /* "intf_msg.h" */
24 #include <stdlib.h> /* calloc(), malloc(), free() */
26 #include <dlfcn.h> /* plugins */
30 #include "mtime.h" /* mtime_t, mdate(), msleep() */
31 #include "vlc_thread.h"
33 #include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
35 #include "audio_output.h"
38 /*****************************************************************************
40 *****************************************************************************/
42 static int aout_SpawnThread( aout_thread_t * p_aout );
44 /* Creating as much aout_Thread functions as configurations is one solution,
45 * examining the different cases in the Thread loop of an unique function is
46 * another. I chose the first solution. */
47 void aout_Thread_S8_Mono ( aout_thread_t * p_aout );
48 void aout_Thread_U8_Mono ( aout_thread_t * p_aout );
49 void aout_Thread_S16_Mono ( aout_thread_t * p_aout );
50 void aout_Thread_U16_Mono ( aout_thread_t * p_aout );
51 void aout_Thread_S8_Stereo ( aout_thread_t * p_aout );
52 void aout_Thread_U8_Stereo ( aout_thread_t * p_aout );
53 void aout_Thread_S16_Stereo ( aout_thread_t * p_aout );
54 void aout_Thread_U16_Stereo ( aout_thread_t * p_aout );
56 static __inline__ void InitializeIncrement( aout_increment_t * p_increment, long l_numerator, long l_denominator );
57 static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo, mtime_t aout_date );
59 /*****************************************************************************
60 * aout_CreateThread: initialize audio thread
61 *****************************************************************************/
62 aout_thread_t *aout_CreateThread( int *pi_status )
64 aout_thread_t * p_aout; /* thread descriptor */
68 int i_status; /* thread status */
71 /* Allocate descriptor */
72 p_aout = (aout_thread_t *) malloc( sizeof(aout_thread_t) );
78 /* Initialize method-dependent functions */
79 psz_method = main_GetPszVariable( AOUT_METHOD_VAR, AOUT_DEFAULT_METHOD );
81 psz_plugin = malloc( sizeof("./audio_output/aout_.so") + strlen(psz_method) );
82 sprintf( psz_plugin, "./audio_output/aout_%s.so", psz_method );
84 p_aout->p_aout_plugin = dlopen( psz_plugin, RTLD_NOW | RTLD_GLOBAL );
86 if( p_aout->p_aout_plugin == NULL )
88 intf_ErrMsg( "error: could not open audio plugin %s\n", psz_plugin );
96 p_aout->p_sys_open = dlsym(p_aout->p_aout_plugin, "aout_SysOpen");
97 p_aout->p_sys_reset = dlsym(p_aout->p_aout_plugin, "aout_SysReset");
98 p_aout->p_sys_setformat = dlsym(p_aout->p_aout_plugin, "aout_SysSetFormat");
99 p_aout->p_sys_setchannels = dlsym(p_aout->p_aout_plugin, "aout_SysSetChannels");
100 p_aout->p_sys_setrate = dlsym(p_aout->p_aout_plugin, "aout_SysSetRate");
101 p_aout->p_sys_getbufinfo = dlsym(p_aout->p_aout_plugin, "aout_SysGetBufInfo");
102 p_aout->p_sys_playsamples = dlsym(p_aout->p_aout_plugin, "aout_SysPlaySamples");
103 p_aout->p_sys_close = dlsym(p_aout->p_aout_plugin, "aout_SysClose");
106 * Initialize audio device
108 if ( p_aout->p_sys_open( p_aout ) )
110 dlclose( p_aout->p_aout_plugin );
115 p_aout->b_stereo = ( p_aout->i_channels == 2 ) ? 1 : 0; /* FIXME: only works
116 for i_channels == 1 or 2 ??*/
118 if ( p_aout->p_sys_reset( p_aout ) )
120 p_aout->p_sys_close( p_aout );
121 dlclose( p_aout->p_aout_plugin );
125 if ( p_aout->p_sys_setformat( p_aout ) )
127 p_aout->p_sys_close( p_aout );
128 dlclose( p_aout->p_aout_plugin );
132 if ( p_aout->p_sys_setchannels( p_aout ) )
134 p_aout->p_sys_close( p_aout );
135 dlclose( p_aout->p_aout_plugin );
139 if ( p_aout->p_sys_setrate( p_aout ) )
141 p_aout->p_sys_close( p_aout );
142 dlclose( p_aout->p_aout_plugin );
147 /* FIXME: maybe it would be cleaner to change SpawnThread prototype
148 * see vout to handle status correctly ?? however, it is not critical since
149 * this thread is only called in main and all calls are blocking */
150 if( aout_SpawnThread( p_aout ) )
152 p_aout->p_sys_close( p_aout );
153 dlclose( p_aout->p_aout_plugin );
161 /*****************************************************************************
163 *****************************************************************************/
164 static int aout_SpawnThread( aout_thread_t * p_aout )
168 void * aout_thread = NULL;
170 intf_DbgMsg("aout debug: spawning audio output thread (%p)\n", p_aout);
172 /* We want the audio output thread to live */
175 /* Initialize the fifos lock */
176 vlc_mutex_init( &p_aout->fifos_lock );
177 /* Initialize audio fifos : set all fifos as empty and initialize locks */
178 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
180 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
181 vlc_mutex_init( &p_aout->fifo[i_fifo].data_lock );
182 vlc_cond_init( &p_aout->fifo[i_fifo].data_wait );
185 /* Compute the size (in audio units) of the audio output buffer. Although
186 * AOUT_BUFFER_DURATION is given in microseconds, the output rate is given
187 * in Hz, that's why we need to divide by 10^6 microseconds (1 second) */
188 p_aout->l_units = (long)( ((s64)p_aout->l_rate * AOUT_BUFFER_DURATION) / 1000000 );
189 p_aout->l_msleep = (long)( ((s64)p_aout->l_units * 1000000) / (s64)p_aout->l_rate );
191 /* Make aout_thread point to the right thread function, and compute the
192 * byte size of the audio output buffer */
193 switch ( p_aout->i_channels )
195 /* Audio output is mono */
197 switch ( p_aout->i_format )
200 l_bytes = 1 * sizeof(u8) * p_aout->l_units;
201 aout_thread = (void *)aout_Thread_U8_Mono;
205 l_bytes = 1 * sizeof(s8) * p_aout->l_units;
206 aout_thread = (void *)aout_Thread_S8_Mono;
209 case AOUT_FMT_U16_LE:
210 case AOUT_FMT_U16_BE:
211 l_bytes = 1 * sizeof(u16) * p_aout->l_units;
212 aout_thread = (void *)aout_Thread_U16_Mono;
215 case AOUT_FMT_S16_LE:
216 case AOUT_FMT_S16_BE:
217 l_bytes = 1 * sizeof(s16) * p_aout->l_units;
218 aout_thread = (void *)aout_Thread_S16_Mono;
222 intf_ErrMsg( "aout error: unknown audio output format (%i)\n",
228 /* Audio output is stereo */
230 switch ( p_aout->i_format )
233 l_bytes = 2 * sizeof(u8) * p_aout->l_units;
234 aout_thread = (void *)aout_Thread_U8_Stereo;
238 l_bytes = 2 * sizeof(s8) * p_aout->l_units;
239 aout_thread = (void *)aout_Thread_S8_Stereo;
242 case AOUT_FMT_U16_LE:
243 case AOUT_FMT_U16_BE:
244 l_bytes = 2 * sizeof(u16) * p_aout->l_units;
245 aout_thread = (void *)aout_Thread_U16_Stereo;
248 case AOUT_FMT_S16_LE:
249 case AOUT_FMT_S16_BE:
250 l_bytes = 2 * sizeof(s16) * p_aout->l_units;
251 aout_thread = (void *)aout_Thread_S16_Stereo;
255 intf_ErrMsg("aout error: unknown audio output format (%i)\n",
262 intf_ErrMsg("aout error: unknown number of audio channels (%i)\n",
263 p_aout->i_channels );
267 /* Allocate the memory needed by the audio output buffers, and set to zero
268 * the s32 buffer's memory */
269 if ( (p_aout->buffer = malloc(l_bytes)) == NULL )
271 intf_ErrMsg("aout error: not enough memory to create the output buffer\n");
274 if ( (p_aout->s32_buffer = (s32 *)calloc(p_aout->l_units, sizeof(s32) << ( p_aout->b_stereo))) == NULL )
276 intf_ErrMsg("aout error: not enough memory to create the s32 output buffer\n");
277 free( p_aout->buffer );
281 /* Before launching the thread, we try to predict the date of the first
282 * audio unit in the first output buffer */
283 p_aout->date = mdate() - 1000000;
285 /* Launch the thread */
286 if ( vlc_thread_create( &p_aout->thread_id, "audio output", (vlc_thread_func_t)aout_thread, p_aout ) )
288 intf_ErrMsg("aout error: can't spawn audio output thread (%p)\n", p_aout);
289 free( p_aout->buffer );
290 free( p_aout->s32_buffer );
294 intf_DbgMsg("aout debug: audio output thread (%p) spawned\n", p_aout);
298 /*****************************************************************************
300 *****************************************************************************/
301 void aout_DestroyThread( aout_thread_t * p_aout, int *pi_status )
303 /* FIXME: pi_status is not handled correctly: check vout how to do!?? */
305 intf_DbgMsg("aout debug: requesting termination of audio output thread (%p)\n", p_aout);
307 /* Ask thread to kill itself and wait until it's done */
309 vlc_thread_join( p_aout->thread_id ); /* only if pi_status is NULL */
311 /* Free the allocated memory */
312 free( p_aout->buffer );
313 free( p_aout->s32_buffer );
315 /* Free the structure */
316 p_aout->p_sys_close( p_aout );
317 intf_DbgMsg("aout debug: audio device (%s) closed\n", p_aout->psz_device);
320 dlclose( p_aout->p_aout_plugin );
326 /*****************************************************************************
328 *****************************************************************************/
329 aout_fifo_t * aout_CreateFifo( aout_thread_t * p_aout, aout_fifo_t * p_fifo )
333 /* Take the fifos lock */
334 vlc_mutex_lock( &p_aout->fifos_lock );
336 /* Looking for a free fifo structure */
337 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
339 if ( p_aout->fifo[i_fifo].i_type == AOUT_EMPTY_FIFO)
344 if ( i_fifo == AOUT_MAX_FIFOS )
346 intf_ErrMsg("aout error: no empty fifo available\n");
347 vlc_mutex_unlock( &p_aout->fifos_lock );
351 /* Initialize the new fifo structure */
352 switch ( p_aout->fifo[i_fifo].i_type = p_fifo->i_type )
354 case AOUT_INTF_MONO_FIFO:
355 case AOUT_INTF_STEREO_FIFO:
356 p_aout->fifo[i_fifo].b_die = 0;
358 p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels;
359 p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo;
360 p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate;
362 p_aout->fifo[i_fifo].buffer = p_fifo->buffer;
364 p_aout->fifo[i_fifo].l_unit = 0;
365 InitializeIncrement( &p_aout->fifo[i_fifo].unit_increment, p_fifo->l_rate, p_aout->l_rate );
366 p_aout->fifo[i_fifo].l_units = p_fifo->l_units;
369 case AOUT_ADEC_MONO_FIFO:
370 case AOUT_ADEC_STEREO_FIFO:
371 p_aout->fifo[i_fifo].b_die = 0;
373 p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels;
374 p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo;
375 p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate;
377 p_aout->fifo[i_fifo].l_frame_size = p_fifo->l_frame_size;
378 /* Allocate the memory needed to store the audio frames. As the
379 * fifo is a rotative fifo, we must be able to find out whether the
380 * fifo is full or empty, that's why we must in fact allocate memory
381 * for (AOUT_FIFO_SIZE+1) audio frames. */
382 if ( (p_aout->fifo[i_fifo].buffer = malloc( sizeof(s16)*(AOUT_FIFO_SIZE+1)*p_fifo->l_frame_size )) == NULL )
384 intf_ErrMsg("aout error: not enough memory to create the frames buffer\n");
385 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
386 vlc_mutex_unlock( &p_aout->fifos_lock );
390 /* Allocate the memory needed to store the dates of the frames */
391 if ( (p_aout->fifo[i_fifo].date = (mtime_t *)malloc( sizeof(mtime_t)*(AOUT_FIFO_SIZE+1) )) == NULL )
393 intf_ErrMsg("aout error: not enough memory to create the dates buffer\n");
394 free( p_aout->fifo[i_fifo].buffer );
395 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
396 vlc_mutex_unlock( &p_aout->fifos_lock );
400 /* Set the fifo's buffer as empty (the first frame that is to be
401 * played is also the first frame that is not to be played) */
402 p_aout->fifo[i_fifo].l_start_frame = 0;
403 /* p_aout->fifo[i_fifo].l_next_frame = 0; */
404 p_aout->fifo[i_fifo].l_end_frame = 0;
406 /* Waiting for the audio decoder to compute enough frames to work
407 * out the fifo's current rate (as soon as the decoder has decoded
408 * enough frames, the members of the fifo structure that are not
409 * initialized now will be calculated) */
410 p_aout->fifo[i_fifo].b_start_frame = 0;
411 p_aout->fifo[i_fifo].b_next_frame = 0;
415 intf_ErrMsg("aout error: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
416 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
417 vlc_mutex_unlock( &p_aout->fifos_lock );
421 /* Release the fifos lock */
422 vlc_mutex_unlock( &p_aout->fifos_lock );
424 /* Return the pointer to the fifo structure */
425 intf_DbgMsg("aout debug: audio output fifo (%p) allocated\n", &p_aout->fifo[i_fifo]);
426 return( &p_aout->fifo[i_fifo] );
429 /*****************************************************************************
431 *****************************************************************************/
432 void aout_DestroyFifo( aout_fifo_t * p_fifo )
434 intf_DbgMsg("aout debug: requesting destruction of audio output fifo (%p)\n", p_fifo);
438 /* Here are the local macros */
440 #define UPDATE_INCREMENT( increment, integer ) \
441 if ( ((increment).l_remainder += (increment).l_euclidean_remainder) >= 0 )\
443 (integer) += (increment).l_euclidean_integer + 1; \
444 (increment).l_remainder -= (increment).l_euclidean_denominator; \
448 (integer) += (increment).l_euclidean_integer; \
451 /* Following functions are local */
453 /*****************************************************************************
454 * InitializeIncrement
455 *****************************************************************************/
456 static __inline__ void InitializeIncrement( aout_increment_t * p_increment, long l_numerator, long l_denominator )
458 p_increment->l_remainder = -l_denominator;
460 p_increment->l_euclidean_integer = 0;
461 while ( l_numerator >= l_denominator )
463 p_increment->l_euclidean_integer++;
464 l_numerator -= l_denominator;
467 p_increment->l_euclidean_remainder = l_numerator;
469 p_increment->l_euclidean_denominator = l_denominator;
472 /*****************************************************************************
474 *****************************************************************************/
475 static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo, mtime_t aout_date )
477 long l_units, l_rate;
479 /* We take the lock */
480 vlc_mutex_lock( &p_fifo->data_lock );
482 /* Are we looking for a dated start frame ? */
483 if ( !p_fifo->b_start_frame )
485 while ( p_fifo->l_start_frame != p_fifo->l_end_frame )
487 if ( p_fifo->date[p_fifo->l_start_frame] != LAST_MDATE )
489 p_fifo->b_start_frame = 1;
490 p_fifo->l_next_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE;
491 p_fifo->l_unit = p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo));
494 p_fifo->l_start_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE;
497 if ( p_fifo->l_start_frame == p_fifo->l_end_frame )
499 vlc_mutex_unlock( &p_fifo->data_lock );
504 /* We are looking for the next dated frame */
505 /* FIXME : is the output fifo full ?? */
506 while ( !p_fifo->b_next_frame )
508 while ( p_fifo->l_next_frame != p_fifo->l_end_frame )
510 if ( p_fifo->date[p_fifo->l_next_frame] != LAST_MDATE )
512 p_fifo->b_next_frame = 1;
515 p_fifo->l_next_frame = (p_fifo->l_next_frame + 1) & AOUT_FIFO_SIZE;
518 while ( p_fifo->l_next_frame == p_fifo->l_end_frame )
520 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
523 vlc_mutex_unlock( &p_fifo->data_lock );
529 l_units = ((p_fifo->l_next_frame - p_fifo->l_start_frame) & AOUT_FIFO_SIZE) * (p_fifo->l_frame_size >> (p_fifo->b_stereo));
531 l_rate = p_fifo->l_rate + ((aout_date - p_fifo->date[p_fifo->l_start_frame]) / 256);
532 // fprintf( stderr, "aout debug: %lli (%li);\n", aout_date - p_fifo->date[p_fifo->l_start_frame], l_rate );
534 InitializeIncrement( &p_fifo->unit_increment, l_rate, p_aout->l_rate );
536 p_fifo->l_units = (((l_units - (p_fifo->l_unit -
537 (p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo)))))
538 * p_aout->l_rate) / l_rate) + 1;
540 /* We release the lock before leaving */
541 vlc_mutex_unlock( &p_fifo->data_lock );
545 void aout_Thread_S8_Mono( aout_thread_t * p_aout )
549 void aout_Thread_S8_Stereo( aout_thread_t * p_aout )
553 void aout_Thread_U8_Mono( aout_thread_t * p_aout )
557 void aout_Thread_U8_Stereo( aout_thread_t * p_aout )
560 long l_buffer, l_buffer_limit;
561 long l_units, l_bytes;
563 intf_DbgMsg("adec debug: ********aout_Thread_U8_Stereo********\n");
564 intf_DbgMsg("adec debug: running audio output thread (%p) (pid == %i)\n", p_aout, getpid());
566 /* As the s32_buffer was created with calloc(), we don't have to set this
567 * memory to zero and we can immediately jump into the thread's loop */
568 while ( !p_aout->b_die )
570 vlc_mutex_lock( &p_aout->fifos_lock );
571 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
573 switch ( p_aout->fifo[i_fifo].i_type )
575 case AOUT_EMPTY_FIFO:
578 case AOUT_INTF_MONO_FIFO:
579 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
582 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
584 p_aout->s32_buffer[l_buffer++] +=
585 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
586 p_aout->s32_buffer[l_buffer++] +=
587 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
588 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
590 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
595 while ( l_buffer < (p_aout->fifo[i_fifo].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 free( p_aout->fifo[i_fifo].buffer ); /* !! */
604 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
605 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
609 case AOUT_INTF_STEREO_FIFO:
610 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
613 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
615 p_aout->s32_buffer[l_buffer++] +=
616 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
617 p_aout->s32_buffer[l_buffer++] +=
618 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
619 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
621 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
626 while ( l_buffer < (p_aout->fifo[i_fifo].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 free( p_aout->fifo[i_fifo].buffer ); /* !! */
635 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
636 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
640 case AOUT_ADEC_MONO_FIFO:
641 if ( p_aout->fifo[i_fifo].b_die )
643 free( p_aout->fifo[i_fifo].buffer );
644 free( p_aout->fifo[i_fifo].date );
645 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
646 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
650 l_units = p_aout->l_units;
652 while ( l_units > 0 )
654 if ( !p_aout->fifo[i_fifo].b_next_frame )
656 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
662 if ( p_aout->fifo[i_fifo].l_units > l_units )
664 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
665 while ( l_buffer < l_buffer_limit )
667 p_aout->s32_buffer[l_buffer++] +=
668 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
669 p_aout->s32_buffer[l_buffer++] +=
670 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
672 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
673 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
674 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
676 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
677 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
680 p_aout->fifo[i_fifo].l_units -= l_units;
685 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
686 /* p_aout->b_stereo == 1 */
687 while ( l_buffer < l_buffer_limit )
689 p_aout->s32_buffer[l_buffer++] +=
690 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
691 p_aout->s32_buffer[l_buffer++] +=
692 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
694 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
695 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
696 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
698 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
699 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
702 l_units -= p_aout->fifo[i_fifo].l_units;
704 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
705 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
706 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
707 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
709 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
710 p_aout->fifo[i_fifo].l_next_frame += 1;
711 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
712 p_aout->fifo[i_fifo].b_next_frame = 0;
717 case AOUT_ADEC_STEREO_FIFO:
718 if ( p_aout->fifo[i_fifo].b_die )
720 free( p_aout->fifo[i_fifo].buffer );
721 free( p_aout->fifo[i_fifo].date );
722 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
723 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
727 l_units = p_aout->l_units;
729 while ( l_units > 0 )
731 if ( !p_aout->fifo[i_fifo].b_next_frame )
733 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
739 if ( p_aout->fifo[i_fifo].l_units > l_units )
741 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
742 while ( l_buffer < l_buffer_limit )
744 p_aout->s32_buffer[l_buffer++] +=
745 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
746 p_aout->s32_buffer[l_buffer++] +=
747 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
749 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
750 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
751 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
753 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
754 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
757 p_aout->fifo[i_fifo].l_units -= l_units;
762 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
763 /* p_aout->b_stereo == 1 */
764 while ( l_buffer < l_buffer_limit )
766 p_aout->s32_buffer[l_buffer++] +=
767 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
768 p_aout->s32_buffer[l_buffer++] +=
769 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
771 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
772 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
773 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
775 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
776 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
779 l_units -= p_aout->fifo[i_fifo].l_units;
781 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
782 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
783 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
784 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
786 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
787 p_aout->fifo[i_fifo].l_next_frame += 1;
788 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
789 p_aout->fifo[i_fifo].b_next_frame = 0;
795 intf_DbgMsg("aout debug: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
799 vlc_mutex_unlock( &p_aout->fifos_lock );
801 l_buffer_limit = p_aout->l_units << 1 ; /* p_aout->b_stereo == 1 */
803 for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
805 ((u8 *)p_aout->buffer)[l_buffer] = (u8)( (p_aout->s32_buffer[l_buffer] / 256) + 128 );
806 p_aout->s32_buffer[l_buffer] = 0;
808 l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
809 p_aout->date = mdate() + ((((mtime_t)(l_bytes / 2 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 2 */
810 p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
811 if ( l_bytes > (l_buffer_limit * sizeof(u8)) )
813 msleep( p_aout->l_msleep );
817 vlc_mutex_lock( &p_aout->fifos_lock );
818 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
820 switch ( p_aout->fifo[i_fifo].i_type )
822 case AOUT_EMPTY_FIFO:
825 case AOUT_INTF_MONO_FIFO:
826 case AOUT_INTF_STEREO_FIFO:
827 free( p_aout->fifo[i_fifo].buffer ); /* !! */
828 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
829 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
832 case AOUT_ADEC_MONO_FIFO:
833 case AOUT_ADEC_STEREO_FIFO:
834 free( p_aout->fifo[i_fifo].buffer );
835 free( p_aout->fifo[i_fifo].date );
836 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
837 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
844 vlc_mutex_unlock( &p_aout->fifos_lock );
848 void aout_Thread_S16_Mono( aout_thread_t * p_aout )
852 void aout_Thread_S16_Stereo( aout_thread_t * p_aout )
855 long l_buffer, l_buffer_limit;
856 long l_units, l_bytes;
858 intf_DbgMsg("adec debug: ********aout_Thread_S16_Stereo********\n");
859 intf_DbgMsg("adec debug: running audio output thread (%p) (pid == %i)\n", p_aout, getpid());
861 /* As the s32_buffer was created with calloc(), we don't have to set this
862 * memory to zero and we can immediately jump into the thread's loop */
863 while ( !p_aout->b_die )
865 vlc_mutex_lock( &p_aout->fifos_lock );
866 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
868 switch ( p_aout->fifo[i_fifo].i_type )
870 case AOUT_EMPTY_FIFO:
873 case AOUT_INTF_MONO_FIFO:
874 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
877 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
879 p_aout->s32_buffer[l_buffer++] +=
880 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
881 p_aout->s32_buffer[l_buffer++] +=
882 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
883 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
885 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
890 while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
892 p_aout->s32_buffer[l_buffer++] +=
893 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
894 p_aout->s32_buffer[l_buffer++] +=
895 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
896 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
898 free( p_aout->fifo[i_fifo].buffer ); /* !! */
899 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
900 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
904 case AOUT_INTF_STEREO_FIFO:
905 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
908 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
910 p_aout->s32_buffer[l_buffer++] +=
911 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
912 p_aout->s32_buffer[l_buffer++] +=
913 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
914 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
916 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
921 while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
923 p_aout->s32_buffer[l_buffer++] +=
924 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
925 p_aout->s32_buffer[l_buffer++] +=
926 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
927 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
929 free( p_aout->fifo[i_fifo].buffer ); /* !! */
930 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
931 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
935 case AOUT_ADEC_MONO_FIFO:
936 if ( p_aout->fifo[i_fifo].b_die )
938 free( p_aout->fifo[i_fifo].buffer );
939 free( p_aout->fifo[i_fifo].date );
940 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
941 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
945 l_units = p_aout->l_units;
947 while ( l_units > 0 )
949 if ( !p_aout->fifo[i_fifo].b_next_frame )
951 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
957 if ( p_aout->fifo[i_fifo].l_units > l_units )
959 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
960 while ( l_buffer < l_buffer_limit )
962 p_aout->s32_buffer[l_buffer++] +=
963 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
964 p_aout->s32_buffer[l_buffer++] +=
965 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
967 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
968 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
969 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
971 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
972 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
975 p_aout->fifo[i_fifo].l_units -= l_units;
980 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
981 /* p_aout->b_stereo == 1 */
982 while ( l_buffer < l_buffer_limit )
984 p_aout->s32_buffer[l_buffer++] +=
985 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
986 p_aout->s32_buffer[l_buffer++] +=
987 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
989 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
990 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
991 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
993 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
994 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
997 l_units -= p_aout->fifo[i_fifo].l_units;
999 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1000 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1001 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1002 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1004 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1005 p_aout->fifo[i_fifo].l_next_frame += 1;
1006 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1007 p_aout->fifo[i_fifo].b_next_frame = 0;
1012 case AOUT_ADEC_STEREO_FIFO:
1013 if ( p_aout->fifo[i_fifo].b_die )
1015 free( p_aout->fifo[i_fifo].buffer );
1016 free( p_aout->fifo[i_fifo].date );
1017 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1018 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1022 l_units = p_aout->l_units;
1024 while ( l_units > 0 )
1026 if ( !p_aout->fifo[i_fifo].b_next_frame )
1028 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1034 if ( p_aout->fifo[i_fifo].l_units > l_units )
1036 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1037 while ( l_buffer < l_buffer_limit )
1039 p_aout->s32_buffer[l_buffer++] +=
1040 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1041 p_aout->s32_buffer[l_buffer++] +=
1042 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1044 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1045 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1046 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1048 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1049 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1052 p_aout->fifo[i_fifo].l_units -= l_units;
1057 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1058 /* p_aout->b_stereo == 1 */
1059 while ( l_buffer < l_buffer_limit )
1061 p_aout->s32_buffer[l_buffer++] +=
1062 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1063 p_aout->s32_buffer[l_buffer++] +=
1064 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1066 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1067 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1068 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1070 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1071 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1074 l_units -= p_aout->fifo[i_fifo].l_units;
1076 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1077 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1078 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1079 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1081 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1082 p_aout->fifo[i_fifo].l_next_frame += 1;
1083 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1084 p_aout->fifo[i_fifo].b_next_frame = 0;
1090 intf_DbgMsg("aout debug: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
1094 vlc_mutex_unlock( &p_aout->fifos_lock );
1096 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1098 for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
1100 ((s16 *)p_aout->buffer)[l_buffer] = (s16)( p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS );
1101 p_aout->s32_buffer[l_buffer] = 0;
1104 l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
1105 p_aout->date = -1000000 + mdate() + ((((mtime_t)(l_bytes / 4)) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(s16) << (p_aout->b_stereo) == 4 */
1106 p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(s16) );
1107 if ( l_bytes > (l_buffer_limit * sizeof(s16)) )
1109 msleep( p_aout->l_msleep );
1113 vlc_mutex_lock( &p_aout->fifos_lock );
1114 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1116 switch ( p_aout->fifo[i_fifo].i_type )
1118 case AOUT_EMPTY_FIFO:
1121 case AOUT_INTF_MONO_FIFO:
1122 case AOUT_INTF_STEREO_FIFO:
1123 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1124 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1125 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1128 case AOUT_ADEC_MONO_FIFO:
1129 case AOUT_ADEC_STEREO_FIFO:
1130 free( p_aout->fifo[i_fifo].buffer );
1131 free( p_aout->fifo[i_fifo].date );
1132 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1133 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1140 vlc_mutex_unlock( &p_aout->fifos_lock );
1143 void aout_Thread_U16_Mono( aout_thread_t * p_aout )
1147 void aout_Thread_U16_Stereo( aout_thread_t * p_aout )