1 /*****************************************************************************
2 * aout_u8.c: 8 bit unsigned audio output functions
3 *****************************************************************************
4 * Copyright (C) 1999, 2000, 2001 VideoLAN
6 * Authors: Michel Kaempf <maxx@via.ecp.fr>
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.
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.
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 *****************************************************************************/
23 /*****************************************************************************
25 *****************************************************************************/
28 #include <stdio.h> /* "intf_msg.h" */
29 #include <stdlib.h> /* calloc(), malloc(), free() */
34 #include "mtime.h" /* mtime_t, mdate(), msleep() */
36 #include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */
38 #include "audio_output.h"
39 #include "aout_common.h"
41 /*****************************************************************************
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 );
47 /*****************************************************************************
49 *****************************************************************************/
50 void aout_U8MonoThread( aout_thread_t * p_aout )
53 long l_buffer, l_buffer_limit, l_bytes;
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 )
59 vlc_mutex_lock( &p_aout->fifos_lock );
61 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
63 if( p_aout->fifo[i_fifo].b_die )
65 aout_FreeFifo( &p_aout->fifo[i_fifo] );
69 U8MonoPlay( p_aout, &p_aout->fifo[i_fifo] );
73 vlc_mutex_unlock( &p_aout->fifos_lock );
75 l_buffer_limit = p_aout->l_units; /* p_aout->b_stereo == 0 */
77 for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
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;
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) */
88 msleep( p_aout->l_msleep );
92 vlc_mutex_lock( &p_aout->fifos_lock );
94 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
96 aout_FreeFifo( &p_aout->fifo[i_fifo] );
99 vlc_mutex_unlock( &p_aout->fifos_lock );
102 void aout_U8StereoThread( aout_thread_t * p_aout )
105 long l_buffer, l_buffer_limit, l_bytes;
107 intf_DbgMsg("adec debug: running audio output U8_S_thread (%p) (pid == %i)", p_aout, getpid());
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 )
113 vlc_mutex_lock( &p_aout->fifos_lock );
115 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
117 if( p_aout->fifo[i_fifo].b_die )
119 aout_FreeFifo( &p_aout->fifo[i_fifo] );
123 U8StereoPlay( p_aout, &p_aout->fifo[i_fifo] );
127 vlc_mutex_unlock( &p_aout->fifos_lock );
129 l_buffer_limit = p_aout->l_units << 1 ; /* p_aout->b_stereo == 1 */
131 for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ )
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;
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)) )
141 msleep( p_aout->l_msleep );
145 vlc_mutex_lock( &p_aout->fifos_lock );
147 for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
149 aout_FreeFifo( &p_aout->fifo[i_fifo] );
152 vlc_mutex_unlock( &p_aout->fifos_lock );
155 /* Following functions are local */
157 static void U8MonoPlay( aout_thread_t * p_aout, aout_fifo_t * p_fifo )
160 long l_buffer_limit, l_units;
162 switch ( p_fifo->i_type )
164 case AOUT_EMPTY_FIFO:
168 case AOUT_INTF_MONO_FIFO:
170 if ( p_fifo->l_units > p_aout->l_units )
172 /* p_aout->b_stereo == 0 */
173 while ( l_buffer < (p_aout->l_units) )
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 )
181 p_fifo->l_units -= p_aout->l_units;
185 /* p_aout->b_stereo == 0 */
186 while ( l_buffer < (p_fifo->l_units) )
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 )
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); /* !! */
198 case AOUT_INTF_STEREO_FIFO:
200 if ( p_fifo->l_units > p_aout->l_units )
202 /* p_aout->b_stereo == 0 */
203 while ( l_buffer < (p_aout->l_units) )
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 )
211 p_fifo->l_units -= p_aout->l_units;
215 /* p_aout->b_stereo == 0 */
216 while ( l_buffer < (p_fifo->l_units) )
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 )
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); /* !! */
230 case AOUT_ADEC_MONO_FIFO:
232 l_units = p_aout->l_units;
234 while ( l_units > 0 )
236 if ( !p_fifo->b_next_frame )
238 if ( NextFrame(p_aout, p_fifo, p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
244 if ( p_fifo->l_units > l_units )
246 /* p_aout->b_stereo == 0 */
247 l_buffer_limit = p_aout->l_units;
249 while ( l_buffer < l_buffer_limit )
251 p_aout->s32_buffer[l_buffer++] +=
252 (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] );
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)) )
258 p_fifo->l_unit -= /* p_fifo->b_stereo == 0 */
259 ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0));
262 p_fifo->l_units -= l_units;
267 /* p_aout->b_stereo == 0 */
268 l_buffer_limit = l_buffer + (p_fifo->l_units);
270 while ( l_buffer < l_buffer_limit )
272 p_aout->s32_buffer[l_buffer++] +=
273 (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] );
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)) )
279 p_fifo->l_unit -= /* p_fifo->b_stereo == 0 */
280 ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0));
283 l_units -= p_fifo->l_units;
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 );
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;
298 case AOUT_ADEC_STEREO_FIFO:
300 l_units = p_aout->l_units;
302 while ( l_units > 0 )
304 if ( !p_fifo->b_next_frame )
306 if ( NextFrame(p_aout, p_fifo, p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
312 if ( p_fifo->l_units > l_units )
314 /* p_aout->b_stereo == 0 */
315 l_buffer_limit = p_aout->l_units;
317 while ( l_buffer < l_buffer_limit )
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;
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)) )
328 p_fifo->l_unit -= /* p_fifo->b_stereo == 1 */
329 ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1));
332 p_fifo->l_units -= l_units;
337 /* p_aout->b_stereo == 0 */
338 l_buffer_limit = l_buffer + (p_fifo->l_units);
340 while ( l_buffer < l_buffer_limit )
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;
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)) )
351 p_fifo->l_unit -= /* p_fifo->b_stereo == 1 */
352 ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1));
355 l_units -= p_fifo->l_units;
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 );
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;
372 intf_DbgMsg("aout debug: unknown fifo type (%i)", p_fifo->i_type);
378 static void U8StereoPlay( aout_thread_t * p_aout, aout_fifo_t * p_fifo )
381 long l_buffer_limit, l_units;
383 switch ( p_fifo->i_type )
385 case AOUT_EMPTY_FIFO:
389 case AOUT_INTF_MONO_FIFO:
391 if ( p_fifo->l_units > p_aout->l_units )
393 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
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 )
401 p_fifo->l_units -= p_aout->l_units;
405 while ( l_buffer < (p_fifo->l_units << 1) ) /* p_aout->b_stereo == 1 */
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 )
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); /* !! */
419 case AOUT_INTF_STEREO_FIFO:
421 if ( p_fifo->l_units > p_aout->l_units )
423 while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */
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 )
431 p_fifo->l_units -= p_aout->l_units;
435 while ( l_buffer < (p_fifo->l_units << 1) ) /* p_aout->b_stereo == 1 */
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 )
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); /* !! */
449 case AOUT_ADEC_MONO_FIFO:
451 l_units = p_aout->l_units;
453 while ( l_units > 0 )
455 if ( !p_fifo->b_next_frame )
457 if ( NextFrame(p_aout, p_fifo, p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
463 if ( p_fifo->l_units > l_units )
465 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
466 while ( l_buffer < l_buffer_limit )
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] );
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)) )
477 p_fifo->l_unit -= /* p_fifo->b_stereo == 0 */
478 ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0));
481 p_fifo->l_units -= l_units;
486 /* p_aout->b_stereo == 1 */
487 l_buffer_limit = l_buffer + (p_fifo->l_units << 1);
489 while ( l_buffer < l_buffer_limit )
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] );
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)) )
500 p_fifo->l_unit -= /* p_fifo->b_stereo == 0 */
501 ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0));
504 l_units -= p_fifo->l_units;
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 );
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;
519 case AOUT_ADEC_STEREO_FIFO:
521 l_units = p_aout->l_units;
523 while ( l_units > 0 )
525 if ( !p_fifo->b_next_frame )
527 if ( NextFrame(p_aout, p_fifo, p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) )
533 if ( p_fifo->l_units > l_units )
535 l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */
536 while ( l_buffer < l_buffer_limit )
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] );
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)) )
547 p_fifo->l_unit -= /* p_fifo->b_stereo == 1 */
548 ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1));
551 p_fifo->l_units -= l_units;
556 /* p_aout->b_stereo == 1 */
557 l_buffer_limit = l_buffer + (p_fifo->l_units << 1);
559 while ( l_buffer < l_buffer_limit )
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] );
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)) )
570 p_fifo->l_unit -= /* p_fifo->b_stereo == 1 */
571 ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1));
574 l_units -= p_fifo->l_units;
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 );
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;
590 intf_DbgMsg("aout debug: unknown fifo type (%i)", p_fifo->i_type);