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