[FFmpeg-devel] [PATCH] Common ACELP code & G.729 [6/7] - G.729 postfilter
Michael Niedermayer
michaelni
Tue May 13 20:33:18 CEST 2008
On Wed, May 14, 2008 at 12:25:24AM +0700, Vladimir Voroshilov wrote:
> 2008/5/12 Michael Niedermayer <michaelni at gmx.at>:
> >
> > On Sun, May 11, 2008 at 10:01:41PM +0700, Vladimir Voroshilov wrote:
> > > 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
> >
> > hmm ad which is correct? or is it unused?
>
> :)
> It is used in filter,
> but result is ignored (due to synthesis and residual filters implementation
> it is assumed to always has value 'one').
> Perhaps, weighted filter should be fixed, too to leave first item of input data
> unchanged (because it should be multiplied by gain^0).
not needed (in+1, out+1, wheited_pow+1, filter_len-1) should already achive
that. And the the 2 arrays can be made 1 element shorter.
[...]
> + corr_int_num = 0;
> + best_delay_int = pitch_delay_int - 1;
> + for(i=pitch_delay_int-1; i<=pitch_delay_int+1; i++)
> + {
> + sum = sum_of_squares(sig_scaled - i + RES_PREV_DATA_SIZE, subframe_size, i, 0);
> + if(sum > corr_int_num)
> + {
> + corr_int_num = sum;
> + best_delay_int = i;
> + }
> + }
> + if(!corr_int_num)
> + break;
> +
> + /*
> + Compute denominator of pseudo-normalized correlation R'(0)
> + */
> + corr_int_den = sum_of_squares(sig_scaled - best_delay_int + RES_PREV_DATA_SIZE, subframe_size, 0, 0);
> + if (!corr_int_den)
> + break;
i do not think it can be 0
[...]
> + /*
> + Compute numerator of pseudo-normalized correlation R'(k)
> + (4.2.1, Equation 81)
> + */
> + sum = 0;
> + for(n=0; n<subframe_size; n++)
> + sum += delayed_signal[k][n+i] * sig_scaled[n + RES_PREV_DATA_SIZE];
duplicate of sum_of_squares()
[...]
> + L64_temp0 = (int64_t)gain_num_square << ((sh_gain_num << 1) + 1);
> + L64_temp1 = ((int64_t)gain_den * ener) << (sh_gain_den + sh_ener);
> + if(L64_temp0 < L64_temp1)
> + {
> + gain_num = 0;
> + break;
> + }
> + }while(0);
I do not like fake loops. Especially not to avoid a bunch or gotos.
[...]
> + /*
> + Compute R'(k) correlation's numerator
> + */
> + sum = 0;
> + for(n=0; n<subframe_size; n++)
> + sum += residual_filt[n] * sig_scaled[n + RES_PREV_DATA_SIZE];
duplicate of sum_of_squares()
> +
> + if(sum < 0)
> + {
> + gain_long_num = 0;
> + sh_gain_long_num = 0;
> + }
> + else
> + {
> + tmp = FFMAX(av_log2(sum) - 14, 0);
> + sum >>= tmp;
> + gain_long_num = sum;
> + sh_gain_long_num = tmp;
> + }
> +
> + /*
> + Compute R'(k) correlation's denominator
> + */
> + sum = sum_of_squares(residual_filt, subframe_size, 0, 0);
> +
> + tmp = FFMAX(av_log2(sum) - 14, 0);
> + sum >>= tmp;
> + gain_long_den = sum;
> + sh_gain_long_den = tmp;
duplicate of above
[...]
> + tmp = sh_gain_num - sh_gain_den;
> + if(tmp>0)
> + gain_den >>= tmp;
> + else
> + gain_num >>= -tmp;
> +
> + if(gain_num > gain_den)
> + lt_filt_factor_a = MIN_LT_FILT_FACTOR_A;
> + else
> + {
> + gain_num >>= 2;
> + gain_den >>= 1;
> + lt_filt_factor_a = (gain_den << 15) / (gain_den + gain_num);
> + }
gain_num <<= sh_gain_num;
gain_den <<= sh_gain_den;
lt_filt_factor_a = FFMAX((gain_den << 15) / (gain_den + gain_num), 0x10000/3);
with 64bit casts if needed.
Also note that the explicit exp/mantisse split (X + sh_X) is completely
unacceptable, use float or use fixed point integers but not this float
emulation
> +
> + /*
> + Filtering through selected filter
> + */
> + lt_filt_factor_b = 32767 - lt_filt_factor_a + 1;
> + for(n=0; n<subframe_size; n++)
> + {
> + tmp = lt_filt_factor_a * residual[n + RES_PREV_DATA_SIZE] +
> + lt_filt_factor_b * selected_signal_const[n];
> + residual_filt[n] = (tmp + 0x4000) >> 15;
> + }
I think ive seen such a a*A[x] + b*B[x] filter somewhere already
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
I know you won't believe me, but the highest form of Human Excellence is
to question oneself and others. -- Socrates
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20080513/3a980b8c/attachment.pgp>
More information about the ffmpeg-devel
mailing list