* audio_output.h : audio output thread interface
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: audio_output.h,v 1.39 2001/12/30 07:09:54 sam Exp $
+ * $Id: audio_output.h,v 1.40 2002/01/09 00:33:37 asmax Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
+ * Cyril Deguet <asmax@via.ecp.fr>
*
* 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
void aout_InitBank ( void );
void aout_EndBank ( void );
-aout_thread_t * aout_CreateThread ( int *pi_status );
+aout_thread_t * aout_CreateThread ( int *pi_status, int i_channels,
+ long l_rate );
void aout_DestroyThread ( aout_thread_t *, int * );
aout_fifo_t * aout_CreateFifo ( int, int, long, long, long, void * );
* ac3_adec.c: ac3 decoder module main file
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: ac3_adec.c,v 1.12 2001/12/31 04:53:33 sam Exp $
+ * $Id: ac3_adec.c,v 1.13 2002/01/09 00:33:37 asmax Exp $
*
* Authors: Michel Lespinasse <walken@zoy.org>
*
return ( p_data->i_type == AC3_AUDIO_ES ) ? 50 : 0;
}
-/*****************************************************************************
- * decoder_Run: this function is called just after the thread is created
- *****************************************************************************/
-static int decoder_Run ( decoder_config_t * p_config )
-{
- ac3dec_thread_t * p_ac3thread;
- int sync;
-
- intf_DbgMsg( "ac3_adec debug: ac3_adec thread launched, initializing" );
-
- /* Allocate the memory needed to store the thread's structure */
- p_ac3thread = (ac3dec_thread_t *)memalign(16, sizeof(ac3dec_thread_t));
-
- if( p_ac3thread == NULL )
- {
- intf_ErrMsg ( "ac3_adec error: not enough memory "
- "for decoder_Run() to allocate p_ac3thread" );
- DecoderError( p_config->p_decoder_fifo );
- return( -1 );
- }
-
- /*
- * Initialize the thread properties
- */
- p_ac3thread->p_config = p_config;
- if( InitThread( p_ac3thread ) )
- {
- intf_ErrMsg( "ac3_adec error: could not initialize thread" );
- DecoderError( p_config->p_decoder_fifo );
- free( p_ac3thread );
- return( -1 );
- }
-
- sync = 0;
- p_ac3thread->sync_ptr = 0;
-
- /* ac3 decoder thread's main loop */
- /* FIXME : do we have enough room to store the decoded frames ?? */
- while ((!p_ac3thread->p_fifo->b_die) && (!p_ac3thread->p_fifo->b_error))
- {
- s16 * buffer;
- ac3_sync_info_t sync_info;
- int ptr;
-
- if (!sync) {
- do {
- GetBits(&p_ac3thread->ac3_decoder->bit_stream,8);
- } while ((!p_ac3thread->sync_ptr) && (!p_ac3thread->p_fifo->b_die)
- && (!p_ac3thread->p_fifo->b_error));
-
- ptr = p_ac3thread->sync_ptr;
-
- while(ptr-- && (!p_ac3thread->p_fifo->b_die)
- && (!p_ac3thread->p_fifo->b_error))
- {
- p_ac3thread->ac3_decoder->bit_stream.p_byte++;
- }
-
- /* we are in sync now */
- sync = 1;
- }
-
- if (p_ac3thread->p_fifo->p_first->i_pts)
- {
- p_ac3thread->p_aout_fifo->date[
- p_ac3thread->p_aout_fifo->l_end_frame] =
- p_ac3thread->p_fifo->p_first->i_pts;
- p_ac3thread->p_fifo->p_first->i_pts = 0;
- } else {
- p_ac3thread->p_aout_fifo->date[
- p_ac3thread->p_aout_fifo->l_end_frame] =
- LAST_MDATE;
- }
-
- if (ac3_sync_frame (p_ac3thread->ac3_decoder, &sync_info))
- {
- sync = 0;
- goto bad_frame;
- }
-
- p_ac3thread->p_aout_fifo->l_rate = sync_info.sample_rate;
-
- buffer = ((s16 *)p_ac3thread->p_aout_fifo->buffer) +
- (p_ac3thread->p_aout_fifo->l_end_frame * AC3DEC_FRAME_SIZE);
-
- if (ac3_decode_frame (p_ac3thread->ac3_decoder, buffer))
- {
- sync = 0;
- goto bad_frame;
- }
-
- vlc_mutex_lock (&p_ac3thread->p_aout_fifo->data_lock);
- p_ac3thread->p_aout_fifo->l_end_frame =
- (p_ac3thread->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
- vlc_cond_signal (&p_ac3thread->p_aout_fifo->data_wait);
- vlc_mutex_unlock (&p_ac3thread->p_aout_fifo->data_lock);
-
- bad_frame:
- RealignBits(&p_ac3thread->ac3_decoder->bit_stream);
- }
-
- /* If b_error is set, the ac3 decoder thread enters the error loop */
- if (p_ac3thread->p_fifo->b_error)
- {
- DecoderError( p_ac3thread->p_fifo );
- }
-
- /* End of the ac3 decoder thread */
- EndThread (p_ac3thread);
-
- free( p_ac3thread );
-
- return( 0 );
-}
-
/*****************************************************************************
* InitThread: initialize data before entering main loop
intf_DbgMsg ( "ac3_adec debug: ac3_adec thread (%p) initialized",
p_ac3thread );
- /* Creating the audio output fifo */
- p_ac3thread->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_STEREO_FIFO, 2, 0, 0,
- AC3DEC_FRAME_SIZE, NULL );
- if ( p_ac3thread->p_aout_fifo == NULL )
- {
- free( IMDCT->w_1 );
- free( IMDCT->w_64 );
- free( IMDCT->w_32 );
- free( IMDCT->w_16 );
- free( IMDCT->w_8 );
- free( IMDCT->w_4 );
- free( IMDCT->w_2 );
- free( IMDCT->xcos_sin_sse );
- free( IMDCT->xsin2 );
- free( IMDCT->xcos2 );
- free( IMDCT->xsin1 );
- free( IMDCT->xcos1 );
- free( IMDCT->delay1 );
- free( IMDCT->delay );
- free( IMDCT->buf );
-#undef IMDCT
-
-#if defined( __MINGW32__ )
- free( p_ac3thread->ac3_decoder->samples_back );
-#else
- free( p_ac3thread->ac3_decoder->samples );
-#endif
-
- module_Unneed( p_ac3thread->ac3_decoder->imdct->p_module );
- module_Unneed( p_ac3thread->ac3_decoder->downmix.p_module );
-
- free( p_ac3thread->ac3_decoder->imdct );
- free( p_ac3thread->ac3_decoder );
-
- return( -1 );
- }
-
/*
* Bit stream
*/
return( 0 );
}
+/*****************************************************************************
+ * decoder_Run: this function is called just after the thread is created
+ *****************************************************************************/
+static int decoder_Run ( decoder_config_t * p_config )
+{
+ ac3dec_thread_t * p_ac3thread;
+ int sync;
+
+ intf_DbgMsg( "ac3_adec debug: ac3_adec thread launched, initializing" );
+
+ /* Allocate the memory needed to store the thread's structure */
+ p_ac3thread = (ac3dec_thread_t *)memalign(16, sizeof(ac3dec_thread_t));
+
+ if( p_ac3thread == NULL )
+ {
+ intf_ErrMsg ( "ac3_adec error: not enough memory "
+ "for decoder_Run() to allocate p_ac3thread" );
+ DecoderError( p_config->p_decoder_fifo );
+ return( -1 );
+ }
+
+ /*
+ * Initialize the thread properties
+ */
+ p_ac3thread->p_config = p_config;
+ if( InitThread( p_ac3thread ) )
+ {
+ intf_ErrMsg( "ac3_adec error: could not initialize thread" );
+ DecoderError( p_config->p_decoder_fifo );
+ free( p_ac3thread );
+ return( -1 );
+ }
+
+ sync = 0;
+ p_ac3thread->sync_ptr = 0;
+
+ /* ac3 decoder thread's main loop */
+ /* FIXME : do we have enough room to store the decoded frames ?? */
+ while ((!p_ac3thread->p_fifo->b_die) && (!p_ac3thread->p_fifo->b_error))
+ {
+ s16 * buffer;
+ ac3_sync_info_t sync_info;
+ int ptr;
+
+ if (!sync) {
+ do {
+ GetBits(&p_ac3thread->ac3_decoder->bit_stream,8);
+ } while ((!p_ac3thread->sync_ptr) && (!p_ac3thread->p_fifo->b_die)
+ && (!p_ac3thread->p_fifo->b_error));
+
+ ptr = p_ac3thread->sync_ptr;
+
+ while(ptr-- && (!p_ac3thread->p_fifo->b_die)
+ && (!p_ac3thread->p_fifo->b_error))
+ {
+ p_ac3thread->ac3_decoder->bit_stream.p_byte++;
+ }
+
+ /* we are in sync now */
+ sync = 1;
+ }
+
+ if (ac3_sync_frame (p_ac3thread->ac3_decoder, &sync_info))
+ {
+ sync = 0;
+ goto bad_frame;
+ }
+
+ /* Creating the audio output fifo if not created yet */
+ if (p_ac3thread->p_aout_fifo == NULL ) {
+ p_ac3thread->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_STEREO_FIFO,
+ 2, sync_info.sample_rate, 0, AC3DEC_FRAME_SIZE, NULL );
+ if ( p_ac3thread->p_aout_fifo == NULL )
+ {
+ free( IMDCT->w_1 );
+ free( IMDCT->w_64 );
+ free( IMDCT->w_32 );
+ free( IMDCT->w_16 );
+ free( IMDCT->w_8 );
+ free( IMDCT->w_4 );
+ free( IMDCT->w_2 );
+ free( IMDCT->xcos_sin_sse );
+ free( IMDCT->xsin2 );
+ free( IMDCT->xcos2 );
+ free( IMDCT->xsin1 );
+ free( IMDCT->xcos1 );
+ free( IMDCT->delay1 );
+ free( IMDCT->delay );
+ free( IMDCT->buf );
+ #undef IMDCT
+
+ #if defined( __MINGW32__ )
+ free( p_ac3thread->ac3_decoder->samples_back );
+ #else
+ free( p_ac3thread->ac3_decoder->samples );
+ #endif
+
+ module_Unneed( p_ac3thread->ac3_decoder->imdct->p_module );
+ module_Unneed( p_ac3thread->ac3_decoder->downmix.p_module );
+
+ free( p_ac3thread->ac3_decoder->imdct );
+ free( p_ac3thread->ac3_decoder );
+
+ return( -1 );
+ }
+ }
+
+ if (p_ac3thread->p_fifo->p_first->i_pts)
+ {
+ p_ac3thread->p_aout_fifo->date[
+ p_ac3thread->p_aout_fifo->l_end_frame] =
+ p_ac3thread->p_fifo->p_first->i_pts;
+ p_ac3thread->p_fifo->p_first->i_pts = 0;
+ } else {
+ p_ac3thread->p_aout_fifo->date[
+ p_ac3thread->p_aout_fifo->l_end_frame] =
+ LAST_MDATE;
+ }
+
+ buffer = ((s16 *)p_ac3thread->p_aout_fifo->buffer) +
+ (p_ac3thread->p_aout_fifo->l_end_frame * AC3DEC_FRAME_SIZE);
+
+ if (ac3_decode_frame (p_ac3thread->ac3_decoder, buffer))
+ {
+ sync = 0;
+ goto bad_frame;
+ }
+
+ vlc_mutex_lock (&p_ac3thread->p_aout_fifo->data_lock);
+ p_ac3thread->p_aout_fifo->l_end_frame =
+ (p_ac3thread->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
+ vlc_cond_signal (&p_ac3thread->p_aout_fifo->data_wait);
+ vlc_mutex_unlock (&p_ac3thread->p_aout_fifo->data_lock);
+
+ bad_frame:
+ RealignBits(&p_ac3thread->ac3_decoder->bit_stream);
+ }
+
+ /* If b_error is set, the ac3 decoder thread enters the error loop */
+ if (p_ac3thread->p_fifo->b_error)
+ {
+ DecoderError( p_ac3thread->p_fifo );
+ }
+
+ /* End of the ac3 decoder thread */
+ EndThread (p_ac3thread);
+
+ free( p_ac3thread );
+
+ return( 0 );
+}
+
/*****************************************************************************
* EndThread : ac3 decoder thread destruction
* aout_dsp.c : dsp functions library
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: aout_dsp.c,v 1.18 2001/12/30 07:09:54 sam Exp $
+ * $Id: aout_dsp.c,v 1.19 2002/01/09 00:33:37 asmax Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
/* Initialize some variables */
p_aout->psz_device = main_GetPszVariable( AOUT_DSP_VAR, AOUT_DSP_DEFAULT );
p_aout->i_format = AOUT_FORMAT_DEFAULT;
+
+ /* All that is drawn directly from the audio stream.
p_aout->i_channels = 1 + main_GetIntVariable( AOUT_STEREO_VAR,
AOUT_STEREO_DEFAULT );
p_aout->l_rate = main_GetIntVariable( AOUT_RATE_VAR,
AOUT_RATE_DEFAULT );
+ */
/* Open the sound device */
if( (p_aout->i_fd = open( p_aout->psz_device, O_WRONLY )) < 0 )
* mpeg_adec.c: MPEG audio decoder thread
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: mpeg_adec.c,v 1.10 2001/12/30 07:09:55 sam Exp $
+ * $Id: mpeg_adec.c,v 1.11 2002/01/09 00:33:37 asmax Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr>
* Samuel Hocevar <sam@via.ecp.fr>
+ * Cyril Deguet <asmax@via.ecp.fr>
*
* 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
p_adec->p_config->pf_init_bit_stream( &p_adec->bit_stream,
p_adec->p_config->p_decoder_fifo, NULL, NULL );
- /* Create the audio output fifo */
- p_adec->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_STEREO_FIFO, 2, 0, 0,
- ADEC_FRAME_SIZE, NULL );
- if ( p_adec->p_aout_fifo == NULL )
- {
- intf_ErrMsg("mpeg_adec error: cannot create audio output fifo");
- return -1;
- }
+ /* We do not create the audio output fifo now, but
+ it will be created when the first frame is received */
+ p_adec->p_aout_fifo = NULL;
intf_DbgMsg("mpeg_adec debug: thread initialized, decoding begins.");
if( ! adec_SyncFrame (p_adec, &sync_info) )
{
+
+ /* TODO: check if audio type has changed */
+
+ /* Create the output fifo if it doesn't exist yet */
+ if( p_adec->p_aout_fifo == NULL )
+ {
+ int fifo_type;
+ int channels;
+
+ if( sync_info.b_stereo )
+ {
+ fifo_type = AOUT_ADEC_STEREO_FIFO;
+ channels = 2;
+ }
+ else
+ {
+ fifo_type = AOUT_ADEC_MONO_FIFO;
+ channels = 1;
+ }
+ p_adec->p_aout_fifo = aout_CreateFifo( fifo_type, channels,
+ sync_info.sample_rate, 0, ADEC_FRAME_SIZE, NULL );
+ if( p_adec->p_aout_fifo == NULL)
+ {
+ intf_ErrMsg( "adec error: failed to create Audio Output "
+ "Fifo." );
+ DecoderError( p_adec->p_fifo );
+ }
+ }
+
p_adec->i_sync = 1;
p_adec->p_aout_fifo->l_rate = sync_info.sample_rate;
* adec_generic.c: MPEG audio decoder
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: mpeg_adec_generic.c,v 1.5 2001/12/30 07:09:55 sam Exp $
+ * $Id: mpeg_adec_generic.c,v 1.6 2002/01/09 00:33:37 asmax Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr>
+ * Cyril Deguet <asmax@via.ecp.fr>
*
* 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
RemoveBits( &p_adec->bit_stream, 24 );
p_adec->i_read_bits = 32;
+ if( ! (p_adec->header & 0x10000) )
+ {
+ /* Error check, skip it */
+ RemoveBits( &p_adec->bit_stream, 16 );
+ p_adec->i_read_bits += 16;
+ }
+
+ p_sync_info->b_stereo = ((p_adec->header & 0xc0) != 0xc0);
p_sync_info->sample_rate = sample_rate;
p_sync_info->bit_rate = bit_rate;
p_sync_info->frame_size = frame_size;
{
int i_total_bytes_read;
- if( ! (p_adec->header & 0x10000) )
- {
- /* Error check, skip it */
- RemoveBits( &p_adec->bit_stream, 16 );
- p_adec->i_read_bits += 16;
- }
-
/* parse audio data */
switch( (p_adec->header >> 17) & 3 )
* audio_decoder.h : audio decoder interface
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: mpeg_adec_generic.h,v 1.1 2001/11/13 12:09:18 henri Exp $
+ * $Id: mpeg_adec_generic.h,v 1.2 2002/01/09 00:33:37 asmax Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
*
int sample_rate; /* sample rate in Hz */
int frame_size; /* frame size in bytes */
int bit_rate; /* nominal bit rate in kbps */
+ int b_stereo; /* mono/stereo */
} adec_sync_info_t;
typedef struct adec_bank_s
* aout_ext-dec.c : exported fifo management functions
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: aout_ext-dec.c,v 1.8 2001/12/30 07:09:56 sam Exp $
+ * $Id: aout_ext-dec.c,v 1.9 2002/01/09 00:33:37 asmax Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
+ * Cyril Deguet <asmax@via.ecp.fr>
*
* 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
{
intf_WarnMsg( 1, "aout: no aout present, spawning one" );
- p_aout = aout_CreateThread( NULL );
+ p_aout = aout_CreateThread( NULL, i_channels, l_rate );
/* Everything failed */
if( p_aout == NULL )
aout_DestroyThread( p_aout_bank->pp_aout[0], NULL );
- p_aout = aout_CreateThread( NULL );
+ p_aout = aout_CreateThread( NULL, i_channels, l_rate );
/* Everything failed */
if( p_aout == NULL )
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static void S16StereoPlay( aout_thread_t * p_aout, aout_fifo_t * p_fifo );
+static void S16Play( 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" );
+ 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
+ {
+ S16Play( 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++ )
+ {
+ ((s16 *)p_aout->buffer)[l_buffer] =
+ (s16)( ( p_aout->s32_buffer[l_buffer] / AOUT_MAX_FIFOS )
+ * p_aout->i_volume / 256 ) ;
+ p_aout->s32_buffer[l_buffer] = 0;
+ }
+
+ l_bytes = p_aout->pf_getbufinfo( p_aout, l_buffer_limit );
+
+ /* sizeof(s16) << (p_aout->b_stereo) == 2 */
+ p_aout->date = mdate() + ((((mtime_t)((l_bytes + 2 * p_aout->i_latency) / 2)) * 1000000)
+ / ((mtime_t)p_aout->l_rate))
+ + p_main->i_desync;
+ 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 );
+
}
void aout_S16StereoThread( aout_thread_t * p_aout )
}
else
{
- S16StereoPlay( p_aout, &p_aout->fifo[i_fifo] );
+ S16Play( p_aout, &p_aout->fifo[i_fifo] );
}
}
/* Following functions are local */
-static void S16StereoPlay( aout_thread_t * p_aout, aout_fifo_t * p_fifo )
+static void S16Play( aout_thread_t * p_aout, aout_fifo_t * p_fifo )
{
long l_buffer = 0;
long l_buffer_limit, l_units;
* audio_output.c : audio output thread
*****************************************************************************
* Copyright (C) 1999-2001 VideoLAN
- * $Id: audio_output.c,v 1.69 2001/12/30 07:09:56 sam Exp $
+ * $Id: audio_output.c,v 1.70 2002/01/09 00:33:37 asmax Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
+ * Cyril Deguet <asmax@via.ecp.fr>
*
* 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
/*****************************************************************************
* aout_CreateThread: initialize audio thread
*****************************************************************************/
-aout_thread_t *aout_CreateThread( int *pi_status )
+aout_thread_t *aout_CreateThread( int *pi_status, int i_channels, long l_rate )
{
aout_thread_t * p_aout; /* thread descriptor */
#if 0
return( NULL );
}
- if( p_aout->l_rate == 0 )
- {
- intf_ErrMsg( "aout error: null sample rate" );
- p_aout->pf_close( p_aout );
- module_Unneed( p_aout->p_module );
- free( p_aout );
- return( NULL );
- }
+ p_aout->l_rate = l_rate;
+ p_aout->i_channels = i_channels;
/* special setting for ac3 pass-through mode */
+ /* FIXME is it necessary ? (cf ac3_adec.c) */
if( main_GetIntVariable( AOUT_SPDIF_VAR, 0 ) && p_main->b_ac3 )
{
intf_WarnMsg( 4, "aout info: setting ac3 spdif" );
p_aout->l_rate = 48000;
}
+ if( p_aout->l_rate == 0 )
+ {
+ intf_ErrMsg( "aout error: null sample rate" );
+ p_aout->pf_close( p_aout );
+ module_Unneed( p_aout->p_module );
+ free( p_aout );
+ return( NULL );
+ }
+
/* FIXME: only works for i_channels == 1 or 2 ?? */
p_aout->b_stereo = ( p_aout->i_channels == 2 ) ? 1 : 0;