[FFmpeg-devel] [PATCH] Common ACELP code & G.729 [3/7] - vectors operations

Vladimir Voroshilov voroshil
Tue May 13 19:08:01 CEST 2008


2008/5/12 Michael Niedermayer <michaelni at gmx.at>:
> On Sun, May 11, 2008 at 09:46:04PM +0700, Vladimir Voroshilov wrote:
>  > 2008/5/9 Vladimir Voroshilov <voroshil at gmail.com>:
>  > > Michael Niedermayer wrote:
>  [...]
>
>
>
>  > >> > +/**
>  > >> > + * \brief common routines for 4pulses_13bits and 4pulses_21bits
>  > >> > + *
>  > >> > + * Tables differs only by width, so can be handled via common routine.
>  > >> > + */
>  > >> > +static void ff_acelp_4pulses_13_21_bits(
>  > >> > +        int16_t* fc_v,
>  > >> > +        int fc_index,
>  > >> > +        int pulses_signs,
>  > >> > +        int bits)
>  > >> > +{
>  > >> > +    int mask = (1 << bits) - 1;
>  > >> > +    int i, index;
>  > >> > +
>  > >> > +    for(i=0; i<3; i++)
>  > >> > +    {
>  > >> > +        index = i + 5 * (fc_index & mask);
>  > >> > +        fc_v[ index ] += (pulses_signs & 1) ? 8191 : -8192; // +/-1 in (2.13)
>  > >> > +
>  > >> > +        fc_index >>= bits;
>  > >> > +        pulses_signs >>= 1;
>  > >> > +    }
>  > >> > +
>  > >> > +    index = 3 + (fc_index & 1) + 5 * ((fc_index>>1) & mask);
>  > >> > +    fc_v[ index ] += (pulses_signs & 1) ? 8191 : -8192;
>  > >> > +}
>  > >> > +
>  > >> [...]
>  > >> > +
>  > >> > +void ff_acelp_fc_2pulses_9bits_g729d(
>  > >> > +        int16_t* fc_v,
>  > >> > +        int fc_index,
>  > >> > +        int pulses_signs)
>  > >> > +{
>  > >> > +    int index;
>  > >> > +
>  > >> > +    index = ((5 * gray_decode[fc_index & 15]) >> 1) + 1;
>  > >> > +    fc_v[ index ] += (pulses_signs & 1) ? 8191 : -8192; // +/-1 in (2.13)
>  > >> > +
>  > >> > +    pulses_signs >>= 1;
>  > >> > +    fc_index >>= 4;
>  > >> > +
>  > >> > +    index = fc_2pulses_9bits_track2[gray_decode[fc_index & 31]];
>  > >> > +    fc_v[ index ] += (pulses_signs & 1) ? 8191 : -8192; // +/-1 in (2.13)
>  > >> > +}
>  > >>
>  > >> The only thing that seperates these is the different tables
>  > >>
>  > >>     for(i=0; i<pulse_count; i++){
>  > >>         index = i + tab[fc_index & mask];
>  > >>         fc_v[ index ] += (pulses_signs & 1) ? 8191 : -8192;
>  > >>
>  > >>         fc_index >>= bits;
>  > >>         pulses_signs >>= 1;
>  > >>     }
>  > >>
>  > >>     index = tab2[fc_index];
>  > >>     fc_v[ index ] += pulses_signs ? 8191 : -8192;
>  > >>
>  > >> This also means you no longer need the function pointers.
>  > >>
>  > >
>  > > Hm. I hope, this version is better..
>
>  there are still 2 seperate functions and now there are even wraper functions
>  this is not better IMHO.
>  see my example above, is there a problem with it?

Already implemented yours routine.
Now i should remove those wrappers,
make common routine non-static and
use it in main loop, right?

