Commit 1ae5bed4 authored by Cyril Deguet's avatar Cyril Deguet

- better communication between audio decoder and output: aout plugins

are now opened directly in the right mode (works with mpeg_adec and
ac3_adec, not tested with mad)
- first attempt to implement mono output (doesn't work yet)
parent 1bed861b
...@@ -2,9 +2,10 @@ ...@@ -2,9 +2,10 @@
* audio_output.h : audio output thread interface * audio_output.h : audio output thread interface
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * 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> * 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 * 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 * it under the terms of the GNU General Public License as published by
...@@ -212,7 +213,8 @@ typedef struct aout_thread_s ...@@ -212,7 +213,8 @@ typedef struct aout_thread_s
void aout_InitBank ( void ); void aout_InitBank ( void );
void aout_EndBank ( 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 * ); void aout_DestroyThread ( aout_thread_t *, int * );
aout_fifo_t * aout_CreateFifo ( int, int, long, long, long, void * ); aout_fifo_t * aout_CreateFifo ( int, int, long, long, long, void * );
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ac3_adec.c: ac3 decoder module main file * ac3_adec.c: ac3 decoder module main file
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Authors: Michel Lespinasse <walken@zoy.org>
* *
...@@ -95,121 +95,6 @@ static int decoder_Probe( probedata_t *p_data ) ...@@ -95,121 +95,6 @@ static int decoder_Probe( probedata_t *p_data )
return ( p_data->i_type == AC3_AUDIO_ES ) ? 50 : 0; 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 * InitThread: initialize data before entering main loop
...@@ -312,9 +197,91 @@ static int InitThread( ac3dec_thread_t * p_ac3thread ) ...@@ -312,9 +197,91 @@ static int InitThread( ac3dec_thread_t * p_ac3thread )
intf_DbgMsg ( "ac3_adec debug: ac3_adec thread (%p) initialized", intf_DbgMsg ( "ac3_adec debug: ac3_adec thread (%p) initialized",
p_ac3thread ); p_ac3thread );
/* Creating the audio output fifo */ /*
p_ac3thread->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_STEREO_FIFO, 2, 0, 0, * Bit stream
AC3DEC_FRAME_SIZE, NULL ); */
p_ac3thread->p_config->pf_init_bit_stream(
&p_ac3thread->ac3_decoder->bit_stream,
p_ac3thread->p_config->p_decoder_fifo,
BitstreamCallback, (void *) p_ac3thread );
intf_DbgMsg("ac3dec debug: ac3 decoder thread %p initialized", p_ac3thread);
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 ) if ( p_ac3thread->p_aout_fifo == NULL )
{ {
free( IMDCT->w_1 ); free( IMDCT->w_1 );
...@@ -332,13 +299,13 @@ static int InitThread( ac3dec_thread_t * p_ac3thread ) ...@@ -332,13 +299,13 @@ static int InitThread( ac3dec_thread_t * p_ac3thread )
free( IMDCT->delay1 ); free( IMDCT->delay1 );
free( IMDCT->delay ); free( IMDCT->delay );
free( IMDCT->buf ); free( IMDCT->buf );
#undef IMDCT #undef IMDCT
#if defined( __MINGW32__ ) #if defined( __MINGW32__ )
free( p_ac3thread->ac3_decoder->samples_back ); free( p_ac3thread->ac3_decoder->samples_back );
#else #else
free( p_ac3thread->ac3_decoder->samples ); free( p_ac3thread->ac3_decoder->samples );
#endif #endif
module_Unneed( p_ac3thread->ac3_decoder->imdct->p_module ); module_Unneed( p_ac3thread->ac3_decoder->imdct->p_module );
module_Unneed( p_ac3thread->ac3_decoder->downmix.p_module ); module_Unneed( p_ac3thread->ac3_decoder->downmix.p_module );
...@@ -348,16 +315,49 @@ static int InitThread( ac3dec_thread_t * p_ac3thread ) ...@@ -348,16 +315,49 @@ static int InitThread( ac3dec_thread_t * p_ac3thread )
return( -1 ); return( -1 );
} }
}
/* if (p_ac3thread->p_fifo->p_first->i_pts)
* Bit stream {
*/ p_ac3thread->p_aout_fifo->date[
p_ac3thread->p_config->pf_init_bit_stream( p_ac3thread->p_aout_fifo->l_end_frame] =
&p_ac3thread->ac3_decoder->bit_stream, p_ac3thread->p_fifo->p_first->i_pts;
p_ac3thread->p_config->p_decoder_fifo, p_ac3thread->p_fifo->p_first->i_pts = 0;
BitstreamCallback, (void *) p_ac3thread ); } else {
p_ac3thread->p_aout_fifo->date[
p_ac3thread->p_aout_fifo->l_end_frame] =
LAST_MDATE;
}
intf_DbgMsg("ac3dec debug: ac3 decoder thread %p initialized", p_ac3thread); 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 ); return( 0 );
} }
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* aout_dsp.c : dsp functions library * aout_dsp.c : dsp functions library
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org> * Samuel Hocevar <sam@zoy.org>
...@@ -133,10 +133,13 @@ static int aout_Open( aout_thread_t *p_aout ) ...@@ -133,10 +133,13 @@ static int aout_Open( aout_thread_t *p_aout )
/* Initialize some variables */ /* Initialize some variables */
p_aout->psz_device = main_GetPszVariable( AOUT_DSP_VAR, AOUT_DSP_DEFAULT ); p_aout->psz_device = main_GetPszVariable( AOUT_DSP_VAR, AOUT_DSP_DEFAULT );
p_aout->i_format = AOUT_FORMAT_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, p_aout->i_channels = 1 + main_GetIntVariable( AOUT_STEREO_VAR,
AOUT_STEREO_DEFAULT ); AOUT_STEREO_DEFAULT );
p_aout->l_rate = main_GetIntVariable( AOUT_RATE_VAR, p_aout->l_rate = main_GetIntVariable( AOUT_RATE_VAR,
AOUT_RATE_DEFAULT ); AOUT_RATE_DEFAULT );
*/
/* Open the sound device */ /* Open the sound device */
if( (p_aout->i_fd = open( p_aout->psz_device, O_WRONLY )) < 0 ) if( (p_aout->i_fd = open( p_aout->psz_device, O_WRONLY )) < 0 )
......
...@@ -2,11 +2,12 @@ ...@@ -2,11 +2,12 @@
* mpeg_adec.c: MPEG audio decoder thread * mpeg_adec.c: MPEG audio decoder thread
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr> * Michel Lespinasse <walken@via.ecp.fr>
* Samuel Hocevar <sam@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 * 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 * it under the terms of the GNU General Public License as published by
...@@ -125,14 +126,9 @@ static int decoder_Run ( decoder_config_t * p_config ) ...@@ -125,14 +126,9 @@ static int decoder_Run ( decoder_config_t * p_config )
p_adec->p_config->pf_init_bit_stream( &p_adec->bit_stream, p_adec->p_config->pf_init_bit_stream( &p_adec->bit_stream,
p_adec->p_config->p_decoder_fifo, NULL, NULL ); p_adec->p_config->p_decoder_fifo, NULL, NULL );
/* Create the audio output fifo */ /* We do not create the audio output fifo now, but
p_adec->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_STEREO_FIFO, 2, 0, 0, it will be created when the first frame is received */
ADEC_FRAME_SIZE, NULL ); p_adec->p_aout_fifo = NULL;
if ( p_adec->p_aout_fifo == NULL )
{
intf_ErrMsg("mpeg_adec error: cannot create audio output fifo");
return -1;
}
intf_DbgMsg("mpeg_adec debug: thread initialized, decoding begins."); intf_DbgMsg("mpeg_adec debug: thread initialized, decoding begins.");
...@@ -170,6 +166,35 @@ static void DecodeThread( adec_thread_t * p_adec ) ...@@ -170,6 +166,35 @@ static void DecodeThread( adec_thread_t * p_adec )
if( ! adec_SyncFrame (p_adec, &sync_info) ) 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->i_sync = 1;
p_adec->p_aout_fifo->l_rate = sync_info.sample_rate; p_adec->p_aout_fifo->l_rate = sync_info.sample_rate;
......
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
* adec_generic.c: MPEG audio decoder * adec_generic.c: MPEG audio decoder
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* Michel Lespinasse <walken@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 * 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 * it under the terms of the GNU General Public License as published by
...@@ -167,6 +168,14 @@ int adec_SyncFrame( adec_thread_t * p_adec, adec_sync_info_t * p_sync_info ) ...@@ -167,6 +168,14 @@ int adec_SyncFrame( adec_thread_t * p_adec, adec_sync_info_t * p_sync_info )
RemoveBits( &p_adec->bit_stream, 24 ); RemoveBits( &p_adec->bit_stream, 24 );
p_adec->i_read_bits = 32; 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->sample_rate = sample_rate;
p_sync_info->bit_rate = bit_rate; p_sync_info->bit_rate = bit_rate;
p_sync_info->frame_size = frame_size; p_sync_info->frame_size = frame_size;
...@@ -179,13 +188,6 @@ int adec_DecodeFrame( adec_thread_t * p_adec, s16 * buffer ) ...@@ -179,13 +188,6 @@ int adec_DecodeFrame( adec_thread_t * p_adec, s16 * buffer )
{ {
int i_total_bytes_read; 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 */ /* parse audio data */
switch( (p_adec->header >> 17) & 3 ) switch( (p_adec->header >> 17) & 3 )
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* audio_decoder.h : audio decoder interface * audio_decoder.h : audio decoder interface
***************************************************************************** *****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN * 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> * Authors: Michel Kaempf <maxx@via.ecp.fr>
* *
...@@ -29,6 +29,7 @@ typedef struct adec_sync_info_s { ...@@ -29,6 +29,7 @@ typedef struct adec_sync_info_s {
int sample_rate; /* sample rate in Hz */ int sample_rate; /* sample rate in Hz */
int frame_size; /* frame size in bytes */ int frame_size; /* frame size in bytes */
int bit_rate; /* nominal bit rate in kbps */ int bit_rate; /* nominal bit rate in kbps */
int b_stereo; /* mono/stereo */
} adec_sync_info_t; } adec_sync_info_t;
typedef struct adec_bank_s typedef struct adec_bank_s
......
...@@ -2,9 +2,10 @@ ...@@ -2,9 +2,10 @@
* aout_ext-dec.c : exported fifo management functions * aout_ext-dec.c : exported fifo management functions
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * 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 * 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 * it under the terms of the GNU General Public License as published by
...@@ -50,7 +51,7 @@ aout_fifo_t * aout_CreateFifo( int i_type, int i_channels, long l_rate, ...@@ -50,7 +51,7 @@ aout_fifo_t * aout_CreateFifo( int i_type, int i_channels, long l_rate,
{ {
intf_WarnMsg( 1, "aout: no aout present, spawning one" ); 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 */ /* Everything failed */
if( p_aout == NULL ) if( p_aout == NULL )
...@@ -70,7 +71,7 @@ aout_fifo_t * aout_CreateFifo( int i_type, int i_channels, long l_rate, ...@@ -70,7 +71,7 @@ aout_fifo_t * aout_CreateFifo( int i_type, int i_channels, long l_rate,
aout_DestroyThread( p_aout_bank->pp_aout[0], 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 */ /* Everything failed */
if( p_aout == NULL ) if( p_aout == NULL )
......
...@@ -35,14 +35,70 @@ ...@@ -35,14 +35,70 @@
/***************************************************************************** /*****************************************************************************
* Local prototypes * 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 * Functions
*****************************************************************************/ *****************************************************************************/
void aout_S16MonoThread( aout_thread_t * p_aout ) 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 ) void aout_S16StereoThread( aout_thread_t * p_aout )
...@@ -64,7 +120,7 @@ void aout_S16StereoThread( aout_thread_t * p_aout ) ...@@ -64,7 +120,7 @@ void aout_S16StereoThread( aout_thread_t * p_aout )
} }
else else
{ {
S16StereoPlay( p_aout, &p_aout->fifo[i_fifo] ); S16Play( p_aout, &p_aout->fifo[i_fifo] );
} }
} }
...@@ -107,7 +163,7 @@ void aout_S16StereoThread( aout_thread_t * p_aout ) ...@@ -107,7 +163,7 @@ void aout_S16StereoThread( aout_thread_t * p_aout )
/* Following functions are local */ /* 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 = 0;
long l_buffer_limit, l_units; long l_buffer_limit, l_units;
......
...@@ -2,9 +2,10 @@ ...@@ -2,9 +2,10 @@
* audio_output.c : audio output thread * audio_output.c : audio output thread
***************************************************************************** *****************************************************************************
* Copyright (C) 1999-2001 VideoLAN * 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> * 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 * 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 * it under the terms of the GNU General Public License as published by
...@@ -77,7 +78,7 @@ void aout_EndBank ( void ) ...@@ -77,7 +78,7 @@ void aout_EndBank ( void )
/***************************************************************************** /*****************************************************************************
* aout_CreateThread: initialize audio thread * 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 */ aout_thread_t * p_aout; /* thread descriptor */
#if 0 #if 0
...@@ -121,16 +122,11 @@ aout_thread_t *aout_CreateThread( int *pi_status ) ...@@ -121,16 +122,11 @@ aout_thread_t *aout_CreateThread( int *pi_status )
return( NULL ); return( NULL );
} }
if( p_aout->l_rate == 0 ) p_aout->l_rate = l_rate;
{ p_aout->i_channels = i_channels;
intf_ErrMsg( "aout error: null sample rate" );
p_aout->pf_close( p_aout );
module_Unneed( p_aout->p_module );
free( p_aout );
return( NULL );
}
/* special setting for ac3 pass-through mode */ /* 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 ) if( main_GetIntVariable( AOUT_SPDIF_VAR, 0 ) && p_main->b_ac3 )
{ {
intf_WarnMsg( 4, "aout info: setting ac3 spdif" ); intf_WarnMsg( 4, "aout info: setting ac3 spdif" );
...@@ -138,6 +134,15 @@ aout_thread_t *aout_CreateThread( int *pi_status ) ...@@ -138,6 +134,15 @@ aout_thread_t *aout_CreateThread( int *pi_status )
p_aout->l_rate = 48000; 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 ?? */ /* FIXME: only works for i_channels == 1 or 2 ?? */
p_aout->b_stereo = ( p_aout->i_channels == 2 ) ? 1 : 0; p_aout->b_stereo = ( p_aout->i_channels == 2 ) ? 1 : 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment