]> git.sesse.net Git - vlc/blob - src/audio_output/audio_output.c
Bon, puisque �a semble commiter sous BeOS, je commite.
[vlc] / src / audio_output / audio_output.c
1 /*****************************************************************************
2  * audio_output.c : audio output thread
3  *****************************************************************************
4  * Copyright (C) 1999, 2000 VideoLAN
5  *
6  * Authors:
7  *
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.
12  * 
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.
17  *
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  *****************************************************************************/
22
23 /* TODO:
24  *
25  * - Passer un certain nombre de "fonctions" (genre add_samples) en macro ou
26  *   inline
27  * - Faire les optimisations dans les fonctions threads :
28  *   = Stocker les "petits calculs" dans des variables au lieu de les refaire
29  *     à chaque boucle
30  *   = Utiliser des tables pour les gros calculs
31  * - Faire une structure différente pour intf/adec fifo
32  *
33  */
34
35 /*****************************************************************************
36  * Preamble
37  *****************************************************************************/
38 #include "defs.h"
39
40 #include <unistd.h>                                              /* getpid() */
41
42 #include <stdio.h>                                           /* "intf_msg.h" */
43 #include <stdlib.h>                            /* calloc(), malloc(), free() */
44
45 #include "config.h"
46 #include "common.h"
47 #include "threads.h"
48 #include "mtime.h"                             /* mtime_t, mdate(), msleep() */
49 #include "plugins.h"
50
51 #include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
52
53 #include "audio_output.h"
54 #include "main.h"
55
56 /*****************************************************************************
57  * Local prototypes
58  *****************************************************************************/
59
60 static int aout_SpawnThread( aout_thread_t * p_aout );
61
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 );
73
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 );
76
77 /*****************************************************************************
78  * aout_CreateThread: initialize audio thread
79  *****************************************************************************/
80 aout_thread_t *aout_CreateThread( int *pi_status )
81 {
82     aout_thread_t * p_aout;                             /* thread descriptor */
83     typedef void    ( aout_getplugin_t ) ( aout_thread_t * p_aout );
84     int             i_index;
85 #if 0
86     int             i_status;                                 /* thread status */
87 #endif
88
89     /* Allocate descriptor */
90     p_aout = (aout_thread_t *) malloc( sizeof(aout_thread_t) );
91     if( p_aout == NULL )
92     {
93         return( NULL );
94     }
95
96     /* Get a suitable audio plugin */
97     for( i_index = 0 ; i_index < p_main->p_bank->i_plugin_count ; i_index++ )
98     {
99         /* If there's a plugin in p_info ... */
100         if( p_main->p_bank->p_info[ i_index ] != NULL )
101         {
102             /* ... and if this plugin provides the functions we want ... */
103             if( p_main->p_bank->p_info[ i_index ]->aout_GetPlugin != NULL )
104             {
105                 /* ... then get these functions */
106                 ( (aout_getplugin_t *)
107                   p_main->p_bank->p_info[ i_index ]->aout_GetPlugin )( p_aout );
108             }
109         }
110     }
111
112     /*
113      * Initialize audio device
114      */
115     if ( p_aout->p_sys_open( p_aout ) )
116     {
117         free( p_aout );
118         return( NULL );
119     }
120
121     p_aout->b_stereo = ( p_aout->i_channels == 2 ) ? 1 : 0; /* FIXME: only works
122                                                    for i_channels == 1 or 2 ??*/
123
124     if ( p_aout->p_sys_reset( p_aout ) )
125     {
126         p_aout->p_sys_close( p_aout );
127         free( p_aout );
128         return( NULL );
129     }
130     if ( p_aout->p_sys_setformat( p_aout ) )
131     {
132         p_aout->p_sys_close( p_aout );
133         free( p_aout );
134         return( NULL );
135     }
136     if ( p_aout->p_sys_setchannels( p_aout ) )
137     {
138         p_aout->p_sys_close( p_aout );
139         free( p_aout );
140         return( NULL );
141     }
142     if ( p_aout->p_sys_setrate( p_aout ) )
143     {
144         p_aout->p_sys_close( p_aout );
145         free( p_aout );
146         return( NULL );
147     }
148
149     /* Initialize the vomue level */
150     p_aout->vol = VOL;
151     
152     /* FIXME: maybe it would be cleaner to change SpawnThread prototype
153      * see vout to handle status correctly ?? however, it is not critical since
154      * this thread is only called in main and all calls are blocking */
155     if( aout_SpawnThread( p_aout ) )
156     {
157         p_aout->p_sys_close( p_aout );
158         free( p_aout );
159         return( NULL );
160     }
161
162     return( p_aout );
163 }
164
165 /*****************************************************************************
166  * aout_SpawnThread
167  *****************************************************************************/
168 static int aout_SpawnThread( aout_thread_t * p_aout )
169 {
170     int             i_fifo;
171     long            l_bytes;
172     void *          aout_thread = NULL;
173
174     intf_DbgMsg("aout debug: spawning audio output thread (%p)\n", p_aout);
175
176     /* We want the audio output thread to live */
177     p_aout->b_die = 0;
178     p_aout->b_active = 1;
179
180     /* Initialize the fifos lock */
181     vlc_mutex_init( &p_aout->fifos_lock );
182     /* Initialize audio fifos : set all fifos as empty and initialize locks */
183     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
184     {
185         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
186         vlc_mutex_init( &p_aout->fifo[i_fifo].data_lock );
187         vlc_cond_init( &p_aout->fifo[i_fifo].data_wait );
188     }
189
190     /* Compute the size (in audio units) of the audio output buffer. Although
191      * AOUT_BUFFER_DURATION is given in microseconds, the output rate is given
192      * in Hz, that's why we need to divide by 10^6 microseconds (1 second) */
193     p_aout->l_units = (long)( ((s64)p_aout->l_rate * AOUT_BUFFER_DURATION) / 1000000 );
194     p_aout->l_msleep = (long)( ((s64)p_aout->l_units * 1000000) / (s64)p_aout->l_rate );
195
196     /* Make aout_thread point to the right thread function, and compute the
197      * byte size of the audio output buffer */
198     switch ( p_aout->i_channels )
199     {
200         /* Audio output is mono */
201         case 1:
202             switch ( p_aout->i_format )
203             {
204                 case AOUT_FMT_U8:
205                     l_bytes = 1 * sizeof(u8) * p_aout->l_units;
206                     aout_thread = (void *)aout_Thread_U8_Mono;
207                     break;
208
209                 case AOUT_FMT_S8:
210                     l_bytes = 1 * sizeof(s8) * p_aout->l_units;
211                     aout_thread = (void *)aout_Thread_S8_Mono;
212                     break;
213
214                 case AOUT_FMT_U16_LE:
215                 case AOUT_FMT_U16_BE:
216                     l_bytes = 1 * sizeof(u16) * p_aout->l_units;
217                     aout_thread = (void *)aout_Thread_U16_Mono;
218                     break;
219
220                 case AOUT_FMT_S16_LE:
221                 case AOUT_FMT_S16_BE:
222                     l_bytes = 1 * sizeof(s16) * p_aout->l_units;
223                     aout_thread = (void *)aout_Thread_S16_Mono;
224                     break;
225
226                 default:
227                     intf_ErrMsg( "aout error: unknown audio output format (%i)\n",
228                                  p_aout->i_format );
229                     return( -1 );
230             }
231             break;
232
233         /* Audio output is stereo */
234         case 2:
235             switch ( p_aout->i_format )
236             {
237                 case AOUT_FMT_U8:
238                     l_bytes = 2 * sizeof(u8) * p_aout->l_units;
239                     aout_thread = (void *)aout_Thread_U8_Stereo;
240                     break;
241
242                 case AOUT_FMT_S8:
243                     l_bytes = 2 * sizeof(s8) * p_aout->l_units;
244                     aout_thread = (void *)aout_Thread_S8_Stereo;
245                     break;
246
247                 case AOUT_FMT_U16_LE:
248                 case AOUT_FMT_U16_BE:
249                     l_bytes = 2 * sizeof(u16) * p_aout->l_units;
250                     aout_thread = (void *)aout_Thread_U16_Stereo;
251                     break;
252
253                 case AOUT_FMT_S16_LE:
254                 case AOUT_FMT_S16_BE:
255                     l_bytes = 2 * sizeof(s16) * p_aout->l_units;
256                     aout_thread = (void *)aout_Thread_S16_Stereo;
257                     break;
258
259                 default:
260                     intf_ErrMsg("aout error: unknown audio output format (%i)\n",
261                         p_aout->i_format);
262                     return( -1 );
263             }
264             break;
265
266         default:
267             intf_ErrMsg("aout error: unknown number of audio channels (%i)\n",
268                 p_aout->i_channels );
269             return( -1 );
270     }
271
272     /* Allocate the memory needed by the audio output buffers, and set to zero
273      * the s32 buffer's memory */
274     if ( (p_aout->buffer = malloc(l_bytes)) == NULL )
275     {
276         intf_ErrMsg("aout error: not enough memory to create the output buffer\n");
277         return( -1 );
278     }
279     if ( (p_aout->s32_buffer = (s32 *)calloc(p_aout->l_units, sizeof(s32) << ( p_aout->b_stereo))) == NULL )
280     {
281         intf_ErrMsg("aout error: not enough memory to create the s32 output buffer\n");
282         free( p_aout->buffer );
283         return( -1 );
284     }
285
286     /* Before launching the thread, we try to predict the date of the first
287      * audio unit in the first output buffer */
288     p_aout->date = mdate() - 1000000;
289
290     /* Launch the thread */
291     if ( vlc_thread_create( &p_aout->thread_id, "audio output", (vlc_thread_func_t)aout_thread, p_aout ) )
292     {
293         intf_ErrMsg("aout error: can't spawn audio output thread (%p)\n", p_aout);
294         free( p_aout->buffer );
295         free( p_aout->s32_buffer );
296         return( -1 );
297     }
298
299     intf_DbgMsg("aout debug: audio output thread (%p) spawned\n", p_aout);
300     return( 0 );
301 }
302
303 /*****************************************************************************
304  * aout_DestroyThread
305  *****************************************************************************/
306 void aout_DestroyThread( aout_thread_t * p_aout, int *pi_status )
307 {
308     /* FIXME: pi_status is not handled correctly: check vout how to do!?? */
309
310     intf_DbgMsg("aout debug: requesting termination of audio output thread (%p)\n", p_aout);
311
312     /* Ask thread to kill itself and wait until it's done */
313     p_aout->b_die = 1;
314     vlc_thread_join( p_aout->thread_id ); /* only if pi_status is NULL */
315
316     /* Free the allocated memory */
317     free( p_aout->buffer );
318     free( p_aout->s32_buffer );
319
320     /* Free the structure */
321     p_aout->p_sys_close( p_aout );
322     intf_DbgMsg("aout debug: audio device (%s) closed\n", p_aout->psz_device);
323
324     /* Free structure */
325     free( p_aout );
326 }
327
328 /*****************************************************************************
329  * aout_CreateFifo
330  *****************************************************************************/
331 aout_fifo_t * aout_CreateFifo( aout_thread_t * p_aout, aout_fifo_t * p_fifo )
332 {
333     int i_fifo;
334
335     /* Take the fifos lock */
336     vlc_mutex_lock( &p_aout->fifos_lock );
337
338     /* Looking for a free fifo structure */
339     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
340     {
341         if ( p_aout->fifo[i_fifo].i_type == AOUT_EMPTY_FIFO)
342         {
343             break;
344         }
345     }
346     if ( i_fifo == AOUT_MAX_FIFOS )
347     {
348         intf_ErrMsg("aout error: no empty fifo available\n");
349         vlc_mutex_unlock( &p_aout->fifos_lock );
350         return( NULL );
351     }
352
353     /* Initialize the new fifo structure */
354     switch ( p_aout->fifo[i_fifo].i_type = p_fifo->i_type )
355     {
356         case AOUT_INTF_MONO_FIFO:
357         case AOUT_INTF_STEREO_FIFO:
358             p_aout->fifo[i_fifo].b_die = 0;
359
360             p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels;
361             p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo;
362             p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate;
363
364             p_aout->fifo[i_fifo].buffer = p_fifo->buffer;
365
366             p_aout->fifo[i_fifo].l_unit = 0;
367             InitializeIncrement( &p_aout->fifo[i_fifo].unit_increment, p_fifo->l_rate, p_aout->l_rate );
368             p_aout->fifo[i_fifo].l_units = p_fifo->l_units;
369             break;
370
371         case AOUT_ADEC_MONO_FIFO:
372         case AOUT_ADEC_STEREO_FIFO:
373             p_aout->fifo[i_fifo].b_die = 0;
374
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;
378
379             p_aout->fifo[i_fifo].l_frame_size = p_fifo->l_frame_size;
380             /* Allocate the memory needed to store the audio frames. As the
381              * fifo is a rotative fifo, we must be able to find out whether the
382              * fifo is full or empty, that's why we must in fact allocate memory
383              * for (AOUT_FIFO_SIZE+1) audio frames. */
384             if ( (p_aout->fifo[i_fifo].buffer = malloc( sizeof(s16)*(AOUT_FIFO_SIZE+1)*p_fifo->l_frame_size )) == NULL )
385             {
386                 intf_ErrMsg("aout error: not enough memory to create the frames buffer\n");
387                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
388                 vlc_mutex_unlock( &p_aout->fifos_lock );
389                 return( NULL );
390             }
391
392             /* Allocate the memory needed to store the dates of the frames */
393             if ( (p_aout->fifo[i_fifo].date = (mtime_t *)malloc( sizeof(mtime_t)*(AOUT_FIFO_SIZE+1) )) == NULL )
394             {
395                 intf_ErrMsg("aout error: not enough memory to create the dates buffer\n");
396                 free( p_aout->fifo[i_fifo].buffer );
397                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
398                 vlc_mutex_unlock( &p_aout->fifos_lock );
399                 return( NULL );
400             }
401
402             /* Set the fifo's buffer as empty (the first frame that is to be
403              * played is also the first frame that is not to be played) */
404             p_aout->fifo[i_fifo].l_start_frame = 0;
405             /* p_aout->fifo[i_fifo].l_next_frame = 0; */
406             p_aout->fifo[i_fifo].l_end_frame = 0;
407
408             /* Waiting for the audio decoder to compute enough frames to work
409              * out the fifo's current rate (as soon as the decoder has decoded
410              * enough frames, the members of the fifo structure that are not
411              * initialized now will be calculated) */
412             p_aout->fifo[i_fifo].b_start_frame = 0;
413             p_aout->fifo[i_fifo].b_next_frame = 0;
414             break;
415
416         default:
417             intf_ErrMsg("aout error: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
418             p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
419             vlc_mutex_unlock( &p_aout->fifos_lock );
420             return( NULL );
421     }
422
423     /* Release the fifos lock */
424     vlc_mutex_unlock( &p_aout->fifos_lock );
425
426     /* Return the pointer to the fifo structure */
427     intf_DbgMsg("aout debug: audio output fifo (%p) allocated\n", &p_aout->fifo[i_fifo]);
428     return( &p_aout->fifo[i_fifo] );
429 }
430
431 /*****************************************************************************
432  * aout_DestroyFifo
433  *****************************************************************************/
434 void aout_DestroyFifo( aout_fifo_t * p_fifo )
435 {
436     intf_DbgMsg("aout debug: requesting destruction of audio output fifo (%p)\n", p_fifo);
437     p_fifo->b_die = 1;
438 }
439
440 /* Here are the local macros */
441
442 #define UPDATE_INCREMENT( increment, integer ) \
443     if ( ((increment).l_remainder += (increment).l_euclidean_remainder) >= 0 )\
444     { \
445         (integer) += (increment).l_euclidean_integer + 1; \
446         (increment).l_remainder -= (increment).l_euclidean_denominator; \
447     } \
448     else \
449     { \
450         (integer) += (increment).l_euclidean_integer; \
451     }
452
453 /* Following functions are local */
454
455 /*****************************************************************************
456  * InitializeIncrement
457  *****************************************************************************/
458 static __inline__ void InitializeIncrement( aout_increment_t * p_increment, long l_numerator, long l_denominator )
459 {
460     p_increment->l_remainder = -l_denominator;
461
462     p_increment->l_euclidean_integer = 0;
463     while ( l_numerator >= l_denominator )
464     {
465         p_increment->l_euclidean_integer++;
466         l_numerator -= l_denominator;
467     }
468
469     p_increment->l_euclidean_remainder = l_numerator;
470
471     p_increment->l_euclidean_denominator = l_denominator;
472 }
473
474 /*****************************************************************************
475  * NextFrame
476  *****************************************************************************/
477 static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo, mtime_t aout_date )
478 {
479     long l_units, l_rate;
480
481     /* We take the lock */
482     vlc_mutex_lock( &p_fifo->data_lock );
483
484     /* Are we looking for a dated start frame ? */
485     if ( !p_fifo->b_start_frame )
486     {
487         while ( p_fifo->l_start_frame != p_fifo->l_end_frame )
488         {
489             if ( p_fifo->date[p_fifo->l_start_frame] != LAST_MDATE )
490             {
491                 p_fifo->b_start_frame = 1;
492                 p_fifo->l_next_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE;
493                 p_fifo->l_unit = p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo));
494                 break;
495             }
496             p_fifo->l_start_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE;
497         }
498
499         if ( p_fifo->l_start_frame == p_fifo->l_end_frame )
500         {
501             vlc_mutex_unlock( &p_fifo->data_lock );
502             return( -1 );
503         }
504     }
505
506     /* We are looking for the next dated frame */
507     /* FIXME : is the output fifo full ?? */
508     while ( !p_fifo->b_next_frame )
509     {
510         while ( p_fifo->l_next_frame != p_fifo->l_end_frame )
511         {
512             if ( p_fifo->date[p_fifo->l_next_frame] != LAST_MDATE )
513             {
514                 p_fifo->b_next_frame = 1;
515                 break;
516             }
517             p_fifo->l_next_frame = (p_fifo->l_next_frame + 1) & AOUT_FIFO_SIZE;
518         }
519
520         while ( p_fifo->l_next_frame == p_fifo->l_end_frame )
521         {
522             vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
523             if ( p_fifo->b_die )
524             {
525                 vlc_mutex_unlock( &p_fifo->data_lock );
526                 return( -1 );
527             }
528         }
529     }
530
531     l_units = ((p_fifo->l_next_frame - p_fifo->l_start_frame) & AOUT_FIFO_SIZE) * (p_fifo->l_frame_size >> (p_fifo->b_stereo));
532
533     l_rate = p_fifo->l_rate + ((aout_date - p_fifo->date[p_fifo->l_start_frame]) / 256);
534 //    intf_DbgMsg( "aout debug: %lli (%li);\n", aout_date - p_fifo->date[p_fifo->l_start_frame], l_rate );
535
536     InitializeIncrement( &p_fifo->unit_increment, l_rate, p_aout->l_rate );
537
538     p_fifo->l_units = (((l_units - (p_fifo->l_unit -
539         (p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo)))))
540         * p_aout->l_rate) / l_rate) + 1;
541
542     /* We release the lock before leaving */
543     vlc_mutex_unlock( &p_fifo->data_lock );
544     return( 0 );
545 }
546
547 void aout_Thread_S8_Mono( aout_thread_t * p_aout )
548 {
549 }
550
551 void aout_Thread_S8_Stereo( aout_thread_t * p_aout )
552 {
553 }
554
555 void aout_Thread_U8_Mono( aout_thread_t * p_aout )
556 {
557     int i_fifo;
558     long l_buffer, l_buffer_limit;
559     long l_units, l_bytes;
560
561     intf_DbgMsg("adec debug: ********aout_Thread_U8_Mono********\n");
562     intf_DbgMsg("adec debug: running audio output thread (%p) (pid == %i)\n", p_aout, getpid());
563
564     /* As the s32_buffer was created with calloc(), we don't have to set this
565      * memory to zero and we can immediately jump into the thread's loop */
566     while ( !p_aout->b_die )
567     {
568         vlc_mutex_lock( &p_aout->fifos_lock );
569         for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
570         {
571             switch ( p_aout->fifo[i_fifo].i_type )
572             {
573                 case AOUT_EMPTY_FIFO:
574                     break;
575
576                 case AOUT_INTF_MONO_FIFO:
577                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
578                     {
579                         l_buffer = 0;
580                         while ( l_buffer < (p_aout->l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
581                         {
582                             p_aout->s32_buffer[l_buffer++] +=
583                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
584                             p_aout->s32_buffer[l_buffer++] +=
585                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
586                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
587                         }
588                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
589                     }
590                     else
591                     {
592                         l_buffer = 0;
593                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
594                         {
595                             p_aout->s32_buffer[l_buffer++] +=
596                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
597                             p_aout->s32_buffer[l_buffer++] +=
598                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
599                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
600                         }
601                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
602                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
603                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
604                     }
605                     break;
606
607                 case AOUT_INTF_STEREO_FIFO:
608                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
609                     {
610                         l_buffer = 0;
611                         while ( l_buffer < (p_aout->l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
612                         {
613                             p_aout->s32_buffer[l_buffer++] +=
614                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
615                             p_aout->s32_buffer[l_buffer++] +=
616                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
617                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
618                         }
619                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
620                     }
621                     else
622                     {
623                         l_buffer = 0;
624                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
625                         {
626                             p_aout->s32_buffer[l_buffer++] +=
627                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
628                             p_aout->s32_buffer[l_buffer++] +=
629                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
630                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
631                         }
632                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
633                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
634                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
635                     }
636                     break;
637
638                 case AOUT_ADEC_MONO_FIFO:
639                     if ( p_aout->fifo[i_fifo].b_die )
640                     {
641                         free( p_aout->fifo[i_fifo].buffer );
642                         free( p_aout->fifo[i_fifo].date );
643                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
644                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
645                         continue;
646                     }
647
648                     l_units = p_aout->l_units;
649                     l_buffer = 0;
650                     while ( l_units > 0 )
651                     {
652                         if ( !p_aout->fifo[i_fifo].b_next_frame )
653                         {
654                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
655                             {
656                                 break;
657                             }
658                         }
659
660                         if ( p_aout->fifo[i_fifo].l_units > l_units )
661                         {
662                             l_buffer_limit = p_aout->l_units /*<< 1*/; /* p_aout->b_stereo == 1 */
663                             while ( l_buffer < l_buffer_limit )
664                             {
665                                 p_aout->s32_buffer[l_buffer++] +=
666                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
667                                 p_aout->s32_buffer[l_buffer++] +=
668                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
669
670                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
671                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
672                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
673                                 {
674                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
675                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
676                                 }
677                             }
678                             p_aout->fifo[i_fifo].l_units -= l_units;
679                             break;
680                         }
681                         else
682                         {
683                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
684                             /* p_aout->b_stereo == 1 */
685                             while ( l_buffer < l_buffer_limit )
686                             {
687                                 p_aout->s32_buffer[l_buffer++] +=
688                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
689                                 p_aout->s32_buffer[l_buffer++] +=
690                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
691
692                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
693                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
694                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
695                                 {
696                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
697                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
698                                 }
699                             }
700                             l_units -= p_aout->fifo[i_fifo].l_units;
701
702                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
703                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
704                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
705                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
706
707                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
708                             p_aout->fifo[i_fifo].l_next_frame += 1;
709                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
710                             p_aout->fifo[i_fifo].b_next_frame = 0;
711                         }
712                     }
713                     break;
714
715                 case AOUT_ADEC_STEREO_FIFO:
716                     if ( p_aout->fifo[i_fifo].b_die )
717                     {
718                         free( p_aout->fifo[i_fifo].buffer );
719                         free( p_aout->fifo[i_fifo].date );
720                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
721                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
722                         continue;
723                     }
724
725                     l_units = p_aout->l_units;
726                     l_buffer = 0;
727                     while ( l_units > 0 )
728                     {
729                         if ( !p_aout->fifo[i_fifo].b_next_frame )
730                         {
731                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
732                             {
733                                 break;
734                             }
735                         }
736 #define SOUND 1
737 #define ADEBUG 0
738 #define COEFF 2
739                         if ( p_aout->fifo[i_fifo].l_units > l_units )
740                         {
741                             l_buffer_limit = p_aout->l_units /*<< 1*/; /* p_aout->b_stereo == 1 */
742 //intf_DbgMsg( "l_buffer_limit:%d\n",l_buffer_limit );
743                             while ( l_buffer < l_buffer_limit )
744                             {
745 #if SOUND
746
747                                 p_aout->s32_buffer[l_buffer++] +=
748                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] );
749                                 p_aout->s32_buffer[l_buffer++] +=
750                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] );
751
752 /*
753 //intf_DbgMsg( "1deb " );
754 l_buffer++;
755 p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] ) / 2;
756 p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
757 l_buffer++;
758 //intf_DbgMsg( "1fin" );
759 */
760 #endif
761
762 #if ADEBUG 
763 //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] );
764 intf_DbgMsg( "p_aout->fifo %ld\n",COEFF*p_aout->fifo[i_fifo].l_unit );
765 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] ) );
766 //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] );
767 #endif
768
769                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
770                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
771                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/)) )
772                                 {
773                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
774                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/));
775                                 }
776                             }
777                             p_aout->fifo[i_fifo].l_units -= l_units;
778                             break;
779                         }
780                         else
781                         {
782 //#if 0
783                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units /*<< 1*/);
784 //intf_DbgMsg( "l_buffer_limit:%d\n",l_buffer_limit );
785                            /* p_aout->b_stereo == 1 */
786                             while ( l_buffer < l_buffer_limit )
787                             {
788 #if SOUND
789  
790                                 p_aout->s32_buffer[l_buffer++] +=
791                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] );
792                                 p_aout->s32_buffer[l_buffer++] +=
793                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] );
794
795 /*
796 //intf_DbgMsg( "2deb " );
797 l_buffer++;
798 //intf_DbgMsg( "793 ");
799 // !!!!!! Seg Fault !!!!!!! 
800 //intf_DbgMsg( "\n p->aout_buffer : %d\t%d\n",p_aout->s32_buffer[l_buffer],COEFF*p_aout->fifo[i_fifo].l_unit );
801 if( COEFF*p_aout->fifo[i_fifo].l_unit < 60000 )
802 {
803     p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] ) / 2;
804 //    intf_DbgMsg( "795 ");
805     p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
806 //intf_DbgMsg( "797 ");
807     l_buffer++;
808 }
809 //intf_DbgMsg( "2fin " );
810 */
811 #endif
812
813 #if ADEBUG
814 //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] );
815 intf_DbgMsg( "p_aout->fifo %ld\n",COEFF*p_aout->fifo[i_fifo].l_unit );
816 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] ) );
817 //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] );
818 #endif
819
820                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
821 //intf_DbgMsg( "807 ");
822                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
823                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/)) )
824                                 {
825 //intf_DbgMsg( "811 ");
826                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
827                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/));
828                                 }
829                             }
830 //intf_DbgMsg( "816 ");
831                             l_units -= p_aout->fifo[i_fifo].l_units;
832 //intf_DbgMsg( "818 ");
833                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
834 //intf_DbgMsg( "820 ");
835                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
836 //intf_DbgMsg( "822 ");
837                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
838 //intf_DbgMsg( "824 ");
839                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
840 //intf_DbgMsg( "826 ");
841                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
842                             p_aout->fifo[i_fifo].l_next_frame += 1;
843 //intf_DbgMsg( "829 ");
844                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
845 //intf_DbgMsg( "831 ");
846                             p_aout->fifo[i_fifo].b_next_frame = 0;
847 //#endif
848 //intf_DbgMsg( "837 ");
849                         }
850 //intf_DbgMsg( "838 ");
851 /* !!!!!!!!!!!!! Seg Fault !!!!!!!!!!!!!!!!! */
852                     }
853 //intf_DbgMsg( "839 ");
854                     break;
855
856                 default:
857 //intf_DbgMsg( "841 ");
858                     intf_DbgMsg("aout debug: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
859 //intf_DbgMsg( "842 ");
860                     break;
861             }
862         }
863 //intf_DbgMsg( "843 ");
864         vlc_mutex_unlock( &p_aout->fifos_lock );
865 //intf_DbgMsg( "845 ");
866         l_buffer_limit = p_aout->l_units  /*<< 1*/ ; /* p_aout->b_stereo == 1 */
867 //intf_DbgMsg( "\nici commence l'envoi sur sb\n" );
868         for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
869         {
870 //intf_DbgMsg( "3deb ");
871 //intf_DbgMsg( "p_aout->s_32_buffer[l_buffer] : %x (%d)\n",p_aout->s32_buffer[l_buffer],p_aout->s32_buffer[l_buffer] );
872             ((u8 *)p_aout->buffer)[l_buffer] = (u8)( (p_aout->s32_buffer[/*2 **/ l_buffer] / 256) + 128 );
873 //intf_DbgMsg( "p_aout->buffer[l_buffer] : %x (%d)\n", ((u8 *)p_aout->buffer)[l_buffer], ((u8 *)p_aout->buffer)[l_buffer] );
874             p_aout->s32_buffer[/*2 **/ l_buffer] = 0;
875 //            p_aout->s32_buffer[2 * l_buffer + 1] = 0;
876 //intf_DbgMsg( "3fin ");
877         }
878         l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
879         p_aout->date = mdate() + ((((mtime_t)(l_bytes / 2 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 2 */
880         p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
881         if ( l_bytes > (l_buffer_limit * sizeof(u8)) )
882         {
883             msleep( p_aout->l_msleep );
884         }
885     }
886
887     vlc_mutex_lock( &p_aout->fifos_lock );
888     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
889     {
890         switch ( p_aout->fifo[i_fifo].i_type )
891         {
892             case AOUT_EMPTY_FIFO:
893                 break;
894
895             case AOUT_INTF_MONO_FIFO:
896             case AOUT_INTF_STEREO_FIFO:
897                 free( p_aout->fifo[i_fifo].buffer ); /* !! */
898                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
899                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
900                 break;
901
902             case AOUT_ADEC_MONO_FIFO:
903             case AOUT_ADEC_STEREO_FIFO:
904                 free( p_aout->fifo[i_fifo].buffer );
905                 free( p_aout->fifo[i_fifo].date );
906                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
907                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
908                 break;
909
910             default:
911                 break;
912         }
913     }
914     vlc_mutex_unlock( &p_aout->fifos_lock );
915
916 }
917
918 void aout_Thread_U8_Stereo( aout_thread_t * p_aout )
919 {
920     int i_fifo;
921     long l_buffer, l_buffer_limit;
922     long l_units, l_bytes;
923
924     intf_DbgMsg("adec debug: ********aout_Thread_U8_Stereo********\n");
925     intf_DbgMsg("adec debug: running audio output thread (%p) (pid == %i)\n", p_aout, getpid());
926
927     /* As the s32_buffer was created with calloc(), we don't have to set this
928      * memory to zero and we can immediately jump into the thread's loop */
929     while ( !p_aout->b_die )
930     {
931         vlc_mutex_lock( &p_aout->fifos_lock );
932         for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
933         {
934             switch ( p_aout->fifo[i_fifo].i_type )
935             {
936                 case AOUT_EMPTY_FIFO:
937                     break;
938
939                 case AOUT_INTF_MONO_FIFO:
940                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
941                     {
942                         l_buffer = 0;
943                         while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
944                         {
945                             p_aout->s32_buffer[l_buffer++] +=
946                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
947                             p_aout->s32_buffer[l_buffer++] +=
948                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
949                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
950                         }
951                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
952                     }
953                     else
954                     {
955                         l_buffer = 0;
956                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
957                         {
958                             p_aout->s32_buffer[l_buffer++] +=
959                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
960                             p_aout->s32_buffer[l_buffer++] +=
961                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
962                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
963                         }
964                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
965                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
966                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
967                     }
968                     break;
969
970                 case AOUT_INTF_STEREO_FIFO:
971                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
972                     {
973                         l_buffer = 0;
974                         while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
975                         {
976                             p_aout->s32_buffer[l_buffer++] +=
977                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
978                             p_aout->s32_buffer[l_buffer++] +=
979                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
980                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
981                         }
982                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
983                     }
984                     else
985                     {
986                         l_buffer = 0;
987                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
988                         {
989                             p_aout->s32_buffer[l_buffer++] +=
990                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
991                             p_aout->s32_buffer[l_buffer++] +=
992                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
993                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
994                         }
995                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
996                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
997                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
998                     }
999                     break;
1000
1001                 case AOUT_ADEC_MONO_FIFO:
1002                     if ( p_aout->fifo[i_fifo].b_die )
1003                     {
1004                         free( p_aout->fifo[i_fifo].buffer );
1005                         free( p_aout->fifo[i_fifo].date );
1006                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1007                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1008                         continue;
1009                     }
1010
1011                     l_units = p_aout->l_units;
1012                     l_buffer = 0;
1013                     while ( l_units > 0 )
1014                     {
1015                         if ( !p_aout->fifo[i_fifo].b_next_frame )
1016                         {
1017                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1018                             {
1019                                 break;
1020                             }
1021                         }
1022
1023                         if ( p_aout->fifo[i_fifo].l_units > l_units )
1024                         {
1025                             l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1026                             while ( l_buffer < l_buffer_limit )
1027                             {
1028                                 p_aout->s32_buffer[l_buffer++] +=
1029                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1030                                 p_aout->s32_buffer[l_buffer++] +=
1031                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1032
1033                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1034                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1035                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1036                                 {
1037                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1038                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1039                                 }
1040                             }
1041                             p_aout->fifo[i_fifo].l_units -= l_units;
1042                             break;
1043                         }
1044                         else
1045                         {
1046                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1047                             /* p_aout->b_stereo == 1 */
1048                             while ( l_buffer < l_buffer_limit )
1049                             {
1050                                 p_aout->s32_buffer[l_buffer++] +=
1051                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1052                                 p_aout->s32_buffer[l_buffer++] +=
1053                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1054
1055                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1056                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1057                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1058                                 {
1059                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1060                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1061                                 }
1062                             }
1063                             l_units -= p_aout->fifo[i_fifo].l_units;
1064
1065                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1066                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1067                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1068                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1069
1070                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1071                             p_aout->fifo[i_fifo].l_next_frame += 1;
1072                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1073                             p_aout->fifo[i_fifo].b_next_frame = 0;
1074                         }
1075                     }
1076                     break;
1077
1078                 case AOUT_ADEC_STEREO_FIFO:
1079                     if ( p_aout->fifo[i_fifo].b_die )
1080                     {
1081                         free( p_aout->fifo[i_fifo].buffer );
1082                         free( p_aout->fifo[i_fifo].date );
1083                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1084                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1085                         continue;
1086                     }
1087
1088                     l_units = p_aout->l_units;
1089                     l_buffer = 0;
1090                     while ( l_units > 0 )
1091                     {
1092                         if ( !p_aout->fifo[i_fifo].b_next_frame )
1093                         {
1094                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1095                             {
1096                                 break;
1097                             }
1098                         }
1099
1100                         if ( p_aout->fifo[i_fifo].l_units > l_units )
1101                         {
1102                             l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1103                             while ( l_buffer < l_buffer_limit )
1104                             {
1105                                 p_aout->s32_buffer[l_buffer++] +=
1106                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1107                                 p_aout->s32_buffer[l_buffer++] +=
1108                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1109
1110                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1111                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1112                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1113                                 {
1114                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1115                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1116                                 }
1117                             }
1118                             p_aout->fifo[i_fifo].l_units -= l_units;
1119                             break;
1120                         }
1121                         else
1122                         {
1123                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1124                             /* p_aout->b_stereo == 1 */
1125                             while ( l_buffer < l_buffer_limit )
1126                             {
1127                                 p_aout->s32_buffer[l_buffer++] +=
1128                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1129                                 p_aout->s32_buffer[l_buffer++] +=
1130                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1131
1132                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1133                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1134                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1135                                 {
1136                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1137                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1138                                 }
1139                             }
1140                             l_units -= p_aout->fifo[i_fifo].l_units;
1141
1142                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1143                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1144                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1145                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1146
1147                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1148                             p_aout->fifo[i_fifo].l_next_frame += 1;
1149                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1150                             p_aout->fifo[i_fifo].b_next_frame = 0;
1151                         }
1152                     }
1153                     break;
1154
1155             default:
1156                     intf_DbgMsg("aout debug: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
1157                     break;
1158             }
1159         }
1160         vlc_mutex_unlock( &p_aout->fifos_lock );
1161
1162         l_buffer_limit = p_aout->l_units  << 1 ; /* p_aout->b_stereo == 1 */
1163
1164         for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
1165         {
1166             ((u8 *)p_aout->buffer)[l_buffer] = (u8)( ( (p_aout->s32_buffer[l_buffer] / 256) + 128 ) * \
1167                                                      ((float) p_aout->vol / 100 ) );
1168             p_aout->s32_buffer[l_buffer] = 0;
1169         }
1170         l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
1171         p_aout->date = mdate() + ((((mtime_t)(l_bytes / 2 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 2 */
1172         p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
1173         if ( l_bytes > (l_buffer_limit * sizeof(u8)) )
1174         {
1175             msleep( p_aout->l_msleep );
1176         }
1177     }
1178
1179     vlc_mutex_lock( &p_aout->fifos_lock );
1180     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1181     {
1182         switch ( p_aout->fifo[i_fifo].i_type )
1183         {
1184             case AOUT_EMPTY_FIFO:
1185                 break;
1186
1187             case AOUT_INTF_MONO_FIFO:
1188             case AOUT_INTF_STEREO_FIFO:
1189                 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1190                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1191                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1192                 break;
1193
1194             case AOUT_ADEC_MONO_FIFO:
1195             case AOUT_ADEC_STEREO_FIFO:
1196                 free( p_aout->fifo[i_fifo].buffer );
1197                 free( p_aout->fifo[i_fifo].date );
1198                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1199                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1200                 break;
1201
1202             default:
1203                 break;
1204         }
1205     }
1206     vlc_mutex_unlock( &p_aout->fifos_lock );
1207
1208 }
1209
1210 void aout_Thread_S16_Mono( aout_thread_t * p_aout )
1211 {
1212 }
1213
1214 void aout_Thread_S16_Stereo( aout_thread_t * p_aout )
1215 {
1216     int i_fifo;
1217     long l_buffer, l_buffer_limit;
1218     long l_units, l_bytes;
1219
1220     intf_DbgMsg("adec debug: ********aout_Thread_S16_Stereo********\n");
1221     intf_DbgMsg("adec debug: running audio output thread (%p) (pid == %i)\n", p_aout, getpid());
1222
1223     /* As the s32_buffer was created with calloc(), we don't have to set this
1224      * memory to zero and we can immediately jump into the thread's loop */
1225     while ( !p_aout->b_die )
1226     {
1227         vlc_mutex_lock( &p_aout->fifos_lock );
1228         for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1229         {
1230             switch ( p_aout->fifo[i_fifo].i_type )
1231             {
1232                 case AOUT_EMPTY_FIFO:
1233                     break;
1234
1235                 case AOUT_INTF_MONO_FIFO:
1236                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
1237                     {
1238                         l_buffer = 0;
1239                         while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
1240                         {
1241                             p_aout->s32_buffer[l_buffer++] +=
1242                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1243                             p_aout->s32_buffer[l_buffer++] +=
1244                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1245                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1246                         }
1247                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
1248                     }
1249                     else
1250                     {
1251                         l_buffer = 0;
1252                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
1253                         {
1254                             p_aout->s32_buffer[l_buffer++] +=
1255                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1256                             p_aout->s32_buffer[l_buffer++] +=
1257                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1258                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1259                         }
1260                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
1261                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1262                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
1263                     }
1264                     break;
1265
1266                 case AOUT_INTF_STEREO_FIFO:
1267                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
1268                     {
1269                         l_buffer = 0;
1270                         while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
1271                         {
1272                             p_aout->s32_buffer[l_buffer++] +=
1273                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1274                             p_aout->s32_buffer[l_buffer++] +=
1275                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1276                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1277                         }
1278                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
1279                     }
1280                     else
1281                     {
1282                         l_buffer = 0;
1283                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */
1284                         {
1285                             p_aout->s32_buffer[l_buffer++] +=
1286                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1287                             p_aout->s32_buffer[l_buffer++] +=
1288                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1289                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1290                         }
1291                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
1292                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1293                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
1294                     }
1295                     break;
1296
1297                 case AOUT_ADEC_MONO_FIFO:
1298                     if ( p_aout->fifo[i_fifo].b_die )
1299                     {
1300                         free( p_aout->fifo[i_fifo].buffer );
1301                         free( p_aout->fifo[i_fifo].date );
1302                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1303                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1304                         continue;
1305                     }
1306
1307                     l_units = p_aout->l_units;
1308                     l_buffer = 0;
1309                     while ( l_units > 0 )
1310                     {
1311                         if ( !p_aout->fifo[i_fifo].b_next_frame )
1312                         {
1313                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1314                             {
1315                                 break;
1316                             }
1317                         }
1318
1319                         if ( p_aout->fifo[i_fifo].l_units > l_units )
1320                         {
1321                             l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1322                             while ( l_buffer < l_buffer_limit )
1323                             {
1324                                 p_aout->s32_buffer[l_buffer++] +=
1325                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1326                                 p_aout->s32_buffer[l_buffer++] +=
1327                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1328
1329                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1330                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1331                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1332                                 {
1333                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1334                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1335                                 }
1336                             }
1337                             p_aout->fifo[i_fifo].l_units -= l_units;
1338                             break;
1339                         }
1340                         else
1341                         {
1342                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1343                             /* p_aout->b_stereo == 1 */
1344                             while ( l_buffer < l_buffer_limit )
1345                             {
1346                                 p_aout->s32_buffer[l_buffer++] +=
1347                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1348                                 p_aout->s32_buffer[l_buffer++] +=
1349                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
1350
1351                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1352                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1353                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
1354                                 {
1355                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
1356                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
1357                                 }
1358                             }
1359                             l_units -= p_aout->fifo[i_fifo].l_units;
1360
1361                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1362                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1363                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1364                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1365
1366                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1367                             p_aout->fifo[i_fifo].l_next_frame += 1;
1368                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1369                             p_aout->fifo[i_fifo].b_next_frame = 0;
1370                         }
1371                     }
1372                     break;
1373
1374                 case AOUT_ADEC_STEREO_FIFO:
1375                     if ( p_aout->fifo[i_fifo].b_die )
1376                     {
1377                         free( p_aout->fifo[i_fifo].buffer );
1378                         free( p_aout->fifo[i_fifo].date );
1379                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1380                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1381                         continue;
1382                     }
1383
1384                     l_units = p_aout->l_units;
1385                     l_buffer = 0;
1386                     while ( l_units > 0 )
1387                     {
1388                         if ( !p_aout->fifo[i_fifo].b_next_frame )
1389                         {
1390                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
1391                             {
1392                                 break;
1393                             }
1394                         }
1395
1396                         if ( p_aout->fifo[i_fifo].l_units > l_units )
1397                         {
1398                             l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1399                             while ( l_buffer < l_buffer_limit )
1400                             {
1401                                 p_aout->s32_buffer[l_buffer++] +=
1402                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1403                                 p_aout->s32_buffer[l_buffer++] +=
1404                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1405
1406                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1407                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1408                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1409                                 {
1410                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1411                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1412                                 }
1413                             }
1414                             p_aout->fifo[i_fifo].l_units -= l_units;
1415                             break;
1416                         }
1417                         else
1418                         {
1419                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
1420                             /* p_aout->b_stereo == 1 */
1421                             while ( l_buffer < l_buffer_limit )
1422                             {
1423                                 p_aout->s32_buffer[l_buffer++] +=
1424                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
1425                                 p_aout->s32_buffer[l_buffer++] +=
1426                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
1427
1428                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
1429                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1430                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) )
1431                                 {
1432                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
1433                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1));
1434                                 }
1435                             }
1436                             l_units -= p_aout->fifo[i_fifo].l_units;
1437
1438                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
1439                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
1440                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
1441                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
1442
1443                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
1444                             p_aout->fifo[i_fifo].l_next_frame += 1;
1445                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
1446                             p_aout->fifo[i_fifo].b_next_frame = 0;
1447                         }
1448                     }
1449                     break;
1450
1451             default:
1452                     intf_DbgMsg("aout debug: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
1453                     break;
1454             }
1455         }
1456         vlc_mutex_unlock( &p_aout->fifos_lock );
1457
1458         l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
1459
1460         for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
1461         {
1462             ((s16 *)p_aout->buffer)[l_buffer] = (s16)( ( p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS ) * \
1463                                                        ((float) p_aout->vol / 100 ) ) ;
1464             p_aout->s32_buffer[l_buffer] = 0;
1465         }
1466
1467         l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
1468         p_aout->date = mdate() + ((((mtime_t)(l_bytes / 4)) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(s16) << (p_aout->b_stereo) == 4 */
1469         p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(s16) );
1470         if ( l_bytes > (l_buffer_limit * sizeof(s16)) )
1471         {
1472             msleep( p_aout->l_msleep );
1473         }
1474     }
1475
1476     vlc_mutex_lock( &p_aout->fifos_lock );
1477     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1478     {
1479         switch ( p_aout->fifo[i_fifo].i_type )
1480         {
1481             case AOUT_EMPTY_FIFO:
1482                 break;
1483
1484             case AOUT_INTF_MONO_FIFO:
1485             case AOUT_INTF_STEREO_FIFO:
1486                 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1487                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1488                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1489                 break;
1490
1491             case AOUT_ADEC_MONO_FIFO:
1492             case AOUT_ADEC_STEREO_FIFO:
1493                 free( p_aout->fifo[i_fifo].buffer );
1494                 free( p_aout->fifo[i_fifo].date );
1495                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1496                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1497                 break;
1498
1499             default:
1500                 break;
1501         }
1502     }
1503     vlc_mutex_unlock( &p_aout->fifos_lock );
1504 }
1505
1506 void aout_Thread_U16_Mono( aout_thread_t * p_aout )
1507 {
1508 }
1509
1510 void aout_Thread_U16_Stereo( aout_thread_t * p_aout )
1511 {
1512 }