From: Sam Hocevar Date: Tue, 20 Mar 2001 04:44:06 +0000 (+0000) Subject: * Split audio output into several separate files to make it easier X-Git-Tag: 0.2.70~41 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=b004a6619b9a9571bb565407e5690b20cadf380e;p=vlc * Split audio output into several separate files to make it easier to debug. Removed a few redundancies as well. --- diff --git a/Makefile.in b/Makefile.in index ebd22f2234..000688f270 100644 --- a/Makefile.in +++ b/Makefile.in @@ -212,7 +212,12 @@ INPUT = src/input/input_ext-dec.o \ src/input/input.o \ src/input/mpeg_system.o -AUDIO_OUTPUT = src/audio_output/audio_output.o +AUDIO_OUTPUT = src/audio_output/audio_output.o \ + src/audio_output/aout_fifo.o \ + src/audio_output/aout_u8.o \ + src/audio_output/aout_s8.o \ + src/audio_output/aout_u16.o \ + src/audio_output/aout_s16.o VIDEO_OUTPUT = src/video_output/video_output.o \ src/video_output/video_text.o \ diff --git a/include/audio_output.h b/include/audio_output.h index 7e2ba74239..6b9a39dd33 100644 --- a/include/audio_output.h +++ b/include/audio_output.h @@ -78,6 +78,7 @@ typedef struct aout_fifo_s /* See the fifo types below */ int i_type; boolean_t b_die; + int i_fifo; /* Just to keep track of the fifo index */ int i_channels; boolean_t b_stereo; @@ -202,8 +203,11 @@ typedef struct aout_thread_s * Prototypes *****************************************************************************/ aout_thread_t * aout_CreateThread ( int *pi_status ); -void aout_DestroyThread ( aout_thread_t *p_aout, int *pi_status ); +void aout_DestroyThread ( aout_thread_t *p_aout, + int *pi_status ); - -aout_fifo_t * aout_CreateFifo ( aout_thread_t *p_aout, aout_fifo_t *p_fifo ); +aout_fifo_t * aout_CreateFifo ( aout_thread_t *p_aout, + aout_fifo_t *p_fifo ); void aout_DestroyFifo ( aout_fifo_t *p_fifo ); +void aout_FreeFifo ( aout_fifo_t *p_fifo ); + diff --git a/include/modules.h b/include/modules.h index 37569a4a28..7356ec08f2 100644 --- a/include/modules.h +++ b/include/modules.h @@ -21,7 +21,7 @@ *****************************************************************************/ /* Number of tries before we unload an unused module */ -#define MODULE_HIDE_DELAY 20 +#define MODULE_HIDE_DELAY 100 /* The module handle type. */ #ifdef SYS_BEOS diff --git a/src/audio_output/aout_common.h b/src/audio_output/aout_common.h new file mode 100644 index 0000000000..558d078c9e --- /dev/null +++ b/src/audio_output/aout_common.h @@ -0,0 +1,142 @@ +/***************************************************************************** + * aout_common.h: audio output inner functions + ***************************************************************************** + * Copyright (C) 1999, 2000, 2001 VideoLAN + * + * Authors: Michel Kaempf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ + +/* Creating as many aout_Thread functions as configurations was one solution, + * examining the different cases in the Thread loop of an unique function was + * another. I chose the first solution. */ +void aout_U8MonoThread ( aout_thread_t * p_aout ); +void aout_U8StereoThread ( aout_thread_t * p_aout ); +void aout_S8MonoThread ( aout_thread_t * p_aout ); +void aout_S8StereoThread ( aout_thread_t * p_aout ); +void aout_U16MonoThread ( aout_thread_t * p_aout ); +void aout_U16StereoThread ( aout_thread_t * p_aout ); +void aout_S16MonoThread ( aout_thread_t * p_aout ); +void aout_S16StereoThread ( aout_thread_t * p_aout ); + +#define UPDATE_INCREMENT( increment, integer ) \ + if ( ((increment).l_remainder += (increment).l_euclidean_remainder) >= 0 )\ + { \ + (integer) += (increment).l_euclidean_integer + 1; \ + (increment).l_remainder -= (increment).l_euclidean_denominator; \ + } \ + else \ + { \ + (integer) += (increment).l_euclidean_integer; \ + } + +#define FIFO p_aout->fifo[i_fifo] + +/***************************************************************************** + * InitializeIncrement + *****************************************************************************/ +static __inline__ void InitializeIncrement( aout_increment_t * p_increment, + long l_numerator, + long l_denominator ) +{ + p_increment->l_remainder = -l_denominator; + + p_increment->l_euclidean_integer = 0; + while ( l_numerator >= l_denominator ) + { + p_increment->l_euclidean_integer++; + l_numerator -= l_denominator; + } + + p_increment->l_euclidean_remainder = l_numerator; + + p_increment->l_euclidean_denominator = l_denominator; +} + +/***************************************************************************** + * NextFrame + *****************************************************************************/ +static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo, + mtime_t aout_date ) +{ + long l_units, l_rate; + + /* We take the lock */ + vlc_mutex_lock( &p_fifo->data_lock ); + + /* Are we looking for a dated start frame ? */ + if ( !p_fifo->b_start_frame ) + { + while ( p_fifo->l_start_frame != p_fifo->l_end_frame ) + { + if ( p_fifo->date[p_fifo->l_start_frame] != LAST_MDATE ) + { + p_fifo->b_start_frame = 1; + p_fifo->l_next_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE; + p_fifo->l_unit = p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo)); + break; + } + p_fifo->l_start_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE; + } + + if ( p_fifo->l_start_frame == p_fifo->l_end_frame ) + { + vlc_mutex_unlock( &p_fifo->data_lock ); + return( -1 ); + } + } + + /* We are looking for the next dated frame */ + /* FIXME : is the output fifo full ?? */ + while ( !p_fifo->b_next_frame ) + { + while ( p_fifo->l_next_frame != p_fifo->l_end_frame ) + { + if ( p_fifo->date[p_fifo->l_next_frame] != LAST_MDATE ) + { + p_fifo->b_next_frame = 1; + break; + } + p_fifo->l_next_frame = (p_fifo->l_next_frame + 1) & AOUT_FIFO_SIZE; + } + + while ( p_fifo->l_next_frame == p_fifo->l_end_frame ) + { + vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock ); + if ( p_fifo->b_die ) + { + vlc_mutex_unlock( &p_fifo->data_lock ); + return( -1 ); + } + } + } + + l_units = ((p_fifo->l_next_frame - p_fifo->l_start_frame) & AOUT_FIFO_SIZE) * (p_fifo->l_frame_size >> (p_fifo->b_stereo)); + + l_rate = p_fifo->l_rate + ((aout_date - p_fifo->date[p_fifo->l_start_frame]) / 256); + intf_DbgMsg( "aout debug: %lli (%li);", aout_date - p_fifo->date[p_fifo->l_start_frame], l_rate ); + + InitializeIncrement( &p_fifo->unit_increment, l_rate, p_aout->l_rate ); + + p_fifo->l_units = (((l_units - (p_fifo->l_unit - + (p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo))))) + * p_aout->l_rate) / l_rate) + 1; + + /* We release the lock before leaving */ + vlc_mutex_unlock( &p_fifo->data_lock ); + return( 0 ); +} + diff --git a/src/audio_output/aout_fifo.c b/src/audio_output/aout_fifo.c new file mode 100644 index 0000000000..3d02a3d930 --- /dev/null +++ b/src/audio_output/aout_fifo.c @@ -0,0 +1,195 @@ +/***************************************************************************** + * aout_fifo.c : exported fifo management functions + ***************************************************************************** + * Copyright (C) 1999, 2000, 2001 VideoLAN + * + * Authors: Michel Kaempf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ +#include "defs.h" + +#include /* "intf_msg.h" */ +#include /* calloc(), malloc(), free() */ + +#include "config.h" +#include "common.h" +#include "threads.h" +#include "mtime.h" /* mtime_t, mdate(), msleep() */ + +#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */ + +#include "audio_output.h" +#include "aout_common.h" + +/***************************************************************************** + * aout_CreateFifo + *****************************************************************************/ +aout_fifo_t * aout_CreateFifo( aout_thread_t * p_aout, aout_fifo_t * p_fifo ) +{ + int i_fifo; + + /* Take the fifos lock */ + vlc_mutex_lock( &p_aout->fifos_lock ); + + /* Looking for a free fifo structure */ + for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ ) + { + if ( p_aout->fifo[i_fifo].i_type == AOUT_EMPTY_FIFO) + { + /* Not very clever, but at least we know which fifo it is */ + p_aout->fifo[i_fifo].i_fifo = i_fifo; + break; + } + } + + if ( i_fifo == AOUT_MAX_FIFOS ) + { + intf_ErrMsg( "aout error: no fifo available" ); + vlc_mutex_unlock( &p_aout->fifos_lock ); + return( NULL ); + } + + /* Initialize the new fifo structure */ + switch ( p_aout->fifo[i_fifo].i_type = p_fifo->i_type ) + { + case AOUT_INTF_MONO_FIFO: + case AOUT_INTF_STEREO_FIFO: + p_aout->fifo[i_fifo].b_die = 0; + + p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels; + p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo; + p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate; + + p_aout->fifo[i_fifo].buffer = p_fifo->buffer; + + p_aout->fifo[i_fifo].l_unit = 0; + InitializeIncrement( &p_aout->fifo[i_fifo].unit_increment, + p_fifo->l_rate, p_aout->l_rate ); + p_aout->fifo[i_fifo].l_units = p_fifo->l_units; + break; + + case AOUT_ADEC_MONO_FIFO: + case AOUT_ADEC_STEREO_FIFO: + p_aout->fifo[i_fifo].b_die = 0; + + p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels; + p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo; + p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate; + + p_aout->fifo[i_fifo].l_frame_size = p_fifo->l_frame_size; + /* Allocate the memory needed to store the audio frames. As the + * fifo is a rotative fifo, we must be able to find out whether the + * fifo is full or empty, that's why we must in fact allocate memory + * for (AOUT_FIFO_SIZE+1) audio frames. */ + p_aout->fifo[i_fifo].buffer = malloc( sizeof(s16)*(AOUT_FIFO_SIZE+1)*p_fifo->l_frame_size ); + if ( p_aout->fifo[i_fifo].buffer == NULL ) + { + intf_ErrMsg( "aout error: cannot create frame buffer" ); + p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; + vlc_mutex_unlock( &p_aout->fifos_lock ); + return( NULL ); + } + + /* Allocate the memory needed to store the dates of the frames */ + p_aout->fifo[i_fifo].date = (mtime_t *)malloc( sizeof(mtime_t)*(AOUT_FIFO_SIZE+1) ); + if ( p_aout->fifo[i_fifo].date == NULL ) + { + intf_ErrMsg( "aout error: cannot create date buffer"); + free( p_aout->fifo[i_fifo].buffer ); + p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; + vlc_mutex_unlock( &p_aout->fifos_lock ); + return( NULL ); + } + + /* Set the fifo's buffer as empty (the first frame that is to be + * played is also the first frame that is not to be played) */ + p_aout->fifo[i_fifo].l_start_frame = 0; + /* p_aout->fifo[i_fifo].l_next_frame = 0; */ + p_aout->fifo[i_fifo].l_end_frame = 0; + + /* Waiting for the audio decoder to compute enough frames to work + * out the fifo's current rate (as soon as the decoder has decoded + * enough frames, the members of the fifo structure that are not + * initialized now will be calculated) */ + p_aout->fifo[i_fifo].b_start_frame = 0; + p_aout->fifo[i_fifo].b_next_frame = 0; + break; + + default: + intf_ErrMsg( "aout error: unknown fifo type 0x%x", p_aout->fifo[i_fifo].i_type ); + p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; + vlc_mutex_unlock( &p_aout->fifos_lock ); + return( NULL ); + } + + /* Release the fifos lock */ + vlc_mutex_unlock( &p_aout->fifos_lock ); + + intf_WarnMsg( 2, "aout info: fifo #%i allocated, %i channels, rate %li", + p_aout->fifo[i_fifo].i_fifo, p_aout->fifo[i_fifo].i_channels, p_aout->fifo[i_fifo].l_rate ); + + /* Return the pointer to the fifo structure */ + return( &FIFO ); +} + +/***************************************************************************** + * aout_DestroyFifo + *****************************************************************************/ +void aout_DestroyFifo( aout_fifo_t * p_fifo ) +{ + intf_WarnMsg( 2, "aout info: fifo #%i destroyed", p_fifo->i_fifo ); + + p_fifo->b_die = 1; +} + +/***************************************************************************** + * aout_FreeFifo + *****************************************************************************/ +void aout_FreeFifo( aout_fifo_t * p_fifo ) +{ + switch ( p_fifo->i_type ) + { + case AOUT_EMPTY_FIFO: + + break; + + case AOUT_INTF_MONO_FIFO: + case AOUT_INTF_STEREO_FIFO: + + free( p_fifo->buffer ); + p_fifo->i_type = AOUT_EMPTY_FIFO; + + break; + + case AOUT_ADEC_MONO_FIFO: + case AOUT_ADEC_STEREO_FIFO: + + free( p_fifo->buffer ); + free( p_fifo->date ); + p_fifo->i_type = AOUT_EMPTY_FIFO; + + break; + + default: + + break; + } +} + diff --git a/src/audio_output/aout_s16.c b/src/audio_output/aout_s16.c new file mode 100644 index 0000000000..2e31280acb --- /dev/null +++ b/src/audio_output/aout_s16.c @@ -0,0 +1,329 @@ +/***************************************************************************** + * aout_s16.c: 16 bit signed audio output functions + ***************************************************************************** + * Copyright (C) 1999, 2000, 2001 VideoLAN + * + * Authors: Michel Kaempf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ +#include "defs.h" + +#include /* "intf_msg.h" */ +#include /* calloc(), malloc(), free() */ + +#include "config.h" +#include "common.h" +#include "threads.h" +#include "mtime.h" /* mtime_t, mdate(), msleep() */ + +#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */ + +#include "audio_output.h" +#include "aout_common.h" + +/***************************************************************************** + * Local prototypes + *****************************************************************************/ +static void S16StereoPlay( aout_thread_t * p_aout, aout_fifo_t * p_fifo ); + +/***************************************************************************** + * Functions + *****************************************************************************/ +void aout_S16MonoThread( aout_thread_t * p_aout ) +{ + intf_ErrMsg( "aout error: 16 bit signed mono thread unsupported" ); +} + +void aout_S16StereoThread( aout_thread_t * p_aout ) +{ + int i_fifo; + long l_buffer, l_buffer_limit, l_bytes; + + /* As the s32_buffer was created with calloc(), we don't have to set this + * memory to zero and we can immediately jump into the thread's loop */ + while ( ! p_aout->b_die ) + { + vlc_mutex_lock( &p_aout->fifos_lock ); + + for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ ) + { + if( p_aout->fifo[i_fifo].b_die ) + { + aout_FreeFifo( &p_aout->fifo[i_fifo] ); + } + else + { + S16StereoPlay( p_aout, &p_aout->fifo[i_fifo] ); + } + } + + vlc_mutex_unlock( &p_aout->fifos_lock ); + + l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */ + + for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ ) + { + ((s16 *)p_aout->buffer)[l_buffer] = (s16)( ( p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS ) * p_aout->vol / 256 ) ; + p_aout->s32_buffer[l_buffer] = 0; + } + + l_bytes = p_aout->pf_getbufinfo( p_aout, l_buffer_limit ); + p_aout->date = mdate() + ((((mtime_t)(l_bytes / 4)) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(s16) << (p_aout->b_stereo) == 4 */ + p_aout->pf_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(s16) ); + if ( l_bytes > (l_buffer_limit * sizeof(s16)) ) + { + msleep( p_aout->l_msleep ); + } + } + + vlc_mutex_lock( &p_aout->fifos_lock ); + + for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ ) + { + aout_FreeFifo( &p_aout->fifo[i_fifo] ); + } + + vlc_mutex_unlock( &p_aout->fifos_lock ); +} + +/* Following functions are local */ + +static void S16StereoPlay( aout_thread_t * p_aout, aout_fifo_t * p_fifo ) +{ + long l_buffer = 0; + long l_buffer_limit, l_units; + + switch ( p_fifo->i_type ) + { + case AOUT_EMPTY_FIFO: + + break; + + case AOUT_INTF_MONO_FIFO: + + if ( p_fifo->l_units > p_aout->l_units ) + { + /* p_aout->b_stereo == 1 */ + while ( l_buffer < (p_aout->l_units << 1) ) + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + } + p_fifo->l_units -= p_aout->l_units; + } + else + { + /* p_aout->b_stereo == 1 */ + while ( l_buffer < (p_fifo->l_units << 1) ) + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + } + free( p_fifo->buffer ); /* !! */ + p_fifo->i_type = AOUT_EMPTY_FIFO; /* !! */ + } + break; + + case AOUT_INTF_STEREO_FIFO: + + if ( p_fifo->l_units > p_aout->l_units ) + { + /* p_aout->b_stereo == 1 */ + while ( l_buffer < (p_aout->l_units << 1) ) + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] ); + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] ); + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + } + p_fifo->l_units -= p_aout->l_units; + } + else + { + /* p_aout->b_stereo == 1 */ + while ( l_buffer < (p_fifo->l_units << 1) ) + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] ); + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] ); + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + } + free( p_fifo->buffer ); + p_fifo->i_type = AOUT_EMPTY_FIFO; + } + break; + + case AOUT_ADEC_MONO_FIFO: + + l_units = p_aout->l_units; + while ( l_units > 0 ) + { + if ( !p_fifo->b_next_frame ) + { + if ( NextFrame(p_aout, p_fifo, p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) ) + { + break; + } + } + + if ( p_fifo->l_units > l_units ) + { + /* p_aout->b_stereo == 1 */ + l_buffer_limit = p_aout->l_units << 1; + + while ( l_buffer < l_buffer_limit ) + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 0 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0)) ) + { + p_fifo->l_unit -= /* p_fifo->b_stereo == 0 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0)); + } + } + p_fifo->l_units -= l_units; + break; + } + else + { + /* p_aout->b_stereo == 1 */ + l_buffer_limit = l_buffer + (p_fifo->l_units << 1); + + while ( l_buffer < l_buffer_limit ) + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 0 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0)) ) + { + p_fifo->l_unit -= /* p_fifo->b_stereo == 0 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0)); + } + } + l_units -= p_fifo->l_units; + + vlc_mutex_lock( &p_fifo->data_lock ); + p_fifo->l_start_frame = p_fifo->l_next_frame; + vlc_cond_signal( &p_fifo->data_wait ); + vlc_mutex_unlock( &p_fifo->data_lock ); + + /* p_fifo->b_start_frame = 1; */ + p_fifo->l_next_frame += 1; + p_fifo->l_next_frame &= AOUT_FIFO_SIZE; + p_fifo->b_next_frame = 0; + } + } + break; + + case AOUT_ADEC_STEREO_FIFO: + + l_units = p_aout->l_units; + while ( l_units > 0 ) + { + if ( !p_fifo->b_next_frame ) + { + if ( NextFrame(p_aout, p_fifo, p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) ) + { + break; + } + } + + if ( p_fifo->l_units > l_units ) + { + /* p_aout->b_stereo == 1 */ + l_buffer_limit = p_aout->l_units << 1; + + while ( l_buffer < l_buffer_limit ) + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] ); + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] ); + + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 1 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1)) ) + { + p_fifo->l_unit -= /* p_fifo->b_stereo == 1 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1)); + } + } + p_fifo->l_units -= l_units; + break; + } + else + { + /* p_aout->b_stereo == 1 */ + l_buffer_limit = l_buffer + (p_fifo->l_units << 1); + + while ( l_buffer < l_buffer_limit ) + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] ); + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] ); + + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 1 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1)) ) + { + p_fifo->l_unit -= /* p_fifo->b_stereo == 1 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1)); + } + } + l_units -= p_fifo->l_units; + + vlc_mutex_lock( &p_fifo->data_lock ); + p_fifo->l_start_frame = p_fifo->l_next_frame; + vlc_cond_signal( &p_fifo->data_wait ); + vlc_mutex_unlock( &p_fifo->data_lock ); + + /* p_fifo->b_start_frame = 1; */ + p_fifo->l_next_frame += 1; + p_fifo->l_next_frame &= AOUT_FIFO_SIZE; + p_fifo->b_next_frame = 0; + } + } + break; + + default: + + intf_DbgMsg("aout debug: unknown fifo type (%i)", p_fifo->i_type); + break; + } +} + diff --git a/src/audio_output/aout_s8.c b/src/audio_output/aout_s8.c new file mode 100644 index 0000000000..360b261c86 --- /dev/null +++ b/src/audio_output/aout_s8.c @@ -0,0 +1,53 @@ +/***************************************************************************** + * aout_s8.c: 8 bit signed audio output functions + ***************************************************************************** + * Copyright (C) 1999, 2000, 2001 VideoLAN + * + * Authors: Michel Kaempf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ +#include "defs.h" + +#include /* "intf_msg.h" */ +#include /* calloc(), malloc(), free() */ + +#include "config.h" +#include "common.h" +#include "threads.h" +#include "mtime.h" /* mtime_t, mdate(), msleep() */ + +#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */ + +#include "audio_output.h" +#include "aout_common.h" + +/***************************************************************************** + * Functions + *****************************************************************************/ +void aout_S8MonoThread( aout_thread_t * p_aout ) +{ + intf_ErrMsg( "aout error: 8 bit signed mono thread unsupported" ); +} + +void aout_S8StereoThread( aout_thread_t * p_aout ) +{ + intf_ErrMsg( "aout error: 8 bit signed stereo thread unsupported" ); +} + diff --git a/src/audio_output/aout_u16.c b/src/audio_output/aout_u16.c new file mode 100644 index 0000000000..654f836ede --- /dev/null +++ b/src/audio_output/aout_u16.c @@ -0,0 +1,53 @@ +/***************************************************************************** + * aout_u16.c: 16 bit unsigned audio output functions + ***************************************************************************** + * Copyright (C) 1999, 2000, 2001 VideoLAN + * + * Authors: Michel Kaempf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ +#include "defs.h" + +#include /* "intf_msg.h" */ +#include /* calloc(), malloc(), free() */ + +#include "config.h" +#include "common.h" +#include "threads.h" +#include "mtime.h" /* mtime_t, mdate(), msleep() */ + +#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */ + +#include "audio_output.h" +#include "aout_common.h" + +/***************************************************************************** + * Functions + *****************************************************************************/ +void aout_U16MonoThread( aout_thread_t * p_aout ) +{ + intf_ErrMsg( "aout error: 16 bit unsigned mono thread unsupported" ); +} + +void aout_U16StereoThread( aout_thread_t * p_aout ) +{ + intf_ErrMsg( "aout error: 16 bit unsigned stereo thread unsupported" ); +} + diff --git a/src/audio_output/aout_u8.c b/src/audio_output/aout_u8.c new file mode 100644 index 0000000000..8713faa65b --- /dev/null +++ b/src/audio_output/aout_u8.c @@ -0,0 +1,594 @@ +/***************************************************************************** + * aout_u8.c: 8 bit unsigned audio output functions + ***************************************************************************** + * Copyright (C) 1999, 2000, 2001 VideoLAN + * + * Authors: Michel Kaempf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ +#include "defs.h" + +#include /* "intf_msg.h" */ +#include /* calloc(), malloc(), free() */ + +#include "config.h" +#include "common.h" +#include "threads.h" +#include "mtime.h" /* mtime_t, mdate(), msleep() */ + +#include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */ + +#include "audio_output.h" +#include "aout_common.h" + +/***************************************************************************** + * Local prototypes + *****************************************************************************/ +static void U8MonoPlay ( aout_thread_t * p_aout, aout_fifo_t * p_fifo ); +static void U8StereoPlay ( aout_thread_t * p_aout, aout_fifo_t * p_fifo ); + +/***************************************************************************** + * Functions + *****************************************************************************/ +void aout_U8MonoThread( aout_thread_t * p_aout ) +{ + int i_fifo; + long l_buffer, l_buffer_limit, l_bytes; + + /* As the s32_buffer was created with calloc(), we don't have to set this + * memory to zero and we can immediately jump into the thread's loop */ + while ( ! p_aout->b_die ) + { + vlc_mutex_lock( &p_aout->fifos_lock ); + + for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ ) + { + if( p_aout->fifo[i_fifo].b_die ) + { + aout_FreeFifo( &p_aout->fifo[i_fifo] ); + } + else + { + U8MonoPlay( p_aout, &p_aout->fifo[i_fifo] ); + } + } + + vlc_mutex_unlock( &p_aout->fifos_lock ); + + l_buffer_limit = p_aout->l_units; /* p_aout->b_stereo == 0 */ + + for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ ) + { + ((u8 *)p_aout->buffer)[l_buffer] = (u8)( ( (p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS / 256 ) + 128 ) * p_aout->vol / 256 ); + p_aout->s32_buffer[l_buffer] = 0; + } + + l_bytes = p_aout->pf_getbufinfo( p_aout, l_buffer_limit ); + p_aout->date = mdate() + ((((mtime_t)(l_bytes / 1 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 1 */ + p_aout->pf_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) ); + if ( l_bytes > (l_buffer_limit * sizeof(u8) * 2) ) /* There are 2 channels (left & right) */ + { + msleep( p_aout->l_msleep ); + } + } + + vlc_mutex_lock( &p_aout->fifos_lock ); + + for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ ) + { + aout_FreeFifo( &p_aout->fifo[i_fifo] ); + } + + vlc_mutex_unlock( &p_aout->fifos_lock ); +} + +void aout_U8StereoThread( aout_thread_t * p_aout ) +{ + int i_fifo; + long l_buffer, l_buffer_limit, l_bytes; + + intf_DbgMsg("adec debug: running audio output U8_S_thread (%p) (pid == %i)", p_aout, getpid()); + + /* As the s32_buffer was created with calloc(), we don't have to set this + * memory to zero and we can immediately jump into the thread's loop */ + while ( ! p_aout->b_die ) + { + vlc_mutex_lock( &p_aout->fifos_lock ); + + for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ ) + { + if( p_aout->fifo[i_fifo].b_die ) + { + aout_FreeFifo( &p_aout->fifo[i_fifo] ); + } + else + { + U8StereoPlay( p_aout, &p_aout->fifo[i_fifo] ); + } + } + + vlc_mutex_unlock( &p_aout->fifos_lock ); + + l_buffer_limit = p_aout->l_units << 1 ; /* p_aout->b_stereo == 1 */ + + for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ ) + { + ((u8 *)p_aout->buffer)[l_buffer] = (u8)( ( (p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS / 256) + 128 ) * p_aout->vol / 256 ); + p_aout->s32_buffer[l_buffer] = 0; + } + l_bytes = p_aout->pf_getbufinfo( p_aout, l_buffer_limit ); + p_aout->date = mdate() + ((((mtime_t)(l_bytes / 2 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 2 */ + p_aout->pf_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) ); + if ( l_bytes > (l_buffer_limit * sizeof(u8)) ) + { + msleep( p_aout->l_msleep ); + } + } + + vlc_mutex_lock( &p_aout->fifos_lock ); + + for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ ) + { + aout_FreeFifo( &p_aout->fifo[i_fifo] ); + } + + vlc_mutex_unlock( &p_aout->fifos_lock ); +} + +/* Following functions are local */ + +static void U8MonoPlay( aout_thread_t * p_aout, aout_fifo_t * p_fifo ) +{ + long l_buffer = 0; + long l_buffer_limit, l_units; + + switch ( p_fifo->i_type ) + { + case AOUT_EMPTY_FIFO: + + break; + + case AOUT_INTF_MONO_FIFO: + + if ( p_fifo->l_units > p_aout->l_units ) + { + /* p_aout->b_stereo == 0 */ + while ( l_buffer < (p_aout->l_units) ) + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + } + p_fifo->l_units -= p_aout->l_units; + } + else + { + /* p_aout->b_stereo == 0 */ + while ( l_buffer < (p_fifo->l_units) ) + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + } + free( p_fifo->buffer ); /* !! */ + p_fifo->i_type = AOUT_EMPTY_FIFO; /* !! */ + intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", p_fifo); /* !! */ + } + break; + + case AOUT_INTF_STEREO_FIFO: + + if ( p_fifo->l_units > p_aout->l_units ) + { + /* p_aout->b_stereo == 0 */ + while ( l_buffer < (p_aout->l_units) ) + { + /* I mix half left - half right */ + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] ) / 2 + + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] ) / 2; + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + } + p_fifo->l_units -= p_aout->l_units; + } + else + { + /* p_aout->b_stereo == 0 */ + while ( l_buffer < (p_fifo->l_units) ) + { + /* I mix half left - half right */ + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] ) / 2 + + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] ) / 2; + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + } + free( p_fifo->buffer ); /* !! */ + p_fifo->i_type = AOUT_EMPTY_FIFO; /* !! */ + intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", p_fifo); /* !! */ + } + break; + + case AOUT_ADEC_MONO_FIFO: + + l_units = p_aout->l_units; + + while ( l_units > 0 ) + { + if ( !p_fifo->b_next_frame ) + { + if ( NextFrame(p_aout, p_fifo, p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) ) + { + break; + } + } + + if ( p_fifo->l_units > l_units ) + { + /* p_aout->b_stereo == 0 */ + l_buffer_limit = p_aout->l_units; + + while ( l_buffer < l_buffer_limit ) + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 0 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0)) ) + { + p_fifo->l_unit -= /* p_fifo->b_stereo == 0 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0)); + } + } + p_fifo->l_units -= l_units; + break; + } + else + { + /* p_aout->b_stereo == 0 */ + l_buffer_limit = l_buffer + (p_fifo->l_units); + + while ( l_buffer < l_buffer_limit ) + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 0 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0)) ) + { + p_fifo->l_unit -= /* p_fifo->b_stereo == 0 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0)); + } + } + l_units -= p_fifo->l_units; + + vlc_mutex_lock( &p_fifo->data_lock ); + p_fifo->l_start_frame = p_fifo->l_next_frame; + vlc_cond_signal( &p_fifo->data_wait ); + vlc_mutex_unlock( &p_fifo->data_lock ); + + /* p_fifo->b_start_frame = 1; */ + p_fifo->l_next_frame += 1; + p_fifo->l_next_frame &= AOUT_FIFO_SIZE; + p_fifo->b_next_frame = 0; + } + } + break; + + case AOUT_ADEC_STEREO_FIFO: + + l_units = p_aout->l_units; + + while ( l_units > 0 ) + { + if ( !p_fifo->b_next_frame ) + { + if ( NextFrame(p_aout, p_fifo, p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) ) + { + break; + } + } + + if ( p_fifo->l_units > l_units ) + { + /* p_aout->b_stereo == 0 */ + l_buffer_limit = p_aout->l_units; + + while ( l_buffer < l_buffer_limit ) + { + /* I mix half left - half right */ + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] ) / 2 + + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] ) / 2; + + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 1 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1)) ) + { + p_fifo->l_unit -= /* p_fifo->b_stereo == 1 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1)); + } + } + p_fifo->l_units -= l_units; + break; + } + else + { + /* p_aout->b_stereo == 0 */ + l_buffer_limit = l_buffer + (p_fifo->l_units); + + while ( l_buffer < l_buffer_limit ) + { + /* I mix half left - half right */ + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] ) / 2 + + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] ) / 2; + + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 1 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1)) ) + { + p_fifo->l_unit -= /* p_fifo->b_stereo == 1 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1)); + } + } + l_units -= p_fifo->l_units; + + vlc_mutex_lock( &p_fifo->data_lock ); + p_fifo->l_start_frame = p_fifo->l_next_frame; + vlc_cond_signal( &p_fifo->data_wait ); + vlc_mutex_unlock( &p_fifo->data_lock ); + + /* p_fifo->b_start_frame = 1; */ + p_fifo->l_next_frame += 1; + p_fifo->l_next_frame &= AOUT_FIFO_SIZE; + p_fifo->b_next_frame = 0; + } + } + break; + + default: + + intf_DbgMsg("aout debug: unknown fifo type (%i)", p_fifo->i_type); + + break; + } +} + +static void U8StereoPlay( aout_thread_t * p_aout, aout_fifo_t * p_fifo ) +{ + long l_buffer = 0; + long l_buffer_limit, l_units; + + switch ( p_fifo->i_type ) + { + case AOUT_EMPTY_FIFO: + + break; + + case AOUT_INTF_MONO_FIFO: + + if ( p_fifo->l_units > p_aout->l_units ) + { + while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */ + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + } + p_fifo->l_units -= p_aout->l_units; + } + else + { + while ( l_buffer < (p_fifo->l_units << 1) ) /* p_aout->b_stereo == 1 */ + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + } + free( p_fifo->buffer ); /* !! */ + p_fifo->i_type = AOUT_EMPTY_FIFO; /* !! */ + intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", p_fifo); /* !! */ + } + break; + + case AOUT_INTF_STEREO_FIFO: + + if ( p_fifo->l_units > p_aout->l_units ) + { + while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */ + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] ); + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] ); + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + } + p_fifo->l_units -= p_aout->l_units; + } + else + { + while ( l_buffer < (p_fifo->l_units << 1) ) /* p_aout->b_stereo == 1 */ + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] ); + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] ); + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + } + free( p_fifo->buffer ); /* !! */ + p_fifo->i_type = AOUT_EMPTY_FIFO; /* !! */ + intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", p_fifo); /* !! */ + } + break; + + case AOUT_ADEC_MONO_FIFO: + + l_units = p_aout->l_units; + + while ( l_units > 0 ) + { + if ( !p_fifo->b_next_frame ) + { + if ( NextFrame(p_aout, p_fifo, p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) ) + { + break; + } + } + + if ( p_fifo->l_units > l_units ) + { + l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */ + while ( l_buffer < l_buffer_limit ) + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 0 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0)) ) + { + p_fifo->l_unit -= /* p_fifo->b_stereo == 0 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0)); + } + } + p_fifo->l_units -= l_units; + break; + } + else + { + /* p_aout->b_stereo == 1 */ + l_buffer_limit = l_buffer + (p_fifo->l_units << 1); + + while ( l_buffer < l_buffer_limit ) + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[p_fifo->l_unit] ); + + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 0 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0)) ) + { + p_fifo->l_unit -= /* p_fifo->b_stereo == 0 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 0)); + } + } + l_units -= p_fifo->l_units; + + vlc_mutex_lock( &p_fifo->data_lock ); + p_fifo->l_start_frame = p_fifo->l_next_frame; + vlc_cond_signal( &p_fifo->data_wait ); + vlc_mutex_unlock( &p_fifo->data_lock ); + + /* p_fifo->b_start_frame = 1; */ + p_fifo->l_next_frame += 1; + p_fifo->l_next_frame &= AOUT_FIFO_SIZE; + p_fifo->b_next_frame = 0; + } + } + break; + + case AOUT_ADEC_STEREO_FIFO: + + l_units = p_aout->l_units; + + while ( l_units > 0 ) + { + if ( !p_fifo->b_next_frame ) + { + if ( NextFrame(p_aout, p_fifo, p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) ) + { + break; + } + } + + if ( p_fifo->l_units > l_units ) + { + l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */ + while ( l_buffer < l_buffer_limit ) + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] ); + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] ); + + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 1 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1)) ) + { + p_fifo->l_unit -= /* p_fifo->b_stereo == 1 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1)); + } + } + p_fifo->l_units -= l_units; + break; + } + else + { + /* p_aout->b_stereo == 1 */ + l_buffer_limit = l_buffer + (p_fifo->l_units << 1); + + while ( l_buffer < l_buffer_limit ) + { + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit] ); + p_aout->s32_buffer[l_buffer++] += + (s32)( ((s16 *)p_fifo->buffer)[2*p_fifo->l_unit+1] ); + + UPDATE_INCREMENT( p_fifo->unit_increment, p_fifo->l_unit ) + if ( p_fifo->l_unit >= /* p_fifo->b_stereo == 1 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1)) ) + { + p_fifo->l_unit -= /* p_fifo->b_stereo == 1 */ + ((AOUT_FIFO_SIZE + 1) * (p_fifo->l_frame_size >> 1)); + } + } + l_units -= p_fifo->l_units; + + vlc_mutex_lock( &p_fifo->data_lock ); + p_fifo->l_start_frame = p_fifo->l_next_frame; + vlc_cond_signal( &p_fifo->data_wait ); + vlc_mutex_unlock( &p_fifo->data_lock ); + + /* p_fifo->b_start_frame = 1; */ + p_fifo->l_next_frame += 1; + p_fifo->l_next_frame &= AOUT_FIFO_SIZE; + p_fifo->b_next_frame = 0; + } + } + break; + + default: + intf_DbgMsg("aout debug: unknown fifo type (%i)", p_fifo->i_type); + break; + } +} + diff --git a/src/audio_output/audio_output.c b/src/audio_output/audio_output.c index f7513eb022..e4fa2bb5d4 100644 --- a/src/audio_output/audio_output.c +++ b/src/audio_output/audio_output.c @@ -1,7 +1,7 @@ /***************************************************************************** * audio_output.c : audio output thread ***************************************************************************** - * Copyright (C) 1999, 2000 VideoLAN + * Copyright (C) 1999, 2000, 2001 VideoLAN * * Authors: Michel Kaempf * @@ -51,48 +51,15 @@ #include "intf_msg.h" /* intf_DbgMsg(), intf_ErrMsg() */ #include "audio_output.h" +#include "aout_common.h" + #include "main.h" /***************************************************************************** * Local prototypes *****************************************************************************/ - static int aout_SpawnThread( aout_thread_t * p_aout ); -/* Creating as much aout_Thread functions as configurations is one solution, - * examining the different cases in the Thread loop of an unique function is - * another. I chose the first solution. */ -void aout_Thread_S8_Mono ( aout_thread_t * p_aout ); -void aout_Thread_U8_Mono ( aout_thread_t * p_aout ); -void aout_Thread_S16_Mono ( aout_thread_t * p_aout ); -void aout_Thread_U16_Mono ( aout_thread_t * p_aout ); -void aout_Thread_S8_Stereo ( aout_thread_t * p_aout ); -void aout_Thread_U8_Stereo ( aout_thread_t * p_aout ); -void aout_Thread_S16_Stereo ( aout_thread_t * p_aout ); -void aout_Thread_U16_Stereo ( aout_thread_t * p_aout ); - -static __inline__ void InitializeIncrement( aout_increment_t * p_increment, long l_numerator, long l_denominator ); -static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo, mtime_t aout_date ); - -/***************************************************************************** - * InitializeIncrement - *****************************************************************************/ -static __inline__ void InitializeIncrement( aout_increment_t * p_increment, long l_numerator, long l_denominator ) -{ - p_increment->l_remainder = -l_denominator; - - p_increment->l_euclidean_integer = 0; - while ( l_numerator >= l_denominator ) - { - p_increment->l_euclidean_integer++; - l_numerator -= l_denominator; - } - - p_increment->l_euclidean_remainder = l_numerator; - - p_increment->l_euclidean_denominator = l_denominator; -} - /***************************************************************************** * aout_CreateThread: initialize audio thread *****************************************************************************/ @@ -185,8 +152,6 @@ static int aout_SpawnThread( aout_thread_t * p_aout ) long l_bytes; void * aout_thread = NULL; - intf_DbgMsg("aout debug: spawning audio output thread (%p)", p_aout); - /* We want the audio output thread to live */ p_aout->b_die = 0; p_aout->b_active = 1; @@ -211,106 +176,118 @@ static int aout_SpawnThread( aout_thread_t * p_aout ) * byte size of the audio output buffer */ switch ( p_aout->i_channels ) { - /* Audio output is mono */ - case 1: - switch ( p_aout->i_format ) - { - case AOUT_FMT_U8: - l_bytes = 1 * sizeof(u8) * p_aout->l_units; - aout_thread = (void *)aout_Thread_U8_Mono; - break; - - case AOUT_FMT_S8: - l_bytes = 1 * sizeof(s8) * p_aout->l_units; - aout_thread = (void *)aout_Thread_S8_Mono; - break; + /* Audio output is mono */ + case 1: + switch ( p_aout->i_format ) + { + case AOUT_FMT_U8: + intf_WarnMsg( 2, "aout info: unsigned 8 bits mono thread" ); + l_bytes = 1 * sizeof(u8) * p_aout->l_units; + aout_thread = (void *)aout_U8MonoThread; + break; - case AOUT_FMT_U16_LE: - case AOUT_FMT_U16_BE: - l_bytes = 1 * sizeof(u16) * p_aout->l_units; - aout_thread = (void *)aout_Thread_U16_Mono; - break; + case AOUT_FMT_S8: + intf_WarnMsg( 2, "aout info: signed 8 bits mono thread" ); + l_bytes = 1 * sizeof(s8) * p_aout->l_units; + aout_thread = (void *)aout_S8MonoThread; + break; - case AOUT_FMT_S16_LE: - case AOUT_FMT_S16_BE: - l_bytes = 1 * sizeof(s16) * p_aout->l_units; - aout_thread = (void *)aout_Thread_S16_Mono; - break; + case AOUT_FMT_U16_LE: + case AOUT_FMT_U16_BE: + intf_WarnMsg( 2, "aout info: unsigned 16 bits mono thread" ); + l_bytes = 1 * sizeof(u16) * p_aout->l_units; + aout_thread = (void *)aout_U16MonoThread; + break; - default: - intf_ErrMsg( "aout error: unknown audio output format (%i)", - p_aout->i_format ); - return( -1 ); - } + case AOUT_FMT_S16_LE: + case AOUT_FMT_S16_BE: + intf_WarnMsg( 2, "aout info: signed 16 bits mono thread" ); + l_bytes = 1 * sizeof(s16) * p_aout->l_units; + aout_thread = (void *)aout_S16MonoThread; break; - /* Audio output is stereo */ - case 2: - switch ( p_aout->i_format ) - { - case AOUT_FMT_U8: - l_bytes = 2 * sizeof(u8) * p_aout->l_units; - aout_thread = (void *)aout_Thread_U8_Stereo; - break; + default: + intf_ErrMsg( "aout error: unknown audio output format (%i)", + p_aout->i_format ); + return( -1 ); + } + break; - case AOUT_FMT_S8: - l_bytes = 2 * sizeof(s8) * p_aout->l_units; - aout_thread = (void *)aout_Thread_S8_Stereo; - break; + /* Audio output is stereo */ + case 2: + switch ( p_aout->i_format ) + { + case AOUT_FMT_U8: + intf_WarnMsg( 2, "aout info: unsigned 8 bits stereo thread" ); + l_bytes = 2 * sizeof(u8) * p_aout->l_units; + aout_thread = (void *)aout_U8StereoThread; + break; - case AOUT_FMT_U16_LE: - case AOUT_FMT_U16_BE: - l_bytes = 2 * sizeof(u16) * p_aout->l_units; - aout_thread = (void *)aout_Thread_U16_Stereo; - break; + case AOUT_FMT_S8: + intf_WarnMsg( 2, "aout info: signed 8 bits stereo thread" ); + l_bytes = 2 * sizeof(s8) * p_aout->l_units; + aout_thread = (void *)aout_S8StereoThread; + break; - case AOUT_FMT_S16_LE: - case AOUT_FMT_S16_BE: - l_bytes = 2 * sizeof(s16) * p_aout->l_units; - aout_thread = (void *)aout_Thread_S16_Stereo; - break; + case AOUT_FMT_U16_LE: + case AOUT_FMT_U16_BE: + intf_WarnMsg( 2, "aout info: unsigned 16 bits stereo thread" ); + l_bytes = 2 * sizeof(u16) * p_aout->l_units; + aout_thread = (void *)aout_U16StereoThread; + break; - default: - intf_ErrMsg("aout error: unknown audio output format (%i)", - p_aout->i_format); - return( -1 ); - } + case AOUT_FMT_S16_LE: + case AOUT_FMT_S16_BE: + intf_WarnMsg( 2, "aout info: signed 16 bits stereo thread" ); + l_bytes = 2 * sizeof(s16) * p_aout->l_units; + aout_thread = (void *)aout_S16StereoThread; break; default: - intf_ErrMsg("aout error: unknown number of audio channels (%i)", - p_aout->i_channels ); + intf_ErrMsg( "aout error: unknown audio output format %i", + p_aout->i_format ); return( -1 ); + } + break; + + default: + intf_ErrMsg( "aout error: unknown number of audio channels (%i)", + p_aout->i_channels ); + return( -1 ); } /* Allocate the memory needed by the audio output buffers, and set to zero * the s32 buffer's memory */ - if ( (p_aout->buffer = malloc(l_bytes)) == NULL ) + p_aout->buffer = malloc( l_bytes ); + if ( p_aout->buffer == NULL ) { - intf_ErrMsg("aout error: not enough memory to create the output buffer"); + intf_ErrMsg( "aout error: cannot create output buffer" ); return( -1 ); } - if ( (p_aout->s32_buffer = (s32 *)calloc(p_aout->l_units, sizeof(s32) << ( p_aout->b_stereo))) == NULL ) + + p_aout->s32_buffer = (s32 *)calloc( p_aout->l_units, + sizeof(s32) << ( p_aout->b_stereo ) ); + if ( p_aout->s32_buffer == NULL ) { - intf_ErrMsg("aout error: not enough memory to create the s32 output buffer"); + intf_ErrMsg( "aout error: cannot create the s32 output buffer" ); free( p_aout->buffer ); return( -1 ); } - /* Before launching the thread, we try to predict the date of the first - * audio unit in the first output buffer */ - p_aout->date = mdate() - 1000000; + /* Rough estimate of the playing date */ + p_aout->date = mdate(); /* Launch the thread */ - if ( vlc_thread_create( &p_aout->thread_id, "audio output", (vlc_thread_func_t)aout_thread, p_aout ) ) + if ( vlc_thread_create( &p_aout->thread_id, "audio output", + (vlc_thread_func_t)aout_thread, p_aout ) ) { - intf_ErrMsg("aout error: can't spawn audio output thread (%p)", p_aout); + intf_ErrMsg( "aout error: cannot spawn audio output thread" ); free( p_aout->buffer ); free( p_aout->s32_buffer ); return( -1 ); } - intf_DbgMsg("aout debug: audio output thread (%p) spawned", p_aout); + intf_WarnMsg( 2, "aout info: audio output thread %i spawned", getpid() ); return( 0 ); } @@ -324,8 +301,6 @@ void aout_DestroyThread( aout_thread_t * p_aout, int *pi_status ) /* FIXME: pi_status is not handled correctly: check vout how to do!?? */ - intf_DbgMsg("aout debug: requesting termination of audio output thread (%p)", p_aout); - /* Ask thread to kill itself and wait until it's done */ p_aout->b_die = 1; vlc_thread_join( p_aout->thread_id ); /* only if pi_status is NULL */ @@ -352,1087 +327,3 @@ void aout_DestroyThread( aout_thread_t * p_aout, int *pi_status ) free( p_aout ); } -/***************************************************************************** - * aout_CreateFifo - *****************************************************************************/ -aout_fifo_t * aout_CreateFifo( aout_thread_t * p_aout, aout_fifo_t * p_fifo ) -{ - int i_fifo; - - /* Take the fifos lock */ - vlc_mutex_lock( &p_aout->fifos_lock ); - - /* Looking for a free fifo structure */ - for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ ) - { - if ( p_aout->fifo[i_fifo].i_type == AOUT_EMPTY_FIFO) - { - break; - } - } - if ( i_fifo == AOUT_MAX_FIFOS ) - { - intf_ErrMsg("aout error: no empty fifo available"); - vlc_mutex_unlock( &p_aout->fifos_lock ); - return( NULL ); - } - - /* Initialize the new fifo structure */ - switch ( p_aout->fifo[i_fifo].i_type = p_fifo->i_type ) - { - case AOUT_INTF_MONO_FIFO: - case AOUT_INTF_STEREO_FIFO: - p_aout->fifo[i_fifo].b_die = 0; - - p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels; - p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo; - p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate; - - p_aout->fifo[i_fifo].buffer = p_fifo->buffer; - - p_aout->fifo[i_fifo].l_unit = 0; - InitializeIncrement( &p_aout->fifo[i_fifo].unit_increment, p_fifo->l_rate, p_aout->l_rate ); - p_aout->fifo[i_fifo].l_units = p_fifo->l_units; - break; - - case AOUT_ADEC_MONO_FIFO: - case AOUT_ADEC_STEREO_FIFO: - p_aout->fifo[i_fifo].b_die = 0; - - p_aout->fifo[i_fifo].i_channels = p_fifo->i_channels; - p_aout->fifo[i_fifo].b_stereo = p_fifo->b_stereo; - p_aout->fifo[i_fifo].l_rate = p_fifo->l_rate; - - p_aout->fifo[i_fifo].l_frame_size = p_fifo->l_frame_size; - /* Allocate the memory needed to store the audio frames. As the - * fifo is a rotative fifo, we must be able to find out whether the - * fifo is full or empty, that's why we must in fact allocate memory - * for (AOUT_FIFO_SIZE+1) audio frames. */ - if ( (p_aout->fifo[i_fifo].buffer = malloc( sizeof(s16)*(AOUT_FIFO_SIZE+1)*p_fifo->l_frame_size )) == NULL ) - { - intf_ErrMsg("aout error: not enough memory to create the frames buffer"); - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; - vlc_mutex_unlock( &p_aout->fifos_lock ); - return( NULL ); - } - - /* Allocate the memory needed to store the dates of the frames */ - if ( (p_aout->fifo[i_fifo].date = (mtime_t *)malloc( sizeof(mtime_t)*(AOUT_FIFO_SIZE+1) )) == NULL ) - { - intf_ErrMsg("aout error: not enough memory to create the dates buffer"); - free( p_aout->fifo[i_fifo].buffer ); - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; - vlc_mutex_unlock( &p_aout->fifos_lock ); - return( NULL ); - } - - /* Set the fifo's buffer as empty (the first frame that is to be - * played is also the first frame that is not to be played) */ - p_aout->fifo[i_fifo].l_start_frame = 0; - /* p_aout->fifo[i_fifo].l_next_frame = 0; */ - p_aout->fifo[i_fifo].l_end_frame = 0; - - /* Waiting for the audio decoder to compute enough frames to work - * out the fifo's current rate (as soon as the decoder has decoded - * enough frames, the members of the fifo structure that are not - * initialized now will be calculated) */ - p_aout->fifo[i_fifo].b_start_frame = 0; - p_aout->fifo[i_fifo].b_next_frame = 0; - break; - - default: - intf_ErrMsg("aout error: unknown fifo type (%i)", p_aout->fifo[i_fifo].i_type); - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; - vlc_mutex_unlock( &p_aout->fifos_lock ); - return( NULL ); - } - - /* Release the fifos lock */ - vlc_mutex_unlock( &p_aout->fifos_lock ); - - /* Return the pointer to the fifo structure */ - intf_DbgMsg("aout debug: audio output fifo (%p) allocated", &p_aout->fifo[i_fifo]); - return( &p_aout->fifo[i_fifo] ); -} - -/***************************************************************************** - * aout_DestroyFifo - *****************************************************************************/ -void aout_DestroyFifo( aout_fifo_t * p_fifo ) -{ - intf_DbgMsg("aout debug: requesting destruction of audio output fifo (%p)", p_fifo); - p_fifo->b_die = 1; -} - -/* Here are the local macros */ - -#define UPDATE_INCREMENT( increment, integer ) \ - if ( ((increment).l_remainder += (increment).l_euclidean_remainder) >= 0 )\ - { \ - (integer) += (increment).l_euclidean_integer + 1; \ - (increment).l_remainder -= (increment).l_euclidean_denominator; \ - } \ - else \ - { \ - (integer) += (increment).l_euclidean_integer; \ - } - -/* Following functions are local */ - -/***************************************************************************** - * NextFrame - *****************************************************************************/ -static __inline__ int NextFrame( aout_thread_t * p_aout, aout_fifo_t * p_fifo, mtime_t aout_date ) -{ - long l_units, l_rate; - - /* We take the lock */ - vlc_mutex_lock( &p_fifo->data_lock ); - - /* Are we looking for a dated start frame ? */ - if ( !p_fifo->b_start_frame ) - { - while ( p_fifo->l_start_frame != p_fifo->l_end_frame ) - { - if ( p_fifo->date[p_fifo->l_start_frame] != LAST_MDATE ) - { - p_fifo->b_start_frame = 1; - p_fifo->l_next_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE; - p_fifo->l_unit = p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo)); - break; - } - p_fifo->l_start_frame = (p_fifo->l_start_frame + 1) & AOUT_FIFO_SIZE; - } - - if ( p_fifo->l_start_frame == p_fifo->l_end_frame ) - { - vlc_mutex_unlock( &p_fifo->data_lock ); - return( -1 ); - } - } - - /* We are looking for the next dated frame */ - /* FIXME : is the output fifo full ?? */ - while ( !p_fifo->b_next_frame ) - { - while ( p_fifo->l_next_frame != p_fifo->l_end_frame ) - { - if ( p_fifo->date[p_fifo->l_next_frame] != LAST_MDATE ) - { - p_fifo->b_next_frame = 1; - break; - } - p_fifo->l_next_frame = (p_fifo->l_next_frame + 1) & AOUT_FIFO_SIZE; - } - - while ( p_fifo->l_next_frame == p_fifo->l_end_frame ) - { - vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock ); - if ( p_fifo->b_die ) - { - vlc_mutex_unlock( &p_fifo->data_lock ); - return( -1 ); - } - } - } - - l_units = ((p_fifo->l_next_frame - p_fifo->l_start_frame) & AOUT_FIFO_SIZE) * (p_fifo->l_frame_size >> (p_fifo->b_stereo)); - - l_rate = p_fifo->l_rate + ((aout_date - p_fifo->date[p_fifo->l_start_frame]) / 256); - intf_DbgMsg( "aout debug: %lli (%li);", aout_date - p_fifo->date[p_fifo->l_start_frame], l_rate ); - - InitializeIncrement( &p_fifo->unit_increment, l_rate, p_aout->l_rate ); - - p_fifo->l_units = (((l_units - (p_fifo->l_unit - - (p_fifo->l_start_frame * (p_fifo->l_frame_size >> (p_fifo->b_stereo))))) - * p_aout->l_rate) / l_rate) + 1; - - /* We release the lock before leaving */ - vlc_mutex_unlock( &p_fifo->data_lock ); - return( 0 ); -} - -void aout_Thread_S8_Mono( aout_thread_t * p_aout ) -{ -} - -void aout_Thread_S8_Stereo( aout_thread_t * p_aout ) -{ -} - -void aout_Thread_U8_Mono( aout_thread_t * p_aout ) -{ - int i_fifo; - long l_buffer, l_buffer_limit; - long l_units, l_bytes; - - intf_DbgMsg("adec debug: running audio output U8_M_thread (%p) (pid == %i)", p_aout, getpid()); - - /* As the s32_buffer was created with calloc(), we don't have to set this - * memory to zero and we can immediately jump into the thread's loop */ - while ( !p_aout->b_die ) - { - vlc_mutex_lock( &p_aout->fifos_lock ); - for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ ) - { - switch ( p_aout->fifo[i_fifo].i_type ) - { - case AOUT_EMPTY_FIFO: - break; - - case AOUT_INTF_MONO_FIFO: - if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units ) - { - l_buffer = 0; - while ( l_buffer < (p_aout->l_units) ) /* p_aout->b_stereo == 0 */ - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - } - p_aout->fifo[i_fifo].l_units -= p_aout->l_units; - } - else - { - l_buffer = 0; - while ( l_buffer < (p_aout->fifo[i_fifo].l_units) ) /* p_aout->b_stereo == 0 */ - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - } - free( p_aout->fifo[i_fifo].buffer ); /* !! */ - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */ - intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */ - } - break; - - case AOUT_INTF_STEREO_FIFO: - if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units ) - { - l_buffer = 0; - while ( l_buffer < (p_aout->l_units) ) /* p_aout->b_stereo == 0 */ - { - /* I mix half left - half right */ - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ) / 2 + - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ) / 2; - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - } - p_aout->fifo[i_fifo].l_units -= p_aout->l_units; - } - else - { - l_buffer = 0; - while ( l_buffer < (p_aout->fifo[i_fifo].l_units) ) /* p_aout->b_stereo == 0 */ - { - /* I mix half left - half right */ - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ) / 2 + - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ) / 2; - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - } - free( p_aout->fifo[i_fifo].buffer ); /* !! */ - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */ - intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */ - } - break; - - case AOUT_ADEC_MONO_FIFO: - if ( p_aout->fifo[i_fifo].b_die ) - { - free( p_aout->fifo[i_fifo].buffer ); - free( p_aout->fifo[i_fifo].date ); - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */ - intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); - continue; - } - - l_units = p_aout->l_units; - l_buffer = 0; - while ( l_units > 0 ) - { - if ( !p_aout->fifo[i_fifo].b_next_frame ) - { - if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) ) - { - break; - } - } - - if ( p_aout->fifo[i_fifo].l_units > l_units ) - { - l_buffer_limit = p_aout->l_units; /* p_aout->b_stereo == 0 */ - while ( l_buffer < l_buffer_limit ) - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) ) - { - p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)); - } - } - p_aout->fifo[i_fifo].l_units -= l_units; - break; - } - else - { - l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units); - /* p_aout->b_stereo == 0 */ - while ( l_buffer < l_buffer_limit ) - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) ) - { - p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)); - } - } - l_units -= p_aout->fifo[i_fifo].l_units; - - vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock ); - p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame; - vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait ); - vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock ); - - /* p_aout->fifo[i_fifo].b_start_frame = 1; */ - p_aout->fifo[i_fifo].l_next_frame += 1; - p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE; - p_aout->fifo[i_fifo].b_next_frame = 0; - } - } - break; - - case AOUT_ADEC_STEREO_FIFO: - if ( p_aout->fifo[i_fifo].b_die ) - { - free( p_aout->fifo[i_fifo].buffer ); - free( p_aout->fifo[i_fifo].date ); - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */ - intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); - continue; - } - - l_units = p_aout->l_units; - l_buffer = 0; - while ( l_units > 0 ) - { - if ( !p_aout->fifo[i_fifo].b_next_frame ) - { - if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) ) - { - break; - } - } - - if ( p_aout->fifo[i_fifo].l_units > l_units ) - { - l_buffer_limit = p_aout->l_units; /* p_aout->b_stereo == 0 */ - while ( l_buffer < l_buffer_limit ) - { - /* I mix half left - half right */ - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ) / 2 + - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ) / 2; - - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) ) - { - p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)); - } - } - p_aout->fifo[i_fifo].l_units -= l_units; - break; - } - else - { - l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units); - /* p_aout->b_stereo == 0 */ - while ( l_buffer < l_buffer_limit ) - { - /* I mix half left - half right */ - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ) / 2 + - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ) / 2; - - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) ) - { - p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)); - } - } - l_units -= p_aout->fifo[i_fifo].l_units; - - vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock ); - p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame; - vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait ); - vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock ); - - /* p_aout->fifo[i_fifo].b_start_frame = 1; */ - p_aout->fifo[i_fifo].l_next_frame += 1; - p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE; - p_aout->fifo[i_fifo].b_next_frame = 0; - } - } - break; - - default: - intf_DbgMsg("aout debug: unknown fifo type (%i)", p_aout->fifo[i_fifo].i_type); - break; - } - } - vlc_mutex_unlock( &p_aout->fifos_lock ); - - l_buffer_limit = p_aout->l_units; /* p_aout->b_stereo == 0 */ - - for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ ) - { - ((u8 *)p_aout->buffer)[l_buffer] = (u8)( ( (p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS / 256 ) + 128 ) * p_aout->vol / 256 ); - p_aout->s32_buffer[l_buffer] = 0; - } - l_bytes = p_aout->pf_getbufinfo( p_aout, l_buffer_limit ); - p_aout->date = mdate() + ((((mtime_t)(l_bytes / 1 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 1 */ - p_aout->pf_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) ); - if ( l_bytes > (l_buffer_limit * sizeof(u8) * 2) ) /* There are 2 channels (left & right) */ - { - msleep( p_aout->l_msleep ); - } - } - - vlc_mutex_lock( &p_aout->fifos_lock ); - for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ ) - { - switch ( p_aout->fifo[i_fifo].i_type ) - { - case AOUT_EMPTY_FIFO: - break; - - case AOUT_INTF_MONO_FIFO: - case AOUT_INTF_STEREO_FIFO: - free( p_aout->fifo[i_fifo].buffer ); /* !! */ - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */ - intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); - break; - - case AOUT_ADEC_MONO_FIFO: - case AOUT_ADEC_STEREO_FIFO: - free( p_aout->fifo[i_fifo].buffer ); - free( p_aout->fifo[i_fifo].date ); - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */ - intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); - break; - - default: - break; - } - } - vlc_mutex_unlock( &p_aout->fifos_lock ); - - -} - -void aout_Thread_U8_Stereo( aout_thread_t * p_aout ) -{ - int i_fifo; - long l_buffer, l_buffer_limit; - long l_units, l_bytes; - - intf_DbgMsg("adec debug: running audio output U8_S_thread (%p) (pid == %i)", p_aout, getpid()); - - /* As the s32_buffer was created with calloc(), we don't have to set this - * memory to zero and we can immediately jump into the thread's loop */ - while ( !p_aout->b_die ) - { - vlc_mutex_lock( &p_aout->fifos_lock ); - for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ ) - { - switch ( p_aout->fifo[i_fifo].i_type ) - { - case AOUT_EMPTY_FIFO: - break; - - case AOUT_INTF_MONO_FIFO: - if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units ) - { - l_buffer = 0; - while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */ - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - } - p_aout->fifo[i_fifo].l_units -= p_aout->l_units; - } - else - { - l_buffer = 0; - while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */ - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - } - free( p_aout->fifo[i_fifo].buffer ); /* !! */ - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */ - intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */ - } - break; - - case AOUT_INTF_STEREO_FIFO: - if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units ) - { - l_buffer = 0; - while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */ - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ); - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ); - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - } - p_aout->fifo[i_fifo].l_units -= p_aout->l_units; - } - else - { - l_buffer = 0; - while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */ - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ); - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ); - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - } - free( p_aout->fifo[i_fifo].buffer ); /* !! */ - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */ - intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */ - } - break; - - case AOUT_ADEC_MONO_FIFO: - if ( p_aout->fifo[i_fifo].b_die ) - { - free( p_aout->fifo[i_fifo].buffer ); - free( p_aout->fifo[i_fifo].date ); - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */ - intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); - continue; - } - - l_units = p_aout->l_units; - l_buffer = 0; - while ( l_units > 0 ) - { - if ( !p_aout->fifo[i_fifo].b_next_frame ) - { - if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) ) - { - break; - } - } - - if ( p_aout->fifo[i_fifo].l_units > l_units ) - { - l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */ - while ( l_buffer < l_buffer_limit ) - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) ) - { - p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)); - } - } - p_aout->fifo[i_fifo].l_units -= l_units; - break; - } - else - { - l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1); - /* p_aout->b_stereo == 1 */ - while ( l_buffer < l_buffer_limit ) - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) ) - { - p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)); - } - } - l_units -= p_aout->fifo[i_fifo].l_units; - - vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock ); - p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame; - vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait ); - vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock ); - - /* p_aout->fifo[i_fifo].b_start_frame = 1; */ - p_aout->fifo[i_fifo].l_next_frame += 1; - p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE; - p_aout->fifo[i_fifo].b_next_frame = 0; - } - } - break; - - case AOUT_ADEC_STEREO_FIFO: - if ( p_aout->fifo[i_fifo].b_die ) - { - free( p_aout->fifo[i_fifo].buffer ); - free( p_aout->fifo[i_fifo].date ); - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */ - intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); - continue; - } - - l_units = p_aout->l_units; - l_buffer = 0; - while ( l_units > 0 ) - { - if ( !p_aout->fifo[i_fifo].b_next_frame ) - { - if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) ) - { - break; - } - } - - if ( p_aout->fifo[i_fifo].l_units > l_units ) - { - l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */ - while ( l_buffer < l_buffer_limit ) - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ); - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ); - - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) ) - { - p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)); - } - } - p_aout->fifo[i_fifo].l_units -= l_units; - break; - } - else - { - l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1); - /* p_aout->b_stereo == 1 */ - while ( l_buffer < l_buffer_limit ) - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ); - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ); - - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) ) - { - p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)); - } - } - l_units -= p_aout->fifo[i_fifo].l_units; - - vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock ); - p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame; - vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait ); - vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock ); - - /* p_aout->fifo[i_fifo].b_start_frame = 1; */ - p_aout->fifo[i_fifo].l_next_frame += 1; - p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE; - p_aout->fifo[i_fifo].b_next_frame = 0; - } - } - break; - - default: - intf_DbgMsg("aout debug: unknown fifo type (%i)", p_aout->fifo[i_fifo].i_type); - break; - } - } - vlc_mutex_unlock( &p_aout->fifos_lock ); - - l_buffer_limit = p_aout->l_units << 1 ; /* p_aout->b_stereo == 1 */ - - for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ ) - { - ((u8 *)p_aout->buffer)[l_buffer] = (u8)( ( (p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS / 256) + 128 ) * p_aout->vol / 256 ); - p_aout->s32_buffer[l_buffer] = 0; - } - l_bytes = p_aout->pf_getbufinfo( p_aout, l_buffer_limit ); - p_aout->date = mdate() + ((((mtime_t)(l_bytes / 2 )) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(u8) << (p_aout->b_stereo) == 2 */ - p_aout->pf_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(u8) ); - if ( l_bytes > (l_buffer_limit * sizeof(u8)) ) - { - msleep( p_aout->l_msleep ); - } - } - - vlc_mutex_lock( &p_aout->fifos_lock ); - for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ ) - { - switch ( p_aout->fifo[i_fifo].i_type ) - { - case AOUT_EMPTY_FIFO: - break; - - case AOUT_INTF_MONO_FIFO: - case AOUT_INTF_STEREO_FIFO: - free( p_aout->fifo[i_fifo].buffer ); /* !! */ - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */ - intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); - break; - - case AOUT_ADEC_MONO_FIFO: - case AOUT_ADEC_STEREO_FIFO: - free( p_aout->fifo[i_fifo].buffer ); - free( p_aout->fifo[i_fifo].date ); - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */ - intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); - break; - - default: - break; - } - } - vlc_mutex_unlock( &p_aout->fifos_lock ); - -} - -void aout_Thread_S16_Mono( aout_thread_t * p_aout ) -{ -} - -void aout_Thread_S16_Stereo( aout_thread_t * p_aout ) -{ - int i_fifo; - long l_buffer, l_buffer_limit; - long l_units, l_bytes; - - intf_DbgMsg("adec debug: running audio output S16_S_thread (%p) (pid == %i)", p_aout, getpid()); - - /* As the s32_buffer was created with calloc(), we don't have to set this - * memory to zero and we can immediately jump into the thread's loop */ - while ( !p_aout->b_die ) - { - vlc_mutex_lock( &p_aout->fifos_lock ); - for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ ) - { - switch ( p_aout->fifo[i_fifo].i_type ) - { - case AOUT_EMPTY_FIFO: - break; - - case AOUT_INTF_MONO_FIFO: - if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units ) - { - l_buffer = 0; - while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */ - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - } - p_aout->fifo[i_fifo].l_units -= p_aout->l_units; - } - else - { - l_buffer = 0; - while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */ - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - } - free( p_aout->fifo[i_fifo].buffer ); /* !! */ - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */ - intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */ - } - break; - - case AOUT_INTF_STEREO_FIFO: - if ( p_aout->fifo[i_fifo].l_units > p_aout->l_units ) - { - l_buffer = 0; - while ( l_buffer < (p_aout->l_units << 1) ) /* p_aout->b_stereo == 1 */ - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ); - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ); - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - } - p_aout->fifo[i_fifo].l_units -= p_aout->l_units; - } - else - { - l_buffer = 0; - while ( l_buffer < (p_aout->fifo[i_fifo].l_units << 1) ) /* p_aout->b_stereo == 1 */ - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ); - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ); - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - } - free( p_aout->fifo[i_fifo].buffer ); /* !! */ - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */ - intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); /* !! */ - } - break; - - case AOUT_ADEC_MONO_FIFO: - if ( p_aout->fifo[i_fifo].b_die ) - { - free( p_aout->fifo[i_fifo].buffer ); - free( p_aout->fifo[i_fifo].date ); - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */ - intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); - continue; - } - - l_units = p_aout->l_units; - l_buffer = 0; - while ( l_units > 0 ) - { - if ( !p_aout->fifo[i_fifo].b_next_frame ) - { - if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) ) - { - break; - } - } - - if ( p_aout->fifo[i_fifo].l_units > l_units ) - { - l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */ - while ( l_buffer < l_buffer_limit ) - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) ) - { - p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)); - } - } - p_aout->fifo[i_fifo].l_units -= l_units; - break; - } - else - { - l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1); - /* p_aout->b_stereo == 1 */ - while ( l_buffer < l_buffer_limit ) - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[p_aout->fifo[i_fifo].l_unit] ); - - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 0 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)) ) - { - p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 0 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 0)); - } - } - l_units -= p_aout->fifo[i_fifo].l_units; - - vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock ); - p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame; - vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait ); - vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock ); - - /* p_aout->fifo[i_fifo].b_start_frame = 1; */ - p_aout->fifo[i_fifo].l_next_frame += 1; - p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE; - p_aout->fifo[i_fifo].b_next_frame = 0; - } - } - break; - - case AOUT_ADEC_STEREO_FIFO: - if ( p_aout->fifo[i_fifo].b_die ) - { - free( p_aout->fifo[i_fifo].buffer ); - free( p_aout->fifo[i_fifo].date ); - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */ - intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); - continue; - } - - l_units = p_aout->l_units; - l_buffer = 0; - while ( l_units > 0 ) - { - if ( !p_aout->fifo[i_fifo].b_next_frame ) - { - if ( NextFrame(p_aout, &p_aout->fifo[i_fifo], p_aout->date + ((((mtime_t)(l_buffer >> 1)) * 1000000) / ((mtime_t)p_aout->l_rate))) ) - { - break; - } - } - - if ( p_aout->fifo[i_fifo].l_units > l_units ) - { - l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */ - while ( l_buffer < l_buffer_limit ) - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ); - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ); - - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) ) - { - p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)); - } - } - p_aout->fifo[i_fifo].l_units -= l_units; - break; - } - else - { - l_buffer_limit = l_buffer + (p_aout->fifo[i_fifo].l_units << 1); - /* p_aout->b_stereo == 1 */ - while ( l_buffer < l_buffer_limit ) - { - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit] ); - p_aout->s32_buffer[l_buffer++] += - (s32)( ((s16 *)p_aout->fifo[i_fifo].buffer)[2*p_aout->fifo[i_fifo].l_unit+1] ); - - UPDATE_INCREMENT( p_aout->fifo[i_fifo].unit_increment, p_aout->fifo[i_fifo].l_unit ) - if ( p_aout->fifo[i_fifo].l_unit >= /* p_aout->fifo[i_fifo].b_stereo == 1 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)) ) - { - p_aout->fifo[i_fifo].l_unit -= /* p_aout->fifo[i_fifo].b_stereo == 1 */ - ((AOUT_FIFO_SIZE + 1) * (p_aout->fifo[i_fifo].l_frame_size >> 1)); - } - } - l_units -= p_aout->fifo[i_fifo].l_units; - - vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock ); - p_aout->fifo[i_fifo].l_start_frame = p_aout->fifo[i_fifo].l_next_frame; - vlc_cond_signal( &p_aout->fifo[i_fifo].data_wait ); - vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock ); - - /* p_aout->fifo[i_fifo].b_start_frame = 1; */ - p_aout->fifo[i_fifo].l_next_frame += 1; - p_aout->fifo[i_fifo].l_next_frame &= AOUT_FIFO_SIZE; - p_aout->fifo[i_fifo].b_next_frame = 0; - } - } - break; - - default: - intf_DbgMsg("aout debug: unknown fifo type (%i)", p_aout->fifo[i_fifo].i_type); - break; - } - } - vlc_mutex_unlock( &p_aout->fifos_lock ); - - l_buffer_limit = p_aout->l_units << 1; /* p_aout->b_stereo == 1 */ - - for ( l_buffer = 0; l_buffer < l_buffer_limit; l_buffer++ ) - { - ((s16 *)p_aout->buffer)[l_buffer] = (s16)( ( p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS ) * p_aout->vol / 256 ) ; - p_aout->s32_buffer[l_buffer] = 0; - } - - l_bytes = p_aout->pf_getbufinfo( p_aout, l_buffer_limit ); - p_aout->date = mdate() + ((((mtime_t)(l_bytes / 4)) * 1000000) / ((mtime_t)p_aout->l_rate)); /* sizeof(s16) << (p_aout->b_stereo) == 4 */ - p_aout->pf_play( p_aout, (byte_t *)p_aout->buffer, l_buffer_limit * sizeof(s16) ); - if ( l_bytes > (l_buffer_limit * sizeof(s16)) ) - { - msleep( p_aout->l_msleep ); - } - } - - vlc_mutex_lock( &p_aout->fifos_lock ); - for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ ) - { - switch ( p_aout->fifo[i_fifo].i_type ) - { - case AOUT_EMPTY_FIFO: - break; - - case AOUT_INTF_MONO_FIFO: - case AOUT_INTF_STEREO_FIFO: - free( p_aout->fifo[i_fifo].buffer ); /* !! */ - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */ - intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); - break; - - case AOUT_ADEC_MONO_FIFO: - case AOUT_ADEC_STEREO_FIFO: - free( p_aout->fifo[i_fifo].buffer ); - free( p_aout->fifo[i_fifo].date ); - p_aout->fifo[i_fifo].i_type = AOUT_EMPTY_FIFO; /* !! */ - intf_DbgMsg("aout debug: audio output fifo (%p) destroyed", &p_aout->fifo[i_fifo]); - break; - - default: - break; - } - } - vlc_mutex_unlock( &p_aout->fifos_lock ); -} - -void aout_Thread_U16_Mono( aout_thread_t * p_aout ) -{ -} - -void aout_Thread_U16_Stereo( aout_thread_t * p_aout ) -{ -}