• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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