1 /******************************************************************************
2 * audio_output.c : audio output thread
4 ******************************************************************************/
8 * - Passer un certain nombre de "fonctions" (genre add_samples) en macro ou
10 * - Faire les optimisations dans les fonctions threads :
11 * = Stocker les "petits calculs" dans des variables au lieu de les refaire
13 * = Utiliser des tables pour les gros calculs
14 * - Faire une structure différente pour intf/adec fifo
15 * - Rajouter des vlc_cond_signal ?
19 /******************************************************************************
21 ******************************************************************************/
24 #include <sys/soundcard.h>
25 #include <stdio.h> /* "intf_msg.h" */
26 #include <stdlib.h> /* calloc(), malloc(), free() */
30 #include "mtime.h" /* mtime_t, mdate(), msleep() */
31 #include "vlc_thread.h"
33 #include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
35 #include "audio_output.h"
36 #include "audio_dsp.h"
39 /******************************************************************************
41 ******************************************************************************/
43 static int aout_SpawnThread( aout_thread_t * p_aout );
45 /* Creating as much aout_Thread functions as configurations is one solution,
46 * examining the different cases in the Thread loop of an unique function is
47 * another. I chose the first solution. */
48 void aout_Thread_S8_Mono ( aout_thread_t * p_aout );
49 void aout_Thread_U8_Mono ( aout_thread_t * p_aout );
50 void aout_Thread_S16_Mono ( aout_thread_t * p_aout );
51 void aout_Thread_U16_Mono ( aout_thread_t * p_aout );
52 void aout_Thread_S8_Stereo ( aout_thread_t * p_aout );
53 void aout_Thread_U8_Stereo ( aout_thread_t * p_aout );
54 void aout_Thread_S16_Stereo ( aout_thread_t * p_aout );
55 void aout_Thread_U16_Stereo ( aout_thread_t * p_aout );
57 static __inline__ void InitializeIncrement( aout_increment_t * p_increment, long l_numerator, long l_denominator );
58 static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo, mtime_t aout_date );
60 /******************************************************************************
61 * aout_CreateThread: initialize audio thread
62 ******************************************************************************/
63 aout_thread_t *aout_CreateThread( int *pi_status )
65 aout_thread_t * p_aout; /* thread descriptor */
66 int i_status; /* thread status */
68 /* Allocate descriptor */
69 p_aout = (aout_thread_t *) malloc( sizeof(aout_thread_t) );
75 //???? kludge to initialize some audio parameters - place this section somewhere
77 p_aout->dsp.i_format = AOUT_DEFAULT_FORMAT;
78 p_aout->dsp.psz_device = main_GetPszVariable( AOUT_DSP_VAR, AOUT_DSP_DEFAULT );
79 p_aout->dsp.b_stereo = main_GetIntVariable( AOUT_STEREO_VAR, AOUT_STEREO_DEFAULT );
80 p_aout->dsp.l_rate = main_GetIntVariable( AOUT_RATE_VAR, AOUT_RATE_DEFAULT );
86 if ( aout_dspOpen( &p_aout->dsp ) )
91 if ( aout_dspReset( &p_aout->dsp ) )
93 aout_dspClose( &p_aout->dsp );
97 if ( aout_dspSetFormat( &p_aout->dsp ) )
99 aout_dspClose( &p_aout->dsp );
103 if ( aout_dspSetChannels( &p_aout->dsp ) )
105 aout_dspClose( &p_aout->dsp );
109 if ( aout_dspSetRate( &p_aout->dsp ) )
111 aout_dspClose( &p_aout->dsp );
115 intf_DbgMsg("aout debug: audio device (%s) opened (format=%i, stereo=%i, rate=%li)\n",
116 p_aout->dsp.psz_device,
117 p_aout->dsp.i_format,
118 p_aout->dsp.b_stereo, p_aout->dsp.l_rate);
120 //?? maybe it would be cleaner to change SpawnThread prototype
121 //?? see vout to handle status correctly - however, it is not critical since
122 //?? this thread is only called in main is all calls are blocking
123 if( aout_SpawnThread( p_aout ) )
125 aout_dspClose( &p_aout->dsp );
133 /******************************************************************************
135 ******************************************************************************/
136 static int aout_SpawnThread( aout_thread_t * p_aout )
140 void * aout_thread = NULL;
142 intf_DbgMsg("aout debug: spawning audio output thread (%p)\n", p_aout);
144 /* We want the audio output thread to live */
147 /* Initialize the fifos lock */
148 vlc_mutex_init( &p_aout->fifos_lock );
149 /* Initialize audio fifos : set all fifos as empty and initialize locks */
150 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
152 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
153 vlc_mutex_init( &p_aout->fifo[i_fifo].data_lock );
154 vlc_cond_init( &p_aout->fifo[i_fifo].data_wait );
157 /* Compute the size (in audio units) of the audio output buffer. Although
158 * AOUT_BUFFER_DURATION is given in microseconds, the output rate is given
159 * in Hz, that's why we need to divide by 10^6 microseconds (1 second) */
160 p_aout->l_units = (long)( ((s64)p_aout->dsp.l_rate * AOUT_BUFFER_DURATION) / 1000000 );
161 p_aout->l_msleep = ((s64)p_aout->l_units * 1000000) / (s64)p_aout->dsp.l_rate;
163 /* Make aout_thread point to the right thread function, and compute the
164 * byte size of the audio output buffer */
165 switch ( p_aout->dsp.b_stereo )
167 /* Audio output is mono */
169 switch ( p_aout->dsp.i_format )
172 l_bytes = 1 * sizeof(u8) * p_aout->l_units;
173 aout_thread = (void *)aout_Thread_U8_Mono;
177 l_bytes = 1 * sizeof(s8) * p_aout->l_units;
178 aout_thread = (void *)aout_Thread_S8_Mono;
183 l_bytes = 1 * sizeof(u16) * p_aout->l_units;
184 aout_thread = (void *)aout_Thread_U16_Mono;
189 l_bytes = 1 * sizeof(s16) * p_aout->l_units;
190 aout_thread = (void *)aout_Thread_S16_Mono;
194 intf_ErrMsg("aout error: unknown audio output format (%i)\n",
195 p_aout->dsp.i_format);
200 /* Audio output is stereo */
202 switch ( p_aout->dsp.i_format )
205 l_bytes = 2 * sizeof(u8) * p_aout->l_units;
206 aout_thread = (void *)aout_Thread_U8_Stereo;
210 l_bytes = 2 * sizeof(s8) * p_aout->l_units;
211 aout_thread = (void *)aout_Thread_S8_Stereo;
216 l_bytes = 2 * sizeof(u16) * p_aout->l_units;
217 aout_thread = (void *)aout_Thread_U16_Stereo;
222 l_bytes = 2 * sizeof(s16) * p_aout->l_units;
223 aout_thread = (void *)aout_Thread_S16_Stereo;
227 intf_ErrMsg("aout error: unknown audio output format (%i)\n",
228 p_aout->dsp.i_format);
234 intf_ErrMsg("aout error: unknown number of audio channels (%i)\n",
235 p_aout->dsp.b_stereo + 1);
239 /* Allocate the memory needed by the audio output buffers, and set to zero
240 * the s32 buffer's memory */
241 if ( (p_aout->buffer = malloc(l_bytes)) == NULL )
243 intf_ErrMsg("aout error: not enough memory to create the output buffer\n");
246 if ( (p_aout->s32_buffer = (s32 *)calloc(p_aout->l_units, sizeof(s32) << p_aout->dsp.b_stereo)) == NULL )
248 intf_ErrMsg("aout error: not enough memory to create the s32 output buffer\n");
249 free( p_aout->buffer );
253 /* Before launching the thread, we try to predict the date of the first
254 * audio unit in the first output buffer */
255 p_aout->date = mdate();
257 /* Launch the thread */
258 if ( vlc_thread_create( &p_aout->thread_id, "audio output", (vlc_thread_func_t)aout_thread, p_aout ) )
260 intf_ErrMsg("aout error: can't spawn audio output thread (%p)\n", p_aout);
261 free( p_aout->buffer );
262 free( p_aout->s32_buffer );
266 intf_DbgMsg("aout debug: audio output thread (%p) spawned\n", p_aout);
270 /******************************************************************************
272 ******************************************************************************/
273 void aout_DestroyThread( aout_thread_t * p_aout, int *pi_status )
275 //???? pi_status is not handled correctly: check vout how to do!
277 intf_DbgMsg("aout debug: requesting termination of audio output thread (%p)\n", p_aout);
279 /* Ask thread to kill itself and wait until it's done */
281 vlc_thread_join( p_aout->thread_id ); // only if pi_status is NULL
283 /* Free the allocated memory */
284 free( p_aout->buffer );
285 free( p_aout->s32_buffer );
287 /* Free the structure */
288 aout_dspClose( &p_aout->dsp );
289 intf_DbgMsg("aout debug: audio device (%s) closed\n", p_aout->dsp.psz_device);
293 /******************************************************************************
295 ******************************************************************************/
296 aout_fifo_t * aout_CreateFifo( aout_thread_t * p_aout, aout_fifo_t * p_fifo )
300 /* Take the fifos lock */
301 vlc_mutex_lock( &p_aout->fifos_lock );
303 /* Looking for a free fifo structure */
304 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
306 if ( p_aout->fifo[i_fifo].i_type == AOUT_EMPTY_FIFO)
311 if ( i_fifo == AOUT_MAX_FIFOS )
313 intf_ErrMsg("aout error: no empty fifo available\n");
314 vlc_mutex_unlock( &p_aout->fifos_lock );
318 /* Initialize the new fifo structure */
319 switch ( p_aout->fifo[i_fifo].i_type = p_fifo->i_type )
321 case AOUT_INTF_MONO_FIFO:
322 case AOUT_INTF_STEREO_FIFO:
323 p_aout->fifo[i_fifo].b_die = 0;
325 p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo;
326 p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate;
328 p_aout->fifo[i_fifo].buffer = p_fifo->buffer;
330 p_aout->fifo[i_fifo].l_unit = 0;
331 InitializeIncrement( &p_aout->fifo[i_fifo].unit_increment, p_fifo->l_rate, p_aout->dsp.l_rate );
332 p_aout->fifo[i_fifo].l_units = p_fifo->l_units;
335 case AOUT_ADEC_MONO_FIFO:
336 case AOUT_ADEC_STEREO_FIFO:
337 p_aout->fifo[i_fifo].b_die = 0;
339 p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo;
340 p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate;
342 p_aout->fifo[i_fifo].l_frame_size = p_fifo->l_frame_size;
343 /* Allocate the memory needed to store the audio frames. As the
344 * fifo is a rotative fifo, we must be able to find out whether the
345 * fifo is full or empty, that's why we must in fact allocate memory
346 * for (AOUT_FIFO_SIZE+1) audio frames. */
347 if ( (p_aout->fifo[i_fifo].buffer = malloc( sizeof(s16)*(AOUT_FIFO_SIZE+1)*p_fifo->l_frame_size )) == NULL )
349 intf_ErrMsg("aout error: not enough memory to create the frames buffer\n");
350 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
351 vlc_mutex_unlock( &p_aout->fifos_lock );
355 /* Allocate the memory needed to store the dates of the frames */
356 if ( (p_aout->fifo[i_fifo].date = (mtime_t *)malloc( sizeof(mtime_t)*(AOUT_FIFO_SIZE+1) )) == NULL )
358 intf_ErrMsg("aout error: not enough memory to create the dates buffer\n");
359 free( p_aout->fifo[i_fifo].buffer );
360 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
361 vlc_mutex_unlock( &p_aout->fifos_lock );
365 /* Set the fifo's buffer as empty (the first frame that is to be
366 * played is also the first frame that is not to be played) */
367 p_aout->fifo[i_fifo].l_start_frame = 0;
368 /* p_aout->fifo[i_fifo].l_next_frame = 0; */
369 p_aout->fifo[i_fifo].l_end_frame = 0;
371 /* Waiting for the audio decoder to compute enough frames to work
372 * out the fifo's current rate (as soon as the decoder has decoded
373 * enough frames, the members of the fifo structure that are not
374 * initialized now will be calculated) */
375 p_aout->fifo[i_fifo].b_start_frame = 0;
376 p_aout->fifo[i_fifo].b_next_frame = 0;
380 intf_ErrMsg("aout error: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
381 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
382 vlc_mutex_unlock( &p_aout->fifos_lock );
386 /* Release the fifos lock */
387 vlc_mutex_unlock( &p_aout->fifos_lock );
389 /* Return the pointer to the fifo structure */
390 intf_DbgMsg("aout debug: audio output fifo (%p) allocated\n", &p_aout->fifo[i_fifo]);
391 return( &p_aout->fifo[i_fifo] );
394 /******************************************************************************
396 ******************************************************************************/
397 void aout_DestroyFifo( aout_fifo_t * p_fifo )
399 intf_DbgMsg("aout debug: requesting destruction of audio output fifo (%p)\n", p_fifo);
403 /* Here are the local macros */
405 #define UPDATE_INCREMENT( increment, integer ) \
406 if ( ((increment).l_remainder += (increment).l_euclidean_remainder) >= 0 ) \
408 (integer) += (increment).l_euclidean_integer + 1; \
409 (increment).l_remainder -= (increment).l_euclidean_denominator; \
413 (integer) += (increment).l_euclidean_integer; \
416 /* Following functions are local */
418 /******************************************************************************
419 * InitializeIncrement
420 ******************************************************************************/
421 static __inline__ void InitializeIncrement( aout_increment_t * p_increment, long l_numerator, long l_denominator )
423 p_increment->l_remainder = -l_denominator;
425 p_increment->l_euclidean_integer = 0;
426 while ( l_numerator >= l_denominator )
428 p_increment->l_euclidean_integer++;
429 l_numerator -= l_denominator;
432 p_increment->l_euclidean_remainder = l_numerator;
434 p_increment->l_euclidean_denominator = l_denominator;
437 /******************************************************************************
439 ******************************************************************************/
440 static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo, mtime_t aout_date )
442 long l_units, l_rate;
444 /* We take the lock */
445 vlc_mutex_lock( &p_fifo->data_lock );
447 /* Are we looking for a dated start frame ? */
448 if ( !p_fifo->b_start_frame )
450 while ( p_fifo->l_start_frame != p_fifo->l_end_frame )
452 if ( p_fifo->date[p_fifo->l_start_frame] != LAST_MDATE )
454 p_fifo->b_start_frame = 1;
455 p_fifo->l_next_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE;
456 p_fifo->l_unit = p_fifo->l_start_frame * (p_fifo->l_frame_size >> p_fifo->b_stereo);
459 p_fifo->l_start_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE;
461 if ( p_fifo->l_start_frame == p_fifo->l_end_frame )
463 vlc_mutex_unlock( &p_fifo->data_lock );
469 if ( aout_date < p_fifo->date[p_fifo->l_start_frame] - 100000 )
471 fprintf( stderr, "-" );
473 vlc_mutex_unlock( &p_fifo->data_lock );
478 /* We are looking for the next dated frame */
481 while ( p_fifo->l_next_frame != p_fifo->l_end_frame )
483 if ( p_fifo->date[p_fifo->l_next_frame] != LAST_MDATE )
486 if ( p_fifo->date[p_fifo->l_start_frame] >= p_fifo->date[p_fifo->l_next_frame] )
488 fprintf( stderr, "aout debug: %lli >= %lli\n", p_fifo->date[p_fifo->l_start_frame], p_fifo->date[p_fifo->l_next_frame] );
489 p_fifo->date[p_fifo->l_start_frame] = p_fifo->date[p_fifo->l_next_frame] - ((1000000 * ((mtime_t)(p_fifo->l_frame_size * ((p_fifo->l_next_frame - p_fifo->l_start_frame) & AOUT_FIFO_SIZE))) >> p_fifo->b_stereo) / ((mtime_t)p_fifo->l_rate));
492 else if ( (p_fifo->date[p_fifo->l_next_frame] - p_fifo->date[p_fifo->l_start_frame]) > 1000000 )
494 fprintf( stderr, "aout debug: (%lli - %lli) > 1000000\n", p_fifo->date[p_fifo->l_next_frame], p_fifo->date[p_fifo->l_start_frame] );
495 p_fifo->date[p_fifo->l_start_frame] = p_fifo->date[p_fifo->l_next_frame] - ((1000000 * ((mtime_t)(p_fifo->l_frame_size * ((p_fifo->l_next_frame - p_fifo->l_start_frame) & AOUT_FIFO_SIZE))) >> p_fifo->b_stereo) / ((mtime_t)p_fifo->l_rate));
499 if ( aout_date < p_fifo->date[p_fifo->l_next_frame] + 100000 )
502 p_fifo->b_next_frame = 1;
508 fprintf( stderr, "+" );
509 // p_fifo->b_next_frame = 1;
511 p_fifo->l_start_frame = p_fifo->l_next_frame;
512 p_fifo->l_unit = p_fifo->l_start_frame * (p_fifo->l_frame_size >> p_fifo->b_stereo);
517 p_fifo->l_next_frame = (p_fifo->l_next_frame + 1) & AOUT_FIFO_SIZE;
519 if ( p_fifo->l_next_frame == p_fifo->l_end_frame )
521 if ( (((p_fifo->l_end_frame + 1) - p_fifo->l_start_frame) & AOUT_FIFO_SIZE) == 0 )
523 fprintf( stderr, "aout debug: synkro suxx rocks;\n" );
524 p_fifo->l_start_frame = 0;
525 p_fifo->b_start_frame = 0;
526 /* p_fifo->l_next_frame = 0; */
527 /* p_fifo->b_next_frame = 0; */
528 p_fifo->l_end_frame = 0;
529 vlc_mutex_unlock( &p_fifo->data_lock );
532 while ( p_fifo->l_next_frame == p_fifo->l_end_frame )
534 vlc_cond_wait(&p_fifo->data_wait, &p_fifo->data_lock);
543 if ( p_fifo->l_next_frame == p_fifo->l_end_frame )
545 fprintf( stderr, "aout debug: synkro suxx rocks (%li);\n", p_fifo->l_dr );
546 if ( (((p_fifo->l_end_frame + 1) - p_fifo->l_start_frame) & AOUT_FIFO_SIZE) == 0 )
548 p_fifo->l_start_frame = 0;
549 p_fifo->b_start_frame = 0;
550 /* p_fifo->l_next_frame = 0; */
551 /* p_fifo->b_next_frame = 0; */
552 p_fifo->l_end_frame = 0;
554 vlc_mutex_unlock( &p_fifo->data_lock );
559 l_units = ((p_fifo->l_next_frame - p_fifo->l_start_frame) & AOUT_FIFO_SIZE) * (p_fifo->l_frame_size >> p_fifo->b_stereo);
560 // fprintf( stderr, "%li", p_fifo->l_unit - (p_fifo->l_start_frame * (p_fifo->l_frame_size >> p_fifo->b_stereo)) );
563 // fprintf( stderr, "aout debug: %lli;\n", aout_date - p_fifo->date[p_fifo->l_start_frame] );
564 if ( /*(p_fifo->date[p_fifo->l_start_frame] < aout_date) &&*/ (aout_date < p_fifo->date[p_fifo->l_next_frame]) )
566 fprintf( stderr, "*" );
567 l_rate = (long)(((mtime_t)l_units * 1000000) / (p_fifo->date[p_fifo->l_next_frame] - aout_date));
571 l_rate = (long)(((mtime_t)l_units * 1000000) / (p_fifo->date[p_fifo->l_next_frame] - p_fifo->date[p_fifo->l_start_frame]));
574 // l_rate = (long)( ((mtime_t)l_units * 1000000) / (p_fifo->date[p_fifo->l_next_frame] - ((p_fifo->date[p_fifo->l_start_frame] + aout_date) / 2)) );
575 // fprintf( stderr, "aout debug: l_rate == %li;\n", l_rate );
576 // fprintf( stderr, "aout debug: %li;\n", l_rate );
577 // fprintf( stderr, "aout debug: %lli, %li, %lli;\n", aout_date - p_fifo->date[p_fifo->l_start_frame], p_fifo->l_unit - (p_fifo->l_start_frame * (p_fifo->l_frame_size >> p_fifo->b_stereo)), p_fifo->date[p_fifo->l_next_frame] - aout_date );
580 if ( aout_date < p_fifo->date[p_fifo->l_start_frame] )
584 else if ( p_fifo->date[p_fifo->l_start_frame] < aout_date )
589 l_rate = p_fifo->l_rate + ((aout_date - p_fifo->date[p_fifo->l_start_frame]) / 8);
590 // l_rate = (long)(((mtime_t)l_units * 1000000) / (p_fifo->date[p_fifo->l_next_frame] - p_fifo->date[p_fifo->l_start_frame])) + p_fifo->l_dr;
591 // fprintf( stderr, "aout debug: l_rate == %li (%lli);\n", l_rate /*+ p_fifo->l_dr*/, aout_date - p_fifo->date[p_fifo->l_start_frame] );
593 // p_fifo->delta += aout_date - p_fifo->date[p_fifo->l_start_frame];
595 // fprintf( stderr, "aout debug: %lli, %lli, %li;\n", aout_date - p_fifo->date[p_fifo->l_start_frame], p_fifo->delta/p_fifo->n, l_rate );
597 InitializeIncrement( &p_fifo->unit_increment, l_rate, p_aout->dsp.l_rate );
599 p_fifo->l_units = (((l_units - (p_fifo->l_unit -
600 (p_fifo->l_start_frame * (p_fifo->l_frame_size >> p_fifo->b_stereo))))
601 * p_aout->dsp.l_rate) / l_rate) + 1;
603 /* We release the lock before leaving */
604 vlc_mutex_unlock( &p_fifo->data_lock );
608 void aout_Thread_S8_Mono( aout_thread_t * p_aout )
612 void aout_Thread_S8_Stereo( aout_thread_t * p_aout )
616 void aout_Thread_U8_Mono( aout_thread_t * p_aout )
620 void aout_Thread_U8_Stereo( aout_thread_t * p_aout )
624 void aout_Thread_S16_Mono( aout_thread_t * p_aout )
628 void aout_Thread_S16_Stereo( aout_thread_t * p_aout )
631 long l_buffer, l_buffer_limit;
632 long l_units, l_bytes;
634 intf_DbgMsg("adec debug: running audio output thread (%p) (pid == %i)\n", p_aout, getpid());
636 /* As the s32_buffer was created with calloc(), we don't have to set this
637 * memory to zero and we can immediately jump into the thread's loop */
638 while ( !p_aout->b_die )
640 vlc_mutex_lock( &p_aout->fifos_lock );
641 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
643 switch ( p_aout->fifo[i_fifo].i_type )
645 case AOUT_EMPTY_FIFO:
648 case AOUT_INTF_MONO_FIFO:
649 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
652 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->dsp.b_stereo == 1 */
654 p_aout->s32_buffer[l_buffer++] +=
655 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
656 p_aout->s32_buffer[l_buffer++] +=
657 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
658 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
660 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
665 while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->dsp.b_stereo == 1 */
667 p_aout->s32_buffer[l_buffer++] +=
668 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
669 p_aout->s32_buffer[l_buffer++] +=
670 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
671 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
673 free( p_aout->fifo[i_fifo].buffer ); /* !! */
674 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
675 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
679 case AOUT_INTF_STEREO_FIFO:
680 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
683 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->dsp.b_stereo == 1 */
685 p_aout->s32_buffer[l_buffer++] +=
686 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
687 p_aout->s32_buffer[l_buffer++] +=
688 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
689 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
691 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
696 while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->dsp.b_stereo */
698 p_aout->s32_buffer[l_buffer++] +=
699 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
700 p_aout->s32_buffer[l_buffer++] +=
701 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
702 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
704 free( p_aout->fifo[i_fifo].buffer ); /* !! */
705 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
706 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
710 case AOUT_ADEC_MONO_FIFO:
711 if ( p_aout->fifo[i_fifo].b_die )
713 free( p_aout->fifo[i_fifo].buffer );
714 free( p_aout->fifo[i_fifo].date );
715 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
716 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
720 l_units = p_aout->l_units;
722 while ( l_units > 0 )
724 if ( !p_aout->fifo[i_fifo].b_next_frame )
726 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->dsp.l_rate))) )
732 if ( p_aout->fifo[i_fifo].l_units > l_units )
734 l_buffer_limit = p_aout->l_units << 1; /* p_aout->dsp.b_stereo == 1 */
735 while ( l_buffer < l_buffer_limit )
737 p_aout->s32_buffer[l_buffer++] +=
738 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
739 p_aout->s32_buffer[l_buffer++] +=
740 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
742 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
743 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
744 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
746 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
747 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
750 p_aout->fifo[i_fifo].l_units -= l_units;
755 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
756 /* p_aout->dsp.b_stereo == 1 */
757 while ( l_buffer < l_buffer_limit )
759 p_aout->s32_buffer[l_buffer++] +=
760 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
761 p_aout->s32_buffer[l_buffer++] +=
762 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
764 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
765 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
766 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
768 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
769 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
772 l_units -= p_aout->fifo[i_fifo].l_units;
774 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
775 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
776 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
777 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
779 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
780 p_aout->fifo[i_fifo].l_next_frame += 1;
781 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
782 p_aout->fifo[i_fifo].b_next_frame = 0;
787 case AOUT_ADEC_STEREO_FIFO:
788 if ( p_aout->fifo[i_fifo].b_die )
790 free( p_aout->fifo[i_fifo].buffer );
791 free( p_aout->fifo[i_fifo].date );
792 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
793 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
797 l_units = p_aout->l_units;
799 while ( l_units > 0 )
801 if ( !p_aout->fifo[i_fifo].b_next_frame )
803 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->dsp.l_rate))) )
809 if ( p_aout->fifo[i_fifo].l_units > l_units )
811 l_buffer_limit = p_aout->l_units << 1; /* p_aout->dsp.b_stereo == 1 */
812 while ( l_buffer < l_buffer_limit )
814 p_aout->s32_buffer[l_buffer++] +=
815 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
816 p_aout->s32_buffer[l_buffer++] +=
817 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
819 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
820 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
821 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
823 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
824 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
827 p_aout->fifo[i_fifo].l_units -= l_units;
832 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
833 /* p_aout->dsp.b_stereo == 1 */
834 while ( l_buffer < l_buffer_limit )
836 p_aout->s32_buffer[l_buffer++] +=
837 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
838 p_aout->s32_buffer[l_buffer++] +=
839 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
841 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
842 if ( 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 >> 1)) )
845 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
846 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
849 l_units -= p_aout->fifo[i_fifo].l_units;
851 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
852 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
853 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
854 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
856 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
857 p_aout->fifo[i_fifo].l_next_frame += 1;
858 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
859 p_aout->fifo[i_fifo].b_next_frame = 0;
865 intf_DbgMsg("aout debug: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
869 vlc_mutex_unlock( &p_aout->fifos_lock );
871 l_buffer_limit = p_aout->l_units << 1; /* p_aout->dsp.b_stereo == 1 */
873 for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
875 ((s16 *)p_aout->buffer)[l_buffer] = (s16)( p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS );
876 p_aout->s32_buffer[l_buffer] = 0;
879 aout_dspGetBufInfo( &p_aout->dsp );
880 l_bytes = (p_aout->dsp.buf_info.fragstotal * p_aout->dsp.buf_info.fragsize) - p_aout->dsp.buf_info.bytes;
881 p_aout->date = mdate() + ((((mtime_t)(l_bytes / 4)) * 1000000) / ((mtime_t)p_aout->dsp.l_rate)); /* sizeof(s16) << p_aout->dsp.b_stereo == 4 */
882 aout_dspPlaySamples( &p_aout->dsp, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(s16) );
883 if ( l_bytes > (l_buffer_limit * sizeof(s16)) )
885 msleep( p_aout->l_msleep );
888 if ( p_aout->dsp.buf_info.fragments == p_aout->dsp.buf_info.fragstotal ) /* ?? */
890 p_aout->date = mdate();
891 aout_dspPlaySamples( &p_aout->dsp, (byte_t *)p_aout->buffer, sizeof(s16) * l_buffer_limit );
893 else if ( p_aout->dsp.buf_info.bytes >=
894 ((p_aout->dsp.buf_info.fragsize * p_aout->dsp.buf_info.fragstotal) -
895 (sizeof(s16) * l_buffer_limit)) )
897 aout_dspPlaySamples( &p_aout->dsp, (byte_t *)p_aout->buffer, sizeof(s16) * l_buffer_limit );
901 fprintf( stderr, "%lli\n", mdate() - date );
903 aout_dspPlaySamples( &p_aout->dsp, (byte_t *)p_aout->buffer, sizeof(s16) * l_buffer_limit );
904 // fprintf( stderr, "%lli\n", (date + ((((mtime_t)((p_aout->dsp.buf_info.fragstotal * p_aout->dsp.buf_info.fragsize - p_aout->dsp.buf_info.bytes) / 4)) * 1000000)/((mtime_t)p_aout->dsp.l_rate))) - p_aout->date );
905 msleep( p_aout->date_increment.l_euclidean_integer );
907 UPDATE_INCREMENT( p_aout->date_increment, p_aout->date )
911 vlc_mutex_lock( &p_aout->fifos_lock );
912 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
914 switch ( p_aout->fifo[i_fifo].i_type )
916 case AOUT_EMPTY_FIFO:
919 case AOUT_INTF_MONO_FIFO:
920 case AOUT_INTF_STEREO_FIFO:
921 free( p_aout->fifo[i_fifo].buffer ); /* !! */
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]);
926 case AOUT_ADEC_MONO_FIFO:
927 case AOUT_ADEC_STEREO_FIFO:
928 free( p_aout->fifo[i_fifo].buffer );
929 free( p_aout->fifo[i_fifo].date );
930 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
931 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
938 vlc_mutex_unlock( &p_aout->fifos_lock );
941 void aout_Thread_U16_Mono( aout_thread_t * p_aout )
945 void aout_Thread_U16_Stereo( aout_thread_t * p_aout )