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() */
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 */
184 p_aout->vol = VOLUME_DEFAULT;
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 )
574 long l_buffer, l_buffer_limit;
575 long l_units, l_bytes;
577 intf_DbgMsg("adec debug: ********aout_Thread_U8_Mono********\n");
578 intf_DbgMsg("adec debug: running audio output thread (%p) (pid == %i)\n", p_aout, getpid());
580 /* As the s32_buffer was created with calloc(), we don't have to set this
581 * memory to zero and we can immediately jump into the thread's loop */
582 while ( !p_aout->b_die )
584 vlc_mutex_lock( &p_aout->fifos_lock );
585 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
587 switch ( p_aout->fifo[i_fifo].i_type )
589 case AOUT_EMPTY_FIFO:
592 case AOUT_INTF_MONO_FIFO:
593 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
596 while ( l_buffer < (p_aout->l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
598 p_aout->s32_buffer[l_buffer++] +=
599 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
600 p_aout->s32_buffer[l_buffer++] +=
601 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
602 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
604 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
609 while ( l_buffer < (p_aout->fifo[i_fifo].l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
611 p_aout->s32_buffer[l_buffer++] +=
612 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
613 p_aout->s32_buffer[l_buffer++] +=
614 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
615 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
617 free( p_aout->fifo[i_fifo].buffer ); /* !! */
618 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
619 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
623 case AOUT_INTF_STEREO_FIFO:
624 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
627 while ( l_buffer < (p_aout->l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
629 p_aout->s32_buffer[l_buffer++] +=
630 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
631 p_aout->s32_buffer[l_buffer++] +=
632 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
633 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
635 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
640 while ( l_buffer < (p_aout->fifo[i_fifo].l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
642 p_aout->s32_buffer[l_buffer++] +=
643 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
644 p_aout->s32_buffer[l_buffer++] +=
645 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
646 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
648 free( p_aout->fifo[i_fifo].buffer ); /* !! */
649 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
650 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
654 case AOUT_ADEC_MONO_FIFO:
655 if ( p_aout->fifo[i_fifo].b_die )
657 free( p_aout->fifo[i_fifo].buffer );
658 free( p_aout->fifo[i_fifo].date );
659 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
660 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
664 l_units = p_aout->l_units;
666 while ( l_units > 0 )
668 if ( !p_aout->fifo[i_fifo].b_next_frame )
670 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
676 if ( p_aout->fifo[i_fifo].l_units > l_units )
678 l_buffer_limit = p_aout->l_units /*<< 1*/; /* p_aout->b_stereo == 1 */
679 while ( l_buffer < l_buffer_limit )
681 p_aout->s32_buffer[l_buffer++] +=
682 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
683 p_aout->s32_buffer[l_buffer++] +=
684 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
686 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
687 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
688 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
690 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
691 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
694 p_aout->fifo[i_fifo].l_units -= l_units;
699 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
700 /* p_aout->b_stereo == 1 */
701 while ( l_buffer < l_buffer_limit )
703 p_aout->s32_buffer[l_buffer++] +=
704 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
705 p_aout->s32_buffer[l_buffer++] +=
706 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
708 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
709 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
710 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
712 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
713 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
716 l_units -= p_aout->fifo[i_fifo].l_units;
718 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
719 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
720 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
721 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
723 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
724 p_aout->fifo[i_fifo].l_next_frame += 1;
725 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
726 p_aout->fifo[i_fifo].b_next_frame = 0;
731 case AOUT_ADEC_STEREO_FIFO:
732 if ( p_aout->fifo[i_fifo].b_die )
734 free( p_aout->fifo[i_fifo].buffer );
735 free( p_aout->fifo[i_fifo].date );
736 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
737 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
741 l_units = p_aout->l_units;
743 while ( l_units > 0 )
745 if ( !p_aout->fifo[i_fifo].b_next_frame )
747 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
755 if ( p_aout->fifo[i_fifo].l_units > l_units )
757 l_buffer_limit = p_aout->l_units /*<< 1*/; /* p_aout->b_stereo == 1 */
758 //intf_DbgMsg( "l_buffer_limit:%d\n",l_buffer_limit );
759 while ( l_buffer < l_buffer_limit )
763 p_aout->s32_buffer[l_buffer++] +=
764 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] );
765 p_aout->s32_buffer[l_buffer++] +=
766 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] );
769 //intf_DbgMsg( "1deb " );
771 p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] ) / 2;
772 p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
774 //intf_DbgMsg( "1fin" );
779 //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] );
780 intf_DbgMsg( "p_aout->fifo %ld\n",COEFF*p_aout->fifo[i_fifo].l_unit );
781 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] ) );
782 //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] );
785 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
786 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
787 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/)) )
789 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
790 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/));
793 p_aout->fifo[i_fifo].l_units -= l_units;
799 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units /*<< 1*/);
800 //intf_DbgMsg( "l_buffer_limit:%d\n",l_buffer_limit );
801 /* p_aout->b_stereo == 1 */
802 while ( l_buffer < l_buffer_limit )
806 p_aout->s32_buffer[l_buffer++] +=
807 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] );
808 p_aout->s32_buffer[l_buffer++] +=
809 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] );
812 //intf_DbgMsg( "2deb " );
814 //intf_DbgMsg( "793 ");
815 // !!!!!! Seg Fault !!!!!!!
816 //intf_DbgMsg( "\n p->aout_buffer : %d\t%d\n",p_aout->s32_buffer[l_buffer],COEFF*p_aout->fifo[i_fifo].l_unit );
817 if( COEFF*p_aout->fifo[i_fifo].l_unit < 60000 )
819 p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] ) / 2;
820 // intf_DbgMsg( "795 ");
821 p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
822 //intf_DbgMsg( "797 ");
825 //intf_DbgMsg( "2fin " );
830 //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] );
831 intf_DbgMsg( "p_aout->fifo %ld\n",COEFF*p_aout->fifo[i_fifo].l_unit );
832 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] ) );
833 //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] );
836 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
837 //intf_DbgMsg( "807 ");
838 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
839 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/)) )
841 //intf_DbgMsg( "811 ");
842 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
843 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/));
846 //intf_DbgMsg( "816 ");
847 l_units -= p_aout->fifo[i_fifo].l_units;
848 //intf_DbgMsg( "818 ");
849 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
850 //intf_DbgMsg( "820 ");
851 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
852 //intf_DbgMsg( "822 ");
853 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
854 //intf_DbgMsg( "824 ");
855 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
856 //intf_DbgMsg( "826 ");
857 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
858 p_aout->fifo[i_fifo].l_next_frame += 1;
859 //intf_DbgMsg( "829 ");
860 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
861 //intf_DbgMsg( "831 ");
862 p_aout->fifo[i_fifo].b_next_frame = 0;
864 //intf_DbgMsg( "837 ");
866 //intf_DbgMsg( "838 ");
867 /* !!!!!!!!!!!!! Seg Fault !!!!!!!!!!!!!!!!! */
869 //intf_DbgMsg( "839 ");
873 //intf_DbgMsg( "841 ");
874 intf_DbgMsg("aout debug: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
875 //intf_DbgMsg( "842 ");
879 //intf_DbgMsg( "843 ");
880 vlc_mutex_unlock( &p_aout->fifos_lock );
881 //intf_DbgMsg( "845 ");
882 l_buffer_limit = p_aout->l_units /*<< 1*/ ; /* p_aout->b_stereo == 1 */
883 //intf_DbgMsg( "\nici commence l'envoi sur sb\n" );
884 for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
886 //intf_DbgMsg( "3deb ");
887 //intf_DbgMsg( "p_aout->s_32_buffer[l_buffer] : %x (%d)\n",p_aout->s32_buffer[l_buffer],p_aout->s32_buffer[l_buffer] );
888 ((u8 *)p_aout->buffer)[l_buffer] = (u8)( (p_aout->s32_buffer[/*2 **/ l_buffer] / 256) + 128 );
889 //intf_DbgMsg( "p_aout->buffer[l_buffer] : %x (%d)\n", ((u8 *)p_aout->buffer)[l_buffer], ((u8 *)p_aout->buffer)[l_buffer] );
890 p_aout->s32_buffer[/*2 **/ l_buffer] = 0;
891 // p_aout->s32_buffer[2 * l_buffer + 1] = 0;
892 //intf_DbgMsg( "3fin ");
894 l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
895 p_aout->date = mdate() + ((((mtime_t)(l_bytes / 2 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 2 */
896 p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
897 if ( l_bytes > (l_buffer_limit * sizeof(u8)) )
899 msleep( p_aout->l_msleep );
903 vlc_mutex_lock( &p_aout->fifos_lock );
904 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
906 switch ( p_aout->fifo[i_fifo].i_type )
908 case AOUT_EMPTY_FIFO:
911 case AOUT_INTF_MONO_FIFO:
912 case AOUT_INTF_STEREO_FIFO:
913 free( p_aout->fifo[i_fifo].buffer ); /* !! */
914 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
915 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
918 case AOUT_ADEC_MONO_FIFO:
919 case AOUT_ADEC_STEREO_FIFO:
920 free( p_aout->fifo[i_fifo].buffer );
921 free( p_aout->fifo[i_fifo].date );
922 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
923 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
930 vlc_mutex_unlock( &p_aout->fifos_lock );
934 void aout_Thread_U8_Stereo( aout_thread_t * p_aout )
937 long l_buffer, l_buffer_limit;
938 long l_units, l_bytes;
940 intf_DbgMsg("adec debug: ********aout_Thread_U8_Stereo********\n");
941 intf_DbgMsg("adec debug: running audio output thread (%p) (pid == %i)\n", p_aout, getpid());
943 /* As the s32_buffer was created with calloc(), we don't have to set this
944 * memory to zero and we can immediately jump into the thread's loop */
945 while ( !p_aout->b_die )
947 vlc_mutex_lock( &p_aout->fifos_lock );
948 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
950 switch ( p_aout->fifo[i_fifo].i_type )
952 case AOUT_EMPTY_FIFO:
955 case AOUT_INTF_MONO_FIFO:
956 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
959 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
961 p_aout->s32_buffer[l_buffer++] +=
962 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
963 p_aout->s32_buffer[l_buffer++] +=
964 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
965 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
967 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
972 while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
974 p_aout->s32_buffer[l_buffer++] +=
975 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
976 p_aout->s32_buffer[l_buffer++] +=
977 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
978 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
980 free( p_aout->fifo[i_fifo].buffer ); /* !! */
981 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
982 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
986 case AOUT_INTF_STEREO_FIFO:
987 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
990 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
992 p_aout->s32_buffer[l_buffer++] +=
993 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
994 p_aout->s32_buffer[l_buffer++] +=
995 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
996 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
998 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
1003 while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
1005 p_aout->s32_buffer[l_buffer++] +=
1006 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1007 p_aout->s32_buffer[l_buffer++] +=
1008 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1009 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1011 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1012 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1013 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
1017 case AOUT_ADEC_MONO_FIFO:
1018 if ( p_aout->fifo[i_fifo].b_die )
1020 free( p_aout->fifo[i_fifo].buffer );
1021 free( p_aout->fifo[i_fifo].date );
1022 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1023 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1027 l_units = p_aout->l_units;
1029 while ( l_units > 0 )
1031 if ( !p_aout->fifo[i_fifo].b_next_frame )
1033 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1039 if ( p_aout->fifo[i_fifo].l_units > l_units )
1041 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1042 while ( l_buffer < l_buffer_limit )
1044 p_aout->s32_buffer[l_buffer++] +=
1045 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1046 p_aout->s32_buffer[l_buffer++] +=
1047 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1049 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1050 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1051 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1053 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1054 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1057 p_aout->fifo[i_fifo].l_units -= l_units;
1062 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1063 /* p_aout->b_stereo == 1 */
1064 while ( l_buffer < l_buffer_limit )
1066 p_aout->s32_buffer[l_buffer++] +=
1067 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1068 p_aout->s32_buffer[l_buffer++] +=
1069 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1071 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1072 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1073 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1075 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1076 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1079 l_units -= p_aout->fifo[i_fifo].l_units;
1081 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1082 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1083 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1084 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1086 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1087 p_aout->fifo[i_fifo].l_next_frame += 1;
1088 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1089 p_aout->fifo[i_fifo].b_next_frame = 0;
1094 case AOUT_ADEC_STEREO_FIFO:
1095 if ( p_aout->fifo[i_fifo].b_die )
1097 free( p_aout->fifo[i_fifo].buffer );
1098 free( p_aout->fifo[i_fifo].date );
1099 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1100 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1104 l_units = p_aout->l_units;
1106 while ( l_units > 0 )
1108 if ( !p_aout->fifo[i_fifo].b_next_frame )
1110 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1116 if ( p_aout->fifo[i_fifo].l_units > l_units )
1118 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1119 while ( l_buffer < l_buffer_limit )
1121 p_aout->s32_buffer[l_buffer++] +=
1122 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1123 p_aout->s32_buffer[l_buffer++] +=
1124 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1126 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1127 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1128 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1130 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1131 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1134 p_aout->fifo[i_fifo].l_units -= l_units;
1139 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1140 /* p_aout->b_stereo == 1 */
1141 while ( l_buffer < l_buffer_limit )
1143 p_aout->s32_buffer[l_buffer++] +=
1144 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1145 p_aout->s32_buffer[l_buffer++] +=
1146 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1148 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1149 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1150 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1152 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1153 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1156 l_units -= p_aout->fifo[i_fifo].l_units;
1158 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1159 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1160 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1161 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1163 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1164 p_aout->fifo[i_fifo].l_next_frame += 1;
1165 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1166 p_aout->fifo[i_fifo].b_next_frame = 0;
1172 intf_DbgMsg("aout debug: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
1176 vlc_mutex_unlock( &p_aout->fifos_lock );
1178 l_buffer_limit = p_aout->l_units << 1 ; /* p_aout->b_stereo == 1 */
1180 for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
1182 ((u8 *)p_aout->buffer)[l_buffer] = (u8)( ( (p_aout->s32_buffer[l_buffer] / 256) + 128 ) * p_aout->vol / 256 );
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 ) * p_aout->vol / 256 ) ;
1478 p_aout->s32_buffer[l_buffer] = 0;
1481 l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
1482 p_aout->date = mdate() + ((((mtime_t)(l_bytes / 4)) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(s16) << (p_aout->b_stereo) == 4 */
1483 p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(s16) );
1484 if ( l_bytes > (l_buffer_limit * sizeof(s16)) )
1486 msleep( p_aout->l_msleep );
1490 vlc_mutex_lock( &p_aout->fifos_lock );
1491 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1493 switch ( p_aout->fifo[i_fifo].i_type )
1495 case AOUT_EMPTY_FIFO:
1498 case AOUT_INTF_MONO_FIFO:
1499 case AOUT_INTF_STEREO_FIFO:
1500 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1501 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1502 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1505 case AOUT_ADEC_MONO_FIFO:
1506 case AOUT_ADEC_STEREO_FIFO:
1507 free( p_aout->fifo[i_fifo].buffer );
1508 free( p_aout->fifo[i_fifo].date );
1509 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1510 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1517 vlc_mutex_unlock( &p_aout->fifos_lock );
1520 void aout_Thread_U16_Mono( aout_thread_t * p_aout )
1524 void aout_Thread_U16_Stereo( aout_thread_t * p_aout )