Commit | Line | Data |
---|---|---|
55c3a4f6 MNB |
1 | /* |
2 | * G.723.1 compatible decoder | |
3 | * Copyright (c) 2006 Benjamin Larsson | |
4 | * Copyright (c) 2010 Mohamed Naufal Basheer | |
5 | * | |
6 | * This file is part of Libav. | |
7 | * | |
8 | * Libav is free software; you can redistribute it and/or | |
9 | * modify it under the terms of the GNU Lesser General Public | |
10 | * License as published by the Free Software Foundation; either | |
11 | * version 2.1 of the License, or (at your option) any later version. | |
12 | * | |
13 | * Libav is distributed in the hope that it will be useful, | |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | * Lesser General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU Lesser General Public | |
19 | * License along with Libav; if not, write to the Free Software | |
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
21 | */ | |
22 | ||
23 | /** | |
24 | * @file | |
25 | * G.723.1 compatible decoder | |
26 | */ | |
27 | ||
28 | #define BITSTREAM_READER_LE | |
a903f8f0 | 29 | #include "libavutil/channel_layout.h" |
5bac2d0c | 30 | #include "libavutil/mem.h" |
55c3a4f6 MNB |
31 | #include "libavutil/opt.h" |
32 | #include "avcodec.h" | |
33 | #include "get_bits.h" | |
34 | #include "acelp_vectors.h" | |
35 | #include "celp_filters.h" | |
aac996cc | 36 | #include "g723_1.h" |
594d4d5d | 37 | #include "internal.h" |
55c3a4f6 | 38 | |
04fc5c6b KS |
39 | #define CNG_RANDOM_SEED 12345 |
40 | ||
55c3a4f6 MNB |
41 | static av_cold int g723_1_decode_init(AVCodecContext *avctx) |
42 | { | |
43 | G723_1_Context *p = avctx->priv_data; | |
44 | ||
45 | avctx->channel_layout = AV_CH_LAYOUT_MONO; | |
46 | avctx->sample_fmt = AV_SAMPLE_FMT_S16; | |
47 | avctx->channels = 1; | |
48 | avctx->sample_rate = 8000; | |
49 | p->pf_gain = 1 << 12; | |
50 | ||
55c3a4f6 | 51 | memcpy(p->prev_lsp, dc_lsp, LPC_ORDER * sizeof(*p->prev_lsp)); |
04fc5c6b KS |
52 | memcpy(p->sid_lsp, dc_lsp, LPC_ORDER * sizeof(*p->sid_lsp)); |
53 | ||
54 | p->cng_random_seed = CNG_RANDOM_SEED; | |
55 | p->past_frame_type = SID_FRAME; | |
55c3a4f6 MNB |
56 | |
57 | return 0; | |
58 | } | |
59 | ||
60 | /** | |
61 | * Unpack the frame into parameters. | |
62 | * | |
63 | * @param p the context | |
64 | * @param buf pointer to the input buffer | |
65 | * @param buf_size size of the input buffer | |
66 | */ | |
67 | static int unpack_bitstream(G723_1_Context *p, const uint8_t *buf, | |
68 | int buf_size) | |
69 | { | |
70 | GetBitContext gb; | |
71 | int ad_cb_len; | |
72 | int temp, info_bits, i; | |
73 | ||
74 | init_get_bits(&gb, buf, buf_size * 8); | |
75 | ||
76 | /* Extract frame type and rate info */ | |
77 | info_bits = get_bits(&gb, 2); | |
78 | ||
79 | if (info_bits == 3) { | |
80 | p->cur_frame_type = UNTRANSMITTED_FRAME; | |
81 | return 0; | |
82 | } | |
83 | ||
84 | /* Extract 24 bit lsp indices, 8 bit for each band */ | |
85 | p->lsp_index[2] = get_bits(&gb, 8); | |
86 | p->lsp_index[1] = get_bits(&gb, 8); | |
87 | p->lsp_index[0] = get_bits(&gb, 8); | |
88 | ||
89 | if (info_bits == 2) { | |
90 | p->cur_frame_type = SID_FRAME; | |
91 | p->subframe[0].amp_index = get_bits(&gb, 6); | |
92 | return 0; | |
93 | } | |
94 | ||
95 | /* Extract the info common to both rates */ | |
96 | p->cur_rate = info_bits ? RATE_5300 : RATE_6300; | |
97 | p->cur_frame_type = ACTIVE_FRAME; | |
98 | ||
99 | p->pitch_lag[0] = get_bits(&gb, 7); | |
100 | if (p->pitch_lag[0] > 123) /* test if forbidden code */ | |
101 | return -1; | |
102 | p->pitch_lag[0] += PITCH_MIN; | |
103 | p->subframe[1].ad_cb_lag = get_bits(&gb, 2); | |
104 | ||
105 | p->pitch_lag[1] = get_bits(&gb, 7); | |
106 | if (p->pitch_lag[1] > 123) | |
107 | return -1; | |
108 | p->pitch_lag[1] += PITCH_MIN; | |
109 | p->subframe[3].ad_cb_lag = get_bits(&gb, 2); | |
110 | p->subframe[0].ad_cb_lag = 1; | |
111 | p->subframe[2].ad_cb_lag = 1; | |
112 | ||
113 | for (i = 0; i < SUBFRAMES; i++) { | |
114 | /* Extract combined gain */ | |
115 | temp = get_bits(&gb, 12); | |
116 | ad_cb_len = 170; | |
117 | p->subframe[i].dirac_train = 0; | |
118 | if (p->cur_rate == RATE_6300 && p->pitch_lag[i >> 1] < SUBFRAME_LEN - 2) { | |
119 | p->subframe[i].dirac_train = temp >> 11; | |
120 | temp &= 0x7FF; | |
121 | ad_cb_len = 85; | |
122 | } | |
123 | p->subframe[i].ad_cb_gain = FASTDIV(temp, GAIN_LEVELS); | |
124 | if (p->subframe[i].ad_cb_gain < ad_cb_len) { | |
125 | p->subframe[i].amp_index = temp - p->subframe[i].ad_cb_gain * | |
126 | GAIN_LEVELS; | |
127 | } else { | |
128 | return -1; | |
129 | } | |
130 | } | |
131 | ||
132 | p->subframe[0].grid_index = get_bits(&gb, 1); | |
133 | p->subframe[1].grid_index = get_bits(&gb, 1); | |
134 | p->subframe[2].grid_index = get_bits(&gb, 1); | |
135 | p->subframe[3].grid_index = get_bits(&gb, 1); | |
136 | ||
137 | if (p->cur_rate == RATE_6300) { | |
138 | skip_bits(&gb, 1); /* skip reserved bit */ | |
139 | ||
140 | /* Compute pulse_pos index using the 13-bit combined position index */ | |
141 | temp = get_bits(&gb, 13); | |
142 | p->subframe[0].pulse_pos = temp / 810; | |
143 | ||
144 | temp -= p->subframe[0].pulse_pos * 810; | |
145 | p->subframe[1].pulse_pos = FASTDIV(temp, 90); | |
146 | ||
147 | temp -= p->subframe[1].pulse_pos * 90; | |
148 | p->subframe[2].pulse_pos = FASTDIV(temp, 9); | |
149 | p->subframe[3].pulse_pos = temp - p->subframe[2].pulse_pos * 9; | |
150 | ||
151 | p->subframe[0].pulse_pos = (p->subframe[0].pulse_pos << 16) + | |
152 | get_bits(&gb, 16); | |
153 | p->subframe[1].pulse_pos = (p->subframe[1].pulse_pos << 14) + | |
154 | get_bits(&gb, 14); | |
155 | p->subframe[2].pulse_pos = (p->subframe[2].pulse_pos << 16) + | |
156 | get_bits(&gb, 16); | |
157 | p->subframe[3].pulse_pos = (p->subframe[3].pulse_pos << 14) + | |
158 | get_bits(&gb, 14); | |
159 | ||
160 | p->subframe[0].pulse_sign = get_bits(&gb, 6); | |
161 | p->subframe[1].pulse_sign = get_bits(&gb, 5); | |
162 | p->subframe[2].pulse_sign = get_bits(&gb, 6); | |
163 | p->subframe[3].pulse_sign = get_bits(&gb, 5); | |
164 | } else { /* 5300 bps */ | |
165 | p->subframe[0].pulse_pos = get_bits(&gb, 12); | |
166 | p->subframe[1].pulse_pos = get_bits(&gb, 12); | |
167 | p->subframe[2].pulse_pos = get_bits(&gb, 12); | |
168 | p->subframe[3].pulse_pos = get_bits(&gb, 12); | |
169 | ||
170 | p->subframe[0].pulse_sign = get_bits(&gb, 4); | |
171 | p->subframe[1].pulse_sign = get_bits(&gb, 4); | |
172 | p->subframe[2].pulse_sign = get_bits(&gb, 4); | |
173 | p->subframe[3].pulse_sign = get_bits(&gb, 4); | |
174 | } | |
175 | ||
176 | return 0; | |
177 | } | |
178 | ||
179 | /** | |
180 | * Bitexact implementation of sqrt(val/2). | |
181 | */ | |
182 | static int16_t square_root(int val) | |
183 | { | |
184 | int16_t res = 0; | |
185 | int16_t exp = 0x4000; | |
186 | int i; | |
187 | ||
188 | for (i = 0; i < 14; i ++) { | |
189 | int res_exp = res + exp; | |
190 | if (val >= res_exp * res_exp << 1) | |
191 | res += exp; | |
192 | exp >>= 1; | |
193 | } | |
194 | return res; | |
195 | } | |
196 | ||
197 | /** | |
55c3a4f6 MNB |
198 | * Bitexact implementation of 2ab scaled by 1/2^16. |
199 | * | |
200 | * @param a 32 bit multiplicand | |
201 | * @param b 16 bit multiplier | |
202 | */ | |
203 | #define MULL2(a, b) \ | |
204 | ((((a) >> 16) * (b) << 1) + (((a) & 0xffff) * (b) >> 15)) | |
205 | ||
206 | /** | |
55c3a4f6 MNB |
207 | * Generate fixed codebook excitation vector. |
208 | * | |
209 | * @param vector decoded excitation vector | |
210 | * @param subfrm current subframe | |
211 | * @param cur_rate current bitrate | |
212 | * @param pitch_lag closed loop pitch lag | |
213 | * @param index current subframe index | |
214 | */ | |
69665bd6 | 215 | static void gen_fcb_excitation(int16_t *vector, G723_1_Subframe *subfrm, |
55c3a4f6 MNB |
216 | enum Rate cur_rate, int pitch_lag, int index) |
217 | { | |
218 | int temp, i, j; | |
219 | ||
220 | memset(vector, 0, SUBFRAME_LEN * sizeof(*vector)); | |
221 | ||
222 | if (cur_rate == RATE_6300) { | |
69665bd6 | 223 | if (subfrm->pulse_pos >= max_pos[index]) |
55c3a4f6 MNB |
224 | return; |
225 | ||
226 | /* Decode amplitudes and positions */ | |
227 | j = PULSE_MAX - pulses[index]; | |
69665bd6 | 228 | temp = subfrm->pulse_pos; |
55c3a4f6 MNB |
229 | for (i = 0; i < SUBFRAME_LEN / GRID_SIZE; i++) { |
230 | temp -= combinatorial_table[j][i]; | |
231 | if (temp >= 0) | |
232 | continue; | |
233 | temp += combinatorial_table[j++][i]; | |
69665bd6 MR |
234 | if (subfrm->pulse_sign & (1 << (PULSE_MAX - j))) { |
235 | vector[subfrm->grid_index + GRID_SIZE * i] = | |
236 | -fixed_cb_gain[subfrm->amp_index]; | |
55c3a4f6 | 237 | } else { |
69665bd6 MR |
238 | vector[subfrm->grid_index + GRID_SIZE * i] = |
239 | fixed_cb_gain[subfrm->amp_index]; | |
55c3a4f6 MNB |
240 | } |
241 | if (j == PULSE_MAX) | |
242 | break; | |
243 | } | |
69665bd6 | 244 | if (subfrm->dirac_train == 1) |
165cc6fb | 245 | ff_g723_1_gen_dirac_train(vector, pitch_lag); |
55c3a4f6 | 246 | } else { /* 5300 bps */ |
69665bd6 MR |
247 | int cb_gain = fixed_cb_gain[subfrm->amp_index]; |
248 | int cb_shift = subfrm->grid_index; | |
249 | int cb_sign = subfrm->pulse_sign; | |
250 | int cb_pos = subfrm->pulse_pos; | |
55c3a4f6 MNB |
251 | int offset, beta, lag; |
252 | ||
253 | for (i = 0; i < 8; i += 2) { | |
254 | offset = ((cb_pos & 7) << 3) + cb_shift + i; | |
255 | vector[offset] = (cb_sign & 1) ? cb_gain : -cb_gain; | |
256 | cb_pos >>= 3; | |
257 | cb_sign >>= 1; | |
258 | } | |
259 | ||
260 | /* Enhance harmonic components */ | |
69665bd6 MR |
261 | lag = pitch_contrib[subfrm->ad_cb_gain << 1] + pitch_lag + |
262 | subfrm->ad_cb_lag - 1; | |
263 | beta = pitch_contrib[(subfrm->ad_cb_gain << 1) + 1]; | |
55c3a4f6 MNB |
264 | |
265 | if (lag < SUBFRAME_LEN - 2) { | |
266 | for (i = lag; i < SUBFRAME_LEN; i++) | |
267 | vector[i] += beta * vector[i - lag] >> 15; | |
268 | } | |
269 | } | |
270 | } | |
271 | ||
272 | /** | |
55c3a4f6 MNB |
273 | * Estimate maximum auto-correlation around pitch lag. |
274 | * | |
783da0d6 | 275 | * @param buf buffer with offset applied |
55c3a4f6 MNB |
276 | * @param offset offset of the excitation vector |
277 | * @param ccr_max pointer to the maximum auto-correlation | |
278 | * @param pitch_lag decoded pitch lag | |
279 | * @param length length of autocorrelation | |
280 | * @param dir forward lag(1) / backward lag(-1) | |
281 | */ | |
783da0d6 | 282 | static int autocorr_max(const int16_t *buf, int offset, int *ccr_max, |
55c3a4f6 MNB |
283 | int pitch_lag, int length, int dir) |
284 | { | |
285 | int limit, ccr, lag = 0; | |
55c3a4f6 MNB |
286 | int i; |
287 | ||
288 | pitch_lag = FFMIN(PITCH_MAX - 3, pitch_lag); | |
802bcdcb KS |
289 | if (dir > 0) |
290 | limit = FFMIN(FRAME_LEN + PITCH_MAX - offset - length, pitch_lag + 3); | |
291 | else | |
292 | limit = pitch_lag + 3; | |
55c3a4f6 MNB |
293 | |
294 | for (i = pitch_lag - 3; i <= limit; i++) { | |
165cc6fb | 295 | ccr = ff_g723_1_dot_product(buf, buf + dir * i, length); |
55c3a4f6 MNB |
296 | |
297 | if (ccr > *ccr_max) { | |
298 | *ccr_max = ccr; | |
299 | lag = i; | |
300 | } | |
301 | } | |
302 | return lag; | |
303 | } | |
304 | ||
305 | /** | |
306 | * Calculate pitch postfilter optimal and scaling gains. | |
307 | * | |
308 | * @param lag pitch postfilter forward/backward lag | |
309 | * @param ppf pitch postfilter parameters | |
310 | * @param cur_rate current bitrate | |
311 | * @param tgt_eng target energy | |
312 | * @param ccr cross-correlation | |
313 | * @param res_eng residual energy | |
314 | */ | |
315 | static void comp_ppf_gains(int lag, PPFParam *ppf, enum Rate cur_rate, | |
316 | int tgt_eng, int ccr, int res_eng) | |
317 | { | |
318 | int pf_residual; /* square of postfiltered residual */ | |
47c73a73 | 319 | int temp1, temp2; |
55c3a4f6 MNB |
320 | |
321 | ppf->index = lag; | |
322 | ||
323 | temp1 = tgt_eng * res_eng >> 1; | |
324 | temp2 = ccr * ccr << 1; | |
325 | ||
326 | if (temp2 > temp1) { | |
327 | if (ccr >= res_eng) { | |
328 | ppf->opt_gain = ppf_gain_weight[cur_rate]; | |
329 | } else { | |
330 | ppf->opt_gain = (ccr << 15) / res_eng * | |
331 | ppf_gain_weight[cur_rate] >> 15; | |
332 | } | |
333 | /* pf_res^2 = tgt_eng + 2*ccr*gain + res_eng*gain^2 */ | |
334 | temp1 = (tgt_eng << 15) + (ccr * ppf->opt_gain << 1); | |
335 | temp2 = (ppf->opt_gain * ppf->opt_gain >> 15) * res_eng; | |
47c73a73 | 336 | pf_residual = av_sat_add32(temp1, temp2 + (1 << 15)) >> 16; |
55c3a4f6 MNB |
337 | |
338 | if (tgt_eng >= pf_residual << 1) { | |
339 | temp1 = 0x7fff; | |
340 | } else { | |
341 | temp1 = (tgt_eng << 14) / pf_residual; | |
342 | } | |
343 | ||
344 | /* scaling_gain = sqrt(tgt_eng/pf_res^2) */ | |
345 | ppf->sc_gain = square_root(temp1 << 16); | |
346 | } else { | |
347 | ppf->opt_gain = 0; | |
348 | ppf->sc_gain = 0x7fff; | |
349 | } | |
350 | ||
351 | ppf->opt_gain = av_clip_int16(ppf->opt_gain * ppf->sc_gain >> 15); | |
352 | } | |
353 | ||
354 | /** | |
355 | * Calculate pitch postfilter parameters. | |
356 | * | |
357 | * @param p the context | |
358 | * @param offset offset of the excitation vector | |
359 | * @param pitch_lag decoded pitch lag | |
360 | * @param ppf pitch postfilter parameters | |
361 | * @param cur_rate current bitrate | |
362 | */ | |
363 | static void comp_ppf_coeff(G723_1_Context *p, int offset, int pitch_lag, | |
364 | PPFParam *ppf, enum Rate cur_rate) | |
365 | { | |
366 | ||
367 | int16_t scale; | |
368 | int i; | |
37161051 | 369 | int temp1, temp2; |
55c3a4f6 MNB |
370 | |
371 | /* | |
372 | * 0 - target energy | |
373 | * 1 - forward cross-correlation | |
374 | * 2 - forward residual energy | |
375 | * 3 - backward cross-correlation | |
376 | * 4 - backward residual energy | |
377 | */ | |
378 | int energy[5] = {0, 0, 0, 0, 0}; | |
35b533e4 | 379 | int16_t *buf = p->audio + LPC_ORDER + offset; |
783da0d6 | 380 | int fwd_lag = autocorr_max(buf, offset, &energy[1], pitch_lag, |
55c3a4f6 | 381 | SUBFRAME_LEN, 1); |
783da0d6 | 382 | int back_lag = autocorr_max(buf, offset, &energy[3], pitch_lag, |
55c3a4f6 MNB |
383 | SUBFRAME_LEN, -1); |
384 | ||
385 | ppf->index = 0; | |
386 | ppf->opt_gain = 0; | |
387 | ppf->sc_gain = 0x7fff; | |
388 | ||
389 | /* Case 0, Section 3.6 */ | |
390 | if (!back_lag && !fwd_lag) | |
391 | return; | |
392 | ||
393 | /* Compute target energy */ | |
165cc6fb | 394 | energy[0] = ff_g723_1_dot_product(buf, buf, SUBFRAME_LEN); |
55c3a4f6 MNB |
395 | |
396 | /* Compute forward residual energy */ | |
397 | if (fwd_lag) | |
165cc6fb VG |
398 | energy[2] = ff_g723_1_dot_product(buf + fwd_lag, buf + fwd_lag, |
399 | SUBFRAME_LEN); | |
55c3a4f6 MNB |
400 | |
401 | /* Compute backward residual energy */ | |
402 | if (back_lag) | |
165cc6fb VG |
403 | energy[4] = ff_g723_1_dot_product(buf - back_lag, buf - back_lag, |
404 | SUBFRAME_LEN); | |
55c3a4f6 MNB |
405 | |
406 | /* Normalize and shorten */ | |
407 | temp1 = 0; | |
408 | for (i = 0; i < 5; i++) | |
409 | temp1 = FFMAX(energy[i], temp1); | |
410 | ||
165cc6fb | 411 | scale = ff_g723_1_normalize_bits(temp1, 31); |
55c3a4f6 MNB |
412 | for (i = 0; i < 5; i++) |
413 | energy[i] = (energy[i] << scale) >> 16; | |
414 | ||
415 | if (fwd_lag && !back_lag) { /* Case 1 */ | |
416 | comp_ppf_gains(fwd_lag, ppf, cur_rate, energy[0], energy[1], | |
417 | energy[2]); | |
418 | } else if (!fwd_lag) { /* Case 2 */ | |
419 | comp_ppf_gains(-back_lag, ppf, cur_rate, energy[0], energy[3], | |
420 | energy[4]); | |
421 | } else { /* Case 3 */ | |
422 | ||
423 | /* | |
424 | * Select the largest of energy[1]^2/energy[2] | |
425 | * and energy[3]^2/energy[4] | |
426 | */ | |
427 | temp1 = energy[4] * ((energy[1] * energy[1] + (1 << 14)) >> 15); | |
428 | temp2 = energy[2] * ((energy[3] * energy[3] + (1 << 14)) >> 15); | |
429 | if (temp1 >= temp2) { | |
430 | comp_ppf_gains(fwd_lag, ppf, cur_rate, energy[0], energy[1], | |
431 | energy[2]); | |
432 | } else { | |
433 | comp_ppf_gains(-back_lag, ppf, cur_rate, energy[0], energy[3], | |
434 | energy[4]); | |
435 | } | |
436 | } | |
437 | } | |
438 | ||
439 | /** | |
440 | * Classify frames as voiced/unvoiced. | |
441 | * | |
442 | * @param p the context | |
443 | * @param pitch_lag decoded pitch_lag | |
444 | * @param exc_eng excitation energy estimation | |
445 | * @param scale scaling factor of exc_eng | |
446 | * | |
447 | * @return residual interpolation index if voiced, 0 otherwise | |
448 | */ | |
449 | static int comp_interp_index(G723_1_Context *p, int pitch_lag, | |
450 | int *exc_eng, int *scale) | |
451 | { | |
452 | int offset = PITCH_MAX + 2 * SUBFRAME_LEN; | |
35b533e4 | 453 | int16_t *buf = p->audio + LPC_ORDER; |
55c3a4f6 MNB |
454 | |
455 | int index, ccr, tgt_eng, best_eng, temp; | |
456 | ||
165cc6fb | 457 | *scale = ff_g723_1_scale_vector(buf, p->excitation, FRAME_LEN + PITCH_MAX); |
35b533e4 | 458 | buf += offset; |
55c3a4f6 MNB |
459 | |
460 | /* Compute maximum backward cross-correlation */ | |
461 | ccr = 0; | |
783da0d6 | 462 | index = autocorr_max(buf, offset, &ccr, pitch_lag, SUBFRAME_LEN * 2, -1); |
47c73a73 | 463 | ccr = av_sat_add32(ccr, 1 << 15) >> 16; |
55c3a4f6 MNB |
464 | |
465 | /* Compute target energy */ | |
165cc6fb | 466 | tgt_eng = ff_g723_1_dot_product(buf, buf, SUBFRAME_LEN * 2); |
47c73a73 | 467 | *exc_eng = av_sat_add32(tgt_eng, 1 << 15) >> 16; |
55c3a4f6 MNB |
468 | |
469 | if (ccr <= 0) | |
470 | return 0; | |
471 | ||
472 | /* Compute best energy */ | |
165cc6fb VG |
473 | best_eng = ff_g723_1_dot_product(buf - index, buf - index, |
474 | SUBFRAME_LEN * 2); | |
47c73a73 | 475 | best_eng = av_sat_add32(best_eng, 1 << 15) >> 16; |
55c3a4f6 MNB |
476 | |
477 | temp = best_eng * *exc_eng >> 3; | |
478 | ||
479 | if (temp < ccr * ccr) | |
480 | return index; | |
481 | else | |
482 | return 0; | |
483 | } | |
484 | ||
485 | /** | |
486 | * Peform residual interpolation based on frame classification. | |
487 | * | |
488 | * @param buf decoded excitation vector | |
489 | * @param out output vector | |
490 | * @param lag decoded pitch lag | |
491 | * @param gain interpolated gain | |
492 | * @param rseed seed for random number generator | |
493 | */ | |
494 | static void residual_interp(int16_t *buf, int16_t *out, int lag, | |
495 | int gain, int *rseed) | |
496 | { | |
497 | int i; | |
498 | if (lag) { /* Voiced */ | |
499 | int16_t *vector_ptr = buf + PITCH_MAX; | |
500 | /* Attenuate */ | |
501 | for (i = 0; i < lag; i++) | |
4b728b47 MR |
502 | out[i] = vector_ptr[i - lag] * 3 >> 2; |
503 | av_memcpy_backptr((uint8_t*)(out + lag), lag * sizeof(*out), | |
504 | (FRAME_LEN - lag) * sizeof(*out)); | |
55c3a4f6 MNB |
505 | } else { /* Unvoiced */ |
506 | for (i = 0; i < FRAME_LEN; i++) { | |
507 | *rseed = *rseed * 521 + 259; | |
508 | out[i] = gain * *rseed >> 15; | |
509 | } | |
510 | memset(buf, 0, (FRAME_LEN + PITCH_MAX) * sizeof(*buf)); | |
511 | } | |
512 | } | |
513 | ||
514 | /** | |
515 | * Perform IIR filtering. | |
516 | * | |
517 | * @param fir_coef FIR coefficients | |
518 | * @param iir_coef IIR coefficients | |
519 | * @param src source vector | |
520 | * @param dest destination vector | |
521 | */ | |
165cc6fb VG |
522 | static void iir_filter(int16_t *fir_coef, int16_t *iir_coef, |
523 | int16_t *src, int *dest) | |
55c3a4f6 MNB |
524 | { |
525 | int m, n; | |
526 | ||
527 | for (m = 0; m < SUBFRAME_LEN; m++) { | |
528 | int64_t filter = 0; | |
529 | for (n = 1; n <= LPC_ORDER; n++) { | |
530 | filter -= fir_coef[n - 1] * src[m - n] - | |
531 | iir_coef[n - 1] * (dest[m - n] >> 16); | |
532 | } | |
533 | ||
534 | dest[m] = av_clipl_int32((src[m] << 16) + (filter << 3) + (1 << 15)); | |
535 | } | |
536 | } | |
537 | ||
538 | /** | |
539 | * Adjust gain of postfiltered signal. | |
540 | * | |
541 | * @param p the context | |
542 | * @param buf postfiltered output vector | |
543 | * @param energy input energy coefficient | |
544 | */ | |
545 | static void gain_scale(G723_1_Context *p, int16_t * buf, int energy) | |
546 | { | |
547 | int num, denom, gain, bits1, bits2; | |
548 | int i; | |
549 | ||
550 | num = energy; | |
551 | denom = 0; | |
552 | for (i = 0; i < SUBFRAME_LEN; i++) { | |
1eb1f6f2 MR |
553 | int temp = buf[i] >> 2; |
554 | temp *= temp; | |
47c73a73 | 555 | denom = av_sat_dadd32(denom, temp); |
55c3a4f6 MNB |
556 | } |
557 | ||
558 | if (num && denom) { | |
165cc6fb VG |
559 | bits1 = ff_g723_1_normalize_bits(num, 31); |
560 | bits2 = ff_g723_1_normalize_bits(denom, 31); | |
55c3a4f6 MNB |
561 | num = num << bits1 >> 1; |
562 | denom <<= bits2; | |
563 | ||
564 | bits2 = 5 + bits1 - bits2; | |
565 | bits2 = FFMAX(0, bits2); | |
566 | ||
567 | gain = (num >> 1) / (denom >> 16); | |
568 | gain = square_root(gain << 16 >> bits2); | |
569 | } else { | |
570 | gain = 1 << 12; | |
571 | } | |
572 | ||
573 | for (i = 0; i < SUBFRAME_LEN; i++) { | |
8b0de734 | 574 | p->pf_gain = (15 * p->pf_gain + gain + (1 << 3)) >> 4; |
55c3a4f6 MNB |
575 | buf[i] = av_clip_int16((buf[i] * (p->pf_gain + (p->pf_gain >> 4)) + |
576 | (1 << 10)) >> 11); | |
577 | } | |
578 | } | |
579 | ||
580 | /** | |
581 | * Perform formant filtering. | |
582 | * | |
583 | * @param p the context | |
584 | * @param lpc quantized lpc coefficients | |
f645710c MR |
585 | * @param buf input buffer |
586 | * @param dst output buffer | |
55c3a4f6 | 587 | */ |
f645710c MR |
588 | static void formant_postfilter(G723_1_Context *p, int16_t *lpc, |
589 | int16_t *buf, int16_t *dst) | |
55c3a4f6 | 590 | { |
19532643 | 591 | int16_t filter_coef[2][LPC_ORDER]; |
55c3a4f6 MNB |
592 | int filter_signal[LPC_ORDER + FRAME_LEN], *signal_ptr; |
593 | int i, j, k; | |
594 | ||
595 | memcpy(buf, p->fir_mem, LPC_ORDER * sizeof(*buf)); | |
596 | memcpy(filter_signal, p->iir_mem, LPC_ORDER * sizeof(*filter_signal)); | |
597 | ||
598 | for (i = LPC_ORDER, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) { | |
599 | for (k = 0; k < LPC_ORDER; k++) { | |
600 | filter_coef[0][k] = (-lpc[k] * postfilter_tbl[0][k] + | |
601 | (1 << 14)) >> 15; | |
602 | filter_coef[1][k] = (-lpc[k] * postfilter_tbl[1][k] + | |
603 | (1 << 14)) >> 15; | |
604 | } | |
165cc6fb | 605 | iir_filter(filter_coef[0], filter_coef[1], buf + i, filter_signal + i); |
f86b2f36 | 606 | lpc += LPC_ORDER; |
55c3a4f6 MNB |
607 | } |
608 | ||
609 | memcpy(p->fir_mem, buf + FRAME_LEN, LPC_ORDER * sizeof(*p->fir_mem)); | |
610 | memcpy(p->iir_mem, filter_signal + FRAME_LEN, | |
611 | LPC_ORDER * sizeof(*p->iir_mem)); | |
612 | ||
19532643 | 613 | buf += LPC_ORDER; |
55c3a4f6 MNB |
614 | signal_ptr = filter_signal + LPC_ORDER; |
615 | for (i = 0; i < SUBFRAMES; i++) { | |
52aa3015 | 616 | int temp; |
55c3a4f6 MNB |
617 | int auto_corr[2]; |
618 | int scale, energy; | |
619 | ||
620 | /* Normalize */ | |
165cc6fb | 621 | scale = ff_g723_1_scale_vector(dst, buf, SUBFRAME_LEN); |
55c3a4f6 MNB |
622 | |
623 | /* Compute auto correlation coefficients */ | |
165cc6fb VG |
624 | auto_corr[0] = ff_g723_1_dot_product(dst, dst + 1, SUBFRAME_LEN - 1); |
625 | auto_corr[1] = ff_g723_1_dot_product(dst, dst, SUBFRAME_LEN); | |
55c3a4f6 MNB |
626 | |
627 | /* Compute reflection coefficient */ | |
628 | temp = auto_corr[1] >> 16; | |
629 | if (temp) { | |
630 | temp = (auto_corr[0] >> 2) / temp; | |
631 | } | |
e141cf2c | 632 | p->reflection_coef = (3 * p->reflection_coef + temp + 2) >> 2; |
52aa3015 | 633 | temp = -p->reflection_coef >> 1 & ~3; |
55c3a4f6 MNB |
634 | |
635 | /* Compensation filter */ | |
636 | for (j = 0; j < SUBFRAME_LEN; j++) { | |
f645710c | 637 | dst[j] = av_sat_dadd32(signal_ptr[j], |
19532643 | 638 | (signal_ptr[j - 1] >> 16) * temp) >> 16; |
55c3a4f6 MNB |
639 | } |
640 | ||
641 | /* Compute normalized signal energy */ | |
642 | temp = 2 * scale + 4; | |
643 | if (temp < 0) { | |
644 | energy = av_clipl_int32((int64_t)auto_corr[1] << -temp); | |
645 | } else | |
646 | energy = auto_corr[1] >> temp; | |
647 | ||
f645710c | 648 | gain_scale(p, dst, energy); |
55c3a4f6 | 649 | |
19532643 | 650 | buf += SUBFRAME_LEN; |
55c3a4f6 | 651 | signal_ptr += SUBFRAME_LEN; |
f645710c | 652 | dst += SUBFRAME_LEN; |
55c3a4f6 MNB |
653 | } |
654 | } | |
655 | ||
04fc5c6b KS |
656 | static int sid_gain_to_lsp_index(int gain) |
657 | { | |
658 | if (gain < 0x10) | |
659 | return gain << 6; | |
660 | else if (gain < 0x20) | |
661 | return gain - 8 << 7; | |
662 | else | |
663 | return gain - 20 << 8; | |
664 | } | |
665 | ||
666 | static inline int cng_rand(int *state, int base) | |
667 | { | |
668 | *state = (*state * 521 + 259) & 0xFFFF; | |
669 | return (*state & 0x7FFF) * base >> 15; | |
670 | } | |
671 | ||
672 | static int estimate_sid_gain(G723_1_Context *p) | |
673 | { | |
674 | int i, shift, seg, seg2, t, val, val_add, x, y; | |
675 | ||
676 | shift = 16 - p->cur_gain * 2; | |
677 | if (shift > 0) | |
678 | t = p->sid_gain << shift; | |
679 | else | |
680 | t = p->sid_gain >> -shift; | |
681 | x = t * cng_filt[0] >> 16; | |
682 | ||
683 | if (x >= cng_bseg[2]) | |
684 | return 0x3F; | |
685 | ||
686 | if (x >= cng_bseg[1]) { | |
687 | shift = 4; | |
688 | seg = 3; | |
689 | } else { | |
690 | shift = 3; | |
691 | seg = (x >= cng_bseg[0]); | |
692 | } | |
693 | seg2 = FFMIN(seg, 3); | |
694 | ||
695 | val = 1 << shift; | |
696 | val_add = val >> 1; | |
697 | for (i = 0; i < shift; i++) { | |
698 | t = seg * 32 + (val << seg2); | |
699 | t *= t; | |
700 | if (x >= t) | |
701 | val += val_add; | |
702 | else | |
703 | val -= val_add; | |
704 | val_add >>= 1; | |
705 | } | |
706 | ||
707 | t = seg * 32 + (val << seg2); | |
708 | y = t * t - x; | |
709 | if (y <= 0) { | |
710 | t = seg * 32 + (val + 1 << seg2); | |
711 | t = t * t - x; | |
712 | val = (seg2 - 1 << 4) + val; | |
713 | if (t >= y) | |
714 | val++; | |
715 | } else { | |
716 | t = seg * 32 + (val - 1 << seg2); | |
717 | t = t * t - x; | |
718 | val = (seg2 - 1 << 4) + val; | |
719 | if (t >= y) | |
720 | val--; | |
721 | } | |
722 | ||
723 | return val; | |
724 | } | |
725 | ||
726 | static void generate_noise(G723_1_Context *p) | |
727 | { | |
728 | int i, j, idx, t; | |
729 | int off[SUBFRAMES]; | |
730 | int signs[SUBFRAMES / 2 * 11], pos[SUBFRAMES / 2 * 11]; | |
731 | int tmp[SUBFRAME_LEN * 2]; | |
732 | int16_t *vector_ptr; | |
733 | int64_t sum; | |
734 | int b0, c, delta, x, shift; | |
735 | ||
736 | p->pitch_lag[0] = cng_rand(&p->cng_random_seed, 21) + 123; | |
737 | p->pitch_lag[1] = cng_rand(&p->cng_random_seed, 19) + 123; | |
738 | ||
739 | for (i = 0; i < SUBFRAMES; i++) { | |
740 | p->subframe[i].ad_cb_gain = cng_rand(&p->cng_random_seed, 50) + 1; | |
741 | p->subframe[i].ad_cb_lag = cng_adaptive_cb_lag[i]; | |
742 | } | |
743 | ||
744 | for (i = 0; i < SUBFRAMES / 2; i++) { | |
745 | t = cng_rand(&p->cng_random_seed, 1 << 13); | |
746 | off[i * 2] = t & 1; | |
747 | off[i * 2 + 1] = ((t >> 1) & 1) + SUBFRAME_LEN; | |
748 | t >>= 2; | |
749 | for (j = 0; j < 11; j++) { | |
750 | signs[i * 11 + j] = (t & 1) * 2 - 1 << 14; | |
751 | t >>= 1; | |
752 | } | |
753 | } | |
754 | ||
755 | idx = 0; | |
756 | for (i = 0; i < SUBFRAMES; i++) { | |
757 | for (j = 0; j < SUBFRAME_LEN / 2; j++) | |
758 | tmp[j] = j; | |
759 | t = SUBFRAME_LEN / 2; | |
760 | for (j = 0; j < pulses[i]; j++, idx++) { | |
761 | int idx2 = cng_rand(&p->cng_random_seed, t); | |
762 | ||
763 | pos[idx] = tmp[idx2] * 2 + off[i]; | |
764 | tmp[idx2] = tmp[--t]; | |
765 | } | |
766 | } | |
767 | ||
768 | vector_ptr = p->audio + LPC_ORDER; | |
769 | memcpy(vector_ptr, p->prev_excitation, | |
770 | PITCH_MAX * sizeof(*p->excitation)); | |
771 | for (i = 0; i < SUBFRAMES; i += 2) { | |
165cc6fb VG |
772 | ff_g723_1_gen_acb_excitation(vector_ptr, vector_ptr, |
773 | p->pitch_lag[i >> 1], &p->subframe[i], | |
774 | p->cur_rate); | |
775 | ff_g723_1_gen_acb_excitation(vector_ptr + SUBFRAME_LEN, | |
776 | vector_ptr + SUBFRAME_LEN, | |
777 | p->pitch_lag[i >> 1], &p->subframe[i + 1], | |
778 | p->cur_rate); | |
04fc5c6b KS |
779 | |
780 | t = 0; | |
781 | for (j = 0; j < SUBFRAME_LEN * 2; j++) | |
782 | t |= FFABS(vector_ptr[j]); | |
783 | t = FFMIN(t, 0x7FFF); | |
784 | if (!t) { | |
785 | shift = 0; | |
786 | } else { | |
787 | shift = -10 + av_log2(t); | |
788 | if (shift < -2) | |
789 | shift = -2; | |
790 | } | |
791 | sum = 0; | |
792 | if (shift < 0) { | |
793 | for (j = 0; j < SUBFRAME_LEN * 2; j++) { | |
794 | t = vector_ptr[j] << -shift; | |
795 | sum += t * t; | |
796 | tmp[j] = t; | |
797 | } | |
798 | } else { | |
799 | for (j = 0; j < SUBFRAME_LEN * 2; j++) { | |
800 | t = vector_ptr[j] >> shift; | |
801 | sum += t * t; | |
802 | tmp[j] = t; | |
803 | } | |
804 | } | |
805 | ||
806 | b0 = 0; | |
807 | for (j = 0; j < 11; j++) | |
808 | b0 += tmp[pos[(i / 2) * 11 + j]] * signs[(i / 2) * 11 + j]; | |
809 | b0 = b0 * 2 * 2979LL + (1 << 29) >> 30; // approximated division by 11 | |
810 | ||
811 | c = p->cur_gain * (p->cur_gain * SUBFRAME_LEN >> 5); | |
812 | if (shift * 2 + 3 >= 0) | |
813 | c >>= shift * 2 + 3; | |
814 | else | |
815 | c <<= -(shift * 2 + 3); | |
816 | c = (av_clipl_int32(sum << 1) - c) * 2979LL >> 15; | |
817 | ||
818 | delta = b0 * b0 * 2 - c; | |
819 | if (delta <= 0) { | |
820 | x = -b0; | |
821 | } else { | |
822 | delta = square_root(delta); | |
823 | x = delta - b0; | |
824 | t = delta + b0; | |
825 | if (FFABS(t) < FFABS(x)) | |
826 | x = -t; | |
827 | } | |
828 | shift++; | |
829 | if (shift < 0) | |
830 | x >>= -shift; | |
831 | else | |
832 | x <<= shift; | |
833 | x = av_clip(x, -10000, 10000); | |
834 | ||
835 | for (j = 0; j < 11; j++) { | |
836 | idx = (i / 2) * 11 + j; | |
837 | vector_ptr[pos[idx]] = av_clip_int16(vector_ptr[pos[idx]] + | |
838 | (x * signs[idx] >> 15)); | |
839 | } | |
840 | ||
841 | /* copy decoded data to serve as a history for the next decoded subframes */ | |
842 | memcpy(vector_ptr + PITCH_MAX, vector_ptr, | |
843 | sizeof(*vector_ptr) * SUBFRAME_LEN * 2); | |
844 | vector_ptr += SUBFRAME_LEN * 2; | |
845 | } | |
846 | /* Save the excitation for the next frame */ | |
847 | memcpy(p->prev_excitation, p->audio + LPC_ORDER + FRAME_LEN, | |
848 | PITCH_MAX * sizeof(*p->excitation)); | |
849 | } | |
850 | ||
55c3a4f6 MNB |
851 | static int g723_1_decode_frame(AVCodecContext *avctx, void *data, |
852 | int *got_frame_ptr, AVPacket *avpkt) | |
853 | { | |
854 | G723_1_Context *p = avctx->priv_data; | |
7e52fd6b | 855 | AVFrame *frame = data; |
55c3a4f6 MNB |
856 | const uint8_t *buf = avpkt->data; |
857 | int buf_size = avpkt->size; | |
858 | int dec_mode = buf[0] & 3; | |
859 | ||
860 | PPFParam ppf[SUBFRAMES]; | |
861 | int16_t cur_lsp[LPC_ORDER]; | |
862 | int16_t lpc[SUBFRAMES * LPC_ORDER]; | |
863 | int16_t acb_vector[SUBFRAME_LEN]; | |
d3e0766f | 864 | int16_t *out; |
55c3a4f6 | 865 | int bad_frame = 0, i, j, ret; |
35b533e4 | 866 | int16_t *audio = p->audio; |
55c3a4f6 MNB |
867 | |
868 | if (buf_size < frame_size[dec_mode]) { | |
869 | if (buf_size) | |
870 | av_log(avctx, AV_LOG_WARNING, | |
871 | "Expected %d bytes, got %d - skipping packet\n", | |
872 | frame_size[dec_mode], buf_size); | |
873 | *got_frame_ptr = 0; | |
874 | return buf_size; | |
875 | } | |
876 | ||
877 | if (unpack_bitstream(p, buf, buf_size) < 0) { | |
878 | bad_frame = 1; | |
879 | if (p->past_frame_type == ACTIVE_FRAME) | |
880 | p->cur_frame_type = ACTIVE_FRAME; | |
881 | else | |
882 | p->cur_frame_type = UNTRANSMITTED_FRAME; | |
883 | } | |
884 | ||
7e52fd6b | 885 | frame->nb_samples = FRAME_LEN; |
759001c5 | 886 | if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { |
55c3a4f6 MNB |
887 | av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
888 | return ret; | |
889 | } | |
890 | ||
7e52fd6b | 891 | out = (int16_t *)frame->data[0]; |
d3e0766f | 892 | |
55c3a4f6 MNB |
893 | if (p->cur_frame_type == ACTIVE_FRAME) { |
894 | if (!bad_frame) | |
895 | p->erased_frames = 0; | |
896 | else if (p->erased_frames != 3) | |
897 | p->erased_frames++; | |
898 | ||
165cc6fb VG |
899 | ff_g723_1_inverse_quant(cur_lsp, p->prev_lsp, p->lsp_index, bad_frame); |
900 | ff_g723_1_lsp_interpolate(lpc, cur_lsp, p->prev_lsp); | |
55c3a4f6 MNB |
901 | |
902 | /* Save the lsp_vector for the next frame */ | |
903 | memcpy(p->prev_lsp, cur_lsp, LPC_ORDER * sizeof(*p->prev_lsp)); | |
904 | ||
905 | /* Generate the excitation for the frame */ | |
906 | memcpy(p->excitation, p->prev_excitation, | |
907 | PITCH_MAX * sizeof(*p->excitation)); | |
55c3a4f6 | 908 | if (!p->erased_frames) { |
cbcf1b41 MR |
909 | int16_t *vector_ptr = p->excitation + PITCH_MAX; |
910 | ||
55c3a4f6 MNB |
911 | /* Update interpolation gain memory */ |
912 | p->interp_gain = fixed_cb_gain[(p->subframe[2].amp_index + | |
913 | p->subframe[3].amp_index) >> 1]; | |
914 | for (i = 0; i < SUBFRAMES; i++) { | |
69665bd6 | 915 | gen_fcb_excitation(vector_ptr, &p->subframe[i], p->cur_rate, |
55c3a4f6 | 916 | p->pitch_lag[i >> 1], i); |
165cc6fb VG |
917 | ff_g723_1_gen_acb_excitation(acb_vector, |
918 | &p->excitation[SUBFRAME_LEN * i], | |
919 | p->pitch_lag[i >> 1], | |
920 | &p->subframe[i], p->cur_rate); | |
55c3a4f6 MNB |
921 | /* Get the total excitation */ |
922 | for (j = 0; j < SUBFRAME_LEN; j++) { | |
138914dc MR |
923 | int v = av_clip_int16(vector_ptr[j] << 1); |
924 | vector_ptr[j] = av_clip_int16(v + acb_vector[j]); | |
55c3a4f6 MNB |
925 | } |
926 | vector_ptr += SUBFRAME_LEN; | |
927 | } | |
928 | ||
929 | vector_ptr = p->excitation + PITCH_MAX; | |
930 | ||
55c3a4f6 MNB |
931 | p->interp_index = comp_interp_index(p, p->pitch_lag[1], |
932 | &p->sid_gain, &p->cur_gain); | |
933 | ||
35b533e4 | 934 | /* Peform pitch postfiltering */ |
55c3a4f6 MNB |
935 | if (p->postfilter) { |
936 | i = PITCH_MAX; | |
937 | for (j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) | |
938 | comp_ppf_coeff(p, i, p->pitch_lag[j >> 1], | |
939 | ppf + j, p->cur_rate); | |
55c3a4f6 | 940 | |
55c3a4f6 MNB |
941 | for (i = 0, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) |
942 | ff_acelp_weighted_vector_sum(p->audio + LPC_ORDER + i, | |
943 | vector_ptr + i, | |
944 | vector_ptr + i + ppf[j].index, | |
945 | ppf[j].sc_gain, | |
946 | ppf[j].opt_gain, | |
947 | 1 << 14, 15, SUBFRAME_LEN); | |
35b533e4 MR |
948 | } else { |
949 | audio = vector_ptr - LPC_ORDER; | |
950 | } | |
55c3a4f6 | 951 | |
4b728b47 MR |
952 | /* Save the excitation for the next frame */ |
953 | memcpy(p->prev_excitation, p->excitation + FRAME_LEN, | |
954 | PITCH_MAX * sizeof(*p->excitation)); | |
55c3a4f6 MNB |
955 | } else { |
956 | p->interp_gain = (p->interp_gain * 3 + 2) >> 2; | |
957 | if (p->erased_frames == 3) { | |
958 | /* Mute output */ | |
959 | memset(p->excitation, 0, | |
960 | (FRAME_LEN + PITCH_MAX) * sizeof(*p->excitation)); | |
4b728b47 MR |
961 | memset(p->prev_excitation, 0, |
962 | PITCH_MAX * sizeof(*p->excitation)); | |
7e52fd6b | 963 | memset(frame->data[0], 0, |
55c3a4f6 MNB |
964 | (FRAME_LEN + LPC_ORDER) * sizeof(int16_t)); |
965 | } else { | |
4b728b47 MR |
966 | int16_t *buf = p->audio + LPC_ORDER; |
967 | ||
55c3a4f6 | 968 | /* Regenerate frame */ |
4b728b47 | 969 | residual_interp(p->excitation, buf, p->interp_index, |
55c3a4f6 | 970 | p->interp_gain, &p->random_seed); |
4b728b47 MR |
971 | |
972 | /* Save the excitation for the next frame */ | |
973 | memcpy(p->prev_excitation, buf + (FRAME_LEN - PITCH_MAX), | |
974 | PITCH_MAX * sizeof(*p->excitation)); | |
55c3a4f6 MNB |
975 | } |
976 | } | |
04fc5c6b | 977 | p->cng_random_seed = CNG_RANDOM_SEED; |
55c3a4f6 | 978 | } else { |
04fc5c6b KS |
979 | if (p->cur_frame_type == SID_FRAME) { |
980 | p->sid_gain = sid_gain_to_lsp_index(p->subframe[0].amp_index); | |
165cc6fb | 981 | ff_g723_1_inverse_quant(p->sid_lsp, p->prev_lsp, p->lsp_index, 0); |
04fc5c6b KS |
982 | } else if (p->past_frame_type == ACTIVE_FRAME) { |
983 | p->sid_gain = estimate_sid_gain(p); | |
984 | } | |
55c3a4f6 | 985 | |
04fc5c6b KS |
986 | if (p->past_frame_type == ACTIVE_FRAME) |
987 | p->cur_gain = p->sid_gain; | |
988 | else | |
989 | p->cur_gain = (p->cur_gain * 7 + p->sid_gain) >> 3; | |
990 | generate_noise(p); | |
165cc6fb | 991 | ff_g723_1_lsp_interpolate(lpc, p->sid_lsp, p->prev_lsp); |
04fc5c6b KS |
992 | /* Save the lsp_vector for the next frame */ |
993 | memcpy(p->prev_lsp, p->sid_lsp, LPC_ORDER * sizeof(*p->prev_lsp)); | |
55c3a4f6 MNB |
994 | } |
995 | ||
996 | p->past_frame_type = p->cur_frame_type; | |
997 | ||
998 | memcpy(p->audio, p->synth_mem, LPC_ORDER * sizeof(*p->audio)); | |
999 | for (i = LPC_ORDER, j = 0; j < SUBFRAMES; i += SUBFRAME_LEN, j++) | |
1000 | ff_celp_lp_synthesis_filter(p->audio + i, &lpc[j * LPC_ORDER], | |
35b533e4 | 1001 | audio + i, SUBFRAME_LEN, LPC_ORDER, |
55c3a4f6 MNB |
1002 | 0, 1, 1 << 12); |
1003 | memcpy(p->synth_mem, p->audio + FRAME_LEN, LPC_ORDER * sizeof(*p->audio)); | |
1004 | ||
d3e0766f | 1005 | if (p->postfilter) { |
f645710c | 1006 | formant_postfilter(p, lpc, p->audio, out); |
d3e0766f KS |
1007 | } else { // if output is not postfiltered it should be scaled by 2 |
1008 | for (i = 0; i < FRAME_LEN; i++) | |
1009 | out[i] = av_clip_int16(p->audio[LPC_ORDER + i] << 1); | |
1010 | } | |
55c3a4f6 | 1011 | |
7e52fd6b | 1012 | *got_frame_ptr = 1; |
55c3a4f6 MNB |
1013 | |
1014 | return frame_size[dec_mode]; | |
1015 | } | |
1016 | ||
1017 | #define OFFSET(x) offsetof(G723_1_Context, x) | |
1018 | #define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM | |
1019 | ||
1020 | static const AVOption options[] = { | |
1021 | { "postfilter", "postfilter on/off", OFFSET(postfilter), AV_OPT_TYPE_INT, | |
e6153f17 | 1022 | { .i64 = 1 }, 0, 1, AD }, |
55c3a4f6 MNB |
1023 | { NULL } |
1024 | }; | |
1025 | ||
1026 | ||
1027 | static const AVClass g723_1dec_class = { | |
1028 | .class_name = "G.723.1 decoder", | |
1029 | .item_name = av_default_item_name, | |
1030 | .option = options, | |
1031 | .version = LIBAVUTIL_VERSION_INT, | |
1032 | }; | |
1033 | ||
1034 | AVCodec ff_g723_1_decoder = { | |
1035 | .name = "g723_1", | |
b2bed932 | 1036 | .long_name = NULL_IF_CONFIG_SMALL("G.723.1"), |
55c3a4f6 | 1037 | .type = AVMEDIA_TYPE_AUDIO, |
36ef5369 | 1038 | .id = AV_CODEC_ID_G723_1, |
55c3a4f6 MNB |
1039 | .priv_data_size = sizeof(G723_1_Context), |
1040 | .init = g723_1_decode_init, | |
1041 | .decode = g723_1_decode_frame, | |
def97856 | 1042 | .capabilities = AV_CODEC_CAP_SUBFRAMES | AV_CODEC_CAP_DR1, |
55c3a4f6 MNB |
1043 | .priv_class = &g723_1dec_class, |
1044 | }; |