#include <stdint.h>Go to the source code of this file.
Functions | |
| 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) |
| Generic interpolation routine. | |
| void | ff_acelp_convolve_circ (int16_t *fc_out, const int16_t *fc_in, const int16_t *filter, int subframe_size) |
| Circularly convolve fixed vector with a phase dispersion impulse response filter (D.6.2 of G.729 and 6.1.5 of AMR). | |
| int | ff_acelp_lp_synthesis_filter (int16_t *out, const int16_t *filter_coeffs, const int16_t *in, int buffer_length, int filter_length, int stop_on_overflow, int rounder) |
| LP synthesis filter. | |
| void | ff_acelp_weighted_filter (int16_t *out, const int16_t *in, const int16_t *weight_pow, int filter_length) |
| Calculates coefficients of weighted A(z/weight) filter. | |
| void | ff_acelp_high_pass_filter (int16_t *out, int hpf_f[2], const int16_t *in, int length) |
| high-pass filtering and upscaling (4.2.5 of G.729) | |
Variables | |
| const int16_t | ff_acelp_interp_filter [61] |
| void ff_acelp_convolve_circ | ( | int16_t * | fc_out, | |
| const int16_t * | fc_in, | |||
| const int16_t * | filter, | |||
| int | subframe_size | |||
| ) |
Circularly convolve fixed vector with a phase dispersion impulse response filter (D.6.2 of G.729 and 6.1.5 of AMR).
| fc_out | vector with filter applied | |
| fc_in | source vector | |
| filter | phase filter coefficients |
Definition at line 84 of file acelp_filters.c.
00089 { 00090 int i, k; 00091 00092 memset(fc_out, 0, subframe_size * sizeof(int16_t)); 00093 00094 /* Since there are few pulses over an entire subframe (i.e. almost 00095 all fc_in[i] are zero) it is faster to swap two loops and process 00096 non-zero samples only. In the case of G.729D the buffer contains 00097 two non-zero samples before the call to ff_acelp_enhance_harmonics 00098 and, due to pitch_delay being bounded by [20; 143], a maximum 00099 of four non-zero samples for a total of 40 after the call. */ 00100 for(i=0; i<subframe_size; i++) 00101 { 00102 if(fc_in[i]) 00103 { 00104 for(k=0; k<i; k++) 00105 fc_out[k] += (fc_in[i] * filter[subframe_size + k - i]) >> 15; 00106 00107 for(k=i; k<subframe_size; k++) 00108 fc_out[k] += (fc_in[i] * filter[k - i]) >> 15; 00109 } 00110 } 00111 }
| void ff_acelp_high_pass_filter | ( | int16_t * | out, | |
| int | hpf_f[2], | |||
| const int16_t * | in, | |||
| int | length | |||
| ) |
high-pass filtering and upscaling (4.2.5 of G.729)
| out | [out] output buffer for filtered speech data | |
| hpf_f | [in/out] past filtered data from previous (2 items long) frames (-0x20000000 <= (14.13) < 0x20000000) | |
| in | speech data to process | |
| length | input data size |
The filter has a cut-off frequency of 100Hz
AMR uses mostly the same filter (cut-off frequency 60Hz, same formula, but constants differs in 5th sign after comma). Fortunately in fixed-point all coefficients are the same as in G.729. Thus this routine can be used for the fixed-point AMR decoder, too.
Definition at line 160 of file acelp_filters.c.
References av_clip_int16(), and MULL.
00165 { 00166 int i; 00167 int tmp; 00168 00169 for(i=0; i<length; i++) 00170 { 00171 tmp = MULL(hpf_f[0], 15836); /* (14.13) = (13.13) * (1.13) */ 00172 tmp += MULL(hpf_f[1], -7667); /* (13.13) = (13.13) * (0.13) */ 00173 tmp += 7699 * (in[i] - 2*in[i-1] + in[i-2]); /* (14.13) = (0.13) * (14.0) */ 00174 00175 /* Multiplication by 2 with rounding can cause short type 00176 overflow, thus clipping is required. */ 00177 00178 out[i] = av_clip_int16((tmp + 0x800) >> 12); /* (15.0) = 2 * (13.13) = (14.13) */ 00179 00180 hpf_f[1] = hpf_f[0]; 00181 hpf_f[0] = tmp; 00182 } 00183 }
| 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 | |||
| ) |
Generic interpolation routine.
| out | [out] buffer for interpolated data | |
| in | input data | |
| filter_coeffs | interpolation filter coefficients (0.15) | |
| precision | filter is able to interpolate with 1/precision precision of pitch delay | |
| pitch_delay_frac | pitch delay, fractional part [0..precision-1] | |
| filter_length | filter length | |
| length | length of speech data to process |
Definition at line 45 of file acelp_filters.c.
References av_clip_int16().
00053 { 00054 int n, i; 00055 00056 assert(pitch_delay_frac >= 0 && pitch_delay_frac < precision); 00057 00058 for(n=0; n<length; n++) 00059 { 00060 int idx = 0; 00061 int v = 0x4000; 00062 00063 for(i=0; i<filter_length;) 00064 { 00065 00066 /* The reference G.729 and AMR fixed point code performs clipping after 00067 each of the two following accumulations. 00068 Since clipping affects only the synthetic OVERFLOW test without 00069 causing an int type overflow, it was moved outside the loop. */ 00070 00071 /* R(x):=ac_v[-k+x] 00072 v += R(n-i)*ff_acelp_interp_filter(t+6i) 00073 v += R(n+i+1)*ff_acelp_interp_filter(6-t+6i) */ 00074 00075 v += in[n + i] * filter_coeffs[idx + pitch_delay_frac]; 00076 idx += precision; 00077 i++; 00078 v += in[n - i] * filter_coeffs[idx - pitch_delay_frac]; 00079 } 00080 out[n] = av_clip_int16(v >> 15); 00081 } 00082 }
| int ff_acelp_lp_synthesis_filter | ( | int16_t * | out, | |
| const int16_t * | filter_coeffs, | |||
| const int16_t * | in, | |||
| int | buffer_length, | |||
| int | filter_length, | |||
| int | stop_on_overflow, | |||
| int | rounder | |||
| ) |
LP synthesis filter.
| out | [out] pointer to output buffer | |
| filter_coeffs | filter coefficients (-0x8000 <= (3.12) < 0x8000) | |
| in | input signal | |
| buffer_length | amount of data to process | |
| filter_length | filter length (10 for 10th order LP filter) | |
| stop_on_overflow | 1 - return immediately if overflow occurs 0 - ignore overflows | |
| rounder | the amount to add for rounding (usually 0x800 or 0xfff) |
Definition at line 113 of file acelp_filters.c.
Referenced by do_output_subblock().
00121 { 00122 int i,n; 00123 00124 // These two lines are to avoid a -1 subtraction in the main loop 00125 filter_length++; 00126 filter_coeffs--; 00127 00128 for(n=0; n<buffer_length; n++) 00129 { 00130 int sum = rounder; 00131 for(i=1; i<filter_length; i++) 00132 sum -= filter_coeffs[i] * out[n-i]; 00133 00134 sum = (sum >> 12) + in[n]; 00135 00136 /* Check for overflow */ 00137 if(sum + 0x8000 > 0xFFFFU) 00138 { 00139 if(stop_on_overflow) 00140 return 1; 00141 sum = (sum >> 31) ^ 32767; 00142 } 00143 out[n] = sum; 00144 } 00145 00146 return 0; 00147 }
| void ff_acelp_weighted_filter | ( | int16_t * | out, | |
| const int16_t * | in, | |||
| const int16_t * | weight_pow, | |||
| int | filter_length | |||
| ) |
Calculates coefficients of weighted A(z/weight) filter.
| out | [out] weighted A(z/weight) result filter (-0x8000 <= (3.12) < 0x8000) | |
| in | source filter (-0x8000 <= (3.12) < 0x8000) | |
| weight_pow | array containing weight^i (-0x8000 <= (0.15) < 0x8000) | |
| filter_length | filter length (11 for 10th order LP filter) |
Definition at line 149 of file acelp_filters.c.
00154 { 00155 int n; 00156 for(n=0; n<filter_length; n++) 00157 out[n] = (in[n] * weight_pow[n] + 0x4000) >> 15; /* (3.12) = (0.15) * (3.12) with rounding */ 00158 }
| const int16_t ff_acelp_interp_filter[61] |
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.
Definition at line 30 of file acelp_filters.c.
1.5.1