]> git.sesse.net Git - vlc/blob - src/audio_output/aout_u8.c
* Split audio output into several separate files to make it easier
[vlc] / src / audio_output / aout_u8.c
1 /*****************************************************************************
2  * aout_u8.c: 8 bit unsigned audio output functions
3  *****************************************************************************
4  * Copyright (C) 1999, 2000, 2001 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 /*****************************************************************************
24  * Preamble
25  *****************************************************************************/
26 #include "defs.h"
27
28 #include <stdio.h>                                           /* "intf_msg.h" */
29 #include <stdlib.h>                            /* calloc(), malloc(), free() */
30
31 #include "config.h"
32 #include "common.h"
33 #include "threads.h"
34 #include "mtime.h"                             /* mtime_t, mdate(), msleep() */
35
36 #include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
37
38 #include "audio_output.h"
39 #include "aout_common.h"
40
41 /*****************************************************************************
42  * Local prototypes
43  *****************************************************************************/
44 static void U8MonoPlay   ( aout_thread_t * p_aout, aout_fifo_t * p_fifo );
45 static void U8StereoPlay ( aout_thread_t * p_aout, aout_fifo_t * p_fifo );
46
47 /*****************************************************************************
48  * Functions
49  *****************************************************************************/
50 void aout_U8MonoThread( aout_thread_t * p_aout )
51 {
52     int i_fifo;
53     long l_buffer, l_buffer_limit, l_bytes;
54
55     /* As the s32_buffer was created with calloc(), we don't have to set this
56      * memory to zero and we can immediately jump into the thread's loop */
57     while ( ! p_aout->b_die )
58     {
59         vlc_mutex_lock( &p_aout->fifos_lock );
60
61         for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
62         {
63             if( p_aout->fifo[i_fifo].b_die )
64             {
65                 aout_FreeFifo( &p_aout->fifo[i_fifo] );
66             }
67             else
68             {
69                 U8MonoPlay( p_aout, &p_aout->fifo[i_fifo] );
70             }
71         }
72
73         vlc_mutex_unlock( &p_aout->fifos_lock );
74
75         l_buffer_limit = p_aout->l_units; /* p_aout->b_stereo == 0 */
76
77         for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
78         {
79             ((u8 *)p_aout->buffer)[l_buffer] = (u8)( ( (p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS / 256 ) + 128 ) * p_aout->vol / 256 );
80             p_aout->s32_buffer[l_buffer] = 0;
81         }
82
83         l_bytes = p_aout->pf_getbufinfo( p_aout, l_buffer_limit );
84         p_aout->date = mdate() + ((((mtime_t)(l_bytes / 1 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 1 */
85         p_aout->pf_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
86         if ( l_bytes > (l_buffer_limit * sizeof(u8) * 2) ) /* There are 2 channels (left & right) */
87         {
88             msleep( p_aout->l_msleep );
89         }
90     }
91
92     vlc_mutex_lock( &p_aout->fifos_lock );
93
94     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
95     {
96         aout_FreeFifo( &p_aout->fifo[i_fifo] );
97     }
98
99     vlc_mutex_unlock( &p_aout->fifos_lock );
100 }
101
102 void aout_U8StereoThread( aout_thread_t * p_aout )
103 {
104     int i_fifo;
105     long l_buffer, l_buffer_limit, l_bytes;
106
107     intf_DbgMsg("adec debug: running audio output U8_S_thread (%p) (pid == %i)", p_aout, getpid());
108
109     /* As the s32_buffer was created with calloc(), we don't have to set this
110      * memory to zero and we can immediately jump into the thread's loop */
111     while ( ! p_aout->b_die )
112     {
113         vlc_mutex_lock( &p_aout->fifos_lock );
114
115         for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
116         {
117             if( p_aout->fifo[i_fifo].b_die )
118             {
119                 aout_FreeFifo( &p_aout->fifo[i_fifo] );
120             }
121             else
122             {
123                 U8StereoPlay( p_aout, &p_aout->fifo[i_fifo] );
124             }
125         }
126
127         vlc_mutex_unlock( &p_aout->fifos_lock );
128
129         l_buffer_limit = p_aout->l_units  << 1 ; /* p_aout->b_stereo == 1 */
130
131         for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
132         {
133             ((u8 *)p_aout->buffer)[l_buffer] = (u8)( ( (p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS / 256) + 128 ) * p_aout->vol / 256 );
134             p_aout->s32_buffer[l_buffer] = 0;
135         }
136         l_bytes = p_aout->pf_getbufinfo( p_aout, l_buffer_limit );
137         p_aout->date = mdate() + ((((mtime_t)(l_bytes / 2 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 2 */
138         p_aout->pf_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) );
139         if ( l_bytes > (l_buffer_limit * sizeof(u8)) )
140         {
141             msleep( p_aout->l_msleep );
142         }
143     }
144
145     vlc_mutex_lock( &p_aout->fifos_lock );
146
147     for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
148     {
149         aout_FreeFifo( &p_aout->fifo[i_fifo] );
150     }
151
152     vlc_mutex_unlock( &p_aout->fifos_lock );
153 }
154
155 /* Following functions are local */
156
157 static void U8MonoPlay( aout_thread_t * p_aout, aout_fifo_t * p_fifo )
158 {
159     long l_buffer = 0;
160     long l_buffer_limit, l_units;
161
162     switch ( p_fifo->i_type )
163     {
164     case AOUT_EMPTY_FIFO:
165
166         break;
167
168     case AOUT_INTF_MONO_FIFO:
169
170         if ( p_fifo->l_units > p_aout->l_units )
171         {
172             /* p_aout->b_stereo == 0 */
173             while ( l_buffer < (p_aout->l_units) )
174             {
175                 p_aout->s32_buffer[l_buffer++] +=
176                     (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] );
177                 p_aout->s32_buffer[l_buffer++] +=
178                     (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] );
179                 UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit )
180             }
181             p_fifo->l_units -= p_aout->l_units;
182         }
183         else
184         {
185             /* p_aout->b_stereo == 0 */
186             while ( l_buffer < (p_fifo->l_units) )
187             {
188                 p_aout->s32_buffer[l_buffer++] +=
189                     (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] );
190                 UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit )
191             }
192             free( p_fifo->buffer ); /* !! */
193             p_fifo->i_type = AOUT_EMPTY_FIFO; /* !! */
194             intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", p_fifo); /* !! */
195         }
196         break;
197
198     case AOUT_INTF_STEREO_FIFO:
199
200         if ( p_fifo->l_units > p_aout->l_units )
201         {
202             /* p_aout->b_stereo == 0 */
203             while ( l_buffer < (p_aout->l_units) )
204             {
205                 /* I mix half left - half right */
206                 p_aout->s32_buffer[l_buffer++] +=
207                     (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] ) / 2 +
208                     (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] ) / 2;
209                 UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit )
210             }
211             p_fifo->l_units -= p_aout->l_units;
212         }
213         else
214         {
215             /* p_aout->b_stereo == 0 */
216             while ( l_buffer < (p_fifo->l_units) )
217             {
218                 /* I mix half left - half right */
219                 p_aout->s32_buffer[l_buffer++] +=
220                     (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] ) / 2 +
221                     (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] ) / 2;
222                 UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit )
223             }
224             free( p_fifo->buffer ); /* !! */
225             p_fifo->i_type = AOUT_EMPTY_FIFO; /* !! */
226             intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", p_fifo); /* !! */
227         }
228         break;
229
230     case AOUT_ADEC_MONO_FIFO:
231
232         l_units = p_aout->l_units;
233
234         while ( l_units > 0 )
235         {
236             if ( !p_fifo->b_next_frame )
237             {
238                 if ( NextFrame(p_aout, p_fifo, p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
239                 {
240                     break;
241                 }
242             }
243
244             if ( p_fifo->l_units > l_units )
245             {
246                 /* p_aout->b_stereo == 0 */
247                 l_buffer_limit = p_aout->l_units;
248
249                 while ( l_buffer < l_buffer_limit )
250                 {
251                     p_aout->s32_buffer[l_buffer++] +=
252                         (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] );
253
254                     UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit )
255                     if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 0 */
256                          ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0)) )
257                     {
258                         p_fifo->l_unit -= /* p_fifo->b_stereo == 0 */
259                             ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0));
260                     }
261                 }
262                 p_fifo->l_units -= l_units;
263                 break;
264             }
265             else
266             {
267                 /* p_aout->b_stereo == 0 */
268                 l_buffer_limit = l_buffer + (p_fifo->l_units);
269
270                 while ( l_buffer < l_buffer_limit )
271                 {
272                     p_aout->s32_buffer[l_buffer++] +=
273                         (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] );
274
275                     UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit )
276                     if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 0 */
277                          ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0)) )
278                     {
279                         p_fifo->l_unit -= /* p_fifo->b_stereo == 0 */
280                             ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0));
281                     }
282                 }
283                 l_units -= p_fifo->l_units;
284
285                 vlc_mutex_lock( &p_fifo->data_lock );
286                 p_fifo->l_start_frame = p_fifo->l_next_frame;
287                 vlc_cond_signal( &p_fifo->data_wait );
288                 vlc_mutex_unlock( &p_fifo->data_lock );
289
290                 /* p_fifo->b_start_frame = 1; */
291                 p_fifo->l_next_frame += 1;
292                 p_fifo->l_next_frame &= AOUT_FIFO_SIZE;
293                 p_fifo->b_next_frame = 0;
294             }
295         }
296         break;
297
298     case AOUT_ADEC_STEREO_FIFO:
299
300         l_units = p_aout->l_units;
301
302         while ( l_units > 0 )
303         {
304             if ( !p_fifo->b_next_frame )
305             {
306                 if ( NextFrame(p_aout, p_fifo, p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
307                 {
308                     break;
309                 }
310             }
311
312             if ( p_fifo->l_units > l_units )
313             {
314                 /* p_aout->b_stereo == 0 */
315                 l_buffer_limit = p_aout->l_units;
316
317                 while ( l_buffer < l_buffer_limit )
318                 {
319                     /* I mix half left - half right */
320                     p_aout->s32_buffer[l_buffer++] +=
321                         (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] ) / 2 +
322                         (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] ) / 2;
323
324                     UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit )
325                     if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 1 */
326                          ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1)) )
327                     {
328                         p_fifo->l_unit -= /* p_fifo->b_stereo == 1 */
329                             ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1));
330                     }
331                 }
332                 p_fifo->l_units -= l_units;
333                 break;
334             }
335             else
336             {
337                 /* p_aout->b_stereo == 0 */
338                 l_buffer_limit = l_buffer + (p_fifo->l_units);
339
340                 while ( l_buffer < l_buffer_limit )
341                 {
342                     /* I mix half left - half right */
343                     p_aout->s32_buffer[l_buffer++] +=
344                         (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] ) / 2 +
345                         (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] ) / 2;
346
347                     UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit )
348                     if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 1 */
349                          ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1)) )
350                     {
351                         p_fifo->l_unit -= /* p_fifo->b_stereo == 1 */
352                             ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1));
353                     }
354                 }
355                 l_units -= p_fifo->l_units;
356
357                 vlc_mutex_lock( &p_fifo->data_lock );
358                 p_fifo->l_start_frame = p_fifo->l_next_frame;
359                 vlc_cond_signal( &p_fifo->data_wait );
360                 vlc_mutex_unlock( &p_fifo->data_lock );
361
362                 /* p_fifo->b_start_frame = 1; */
363                 p_fifo->l_next_frame += 1;
364                 p_fifo->l_next_frame &= AOUT_FIFO_SIZE;
365                 p_fifo->b_next_frame = 0;
366             }
367         }
368         break;
369
370     default:
371
372         intf_DbgMsg("aout debug: unknown fifo type (%i)", p_fifo->i_type);
373
374         break;
375     }
376 }
377
378 static void U8StereoPlay( aout_thread_t * p_aout, aout_fifo_t * p_fifo )
379 {
380     long l_buffer = 0;
381     long l_buffer_limit, l_units;
382
383     switch ( p_fifo->i_type )
384     {
385     case AOUT_EMPTY_FIFO:
386
387         break;
388
389     case AOUT_INTF_MONO_FIFO:
390
391         if ( p_fifo->l_units > p_aout->l_units )
392         {
393             while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
394             {
395                 p_aout->s32_buffer[l_buffer++] +=
396                     (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] );
397                 p_aout->s32_buffer[l_buffer++] +=
398                     (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] );
399                 UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit )
400             }
401             p_fifo->l_units -= p_aout->l_units;
402         }
403         else
404         {
405             while ( l_buffer < (p_fifo->l_units << 1) ) /* p_aout->b_stereo == 1 */
406             {
407                 p_aout->s32_buffer[l_buffer++] +=
408                     (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] );
409                 p_aout->s32_buffer[l_buffer++] +=
410                     (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] );
411                 UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit )
412             }
413             free( p_fifo->buffer ); /* !! */
414             p_fifo->i_type = AOUT_EMPTY_FIFO; /* !! */
415             intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", p_fifo); /* !! */
416         }
417         break;
418
419     case AOUT_INTF_STEREO_FIFO:
420
421         if ( p_fifo->l_units > p_aout->l_units )
422         {
423             while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
424             {
425                 p_aout->s32_buffer[l_buffer++] +=
426                     (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] );
427                 p_aout->s32_buffer[l_buffer++] +=
428                     (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] );
429                 UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit )
430             }
431             p_fifo->l_units -= p_aout->l_units;
432         }
433         else
434         {
435             while ( l_buffer < (p_fifo->l_units << 1) ) /* p_aout->b_stereo == 1 */
436             {
437                 p_aout->s32_buffer[l_buffer++] +=
438                     (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] );
439                 p_aout->s32_buffer[l_buffer++] +=
440                     (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] );
441                 UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit )
442             }
443             free( p_fifo->buffer ); /* !! */
444             p_fifo->i_type = AOUT_EMPTY_FIFO; /* !! */
445             intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", p_fifo); /* !! */
446         }
447         break;
448
449     case AOUT_ADEC_MONO_FIFO:
450
451         l_units = p_aout->l_units;
452
453         while ( l_units > 0 )
454         {
455             if ( !p_fifo->b_next_frame )
456             {
457                 if ( NextFrame(p_aout, p_fifo, p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
458                 {
459                     break;
460                 }
461             }
462
463             if ( p_fifo->l_units > l_units )
464             {
465                 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
466                 while ( l_buffer < l_buffer_limit )
467                 {
468                     p_aout->s32_buffer[l_buffer++] +=
469                         (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] );
470                     p_aout->s32_buffer[l_buffer++] +=
471                         (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] );
472
473                     UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit )
474                     if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 0 */
475                          ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0)) )
476                     {
477                         p_fifo->l_unit -= /* p_fifo->b_stereo == 0 */
478                             ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0));
479                     }
480                 }
481                 p_fifo->l_units -= l_units;
482                 break;
483             }
484             else
485             {
486                 /* p_aout->b_stereo == 1 */
487                 l_buffer_limit = l_buffer + (p_fifo->l_units << 1);
488
489                 while ( l_buffer < l_buffer_limit )
490                 {
491                     p_aout->s32_buffer[l_buffer++] +=
492                         (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] );
493                     p_aout->s32_buffer[l_buffer++] +=
494                         (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] );
495
496                     UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit )
497                     if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 0 */
498                          ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0)) )
499                     {
500                         p_fifo->l_unit -= /* p_fifo->b_stereo == 0 */
501                             ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0));
502                     }
503                 }
504                 l_units -= p_fifo->l_units;
505
506                 vlc_mutex_lock( &p_fifo->data_lock );
507                 p_fifo->l_start_frame = p_fifo->l_next_frame;
508                 vlc_cond_signal( &p_fifo->data_wait );
509                 vlc_mutex_unlock( &p_fifo->data_lock );
510
511                 /* p_fifo->b_start_frame = 1; */
512                 p_fifo->l_next_frame += 1;
513                 p_fifo->l_next_frame &= AOUT_FIFO_SIZE;
514                 p_fifo->b_next_frame = 0;
515             }
516         }
517         break;
518
519     case AOUT_ADEC_STEREO_FIFO:
520
521         l_units = p_aout->l_units;
522
523         while ( l_units > 0 )
524         {
525             if ( !p_fifo->b_next_frame )
526             {
527                 if ( NextFrame(p_aout, p_fifo, p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
528                 {
529                     break;
530                 }
531             }
532
533             if ( p_fifo->l_units > l_units )
534             {
535                 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
536                 while ( l_buffer < l_buffer_limit )
537                 {
538                     p_aout->s32_buffer[l_buffer++] +=
539                         (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] );
540                     p_aout->s32_buffer[l_buffer++] +=
541                         (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] );
542
543                     UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit )
544                     if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 1 */
545                          ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1)) )
546                     {
547                         p_fifo->l_unit -= /* p_fifo->b_stereo == 1 */
548                             ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1));
549                     }
550                 }
551                 p_fifo->l_units -= l_units;
552                 break;
553             }
554             else
555             {
556                 /* p_aout->b_stereo == 1 */
557                 l_buffer_limit = l_buffer + (p_fifo->l_units << 1);
558
559                 while ( l_buffer < l_buffer_limit )
560                 {
561                     p_aout->s32_buffer[l_buffer++] +=
562                         (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] );
563                     p_aout->s32_buffer[l_buffer++] +=
564                         (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] );
565
566                     UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit )
567                     if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 1 */
568                          ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1)) )
569                     {
570                         p_fifo->l_unit -= /* p_fifo->b_stereo == 1 */
571                             ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1));
572                     }
573                 }
574                 l_units -= p_fifo->l_units;
575
576                 vlc_mutex_lock( &p_fifo->data_lock );
577                 p_fifo->l_start_frame = p_fifo->l_next_frame;
578                 vlc_cond_signal( &p_fifo->data_wait );
579                 vlc_mutex_unlock( &p_fifo->data_lock );
580
581                 /* p_fifo->b_start_frame = 1; */
582                 p_fifo->l_next_frame += 1;
583                 p_fifo->l_next_frame &= AOUT_FIFO_SIZE;
584                 p_fifo->b_next_frame = 0;
585             }
586         }
587         break;
588
589     default:
590         intf_DbgMsg("aout debug: unknown fifo type (%i)", p_fifo->i_type);
591         break;
592     }
593 }
594