Remove mixing from audio mixers

Only software amplification is left
This commit is contained in:
Rémi Denis-Courmont 2011-04-07 21:36:02 +03:00
parent a0ee6ee7c6
commit bcb8d0bc6f
5 changed files with 42 additions and 143 deletions

View File

@ -84,8 +84,7 @@ struct aout_mixer_t {
float multiplier;
/* Array of mixer inputs */
unsigned input_count;
aout_mixer_input_t **input;
aout_mixer_input_t *input;
/* Mix input into the given buffer (mandatory) */
void (*mix)(aout_mixer_t *, aout_buffer_t *);

View File

@ -63,11 +63,8 @@ static int Create( vlc_object_t *p_this )
return -1;
/* Use the trivial mixer when we can */
if ( p_mixer->input_count == 1 && p_mixer->multiplier == 1.0 )
{
if( p_mixer->input[0]->multiplier == 1.0 )
return -1;
}
if( p_mixer->multiplier == 1.0 && p_mixer->input->multiplier == 1.0 )
return -1;
p_mixer->mix = DoWork;
return 0;
@ -77,30 +74,10 @@ static int Create( vlc_object_t *p_this )
* ScaleWords: prepare input words for averaging
*****************************************************************************/
static void ScaleWords( float * p_out, const float * p_in, size_t i_nb_words,
int i_nb_inputs, float f_multiplier )
float f_multiplier )
{
int i;
f_multiplier /= i_nb_inputs;
for ( i = i_nb_words; i--; )
{
for( size_t i = i_nb_words; i--; )
*p_out++ = *p_in++ * f_multiplier;
}
}
/*****************************************************************************
* MeanWords: average input words
*****************************************************************************/
static void MeanWords( float * p_out, const float * p_in, size_t i_nb_words,
int i_nb_inputs, float f_multiplier )
{
int i;
f_multiplier /= i_nb_inputs;
for ( i = i_nb_words; i--; )
{
*p_out++ += *p_in++ * f_multiplier;
}
}
/*****************************************************************************
@ -111,79 +88,49 @@ static void MeanWords( float * p_out, const float * p_in, size_t i_nb_words,
*****************************************************************************/
static void DoWork( aout_mixer_t * p_mixer, aout_buffer_t * p_buffer )
{
const int i_nb_inputs = p_mixer->input_count;
const float f_multiplier_global = p_mixer->multiplier;
const int i_nb_channels = aout_FormatNbChannels( &p_mixer->fmt );
int i_input;
for ( i_input = 0; i_input < i_nb_inputs; i_input++ )
int i_nb_words = p_buffer->i_nb_samples * i_nb_channels;
aout_mixer_input_t * p_input = p_mixer->input;
float f_multiplier = f_multiplier_global * p_input->multiplier;
float * p_out = (float *)p_buffer->p_buffer;
float * p_in = (float *)p_input->begin;
for( ; ; )
{
int i_nb_words = p_buffer->i_nb_samples * i_nb_channels;
aout_mixer_input_t * p_input = p_mixer->input[i_input];
float f_multiplier = f_multiplier_global * p_input->multiplier;
ptrdiff_t i_available_words = (
(float *)p_input->fifo.p_first->p_buffer - p_in)
+ p_input->fifo.p_first->i_nb_samples
* i_nb_channels;
float * p_out = (float *)p_buffer->p_buffer;
float * p_in = (float *)p_input->begin;
if ( p_input->is_invalid )
continue;
for ( ; ; )
if( i_available_words < i_nb_words )
{
ptrdiff_t i_available_words = (
(float *)p_input->fifo.p_first->p_buffer - p_in)
+ p_input->fifo.p_first->i_nb_samples
* i_nb_channels;
aout_buffer_t * p_old_buffer;
if ( i_available_words < i_nb_words )
if( i_available_words > 0 )
ScaleWords( p_out, p_in, i_available_words, f_multiplier );
i_nb_words -= i_available_words;
p_out += i_available_words;
/* Next buffer */
p_old_buffer = aout_FifoPop( NULL, &p_input->fifo );
aout_BufferFree( p_old_buffer );
if( p_input->fifo.p_first == NULL )
{
aout_buffer_t * p_old_buffer;
if ( i_available_words > 0 )
{
if ( !i_input )
{
ScaleWords( p_out, p_in, i_available_words,
i_nb_inputs, f_multiplier );
}
else
{
MeanWords( p_out, p_in, i_available_words,
i_nb_inputs, f_multiplier );
}
}
i_nb_words -= i_available_words;
p_out += i_available_words;
/* Next buffer */
p_old_buffer = aout_FifoPop( NULL, &p_input->fifo );
aout_BufferFree( p_old_buffer );
if ( p_input->fifo.p_first == NULL )
{
msg_Err( p_mixer, "internal amix error" );
return;
}
p_in = (float *)p_input->fifo.p_first->p_buffer;
}
else
{
if ( i_nb_words > 0 )
{
if ( !i_input )
{
ScaleWords( p_out, p_in, i_nb_words, i_nb_inputs,
f_multiplier );
}
else
{
MeanWords( p_out, p_in, i_nb_words, i_nb_inputs,
f_multiplier );
}
}
p_input->begin = (void *)(p_in + i_nb_words);
break;
msg_Err( p_mixer, "internal amix error" );
return;
}
p_in = (float *)p_input->fifo.p_first->p_buffer;
}
else
{
if( i_nb_words > 0 )
ScaleWords( p_out, p_in, i_nb_words, f_multiplier );
p_input->begin = (void *)(p_in + i_nb_words);
break;
}
}
}

