[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