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