1 /*****************************************************************************
2 * audio_output.c : audio output thread
3 *****************************************************************************
4 * Copyright (C) 1999, 2000 VideoLAN
6 * Authors: Michel Kaempf <maxx@via.ecp.fr>
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() */
52 #include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
54 #include "audio_output.h"
57 /*****************************************************************************
59 *****************************************************************************/
61 static int aout_SpawnThread( aout_thread_t * p_aout );
63 /* Creating as much aout_Thread functions as configurations is one solution,
64 * examining the different cases in the Thread loop of an unique function is
65 * another. I chose the first solution. */
66 void aout_Thread_S8_Mono ( aout_thread_t * p_aout );
67 void aout_Thread_U8_Mono ( aout_thread_t * p_aout );
68 void aout_Thread_S16_Mono ( aout_thread_t * p_aout );
69 void aout_Thread_U16_Mono ( aout_thread_t * p_aout );
70 void aout_Thread_S8_Stereo ( aout_thread_t * p_aout );
71 void aout_Thread_U8_Stereo ( aout_thread_t * p_aout );
72 void aout_Thread_S16_Stereo ( aout_thread_t * p_aout );
73 void aout_Thread_U16_Stereo ( aout_thread_t * p_aout );
75 static __inline__ void InitializeIncrement( aout_increment_t * p_increment, long l_numerator, long l_denominator );
76 static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo, mtime_t aout_date );
78 /*****************************************************************************
80 *****************************************************************************/
81 static __inline__ void InitializeIncrement( aout_increment_t * p_increment, long l_numerator, long l_denominator )
83 p_increment->l_remainder = -l_denominator;
85 p_increment->l_euclidean_integer = 0;
86 while ( l_numerator >= l_denominator )
88 p_increment->l_euclidean_integer++;
89 l_numerator -= l_denominator;
92 p_increment->l_euclidean_remainder = l_numerator;
94 p_increment->l_euclidean_denominator = l_denominator;
97 /*****************************************************************************
98 * aout_CreateThread: initialize audio thread
99 *****************************************************************************/
100 aout_thread_t *aout_CreateThread( int *pi_status )
102 aout_thread_t * p_aout; /* thread descriptor */
104 int i_status; /* thread status */
107 /* Allocate descriptor */
108 p_aout = (aout_thread_t *) malloc( sizeof(aout_thread_t) );
114 /* Choose the best module */
115 p_aout->p_module = module_Need( p_main->p_module_bank,
116 MODULE_CAPABILITY_AOUT, NULL );
118 if( p_aout->p_module == NULL )
120 intf_ErrMsg( "aout error: no suitable aout module" );
125 #define aout_functions p_aout->p_module->p_functions->aout.functions.aout
126 p_aout->pf_open = aout_functions.pf_open;
127 p_aout->pf_setformat = aout_functions.pf_setformat;
128 p_aout->pf_getbufinfo = aout_functions.pf_getbufinfo;
129 p_aout->pf_play = aout_functions.pf_play;
130 p_aout->pf_close = aout_functions.pf_close;
131 #undef aout_functions
134 * Initialize audio device
136 if ( p_aout->pf_open( p_aout ) )
138 module_Unneed( p_main->p_module_bank, p_aout->p_module );
143 p_aout->b_stereo = ( p_aout->i_channels == 2 ) ? 1 : 0; /* FIXME: only works
144 for i_channels == 1 or 2 ??*/
146 if ( p_aout->pf_setformat( p_aout ) )
148 p_aout->pf_close( p_aout );
149 module_Unneed( p_main->p_module_bank, p_aout->p_module );
154 /* Initialize the volume level */
155 p_aout->vol = VOLUME_DEFAULT;
157 /* FIXME: maybe it would be cleaner to change SpawnThread prototype
158 * see vout to handle status correctly ?? however, it is not critical since
159 * this thread is only called in main and all calls are blocking */
160 if( aout_SpawnThread( p_aout ) )
162 p_aout->pf_close( p_aout );
163 module_Unneed( p_main->p_module_bank, p_aout->p_module );
171 /*****************************************************************************
173 *****************************************************************************/
174 static int aout_SpawnThread( aout_thread_t * p_aout )
178 void * aout_thread = NULL;
180 intf_DbgMsg("aout debug: spawning audio output thread (%p)", p_aout);
182 /* We want the audio output thread to live */
184 p_aout->b_active = 1;
186 /* Initialize the fifos lock */
187 vlc_mutex_init( &p_aout->fifos_lock );
188 /* Initialize audio fifos : set all fifos as empty and initialize locks */
189 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
191 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
192 vlc_mutex_init( &p_aout->fifo[i_fifo].data_lock );
193 vlc_cond_init( &p_aout->fifo[i_fifo].data_wait );
196 /* Compute the size (in audio units) of the audio output buffer. Although
197 * AOUT_BUFFER_DURATION is given in microseconds, the output rate is given
198 * in Hz, that's why we need to divide by 10^6 microseconds (1 second) */
199 p_aout->l_units = (long)( ((s64)p_aout->l_rate * AOUT_BUFFER_DURATION) / 1000000 );
200 p_aout->l_msleep = (long)( ((s64)p_aout->l_units * 1000000) / (s64)p_aout->l_rate );
202 /* Make aout_thread point to the right thread function, and compute the
203 * byte size of the audio output buffer */
204 switch ( p_aout->i_channels )
206 /* Audio output is mono */
208 switch ( p_aout->i_format )
211 l_bytes = 1 * sizeof(u8) * p_aout->l_units;
212 aout_thread = (void *)aout_Thread_U8_Mono;
216 l_bytes = 1 * sizeof(s8) * p_aout->l_units;
217 aout_thread = (void *)aout_Thread_S8_Mono;
220 case AOUT_FMT_U16_LE:
221 case AOUT_FMT_U16_BE:
222 l_bytes = 1 * sizeof(u16) * p_aout->l_units;
223 aout_thread = (void *)aout_Thread_U16_Mono;
226 case AOUT_FMT_S16_LE:
227 case AOUT_FMT_S16_BE:
228 l_bytes = 1 * sizeof(s16) * p_aout->l_units;
229 aout_thread = (void *)aout_Thread_S16_Mono;
233 intf_ErrMsg( "aout error: unknown audio output format (%i)",
239 /* Audio output is stereo */
241 switch ( p_aout->i_format )
244 l_bytes = 2 * sizeof(u8) * p_aout->l_units;
245 aout_thread = (void *)aout_Thread_U8_Stereo;
249 l_bytes = 2 * sizeof(s8) * p_aout->l_units;
250 aout_thread = (void *)aout_Thread_S8_Stereo;
253 case AOUT_FMT_U16_LE:
254 case AOUT_FMT_U16_BE:
255 l_bytes = 2 * sizeof(u16) * p_aout->l_units;
256 aout_thread = (void *)aout_Thread_U16_Stereo;
259 case AOUT_FMT_S16_LE:
260 case AOUT_FMT_S16_BE:
261 l_bytes = 2 * sizeof(s16) * p_aout->l_units;
262 aout_thread = (void *)aout_Thread_S16_Stereo;
266 intf_ErrMsg("aout error: unknown audio output format (%i)",
273 intf_ErrMsg("aout error: unknown number of audio channels (%i)",
274 p_aout->i_channels );
278 /* Allocate the memory needed by the audio output buffers, and set to zero
279 * the s32 buffer's memory */
280 if ( (p_aout->buffer = malloc(l_bytes)) == NULL )
282 intf_ErrMsg("aout error: not enough memory to create the output buffer");
285 if ( (p_aout->s32_buffer = (s32 *)calloc(p_aout->l_units, sizeof(s32) << ( p_aout->b_stereo))) == NULL )
287 intf_ErrMsg("aout error: not enough memory to create the s32 output buffer");
288 free( p_aout->buffer );
292 /* Before launching the thread, we try to predict the date of the first
293 * audio unit in the first output buffer */
294 p_aout->date = mdate() - 1000000;
296 /* Launch the thread */
297 if ( vlc_thread_create( &p_aout->thread_id, "audio output", (vlc_thread_func_t)aout_thread, p_aout ) )
299 intf_ErrMsg("aout error: can't spawn audio output thread (%p)", p_aout);
300 free( p_aout->buffer );
301 free( p_aout->s32_buffer );
305 intf_DbgMsg("aout debug: audio output thread (%p) spawned", p_aout);
309 /*****************************************************************************
311 *****************************************************************************/
312 void aout_DestroyThread( aout_thread_t * p_aout, int *pi_status )
317 /* FIXME: pi_status is not handled correctly: check vout how to do!?? */
319 intf_DbgMsg("aout debug: requesting termination of audio output thread (%p)", p_aout);
321 /* Ask thread to kill itself and wait until it's done */
323 vlc_thread_join( p_aout->thread_id ); /* only if pi_status is NULL */
325 /* Free the allocated memory */
326 free( p_aout->buffer );
327 free( p_aout->s32_buffer );
329 /* Destroy the condition and mutex locks */
330 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
332 vlc_mutex_destroy( &p_aout->fifo[i_fifo].data_lock );
333 vlc_cond_destroy( &p_aout->fifo[i_fifo].data_wait );
335 vlc_mutex_destroy( &p_aout->fifos_lock );
337 /* Free the plugin */
338 p_aout->pf_close( p_aout );
340 /* Release the aout module */
341 module_Unneed( p_main->p_module_bank, p_aout->p_module );
347 /*****************************************************************************
349 *****************************************************************************/
350 aout_fifo_t * aout_CreateFifo( aout_thread_t * p_aout, aout_fifo_t * p_fifo )
354 /* Take the fifos lock */
355 vlc_mutex_lock( &p_aout->fifos_lock );
357 /* Looking for a free fifo structure */
358 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
360 if ( p_aout->fifo[i_fifo].i_type == AOUT_EMPTY_FIFO)
365 if ( i_fifo == AOUT_MAX_FIFOS )
367 intf_ErrMsg("aout error: no empty fifo available");
368 vlc_mutex_unlock( &p_aout->fifos_lock );
372 /* Initialize the new fifo structure */
373 switch ( p_aout->fifo[i_fifo].i_type = p_fifo->i_type )
375 case AOUT_INTF_MONO_FIFO:
376 case AOUT_INTF_STEREO_FIFO:
377 p_aout->fifo[i_fifo].b_die = 0;
379 p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels;
380 p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo;
381 p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate;
383 p_aout->fifo[i_fifo].buffer = p_fifo->buffer;
385 p_aout->fifo[i_fifo].l_unit = 0;
386 InitializeIncrement( &p_aout->fifo[i_fifo].unit_increment, p_fifo->l_rate, p_aout->l_rate );
387 p_aout->fifo[i_fifo].l_units = p_fifo->l_units;
390 case AOUT_ADEC_MONO_FIFO:
391 case AOUT_ADEC_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].l_frame_size = p_fifo->l_frame_size;
399 /* Allocate the memory needed to store the audio frames. As the
400 * fifo is a rotative fifo, we must be able to find out whether the
401 * fifo is full or empty, that's why we must in fact allocate memory
402 * for (AOUT_FIFO_SIZE+1) audio frames. */
403 if ( (p_aout->fifo[i_fifo].buffer = malloc( sizeof(s16)*(AOUT_FIFO_SIZE+1)*p_fifo->l_frame_size )) == NULL )
405 intf_ErrMsg("aout error: not enough memory to create the frames buffer");
406 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
407 vlc_mutex_unlock( &p_aout->fifos_lock );
411 /* Allocate the memory needed to store the dates of the frames */
412 if ( (p_aout->fifo[i_fifo].date = (mtime_t *)malloc( sizeof(mtime_t)*(AOUT_FIFO_SIZE+1) )) == NULL )
414 intf_ErrMsg("aout error: not enough memory to create the dates buffer");
415 free( p_aout->fifo[i_fifo].buffer );
416 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
417 vlc_mutex_unlock( &p_aout->fifos_lock );
421 /* Set the fifo's buffer as empty (the first frame that is to be
422 * played is also the first frame that is not to be played) */
423 p_aout->fifo[i_fifo].l_start_frame = 0;
424 /* p_aout->fifo[i_fifo].l_next_frame = 0; */
425 p_aout->fifo[i_fifo].l_end_frame = 0;
427 /* Waiting for the audio decoder to compute enough frames to work
428 * out the fifo's current rate (as soon as the decoder has decoded
429 * enough frames, the members of the fifo structure that are not
430 * initialized now will be calculated) */
431 p_aout->fifo[i_fifo].b_start_frame = 0;
432 p_aout->fifo[i_fifo].b_next_frame = 0;
436 intf_ErrMsg("aout error: unknown fifo type (%i)", p_aout->fifo[i_fifo].i_type);
437 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
438 vlc_mutex_unlock( &p_aout->fifos_lock );
442 /* Release the fifos lock */
443 vlc_mutex_unlock( &p_aout->fifos_lock );
445 /* Return the pointer to the fifo structure */
446 intf_DbgMsg("aout debug: audio output fifo (%p) allocated", &p_aout->fifo[i_fifo]);
447 return( &p_aout->fifo[i_fifo] );
450 /*****************************************************************************
452 *****************************************************************************/
453 void aout_DestroyFifo( aout_fifo_t * p_fifo )
455 intf_DbgMsg("aout debug: requesting destruction of audio output fifo (%p)", p_fifo);
459 /* Here are the local macros */
461 #define UPDATE_INCREMENT( increment, integer ) \
462 if ( ((increment).l_remainder += (increment).l_euclidean_remainder) >= 0 )\
464 (integer) += (increment).l_euclidean_integer + 1; \
465 (increment).l_remainder -= (increment).l_euclidean_denominator; \
469 (integer) += (increment).l_euclidean_integer; \
472 /* Following functions are local */
474 /*****************************************************************************
476 *****************************************************************************/
477 static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo, mtime_t aout_date )
479 long l_units, l_rate;
481 /* We take the lock */
482 vlc_mutex_lock( &p_fifo->data_lock );
484 /* Are we looking for a dated start frame ? */
485 if ( !p_fifo->b_start_frame )
487 while ( p_fifo->l_start_frame != p_fifo->l_end_frame )
489 if ( p_fifo->date[p_fifo->l_start_frame] != LAST_MDATE )
491 p_fifo->b_start_frame = 1;
492 p_fifo->l_next_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE;
493 p_fifo->l_unit = p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo));
496 p_fifo->l_start_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE;
499 if ( p_fifo->l_start_frame == p_fifo->l_end_frame )
501 vlc_mutex_unlock( &p_fifo->data_lock );
506 /* We are looking for the next dated frame */
507 /* FIXME : is the output fifo full ?? */
508 while ( !p_fifo->b_next_frame )
510 while ( p_fifo->l_next_frame != p_fifo->l_end_frame )
512 if ( p_fifo->date[p_fifo->l_next_frame] != LAST_MDATE )
514 p_fifo->b_next_frame = 1;
517 p_fifo->l_next_frame = (p_fifo->l_next_frame + 1) & AOUT_FIFO_SIZE;
520 while ( p_fifo->l_next_frame == p_fifo->l_end_frame )
522 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
525 vlc_mutex_unlock( &p_fifo->data_lock );
531 l_units = ((p_fifo->l_next_frame - p_fifo->l_start_frame) & AOUT_FIFO_SIZE) * (p_fifo->l_frame_size >> (p_fifo->b_stereo));
533 l_rate = p_fifo->l_rate + ((aout_date - p_fifo->date[p_fifo->l_start_frame]) / 256);
534 intf_DbgMsg( "aout debug: %lli (%li);", aout_date - p_fifo->date[p_fifo->l_start_frame], l_rate );
536 InitializeIncrement( &p_fifo->unit_increment, l_rate, p_aout->l_rate );
538 p_fifo->l_units = (((l_units - (p_fifo->l_unit -
539 (p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo)))))
540 * p_aout->l_rate) / l_rate) + 1;
542 /* We release the lock before leaving */
543 vlc_mutex_unlock( &p_fifo->data_lock );
547 void aout_Thread_S8_Mono( aout_thread_t * p_aout )
551 void aout_Thread_S8_Stereo( aout_thread_t * p_aout )
555 void aout_Thread_U8_Mono( aout_thread_t * p_aout )
558 long l_buffer, l_buffer_limit;
559 long l_units, l_bytes;
561 intf_DbgMsg("adec debug: running audio output U8_M_thread (%p) (pid == %i)", p_aout, getpid());
563 /* As the s32_buffer was created with calloc(), we don't have to set this
564 * memory to zero and we can immediately jump into the thread's loop */
565 while ( !p_aout->b_die )
567 vlc_mutex_lock( &p_aout->fifos_lock );
568 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
570 switch ( p_aout->fifo[i_fifo].i_type )
572 case AOUT_EMPTY_FIFO:
575 case AOUT_INTF_MONO_FIFO:
576 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
579 while ( l_buffer < (p_aout->l_units) ) /* p_aout->b_stereo == 0 */
581 p_aout->s32_buffer[l_buffer++] +=
582 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
583 p_aout->s32_buffer[l_buffer++] +=
584 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
585 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
587 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
592 while ( l_buffer < (p_aout->fifo[i_fifo].l_units) ) /* p_aout->b_stereo == 0 */
594 p_aout->s32_buffer[l_buffer++] +=
595 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
596 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
598 free( p_aout->fifo[i_fifo].buffer ); /* !! */
599 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
600 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */
604 case AOUT_INTF_STEREO_FIFO:
605 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
608 while ( l_buffer < (p_aout->l_units) ) /* p_aout->b_stereo == 0 */
610 /* I mix half left - half right */
611 p_aout->s32_buffer[l_buffer++] +=
612 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ) / 2 +
613 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
614 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
616 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
621 while ( l_buffer < (p_aout->fifo[i_fifo].l_units) ) /* p_aout->b_stereo == 0 */
623 /* I mix half left - half right */
624 p_aout->s32_buffer[l_buffer++] +=
625 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ) / 2 +
626 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
627 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
629 free( p_aout->fifo[i_fifo].buffer ); /* !! */
630 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
631 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */
635 case AOUT_ADEC_MONO_FIFO:
636 if ( p_aout->fifo[i_fifo].b_die )
638 free( p_aout->fifo[i_fifo].buffer );
639 free( p_aout->fifo[i_fifo].date );
640 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
641 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
645 l_units = p_aout->l_units;
647 while ( l_units > 0 )
649 if ( !p_aout->fifo[i_fifo].b_next_frame )
651 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
657 if ( p_aout->fifo[i_fifo].l_units > l_units )
659 l_buffer_limit = p_aout->l_units; /* p_aout->b_stereo == 0 */
660 while ( l_buffer < l_buffer_limit )
662 p_aout->s32_buffer[l_buffer++] +=
663 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
665 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
666 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
667 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
669 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
670 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
673 p_aout->fifo[i_fifo].l_units -= l_units;
678 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units);
679 /* p_aout->b_stereo == 0 */
680 while ( l_buffer < l_buffer_limit )
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 l_units -= p_aout->fifo[i_fifo].l_units;
695 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
696 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
697 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
698 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
700 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
701 p_aout->fifo[i_fifo].l_next_frame += 1;
702 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
703 p_aout->fifo[i_fifo].b_next_frame = 0;
708 case AOUT_ADEC_STEREO_FIFO:
709 if ( p_aout->fifo[i_fifo].b_die )
711 free( p_aout->fifo[i_fifo].buffer );
712 free( p_aout->fifo[i_fifo].date );
713 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
714 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
718 l_units = p_aout->l_units;
720 while ( l_units > 0 )
722 if ( !p_aout->fifo[i_fifo].b_next_frame )
724 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
730 if ( p_aout->fifo[i_fifo].l_units > l_units )
732 l_buffer_limit = p_aout->l_units; /* p_aout->b_stereo == 0 */
733 while ( l_buffer < l_buffer_limit )
735 /* I mix half left - half right */
736 p_aout->s32_buffer[l_buffer++] +=
737 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ) / 2 +
738 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
740 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
741 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
742 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
744 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
745 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
748 p_aout->fifo[i_fifo].l_units -= l_units;
753 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units);
754 /* p_aout->b_stereo == 0 */
755 while ( l_buffer < l_buffer_limit )
757 /* I mix half left - half right */
758 p_aout->s32_buffer[l_buffer++] +=
759 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ) / 2 +
760 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
762 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
763 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
764 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
766 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
767 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
770 l_units -= p_aout->fifo[i_fifo].l_units;
772 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
773 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
774 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
775 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
777 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
778 p_aout->fifo[i_fifo].l_next_frame += 1;
779 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
780 p_aout->fifo[i_fifo].b_next_frame = 0;
786 intf_DbgMsg("aout debug: unknown fifo type (%i)", p_aout->fifo[i_fifo].i_type);
790 vlc_mutex_unlock( &p_aout->fifos_lock );
792 l_buffer_limit = p_aout->l_units; /* p_aout->b_stereo == 0 */
794 for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
796 ((u8 *)p_aout->buffer)[l_buffer] = (u8)( ( (p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS / 256 ) + 128 ) * p_aout->vol / 256 );
797 p_aout->s32_buffer[l_buffer] = 0;
799 l_bytes = p_aout->pf_getbufinfo( p_aout, l_buffer_limit );
800 p_aout->date = mdate() + ((((mtime_t)(l_bytes / 1 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 1 */
801 p_aout->pf_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
802 if ( l_bytes > (l_buffer_limit * sizeof(u8) * 2) ) /* There are 2 channels (left & right) */
804 msleep( p_aout->l_msleep );
808 vlc_mutex_lock( &p_aout->fifos_lock );
809 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
811 switch ( p_aout->fifo[i_fifo].i_type )
813 case AOUT_EMPTY_FIFO:
816 case AOUT_INTF_MONO_FIFO:
817 case AOUT_INTF_STEREO_FIFO:
818 free( p_aout->fifo[i_fifo].buffer ); /* !! */
819 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
820 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
823 case AOUT_ADEC_MONO_FIFO:
824 case AOUT_ADEC_STEREO_FIFO:
825 free( p_aout->fifo[i_fifo].buffer );
826 free( p_aout->fifo[i_fifo].date );
827 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
828 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
835 vlc_mutex_unlock( &p_aout->fifos_lock );
840 void aout_Thread_U8_Stereo( aout_thread_t * p_aout )
843 long l_buffer, l_buffer_limit;
844 long l_units, l_bytes;
846 intf_DbgMsg("adec debug: running audio output U8_S_thread (%p) (pid == %i)", p_aout, getpid());
848 /* As the s32_buffer was created with calloc(), we don't have to set this
849 * memory to zero and we can immediately jump into the thread's loop */
850 while ( !p_aout->b_die )
852 vlc_mutex_lock( &p_aout->fifos_lock );
853 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
855 switch ( p_aout->fifo[i_fifo].i_type )
857 case AOUT_EMPTY_FIFO:
860 case AOUT_INTF_MONO_FIFO:
861 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
864 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
866 p_aout->s32_buffer[l_buffer++] +=
867 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
868 p_aout->s32_buffer[l_buffer++] +=
869 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
870 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
872 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
877 while ( l_buffer < (p_aout->fifo[i_fifo].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 free( p_aout->fifo[i_fifo].buffer ); /* !! */
886 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
887 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */
891 case AOUT_INTF_STEREO_FIFO:
892 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
895 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
897 p_aout->s32_buffer[l_buffer++] +=
898 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
899 p_aout->s32_buffer[l_buffer++] +=
900 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
901 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
903 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
908 while ( l_buffer < (p_aout->fifo[i_fifo].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 free( p_aout->fifo[i_fifo].buffer ); /* !! */
917 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
918 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */
922 case AOUT_ADEC_MONO_FIFO:
923 if ( p_aout->fifo[i_fifo].b_die )
925 free( p_aout->fifo[i_fifo].buffer );
926 free( p_aout->fifo[i_fifo].date );
927 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
928 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
932 l_units = p_aout->l_units;
934 while ( l_units > 0 )
936 if ( !p_aout->fifo[i_fifo].b_next_frame )
938 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
944 if ( p_aout->fifo[i_fifo].l_units > l_units )
946 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
947 while ( l_buffer < l_buffer_limit )
949 p_aout->s32_buffer[l_buffer++] +=
950 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
951 p_aout->s32_buffer[l_buffer++] +=
952 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
954 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
955 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
956 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
958 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
959 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
962 p_aout->fifo[i_fifo].l_units -= l_units;
967 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
968 /* p_aout->b_stereo == 1 */
969 while ( l_buffer < l_buffer_limit )
971 p_aout->s32_buffer[l_buffer++] +=
972 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
973 p_aout->s32_buffer[l_buffer++] +=
974 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
976 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
977 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
978 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
980 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
981 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
984 l_units -= p_aout->fifo[i_fifo].l_units;
986 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
987 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
988 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
989 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
991 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
992 p_aout->fifo[i_fifo].l_next_frame += 1;
993 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
994 p_aout->fifo[i_fifo].b_next_frame = 0;
999 case AOUT_ADEC_STEREO_FIFO:
1000 if ( p_aout->fifo[i_fifo].b_die )
1002 free( p_aout->fifo[i_fifo].buffer );
1003 free( p_aout->fifo[i_fifo].date );
1004 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1005 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1009 l_units = p_aout->l_units;
1011 while ( l_units > 0 )
1013 if ( !p_aout->fifo[i_fifo].b_next_frame )
1015 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1021 if ( p_aout->fifo[i_fifo].l_units > l_units )
1023 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1024 while ( l_buffer < l_buffer_limit )
1026 p_aout->s32_buffer[l_buffer++] +=
1027 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1028 p_aout->s32_buffer[l_buffer++] +=
1029 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1031 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1032 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1033 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1035 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1036 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1039 p_aout->fifo[i_fifo].l_units -= l_units;
1044 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1045 /* p_aout->b_stereo == 1 */
1046 while ( l_buffer < l_buffer_limit )
1048 p_aout->s32_buffer[l_buffer++] +=
1049 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1050 p_aout->s32_buffer[l_buffer++] +=
1051 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1053 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1054 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1055 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1057 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1058 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1061 l_units -= p_aout->fifo[i_fifo].l_units;
1063 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1064 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1065 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1066 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1068 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1069 p_aout->fifo[i_fifo].l_next_frame += 1;
1070 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1071 p_aout->fifo[i_fifo].b_next_frame = 0;
1077 intf_DbgMsg("aout debug: unknown fifo type (%i)", p_aout->fifo[i_fifo].i_type);
1081 vlc_mutex_unlock( &p_aout->fifos_lock );
1083 l_buffer_limit = p_aout->l_units << 1 ; /* p_aout->b_stereo == 1 */
1085 for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
1087 ((u8 *)p_aout->buffer)[l_buffer] = (u8)( ( (p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS / 256) + 128 ) * p_aout->vol / 256 );
1088 p_aout->s32_buffer[l_buffer] = 0;
1090 l_bytes = p_aout->pf_getbufinfo( p_aout, l_buffer_limit );
1091 p_aout->date = mdate() + ((((mtime_t)(l_bytes / 2 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 2 */
1092 p_aout->pf_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
1093 if ( l_bytes > (l_buffer_limit * sizeof(u8)) )
1095 msleep( p_aout->l_msleep );
1099 vlc_mutex_lock( &p_aout->fifos_lock );
1100 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1102 switch ( p_aout->fifo[i_fifo].i_type )
1104 case AOUT_EMPTY_FIFO:
1107 case AOUT_INTF_MONO_FIFO:
1108 case AOUT_INTF_STEREO_FIFO:
1109 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1110 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1111 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1114 case AOUT_ADEC_MONO_FIFO:
1115 case AOUT_ADEC_STEREO_FIFO:
1116 free( p_aout->fifo[i_fifo].buffer );
1117 free( p_aout->fifo[i_fifo].date );
1118 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1119 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1126 vlc_mutex_unlock( &p_aout->fifos_lock );
1130 void aout_Thread_S16_Mono( aout_thread_t * p_aout )
1134 void aout_Thread_S16_Stereo( aout_thread_t * p_aout )
1137 long l_buffer, l_buffer_limit;
1138 long l_units, l_bytes;
1140 intf_DbgMsg("adec debug: running audio output S16_S_thread (%p) (pid == %i)", p_aout, getpid());
1142 /* As the s32_buffer was created with calloc(), we don't have to set this
1143 * memory to zero and we can immediately jump into the thread's loop */
1144 while ( !p_aout->b_die )
1146 vlc_mutex_lock( &p_aout->fifos_lock );
1147 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1149 switch ( p_aout->fifo[i_fifo].i_type )
1151 case AOUT_EMPTY_FIFO:
1154 case AOUT_INTF_MONO_FIFO:
1155 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
1158 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
1160 p_aout->s32_buffer[l_buffer++] +=
1161 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1162 p_aout->s32_buffer[l_buffer++] +=
1163 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1164 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1166 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
1171 while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
1173 p_aout->s32_buffer[l_buffer++] +=
1174 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1175 p_aout->s32_buffer[l_buffer++] +=
1176 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1177 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1179 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1180 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1181 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */
1185 case AOUT_INTF_STEREO_FIFO:
1186 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
1189 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
1191 p_aout->s32_buffer[l_buffer++] +=
1192 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1193 p_aout->s32_buffer[l_buffer++] +=
1194 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1195 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1197 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
1202 while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
1204 p_aout->s32_buffer[l_buffer++] +=
1205 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1206 p_aout->s32_buffer[l_buffer++] +=
1207 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1208 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1210 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1211 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1212 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */
1216 case AOUT_ADEC_MONO_FIFO:
1217 if ( p_aout->fifo[i_fifo].b_die )
1219 free( p_aout->fifo[i_fifo].buffer );
1220 free( p_aout->fifo[i_fifo].date );
1221 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1222 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1226 l_units = p_aout->l_units;
1228 while ( l_units > 0 )
1230 if ( !p_aout->fifo[i_fifo].b_next_frame )
1232 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1238 if ( p_aout->fifo[i_fifo].l_units > l_units )
1240 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1241 while ( l_buffer < l_buffer_limit )
1243 p_aout->s32_buffer[l_buffer++] +=
1244 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1245 p_aout->s32_buffer[l_buffer++] +=
1246 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1248 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1249 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1250 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1252 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1253 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1256 p_aout->fifo[i_fifo].l_units -= l_units;
1261 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1262 /* p_aout->b_stereo == 1 */
1263 while ( l_buffer < l_buffer_limit )
1265 p_aout->s32_buffer[l_buffer++] +=
1266 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1267 p_aout->s32_buffer[l_buffer++] +=
1268 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1270 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1271 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1272 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1274 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1275 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1278 l_units -= p_aout->fifo[i_fifo].l_units;
1280 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1281 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1282 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1283 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1285 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1286 p_aout->fifo[i_fifo].l_next_frame += 1;
1287 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1288 p_aout->fifo[i_fifo].b_next_frame = 0;
1293 case AOUT_ADEC_STEREO_FIFO:
1294 if ( p_aout->fifo[i_fifo].b_die )
1296 free( p_aout->fifo[i_fifo].buffer );
1297 free( p_aout->fifo[i_fifo].date );
1298 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1299 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1303 l_units = p_aout->l_units;
1305 while ( l_units > 0 )
1307 if ( !p_aout->fifo[i_fifo].b_next_frame )
1309 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1315 if ( p_aout->fifo[i_fifo].l_units > l_units )
1317 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1318 while ( l_buffer < l_buffer_limit )
1320 p_aout->s32_buffer[l_buffer++] +=
1321 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1322 p_aout->s32_buffer[l_buffer++] +=
1323 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1325 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1326 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1327 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1329 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1330 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1333 p_aout->fifo[i_fifo].l_units -= l_units;
1338 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1339 /* p_aout->b_stereo == 1 */
1340 while ( l_buffer < l_buffer_limit )
1342 p_aout->s32_buffer[l_buffer++] +=
1343 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1344 p_aout->s32_buffer[l_buffer++] +=
1345 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1347 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1348 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1349 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1351 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1352 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1355 l_units -= p_aout->fifo[i_fifo].l_units;
1357 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1358 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1359 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1360 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1362 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1363 p_aout->fifo[i_fifo].l_next_frame += 1;
1364 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1365 p_aout->fifo[i_fifo].b_next_frame = 0;
1371 intf_DbgMsg("aout debug: unknown fifo type (%i)", p_aout->fifo[i_fifo].i_type);
1375 vlc_mutex_unlock( &p_aout->fifos_lock );
1377 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1379 for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
1381 ((s16 *)p_aout->buffer)[l_buffer] = (s16)( ( p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS ) * p_aout->vol / 256 ) ;
1382 p_aout->s32_buffer[l_buffer] = 0;
1385 l_bytes = p_aout->pf_getbufinfo( p_aout, l_buffer_limit );
1386 p_aout->date = mdate() + ((((mtime_t)(l_bytes / 4)) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(s16) << (p_aout->b_stereo) == 4 */
1387 p_aout->pf_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(s16) );
1388 if ( l_bytes > (l_buffer_limit * sizeof(s16)) )
1390 msleep( p_aout->l_msleep );
1394 vlc_mutex_lock( &p_aout->fifos_lock );
1395 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1397 switch ( p_aout->fifo[i_fifo].i_type )
1399 case AOUT_EMPTY_FIFO:
1402 case AOUT_INTF_MONO_FIFO:
1403 case AOUT_INTF_STEREO_FIFO:
1404 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1405 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1406 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1409 case AOUT_ADEC_MONO_FIFO:
1410 case AOUT_ADEC_STEREO_FIFO:
1411 free( p_aout->fifo[i_fifo].buffer );
1412 free( p_aout->fifo[i_fifo].date );
1413 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1414 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]);
1421 vlc_mutex_unlock( &p_aout->fifos_lock );
1424 void aout_Thread_U16_Mono( aout_thread_t * p_aout )
1428 void aout_Thread_U16_Stereo( aout_thread_t * p_aout )