Revision 77a78e9b libavcodec/lpc.c
libavcodec/lpc.c | ||
---|---|---|
28 | 28 |
/** |
29 | 29 |
* Apply Welch window function to audio block |
30 | 30 |
*/ |
31 |
static void apply_welch_window(const int32_t *data, int len, double *w_data) |
|
31 |
static void apply_welch_window_c(const int32_t *data, int len, double *w_data)
|
|
32 | 32 |
{ |
33 | 33 |
int i, n2; |
34 | 34 |
double w; |
... | ... | |
54 | 54 |
* Calculate autocorrelation data from audio samples |
55 | 55 |
* A Welch window function is applied before calculation. |
56 | 56 |
*/ |
57 |
static void lpc_compute_autocorr_c(const int32_t *data, int len, int lag,
|
|
57 |
static void lpc_compute_autocorr_c(const double *data, int len, int lag,
|
|
58 | 58 |
double *autoc) |
59 | 59 |
{ |
60 | 60 |
int i, j; |
61 |
double tmp[len + lag + 1]; |
|
62 |
double *data1= tmp + lag; |
|
63 |
|
|
64 |
apply_welch_window(data, len, data1); |
|
65 |
|
|
66 |
for(j=0; j<lag; j++) |
|
67 |
data1[j-lag]= 0.0; |
|
68 |
data1[len] = 0.0; |
|
69 | 61 |
|
70 | 62 |
for(j=0; j<lag; j+=2){ |
71 | 63 |
double sum0 = 1.0, sum1 = 1.0; |
72 | 64 |
for(i=j; i<len; i++){ |
73 |
sum0 += data1[i] * data1[i-j];
|
|
74 |
sum1 += data1[i] * data1[i-j-1];
|
|
65 |
sum0 += data[i] * data[i-j];
|
|
66 |
sum1 += data[i] * data[i-j-1];
|
|
75 | 67 |
} |
76 | 68 |
autoc[j ] = sum0; |
77 | 69 |
autoc[j+1] = sum1; |
... | ... | |
80 | 72 |
if(j==lag){ |
81 | 73 |
double sum = 1.0; |
82 | 74 |
for(i=j-1; i<len; i+=2){ |
83 |
sum += data1[i ] * data1[i-j ]
|
|
84 |
+ data1[i+1] * data1[i-j+1];
|
|
75 |
sum += data[i ] * data[i-j ]
|
|
76 |
+ data[i+1] * data[i-j+1];
|
|
85 | 77 |
} |
86 | 78 |
autoc[j] = sum; |
87 | 79 |
} |
... | ... | |
177 | 169 |
assert(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER && |
178 | 170 |
lpc_type > AV_LPC_TYPE_FIXED); |
179 | 171 |
|
172 |
/* reinit LPC context if parameters have changed */ |
|
173 |
if (blocksize != s->blocksize || max_order != s->max_order || |
|
174 |
lpc_type != s->lpc_type) { |
|
175 |
ff_lpc_end(s); |
|
176 |
ff_lpc_init(s, blocksize, max_order, lpc_type); |
|
177 |
} |
|
178 |
|
|
180 | 179 |
if (lpc_type == AV_LPC_TYPE_LEVINSON) { |
181 |
s->lpc_compute_autocorr(samples, blocksize, max_order, autoc); |
|
180 |
double *windowed_samples = s->windowed_samples + max_order; |
|
181 |
|
|
182 |
s->lpc_apply_welch_window(samples, blocksize, windowed_samples); |
|
183 |
|
|
184 |
s->lpc_compute_autocorr(windowed_samples, blocksize, max_order, autoc); |
|
182 | 185 |
|
183 | 186 |
compute_lpc_coefs(autoc, max_order, &lpc[0][0], MAX_LPC_ORDER, 0, 1); |
184 | 187 |
|
... | ... | |
236 | 239 |
return opt_order; |
237 | 240 |
} |
238 | 241 |
|
239 |
av_cold void ff_lpc_init(LPCContext *s) |
|
242 |
av_cold int ff_lpc_init(LPCContext *s, int blocksize, int max_order, |
|
243 |
enum AVLPCType lpc_type) |
|
240 | 244 |
{ |
245 |
s->blocksize = blocksize; |
|
246 |
s->max_order = max_order; |
|
247 |
s->lpc_type = lpc_type; |
|
248 |
|
|
249 |
if (lpc_type == AV_LPC_TYPE_LEVINSON) { |
|
250 |
s->windowed_samples = av_mallocz((blocksize + max_order + 2) * |
|
251 |
sizeof(*s->windowed_samples)); |
|
252 |
if (!s->windowed_samples) |
|
253 |
return AVERROR(ENOMEM); |
|
254 |
} else { |
|
255 |
s->windowed_samples = NULL; |
|
256 |
} |
|
257 |
|
|
258 |
s->lpc_apply_welch_window = apply_welch_window_c; |
|
241 | 259 |
s->lpc_compute_autocorr = lpc_compute_autocorr_c; |
242 | 260 |
|
243 | 261 |
if (HAVE_MMX) |
244 | 262 |
ff_lpc_init_x86(s); |
263 |
|
|
264 |
return 0; |
|
265 |
} |
|
266 |
|
|
267 |
av_cold void ff_lpc_end(LPCContext *s) |
|
268 |
{ |
|
269 |
av_freep(&s->windowed_samples); |
|
245 | 270 |
} |
Also available in: Unified diff