1 /*****************************************************************************
2 * audio_output.c : audio output thread
3 *****************************************************************************
4 * Copyright (C) 1999, 2000 VideoLAN
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
22 *****************************************************************************/
26 * - Passer un certain nombre de "fonctions" (genre add_samples) en macro ou
28 * - Faire les optimisations dans les fonctions threads :
29 * = Stocker les "petits calculs" dans des variables au lieu de les refaire
31 * = Utiliser des tables pour les gros calculs
32 * - Faire une structure différente pour intf/adec fifo
36 /*****************************************************************************
38 *****************************************************************************/
41 #include <unistd.h> /* getpid() */
43 #include <stdio.h> /* "intf_msg.h" */
44 #include <stdlib.h> /* calloc(), malloc(), free() */
49 #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 /*****************************************************************************
79 * aout_CreateThread: initialize audio thread
80 *****************************************************************************/
81 aout_thread_t *aout_CreateThread( int *pi_status )
83 aout_thread_t * p_aout; /* thread descriptor */
86 int i_status; /* thread status */
89 /* Allocate descriptor */
90 p_aout = (aout_thread_t *) malloc( sizeof(aout_thread_t) );
96 /* Request an interface plugin */
97 psz_method = main_GetPszVariable( AOUT_METHOD_VAR, AOUT_DEFAULT_METHOD );
99 if( RequestPlugin( &p_aout->aout_plugin, "aout", psz_method ) )
101 intf_ErrMsg( "error: could not open audio plugin aout_%s.so\n", psz_method );
107 p_aout->p_sys_open = GetPluginFunction( p_aout->aout_plugin, "aout_SysOpen" );
108 p_aout->p_sys_reset = GetPluginFunction( p_aout->aout_plugin, "aout_SysReset" );
109 p_aout->p_sys_setformat = GetPluginFunction( p_aout->aout_plugin, "aout_SysSetFormat" );
110 p_aout->p_sys_setchannels = GetPluginFunction( p_aout->aout_plugin, "aout_SysSetChannels" );
111 p_aout->p_sys_setrate = GetPluginFunction( p_aout->aout_plugin, "aout_SysSetRate" );
112 p_aout->p_sys_getbufinfo = GetPluginFunction( p_aout->aout_plugin, "aout_SysGetBufInfo" );
113 p_aout->p_sys_playsamples = GetPluginFunction( p_aout->aout_plugin, "aout_SysPlaySamples" );
114 p_aout->p_sys_close = GetPluginFunction( p_aout->aout_plugin, "aout_SysClose" );
117 * Initialize audio device
119 if ( p_aout->p_sys_open( p_aout ) )
121 TrashPlugin( p_aout->aout_plugin );
126 p_aout->b_stereo = ( p_aout->i_channels == 2 ) ? 1 : 0; /* FIXME: only works
127 for i_channels == 1 or 2 ??*/
129 if ( p_aout->p_sys_reset( p_aout ) )
131 p_aout->p_sys_close( p_aout );
132 TrashPlugin( p_aout->aout_plugin );
136 if ( p_aout->p_sys_setformat( p_aout ) )
138 p_aout->p_sys_close( p_aout );
139 TrashPlugin( p_aout->aout_plugin );
143 if ( p_aout->p_sys_setchannels( p_aout ) )
145 p_aout->p_sys_close( p_aout );
146 TrashPlugin( p_aout->aout_plugin );
150 if ( p_aout->p_sys_setrate( p_aout ) )
152 p_aout->p_sys_close( p_aout );
153 TrashPlugin( p_aout->aout_plugin );
158 /* Initialize the vomue level */
163 /* FIXME: maybe it would be cleaner to change SpawnThread prototype
164 * see vout to handle status correctly ?? however, it is not critical since
165 * this thread is only called in main and all calls are blocking */
166 if( aout_SpawnThread( p_aout ) )
168 p_aout->p_sys_close( p_aout );
169 TrashPlugin( p_aout->aout_plugin );
177 /*****************************************************************************
179 *****************************************************************************/
180 static int aout_SpawnThread( aout_thread_t * p_aout )
184 void * aout_thread = NULL;
186 intf_DbgMsg("aout debug: spawning audio output thread (%p)\n", p_aout);
188 /* We want the audio output thread to live */
190 p_aout->b_active = 1;
192 /* Initialize the fifos lock */
193 vlc_mutex_init( &p_aout->fifos_lock );
194 /* Initialize audio fifos : set all fifos as empty and initialize locks */
195 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
197 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
198 vlc_mutex_init( &p_aout->fifo[i_fifo].data_lock );
199 vlc_cond_init( &p_aout->fifo[i_fifo].data_wait );
202 /* Compute the size (in audio units) of the audio output buffer. Although
203 * AOUT_BUFFER_DURATION is given in microseconds, the output rate is given
204 * in Hz, that's why we need to divide by 10^6 microseconds (1 second) */
205 p_aout->l_units = (long)( ((s64)p_aout->l_rate * AOUT_BUFFER_DURATION) / 1000000 );
206 p_aout->l_msleep = (long)( ((s64)p_aout->l_units * 1000000) / (s64)p_aout->l_rate );
208 /* Make aout_thread point to the right thread function, and compute the
209 * byte size of the audio output buffer */
210 switch ( p_aout->i_channels )
212 /* Audio output is mono */
214 switch ( p_aout->i_format )
217 l_bytes = 1 * sizeof(u8) * p_aout->l_units;
218 aout_thread = (void *)aout_Thread_U8_Mono;
222 l_bytes = 1 * sizeof(s8) * p_aout->l_units;
223 aout_thread = (void *)aout_Thread_S8_Mono;
226 case AOUT_FMT_U16_LE:
227 case AOUT_FMT_U16_BE:
228 l_bytes = 1 * sizeof(u16) * p_aout->l_units;
229 aout_thread = (void *)aout_Thread_U16_Mono;
232 case AOUT_FMT_S16_LE:
233 case AOUT_FMT_S16_BE:
234 l_bytes = 1 * sizeof(s16) * p_aout->l_units;
235 aout_thread = (void *)aout_Thread_S16_Mono;
239 intf_ErrMsg( "aout error: unknown audio output format (%i)\n",
245 /* Audio output is stereo */
247 switch ( p_aout->i_format )
250 l_bytes = 2 * sizeof(u8) * p_aout->l_units;
251 aout_thread = (void *)aout_Thread_U8_Stereo;
255 l_bytes = 2 * sizeof(s8) * p_aout->l_units;
256 aout_thread = (void *)aout_Thread_S8_Stereo;
259 case AOUT_FMT_U16_LE:
260 case AOUT_FMT_U16_BE:
261 l_bytes = 2 * sizeof(u16) * p_aout->l_units;
262 aout_thread = (void *)aout_Thread_U16_Stereo;
265 case AOUT_FMT_S16_LE:
266 case AOUT_FMT_S16_BE:
267 l_bytes = 2 * sizeof(s16) * p_aout->l_units;
268 aout_thread = (void *)aout_Thread_S16_Stereo;
272 intf_ErrMsg("aout error: unknown audio output format (%i)\n",
279 intf_ErrMsg("aout error: unknown number of audio channels (%i)\n",
280 p_aout->i_channels );
284 /* Allocate the memory needed by the audio output buffers, and set to zero
285 * the s32 buffer's memory */
286 if ( (p_aout->buffer = malloc(l_bytes)) == NULL )
288 intf_ErrMsg("aout error: not enough memory to create the output buffer\n");
291 if ( (p_aout->s32_buffer = (s32 *)calloc(p_aout->l_units, sizeof(s32) << ( p_aout->b_stereo))) == NULL )
293 intf_ErrMsg("aout error: not enough memory to create the s32 output buffer\n");
294 free( p_aout->buffer );
298 /* Before launching the thread, we try to predict the date of the first
299 * audio unit in the first output buffer */
300 p_aout->date = mdate() - 1000000;
302 /* Launch the thread */
303 if ( vlc_thread_create( &p_aout->thread_id, "audio output", (vlc_thread_func_t)aout_thread, p_aout ) )
305 intf_ErrMsg("aout error: can't spawn audio output thread (%p)\n", p_aout);
306 free( p_aout->buffer );
307 free( p_aout->s32_buffer );
311 intf_DbgMsg("aout debug: audio output thread (%p) spawned\n", p_aout);
315 /*****************************************************************************
317 *****************************************************************************/
318 void aout_DestroyThread( aout_thread_t * p_aout, int *pi_status )
320 /* FIXME: pi_status is not handled correctly: check vout how to do!?? */
322 intf_DbgMsg("aout debug: requesting termination of audio output thread (%p)\n", p_aout);
324 /* Ask thread to kill itself and wait until it's done */
326 vlc_thread_join( p_aout->thread_id ); /* only if pi_status is NULL */
328 /* Free the allocated memory */
329 free( p_aout->buffer );
330 free( p_aout->s32_buffer );
332 /* Free the structure */
333 p_aout->p_sys_close( p_aout );
334 intf_DbgMsg("aout debug: audio device (%s) closed\n", p_aout->psz_device);
337 TrashPlugin( p_aout->aout_plugin );
343 /*****************************************************************************
345 *****************************************************************************/
346 aout_fifo_t * aout_CreateFifo( aout_thread_t * p_aout, aout_fifo_t * p_fifo )
350 /* Take the fifos lock */
351 vlc_mutex_lock( &p_aout->fifos_lock );
353 /* Looking for a free fifo structure */
354 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
356 if ( p_aout->fifo[i_fifo].i_type == AOUT_EMPTY_FIFO)
361 if ( i_fifo == AOUT_MAX_FIFOS )
363 intf_ErrMsg("aout error: no empty fifo available\n");
364 vlc_mutex_unlock( &p_aout->fifos_lock );
368 /* Initialize the new fifo structure */
369 switch ( p_aout->fifo[i_fifo].i_type = p_fifo->i_type )
371 case AOUT_INTF_MONO_FIFO:
372 case AOUT_INTF_STEREO_FIFO:
373 p_aout->fifo[i_fifo].b_die = 0;
375 p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels;
376 p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo;
377 p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate;
379 p_aout->fifo[i_fifo].buffer = p_fifo->buffer;
381 p_aout->fifo[i_fifo].l_unit = 0;
382 InitializeIncrement( &p_aout->fifo[i_fifo].unit_increment, p_fifo->l_rate, p_aout->l_rate );
383 p_aout->fifo[i_fifo].l_units = p_fifo->l_units;
386 case AOUT_ADEC_MONO_FIFO:
387 case AOUT_ADEC_STEREO_FIFO:
388 p_aout->fifo[i_fifo].b_die = 0;
390 p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels;
391 p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo;
392 p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate;
394 p_aout->fifo[i_fifo].l_frame_size = p_fifo->l_frame_size;
395 /* Allocate the memory needed to store the audio frames. As the
396 * fifo is a rotative fifo, we must be able to find out whether the
397 * fifo is full or empty, that's why we must in fact allocate memory
398 * for (AOUT_FIFO_SIZE+1) audio frames. */
399 if ( (p_aout->fifo[i_fifo].buffer = malloc( sizeof(s16)*(AOUT_FIFO_SIZE+1)*p_fifo->l_frame_size )) == NULL )
401 intf_ErrMsg("aout error: not enough memory to create the frames buffer\n");
402 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
403 vlc_mutex_unlock( &p_aout->fifos_lock );
407 /* Allocate the memory needed to store the dates of the frames */
408 if ( (p_aout->fifo[i_fifo].date = (mtime_t *)malloc( sizeof(mtime_t)*(AOUT_FIFO_SIZE+1) )) == NULL )
410 intf_ErrMsg("aout error: not enough memory to create the dates buffer\n");
411 free( p_aout->fifo[i_fifo].buffer );
412 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
413 vlc_mutex_unlock( &p_aout->fifos_lock );
417 /* Set the fifo's buffer as empty (the first frame that is to be
418 * played is also the first frame that is not to be played) */
419 p_aout->fifo[i_fifo].l_start_frame = 0;
420 /* p_aout->fifo[i_fifo].l_next_frame = 0; */
421 p_aout->fifo[i_fifo].l_end_frame = 0;
423 /* Waiting for the audio decoder to compute enough frames to work
424 * out the fifo's current rate (as soon as the decoder has decoded
425 * enough frames, the members of the fifo structure that are not
426 * initialized now will be calculated) */
427 p_aout->fifo[i_fifo].b_start_frame = 0;
428 p_aout->fifo[i_fifo].b_next_frame = 0;
432 intf_ErrMsg("aout error: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
433 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
434 vlc_mutex_unlock( &p_aout->fifos_lock );
438 /* Release the fifos lock */
439 vlc_mutex_unlock( &p_aout->fifos_lock );
441 /* Return the pointer to the fifo structure */
442 intf_DbgMsg("aout debug: audio output fifo (%p) allocated\n", &p_aout->fifo[i_fifo]);
443 return( &p_aout->fifo[i_fifo] );
446 /*****************************************************************************
448 *****************************************************************************/
449 void aout_DestroyFifo( aout_fifo_t * p_fifo )
451 intf_DbgMsg("aout debug: requesting destruction of audio output fifo (%p)\n", p_fifo);
455 /* Here are the local macros */
457 #define UPDATE_INCREMENT( increment, integer ) \
458 if ( ((increment).l_remainder += (increment).l_euclidean_remainder) >= 0 )\
460 (integer) += (increment).l_euclidean_integer + 1; \
461 (increment).l_remainder -= (increment).l_euclidean_denominator; \
465 (integer) += (increment).l_euclidean_integer; \
468 /* Following functions are local */
470 /*****************************************************************************
471 * InitializeIncrement
472 *****************************************************************************/
473 static __inline__ void InitializeIncrement( aout_increment_t * p_increment, long l_numerator, long l_denominator )
475 p_increment->l_remainder = -l_denominator;
477 p_increment->l_euclidean_integer = 0;
478 while ( l_numerator >= l_denominator )
480 p_increment->l_euclidean_integer++;
481 l_numerator -= l_denominator;
484 p_increment->l_euclidean_remainder = l_numerator;
486 p_increment->l_euclidean_denominator = l_denominator;
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 // fprintf( stderr, "aout debug: %lli (%li);\n", aout_date - p_fifo->date[p_fifo->l_start_frame], l_rate );
551 InitializeIncrement( &p_fifo->unit_increment, l_rate, p_aout->l_rate );
553 p_fifo->l_units = (((l_units - (p_fifo->l_unit -
554 (p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo)))))
555 * p_aout->l_rate) / l_rate) + 1;
557 /* We release the lock before leaving */
558 vlc_mutex_unlock( &p_fifo->data_lock );
562 void aout_Thread_S8_Mono( aout_thread_t * p_aout )
566 void aout_Thread_S8_Stereo( aout_thread_t * p_aout )
570 void aout_Thread_U8_Mono( aout_thread_t * p_aout )
573 long l_buffer, l_buffer_limit;
574 long l_units, l_bytes;
576 intf_DbgMsg("adec debug: ********aout_Thread_U8_Mono********\n");
577 intf_DbgMsg("adec debug: running audio output thread (%p) (pid == %i)\n", p_aout, getpid());
579 /* As the s32_buffer was created with calloc(), we don't have to set this
580 * memory to zero and we can immediately jump into the thread's loop */
581 while ( !p_aout->b_die )
583 vlc_mutex_lock( &p_aout->fifos_lock );
584 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
586 switch ( p_aout->fifo[i_fifo].i_type )
588 case AOUT_EMPTY_FIFO:
591 case AOUT_INTF_MONO_FIFO:
592 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
595 while ( l_buffer < (p_aout->l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
597 p_aout->s32_buffer[l_buffer++] +=
598 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
599 p_aout->s32_buffer[l_buffer++] +=
600 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
601 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
603 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
608 while ( l_buffer < (p_aout->fifo[i_fifo].l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
610 p_aout->s32_buffer[l_buffer++] +=
611 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
612 p_aout->s32_buffer[l_buffer++] +=
613 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
614 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
616 free( p_aout->fifo[i_fifo].buffer ); /* !! */
617 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
618 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
622 case AOUT_INTF_STEREO_FIFO:
623 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
626 while ( l_buffer < (p_aout->l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
628 p_aout->s32_buffer[l_buffer++] +=
629 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
630 p_aout->s32_buffer[l_buffer++] +=
631 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
632 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
634 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
639 while ( l_buffer < (p_aout->fifo[i_fifo].l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
641 p_aout->s32_buffer[l_buffer++] +=
642 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
643 p_aout->s32_buffer[l_buffer++] +=
644 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
645 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
647 free( p_aout->fifo[i_fifo].buffer ); /* !! */
648 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
649 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
653 case AOUT_ADEC_MONO_FIFO:
654 if ( p_aout->fifo[i_fifo].b_die )
656 free( p_aout->fifo[i_fifo].buffer );
657 free( p_aout->fifo[i_fifo].date );
658 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
659 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
663 l_units = p_aout->l_units;
665 while ( l_units > 0 )
667 if ( !p_aout->fifo[i_fifo].b_next_frame )
669 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
675 if ( p_aout->fifo[i_fifo].l_units > l_units )
677 l_buffer_limit = p_aout->l_units /*<< 1*/; /* p_aout->b_stereo == 1 */
678 while ( l_buffer < l_buffer_limit )
680 p_aout->s32_buffer[l_buffer++] +=
681 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
682 p_aout->s32_buffer[l_buffer++] +=
683 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
685 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
686 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
687 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
689 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
690 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
693 p_aout->fifo[i_fifo].l_units -= l_units;
698 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
699 /* p_aout->b_stereo == 1 */
700 while ( l_buffer < l_buffer_limit )
702 p_aout->s32_buffer[l_buffer++] +=
703 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
704 p_aout->s32_buffer[l_buffer++] +=
705 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
707 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
708 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
709 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
711 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
712 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
715 l_units -= p_aout->fifo[i_fifo].l_units;
717 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
718 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
719 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
720 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
722 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
723 p_aout->fifo[i_fifo].l_next_frame += 1;
724 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
725 p_aout->fifo[i_fifo].b_next_frame = 0;
730 case AOUT_ADEC_STEREO_FIFO:
731 if ( p_aout->fifo[i_fifo].b_die )
733 free( p_aout->fifo[i_fifo].buffer );
734 free( p_aout->fifo[i_fifo].date );
735 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
736 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
740 l_units = p_aout->l_units;
742 while ( l_units > 0 )
744 if ( !p_aout->fifo[i_fifo].b_next_frame )
746 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
754 if ( p_aout->fifo[i_fifo].l_units > l_units )
756 l_buffer_limit = p_aout->l_units /*<< 1*/; /* p_aout->b_stereo == 1 */
757 //fprintf(stderr,"l_buffer_limit:%d\n",l_buffer_limit);
758 while ( l_buffer < l_buffer_limit )
762 p_aout->s32_buffer[l_buffer++] +=
763 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] );
764 p_aout->s32_buffer[l_buffer++] +=
765 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] );
768 //fprintf(stderr,"1deb ");
770 p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] ) / 2;
771 p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
773 //fprintf (stderr,"1fin ");
778 //fprintf(stderr,"p_aout->s32_buffer[l_buffer] 11 : %x (%d)",p_aout->s32_buffer[l_buffer-1],p_aout->s32_buffer[l_buffer-1]);
779 fprintf(stderr,"p_aout->fifo %ld\n",COEFF*p_aout->fifo[i_fifo].l_unit);
780 fprintf(stderr,"%d - p_aout->s32b %ld\n", l_buffer, (s32) ( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] ) );
781 //fprintf(stderr,"p_aout->s32_buffer[l_buffer] 12 : %x (%d)\n",p_aout->s32_buffer[l_buffer-1],p_aout->s32_buffer[l_buffer-1]);
784 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
785 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
786 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/)) )
788 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
789 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/));
792 p_aout->fifo[i_fifo].l_units -= l_units;
798 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units /*<< 1*/);
799 //fprintf(stderr,"l_buffer_limit:%d\n",l_buffer_limit);
800 /* p_aout->b_stereo == 1 */
801 while ( l_buffer < l_buffer_limit )
805 p_aout->s32_buffer[l_buffer++] +=
806 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] );
807 p_aout->s32_buffer[l_buffer++] +=
808 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] );
811 //fprintf(stderr,"2deb ");
813 //fprintf(stderr,"793 ");
814 // !!!!!! Seg Fault !!!!!!!
815 //fprintf(stderr,"\n p->aout_buffer : %d\t%d\n",p_aout->s32_buffer[l_buffer],COEFF*p_aout->fifo[i_fifo].l_unit);
816 if( COEFF*p_aout->fifo[i_fifo].l_unit < 60000 )
818 p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] ) / 2;
819 // fprintf(stderr,"795 ");
820 p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
821 //fprintf(stderr,"797 ");
824 //fprintf(stderr,"2fin ");
829 //fprintf(stderr,"p_aout->s32_buffer[l_buffer] 21 : %x (%d)",p_aout->s32_buffer[l_buffer-1],p_aout->s32_buffer[l_buffer-1]);
830 fprintf(stderr,"p_aout->fifo %ld\n",COEFF*p_aout->fifo[i_fifo].l_unit);
831 fprintf(stderr,"%d - p_aout->s32b %ld\n", l_buffer, (s32) ( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] ) );
832 //fprintf(stderr,"p_aout->s32_buffer[l_buffer] 22 : %x (%d)\n",p_aout->s32_buffer[l_buffer-1],p_aout->s32_buffer[l_buffer-1]);
835 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
836 //fprintf(stderr,"807 ");
837 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
838 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/)) )
840 //fprintf(stderr,"811 ");
841 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
842 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/));
845 //fprintf(stderr,"816 ");
846 l_units -= p_aout->fifo[i_fifo].l_units;
847 //fprintf(stderr,"818 ");
848 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
849 //fprintf(stderr,"820 ");
850 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
851 //fprintf(stderr,"822 ");
852 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
853 //fprintf(stderr,"824 ");
854 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
855 //fprintf(stderr,"826 ");
856 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
857 p_aout->fifo[i_fifo].l_next_frame += 1;
858 //fprintf(stderr,"829 ");
859 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
860 //fprintf(stderr,"831 ");
861 p_aout->fifo[i_fifo].b_next_frame = 0;
863 //fprintf(stderr,"837 ");
865 //fprintf(stderr,"838 ");
866 /* !!!!!!!!!!!!! Seg Fault !!!!!!!!!!!!!!!!! */
868 //fprintf(stderr,"839 ");
872 //fprintf(stderr,"841 ");
873 intf_DbgMsg("aout debug: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
874 //fprintf(stderr,"842 ");
878 //fprintf(stderr,"843 ");
879 vlc_mutex_unlock( &p_aout->fifos_lock );
880 //fprintf(stderr,"845 ");
881 l_buffer_limit = p_aout->l_units /*<< 1*/ ; /* p_aout->b_stereo == 1 */
882 //fprintf(stderr,"\nici commence l'envoie sur sb\n");
883 for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
885 //fprintf(stderr,"3deb ");
886 //fprintf(stderr,"p_aout->s_32_buffer[l_buffer] : %x (%d)\n",p_aout->s32_buffer[l_buffer],p_aout->s32_buffer[l_buffer]);
887 ((u8 *)p_aout->buffer)[l_buffer] = (u8)( (p_aout->s32_buffer[/*2 **/ l_buffer] / 256) + 128 );
888 //fprintf(stderr,"p_aout->buffer[l_buffer] : %x (%d)\n", ((u8 *)p_aout->buffer)[l_buffer], ((u8 *)p_aout->buffer)[l_buffer] );
889 p_aout->s32_buffer[/*2 **/ l_buffer] = 0;
890 // p_aout->s32_buffer[2 * l_buffer + 1] = 0;
891 //fprintf(stderr,"3fin ");
893 l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
894 p_aout->date = mdate() + ((((mtime_t)(l_bytes / 2 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 2 */
895 p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
896 if ( l_bytes > (l_buffer_limit * sizeof(u8)) )
898 msleep( p_aout->l_msleep );
902 vlc_mutex_lock( &p_aout->fifos_lock );
903 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
905 switch ( p_aout->fifo[i_fifo].i_type )
907 case AOUT_EMPTY_FIFO:
910 case AOUT_INTF_MONO_FIFO:
911 case AOUT_INTF_STEREO_FIFO:
912 free( p_aout->fifo[i_fifo].buffer ); /* !! */
913 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
914 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
917 case AOUT_ADEC_MONO_FIFO:
918 case AOUT_ADEC_STEREO_FIFO:
919 free( p_aout->fifo[i_fifo].buffer );
920 free( p_aout->fifo[i_fifo].date );
921 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
922 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
929 vlc_mutex_unlock( &p_aout->fifos_lock );
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 ) * \
1183 ((float) p_aout->vol / 100 ) );
1184 p_aout->s32_buffer[l_buffer] = 0;
1186 l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
1187 p_aout->date = mdate() + ((((mtime_t)(l_bytes / 2 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 2 */
1188 p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
1189 if ( l_bytes > (l_buffer_limit * sizeof(u8)) )
1191 msleep( p_aout->l_msleep );
1195 vlc_mutex_lock( &p_aout->fifos_lock );
1196 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1198 switch ( p_aout->fifo[i_fifo].i_type )
1200 case AOUT_EMPTY_FIFO:
1203 case AOUT_INTF_MONO_FIFO:
1204 case AOUT_INTF_STEREO_FIFO:
1205 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1206 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1207 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1210 case AOUT_ADEC_MONO_FIFO:
1211 case AOUT_ADEC_STEREO_FIFO:
1212 free( p_aout->fifo[i_fifo].buffer );
1213 free( p_aout->fifo[i_fifo].date );
1214 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1215 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1222 vlc_mutex_unlock( &p_aout->fifos_lock );
1226 void aout_Thread_S16_Mono( aout_thread_t * p_aout )
1230 void aout_Thread_S16_Stereo( aout_thread_t * p_aout )
1233 long l_buffer, l_buffer_limit;
1234 long l_units, l_bytes;
1236 intf_DbgMsg("adec debug: ********aout_Thread_S16_Stereo********\n");
1237 intf_DbgMsg("adec debug: running audio output thread (%p) (pid == %i)\n", p_aout, getpid());
1239 /* As the s32_buffer was created with calloc(), we don't have to set this
1240 * memory to zero and we can immediately jump into the thread's loop */
1241 while ( !p_aout->b_die )
1243 vlc_mutex_lock( &p_aout->fifos_lock );
1244 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1246 switch ( p_aout->fifo[i_fifo].i_type )
1248 case AOUT_EMPTY_FIFO:
1251 case AOUT_INTF_MONO_FIFO:
1252 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
1255 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
1257 p_aout->s32_buffer[l_buffer++] +=
1258 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1259 p_aout->s32_buffer[l_buffer++] +=
1260 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1261 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1263 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
1268 while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
1270 p_aout->s32_buffer[l_buffer++] +=
1271 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1272 p_aout->s32_buffer[l_buffer++] +=
1273 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1274 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1276 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1277 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1278 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
1282 case AOUT_INTF_STEREO_FIFO:
1283 if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
1286 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
1288 p_aout->s32_buffer[l_buffer++] +=
1289 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1290 p_aout->s32_buffer[l_buffer++] +=
1291 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1292 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1294 p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
1299 while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
1301 p_aout->s32_buffer[l_buffer++] +=
1302 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1303 p_aout->s32_buffer[l_buffer++] +=
1304 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1305 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1307 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1308 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1309 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
1313 case AOUT_ADEC_MONO_FIFO:
1314 if ( p_aout->fifo[i_fifo].b_die )
1316 free( p_aout->fifo[i_fifo].buffer );
1317 free( p_aout->fifo[i_fifo].date );
1318 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1319 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1323 l_units = p_aout->l_units;
1325 while ( l_units > 0 )
1327 if ( !p_aout->fifo[i_fifo].b_next_frame )
1329 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1335 if ( p_aout->fifo[i_fifo].l_units > l_units )
1337 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1338 while ( l_buffer < l_buffer_limit )
1340 p_aout->s32_buffer[l_buffer++] +=
1341 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1342 p_aout->s32_buffer[l_buffer++] +=
1343 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1345 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1346 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1347 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1349 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1350 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1353 p_aout->fifo[i_fifo].l_units -= l_units;
1358 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1359 /* p_aout->b_stereo == 1 */
1360 while ( l_buffer < l_buffer_limit )
1362 p_aout->s32_buffer[l_buffer++] +=
1363 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1364 p_aout->s32_buffer[l_buffer++] +=
1365 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1367 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1368 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1369 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1371 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1372 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1375 l_units -= p_aout->fifo[i_fifo].l_units;
1377 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1378 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1379 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1380 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1382 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1383 p_aout->fifo[i_fifo].l_next_frame += 1;
1384 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1385 p_aout->fifo[i_fifo].b_next_frame = 0;
1390 case AOUT_ADEC_STEREO_FIFO:
1391 if ( p_aout->fifo[i_fifo].b_die )
1393 free( p_aout->fifo[i_fifo].buffer );
1394 free( p_aout->fifo[i_fifo].date );
1395 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1396 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1400 l_units = p_aout->l_units;
1402 while ( l_units > 0 )
1404 if ( !p_aout->fifo[i_fifo].b_next_frame )
1406 if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1412 if ( p_aout->fifo[i_fifo].l_units > l_units )
1414 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1415 while ( l_buffer < l_buffer_limit )
1417 p_aout->s32_buffer[l_buffer++] +=
1418 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1419 p_aout->s32_buffer[l_buffer++] +=
1420 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1422 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1423 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1424 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1426 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1427 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1430 p_aout->fifo[i_fifo].l_units -= l_units;
1435 l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1436 /* p_aout->b_stereo == 1 */
1437 while ( l_buffer < l_buffer_limit )
1439 p_aout->s32_buffer[l_buffer++] +=
1440 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1441 p_aout->s32_buffer[l_buffer++] +=
1442 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1444 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1445 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1446 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1448 p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1449 ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1452 l_units -= p_aout->fifo[i_fifo].l_units;
1454 vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1455 p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1456 vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1457 vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1459 /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1460 p_aout->fifo[i_fifo].l_next_frame += 1;
1461 p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1462 p_aout->fifo[i_fifo].b_next_frame = 0;
1468 intf_DbgMsg("aout debug: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
1472 vlc_mutex_unlock( &p_aout->fifos_lock );
1474 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1476 for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
1478 ((s16 *)p_aout->buffer)[l_buffer] = (s16)( ( p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS ) * \
1479 ((float) p_aout->vol / 100 ) ) ;
1480 p_aout->s32_buffer[l_buffer] = 0;
1483 l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
1484 p_aout->date = mdate() + ((((mtime_t)(l_bytes / 4)) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(s16) << (p_aout->b_stereo) == 4 */
1485 p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(s16) );
1486 if ( l_bytes > (l_buffer_limit * sizeof(s16)) )
1488 msleep( p_aout->l_msleep );
1492 vlc_mutex_lock( &p_aout->fifos_lock );
1493 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1495 switch ( p_aout->fifo[i_fifo].i_type )
1497 case AOUT_EMPTY_FIFO:
1500 case AOUT_INTF_MONO_FIFO:
1501 case AOUT_INTF_STEREO_FIFO:
1502 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1503 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1504 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1507 case AOUT_ADEC_MONO_FIFO:
1508 case AOUT_ADEC_STEREO_FIFO:
1509 free( p_aout->fifo[i_fifo].buffer );
1510 free( p_aout->fifo[i_fifo].date );
1511 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1512 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1519 vlc_mutex_unlock( &p_aout->fifos_lock );
1522 void aout_Thread_U16_Mono( aout_thread_t * p_aout )
1526 void aout_Thread_U16_Stereo( aout_thread_t * p_aout )