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