[FFmpeg-devel] [PATCH] Common ACELP code & G.729 [6/7] - G.729 postfilter
Vladimir Voroshilov
voroshil
Sun May 11 17:01:41 CEST 2008
2008/5/8 Michael Niedermayer <michaelni at gmx.at>:
> On Fri, May 02, 2008 at 06:49:43PM +0700, Vladimir Voroshilov wrote:
>> Patch contains G.729 postfilter.
>> It was separated due to large size to help reviewing.
>> G.729 can produce audible speech even without this postfilter.
>>
>> --
>> Regards,
>> Vladimir Voroshilov mailto:voroshil at gmail.com
>> JID: voroshil at gmail.com, voroshil at jabber.ru
>> ICQ: 95587719
>
>> diff --git a/libavcodec/g729postfilter.c b/libavcodec/g729postfilter.c
>> new file mode 100644
>> index 0000000..b09d463
>> --- /dev/null
>> +++ b/libavcodec/g729postfilter.c
>> @@ -0,0 +1,704 @@
>> +#include <inttypes.h>
>> +#include <limits.h>
>> +
>> +#include "avcodec.h"
>> +#include "g729.h"
>> +#include "acelp_pitch_lag.h"
>> +#include "g729postfilter.h"
>> +#include "acelp_math.h"
>> +#include "acelp_filters.h"
>> +
>> +#define FRAC_BITS 15
>> +#include "mathops.h"
>> +
>
>> +/**
>> + * formant_pp_factor_num_pow[i] = FORMANT_PP_FACTOR_NUM^i
>> + */
>> +static const int16_t formant_pp_factor_num_pow[11]=
>> +{
>> + /* (0.15) */
>> + 32768, 18022, 9912, 5451, 2998, 1649, 907, 499, 274, 151, 83
> ^^^^^
> doesnt fit in int16_t, it does fir in uint16_t though
Reduced by 1
>
>
> [...]
>> +static void g729_residual(int16_t* filter_coeffs, const int16_t* speech, int16_t* residual, int subframe_size, int16_t* res_filter_data)
>> +{
>> + int i, n, sum;
>> +
>> + /*
>> + 4.2.1, Equation 79 Residual signal calculation
>> + ( filtering through A(z/FORMANT_PP_FACTOR_NUM) , one half of short-term filter)
>> + */
>
>> + for(n=0; n<subframe_size; n++)
>> + {
>> + sum = res_filter_data[10+n] = speech[n];
>
> this is effectively a memcpy() and i do not like memcpy() ...
Filter is rewritten in similar way to another filters in acelp_filter.c
This added several small memcpy, though.
>> + sum <<= 12;
>> + for(i=0; i<10; i++)
>> + sum += filter_coeffs[i] * res_filter_data[10+n-i-1];
>> +
>> + residual[n] = (sum + 0x800) >> 12;
>
> sum= x<<12
> sum += blah
> y= (sum+z) >> 12;
>
> can be changed to
>
> sum= z
> sum += blah
> y= (sum >> 12) + x;
>
> which does 1 shift less
done.
> [...]
>> + if (shift>0)
>> + for(i=0; i<subframe_size + RES_PREV_DATA_SIZE; i++)
>> + sig_scaled[i] = residual[i] >> shift;
>
> tabs
removed.
> [...]
>> + /*
>> + Recompute delayed signal with an interpolation filter of length 129
>> + */
>> + for(n=0; n<subframe_size; n++)
>> + {
>> + sum = 0;
>> + for(i=0;i<LONG_INT_FILT_LEN; i++)
>> + sum += ff_g729_interp_filt_long[best_delay_frac-1][i] *
>> + sig_scaled[n - (best_delay_int + 1 - delayed_signal_offset) + (LONG_INT_FILT_LEN/2 - i) + RES_PREV_DATA_SIZE];
>> + residual_filt[n] = (sum + 0x4000) >> 15;
>> + }
>
> duplicate, there already was some interpolation code somewhere else in g729
fixed. see also changes in acelp_vectors.
>> +static int16_t g729_get_tilt_comp(int16_t *lp_gn, const int16_t *lp_gd, int16_t* speech, int subframe_size)
>> +{
>> + int rh1,rh0; // Q12
>> + int sum, temp;
>> + int i, n;
>> + int gain_term; //gain term for short-term postfilter
>> +
>> + lp_gn[10] = 4096; //1.0 in Q12
>> +
>> + /* Apply 1/A(z/FORMANT_PP_FACTOR_DEN) filter to hf */
>
>> + for(n=0; n<22; n++)
>> + {
>> + sum = lp_gn[n+11] << 12;
>> + for(i=0; i<10; i++)
>> + sum -= lp_gd[i+1] * lp_gn[n+11-i-1];
>> + sum = av_clip(sum, -0x08000000, 0x07ffffff);
>> +
>> + lp_gn[n+11] = (sum + 0x800) >> 12;
>> + }
>
> This filter looks duplicated as well
fixed.
>
>> + /* Now lp_gn (starting with 10) contains impulse response of A(z/FORMANT_PP_FACTOR_NUM)/A(z/FORMANT_PP_FACTOR_DEN) filter */
>> +
>
>> + /* 4.2.3, Equation 87, calcuate rh(0) */
>> + rh0 = sum_of_squares(lp_gn + 10, 20, 0, 0) << 1; // Q24 -> Q9
>
>> + temp = 30 - av_log2(rh0);
>> + if(temp > 16)
>> + rh0 <<= temp - 16;
>> + else
>> + rh0 >>= 16 - temp;
>> +
> [...]
>> + if(temp > 16)
>> + rh1 <<= temp - 16;
>> + else
>> + rh1 >>= 16 - temp;
>
> looks useless, this just reduces precission
This shift guaranties that later "(rh1<<15)/rh0" will
not cause int overflow.
>
>
> [...]
>> + if(exp_after - exp_before - 1 > 0)
>> + gain <<= exp_after - exp_before - 1;
>> + else
>> + gain >>= exp_before - exp_after + 1;
>
> This stuff is duplicated all over the place and should be in a fuction
Fixed.
> Anyway the whole postfilter looks like it needs some serious cleanup.
Sure.
Postfilter is most complicated part of entire G.729 decoder.
And good cleanup is not made for it yet.
--
Regards,
Vladimir Voroshilov mailto:voroshil at gmail.com
JID: voroshil at gmail.com, voroshil at jabber.ru
ICQ: 95587719
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 06_g729post_49.diff
Type: text/x-diff
Size: 27205 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20080511/f22fdf92/attachment.diff>
More information about the ffmpeg-devel
mailing list