1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4 © Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
5 Forschung e.V. All rights reserved.
6
7 1. INTRODUCTION
8 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9 that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10 scheme for digital audio. This FDK AAC Codec software is intended to be used on
11 a wide variety of Android devices.
12
13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14 general perceptual audio codecs. AAC-ELD is considered the best-performing
15 full-bandwidth communications codec by independent studies and is widely
16 deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17 specifications.
18
19 Patent licenses for necessary patent claims for the FDK AAC Codec (including
20 those of Fraunhofer) may be obtained through Via Licensing
21 (www.vialicensing.com) or through the respective patent owners individually for
22 the purpose of encoding or decoding bit streams in products that are compliant
23 with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24 Android devices already license these patent claims through Via Licensing or
25 directly from the patent owners, and therefore FDK AAC Codec software may
26 already be covered under those patent licenses when it is used for those
27 licensed purposes only.
28
29 Commercially-licensed AAC software libraries, including floating-point versions
30 with enhanced sound quality, are also available from Fraunhofer. Users are
31 encouraged to check the Fraunhofer website for additional applications
32 information and documentation.
33
34 2. COPYRIGHT LICENSE
35
36 Redistribution and use in source and binary forms, with or without modification,
37 are permitted without payment of copyright license fees provided that you
38 satisfy the following conditions:
39
40 You must retain the complete text of this software license in redistributions of
41 the FDK AAC Codec or your modifications thereto in source code form.
42
43 You must retain the complete text of this software license in the documentation
44 and/or other materials provided with redistributions of the FDK AAC Codec or
45 your modifications thereto in binary form. You must make available free of
46 charge copies of the complete source code of the FDK AAC Codec and your
47 modifications thereto to recipients of copies in binary form.
48
49 The name of Fraunhofer may not be used to endorse or promote products derived
50 from this library without prior written permission.
51
52 You may not charge copyright license fees for anyone to use, copy or distribute
53 the FDK AAC Codec software or your modifications thereto.
54
55 Your modified versions of the FDK AAC Codec must carry prominent notices stating
56 that you changed the software and the date of any change. For modified versions
57 of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58 must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59 AAC Codec Library for Android."
60
61 3. NO PATENT LICENSE
62
63 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64 limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65 Fraunhofer provides no warranty of patent non-infringement with respect to this
66 software.
67
68 You may use this FDK AAC Codec software or modifications thereto only for
69 purposes that are authorized by appropriate patent licenses.
70
71 4. DISCLAIMER
72
73 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74 holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75 including but not limited to the implied warranties of merchantability and
76 fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78 or consequential damages, including but not limited to procurement of substitute
79 goods or services; loss of use, data, or profits, or business interruption,
80 however caused and on any theory of liability, whether in contract, strict
81 liability, or tort (including negligence), arising in any way out of the use of
82 this software, even if advised of the possibility of such damage.
83
84 5. CONTACT INFORMATION
85
86 Fraunhofer Institute for Integrated Circuits IIS
87 Attention: Audio and Multimedia Departments - FDK AAC LL
88 Am Wolfsmantel 33
89 91058 Erlangen, Germany
90
91 www.iis.fraunhofer.de/amm
92 amm-info@iis.fraunhofer.de
93 ----------------------------------------------------------------------------- */
94
95 /**************************** AAC decoder library ******************************
96
97 Author(s): Matthias Hildenbrand
98
99 Description: USAC ACELP frame decoder
100
101 *******************************************************************************/
102
103 #include "usacdec_acelp.h"
104
105 #include "usacdec_ace_d4t64.h"
106 #include "usacdec_ace_ltp.h"
107 #include "usacdec_rom.h"
108 #include "usacdec_lpc.h"
109 #include "genericStds.h"
110
111 #define PIT_FR2_12k8 128 /* Minimum pitch lag with resolution 1/2 */
112 #define PIT_FR1_12k8 160 /* Minimum pitch lag with resolution 1 */
113 #define TILT_CODE2 \
114 FL2FXCONST_SGL(0.3f * 2.0f) /* ACELP code pre-emphasis factor ( *2 ) */
115 #define PIT_SHARP \
116 FL2FXCONST_SGL(0.85f) /* pitch sharpening factor */
117 #define PREEMPH_FAC \
118 FL2FXCONST_SGL(0.68f) /* ACELP synth pre-emphasis factor */
119
120 #define ACELP_HEADROOM 1
121 #define ACELP_OUTSCALE (MDCT_OUT_HEADROOM - ACELP_HEADROOM)
122
123 /**
124 * \brief Calculate pre-emphasis (1 - mu z^-1) on input signal.
125 * \param[in] in pointer to input signal; in[-1] is also needed.
126 * \param[out] out pointer to output signal.
127 * \param[in] L length of filtering.
128 */
129 /* static */
E_UTIL_preemph(const FIXP_DBL * in,FIXP_DBL * out,INT L)130 void E_UTIL_preemph(const FIXP_DBL *in, FIXP_DBL *out, INT L) {
131 int i;
132
133 for (i = 0; i < L; i++) {
134 out[i] = in[i] - fMult(PREEMPH_FAC, in[i - 1]);
135 }
136
137 return;
138 }
139
140 /**
141 * \brief Calculate de-emphasis 1/(1 - TILT_CODE z^-1) on innovative codebook
142 * vector.
143 * \param[in,out] x innovative codebook vector.
144 */
Preemph_code(FIXP_COD x[])145 static void Preemph_code(
146 FIXP_COD x[] /* (i/o) : input signal overwritten by the output */
147 ) {
148 int i;
149 FIXP_DBL L_tmp;
150
151 /* ARM926: 12 cycles per sample */
152 for (i = L_SUBFR - 1; i > 0; i--) {
153 L_tmp = FX_COD2FX_DBL(x[i]);
154 L_tmp -= fMultDiv2(x[i - 1], TILT_CODE2);
155 x[i] = FX_DBL2FX_COD(L_tmp);
156 }
157 }
158
159 /**
160 * \brief Apply pitch sharpener to the innovative codebook vector.
161 * \param[in,out] x innovative codebook vector.
162 * \param[in] pit_lag decoded pitch lag.
163 */
Pit_shrp(FIXP_COD x[],int pit_lag)164 static void Pit_shrp(
165 FIXP_COD x[], /* in/out: impulse response (or algebraic code) */
166 int pit_lag /* input : pitch lag */
167 ) {
168 int i;
169 FIXP_DBL L_tmp;
170
171 for (i = pit_lag; i < L_SUBFR; i++) {
172 L_tmp = FX_COD2FX_DBL(x[i]);
173 L_tmp += fMult(x[i - pit_lag], PIT_SHARP);
174 x[i] = FX_DBL2FX_COD(L_tmp);
175 }
176
177 return;
178 }
179
180 /**
181 * \brief Calculate Quantized codebook gain, Quantized pitch gain and unbiased
182 * Innovative code vector energy.
183 * \param[in] index index of quantizer.
184 * \param[in] code innovative code vector with exponent = SF_CODE.
185 * \param[out] gain_pit Quantized pitch gain g_p with exponent = SF_GAIN_P.
186 * \param[out] gain_code Quantized codebook gain g_c.
187 * \param[in] mean_ener mean_ener defined in open-loop (2 bits), exponent = 7.
188 * \param[out] E_code unbiased innovative code vector energy.
189 * \param[out] E_code_e exponent of unbiased innovative code vector energy.
190 */
191
192 #define SF_MEAN_ENER_LG10 9
193
194 /* pow(10.0, {18, 30, 42, 54}/20.0) /(float)(1<<SF_MEAN_ENER_LG10) */
195 static const FIXP_DBL pow_10_mean_energy[4] = {0x01fc5ebd, 0x07e7db92,
196 0x1f791f65, 0x7d4bfba3};
197
D_gain2_plus(int index,FIXP_COD code[],FIXP_SGL * gain_pit,FIXP_DBL * gain_code,int mean_ener_bits,int bfi,FIXP_SGL * past_gpit,FIXP_DBL * past_gcode,FIXP_DBL * pEner_code,int * pEner_code_e)198 static void D_gain2_plus(int index, FIXP_COD code[], FIXP_SGL *gain_pit,
199 FIXP_DBL *gain_code, int mean_ener_bits, int bfi,
200 FIXP_SGL *past_gpit, FIXP_DBL *past_gcode,
201 FIXP_DBL *pEner_code, int *pEner_code_e) {
202 FIXP_DBL Ltmp;
203 FIXP_DBL gcode0, gcode_inov;
204 INT gcode0_e, gcode_inov_e;
205 int i;
206
207 FIXP_DBL ener_code;
208 INT ener_code_e;
209
210 /* ener_code = sum(code[]^2) */
211 ener_code = FIXP_DBL(0);
212 for (i = 0; i < L_SUBFR; i++) {
213 ener_code += fPow2Div2(code[i]);
214 }
215
216 ener_code_e = fMax(fNorm(ener_code) - 1, 0);
217 ener_code <<= ener_code_e;
218 ener_code_e = 2 * SF_CODE + 1 - ener_code_e;
219
220 /* export energy of code for calc_period_factor() */
221 *pEner_code = ener_code;
222 *pEner_code_e = ener_code_e;
223
224 ener_code += scaleValue(FL2FXCONST_DBL(0.01f), -ener_code_e);
225
226 /* ener_code *= 1/L_SUBFR, and make exponent even (because of square root
227 * below). */
228 if (ener_code_e & 1) {
229 ener_code_e -= 5;
230 ener_code >>= 1;
231 } else {
232 ener_code_e -= 6;
233 }
234 gcode_inov = invSqrtNorm2(ener_code, &gcode0_e);
235 gcode_inov_e = gcode0_e - (ener_code_e >> 1);
236
237 if (bfi) {
238 FIXP_DBL tgcode;
239 FIXP_SGL tgpit;
240
241 tgpit = *past_gpit;
242
243 if (tgpit > FL2FXCONST_SGL(0.95f / (1 << SF_GAIN_P))) {
244 tgpit = FL2FXCONST_SGL(0.95f / (1 << SF_GAIN_P));
245 } else if (tgpit < FL2FXCONST_SGL(0.5f / (1 << SF_GAIN_P))) {
246 tgpit = FL2FXCONST_SGL(0.5f / (1 << SF_GAIN_P));
247 }
248 *gain_pit = tgpit;
249 tgpit = FX_DBL2FX_SGL(fMult(tgpit, FL2FXCONST_DBL(0.95f)));
250 *past_gpit = tgpit;
251
252 tgpit = FL2FXCONST_SGL(1.4f / (1 << SF_GAIN_P)) - tgpit;
253 tgcode = fMult(*past_gcode, tgpit) << SF_GAIN_P;
254 *gain_code = scaleValue(fMult(tgcode, gcode_inov), gcode_inov_e);
255 *past_gcode = tgcode;
256
257 return;
258 }
259
260 /*-------------- Decode gains ---------------*/
261 /*
262 gcode0 = pow(10.0, (float)mean_ener/20.0);
263 gcode0 = gcode0 / sqrt(ener_code/L_SUBFR);
264 */
265 gcode0 = pow_10_mean_energy[mean_ener_bits];
266 gcode0 = fMultDiv2(gcode0, gcode_inov);
267 gcode0_e = gcode0_e + SF_MEAN_ENER_LG10 - (ener_code_e >> 1) + 1;
268
269 i = index << 1;
270 *gain_pit = t_qua_gain7b[i]; /* adaptive codebook gain */
271 /* t_qua_gain[ind2p1] : fixed codebook gain correction factor */
272 Ltmp = fMult(t_qua_gain7b[i + 1], gcode0);
273 *gain_code = scaleValue(Ltmp, gcode0_e - SF_GAIN_C + SF_QUA_GAIN7B);
274
275 /* update bad frame handler */
276 *past_gpit = *gain_pit;
277
278 /*--------------------------------------------------------
279 past_gcode = gain_code/gcode_inov
280 --------------------------------------------------------*/
281 {
282 FIXP_DBL gcode_m;
283 INT gcode_e;
284
285 gcode_m = fDivNormHighPrec(Ltmp, gcode_inov, &gcode_e);
286 gcode_e += (gcode0_e - SF_GAIN_C + SF_QUA_GAIN7B) - (gcode_inov_e);
287 *past_gcode = scaleValue(gcode_m, gcode_e);
288 }
289 }
290
291 /**
292 * \brief Calculate period/voicing factor r_v
293 * \param[in] exc pitch excitation.
294 * \param[in] gain_pit gain of pitch g_p.
295 * \param[in] gain_code gain of code g_c.
296 * \param[in] gain_code_e exponent of gain of code.
297 * \param[in] ener_code unbiased innovative code vector energy.
298 * \param[in] ener_code_e exponent of unbiased innovative code vector energy.
299 * \return period/voice factor r_v (-1=unvoiced to 1=voiced), exponent SF_PFAC.
300 */
calc_period_factor(FIXP_DBL exc[],FIXP_SGL gain_pit,FIXP_DBL gain_code,FIXP_DBL ener_code,int ener_code_e)301 static FIXP_DBL calc_period_factor(FIXP_DBL exc[], FIXP_SGL gain_pit,
302 FIXP_DBL gain_code, FIXP_DBL ener_code,
303 int ener_code_e) {
304 int ener_exc_e, L_tmp_e, s = 0;
305 FIXP_DBL ener_exc, L_tmp;
306 FIXP_DBL period_fac;
307
308 /* energy of pitch excitation */
309 ener_exc = (FIXP_DBL)0;
310 for (int i = 0; i < L_SUBFR; i++) {
311 ener_exc += fPow2Div2(exc[i]) >> s;
312 if (ener_exc >= FL2FXCONST_DBL(0.5f)) {
313 ener_exc >>= 1;
314 s++;
315 }
316 }
317
318 ener_exc_e = fNorm(ener_exc);
319 ener_exc = fMult(ener_exc << ener_exc_e, fPow2(gain_pit));
320 if (ener_exc != (FIXP_DBL)0) {
321 ener_exc_e = 2 * SF_EXC + 1 + 2 * SF_GAIN_P - ener_exc_e + s;
322 } else {
323 ener_exc_e = 0;
324 }
325
326 /* energy of innovative code excitation */
327 /* L_tmp = ener_code * gain_code*gain_code; */
328 L_tmp_e = fNorm(gain_code);
329 L_tmp = fPow2(gain_code << L_tmp_e);
330 L_tmp = fMult(ener_code, L_tmp);
331 L_tmp_e = 2 * SF_GAIN_C + ener_code_e - 2 * L_tmp_e;
332
333 /* Find common exponent */
334 {
335 FIXP_DBL num, den;
336 int exp_diff;
337
338 exp_diff = ener_exc_e - L_tmp_e;
339 if (exp_diff >= 0) {
340 ener_exc >>= 1;
341 if (exp_diff <= DFRACT_BITS - 2) {
342 L_tmp >>= exp_diff + 1;
343 } else {
344 L_tmp = (FIXP_DBL)0;
345 }
346 den = ener_exc + L_tmp;
347 if (ener_exc_e < DFRACT_BITS - 1) {
348 den += scaleValue(FL2FXCONST_DBL(0.01f), -ener_exc_e - 1);
349 }
350 } else {
351 if (exp_diff >= -(DFRACT_BITS - 2)) {
352 ener_exc >>= 1 - exp_diff;
353 } else {
354 ener_exc = (FIXP_DBL)0;
355 }
356 L_tmp >>= 1;
357 den = ener_exc + L_tmp;
358 if (L_tmp_e < DFRACT_BITS - 1) {
359 den += scaleValue(FL2FXCONST_DBL(0.01f), -L_tmp_e - 1);
360 }
361 }
362 num = (ener_exc - L_tmp);
363 num >>= SF_PFAC;
364
365 if (den > (FIXP_DBL)0) {
366 if (ener_exc > L_tmp) {
367 period_fac = schur_div(num, den, 16);
368 } else {
369 period_fac = -schur_div(-num, den, 16);
370 }
371 } else {
372 period_fac = (FIXP_DBL)MAXVAL_DBL;
373 }
374 }
375
376 /* exponent = SF_PFAC */
377 return period_fac;
378 }
379
380 /*------------------------------------------------------------*
381 * noise enhancer *
382 * ~~~~~~~~~~~~~~ *
383 * - Enhance excitation on noise. (modify gain of code) *
384 * If signal is noisy and LPC filter is stable, move gain *
385 * of code 1.5 dB toward gain of code threshold. *
386 * This decrease by 3 dB noise energy variation. *
387 *------------------------------------------------------------*/
388 /**
389 * \brief Enhance excitation on noise. (modify gain of code)
390 * \param[in] gain_code Quantized codebook gain g_c, exponent = SF_GAIN_C.
391 * \param[in] period_fac periodicity factor, exponent = SF_PFAC.
392 * \param[in] stab_fac stability factor, exponent = SF_STAB.
393 * \param[in,out] p_gc_threshold modified gain of previous subframe.
394 * \return gain_code smoothed gain of code g_sc, exponent = SF_GAIN_C.
395 */
396 static FIXP_DBL
noise_enhancer(FIXP_DBL gain_code,FIXP_DBL period_fac,FIXP_SGL stab_fac,FIXP_DBL * p_gc_threshold)397 noise_enhancer(/* (o) : smoothed gain g_sc SF_GAIN_C */
398 FIXP_DBL gain_code, /* (i) : Quantized codebook gain SF_GAIN_C */
399 FIXP_DBL period_fac, /* (i) : periodicity factor (-1=unvoiced to
400 1=voiced), SF_PFAC */
401 FIXP_SGL stab_fac, /* (i) : stability factor (0 <= ... < 1.0)
402 SF_STAB */
403 FIXP_DBL
404 *p_gc_threshold) /* (io): gain of code threshold SF_GAIN_C */
405 {
406 FIXP_DBL fac, L_tmp, gc_thres;
407
408 gc_thres = *p_gc_threshold;
409
410 L_tmp = gain_code;
411 if (L_tmp < gc_thres) {
412 L_tmp += fMultDiv2(gain_code,
413 FL2FXCONST_SGL(2.0 * 0.19f)); /* +1.5dB => *(1.0+0.19) */
414 if (L_tmp > gc_thres) {
415 L_tmp = gc_thres;
416 }
417 } else {
418 L_tmp = fMult(gain_code,
419 FL2FXCONST_SGL(1.0f / 1.19f)); /* -1.5dB => *10^(-1.5/20) */
420 if (L_tmp < gc_thres) {
421 L_tmp = gc_thres;
422 }
423 }
424 *p_gc_threshold = L_tmp;
425
426 /* voicing factor lambda = 0.5*(1-period_fac) */
427 /* gain smoothing factor S_m = lambda*stab_fac (=fac)
428 = 0.5(stab_fac - stab_fac * period_fac) */
429 fac = (FX_SGL2FX_DBL(stab_fac) >> (SF_PFAC + 1)) -
430 fMultDiv2(stab_fac, period_fac);
431 /* fac_e = SF_PFAC + SF_STAB */
432 FDK_ASSERT(fac >= (FIXP_DBL)0);
433
434 /* gain_code = (float)((fac*tmp) + ((1.0-fac)*gain_code)); */
435 gain_code = fMult(fac, L_tmp) -
436 fMult(FL2FXCONST_DBL(-1.0f / (1 << (SF_PFAC + SF_STAB))) + fac,
437 gain_code);
438 gain_code <<= (SF_PFAC + SF_STAB);
439
440 return gain_code;
441 }
442
443 /**
444 * \brief Update adaptive codebook u'(n) (exc)
445 * Enhance pitch of c(n) and build post-processed excitation u(n) (exc2)
446 * \param[in] code innovative codevector c(n), exponent = SF_CODE.
447 * \param[in,out] exc filtered adaptive codebook v(n), exponent = SF_EXC.
448 * \param[in] gain_pit adaptive codebook gain, exponent = SF_GAIN_P.
449 * \param[in] gain_code innovative codebook gain g_c, exponent = SF_GAIN_C.
450 * \param[in] gain_code_smoothed smoothed innov. codebook gain g_sc, exponent =
451 * SF_GAIN_C.
452 * \param[in] period_fac periodicity factor r_v, exponent = SF_PFAC.
453 * \param[out] exc2 post-processed excitation u(n), exponent = SF_EXC.
454 */
BuildAdaptiveExcitation(FIXP_COD code[],FIXP_DBL exc[],FIXP_SGL gain_pit,FIXP_DBL gain_code,FIXP_DBL gain_code_smoothed,FIXP_DBL period_fac,FIXP_DBL exc2[])455 void BuildAdaptiveExcitation(
456 FIXP_COD code[], /* (i) : algebraic codevector c(n) Q9 */
457 FIXP_DBL exc[], /* (io): filtered adaptive codebook v(n) Q15 */
458 FIXP_SGL gain_pit, /* (i) : adaptive codebook gain g_p Q14 */
459 FIXP_DBL gain_code, /* (i) : innovative codebook gain g_c Q16 */
460 FIXP_DBL gain_code_smoothed, /* (i) : smoothed innov. codebook gain g_sc
461 Q16 */
462 FIXP_DBL period_fac, /* (i) : periodicity factor r_v Q15 */
463 FIXP_DBL exc2[] /* (o) : post-processed excitation u(n) Q15 */
464 ) {
465 /* Note: code[L_SUBFR] and exc2[L_SUBFR] share the same memory!
466 If exc2[i] is written, code[i] will be destroyed!
467 */
468 #define SF (SF_CODE + SF_GAIN_C + 1 - SF_EXC)
469
470 int i;
471 FIXP_DBL tmp, cpe, code_smooth_prev, code_smooth;
472
473 FIXP_COD code_i;
474 FIXP_DBL cpe_code_smooth, cpe_code_smooth_prev;
475
476 /* cpe = (1+r_v)/8 * 2 ; ( SF = -1) */
477 cpe = (period_fac >> (2 - SF_PFAC)) + FL2FXCONST_DBL(0.25f);
478
479 /* u'(n) */
480 tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1); /* v(0)*g_p */
481 *exc++ = tmp + (fMultDiv2(code[0], gain_code) << SF);
482
483 /* u(n) */
484 code_smooth_prev = fMultDiv2(*code++, gain_code_smoothed)
485 << SF; /* c(0) * g_sc */
486 code_i = *code++;
487 code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF; /* c(1) * g_sc */
488 tmp += code_smooth_prev; /* tmp = v(0)*g_p + c(0)*g_sc */
489 cpe_code_smooth = fMultDiv2(cpe, code_smooth);
490 *exc2++ = tmp - cpe_code_smooth;
491 cpe_code_smooth_prev = fMultDiv2(cpe, code_smooth_prev);
492
493 i = L_SUBFR - 2;
494 do /* ARM926: 22 cycles per iteration */
495 {
496 /* u'(n) */
497 tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1);
498 *exc++ = tmp + (fMultDiv2(code_i, gain_code) << SF);
499 /* u(n) */
500 tmp += code_smooth; /* += g_sc * c(i) */
501 tmp -= cpe_code_smooth_prev;
502 cpe_code_smooth_prev = cpe_code_smooth;
503 code_i = *code++;
504 code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF;
505 cpe_code_smooth = fMultDiv2(cpe, code_smooth);
506 *exc2++ = tmp - cpe_code_smooth; /* tmp - c_pe * g_sc * c(i+1) */
507 } while (--i != 0);
508
509 /* u'(n) */
510 tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P + 1);
511 *exc = tmp + (fMultDiv2(code_i, gain_code) << SF);
512 /* u(n) */
513 tmp += code_smooth;
514 tmp -= cpe_code_smooth_prev;
515 *exc2++ = tmp;
516
517 return;
518 }
519
520 /**
521 * \brief Interpolate LPC vector in LSP domain for current subframe and convert
522 * to LP domain
523 * \param[in] lsp_old LPC vector (LSP domain) corresponding to the beginning of
524 * current ACELP frame.
525 * \param[in] lsp_new LPC vector (LSP domain) corresponding to the end of
526 * current ACELP frame.
527 * \param[in] subfr_nr number of current ACELP subframe 0..3.
528 * \param[in] nb_subfr total number of ACELP subframes in this frame.
529 * \param[out] A LP filter coefficients for current ACELP subframe, exponent =
530 * SF_A_COEFFS.
531 */
532 /* static */
int_lpc_acelp(const FIXP_LPC lsp_old[],const FIXP_LPC lsp_new[],int subfr_nr,int nb_subfr,FIXP_LPC A[],INT * A_exp)533 void int_lpc_acelp(
534 const FIXP_LPC lsp_old[], /* input : LSPs from past frame */
535 const FIXP_LPC lsp_new[], /* input : LSPs from present frame */
536 int subfr_nr, int nb_subfr,
537 FIXP_LPC
538 A[], /* output: interpolated LP coefficients for current subframe */
539 INT *A_exp) {
540 int i;
541 FIXP_LPC lsp_interpol[M_LP_FILTER_ORDER];
542 FIXP_SGL fac_old, fac_new;
543
544 FDK_ASSERT((nb_subfr == 3) || (nb_subfr == 4));
545
546 fac_old = lsp_interpol_factor[nb_subfr & 0x1][(nb_subfr - 1) - subfr_nr];
547 fac_new = lsp_interpol_factor[nb_subfr & 0x1][subfr_nr];
548 for (i = 0; i < M_LP_FILTER_ORDER; i++) {
549 lsp_interpol[i] = FX_DBL2FX_LPC(
550 (fMultDiv2(lsp_old[i], fac_old) + fMultDiv2(lsp_new[i], fac_new)) << 1);
551 }
552
553 E_LPC_f_lsp_a_conversion(lsp_interpol, A, A_exp);
554
555 return;
556 }
557
558 /**
559 * \brief Perform LP synthesis by filtering the post-processed excitation u(n)
560 * through the LP synthesis filter 1/A(z)
561 * \param[in] a LP filter coefficients, exponent = SF_A_COEFFS.
562 * \param[in] length length of input/output signal.
563 * \param[in] x post-processed excitation u(n).
564 * \param[in,out] y LP synthesis signal and filter memory
565 * y[-M_LP_FILTER_ORDER..-1].
566 */
567
568 /* static */
Syn_filt(const FIXP_LPC a[],const INT a_exp,INT length,FIXP_DBL x[],FIXP_DBL y[])569 void Syn_filt(const FIXP_LPC a[], /* (i) : a[m] prediction coefficients Q12 */
570 const INT a_exp,
571 INT length, /* (i) : length of input/output signal (64|128) */
572 FIXP_DBL x[], /* (i) : input signal Qx */
573 FIXP_DBL y[] /* (i/o) : filter states / output signal Qx-s*/
574 ) {
575 int i, j;
576 FIXP_DBL L_tmp;
577
578 for (i = 0; i < length; i++) {
579 L_tmp = (FIXP_DBL)0;
580
581 for (j = 0; j < M_LP_FILTER_ORDER; j++) {
582 L_tmp -= fMultDiv2(a[j], y[i - (j + 1)]) >> (LP_FILTER_SCALE - 1);
583 }
584
585 L_tmp = scaleValue(L_tmp, a_exp + LP_FILTER_SCALE);
586 y[i] = fAddSaturate(L_tmp, x[i]);
587 }
588
589 return;
590 }
591
592 /**
593 * \brief Calculate de-emphasis 1/(1 - mu z^-1) on input signal.
594 * \param[in] x input signal.
595 * \param[out] y output signal.
596 * \param[in] L length of signal.
597 * \param[in,out] mem memory (signal[-1]).
598 */
599 /* static */
Deemph(FIXP_DBL * x,FIXP_DBL * y,int L,FIXP_DBL * mem)600 void Deemph(FIXP_DBL *x, FIXP_DBL *y, int L, FIXP_DBL *mem) {
601 int i;
602 FIXP_DBL yi = *mem;
603
604 for (i = 0; i < L; i++) {
605 FIXP_DBL xi = x[i] >> 1;
606 xi = fMultAddDiv2(xi, PREEMPH_FAC, yi);
607 yi = SATURATE_LEFT_SHIFT(xi, 1, 32);
608 y[i] = yi;
609 }
610 *mem = yi;
611 return;
612 }
613
614 /**
615 * \brief Compute the LP residual by filtering the input speech through the
616 * analysis filter A(z).
617 * \param[in] a LP filter coefficients, exponent = SF_A_COEFFS
618 * \param[in] x input signal (note that values x[-m..-1] are needed), exponent =
619 * SF_SYNTH
620 * \param[out] y output signal (residual), exponent = SF_EXC
621 * \param[in] l length of filtering
622 */
623 /* static */
E_UTIL_residu(const FIXP_LPC * a,const INT a_exp,FIXP_DBL * x,FIXP_DBL * y,INT l)624 void E_UTIL_residu(const FIXP_LPC *a, const INT a_exp, FIXP_DBL *x, FIXP_DBL *y,
625 INT l) {
626 FIXP_DBL s;
627 INT i, j;
628
629 /* (note that values x[-m..-1] are needed) */
630 for (i = 0; i < l; i++) {
631 s = (FIXP_DBL)0;
632
633 for (j = 0; j < M_LP_FILTER_ORDER; j++) {
634 s += fMultDiv2(a[j], x[i - j - 1]) >> (LP_FILTER_SCALE - 1);
635 }
636
637 s = scaleValue(s, a_exp + LP_FILTER_SCALE);
638 y[i] = fAddSaturate(s, x[i]);
639 }
640
641 return;
642 }
643
644 /* use to map subfr number to number of bits used for acb_index */
645 static const UCHAR num_acb_idx_bits_table[2][NB_SUBFR] = {
646 {9, 6, 9, 6}, /* coreCoderFrameLength == 1024 */
647 {9, 6, 6, 0} /* coreCoderFrameLength == 768 */
648 };
649
DecodePitchLag(HANDLE_FDK_BITSTREAM hBs,const UCHAR num_acb_idx_bits,const int PIT_MIN,const int PIT_FR2,const int PIT_FR1,const int PIT_MAX,int * pT0,int * pT0_frac,int * pT0_min,int * pT0_max)650 static int DecodePitchLag(HANDLE_FDK_BITSTREAM hBs,
651 const UCHAR num_acb_idx_bits,
652 const int PIT_MIN, /* TMIN */
653 const int PIT_FR2, /* TFR2 */
654 const int PIT_FR1, /* TFR1 */
655 const int PIT_MAX, /* TMAX */
656 int *pT0, int *pT0_frac, int *pT0_min, int *pT0_max) {
657 int acb_idx;
658 int error = 0;
659 int T0, T0_frac;
660
661 FDK_ASSERT((num_acb_idx_bits == 9) || (num_acb_idx_bits == 6));
662
663 acb_idx = FDKreadBits(hBs, num_acb_idx_bits);
664
665 if (num_acb_idx_bits == 6) {
666 /* When the pitch value is encoded on 6 bits, a pitch resolution of 1/4 is
667 always used in the range [T1-8, T1+7.75], where T1 is nearest integer to
668 the fractional pitch lag of the previous subframe.
669 */
670 T0 = *pT0_min + acb_idx / 4;
671 T0_frac = acb_idx & 0x3;
672 } else { /* num_acb_idx_bits == 9 */
673 /* When the pitch value is encoded on 9 bits, a fractional pitch delay is
674 used with resolutions 0.25 in the range [TMIN, TFR2-0.25], resolutions
675 0.5 in the range [TFR2, TFR1-0.5], and integers only in the range [TFR1,
676 TMAX]. NOTE: for small sampling rates TMAX can get smaller than TFR1.
677 */
678 int T0_min, T0_max;
679
680 if (acb_idx < (PIT_FR2 - PIT_MIN) * 4) {
681 /* first interval with 0.25 pitch resolution */
682 T0 = PIT_MIN + (acb_idx / 4);
683 T0_frac = acb_idx & 0x3;
684 } else if (acb_idx < ((PIT_FR2 - PIT_MIN) * 4 + (PIT_FR1 - PIT_FR2) * 2)) {
685 /* second interval with 0.5 pitch resolution */
686 acb_idx -= (PIT_FR2 - PIT_MIN) * 4;
687 T0 = PIT_FR2 + (acb_idx / 2);
688 T0_frac = (acb_idx & 0x1) * 2;
689 } else {
690 /* third interval with 1.0 pitch resolution */
691 T0 = acb_idx + PIT_FR1 - ((PIT_FR2 - PIT_MIN) * 4) -
692 ((PIT_FR1 - PIT_FR2) * 2);
693 T0_frac = 0;
694 }
695 /* find T0_min and T0_max for subframe 1 or 3 */
696 T0_min = T0 - 8;
697 if (T0_min < PIT_MIN) {
698 T0_min = PIT_MIN;
699 }
700 T0_max = T0_min + 15;
701 if (T0_max > PIT_MAX) {
702 T0_max = PIT_MAX;
703 T0_min = T0_max - 15;
704 }
705 *pT0_min = T0_min;
706 *pT0_max = T0_max;
707 }
708 *pT0 = T0;
709 *pT0_frac = T0_frac;
710
711 return error;
712 }
ConcealPitchLag(CAcelpStaticMem * acelp_mem,const int PIT_MAX,int * pT0,int * pT0_frac)713 static void ConcealPitchLag(CAcelpStaticMem *acelp_mem, const int PIT_MAX,
714 int *pT0, int *pT0_frac) {
715 USHORT *pold_T0 = &acelp_mem->old_T0;
716 UCHAR *pold_T0_frac = &acelp_mem->old_T0_frac;
717
718 if ((int)*pold_T0 >= PIT_MAX) {
719 *pold_T0 = (UCHAR)(PIT_MAX - 5);
720 }
721 *pT0 = (int)*pold_T0;
722 *pT0_frac = (int)*pold_T0_frac;
723 }
724
725 static UCHAR tab_coremode2nbits[8] = {20, 28, 36, 44, 52, 64, 12, 16};
726
MapCoreMode2NBits(int core_mode)727 static int MapCoreMode2NBits(int core_mode) {
728 return (int)tab_coremode2nbits[core_mode];
729 }
730
CLpd_AcelpDecode(CAcelpStaticMem * acelp_mem,INT i_offset,const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],FIXP_SGL stab_fac,CAcelpChannelData * pAcelpData,INT numLostSubframes,int lastLpcLost,int frameCnt,FIXP_DBL synth[],int pT[],FIXP_DBL * pit_gain,INT coreCoderFrameLength)731 void CLpd_AcelpDecode(CAcelpStaticMem *acelp_mem, INT i_offset,
732 const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],
733 const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],
734 FIXP_SGL stab_fac, CAcelpChannelData *pAcelpData,
735 INT numLostSubframes, int lastLpcLost, int frameCnt,
736 FIXP_DBL synth[], int pT[], FIXP_DBL *pit_gain,
737 INT coreCoderFrameLength) {
738 int i_subfr, subfr_nr, l_div, T;
739 int T0 = -1, T0_frac = -1; /* mark invalid */
740
741 int pit_gain_index = 0;
742
743 const int PIT_MAX = PIT_MAX_12k8 + (6 * i_offset); /* maximum pitch lag */
744
745 FIXP_COD *code;
746 FIXP_DBL *exc2;
747 FIXP_DBL *syn;
748 FIXP_DBL *exc;
749 FIXP_LPC A[M_LP_FILTER_ORDER];
750 INT A_exp;
751
752 FIXP_DBL period_fac;
753 FIXP_SGL gain_pit;
754 FIXP_DBL gain_code, gain_code_smooth, Ener_code;
755 int Ener_code_e;
756 int n;
757 int bfi = (numLostSubframes > 0) ? 1 : 0;
758
759 C_ALLOC_SCRATCH_START(
760 exc_buf, FIXP_DBL,
761 PIT_MAX_MAX + L_INTERPOL + L_DIV + 1); /* 411 + 17 + 256 + 1 = 685 */
762 C_ALLOC_SCRATCH_START(syn_buf, FIXP_DBL,
763 M_LP_FILTER_ORDER + L_DIV); /* 16 + 256 = 272 */
764 /* use same memory for code[L_SUBFR] and exc2[L_SUBFR] */
765 C_ALLOC_SCRATCH_START(tmp_buf, FIXP_DBL, L_SUBFR); /* 64 */
766 /* make sure they don't overlap if they are accessed alternatingly in
767 * BuildAdaptiveExcitation() */
768 #if (COD_BITS == FRACT_BITS)
769 code = (FIXP_COD *)(tmp_buf + L_SUBFR / 2);
770 #elif (COD_BITS == DFRACT_BITS)
771 code = (FIXP_COD *)tmp_buf;
772 #endif
773 exc2 = (FIXP_DBL *)tmp_buf;
774
775 syn = syn_buf + M_LP_FILTER_ORDER;
776 exc = exc_buf + PIT_MAX_MAX + L_INTERPOL;
777
778 FDKmemcpy(syn_buf, acelp_mem->old_syn_mem,
779 M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
780 FDKmemcpy(exc_buf, acelp_mem->old_exc_mem,
781 (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));
782
783 FDKmemclear(exc_buf + (PIT_MAX_MAX + L_INTERPOL),
784 (L_DIV + 1) * sizeof(FIXP_DBL));
785
786 l_div = coreCoderFrameLength / NB_DIV;
787
788 for (i_subfr = 0, subfr_nr = 0; i_subfr < l_div;
789 i_subfr += L_SUBFR, subfr_nr++) {
790 /*-------------------------------------------------*
791 * - Decode pitch lag (T0 and T0_frac) *
792 *-------------------------------------------------*/
793 if (bfi) {
794 ConcealPitchLag(acelp_mem, PIT_MAX, &T0, &T0_frac);
795 } else {
796 T0 = (int)pAcelpData->T0[subfr_nr];
797 T0_frac = (int)pAcelpData->T0_frac[subfr_nr];
798 }
799
800 /*-------------------------------------------------*
801 * - Find the pitch gain, the interpolation filter *
802 * and the adaptive codebook vector. *
803 *-------------------------------------------------*/
804 Pred_lt4(&exc[i_subfr], T0, T0_frac);
805
806 if ((!bfi && pAcelpData->ltp_filtering_flag[subfr_nr] == 0) ||
807 (bfi && numLostSubframes == 1 && stab_fac < FL2FXCONST_SGL(0.25f))) {
808 /* find pitch excitation with lp filter: v'(n) => v(n) */
809 Pred_lt4_postfilter(&exc[i_subfr]);
810 }
811
812 /*-------------------------------------------------------*
813 * - Decode innovative codebook. *
814 * - Add the fixed-gain pitch contribution to code[]. *
815 *-------------------------------------------------------*/
816 if (bfi) {
817 for (n = 0; n < L_SUBFR; n++) {
818 code[n] =
819 FX_SGL2FX_COD((FIXP_SGL)E_UTIL_random(&acelp_mem->seed_ace)) >> 4;
820 }
821 } else {
822 int nbits = MapCoreMode2NBits((int)pAcelpData->acelp_core_mode);
823 D_ACELP_decode_4t64(pAcelpData->icb_index[subfr_nr], nbits, &code[0]);
824 }
825
826 T = T0;
827 if (T0_frac > 2) {
828 T += 1;
829 }
830
831 Preemph_code(code);
832 Pit_shrp(code, T);
833
834 /* Output pitch lag for bass post-filter */
835 if (T > PIT_MAX) {
836 pT[subfr_nr] = PIT_MAX;
837 } else {
838 pT[subfr_nr] = T;
839 }
840 D_gain2_plus(
841 pAcelpData->gains[subfr_nr],
842 code, /* (i) : Innovative code vector, exponent = SF_CODE */
843 &gain_pit, /* (o) : Quantized pitch gain, exponent = SF_GAIN_P */
844 &gain_code, /* (o) : Quantized codebook gain */
845 pAcelpData
846 ->mean_energy, /* (i) : mean_ener defined in open-loop (2 bits) */
847 bfi, &acelp_mem->past_gpit, &acelp_mem->past_gcode,
848 &Ener_code, /* (o) : Innovative code vector energy */
849 &Ener_code_e); /* (o) : Innovative code vector energy exponent */
850
851 pit_gain[pit_gain_index++] = FX_SGL2FX_DBL(gain_pit);
852
853 /* calc periodicity factor r_v */
854 period_fac =
855 calc_period_factor(/* (o) : factor (-1=unvoiced to 1=voiced) */
856 &exc[i_subfr], /* (i) : pitch excitation, exponent =
857 SF_EXC */
858 gain_pit, /* (i) : gain of pitch, exponent =
859 SF_GAIN_P */
860 gain_code, /* (i) : gain of code */
861 Ener_code, /* (i) : Energy of code[] */
862 Ener_code_e); /* (i) : Exponent of energy of code[]
863 */
864
865 if (lastLpcLost && frameCnt == 0) {
866 if (gain_pit > FL2FXCONST_SGL(1.0f / (1 << SF_GAIN_P))) {
867 gain_pit = FL2FXCONST_SGL(1.0f / (1 << SF_GAIN_P));
868 }
869 }
870
871 gain_code_smooth =
872 noise_enhancer(/* (o) : smoothed gain g_sc exponent = SF_GAIN_C */
873 gain_code, /* (i) : Quantized codebook gain */
874 period_fac, /* (i) : periodicity factor (-1=unvoiced to
875 1=voiced) */
876 stab_fac, /* (i) : stability factor (0 <= ... < 1),
877 exponent = 1 */
878 &acelp_mem->gc_threshold);
879
880 /* Compute adaptive codebook update u'(n), pitch enhancement c'(n) and
881 * post-processed excitation u(n). */
882 BuildAdaptiveExcitation(code, exc + i_subfr, gain_pit, gain_code,
883 gain_code_smooth, period_fac, exc2);
884
885 /* Interpolate filter coeffs for current subframe in lsp domain and convert
886 * to LP domain */
887 int_lpc_acelp(lsp_old, /* input : LSPs from past frame */
888 lsp_new, /* input : LSPs from present frame */
889 subfr_nr, /* input : ACELP subframe index */
890 coreCoderFrameLength / L_DIV,
891 A, /* output: LP coefficients of this subframe */
892 &A_exp);
893
894 Syn_filt(A, /* (i) : a[m] prediction coefficients */
895 A_exp, L_SUBFR, /* (i) : length */
896 exc2, /* (i) : input signal */
897 &syn[i_subfr] /* (i/o) : filter states / output signal */
898 );
899
900 } /* end of subframe loop */
901
902 /* update pitch value for bfi procedure */
903 acelp_mem->old_T0_frac = T0_frac;
904 acelp_mem->old_T0 = T0;
905
906 /* save old excitation and old synthesis memory for next ACELP frame */
907 FDKmemcpy(acelp_mem->old_exc_mem, exc + l_div - (PIT_MAX_MAX + L_INTERPOL),
908 sizeof(FIXP_DBL) * (PIT_MAX_MAX + L_INTERPOL));
909 FDKmemcpy(acelp_mem->old_syn_mem, syn_buf + l_div,
910 sizeof(FIXP_DBL) * M_LP_FILTER_ORDER);
911
912 Deemph(syn, synth, l_div,
913 &acelp_mem->de_emph_mem); /* ref soft: mem = synth[-1] */
914
915 scaleValues(synth, l_div, -ACELP_OUTSCALE);
916 acelp_mem->deemph_mem_wsyn = acelp_mem->de_emph_mem;
917
918 C_ALLOC_SCRATCH_END(tmp_buf, FIXP_DBL, L_SUBFR);
919 C_ALLOC_SCRATCH_END(syn_buf, FIXP_DBL, M_LP_FILTER_ORDER + L_DIV);
920 C_ALLOC_SCRATCH_END(exc_buf, FIXP_DBL, PIT_MAX_MAX + L_INTERPOL + L_DIV + 1);
921 return;
922 }
923
CLpd_AcelpReset(CAcelpStaticMem * acelp)924 void CLpd_AcelpReset(CAcelpStaticMem *acelp) {
925 acelp->gc_threshold = (FIXP_DBL)0;
926
927 acelp->past_gpit = (FIXP_SGL)0;
928 acelp->past_gcode = (FIXP_DBL)0;
929 acelp->old_T0 = 64;
930 acelp->old_T0_frac = 0;
931 acelp->deemph_mem_wsyn = (FIXP_DBL)0;
932 acelp->wsyn_rms = (FIXP_DBL)0;
933 acelp->seed_ace = 0;
934 }
935
936 /* TCX time domain concealment */
937 /* Compare to figure 13a on page 54 in 3GPP TS 26.290 */
CLpd_TcxTDConceal(CAcelpStaticMem * acelp_mem,SHORT * pitch,const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],const FIXP_SGL stab_fac,INT nLostSf,FIXP_DBL synth[],INT coreCoderFrameLength,UCHAR last_tcx_noise_factor)938 void CLpd_TcxTDConceal(CAcelpStaticMem *acelp_mem, SHORT *pitch,
939 const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],
940 const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],
941 const FIXP_SGL stab_fac, INT nLostSf, FIXP_DBL synth[],
942 INT coreCoderFrameLength, UCHAR last_tcx_noise_factor) {
943 /* repeat past excitation with pitch from previous decoded TCX frame */
944 C_ALLOC_SCRATCH_START(
945 exc_buf, FIXP_DBL,
946 PIT_MAX_MAX + L_INTERPOL + L_DIV); /* 411 + 17 + 256 + 1 = */
947 C_ALLOC_SCRATCH_START(syn_buf, FIXP_DBL,
948 M_LP_FILTER_ORDER + L_DIV); /* 256 + 16 = */
949 /* += */
950 FIXP_DBL ns_buf[L_DIV + 1];
951 FIXP_DBL *syn = syn_buf + M_LP_FILTER_ORDER;
952 FIXP_DBL *exc = exc_buf + PIT_MAX_MAX + L_INTERPOL;
953 FIXP_DBL *ns = ns_buf + 1;
954 FIXP_DBL tmp, fact_exc;
955 INT T = fMin(*pitch, (SHORT)PIT_MAX_MAX);
956 int i, i_subfr, subfr_nr;
957 int lDiv = coreCoderFrameLength / NB_DIV;
958
959 FDKmemcpy(syn_buf, acelp_mem->old_syn_mem,
960 M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
961 FDKmemcpy(exc_buf, acelp_mem->old_exc_mem,
962 (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));
963
964 /* if we lost all packets (i.e. 1 packet of TCX-20 ms, 2 packets of
965 the TCX-40 ms or 4 packets of the TCX-80ms), we lost the whole
966 coded frame extrapolation strategy: repeat lost excitation and
967 use extrapolated LSFs */
968
969 /* AMR-WB+ like TCX TD concealment */
970
971 /* number of lost frame cmpt */
972 if (nLostSf < 2) {
973 fact_exc = FL2FXCONST_DBL(0.8f);
974 } else {
975 fact_exc = FL2FXCONST_DBL(0.4f);
976 }
977
978 /* repeat past excitation */
979 for (i = 0; i < lDiv; i++) {
980 exc[i] = fMult(fact_exc, exc[i - T]);
981 }
982
983 tmp = fMult(fact_exc, acelp_mem->wsyn_rms);
984 acelp_mem->wsyn_rms = tmp;
985
986 /* init deemph_mem_wsyn */
987 acelp_mem->deemph_mem_wsyn = exc[-1];
988
989 ns[-1] = acelp_mem->deemph_mem_wsyn;
990
991 for (i_subfr = 0, subfr_nr = 0; i_subfr < lDiv;
992 i_subfr += L_SUBFR, subfr_nr++) {
993 FIXP_DBL tRes[L_SUBFR];
994 FIXP_LPC A[M_LP_FILTER_ORDER];
995 INT A_exp;
996
997 /* interpolate LPC coefficients */
998 int_lpc_acelp(lsp_old, lsp_new, subfr_nr, lDiv / L_SUBFR, A, &A_exp);
999
1000 Syn_filt(A, /* (i) : a[m] prediction coefficients */
1001 A_exp, L_SUBFR, /* (i) : length */
1002 &exc[i_subfr], /* (i) : input signal */
1003 &syn[i_subfr] /* (i/o) : filter states / output signal */
1004 );
1005
1006 E_LPC_a_weight(
1007 A, A,
1008 M_LP_FILTER_ORDER); /* overwrite A as it is not needed any longer */
1009
1010 E_UTIL_residu(A, A_exp, &syn[i_subfr], tRes, L_SUBFR);
1011
1012 Deemph(tRes, &ns[i_subfr], L_SUBFR, &acelp_mem->deemph_mem_wsyn);
1013
1014 /* Amplitude limiter (saturate at wsyn_rms) */
1015 for (i = i_subfr; i < i_subfr + L_SUBFR; i++) {
1016 if (ns[i] > tmp) {
1017 ns[i] = tmp;
1018 } else {
1019 if (ns[i] < -tmp) {
1020 ns[i] = -tmp;
1021 }
1022 }
1023 }
1024
1025 E_UTIL_preemph(&ns[i_subfr], tRes, L_SUBFR);
1026
1027 Syn_filt(A, /* (i) : a[m] prediction coefficients */
1028 A_exp, L_SUBFR, /* (i) : length */
1029 tRes, /* (i) : input signal */
1030 &syn[i_subfr] /* (i/o) : filter states / output signal */
1031 );
1032
1033 FDKmemmove(&synth[i_subfr], &syn[i_subfr], L_SUBFR * sizeof(FIXP_DBL));
1034 }
1035
1036 /* save old excitation and old synthesis memory for next ACELP frame */
1037 FDKmemcpy(acelp_mem->old_exc_mem, exc + lDiv - (PIT_MAX_MAX + L_INTERPOL),
1038 sizeof(FIXP_DBL) * (PIT_MAX_MAX + L_INTERPOL));
1039 FDKmemcpy(acelp_mem->old_syn_mem, syn_buf + lDiv,
1040 sizeof(FIXP_DBL) * M_LP_FILTER_ORDER);
1041 acelp_mem->de_emph_mem = acelp_mem->deemph_mem_wsyn;
1042
1043 C_ALLOC_SCRATCH_END(syn_buf, FIXP_DBL, M_LP_FILTER_ORDER + L_DIV);
1044 C_ALLOC_SCRATCH_END(exc_buf, FIXP_DBL, PIT_MAX_MAX + L_INTERPOL + L_DIV);
1045 }
1046
Acelp_PreProcessing(FIXP_DBL * synth_buf,FIXP_DBL * old_synth,INT * pitch,INT * old_T_pf,FIXP_DBL * pit_gain,FIXP_DBL * old_gain_pf,INT samplingRate,INT * i_offset,INT coreCoderFrameLength,INT synSfd,INT nbSubfrSuperfr)1047 void Acelp_PreProcessing(FIXP_DBL *synth_buf, FIXP_DBL *old_synth, INT *pitch,
1048 INT *old_T_pf, FIXP_DBL *pit_gain,
1049 FIXP_DBL *old_gain_pf, INT samplingRate, INT *i_offset,
1050 INT coreCoderFrameLength, INT synSfd,
1051 INT nbSubfrSuperfr) {
1052 int n;
1053
1054 /* init beginning of synth_buf with old synthesis from previous frame */
1055 FDKmemcpy(synth_buf, old_synth, sizeof(FIXP_DBL) * (PIT_MAX_MAX - BPF_DELAY));
1056
1057 /* calculate pitch lag offset for ACELP decoder */
1058 *i_offset =
1059 (samplingRate * PIT_MIN_12k8 + (FSCALE_DENOM / 2)) / FSCALE_DENOM -
1060 PIT_MIN_12k8;
1061
1062 /* for bass postfilter */
1063 for (n = 0; n < synSfd; n++) {
1064 pitch[n] = old_T_pf[n];
1065 pit_gain[n] = old_gain_pf[n];
1066 }
1067 for (n = 0; n < nbSubfrSuperfr; n++) {
1068 pitch[n + synSfd] = L_SUBFR;
1069 pit_gain[n + synSfd] = (FIXP_DBL)0;
1070 }
1071 }
1072
Acelp_PostProcessing(FIXP_DBL * synth_buf,FIXP_DBL * old_synth,INT * pitch,INT * old_T_pf,INT coreCoderFrameLength,INT synSfd,INT nbSubfrSuperfr)1073 void Acelp_PostProcessing(FIXP_DBL *synth_buf, FIXP_DBL *old_synth, INT *pitch,
1074 INT *old_T_pf, INT coreCoderFrameLength, INT synSfd,
1075 INT nbSubfrSuperfr) {
1076 int n;
1077
1078 /* store last part of synth_buf (which is not handled by the IMDCT overlap)
1079 * for next frame */
1080 FDKmemcpy(old_synth, synth_buf + coreCoderFrameLength,
1081 sizeof(FIXP_DBL) * (PIT_MAX_MAX - BPF_DELAY));
1082
1083 /* for bass postfilter */
1084 for (n = 0; n < synSfd; n++) {
1085 old_T_pf[n] = pitch[nbSubfrSuperfr + n];
1086 }
1087 }
1088
1089 #define L_FAC_ZIR (LFAC)
1090
CLpd_Acelp_Zir(const FIXP_LPC A[],const INT A_exp,CAcelpStaticMem * acelp_mem,const INT length,FIXP_DBL zir[],int doDeemph)1091 void CLpd_Acelp_Zir(const FIXP_LPC A[], const INT A_exp,
1092 CAcelpStaticMem *acelp_mem, const INT length,
1093 FIXP_DBL zir[], int doDeemph) {
1094 C_ALLOC_SCRATCH_START(tmp_buf, FIXP_DBL, L_FAC_ZIR + M_LP_FILTER_ORDER);
1095 FDK_ASSERT(length <= L_FAC_ZIR);
1096
1097 FDKmemcpy(tmp_buf, acelp_mem->old_syn_mem,
1098 M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
1099 FDKmemset(tmp_buf + M_LP_FILTER_ORDER, 0, L_FAC_ZIR * sizeof(FIXP_DBL));
1100
1101 Syn_filt(A, A_exp, length, &tmp_buf[M_LP_FILTER_ORDER],
1102 &tmp_buf[M_LP_FILTER_ORDER]);
1103 if (!doDeemph) {
1104 /* if last lpd mode was TD concealment, then bypass deemph */
1105 FDKmemcpy(zir, tmp_buf, length * sizeof(*zir));
1106 } else {
1107 Deemph(&tmp_buf[M_LP_FILTER_ORDER], &zir[0], length,
1108 &acelp_mem->de_emph_mem);
1109 scaleValues(zir, length, -ACELP_OUTSCALE);
1110 }
1111 C_ALLOC_SCRATCH_END(tmp_buf, FIXP_DBL, L_FAC_ZIR + M_LP_FILTER_ORDER);
1112 }
1113
CLpd_AcelpPrepareInternalMem(const FIXP_DBL * synth,UCHAR last_lpd_mode,UCHAR last_last_lpd_mode,const FIXP_LPC * A_new,const INT A_new_exp,const FIXP_LPC * A_old,const INT A_old_exp,CAcelpStaticMem * acelp_mem,INT coreCoderFrameLength,INT clearOldExc,UCHAR lpd_mode)1114 void CLpd_AcelpPrepareInternalMem(const FIXP_DBL *synth, UCHAR last_lpd_mode,
1115 UCHAR last_last_lpd_mode,
1116 const FIXP_LPC *A_new, const INT A_new_exp,
1117 const FIXP_LPC *A_old, const INT A_old_exp,
1118 CAcelpStaticMem *acelp_mem,
1119 INT coreCoderFrameLength, INT clearOldExc,
1120 UCHAR lpd_mode) {
1121 int l_div =
1122 coreCoderFrameLength / NB_DIV; /* length of one ACELP/TCX20 frame */
1123 int l_div_partial;
1124 FIXP_DBL *syn, *old_exc_mem;
1125
1126 C_ALLOC_SCRATCH_START(synth_buf, FIXP_DBL,
1127 PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
1128 syn = &synth_buf[M_LP_FILTER_ORDER];
1129
1130 l_div_partial = PIT_MAX_MAX + L_INTERPOL - l_div;
1131 old_exc_mem = acelp_mem->old_exc_mem;
1132
1133 if (lpd_mode == 4) {
1134 /* Bypass Domain conversion. TCXTD Concealment does no deemphasis in the
1135 * end. */
1136 FDKmemcpy(
1137 synth_buf, &synth[-(PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER)],
1138 (PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER) * sizeof(FIXP_DBL));
1139 /* Set deemphasis memory state for TD concealment */
1140 acelp_mem->deemph_mem_wsyn = scaleValueSaturate(synth[-1], ACELP_OUTSCALE);
1141 } else {
1142 /* convert past [PIT_MAX_MAX+L_INTERPOL+M_LP_FILTER_ORDER] synthesis to
1143 * preemph domain */
1144 E_UTIL_preemph(&synth[-(PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER)],
1145 synth_buf, PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
1146 scaleValuesSaturate(synth_buf, PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER,
1147 ACELP_OUTSCALE);
1148 }
1149
1150 /* Set deemphasis memory state */
1151 acelp_mem->de_emph_mem = scaleValueSaturate(synth[-1], ACELP_OUTSCALE);
1152
1153 /* update acelp synth filter memory */
1154 FDKmemcpy(acelp_mem->old_syn_mem,
1155 &syn[PIT_MAX_MAX + L_INTERPOL - M_LP_FILTER_ORDER],
1156 M_LP_FILTER_ORDER * sizeof(FIXP_DBL));
1157
1158 if (clearOldExc) {
1159 FDKmemclear(old_exc_mem, (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));
1160 C_ALLOC_SCRATCH_END(synth_buf, FIXP_DBL,
1161 PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
1162 return;
1163 }
1164
1165 /* update past [PIT_MAX_MAX+L_INTERPOL] samples of exc memory */
1166 if (last_lpd_mode == 1) { /* last frame was TCX20 */
1167 if (last_last_lpd_mode == 0) { /* ACELP -> TCX20 -> ACELP transition */
1168 /* Delay valid part of excitation buffer (from previous ACELP frame) by
1169 * l_div samples */
1170 FDKmemmove(old_exc_mem, old_exc_mem + l_div,
1171 sizeof(FIXP_DBL) * l_div_partial);
1172 } else if (last_last_lpd_mode > 0) { /* TCX -> TCX20 -> ACELP transition */
1173 E_UTIL_residu(A_old, A_old_exp, syn, old_exc_mem, l_div_partial);
1174 }
1175 E_UTIL_residu(A_new, A_new_exp, syn + l_div_partial,
1176 old_exc_mem + l_div_partial, l_div);
1177 } else { /* prev frame was FD, TCX40 or TCX80 */
1178 int exc_A_new_length = (coreCoderFrameLength / 2 > PIT_MAX_MAX + L_INTERPOL)
1179 ? PIT_MAX_MAX + L_INTERPOL
1180 : coreCoderFrameLength / 2;
1181 int exc_A_old_length = PIT_MAX_MAX + L_INTERPOL - exc_A_new_length;
1182 E_UTIL_residu(A_old, A_old_exp, syn, old_exc_mem, exc_A_old_length);
1183 E_UTIL_residu(A_new, A_new_exp, &syn[exc_A_old_length],
1184 &old_exc_mem[exc_A_old_length], exc_A_new_length);
1185 }
1186 C_ALLOC_SCRATCH_END(synth_buf, FIXP_DBL,
1187 PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);
1188
1189 return;
1190 }
1191
CLpd_ACELP_GetFreeExcMem(CAcelpStaticMem * acelp_mem,INT length)1192 FIXP_DBL *CLpd_ACELP_GetFreeExcMem(CAcelpStaticMem *acelp_mem, INT length) {
1193 FDK_ASSERT(length <= PIT_MAX_MAX + L_INTERPOL);
1194 return acelp_mem->old_exc_mem;
1195 }
1196
CLpd_AcelpRead(HANDLE_FDK_BITSTREAM hBs,CAcelpChannelData * acelp,INT acelp_core_mode,INT coreCoderFrameLength,INT i_offset)1197 INT CLpd_AcelpRead(HANDLE_FDK_BITSTREAM hBs, CAcelpChannelData *acelp,
1198 INT acelp_core_mode, INT coreCoderFrameLength,
1199 INT i_offset) {
1200 int nb_subfr = coreCoderFrameLength / L_DIV;
1201 const UCHAR *num_acb_index_bits =
1202 (nb_subfr == 4) ? num_acb_idx_bits_table[0] : num_acb_idx_bits_table[1];
1203 int nbits;
1204 int error = 0;
1205
1206 const int PIT_MIN = PIT_MIN_12k8 + i_offset;
1207 const int PIT_FR2 = PIT_FR2_12k8 - i_offset;
1208 const int PIT_FR1 = PIT_FR1_12k8;
1209 const int PIT_MAX = PIT_MAX_12k8 + (6 * i_offset);
1210 int T0, T0_frac, T0_min = 0, T0_max;
1211
1212 if (PIT_MAX > PIT_MAX_MAX) {
1213 error = AAC_DEC_DECODE_FRAME_ERROR;
1214 goto bail;
1215 }
1216
1217 acelp->acelp_core_mode = acelp_core_mode;
1218
1219 nbits = MapCoreMode2NBits(acelp_core_mode);
1220
1221 /* decode mean energy with 2 bits : 18, 30, 42 or 54 dB */
1222 acelp->mean_energy = FDKreadBits(hBs, 2);
1223
1224 for (int sfr = 0; sfr < nb_subfr; sfr++) {
1225 /* read ACB index and store T0 and T0_frac for each ACELP subframe. */
1226 error = DecodePitchLag(hBs, num_acb_index_bits[sfr], PIT_MIN, PIT_FR2,
1227 PIT_FR1, PIT_MAX, &T0, &T0_frac, &T0_min, &T0_max);
1228 if (error) {
1229 goto bail;
1230 }
1231 acelp->T0[sfr] = (USHORT)T0;
1232 acelp->T0_frac[sfr] = (UCHAR)T0_frac;
1233 acelp->ltp_filtering_flag[sfr] = FDKreadBits(hBs, 1);
1234 switch (nbits) {
1235 case 12: /* 12 bits AMR-WB codebook is used */
1236 acelp->icb_index[sfr][0] = FDKreadBits(hBs, 1);
1237 acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);
1238 acelp->icb_index[sfr][2] = FDKreadBits(hBs, 1);
1239 acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
1240 break;
1241 case 16: /* 16 bits AMR-WB codebook is used */
1242 acelp->icb_index[sfr][0] = FDKreadBits(hBs, 1);
1243 acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);
1244 acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);
1245 acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
1246 break;
1247 case 20: /* 20 bits AMR-WB codebook is used */
1248 acelp->icb_index[sfr][0] = FDKreadBits(hBs, 5);
1249 acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);
1250 acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);
1251 acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
1252 break;
1253 case 28: /* 28 bits AMR-WB codebook is used */
1254 acelp->icb_index[sfr][0] = FDKreadBits(hBs, 9);
1255 acelp->icb_index[sfr][1] = FDKreadBits(hBs, 9);
1256 acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);
1257 acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);
1258 break;
1259 case 36: /* 36 bits AMR-WB codebook is used */
1260 acelp->icb_index[sfr][0] = FDKreadBits(hBs, 9);
1261 acelp->icb_index[sfr][1] = FDKreadBits(hBs, 9);
1262 acelp->icb_index[sfr][2] = FDKreadBits(hBs, 9);
1263 acelp->icb_index[sfr][3] = FDKreadBits(hBs, 9);
1264 break;
1265 case 44: /* 44 bits AMR-WB codebook is used */
1266 acelp->icb_index[sfr][0] = FDKreadBits(hBs, 13);
1267 acelp->icb_index[sfr][1] = FDKreadBits(hBs, 13);
1268 acelp->icb_index[sfr][2] = FDKreadBits(hBs, 9);
1269 acelp->icb_index[sfr][3] = FDKreadBits(hBs, 9);
1270 break;
1271 case 52: /* 52 bits AMR-WB codebook is used */
1272 acelp->icb_index[sfr][0] = FDKreadBits(hBs, 13);
1273 acelp->icb_index[sfr][1] = FDKreadBits(hBs, 13);
1274 acelp->icb_index[sfr][2] = FDKreadBits(hBs, 13);
1275 acelp->icb_index[sfr][3] = FDKreadBits(hBs, 13);
1276 break;
1277 case 64: /* 64 bits AMR-WB codebook is used */
1278 acelp->icb_index[sfr][0] = FDKreadBits(hBs, 2);
1279 acelp->icb_index[sfr][1] = FDKreadBits(hBs, 2);
1280 acelp->icb_index[sfr][2] = FDKreadBits(hBs, 2);
1281 acelp->icb_index[sfr][3] = FDKreadBits(hBs, 2);
1282 acelp->icb_index[sfr][4] = FDKreadBits(hBs, 14);
1283 acelp->icb_index[sfr][5] = FDKreadBits(hBs, 14);
1284 acelp->icb_index[sfr][6] = FDKreadBits(hBs, 14);
1285 acelp->icb_index[sfr][7] = FDKreadBits(hBs, 14);
1286 break;
1287 default:
1288 FDK_ASSERT(0);
1289 break;
1290 }
1291 acelp->gains[sfr] = FDKreadBits(hBs, 7);
1292 }
1293
1294 bail:
1295 return error;
1296 }
1297