and convert it to a generic interpolation routine. Originally committed as revision 13284 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
| @@ -27,6 +27,60 @@ | |||
| #define FRAC_BITS 13 | |||
| #include "mathops.h" | |||
| const int16_t ff_acelp_interp_filter[61] = | |||
| { /* (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, | |||
| }; | |||
| void ff_acelp_interpolate( | |||
| int16_t* out, | |||
| const int16_t* in, | |||
| const int16_t* filter_coeffs, | |||
| int precision, | |||
| int pitch_delay_frac, | |||
| int filter_length, | |||
| int length) | |||
| { | |||
| int n, i; | |||
| assert(pitch_delay_frac >= 0 && pitch_delay_frac < precision); | |||
| for(n=0; n<length; n++) | |||
| { | |||
| int idx = 0; | |||
| int v = 0x4000; | |||
| for(i=0; i<filter_length;) | |||
| { | |||
| /* 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 + i] * filter_coeffs[idx + pitch_delay_frac]; | |||
| idx += precision; | |||
| i++; | |||
| v += in[n - i] * filter_coeffs[idx - pitch_delay_frac]; | |||
| } | |||
| out[n] = av_clip_int16(v >> 15); | |||
| } | |||
| } | |||
| void ff_acelp_convolve_circ( | |||
| int16_t* fc_out, | |||
| const int16_t* fc_in, | |||
| @@ -25,6 +25,83 @@ | |||
| #include <stdint.h> | |||
| /** | |||
| * 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[6*i+j] = b(10, 3600/8000, i+j/6) | |||
| * | |||
| * The filter assumes the following order of fractions (X - integer delay): | |||
| * | |||
| * 1/3 precision: X 1/3 2/3 X 1/3 2/3 X | |||
| * 1/6 precision: X 1/6 2/6 3/6 4/6 5/6 X 1/6 2/6 3/6 4/6 5/6 X | |||
| * | |||
| * The filter can be used for 1/3 precision, too, by | |||
| * passing 2*pitch_delay_frac as third parameter to the interpolation routine. | |||
| * | |||
| */ | |||
| extern const int16_t ff_acelp_interp_filter[61]; | |||
| /** | |||
| * \brief Generic interpolation routine | |||
| * \param out [out] buffer for interpolated data | |||
| * \param in input data | |||
| * \param filter_coeffs interpolation filter coefficients (0.15) | |||
| * \param precision filter is able to interpolate with 1/precision precision of pitch delay | |||
| * \param pitch_delay_frac pitch delay, fractional part [0..precision-1] | |||
| * \param filter_length filter length | |||
| * \param length length of speech data to process | |||
| * | |||
| * filter_coeffs contains coefficients of the positive half of the symmetric | |||
| * interpolation filter. filter_coeffs[0] should the central (unpaired) coefficient. | |||
| * See ff_acelp_interp_filter fot example. | |||
| * | |||
| */ | |||
| void ff_acelp_interpolate( | |||
| int16_t* out, | |||
| const int16_t* in, | |||
| const int16_t* filter_coeffs, | |||
| int precision, | |||
| int pitch_delay_frac, | |||
| int filter_length, | |||
| int length); | |||
| /** | |||
| * \brief Circularly convolve fixed vector with a phase dispersion impulse | |||
| * response filter (D.6.2 of G.729 and 6.1.5 of AMR). | |||