Commit 81442b6b authored by Christophe Massiot's avatar Christophe Massiot

* Audio volume management now works properly. See src/audio_output/intf.c

  for information on how to use it in your interface plug-ins. In the
  SDL vout, b and n are mapped to sound down/sound up.
* Fixed a major in the mad plug-in with wrong dates.
* Fixed a compilation bug.
parent e059b117
......@@ -2,7 +2,7 @@
* aout_internal.h : internal defines for audio output
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: aout_internal.h,v 1.18 2002/09/18 21:21:23 massiot Exp $
* $Id: aout_internal.h,v 1.19 2002/09/19 21:56:39 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -166,7 +166,7 @@ typedef struct aout_output_t
void (* pf_play)( aout_instance_t * );
int (* pf_volume_get )( aout_instance_t *, audio_volume_t * );
int (* pf_volume_set )( aout_instance_t *, audio_volume_t );
int (* pf_volume_infos )( aout_instance_t *, audio_volume_t *, audio_volume_t * );
int (* pf_volume_infos )( aout_instance_t *, audio_volume_t * );
int i_nb_samples;
/* Current volume for the output - it's just a placeholder, the plug-in
......@@ -259,9 +259,9 @@ void aout_FifoDestroy( aout_instance_t * p_aout, aout_fifo_t * p_fifo );
VLC_EXPORT( void, aout_VolumeSoftInit, ( aout_instance_t * ) );
int aout_VolumeSoftGet( aout_instance_t *, audio_volume_t * );
int aout_VolumeSoftSet( aout_instance_t *, audio_volume_t );
int aout_VolumeSoftInfos( aout_instance_t *, audio_volume_t *, audio_volume_t * );
int aout_VolumeSoftInfos( aout_instance_t *, audio_volume_t * );
VLC_EXPORT( void, aout_VolumeNoneInit, ( aout_instance_t * ) );
int aout_VolumeNoneGet( aout_instance_t *, audio_volume_t * );
int aout_VolumeNoneSet( aout_instance_t *, audio_volume_t );
int aout_VolumeNoneInfos( aout_instance_t *, audio_volume_t *, audio_volume_t * );
int aout_VolumeNoneInfos( aout_instance_t *, audio_volume_t * );
......@@ -2,7 +2,7 @@
* audio_output.h : audio output interface
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: audio_output.h,v 1.64 2002/09/18 21:21:23 massiot Exp $
* $Id: audio_output.h,v 1.65 2002/09/19 21:56:39 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -189,7 +189,7 @@ VLC_EXPORT( void, aout_InputDelete, ( aout_instance_t *, aout_input_t * ) );
/* From intf.c : */
VLC_EXPORT( int, aout_VolumeGet, ( aout_instance_t *, audio_volume_t * ) );
VLC_EXPORT( int, aout_VolumeSet, ( aout_instance_t *, audio_volume_t ) );
VLC_EXPORT( int, aout_VolumeInfos, ( aout_instance_t *, audio_volume_t *, audio_volume_t * ) );
VLC_EXPORT( int, aout_VolumeInfos, ( aout_instance_t *, audio_volume_t * ) );
VLC_EXPORT( int, aout_VolumeUp, ( aout_instance_t *, int, audio_volume_t * ) );
VLC_EXPORT( int, aout_VolumeDown, ( aout_instance_t *, int, audio_volume_t * ) );
......@@ -105,7 +105,7 @@
/* Duration between the time we receive the data packet, and the time we will
* mark it to be presented */
#define DEFAULT_PTS_DELAY (mtime_t)(.2*CLOCK_FREQ)
#define DEFAULT_PTS_DELAY (mtime_t)(.3*CLOCK_FREQ)
/* DVD and VCD devices */
#ifndef WIN32
......
......@@ -40,7 +40,7 @@ struct module_symbols_t
int (* aout_FormatNbChannels_inner) ( audio_sample_format_t * p_format ) ;
int (* aout_VolumeDown_inner) ( aout_instance_t *, int, audio_volume_t * ) ;
int (* aout_VolumeGet_inner) ( aout_instance_t *, audio_volume_t * ) ;
int (* aout_VolumeInfos_inner) ( aout_instance_t *, audio_volume_t *, audio_volume_t * ) ;
int (* aout_VolumeInfos_inner) ( aout_instance_t *, audio_volume_t * ) ;
int (* aout_VolumeSet_inner) ( aout_instance_t *, audio_volume_t ) ;
int (* aout_VolumeUp_inner) ( aout_instance_t *, int, audio_volume_t * ) ;
int (* input_AccessInit_inner) ( input_thread_t * ) ;
......
......@@ -7,3 +7,4 @@ a52tofloat32_SOURCES = a52tofloat32.c
fixed32tos16_SOURCES = fixed32tos16.c
fixed32tofloat32_SOURCES = fixed32tofloat32.c
s16tofloat32_SOURCES = s16tofloat32.c
s16tofloat32swab_SOURCES = s16tofloat32swab.C
......@@ -2,7 +2,7 @@
* float32.c : precise float32 audio mixer implementation
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: float32.c,v 1.2 2002/09/16 20:46:37 massiot Exp $
* $Id: float32.c,v 1.3 2002/09/19 21:56:39 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -110,6 +110,7 @@ static void MeanWords( float * p_out, const float * p_in, size_t i_nb_words,
static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
{
int i_nb_inputs = p_aout->i_nb_inputs;
float f_multiplier = p_aout->mixer.f_multiplier;
int i_input;
for ( i_input = 0; i_input < i_nb_inputs; i_input++ )
......@@ -136,12 +137,12 @@ static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
if ( !i_input )
{
ScaleWords( p_out, p_in, i_available_words,
i_nb_inputs, p_aout->mixer.f_multiplier );
i_nb_inputs, f_multiplier );
}
else
{
MeanWords( p_out, p_in, i_available_words,
i_nb_inputs, p_aout->mixer.f_multiplier );
i_nb_inputs, f_multiplier );
}
}
......@@ -165,12 +166,12 @@ static void DoWork( aout_instance_t * p_aout, aout_buffer_t * p_buffer )
if ( !i_input )
{
ScaleWords( p_out, p_in, i_nb_words, i_nb_inputs,
p_aout->mixer.f_multiplier );
f_multiplier );
}
else
{
MeanWords( p_out, p_in, i_nb_words, i_nb_inputs,
p_aout->mixer.f_multiplier );
f_multiplier );
}
}
p_input->p_first_byte_to_mix = (void *)(p_in
......
......@@ -48,14 +48,8 @@ static void EndThread ( mad_adec_thread_t * );
/*****************************************************************************
* Module descriptor
*****************************************************************************/
#define DOWNSCALE_TEXT N_("mad audio downscale routine (fast,mpg321)")
#define DOWNSCALE_LONGTEXT N_( \
"Specify the mad audio downscale routine you want to use. By default " \
"the mad plugin will use the fastest routine.")
vlc_module_begin();
add_category_hint( N_("Libmad"), NULL );
add_string( "downscale", "fast", NULL, DOWNSCALE_TEXT, DOWNSCALE_LONGTEXT );
set_description( _("libmad MPEG 1/2/3 audio decoder") );
set_capability( "decoder", 100 );
set_callbacks( OpenDecoder, NULL );
......@@ -143,39 +137,16 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
static int InitThread( mad_adec_thread_t * p_dec )
{
decoder_fifo_t * p_fifo = p_dec->p_fifo;
char *psz_downscale = NULL;
/* Initialize the thread properties */
p_dec->p_aout = NULL;
p_dec->p_aout_input = NULL;
p_dec->output_format.i_format = AOUT_FMT_FIXED32;
p_dec->output_format.i_channels = 2; /* FIXME ! */
/*
* Properties of audio for libmad
*/
/* Look what scaling method was requested by the user */
psz_downscale = config_GetPsz( p_fifo, "downscale" );
if ( strncmp(psz_downscale,"fast",4)==0 )
{
p_dec->audio_scaling = FAST_SCALING;
msg_Dbg( p_fifo, "downscale fast selected" );
}
else if ( strncmp(psz_downscale,"mpg321",7)==0 )
{
p_dec->audio_scaling = MPG321_SCALING;
msg_Dbg( p_fifo, "downscale mpg321 selected" );
}
else
{
p_dec->audio_scaling = FAST_SCALING;
msg_Dbg( p_fifo, "downscale default fast selected" );
}
if (psz_downscale) free(psz_downscale);
/* Initialize the libmad decoder structures */
p_dec->i_current_pts = p_dec->i_next_pts = 0;
......@@ -194,9 +165,6 @@ static int InitThread( mad_adec_thread_t * p_dec )
* Initialize the input properties
*/
/* Init the Bitstream */
InitBitstream( &p_dec->bit_stream, p_dec->p_fifo, NULL, NULL );
/* Get the first data packet. */
vlc_mutex_lock( &p_fifo->data_lock );
while ( p_fifo->p_first == NULL )
......
......@@ -38,9 +38,6 @@ typedef struct mad_adec_thread_s
*/
vlc_thread_t thread_id; /* id for thread functions */
/* The bit stream structure handles the PES stream at the bit level */
bit_stream_t bit_stream;
/*
* Input properties
*/
......@@ -57,9 +54,6 @@ typedef struct mad_adec_thread_s
aout_input_t * p_aout_input; /* opaque */
audio_sample_format_t output_format;
audio_date_t end_date;
enum mad_scaling audio_scaling;
} mad_adec_thread_t;
/*****************************************************************************
......
......@@ -91,6 +91,7 @@ enum mad_flow libmad_input( void *p_data, struct mad_stream *p_stream )
/* Store timestamp for this frame */
p_dec->i_current_pts = p_dec->p_fifo->p_first->i_pts;
}
p_dec->p_fifo->p_first->i_pts = 0;
/* Fill-in the buffer. If an error occurs print a message and leave
* the decoding loop. If the end of stream is reached we also leave
......@@ -144,13 +145,14 @@ enum mad_flow libmad_output( void *p_data, struct mad_header const *p_header,
aout_buffer_t * p_buffer;
mad_fixed_t const * p_left = p_pcm->samples[0];
mad_fixed_t const * p_right = p_pcm->samples[1];
register int i_samples = p_pcm->length;
int i_samples = p_pcm->length;
mad_fixed_t * p_samples;
/* Creating the audio output fifo. Assume the samplerate and nr of channels
* from the first decoded frame is right for the entire audio track. */
if( (p_dec->p_aout_input != NULL) &&
(p_dec->output_format.i_rate != p_pcm->samplerate) )
(p_dec->output_format.i_rate != p_pcm->samplerate
|| p_dec->output_format.i_channels != p_pcm->channels) )
{
/* Parameters changed - this should not happen. */
aout_InputDelete( p_dec->p_aout, p_dec->p_aout_input );
......@@ -161,7 +163,7 @@ enum mad_flow libmad_output( void *p_data, struct mad_header const *p_header,
if( p_dec->p_aout_input == NULL )
{
p_dec->output_format.i_rate = p_pcm->samplerate;
/* p_dec->output_format.i_channels = p_pcm->channels; */
p_dec->output_format.i_channels = p_pcm->channels;
aout_DateInit( &p_dec->end_date, p_pcm->samplerate );
p_dec->p_aout_input = aout_InputNew( p_dec->p_fifo,
&p_dec->p_aout,
......@@ -221,12 +223,8 @@ enum mad_flow libmad_output( void *p_data, struct mad_header const *p_header,
}
break;
case 1:
while( i_samples-- )
{
*p_samples++ = *p_left;
*p_samples++ = *p_left++;
}
break;
p_dec->p_fifo->p_vlc->pf_memcpy( p_samples, p_left,
i_samples * sizeof(mad_fixed_t) );
default:
msg_Err( p_dec->p_fifo, "cannot interleave %i channels",
p_pcm->channels );
......
......@@ -2,7 +2,7 @@
* sdl.c: SDL video output display method
*****************************************************************************
* Copyright (C) 1998-2001 VideoLAN
* $Id: sdl.c,v 1.1 2002/08/13 11:59:36 sam Exp $
* $Id: sdl.c,v 1.2 2002/09/19 21:56:40 massiot Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Pierre Baillet <oct@zoy.org>
......@@ -429,7 +429,7 @@ static int Manage( vout_thread_t *p_vout )
intf_thread_t *p_intf;
p_intf = vlc_object_find( p_vout, VLC_OBJECT_INTF,
FIND_ANYWHERE );
if( p_intf )
if( p_intf != NULL )
{
p_intf->b_menu_change = 1;
vlc_object_release( p_intf );
......@@ -466,6 +466,48 @@ static int Manage( vout_thread_t *p_vout )
case SDLK_F11: network_ChannelJoin( p_vout, 11 ); break;
case SDLK_F12: network_ChannelJoin( p_vout, 12 ); break;
case SDLK_b:
{
aout_instance_t * p_aout;
audio_volume_t i_volume;
p_aout = vlc_object_find( p_vout, VLC_OBJECT_AOUT,
FIND_ANYWHERE );
if( p_aout != NULL )
{
if ( !aout_VolumeDown( p_aout, 1, &i_volume ) )
{
msg_Dbg( p_vout, "audio volume is now %d", i_volume );
}
else
{
msg_Dbg( p_vout, "audio volume: operation not supported" );
}
vlc_object_release( (vlc_object_t *)p_aout );
}
}
break;
case SDLK_n:
{
aout_instance_t * p_aout;
audio_volume_t i_volume;
p_aout = vlc_object_find( p_vout, VLC_OBJECT_AOUT,
FIND_ANYWHERE );
if( p_aout != NULL )
{
if ( !aout_VolumeUp( p_aout, 1, &i_volume ) )
{
msg_Dbg( p_vout, "audio volume is now %d", i_volume );
}
else
{
msg_Dbg( p_vout, "audio volume: operation not supported" );
}
vlc_object_release( (vlc_object_t *)p_aout );
}
}
break;
default:
break;
}
......
......@@ -2,7 +2,7 @@
* intf.c : audio output API towards the interface modules
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: intf.c,v 1.2 2002/09/18 21:21:24 massiot Exp $
* $Id: intf.c,v 1.3 2002/09/19 21:56:40 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -41,21 +41,18 @@
*
* Here is a schematic of the i_volume range :
*
* |------------------+------------------------------------+--------------|
* 0 pi_low_soft pi_high_soft 1024
* |------------------------------+---------------------------------------|
* 0 pi_soft 1024
*
* Between pi_low_soft and pi_high_soft, the volume is done in hardware
* by the output module. Outside, the output module will change
* p_aout->mixer.i_multiplier (done in software). This scaling may result
* in cropping errors and should be avoided as much as possible.
* Between 0 and pi_soft, the volume is done in hardware by the output
* module. Above, the output module will change p_aout->mixer.i_multiplier
* (done in software). This scaling may result * in cropping errors and
* should be avoided as much as possible.
*
* It is legal to have *pi_low_soft == *pi_high_soft, and do everything in
* software. In that case, it is recommended to use *pi_low_soft == 256,
* along with the utility functions provided in this file.
*
* It is also legal to have *pi_low_soft == 0 and *pi_high_soft == 1024, and
* completely avoid software scaling. However, some streams (esp. A/52)
* are encoded with a very low volume and users may complain.
* It is legal to have *pi_soft == 0, and do everything in software.
* It is also legal to have *pi_soft == 1024, and completely avoid
* software scaling. However, some streams (esp. A/52) are encoded with
* a very low volume and users may complain.
*/
/*****************************************************************************
......@@ -77,7 +74,7 @@ int aout_VolumeGet( aout_instance_t * p_aout, audio_volume_t * pi_volume )
i_result = p_aout->output.pf_volume_get( p_aout, pi_volume );
vlc_mutex_lock( &p_aout->mixer_lock );
vlc_mutex_unlock( &p_aout->mixer_lock );
return i_result;
}
......@@ -100,15 +97,14 @@ int aout_VolumeSet( aout_instance_t * p_aout, audio_volume_t i_volume )
i_result = p_aout->output.pf_volume_set( p_aout, i_volume );
vlc_mutex_lock( &p_aout->mixer_lock );
vlc_mutex_unlock( &p_aout->mixer_lock );
return i_result;
}
/*****************************************************************************
* aout_VolumeInfos : get the boundaries pi_low_soft and pi_high_soft
*****************************************************************************/
int aout_VolumeInfos( aout_instance_t * p_aout, audio_volume_t * pi_low_soft,
audio_volume_t * pi_high_soft )
int aout_VolumeInfos( aout_instance_t * p_aout, audio_volume_t * pi_soft )
{
int i_result;
......@@ -122,10 +118,9 @@ int aout_VolumeInfos( aout_instance_t * p_aout, audio_volume_t * pi_low_soft,
return -1;
}
i_result = p_aout->output.pf_volume_infos( p_aout, pi_low_soft,
pi_high_soft );
i_result = p_aout->output.pf_volume_infos( p_aout, pi_soft );
vlc_mutex_lock( &p_aout->mixer_lock );
vlc_mutex_unlock( &p_aout->mixer_lock );
return i_result;
}
......@@ -162,7 +157,7 @@ int aout_VolumeUp( aout_instance_t * p_aout, int i_nb_steps,
i_result = p_aout->output.pf_volume_set( p_aout, i_volume );
vlc_mutex_lock( &p_aout->mixer_lock );
vlc_mutex_unlock( &p_aout->mixer_lock );
if ( pi_volume != NULL ) *pi_volume = i_volume;
return i_result;
......@@ -203,7 +198,7 @@ int aout_VolumeDown( aout_instance_t * p_aout, int i_nb_steps,
i_result = p_aout->output.pf_volume_set( p_aout, i_volume );
vlc_mutex_lock( &p_aout->mixer_lock );
vlc_mutex_unlock( &p_aout->mixer_lock );
if ( pi_volume != NULL ) *pi_volume = i_volume;
return i_result;
......@@ -219,33 +214,28 @@ void aout_VolumeSoftInit( aout_instance_t * p_aout )
{
int i_volume;
p_aout->output.pf_volume_infos = aout_VolumeSoftInfos;
p_aout->output.pf_volume_get = aout_VolumeSoftGet;
p_aout->output.pf_volume_set = aout_VolumeSoftSet;
i_volume = config_GetInt( p_aout, "volume" );
if ( i_volume == -1 )
{
p_aout->output.i_volume = AOUT_VOLUME_DEFAULT;
}
else
{
p_aout->output.i_volume = i_volume;
i_volume = AOUT_VOLUME_DEFAULT;
}
p_aout->output.pf_volume_infos = aout_VolumeSoftInfos;
p_aout->output.pf_volume_get = aout_VolumeSoftGet;
p_aout->output.pf_volume_set = aout_VolumeSoftSet;
aout_VolumeSoftSet( p_aout, i_volume );
}
/* Placeholder for pf_volume_infos(). */
int aout_VolumeSoftInfos( aout_instance_t * p_aout,
audio_volume_t * pi_low_soft,
audio_volume_t * pi_high_soft )
int aout_VolumeSoftInfos( aout_instance_t * p_aout, audio_volume_t * pi_soft )
{
*pi_low_soft = *pi_high_soft = AOUT_VOLUME_DEFAULT;
*pi_soft = 0;
return 0;
}
/* Placeholder for pf_volume_get(). */
int aout_VolumeSoftGet( aout_instance_t * p_aout,
audio_volume_t * pi_volume )
int aout_VolumeSoftGet( aout_instance_t * p_aout, audio_volume_t * pi_volume )
{
*pi_volume = p_aout->output.i_volume;
return 0;
......@@ -253,10 +243,10 @@ int aout_VolumeSoftGet( aout_instance_t * p_aout,
/* Placeholder for pf_volume_set(). */
int aout_VolumeSoftSet( aout_instance_t * p_aout,
audio_volume_t i_volume )
int aout_VolumeSoftSet( aout_instance_t * p_aout, audio_volume_t i_volume )
{
aout_MixerMultiplierSet( p_aout, (float)(i_volume / AOUT_VOLUME_DEFAULT) );
aout_MixerMultiplierSet( p_aout, (float)i_volume / AOUT_VOLUME_DEFAULT );
p_aout->output.i_volume = i_volume;
return 0;
}
......@@ -274,9 +264,7 @@ void aout_VolumeNoneInit( aout_instance_t * p_aout )
}
/* Placeholder for pf_volume_infos(). */
int aout_VolumeNoneInfos( aout_instance_t * p_aout,
audio_volume_t * pi_low_soft,
audio_volume_t * pi_high_soft )
int aout_VolumeNoneInfos( aout_instance_t * p_aout, audio_volume_t * pi_soft )
{
return -1;
}
......
......@@ -2,7 +2,7 @@
* mixer.c : audio output mixing operations
*****************************************************************************
* Copyright (C) 2002 VideoLAN
* $Id: mixer.c,v 1.12 2002/09/16 20:46:38 massiot Exp $
* $Id: mixer.c,v 1.13 2002/09/19 21:56:40 massiot Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -86,8 +86,8 @@ static int MixBuffer( aout_instance_t * p_aout )
/* The output is _very_ late. This can only happen if the user
* pauses the stream (or if the decoder is buggy, which cannot
* happen :). */
msg_Warn( p_aout, "Output PTS is out of range (%lld), clearing out",
start_date );
msg_Warn( p_aout, "output PTS is out of range (%lld), clearing out",
mdate() - start_date );
aout_FifoSet( p_aout, &p_aout->output.fifo, 0 );
aout_DateSet( &exact_start_date, 0 );
start_date = 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