View File

@ -80,10 +80,7 @@ static void DoWork( aout_mixer_t * p_mixer, aout_buffer_t * p_buffer )
{
VLC_UNUSED( p_buffer );
unsigned i = 0;
aout_mixer_input_t * p_input = p_mixer->input[i];
while ( p_input->is_invalid )
p_input = p_mixer->input[++i];
aout_mixer_input_t * p_input = p_mixer->input;
aout_buffer_t * p_old_buffer = aout_FifoPop( NULL, &p_input->fifo );
/* We don't free the old buffer because,
@ -91,15 +88,4 @@ static void DoWork( aout_mixer_t * p_mixer, aout_buffer_t * p_buffer )
* to mix is the same as the one in the first active input fifo.
* So the ownership of that buffer belongs to our caller */
assert( p_old_buffer == p_buffer );
/* Empty other FIFOs to avoid a memory leak. */
for ( i++; i < p_mixer->input_count; i++ )
{
p_input = p_mixer->input[i];
if ( p_input->is_invalid )
continue;
while ((p_old_buffer = aout_FifoPop( NULL, &p_input->fifo )))
aout_BufferFree( p_old_buffer );
}
}

View File

@ -75,20 +75,13 @@ static int Create( vlc_object_t *p_this )
*****************************************************************************/
static void DoWork( aout_mixer_t *p_mixer, aout_buffer_t * p_buffer )
{
unsigned i = 0;
aout_mixer_input_t * p_input = p_mixer->input[i];
aout_mixer_input_t *p_input = p_mixer->input;
int i_nb_channels = aout_FormatNbChannels( &p_mixer->fmt );
int i_buffer = p_buffer->i_nb_samples * sizeof(int32_t)
* i_nb_channels;
uint8_t * p_in;
uint8_t * p_out;
while ( p_input->is_invalid )
{
p_input = p_mixer->input[++i];
/* This can't crash because if no input has b_error == 0, the
* audio mixer cannot run and we can't be here. */
}
p_in = p_input->begin;
p_out = p_buffer->p_buffer;
@ -125,26 +118,4 @@ static void DoWork( aout_mixer_t *p_mixer, aout_buffer_t * p_buffer )
break;
}
}
/* Empty other FIFOs to avoid a memory leak. */
for ( i++; i < p_mixer->input_count; i++ )
{
aout_fifo_t * p_fifo;
aout_buffer_t * p_deleted;
p_input = p_mixer->input[i];
if ( p_input->is_invalid )
continue;
p_fifo = &p_input->fifo;
p_deleted = p_fifo->p_first;
while ( p_deleted != NULL )
{
aout_buffer_t * p_next = p_deleted->p_next;
aout_BufferFree( p_deleted );
p_deleted = p_next;
}
p_fifo->p_first = NULL;
p_fifo->pp_last = &p_fifo->p_first;
}
}

View File

@ -53,10 +53,7 @@ int aout_MixerNew( aout_instance_t * p_aout )
p_mixer->fmt = p_aout->mixer_format;
p_mixer->allocation = p_aout->mixer_allocation;
p_mixer->multiplier = p_aout->mixer_multiplier;
p_mixer->input_count = p_aout->i_nb_inputs;
p_mixer->input = calloc( p_mixer->input_count, sizeof(*p_mixer->input) );
for( int i = 0; i < p_aout->i_nb_inputs; i++ )
p_mixer->input[i] = &p_aout->pp_inputs[i]->mixer;
p_mixer->input = &p_aout->pp_inputs[0]->mixer;
p_mixer->mix = NULL;
p_mixer->sys = NULL;
@ -88,7 +85,6 @@ void aout_MixerDelete( aout_instance_t * p_aout )
module_unneed( p_aout->p_mixer, p_aout->p_mixer->module );
free( p_aout->p_mixer->input );
vlc_object_release( p_aout->p_mixer );
/* */