>  > +/**
>  > + * low-pass FIR (Finite Impulse Response) filter coefficients
>  > + *
>  > + *   A similar filter is named b30 in G.729.
>  > + *
>
> > + *   G.729 specification says:
>  > + *     b30 is based on Hamming windowed sinc functions, truncated at +/-29 and
>  > + *     padded with zeros at +/-30 b30[30]=0
>  > + *     The filter has a cut-off frequency (-3 dB) at 3600 Hz in the oversampled
>  > + *     domain.
>  > + *
>  > + *   After some analysis, I found this approximation:
>  > + *
>  > + *                                    PI * x
>  > + *   Hamm(x,N) = 0.53836-0.46164*cos(--------)
>  > + *                                      N-1
>  > + *                                      ---
>  > + *                                       2
>  > + *
>  > + *                                                             PI * x
>  > + *   Hamm'(x,k) = Hamm(x - k, 2*k+1) =  0.53836 + 0.46164*cos(--------)
>  > + *                                                                k
>  > + *
>  > + *             sin(PI * x)
>  > + *   Sinc(x) = ----------- (normalized sinc function)
>  > + *               PI * x
>  > + *
>  > + *   h(t,B) = 2 * B * Sinc(2 * B * t) (impulse response of sinc low-pass filter)
>  > + *
>  > + *   b(k,B, n) = Hamm'(n, k) * h(n, B)
>  > + *
>  > + *
>  > + *       3600
>  > + *   B = ----
>  > + *       8000
>  > + *
>  > + *   3600 - cut-off frequency
>  > + *   8000 - sampling rate
>  > + *   k    - filter order
>  > + *
>  > + *   ff_acelp_interp_filter[i][j] = b(10, 3600/8000, i+j/6)
>  > + *
>  > + */
>  > +const int16_t ff_acelp_interp_filter[66] =
>  > +{ /* (0.15) */
>  > +  29443, 28346, 25207, 20449, 14701,  8693,
>  > +   3143, -1352, -4402, -5865, -5850, -4673,
>  > +  -2783,  -672,  1211,  2536,  3130,  2991,
>  > +   2259,  1170,     0, -1001, -1652, -1868,
>  > +  -1666, -1147,  -464,   218,   756,  1060,
>  > +   1099,   904,   550,   135,  -245,  -514,
>  > +   -634,  -602,  -451,  -231,     0,   191,
>  > +    308,   340,   296,   198,    78,   -36,
>  > +   -120,  -163,  -165,  -132,   -79,   -19,
>  > +     34,    73,    91,    89,    70,    38,
>  > +      0,     0,     0,     0,     0,     0,
>  > +};
>  > +
>  > +void ff_acelp_interpolate_pitch_vector(
>  > +        int16_t* out,
>  > +        const int16_t* in,
>  > +        const int16_t* filter_coeffs,
>  > +        int precision,
>
> > +        int pitch_delay_int,
>  > +        int pitch_delay_frac,
>  > +        int filter_length,
>
> > +        int subframe_size)
>  > +{
>  > +    int n, i;
>  > +
>
> > +    /* pitch_delay_frac [0; 5]
>  > +       pitch_delay_int  [PITCH_LAG_MIN; PITCH_LAG_MAX] */
>  > +    for(n=0; n<subframe_size; n++)
>  > +    {
>  > +        int idx = precision;
>
> > +        /* 3.7.1 of G.729, Equation 40 */
>  > +        int v = in[n - pitch_delay_int] * filter_coeffs[FFABS(pitch_delay_frac)];
>  > +        for(i=1; i<filter_length+1; i++)
>  > +        {
>  > +
>  > +            /* The reference G.729 and AMR fixed point code performs clipping after
>
> > +               each of the two following accumulations.
>  > +               Since clipping affects only the synthetic OVERFLOW test without
>  > +               causing an int type overflow, it was moved outside the loop. */
>
> > +
>  > +            /*  R(x):=ac_v[-k+x]
>  > +                v += R(n-i)*ff_acelp_interp_filter(t+6i)
>
> > +                v += R(n+i+1)*ff_acelp_interp_filter(6-t+6i) */
>  > +
>  > +            v += in[n - pitch_delay_int - i] * filter_coeffs[idx - pitch_delay_frac];
>  > +            v += in[n - pitch_delay_int + i] * filter_coeffs[idx + pitch_delay_frac];
>  > +            idx += precision;
>  > +        }
>  > +        out[n] = av_clip_int16((v + 0x4000) >> 15);
>  > +    }
>  > +}
>
>  Maybe the generic interpolation should be in a seperate file.

Move it back to acelp_filters together with corresponding lookup tables?




-- 
Regards,
Vladimir Voroshilov mailto:voroshil at gmail.com
JID: voroshil at gmail.com, voroshil at jabber.ru
ICQ: 95587719




More information about the ffmpeg-devel mailing list