Move pitch vector interpolation code to acelp_filters

and convert it to a generic interpolation routine.

Originally committed as revision 13284 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Vladimir Voroshilov 2008-05-24 17:18:42 +00:00
parent 13b6729361
commit d347a046e2
2 changed files with 131 additions and 0 deletions

View File

@ -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,

View File

@ -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).