From 827d60ce665c7088eae6761a9c3deb6a694dac42 Mon Sep 17 00:00:00 2001 From: Laurent Aimar Date: Sun, 2 May 2010 01:50:21 +0200 Subject: [PATCH] Factorized a bit bandlimited audio filter code. --- modules/audio_filter/resampler/bandlimited.c | 262 ++++++++----------- 1 file changed, 116 insertions(+), 146 deletions(-) diff --git a/modules/audio_filter/resampler/bandlimited.c b/modules/audio_filter/resampler/bandlimited.c index 88512f010a..80ef03b2f2 100644 --- a/modules/audio_filter/resampler/bandlimited.c +++ b/modules/audio_filter/resampler/bandlimited.c @@ -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; +} + + -- 2.39.5