]> git.sesse.net Git - vlc/blob - src/audio_output/audio_output.c
Modification l�g�re de la gestion du volume
[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: Michel Kaempf <maxx@via.ecp.fr>
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  * InitializeIncrement
79  *****************************************************************************/
80 static __inline__ void InitializeIncrement( aout_increment_t * p_increment, long l_numerator, long l_denominator )
81 {
82     p_increment->l_remainder = -l_denominator;
83
84     p_increment->l_euclidean_integer = 0;
85     while ( l_numerator >= l_denominator )
86     {
87         p_increment->l_euclidean_integer++;
88         l_numerator -= l_denominator;
89     }
90
91     p_increment->l_euclidean_remainder = l_numerator;
92
93     p_increment->l_euclidean_denominator = l_denominator;
94 }
95
96 /*****************************************************************************
97  * aout_CreateThread: initialize audio thread
98  *****************************************************************************/
99 aout_thread_t *aout_CreateThread( int *pi_status )
100 {
101     aout_thread_t * p_aout;                             /* thread descriptor */
102     typedef void    ( aout_getplugin_t ) ( aout_thread_t * p_aout );
103     int             i_index;
104     int             i_best_index = 0, i_best_score = 0;
105 #if 0
106     int             i_status;                               /* thread status */
107 #endif
108
109     /* Allocate descriptor */
110     p_aout = (aout_thread_t *) malloc( sizeof(aout_thread_t) );
111     if( p_aout == NULL )
112     {
113         return( NULL );
114     }
115
116     /* Get a suitable audio plugin */
117     for( i_index = 0 ; i_index < p_main->p_bank->i_plugin_count ; i_index++ )
118     {
119         /* If there's a plugin in p_info ... */
120         if( p_main->p_bank->p_info[ i_index ] != NULL )
121         {
122             /* ... and if this plugin provides the functions we want ... */
123             if( p_main->p_bank->p_info[ i_index ]->aout_GetPlugin != NULL )
124             {
125                 /* ... and if this plugin has a good score ... */
126                 if( p_main->p_bank->p_info[ i_index ]->i_score > i_best_score )
127                 {
128                     /* ... then take it */
129                     i_best_score = p_main->p_bank->p_info[ i_index ]->i_score;
130                     i_best_index = i_index;
131                 }
132             }
133         }
134     }
135
136     if( i_best_score == 0 )
137     {
138         free( p_aout );
139         return( NULL );
140     }
141
142     /* Get the plugin functions */
143     ( (aout_getplugin_t *)
144       p_main->p_bank->p_info[ i_best_index ]->aout_GetPlugin )( p_aout );
145
146     /*
147      * Initialize audio device
148      */
149     if ( p_aout->p_sys_open( p_aout ) )
150     {
151         free( p_aout );
152         return( NULL );
153     }
154
155     p_aout->b_stereo = ( p_aout->i_channels == 2 ) ? 1 : 0; /* FIXME: only works
156                                                    for i_channels == 1 or 2 ??*/
157
158     if ( p_aout->p_sys_reset( p_aout ) )
159     {
160         p_aout->p_sys_close( p_aout );
161         free( p_aout );
162         return( NULL );
163     }
164     if ( p_aout->p_sys_setformat( p_aout ) )
165     {
166         p_aout->p_sys_close( p_aout );
167         free( p_aout );
168         return( NULL );
169     }
170     if ( p_aout->p_sys_setchannels( p_aout ) )
171     {
172         p_aout->p_sys_close( p_aout );
173         free( p_aout );
174         return( NULL );
175     }
176     if ( p_aout->p_sys_setrate( p_aout ) )
177     {
178         p_aout->p_sys_close( p_aout );
179         free( p_aout );
180         return( NULL );
181     }
182
183     /* Initialize the vomue level */
184     p_aout->vol = VOL;
185     
186     /* FIXME: maybe it would be cleaner to change SpawnThread prototype
187      * see vout to handle status correctly ?? however, it is not critical since
188      * this thread is only called in main and all calls are blocking */
189     if( aout_SpawnThread( p_aout ) )
190     {
191         p_aout->p_sys_close( p_aout );
192         free( p_aout );
193         return( NULL );
194     }
195
196     return( p_aout );
197 }
198
199 /*****************************************************************************
200  * aout_SpawnThread
201  *****************************************************************************/
202 static int aout_SpawnThread( aout_thread_t * p_aout )
203 {
204     int             i_fifo;
205     long            l_bytes;
206     void *          aout_thread = NULL;
207
208     intf_DbgMsg("aout debug: spawning audio output thread (%p)\n", p_aout);
209
210     /* We want the audio output thread to live */
211     p_aout->b_die = 0;
212     p_aout->b_active = 1;
213
214     /* Initialize the fifos lock */
215     vlc_mutex_init( &p_aout->fifos_lock );
216     /* Initialize audio fifos : set all fifos as empty and initialize locks */
217     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
218     {
219         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
220         vlc_mutex_init( &p_aout->fifo[i_fifo].data_lock );
221         vlc_cond_init( &p_aout->fifo[i_fifo].data_wait );
222     }
223
224     /* Compute the size (in audio units) of the audio output buffer. Although
225      * AOUT_BUFFER_DURATION is given in microseconds, the output rate is given
226      * in Hz, that's why we need to divide by 10^6 microseconds (1 second) */
227     p_aout->l_units = (long)( ((s64)p_aout->l_rate * AOUT_BUFFER_DURATION) / 1000000 );
228     p_aout->l_msleep = (long)( ((s64)p_aout->l_units * 1000000) / (s64)p_aout->l_rate );
229
230     /* Make aout_thread point to the right thread function, and compute the
231      * byte size of the audio output buffer */
232     switch ( p_aout->i_channels )
233     {
234         /* Audio output is mono */
235         case 1:
236             switch ( p_aout->i_format )
237             {
238                 case AOUT_FMT_U8:
239                     l_bytes = 1 * sizeof(u8) * p_aout->l_units;
240                     aout_thread = (void *)aout_Thread_U8_Mono;
241                     break;
242
243                 case AOUT_FMT_S8:
244                     l_bytes = 1 * sizeof(s8) * p_aout->l_units;
245                     aout_thread = (void *)aout_Thread_S8_Mono;
246                     break;
247
248                 case AOUT_FMT_U16_LE:
249                 case AOUT_FMT_U16_BE:
250                     l_bytes = 1 * sizeof(u16) * p_aout->l_units;
251                     aout_thread = (void *)aout_Thread_U16_Mono;
252                     break;
253
254                 case AOUT_FMT_S16_LE:
255                 case AOUT_FMT_S16_BE:
256                     l_bytes = 1 * sizeof(s16) * p_aout->l_units;
257                     aout_thread = (void *)aout_Thread_S16_Mono;
258                     break;
259
260                 default:
261                     intf_ErrMsg( "aout error: unknown audio output format (%i)\n",
262                                  p_aout->i_format );
263                     return( -1 );
264             }
265             break;
266
267         /* Audio output is stereo */
268         case 2:
269             switch ( p_aout->i_format )
270             {
271                 case AOUT_FMT_U8:
272                     l_bytes = 2 * sizeof(u8) * p_aout->l_units;
273                     aout_thread = (void *)aout_Thread_U8_Stereo;
274                     break;
275
276                 case AOUT_FMT_S8:
277                     l_bytes = 2 * sizeof(s8) * p_aout->l_units;
278                     aout_thread = (void *)aout_Thread_S8_Stereo;
279                     break;
280
281                 case AOUT_FMT_U16_LE:
282                 case AOUT_FMT_U16_BE:
283                     l_bytes = 2 * sizeof(u16) * p_aout->l_units;
284                     aout_thread = (void *)aout_Thread_U16_Stereo;
285                     break;
286
287                 case AOUT_FMT_S16_LE:
288                 case AOUT_FMT_S16_BE:
289                     l_bytes = 2 * sizeof(s16) * p_aout->l_units;
290                     aout_thread = (void *)aout_Thread_S16_Stereo;
291                     break;
292
293                 default:
294                     intf_ErrMsg("aout error: unknown audio output format (%i)\n",
295                         p_aout->i_format);
296                     return( -1 );
297             }
298             break;
299
300         default:
301             intf_ErrMsg("aout error: unknown number of audio channels (%i)\n",
302                 p_aout->i_channels );
303             return( -1 );
304     }
305
306     /* Allocate the memory needed by the audio output buffers, and set to zero
307      * the s32 buffer's memory */
308     if ( (p_aout->buffer = malloc(l_bytes)) == NULL )
309     {
310         intf_ErrMsg("aout error: not enough memory to create the output buffer\n");
311         return( -1 );
312     }
313     if ( (p_aout->s32_buffer = (s32 *)calloc(p_aout->l_units, sizeof(s32) << ( p_aout->b_stereo))) == NULL )
314     {
315         intf_ErrMsg("aout error: not enough memory to create the s32 output buffer\n");
316         free( p_aout->buffer );
317         return( -1 );
318     }
319
320     /* Before launching the thread, we try to predict the date of the first
321      * audio unit in the first output buffer */
322     p_aout->date = mdate() - 1000000;
323
324     /* Launch the thread */
325     if ( vlc_thread_create( &p_aout->thread_id, "audio output", (vlc_thread_func_t)aout_thread, p_aout ) )
326     {
327         intf_ErrMsg("aout error: can't spawn audio output thread (%p)\n", p_aout);
328         free( p_aout->buffer );
329         free( p_aout->s32_buffer );
330         return( -1 );
331     }
332
333     intf_DbgMsg("aout debug: audio output thread (%p) spawned\n", p_aout);
334     return( 0 );
335 }
336
337 /*****************************************************************************
338  * aout_DestroyThread
339  *****************************************************************************/
340 void aout_DestroyThread( aout_thread_t * p_aout, int *pi_status )
341 {
342     /* FIXME: pi_status is not handled correctly: check vout how to do!?? */
343
344     intf_DbgMsg("aout debug: requesting termination of audio output thread (%p)\n", p_aout);
345
346     /* Ask thread to kill itself and wait until it's done */
347     p_aout->b_die = 1;
348     vlc_thread_join( p_aout->thread_id ); /* only if pi_status is NULL */
349
350     /* Free the allocated memory */
351     free( p_aout->buffer );
352     free( p_aout->s32_buffer );
353
354     /* Free the structure */
355     p_aout->p_sys_close( p_aout );
356     intf_DbgMsg("aout debug: audio device (%s) closed\n", p_aout->psz_device);
357
358     /* Free structure */
359     free( p_aout );
360 }
361
362 /*****************************************************************************
363  * aout_CreateFifo
364  *****************************************************************************/
365 aout_fifo_t * aout_CreateFifo( aout_thread_t * p_aout, aout_fifo_t * p_fifo )
366 {
367     int i_fifo;
368
369     /* Take the fifos lock */
370     vlc_mutex_lock( &p_aout->fifos_lock );
371
372     /* Looking for a free fifo structure */
373     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
374     {
375         if ( p_aout->fifo[i_fifo].i_type == AOUT_EMPTY_FIFO)
376         {
377             break;
378         }
379     }
380     if ( i_fifo == AOUT_MAX_FIFOS )
381     {
382         intf_ErrMsg("aout error: no empty fifo available\n");
383         vlc_mutex_unlock( &p_aout->fifos_lock );
384         return( NULL );
385     }
386
387     /* Initialize the new fifo structure */
388     switch ( p_aout->fifo[i_fifo].i_type = p_fifo->i_type )
389     {
390         case AOUT_INTF_MONO_FIFO:
391         case AOUT_INTF_STEREO_FIFO:
392             p_aout->fifo[i_fifo].b_die = 0;
393
394             p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels;
395             p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo;
396             p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate;
397
398             p_aout->fifo[i_fifo].buffer = p_fifo->buffer;
399
400             p_aout->fifo[i_fifo].l_unit = 0;
401             InitializeIncrement( &p_aout->fifo[i_fifo].unit_increment, p_fifo->l_rate, p_aout->l_rate );
402             p_aout->fifo[i_fifo].l_units = p_fifo->l_units;
403             break;
404
405         case AOUT_ADEC_MONO_FIFO:
406         case AOUT_ADEC_STEREO_FIFO:
407             p_aout->fifo[i_fifo].b_die = 0;
408
409             p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels;
410             p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo;
411             p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate;
412
413             p_aout->fifo[i_fifo].l_frame_size = p_fifo->l_frame_size;
414             /* Allocate the memory needed to store the audio frames. As the
415              * fifo is a rotative fifo, we must be able to find out whether the
416              * fifo is full or empty, that's why we must in fact allocate memory
417              * for (AOUT_FIFO_SIZE+1) audio frames. */
418             if ( (p_aout->fifo[i_fifo].buffer = malloc( sizeof(s16)*(AOUT_FIFO_SIZE+1)*p_fifo->l_frame_size )) == NULL )
419             {
420                 intf_ErrMsg("aout error: not enough memory to create the frames buffer\n");
421                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
422                 vlc_mutex_unlock( &p_aout->fifos_lock );
423                 return( NULL );
424             }
425
426             /* Allocate the memory needed to store the dates of the frames */
427             if ( (p_aout->fifo[i_fifo].date = (mtime_t *)malloc( sizeof(mtime_t)*(AOUT_FIFO_SIZE+1) )) == NULL )
428             {
429                 intf_ErrMsg("aout error: not enough memory to create the dates buffer\n");
430                 free( p_aout->fifo[i_fifo].buffer );
431                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
432                 vlc_mutex_unlock( &p_aout->fifos_lock );
433                 return( NULL );
434             }
435
436             /* Set the fifo's buffer as empty (the first frame that is to be
437              * played is also the first frame that is not to be played) */
438             p_aout->fifo[i_fifo].l_start_frame = 0;
439             /* p_aout->fifo[i_fifo].l_next_frame = 0; */
440             p_aout->fifo[i_fifo].l_end_frame = 0;
441
442             /* Waiting for the audio decoder to compute enough frames to work
443              * out the fifo's current rate (as soon as the decoder has decoded
444              * enough frames, the members of the fifo structure that are not
445              * initialized now will be calculated) */
446             p_aout->fifo[i_fifo].b_start_frame = 0;
447             p_aout->fifo[i_fifo].b_next_frame = 0;
448             break;
449
450         default:
451             intf_ErrMsg("aout error: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
452             p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO;
453             vlc_mutex_unlock( &p_aout->fifos_lock );
454             return( NULL );
455     }
456
457     /* Release the fifos lock */
458     vlc_mutex_unlock( &p_aout->fifos_lock );
459
460     /* Return the pointer to the fifo structure */
461     intf_DbgMsg("aout debug: audio output fifo (%p) allocated\n", &p_aout->fifo[i_fifo]);
462     return( &p_aout->fifo[i_fifo] );
463 }
464
465 /*****************************************************************************
466  * aout_DestroyFifo
467  *****************************************************************************/
468 void aout_DestroyFifo( aout_fifo_t * p_fifo )
469 {
470     intf_DbgMsg("aout debug: requesting destruction of audio output fifo (%p)\n", p_fifo);
471     p_fifo->b_die = 1;
472 }
473
474 /* Here are the local macros */
475
476 #define UPDATE_INCREMENT( increment, integer ) \
477     if ( ((increment).l_remainder += (increment).l_euclidean_remainder) >= 0 )\
478     { \
479         (integer) += (increment).l_euclidean_integer + 1; \
480         (increment).l_remainder -= (increment).l_euclidean_denominator; \
481     } \
482     else \
483     { \
484         (integer) += (increment).l_euclidean_integer; \
485     }
486
487 /* Following functions are local */
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 //    intf_DbgMsg( "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 # if 0
573     int i_fifo;
574     long l_buffer, l_buffer_limit;
575     long l_units, l_bytes;
576
577     intf_DbgMsg("adec debug: ********aout_Thread_U8_Mono********\n");
578     intf_DbgMsg("adec debug: running audio output thread (%p) (pid == %i)\n", p_aout, getpid());
579
580     /* As the s32_buffer was created with calloc(), we don't have to set this
581      * memory to zero and we can immediately jump into the thread's loop */
582     while ( !p_aout->b_die )
583     {
584         vlc_mutex_lock( &p_aout->fifos_lock );
585         for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
586         {
587             switch ( p_aout->fifo[i_fifo].i_type )
588             {
589                 case AOUT_EMPTY_FIFO:
590                     break;
591
592                 case AOUT_INTF_MONO_FIFO:
593                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
594                     {
595                         l_buffer = 0;
596                         while ( l_buffer < (p_aout->l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
597                         {
598                             p_aout->s32_buffer[l_buffer++] +=
599                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
600                             p_aout->s32_buffer[l_buffer++] +=
601                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
602                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
603                         }
604                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
605                     }
606                     else
607                     {
608                         l_buffer = 0;
609                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
610                         {
611                             p_aout->s32_buffer[l_buffer++] +=
612                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
613                             p_aout->s32_buffer[l_buffer++] +=
614                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
615                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
616                         }
617                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
618                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
619                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
620                     }
621                     break;
622
623                 case AOUT_INTF_STEREO_FIFO:
624                     if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units )
625                     {
626                         l_buffer = 0;
627                         while ( l_buffer < (p_aout->l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
628                         {
629                             p_aout->s32_buffer[l_buffer++] +=
630                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
631                             p_aout->s32_buffer[l_buffer++] +=
632                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
633                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
634                         }
635                         p_aout->fifo[i_fifo].l_units -= p_aout->l_units;
636                     }
637                     else
638                     {
639                         l_buffer = 0;
640                         while ( l_buffer < (p_aout->fifo[i_fifo].l_units /*<< 1*/) ) /* p_aout->b_stereo == 1 */
641                         {
642                             p_aout->s32_buffer[l_buffer++] +=
643                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] );
644                             p_aout->s32_buffer[l_buffer++] +=
645                                 (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] );
646                             UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
647                         }
648                         free( p_aout->fifo[i_fifo].buffer ); /* !! */
649                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
650                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]); /* !! */
651                     }
652                     break;
653
654                 case AOUT_ADEC_MONO_FIFO:
655                     if ( p_aout->fifo[i_fifo].b_die )
656                     {
657                         free( p_aout->fifo[i_fifo].buffer );
658                         free( p_aout->fifo[i_fifo].date );
659                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
660                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
661                         continue;
662                     }
663
664                     l_units = p_aout->l_units;
665                     l_buffer = 0;
666                     while ( l_units > 0 )
667                     {
668                         if ( !p_aout->fifo[i_fifo].b_next_frame )
669                         {
670                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
671                             {
672                                 break;
673                             }
674                         }
675
676                         if ( p_aout->fifo[i_fifo].l_units > l_units )
677                         {
678                             l_buffer_limit = p_aout->l_units /*<< 1*/; /* p_aout->b_stereo == 1 */
679                             while ( l_buffer < l_buffer_limit )
680                             {
681                                 p_aout->s32_buffer[l_buffer++] +=
682                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
683                                 p_aout->s32_buffer[l_buffer++] +=
684                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
685
686                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
687                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
688                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
689                                 {
690                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
691                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
692                                 }
693                             }
694                             p_aout->fifo[i_fifo].l_units -= l_units;
695                             break;
696                         }
697                         else
698                         {
699                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1);
700                             /* p_aout->b_stereo == 1 */
701                             while ( l_buffer < l_buffer_limit )
702                             {
703                                 p_aout->s32_buffer[l_buffer++] +=
704                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
705                                 p_aout->s32_buffer[l_buffer++] +=
706                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] );
707
708                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
709                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */
710                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) )
711                                 {
712                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */
713                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0));
714                                 }
715                             }
716                             l_units -= p_aout->fifo[i_fifo].l_units;
717
718                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
719                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
720                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
721                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
722
723                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
724                             p_aout->fifo[i_fifo].l_next_frame += 1;
725                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
726                             p_aout->fifo[i_fifo].b_next_frame = 0;
727                         }
728                     }
729                     break;
730
731                 case AOUT_ADEC_STEREO_FIFO:
732                     if ( p_aout->fifo[i_fifo].b_die )
733                     {
734                         free( p_aout->fifo[i_fifo].buffer );
735                         free( p_aout->fifo[i_fifo].date );
736                         p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
737                         intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
738                         continue;
739                     }
740
741                     l_units = p_aout->l_units;
742                     l_buffer = 0;
743                     while ( l_units > 0 )
744                     {
745                         if ( !p_aout->fifo[i_fifo].b_next_frame )
746                         {
747                             if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
748                             {
749                                 break;
750                             }
751                         }
752 #define SOUND 1
753 #define ADEBUG 0
754 #define COEFF 2
755                         if ( p_aout->fifo[i_fifo].l_units > l_units )
756                         {
757                             l_buffer_limit = p_aout->l_units /*<< 1*/; /* p_aout->b_stereo == 1 */
758 //intf_DbgMsg( "l_buffer_limit:%d\n",l_buffer_limit );
759                             while ( l_buffer < l_buffer_limit )
760                             {
761 #if SOUND
762
763                                 p_aout->s32_buffer[l_buffer++] +=
764                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] );
765                                 p_aout->s32_buffer[l_buffer++] +=
766                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] );
767
768 /*
769 //intf_DbgMsg( "1deb " );
770 l_buffer++;
771 p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] ) / 2;
772 p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
773 l_buffer++;
774 //intf_DbgMsg( "1fin" );
775 */
776 #endif
777
778 #if ADEBUG 
779 //intf_DbgMsg( "p_aout->s32_buffer[l_buffer] 11 : %x (%d)",p_aout->s32_buffer[l_buffer-1],p_aout->s32_buffer[l_buffer-1] );
780 intf_DbgMsg( "p_aout->fifo %ld\n",COEFF*p_aout->fifo[i_fifo].l_unit );
781 intf_DbgMsg( "%d - p_aout->s32b %ld\n", l_buffer, (s32) ( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] ) );
782 //intf_DbgMsg( "p_aout->s32_buffer[l_buffer] 12 : %x (%d)\n",p_aout->s32_buffer[l_buffer-1],p_aout->s32_buffer[l_buffer-1] );
783 #endif
784
785                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
786                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
787                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/)) )
788                                 {
789                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
790                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/));
791                                 }
792                             }
793                             p_aout->fifo[i_fifo].l_units -= l_units;
794                             break;
795                         }
796                         else
797                         {
798 //#if 0
799                             l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units /*<< 1*/);
800 //intf_DbgMsg( "l_buffer_limit:%d\n",l_buffer_limit );
801                            /* p_aout->b_stereo == 1 */
802                             while ( l_buffer < l_buffer_limit )
803                             {
804 #if SOUND
805  
806                                 p_aout->s32_buffer[l_buffer++] +=
807                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] );
808                                 p_aout->s32_buffer[l_buffer++] +=
809                                     (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] );
810
811 /*
812 //intf_DbgMsg( "2deb " );
813 l_buffer++;
814 //intf_DbgMsg( "793 ");
815 // !!!!!! Seg Fault !!!!!!! 
816 //intf_DbgMsg( "\n p->aout_buffer : %d\t%d\n",p_aout->s32_buffer[l_buffer],COEFF*p_aout->fifo[i_fifo].l_unit );
817 if( COEFF*p_aout->fifo[i_fifo].l_unit < 60000 )
818 {
819     p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] ) / 2;
820 //    intf_DbgMsg( "795 ");
821     p_aout->s32_buffer[l_buffer] += (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit+1] ) / 2;
822 //intf_DbgMsg( "797 ");
823     l_buffer++;
824 }
825 //intf_DbgMsg( "2fin " );
826 */
827 #endif
828
829 #if ADEBUG
830 //intf_DbgMsg( "p_aout->s32_buffer[l_buffer] 21 : %x (%d)",p_aout->s32_buffer[l_buffer-1],p_aout->s32_buffer[l_buffer-1] );
831 intf_DbgMsg( "p_aout->fifo %ld\n",COEFF*p_aout->fifo[i_fifo].l_unit );
832 intf_DbgMsg( "%d - p_aout->s32b %ld\n", l_buffer, (s32) ( ((s16 *)p_aout->fifo[i_fifo].buffer)[COEFF*p_aout->fifo[i_fifo].l_unit] ) );
833 //intf_DbgMsg( "p_aout->s32_buffer[l_buffer] 22 : %x (%d)\n",p_aout->s32_buffer[l_buffer-1],p_aout->s32_buffer[l_buffer-1] );
834 #endif
835
836                                 UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit )
837 //intf_DbgMsg( "807 ");
838                                 if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */
839                                      ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/)) )
840                                 {
841 //intf_DbgMsg( "811 ");
842                                     p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */
843                                         ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 2/*1*/));
844                                 }
845                             }
846 //intf_DbgMsg( "816 ");
847                             l_units -= p_aout->fifo[i_fifo].l_units;
848 //intf_DbgMsg( "818 ");
849                             vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
850 //intf_DbgMsg( "820 ");
851                             p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame;
852 //intf_DbgMsg( "822 ");
853                             vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait );
854 //intf_DbgMsg( "824 ");
855                             vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
856 //intf_DbgMsg( "826 ");
857                             /* p_aout->fifo[i_fifo].b_start_frame = 1; */
858                             p_aout->fifo[i_fifo].l_next_frame += 1;
859 //intf_DbgMsg( "829 ");
860                             p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE;
861 //intf_DbgMsg( "831 ");
862                             p_aout->fifo[i_fifo].b_next_frame = 0;
863 //#endif
864 //intf_DbgMsg( "837 ");
865                         }
866 //intf_DbgMsg( "838 ");
867 /* !!!!!!!!!!!!! Seg Fault !!!!!!!!!!!!!!!!! */
868                     }
869 //intf_DbgMsg( "839 ");
870                     break;
871
872                 default:
873 //intf_DbgMsg( "841 ");
874                     intf_DbgMsg("aout debug: unknown fifo type (%i)\n", p_aout->fifo[i_fifo].i_type);
875 //intf_DbgMsg( "842 ");
876                     break;
877             }
878         }
879 //intf_DbgMsg( "843 ");
880         vlc_mutex_unlock( &p_aout->fifos_lock );
881 //intf_DbgMsg( "845 ");
882         l_buffer_limit = p_aout->l_units  /*<< 1*/ ; /* p_aout->b_stereo == 1 */
883 //intf_DbgMsg( "\nici commence l'envoi sur sb\n" );
884         for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
885         {
886 //intf_DbgMsg( "3deb ");
887 //intf_DbgMsg( "p_aout->s_32_buffer[l_buffer] : %x (%d)\n",p_aout->s32_buffer[l_buffer],p_aout->s32_buffer[l_buffer] );
888             ((u8 *)p_aout->buffer)[l_buffer] = (u8)( (p_aout->s32_buffer[/*2 **/ l_buffer] / 256) + 128 );
889 //intf_DbgMsg( "p_aout->buffer[l_buffer] : %x (%d)\n", ((u8 *)p_aout->buffer)[l_buffer], ((u8 *)p_aout->buffer)[l_buffer] );
890             p_aout->s32_buffer[/*2 **/ l_buffer] = 0;
891 //            p_aout->s32_buffer[2 * l_buffer + 1] = 0;
892 //intf_DbgMsg( "3fin ");
893         }
894         l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
895         p_aout->date = mdate() + ((((mtime_t)(l_bytes / 2 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 2 */
896         p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
897         if ( l_bytes > (l_buffer_limit * sizeof(u8)) )
898         {
899             msleep( p_aout->l_msleep );
900         }
901     }
902
903     vlc_mutex_lock( &p_aout->fifos_lock );
904     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
905     {
906         switch ( p_aout->fifo[i_fifo].i_type )
907         {
908             case AOUT_EMPTY_FIFO:
909                 break;
910
911             case AOUT_INTF_MONO_FIFO:
912             case AOUT_INTF_STEREO_FIFO:
913                 free( p_aout->fifo[i_fifo].buffer ); /* !! */
914                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
915                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
916                 break;
917
918             case AOUT_ADEC_MONO_FIFO:
919             case AOUT_ADEC_STEREO_FIFO:
920                 free( p_aout->fifo[i_fifo].buffer );
921                 free( p_aout->fifo[i_fifo].date );
922                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
923                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
924                 break;
925
926             default:
927                 break;
928         }
929     }
930     vlc_mutex_unlock( &p_aout->fifos_lock );
931 #endif
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 ) * p_aout->vol / 256 );
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 ) * p_aout->vol / 256 ) ;
1478             p_aout->s32_buffer[l_buffer] = 0;
1479         }
1480
1481         l_bytes = p_aout->p_sys_getbufinfo( p_aout, l_buffer_limit );
1482         p_aout->date = mdate() + ((((mtime_t)(l_bytes / 4)) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(s16) << (p_aout->b_stereo) == 4 */
1483         p_aout->p_sys_playsamples( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(s16) );
1484         if ( l_bytes > (l_buffer_limit * sizeof(s16)) )
1485         {
1486             msleep( p_aout->l_msleep );
1487         }
1488     }
1489
1490     vlc_mutex_lock( &p_aout->fifos_lock );
1491     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
1492     {
1493         switch ( p_aout->fifo[i_fifo].i_type )
1494         {
1495             case AOUT_EMPTY_FIFO:
1496                 break;
1497
1498             case AOUT_INTF_MONO_FIFO:
1499             case AOUT_INTF_STEREO_FIFO:
1500                 free( p_aout->fifo[i_fifo].buffer ); /* !! */
1501                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1502                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1503                 break;
1504
1505             case AOUT_ADEC_MONO_FIFO:
1506             case AOUT_ADEC_STEREO_FIFO:
1507                 free( p_aout->fifo[i_fifo].buffer );
1508                 free( p_aout->fifo[i_fifo].date );
1509                 p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */
1510                 intf_DbgMsg("aout debug: audio output fifo (%p) destroyed\n", &p_aout->fifo[i_fifo]);
1511                 break;
1512
1513             default:
1514                 break;
1515         }
1516     }
1517     vlc_mutex_unlock( &p_aout->fifos_lock );
1518 }
1519
1520 void aout_Thread_U16_Mono( aout_thread_t * p_aout )
1521 {
1522 }
1523
1524 void aout_Thread_U16_Stereo( aout_thread_t * p_aout )
1525 {
1526 }