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