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