Commit 1dae4565 authored by Laurent Aimar's avatar Laurent Aimar Committed by Jean-Baptiste Kempf

Factorized a bit bandlimited audio filter code.

(cherry picked from commit 827d60ce665c7088eae6761a9c3deb6a694dac42)
parent da7b8fb9
......@@ -56,16 +56,12 @@ static int OpenFilter ( vlc_object_t * );
static void CloseFilter( vlc_object_t * );
static block_t *Resample( filter_t *, block_t * );
static void FilterFloatUP( const float Imp[], const float ImpD[], uint16_t Nwing,
float *f_in, float *f_out, uint32_t ui_remainder,
uint32_t ui_output_rate, int16_t Inc,
int i_nb_channels );
static void FilterFloatUD( const float Imp[], const float ImpD[], uint16_t Nwing,
float *f_in, float *f_out, uint32_t ui_remainder,
uint32_t ui_output_rate, uint32_t ui_input_rate,
int16_t Inc, int i_nb_channels );
static void ResampleFloat( filter_t *p_filter,
block_t *p_out_buf, size_t *pi_out,
float **pp_in,
int i_in, int i_in_end,
double d_factor, bool b_factor_old,
int i_nb_channels, int i_bytes_per_frame );
/*****************************************************************************
* Local structures
......@@ -212,76 +208,17 @@ static block_t *Resample( filter_t * p_filter, block_t * p_in_buf )
/* Apply the old rate until we have enough samples for the new one */
i_in = p_sys->i_old_wing;
p_in += p_sys->i_old_wing * i_nb_channels;
for( ; i_in < i_filter_wing &&
(i_in + p_sys->i_old_wing) < i_in_nb; i_in++ )
{
if( p_sys->d_old_factor == 1 )
{
/* Just copy the samples */
memcpy( p_out, p_in, i_bytes_per_frame );
p_in += i_nb_channels;
p_out += i_nb_channels;
i_out++;
continue;
}
while( p_sys->i_remainder < p_filter->fmt_out.audio.i_rate )
{
if( p_out_buf->i_buffer/i_bytes_per_frame <= i_out )
break;
size_t i_old_in_end = 0;
if( p_sys->i_old_wing <= i_in_nb )
i_old_in_end = __MIN( i_filter_wing, i_in_nb - p_sys->i_old_wing );
if( p_sys->d_old_factor >= 1 )
{
/* FilterFloatUP() is faster if we can use it */
/* Perform left-wing inner product */
FilterFloatUP( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
SMALL_FILTER_NWING, p_in, p_out,
p_sys->i_remainder,
p_filter->fmt_out.audio.i_rate,
-1, i_nb_channels );
/* Perform right-wing inner product */
FilterFloatUP( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
SMALL_FILTER_NWING, p_in + i_nb_channels, p_out,
p_filter->fmt_out.audio.i_rate -
p_sys->i_remainder,
p_filter->fmt_out.audio.i_rate,
1, i_nb_channels );
#if 0
/* Normalize for unity filter gain */
for( i = 0; i < i_nb_channels; i++ )
{
*(p_out+i) *= d_old_scale_factor;
}
#endif
}
else
{
/* Perform left-wing inner product */
FilterFloatUD( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
SMALL_FILTER_NWING, p_in, p_out,
p_sys->i_remainder,
p_filter->fmt_out.audio.i_rate, p_filter->fmt_in.audio.i_rate,
-1, i_nb_channels );
/* Perform right-wing inner product */
FilterFloatUD( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
SMALL_FILTER_NWING, p_in + i_nb_channels, p_out,
p_filter->fmt_out.audio.i_rate -
p_sys->i_remainder,
p_filter->fmt_out.audio.i_rate, p_filter->fmt_in.audio.i_rate,
1, i_nb_channels );
}
p_out += i_nb_channels;
i_out++;
p_sys->i_remainder += p_filter->fmt_in.audio.i_rate;
}
p_in += i_nb_channels;
p_sys->i_remainder -= p_filter->fmt_out.audio.i_rate;
}
ResampleFloat( p_filter,
p_out_buf, &i_out, &p_in,
i_in, i_old_in_end,
p_sys->d_old_factor, true,
i_nb_channels, i_bytes_per_frame );
i_in = __MAX( i_in, i_old_in_end );
/* Apply the new rate for the rest of the samples */
if( i_in < i_in_nb - i_filter_wing )
......@@ -289,67 +226,11 @@ static block_t *Resample( filter_t * p_filter, block_t * p_in_buf )
p_sys->d_old_factor = d_factor;
p_sys->i_old_wing = i_filter_wing;
}
for( ; i_in < i_in_nb - i_filter_wing; i_in++ )
{
while( p_sys->i_remainder < p_filter->fmt_out.audio.i_rate )
{
if( p_out_buf->i_buffer/i_bytes_per_frame <= i_out )
break;
assert( i_out < p_out_buf->i_buffer/i_bytes_per_frame );
if( d_factor >= 1 )
{
/* FilterFloatUP() is faster if we can use it */
/* Perform left-wing inner product */
FilterFloatUP( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
SMALL_FILTER_NWING, p_in, p_out,
p_sys->i_remainder,
p_filter->fmt_out.audio.i_rate,
-1, i_nb_channels );
/* Perform right-wing inner product */
FilterFloatUP( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
SMALL_FILTER_NWING, p_in + i_nb_channels, p_out,
p_filter->fmt_out.audio.i_rate -
p_sys->i_remainder,
p_filter->fmt_out.audio.i_rate,
1, i_nb_channels );
#if 0
/* Normalize for unity filter gain */
for( int i = 0; i < i_nb_channels; i++ )
{
*(p_out+i) *= d_old_scale_factor;
}
#endif
}
else
{
/* Perform left-wing inner product */
FilterFloatUD( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
SMALL_FILTER_NWING, p_in, p_out,
p_sys->i_remainder,
p_filter->fmt_out.audio.i_rate, p_filter->fmt_in.audio.i_rate,
-1, i_nb_channels );
/* Perform right-wing inner product */
FilterFloatUD( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
SMALL_FILTER_NWING, p_in + i_nb_channels, p_out,
p_filter->fmt_out.audio.i_rate -
p_sys->i_remainder,
p_filter->fmt_out.audio.i_rate, p_filter->fmt_in.audio.i_rate,
1, i_nb_channels );
}
p_out += i_nb_channels;
i_out++;
p_sys->i_remainder += p_filter->fmt_in.audio.i_rate;
}
p_in += i_nb_channels;
p_sys->i_remainder -= p_filter->fmt_out.audio.i_rate;
}
ResampleFloat( p_filter,
p_out_buf, &i_out, &p_in,
i_in, i_in_nb - i_filter_wing,
d_factor, false,
i_nb_channels, i_bytes_per_frame );
/* Finalize aout buffer */
p_out_buf->i_nb_samples = i_out;
......@@ -455,9 +336,9 @@ static void CloseFilter( vlc_object_t *p_this )
free( p_filter->p_sys );
}
void FilterFloatUP( const float Imp[], const float ImpD[], uint16_t Nwing, float *p_in,
float *p_out, uint32_t ui_remainder,
uint32_t ui_output_rate, int16_t Inc, int i_nb_channels )
static void FilterFloatUP( const float Imp[], const float ImpD[], uint16_t Nwing, float *p_in,
float *p_out, uint32_t ui_remainder,
uint32_t ui_output_rate, int16_t Inc, int i_nb_channels )
{
const float *Hp, *Hdp, *End;
float t, temp;
......@@ -498,10 +379,10 @@ void FilterFloatUP( const float Imp[], const float ImpD[], uint16_t Nwing, float
}
}
void FilterFloatUD( const float Imp[], const float ImpD[], uint16_t Nwing, float *p_in,
float *p_out, uint32_t ui_remainder,
uint32_t ui_output_rate, uint32_t ui_input_rate,
int16_t Inc, int i_nb_channels )
static void FilterFloatUD( const float Imp[], const float ImpD[], uint16_t Nwing, float *p_in,
float *p_out, uint32_t ui_remainder,
uint32_t ui_output_rate, uint32_t ui_input_rate,
int16_t Inc, int i_nb_channels )
{
const float *Hp, *Hdp, *End;
float t, temp;
......@@ -553,3 +434,92 @@ void FilterFloatUD( const float Imp[], const float ImpD[], uint16_t Nwing, float
p_in += (Inc * i_nb_channels); /* Input signal step */
}
}
static void ResampleFloat( filter_t *p_filter,
block_t *p_out_buf, size_t *pi_out,
float **pp_in,
int i_in, int i_in_end,
double d_factor, bool b_factor_old,
int i_nb_channels, int i_bytes_per_frame )
{
filter_sys_t *p_sys = p_filter->p_sys;
float *p_in = *pp_in;
size_t i_out = *pi_out;
float *p_out = (float*)p_out_buf->p_buffer + i_out * i_nb_channels;
for( ; i_in < i_in_end; i_in++ )
{
if( b_factor_old && d_factor == 1 )
{
/* Just copy the samples */
memcpy( p_out, p_in, i_bytes_per_frame );
p_in += i_nb_channels;
p_out += i_nb_channels;
i_out++;
continue;
}
while( p_sys->i_remainder < p_filter->fmt_out.audio.i_rate )
{
if( p_out_buf->i_buffer/i_bytes_per_frame <= i_out )
break;
if( d_factor >= 1 )
{
/* FilterFloatUP() is faster if we can use it */
/* Perform left-wing inner product */
FilterFloatUP( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
SMALL_FILTER_NWING, p_in, p_out,
p_sys->i_remainder,
p_filter->fmt_out.audio.i_rate,
-1, i_nb_channels );
/* Perform right-wing inner product */
FilterFloatUP( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
SMALL_FILTER_NWING, p_in + i_nb_channels, p_out,
p_filter->fmt_out.audio.i_rate -
p_sys->i_remainder,
p_filter->fmt_out.audio.i_rate,
1, i_nb_channels );
#if 0
/* Normalize for unity filter gain */
for( i = 0; i < i_nb_channels; i++ )
{
*(p_out+i) *= d_old_scale_factor;
}
#endif
}
else
{
/* Perform left-wing inner product */
FilterFloatUD( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
SMALL_FILTER_NWING, p_in, p_out,
p_sys->i_remainder,
p_filter->fmt_out.audio.i_rate, p_filter->fmt_in.audio.i_rate,
-1, i_nb_channels );
/* Perform right-wing inner product */
FilterFloatUD( SMALL_FILTER_FLOAT_IMP, SMALL_FILTER_FLOAT_IMPD,
SMALL_FILTER_NWING, p_in + i_nb_channels, p_out,
p_filter->fmt_out.audio.i_rate -
p_sys->i_remainder,
p_filter->fmt_out.audio.i_rate, p_filter->fmt_in.audio.i_rate,
1, i_nb_channels );
}
p_out += i_nb_channels;
i_out++;
p_sys->i_remainder += p_filter->fmt_in.audio.i_rate;
}
p_in += i_nb_channels;
p_sys->i_remainder -= p_filter->fmt_out.audio.i_rate;
}
*pp_in = p_in;
*pi_out = i_out;
}
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