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