/src/aac/libAACdec/src/usacdec_acelp.cpp
Line  | Count  | Source  | 
1  |  | /* -----------------------------------------------------------------------------  | 
2  |  | Software License for The Fraunhofer FDK AAC Codec Library for Android  | 
3  |  |  | 
4  |  | © Copyright  1995 - 2020 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  | 0  | #define PIT_FR2_12k8 128 /* Minimum pitch lag with resolution 1/2      */  | 
112  | 0  | #define PIT_FR1_12k8 160 /* Minimum pitch lag with resolution 1        */  | 
113  |  | #define TILT_CODE2 \  | 
114  | 0  |   FL2FXCONST_SGL(0.3f * 2.0f) /* ACELP code pre-emphasis factor ( *2 )      */  | 
115  |  | #define PIT_SHARP \  | 
116  | 0  |   FL2FXCONST_SGL(0.85f) /* pitch sharpening factor                    */  | 
117  |  | #define PREEMPH_FAC \  | 
118  | 0  |   FL2FXCONST_SGL(0.68f) /* ACELP synth pre-emphasis factor            */  | 
119  |  |  | 
120  | 0  | #define ACELP_HEADROOM 1  | 
121  | 0  | #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 */  | 
130  | 0  | void E_UTIL_preemph(const FIXP_DBL *in, FIXP_DBL *out, INT L) { | 
131  | 0  |   int i;  | 
132  |  | 
  | 
133  | 0  |   for (i = 0; i < L; i++) { | 
134  | 0  |     out[i] = fAddSaturate(in[i], -fMult(PREEMPH_FAC, in[i - 1]));  | 
135  | 0  |   }  | 
136  |  | 
  | 
137  | 0  |   return;  | 
138  | 0  | }  | 
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  |  |  */  | 
145  |  | static void Preemph_code(  | 
146  |  |     FIXP_COD x[] /* (i/o)   : input signal overwritten by the output */  | 
147  | 0  | ) { | 
148  | 0  |   int i;  | 
149  | 0  |   FIXP_DBL L_tmp;  | 
150  |  |  | 
151  |  |   /* ARM926: 12 cycles per sample */  | 
152  | 0  |   for (i = L_SUBFR - 1; i > 0; i--) { | 
153  | 0  |     L_tmp = FX_COD2FX_DBL(x[i]);  | 
154  | 0  |     L_tmp -= fMultDiv2(x[i - 1], TILT_CODE2);  | 
155  | 0  |     x[i] = FX_DBL2FX_COD(L_tmp);  | 
156  | 0  |   }  | 
157  | 0  | }  | 
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  |  |  */  | 
164  |  | static void Pit_shrp(  | 
165  |  |     FIXP_COD x[], /* in/out: impulse response (or algebraic code) */  | 
166  |  |     int pit_lag   /* input : pitch lag                            */  | 
167  | 0  | ) { | 
168  | 0  |   int i;  | 
169  | 0  |   FIXP_DBL L_tmp;  | 
170  |  | 
  | 
171  | 0  |   for (i = pit_lag; i < L_SUBFR; i++) { | 
172  | 0  |     L_tmp = FX_COD2FX_DBL(x[i]);  | 
173  | 0  |     L_tmp += fMult(x[i - pit_lag], PIT_SHARP);  | 
174  | 0  |     x[i] = FX_DBL2FX_COD(L_tmp);  | 
175  | 0  |   }  | 
176  |  | 
  | 
177  | 0  |   return;  | 
178  | 0  | }  | 
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  | 0  | #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  |  |  | 
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  | 0  |                          FIXP_DBL *pEner_code, int *pEner_code_e) { | 
202  | 0  |   FIXP_DBL Ltmp;  | 
203  | 0  |   FIXP_DBL gcode0, gcode_inov;  | 
204  | 0  |   INT gcode0_e, gcode_inov_e;  | 
205  | 0  |   int i;  | 
206  |  | 
  | 
207  | 0  |   FIXP_DBL ener_code;  | 
208  | 0  |   INT ener_code_e;  | 
209  |  |  | 
210  |  |   /* ener_code = sum(code[]^2) */  | 
211  | 0  |   ener_code = FIXP_DBL(0);  | 
212  | 0  |   for (i = 0; i < L_SUBFR; i++) { | 
213  | 0  |     ener_code += fPow2Div2(code[i]);  | 
214  | 0  |   }  | 
215  |  | 
  | 
216  | 0  |   ener_code_e = fMax(fNorm(ener_code) - 1, 0);  | 
217  | 0  |   ener_code <<= ener_code_e;  | 
218  | 0  |   ener_code_e = 2 * SF_CODE + 1 - ener_code_e;  | 
219  |  |  | 
220  |  |   /* export energy of code for calc_period_factor() */  | 
221  | 0  |   *pEner_code = ener_code;  | 
222  | 0  |   *pEner_code_e = ener_code_e;  | 
223  |  | 
  | 
224  | 0  |   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  | 0  |   if (ener_code_e & 1) { | 
229  | 0  |     ener_code_e -= 5;  | 
230  | 0  |     ener_code >>= 1;  | 
231  | 0  |   } else { | 
232  | 0  |     ener_code_e -= 6;  | 
233  | 0  |   }  | 
234  | 0  |   gcode_inov = invSqrtNorm2(ener_code, &gcode0_e);  | 
235  | 0  |   gcode_inov_e = gcode0_e - (ener_code_e >> 1);  | 
236  |  | 
  | 
237  | 0  |   if (bfi) { | 
238  | 0  |     FIXP_DBL tgcode;  | 
239  | 0  |     FIXP_SGL tgpit;  | 
240  |  | 
  | 
241  | 0  |     tgpit = *past_gpit;  | 
242  |  | 
  | 
243  | 0  |     if (tgpit > FL2FXCONST_SGL(0.95f / (1 << SF_GAIN_P))) { | 
244  | 0  |       tgpit = FL2FXCONST_SGL(0.95f / (1 << SF_GAIN_P));  | 
245  | 0  |     } else if (tgpit < FL2FXCONST_SGL(0.5f / (1 << SF_GAIN_P))) { | 
246  | 0  |       tgpit = FL2FXCONST_SGL(0.5f / (1 << SF_GAIN_P));  | 
247  | 0  |     }  | 
248  | 0  |     *gain_pit = tgpit;  | 
249  | 0  |     tgpit = FX_DBL2FX_SGL(fMult(tgpit, FL2FXCONST_DBL(0.95f)));  | 
250  | 0  |     *past_gpit = tgpit;  | 
251  |  | 
  | 
252  | 0  |     tgpit = FL2FXCONST_SGL(1.4f / (1 << SF_GAIN_P)) - tgpit;  | 
253  | 0  |     tgcode = fMult(*past_gcode, tgpit) << SF_GAIN_P;  | 
254  | 0  |     *gain_code = scaleValue(fMult(tgcode, gcode_inov), gcode_inov_e);  | 
255  | 0  |     *past_gcode = tgcode;  | 
256  |  | 
  | 
257  | 0  |     return;  | 
258  | 0  |   }  | 
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  | 0  |   gcode0 = pow_10_mean_energy[mean_ener_bits];  | 
266  | 0  |   gcode0 = fMultDiv2(gcode0, gcode_inov);  | 
267  | 0  |   gcode0_e = gcode0_e + SF_MEAN_ENER_LG10 - (ener_code_e >> 1) + 1;  | 
268  |  | 
  | 
269  | 0  |   i = index << 1;  | 
270  | 0  |   *gain_pit = t_qua_gain7b[i]; /* adaptive codebook gain */  | 
271  |  |   /* t_qua_gain[ind2p1] : fixed codebook gain correction factor */  | 
272  | 0  |   Ltmp = fMult(t_qua_gain7b[i + 1], gcode0);  | 
273  | 0  |   *gain_code = scaleValue(Ltmp, gcode0_e - SF_GAIN_C + SF_QUA_GAIN7B);  | 
274  |  |  | 
275  |  |   /* update bad frame handler */  | 
276  | 0  |   *past_gpit = *gain_pit;  | 
277  |  |  | 
278  |  |   /*--------------------------------------------------------  | 
279  |  |     past_gcode  = gain_code/gcode_inov  | 
280  |  |    --------------------------------------------------------*/  | 
281  | 0  |   { | 
282  | 0  |     FIXP_DBL gcode_m;  | 
283  | 0  |     INT gcode_e;  | 
284  |  | 
  | 
285  | 0  |     gcode_m = fDivNormHighPrec(Ltmp, gcode_inov, &gcode_e);  | 
286  | 0  |     gcode_e += (gcode0_e - SF_GAIN_C + SF_QUA_GAIN7B) - (gcode_inov_e);  | 
287  | 0  |     *past_gcode = scaleValue(gcode_m, gcode_e);  | 
288  | 0  |   }  | 
289  | 0  | }  | 
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  |  |  */  | 
301  |  | static FIXP_DBL calc_period_factor(FIXP_DBL exc[], FIXP_SGL gain_pit,  | 
302  |  |                                    FIXP_DBL gain_code, FIXP_DBL ener_code,  | 
303  | 0  |                                    int ener_code_e) { | 
304  | 0  |   int ener_exc_e, L_tmp_e, s = 0;  | 
305  | 0  |   FIXP_DBL ener_exc, L_tmp;  | 
306  | 0  |   FIXP_DBL period_fac;  | 
307  |  |  | 
308  |  |   /* energy of pitch excitation */  | 
309  | 0  |   ener_exc = (FIXP_DBL)0;  | 
310  | 0  |   for (int i = 0; i < L_SUBFR; i++) { | 
311  | 0  |     ener_exc += fPow2Div2(exc[i]) >> s;  | 
312  | 0  |     if (ener_exc >= FL2FXCONST_DBL(0.5f)) { | 
313  | 0  |       ener_exc >>= 1;  | 
314  | 0  |       s++;  | 
315  | 0  |     }  | 
316  | 0  |   }  | 
317  |  | 
  | 
318  | 0  |   ener_exc_e = fNorm(ener_exc);  | 
319  | 0  |   ener_exc = fMult(ener_exc << ener_exc_e, fPow2(gain_pit));  | 
320  | 0  |   if (ener_exc != (FIXP_DBL)0) { | 
321  | 0  |     ener_exc_e = 2 * SF_EXC + 1 + 2 * SF_GAIN_P - ener_exc_e + s;  | 
322  | 0  |   } else { | 
323  | 0  |     ener_exc_e = 0;  | 
324  | 0  |   }  | 
325  |  |  | 
326  |  |   /* energy of innovative code excitation */  | 
327  |  |   /* L_tmp = ener_code * gain_code*gain_code; */  | 
328  | 0  |   L_tmp_e = fNorm(gain_code);  | 
329  | 0  |   L_tmp = fPow2(gain_code << L_tmp_e);  | 
330  | 0  |   L_tmp = fMult(ener_code, L_tmp);  | 
331  | 0  |   L_tmp_e = 2 * SF_GAIN_C + ener_code_e - 2 * L_tmp_e;  | 
332  |  |  | 
333  |  |   /* Find common exponent */  | 
334  | 0  |   { | 
335  | 0  |     FIXP_DBL num, den;  | 
336  | 0  |     int exp_diff;  | 
337  |  | 
  | 
338  | 0  |     exp_diff = ener_exc_e - L_tmp_e;  | 
339  | 0  |     if (exp_diff >= 0) { | 
340  | 0  |       ener_exc >>= 1;  | 
341  | 0  |       if (exp_diff <= DFRACT_BITS - 2) { | 
342  | 0  |         L_tmp >>= exp_diff + 1;  | 
343  | 0  |       } else { | 
344  | 0  |         L_tmp = (FIXP_DBL)0;  | 
345  | 0  |       }  | 
346  | 0  |       den = ener_exc + L_tmp;  | 
347  | 0  |       if (ener_exc_e < DFRACT_BITS - 1) { | 
348  | 0  |         den += scaleValue(FL2FXCONST_DBL(0.01f), -ener_exc_e - 1);  | 
349  | 0  |       }  | 
350  | 0  |     } else { | 
351  | 0  |       if (exp_diff >= -(DFRACT_BITS - 2)) { | 
352  | 0  |         ener_exc >>= 1 - exp_diff;  | 
353  | 0  |       } else { | 
354  | 0  |         ener_exc = (FIXP_DBL)0;  | 
355  | 0  |       }  | 
356  | 0  |       L_tmp >>= 1;  | 
357  | 0  |       den = ener_exc + L_tmp;  | 
358  | 0  |       if (L_tmp_e < DFRACT_BITS - 1) { | 
359  | 0  |         den += scaleValue(FL2FXCONST_DBL(0.01f), -L_tmp_e - 1);  | 
360  | 0  |       }  | 
361  | 0  |     }  | 
362  | 0  |     num = (ener_exc - L_tmp);  | 
363  | 0  |     num >>= SF_PFAC;  | 
364  |  | 
  | 
365  | 0  |     if (den > (FIXP_DBL)0) { | 
366  | 0  |       if (ener_exc > L_tmp) { | 
367  | 0  |         period_fac = schur_div(num, den, 16);  | 
368  | 0  |       } else { | 
369  | 0  |         period_fac = -schur_div(-num, den, 16);  | 
370  | 0  |       }  | 
371  | 0  |     } else { | 
372  | 0  |       period_fac = (FIXP_DBL)MAXVAL_DBL;  | 
373  | 0  |     }  | 
374  | 0  |   }  | 
375  |  |  | 
376  |  |   /* exponent = SF_PFAC */  | 
377  | 0  |   return period_fac;  | 
378  | 0  | }  | 
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  | 
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  | 0  | { | 
406  | 0  |   FIXP_DBL fac, L_tmp, gc_thres;  | 
407  |  | 
  | 
408  | 0  |   gc_thres = *p_gc_threshold;  | 
409  |  | 
  | 
410  | 0  |   L_tmp = gain_code;  | 
411  | 0  |   if (L_tmp < gc_thres) { | 
412  | 0  |     L_tmp += fMultDiv2(gain_code,  | 
413  | 0  |                        FL2FXCONST_SGL(2.0 * 0.19f)); /* +1.5dB => *(1.0+0.19) */  | 
414  | 0  |     if (L_tmp > gc_thres) { | 
415  | 0  |       L_tmp = gc_thres;  | 
416  | 0  |     }  | 
417  | 0  |   } else { | 
418  | 0  |     L_tmp = fMult(gain_code,  | 
419  | 0  |                   FL2FXCONST_SGL(1.0f / 1.19f)); /* -1.5dB => *10^(-1.5/20) */  | 
420  | 0  |     if (L_tmp < gc_thres) { | 
421  | 0  |       L_tmp = gc_thres;  | 
422  | 0  |     }  | 
423  | 0  |   }  | 
424  | 0  |   *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  | 0  |   fac = (FX_SGL2FX_DBL(stab_fac) >> (SF_PFAC + 1)) -  | 
430  | 0  |         fMultDiv2(stab_fac, period_fac);  | 
431  |  |   /* fac_e = SF_PFAC + SF_STAB */  | 
432  | 0  |   FDK_ASSERT(fac >= (FIXP_DBL)0);  | 
433  |  |  | 
434  |  |   /* gain_code = (float)((fac*tmp) + ((1.0-fac)*gain_code)); */  | 
435  | 0  |   gain_code = fMult(fac, L_tmp) -  | 
436  | 0  |               fMult(FL2FXCONST_DBL(-1.0f / (1 << (SF_PFAC + SF_STAB))) + fac,  | 
437  | 0  |                     gain_code);  | 
438  | 0  |   gain_code <<= (SF_PFAC + SF_STAB);  | 
439  |  | 
  | 
440  | 0  |   return gain_code;  | 
441  | 0  | }  | 
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  |  |  */  | 
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  | 0  | ) { | 
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  | 0  | #define SF_HEADROOM (1)  | 
469  | 0  | #define SF (SF_CODE + SF_GAIN_C + 1 - SF_EXC - SF_HEADROOM)  | 
470  | 0  | #define SF_GAIN_P2 (SF_GAIN_P - SF_HEADROOM)  | 
471  |  | 
  | 
472  | 0  |   int i;  | 
473  | 0  |   FIXP_DBL tmp, cpe, code_smooth_prev, code_smooth;  | 
474  |  | 
  | 
475  | 0  |   FIXP_COD code_i;  | 
476  | 0  |   FIXP_DBL cpe_code_smooth, cpe_code_smooth_prev;  | 
477  |  |  | 
478  |  |   /* cpe = (1+r_v)/8 * 2 ; ( SF = -1) */  | 
479  | 0  |   cpe = (period_fac >> (2 - SF_PFAC)) + FL2FXCONST_DBL(0.25f);  | 
480  |  |  | 
481  |  |   /* u'(n) */  | 
482  | 0  |   tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1); /* v(0)*g_p */  | 
483  | 0  |   *exc++ = (tmp + (fMultDiv2(code[0], gain_code) << SF)) << SF_HEADROOM;  | 
484  |  |  | 
485  |  |   /* u(n) */  | 
486  | 0  |   code_smooth_prev = fMultDiv2(*code++, gain_code_smoothed)  | 
487  | 0  |                      << SF; /* c(0) * g_sc */  | 
488  | 0  |   code_i = *code++;  | 
489  | 0  |   code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF; /* c(1) * g_sc */  | 
490  | 0  |   tmp += code_smooth_prev; /* tmp = v(0)*g_p + c(0)*g_sc */  | 
491  | 0  |   cpe_code_smooth = fMultDiv2(cpe, code_smooth);  | 
492  | 0  |   *exc2++ = (tmp - cpe_code_smooth) << SF_HEADROOM;  | 
493  | 0  |   cpe_code_smooth_prev = fMultDiv2(cpe, code_smooth_prev);  | 
494  |  | 
  | 
495  | 0  |   i = L_SUBFR - 2;  | 
496  | 0  |   do /* ARM926: 22 cycles per iteration */  | 
497  | 0  |   { | 
498  |  |     /* u'(n) */  | 
499  | 0  |     tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1);  | 
500  | 0  |     *exc++ = (tmp + (fMultDiv2(code_i, gain_code) << SF)) << SF_HEADROOM;  | 
501  |  |     /* u(n) */  | 
502  | 0  |     tmp += code_smooth; /* += g_sc * c(i) */  | 
503  | 0  |     tmp -= cpe_code_smooth_prev;  | 
504  | 0  |     cpe_code_smooth_prev = cpe_code_smooth;  | 
505  | 0  |     code_i = *code++;  | 
506  | 0  |     code_smooth = fMultDiv2(code_i, gain_code_smoothed) << SF;  | 
507  | 0  |     cpe_code_smooth = fMultDiv2(cpe, code_smooth);  | 
508  | 0  |     *exc2++ = (tmp - cpe_code_smooth)  | 
509  | 0  |               << SF_HEADROOM; /* tmp - c_pe * g_sc * c(i+1) */  | 
510  | 0  |   } while (--i != 0);  | 
511  |  |  | 
512  |  |   /* u'(n) */  | 
513  | 0  |   tmp = fMultDiv2(*exc, gain_pit) << (SF_GAIN_P2 + 1);  | 
514  | 0  |   *exc = (tmp + (fMultDiv2(code_i, gain_code) << SF)) << SF_HEADROOM;  | 
515  |  |   /* u(n) */  | 
516  | 0  |   tmp += code_smooth;  | 
517  | 0  |   tmp -= cpe_code_smooth_prev;  | 
518  | 0  |   *exc2++ = tmp << SF_HEADROOM;  | 
519  |  | 
  | 
520  | 0  |   return;  | 
521  | 0  | }  | 
522  |  |  | 
523  |  | /**  | 
524  |  |  * \brief Interpolate LPC vector in LSP domain for current subframe and convert  | 
525  |  |  * to LP domain  | 
526  |  |  * \param[in] lsp_old LPC vector (LSP domain) corresponding to the beginning of  | 
527  |  |  * current ACELP frame.  | 
528  |  |  * \param[in] lsp_new LPC vector (LSP domain) corresponding to the end of  | 
529  |  |  * current ACELP frame.  | 
530  |  |  * \param[in] subfr_nr number of current ACELP subframe 0..3.  | 
531  |  |  * \param[in] nb_subfr total number of ACELP subframes in this frame.  | 
532  |  |  * \param[out] A LP filter coefficients for current ACELP subframe, exponent =  | 
533  |  |  * SF_A_COEFFS.  | 
534  |  |  */  | 
535  |  | /* static */  | 
536  |  | void int_lpc_acelp(  | 
537  |  |     const FIXP_LPC lsp_old[], /* input : LSPs from past frame              */  | 
538  |  |     const FIXP_LPC lsp_new[], /* input : LSPs from present frame           */  | 
539  |  |     int subfr_nr, int nb_subfr,  | 
540  |  |     FIXP_LPC  | 
541  |  |         A[], /* output: interpolated LP coefficients for current subframe */  | 
542  | 0  |     INT *A_exp) { | 
543  | 0  |   int i;  | 
544  | 0  |   FIXP_LPC lsp_interpol[M_LP_FILTER_ORDER];  | 
545  | 0  |   FIXP_SGL fac_old, fac_new;  | 
546  |  | 
  | 
547  | 0  |   FDK_ASSERT((nb_subfr == 3) || (nb_subfr == 4));  | 
548  |  |  | 
549  | 0  |   fac_old = lsp_interpol_factor[nb_subfr & 0x1][(nb_subfr - 1) - subfr_nr];  | 
550  | 0  |   fac_new = lsp_interpol_factor[nb_subfr & 0x1][subfr_nr];  | 
551  | 0  |   for (i = 0; i < M_LP_FILTER_ORDER; i++) { | 
552  | 0  |     lsp_interpol[i] = FX_DBL2FX_LPC(  | 
553  | 0  |         (fMultDiv2(lsp_old[i], fac_old) + fMultDiv2(lsp_new[i], fac_new)) << 1);  | 
554  | 0  |   }  | 
555  |  | 
  | 
556  | 0  |   E_LPC_f_lsp_a_conversion(lsp_interpol, A, A_exp);  | 
557  |  | 
  | 
558  | 0  |   return;  | 
559  | 0  | }  | 
560  |  |  | 
561  |  | /**  | 
562  |  |  * \brief Perform LP synthesis by filtering the post-processed excitation u(n)  | 
563  |  |  *        through the LP synthesis filter 1/A(z)  | 
564  |  |  * \param[in] a LP filter coefficients, exponent = SF_A_COEFFS.  | 
565  |  |  * \param[in] length length of input/output signal.  | 
566  |  |  * \param[in] x post-processed excitation u(n).  | 
567  |  |  * \param[in,out] y LP synthesis signal and filter memory  | 
568  |  |  * y[-M_LP_FILTER_ORDER..-1].  | 
569  |  |  */  | 
570  |  |  | 
571  |  | /* static */  | 
572  |  | void Syn_filt(const FIXP_LPC a[], /* (i) : a[m] prediction coefficients Q12 */  | 
573  |  |               const INT a_exp,  | 
574  |  |               INT length,   /* (i) : length of input/output signal (64|128)   */  | 
575  |  |               FIXP_DBL x[], /* (i) : input signal Qx  */  | 
576  |  |               FIXP_DBL y[]  /* (i/o) : filter states / output signal  Qx-s*/  | 
577  | 0  | ) { | 
578  | 0  |   int i, j;  | 
579  | 0  |   FIXP_DBL L_tmp;  | 
580  |  | 
  | 
581  | 0  |   for (i = 0; i < length; i++) { | 
582  | 0  |     L_tmp = (FIXP_DBL)0;  | 
583  |  | 
  | 
584  | 0  |     for (j = 0; j < M_LP_FILTER_ORDER; j++) { | 
585  | 0  |       L_tmp -= fMultDiv2(a[j], y[i - (j + 1)]) >> (LP_FILTER_SCALE - 1);  | 
586  | 0  |     }  | 
587  |  | 
  | 
588  | 0  |     L_tmp = scaleValue(L_tmp, a_exp + LP_FILTER_SCALE);  | 
589  | 0  |     y[i] = fAddSaturate(L_tmp, x[i]);  | 
590  | 0  |   }  | 
591  |  | 
  | 
592  | 0  |   return;  | 
593  | 0  | }  | 
594  |  |  | 
595  |  | /**  | 
596  |  |  * \brief Calculate de-emphasis 1/(1 - mu z^-1) on input signal.  | 
597  |  |  * \param[in] x input signal.  | 
598  |  |  * \param[out] y output signal.  | 
599  |  |  * \param[in] L length of signal.  | 
600  |  |  * \param[in,out] mem memory (signal[-1]).  | 
601  |  |  */  | 
602  |  | /* static */  | 
603  | 0  | void Deemph(FIXP_DBL *x, FIXP_DBL *y, int L, FIXP_DBL *mem) { | 
604  | 0  |   int i;  | 
605  | 0  |   FIXP_DBL yi = *mem;  | 
606  |  | 
  | 
607  | 0  |   for (i = 0; i < L; i++) { | 
608  | 0  |     FIXP_DBL xi = x[i] >> 1;  | 
609  | 0  |     xi = fMultAddDiv2(xi, PREEMPH_FAC, yi);  | 
610  | 0  |     yi = SATURATE_LEFT_SHIFT(xi, 1, 32);  | 
611  | 0  |     y[i] = yi;  | 
612  | 0  |   }  | 
613  | 0  |   *mem = yi;  | 
614  | 0  |   return;  | 
615  | 0  | }  | 
616  |  |  | 
617  |  | /**  | 
618  |  |  * \brief Compute the LP residual by filtering the input speech through the  | 
619  |  |  * analysis filter A(z).  | 
620  |  |  * \param[in] a LP filter coefficients, exponent = SF_A_COEFFS  | 
621  |  |  * \param[in] x input signal (note that values x[-m..-1] are needed), exponent =  | 
622  |  |  * SF_SYNTH  | 
623  |  |  * \param[out] y output signal (residual), exponent = SF_EXC  | 
624  |  |  * \param[in] l length of filtering  | 
625  |  |  */  | 
626  |  | /* static */  | 
627  |  | void E_UTIL_residu(const FIXP_LPC *a, const INT a_exp, FIXP_DBL *x, FIXP_DBL *y,  | 
628  | 0  |                    INT l) { | 
629  | 0  |   FIXP_DBL s;  | 
630  | 0  |   INT i, j;  | 
631  |  |  | 
632  |  |   /* (note that values x[-m..-1] are needed) */  | 
633  | 0  |   for (i = 0; i < l; i++) { | 
634  | 0  |     s = (FIXP_DBL)0;  | 
635  |  | 
  | 
636  | 0  |     for (j = 0; j < M_LP_FILTER_ORDER; j++) { | 
637  | 0  |       s += fMultDiv2(a[j], x[i - j - 1]) >> (LP_FILTER_SCALE - 1);  | 
638  | 0  |     }  | 
639  |  | 
  | 
640  | 0  |     s = scaleValue(s, a_exp + LP_FILTER_SCALE);  | 
641  | 0  |     y[i] = fAddSaturate(s, x[i]);  | 
642  | 0  |   }  | 
643  |  | 
  | 
644  | 0  |   return;  | 
645  | 0  | }  | 
646  |  |  | 
647  |  | /* use to map subfr number to number of bits used for acb_index */  | 
648  |  | static const UCHAR num_acb_idx_bits_table[2][NB_SUBFR] = { | 
649  |  |     {9, 6, 9, 6}, /* coreCoderFrameLength == 1024 */ | 
650  |  |     {9, 6, 6, 0}  /* coreCoderFrameLength == 768  */ | 
651  |  | };  | 
652  |  |  | 
653  |  | static int DecodePitchLag(HANDLE_FDK_BITSTREAM hBs,  | 
654  |  |                           const UCHAR num_acb_idx_bits,  | 
655  |  |                           const int PIT_MIN, /* TMIN */  | 
656  |  |                           const int PIT_FR2, /* TFR2 */  | 
657  |  |                           const int PIT_FR1, /* TFR1 */  | 
658  |  |                           const int PIT_MAX, /* TMAX */  | 
659  | 0  |                           int *pT0, int *pT0_frac, int *pT0_min, int *pT0_max) { | 
660  | 0  |   int acb_idx;  | 
661  | 0  |   int error = 0;  | 
662  | 0  |   int T0, T0_frac;  | 
663  |  | 
  | 
664  | 0  |   FDK_ASSERT((num_acb_idx_bits == 9) || (num_acb_idx_bits == 6));  | 
665  |  |  | 
666  | 0  |   acb_idx = FDKreadBits(hBs, num_acb_idx_bits);  | 
667  |  | 
  | 
668  | 0  |   if (num_acb_idx_bits == 6) { | 
669  |  |     /* When the pitch value is encoded on 6 bits, a pitch resolution of 1/4 is  | 
670  |  |        always used in the range [T1-8, T1+7.75], where T1 is nearest integer to  | 
671  |  |        the fractional pitch lag of the previous subframe.  | 
672  |  |     */  | 
673  | 0  |     T0 = *pT0_min + acb_idx / 4;  | 
674  | 0  |     T0_frac = acb_idx & 0x3;  | 
675  | 0  |   } else { /* num_acb_idx_bits == 9 */ | 
676  |  |     /* When the pitch value is encoded on 9 bits, a fractional pitch delay is  | 
677  |  |        used with resolutions 0.25 in the range [TMIN, TFR2-0.25], resolutions  | 
678  |  |        0.5 in the range [TFR2, TFR1-0.5], and integers only in the range [TFR1,  | 
679  |  |        TMAX]. NOTE: for small sampling rates TMAX can get smaller than TFR1.  | 
680  |  |     */  | 
681  | 0  |     int T0_min, T0_max;  | 
682  |  | 
  | 
683  | 0  |     if (acb_idx < (PIT_FR2 - PIT_MIN) * 4) { | 
684  |  |       /* first interval with 0.25 pitch resolution */  | 
685  | 0  |       T0 = PIT_MIN + (acb_idx / 4);  | 
686  | 0  |       T0_frac = acb_idx & 0x3;  | 
687  | 0  |     } else if (acb_idx < ((PIT_FR2 - PIT_MIN) * 4 + (PIT_FR1 - PIT_FR2) * 2)) { | 
688  |  |       /* second interval with 0.5 pitch resolution */  | 
689  | 0  |       acb_idx -= (PIT_FR2 - PIT_MIN) * 4;  | 
690  | 0  |       T0 = PIT_FR2 + (acb_idx / 2);  | 
691  | 0  |       T0_frac = (acb_idx & 0x1) * 2;  | 
692  | 0  |     } else { | 
693  |  |       /* third interval with 1.0 pitch resolution */  | 
694  | 0  |       T0 = acb_idx + PIT_FR1 - ((PIT_FR2 - PIT_MIN) * 4) -  | 
695  | 0  |            ((PIT_FR1 - PIT_FR2) * 2);  | 
696  | 0  |       T0_frac = 0;  | 
697  | 0  |     }  | 
698  |  |     /* find T0_min and T0_max for subframe 1 or 3 */  | 
699  | 0  |     T0_min = T0 - 8;  | 
700  | 0  |     if (T0_min < PIT_MIN) { | 
701  | 0  |       T0_min = PIT_MIN;  | 
702  | 0  |     }  | 
703  | 0  |     T0_max = T0_min + 15;  | 
704  | 0  |     if (T0_max > PIT_MAX) { | 
705  | 0  |       T0_max = PIT_MAX;  | 
706  | 0  |       T0_min = T0_max - 15;  | 
707  | 0  |     }  | 
708  | 0  |     *pT0_min = T0_min;  | 
709  | 0  |     *pT0_max = T0_max;  | 
710  | 0  |   }  | 
711  | 0  |   *pT0 = T0;  | 
712  | 0  |   *pT0_frac = T0_frac;  | 
713  |  | 
  | 
714  | 0  |   return error;  | 
715  | 0  | }  | 
716  |  | static void ConcealPitchLag(CAcelpStaticMem *acelp_mem, const int PIT_MAX,  | 
717  | 0  |                             int *pT0, int *pT0_frac) { | 
718  | 0  |   USHORT *pold_T0 = &acelp_mem->old_T0;  | 
719  | 0  |   UCHAR *pold_T0_frac = &acelp_mem->old_T0_frac;  | 
720  |  | 
  | 
721  | 0  |   if ((int)*pold_T0 >= PIT_MAX) { | 
722  | 0  |     *pold_T0 = (USHORT)(PIT_MAX - 5);  | 
723  | 0  |   }  | 
724  | 0  |   *pT0 = (int)*pold_T0;  | 
725  | 0  |   *pT0_frac = (int)*pold_T0_frac;  | 
726  | 0  | }  | 
727  |  |  | 
728  |  | static UCHAR tab_coremode2nbits[8] = {20, 28, 36, 44, 52, 64, 12, 16}; | 
729  |  |  | 
730  | 0  | static int MapCoreMode2NBits(int core_mode) { | 
731  | 0  |   return (int)tab_coremode2nbits[core_mode];  | 
732  | 0  | }  | 
733  |  |  | 
734  |  | void CLpd_AcelpDecode(CAcelpStaticMem *acelp_mem, INT i_offset,  | 
735  |  |                       const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],  | 
736  |  |                       const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],  | 
737  |  |                       FIXP_SGL stab_fac, CAcelpChannelData *pAcelpData,  | 
738  |  |                       INT numLostSubframes, int lastLpcLost, int frameCnt,  | 
739  |  |                       FIXP_DBL synth[], int pT[], FIXP_DBL *pit_gain,  | 
740  | 0  |                       INT coreCoderFrameLength) { | 
741  | 0  |   int i_subfr, subfr_nr, l_div, T;  | 
742  | 0  |   int T0 = -1, T0_frac = -1; /* mark invalid */  | 
743  |  | 
  | 
744  | 0  |   int pit_gain_index = 0;  | 
745  |  | 
  | 
746  | 0  |   const int PIT_MAX = PIT_MAX_12k8 + (6 * i_offset); /* maximum pitch lag */  | 
747  |  | 
  | 
748  | 0  |   FIXP_COD *code;  | 
749  | 0  |   FIXP_DBL *exc2;  | 
750  | 0  |   FIXP_DBL *syn;  | 
751  | 0  |   FIXP_DBL *exc;  | 
752  | 0  |   FIXP_LPC A[M_LP_FILTER_ORDER];  | 
753  | 0  |   INT A_exp;  | 
754  |  | 
  | 
755  | 0  |   FIXP_DBL period_fac;  | 
756  | 0  |   FIXP_SGL gain_pit;  | 
757  | 0  |   FIXP_DBL gain_code, gain_code_smooth, Ener_code;  | 
758  | 0  |   int Ener_code_e;  | 
759  | 0  |   int n;  | 
760  | 0  |   int bfi = (numLostSubframes > 0) ? 1 : 0;  | 
761  |  | 
  | 
762  | 0  |   C_ALLOC_SCRATCH_START(  | 
763  | 0  |       exc_buf, FIXP_DBL,  | 
764  | 0  |       PIT_MAX_MAX + L_INTERPOL + L_DIV + 1); /* 411 + 17 + 256 + 1 = 685 */  | 
765  | 0  |   C_ALLOC_SCRATCH_START(syn_buf, FIXP_DBL,  | 
766  | 0  |                         M_LP_FILTER_ORDER + L_DIV); /* 16 + 256 = 272 */  | 
767  |  |   /* use same memory for code[L_SUBFR] and exc2[L_SUBFR] */  | 
768  | 0  |   C_ALLOC_SCRATCH_START(tmp_buf, FIXP_DBL, L_SUBFR); /* 64 */  | 
769  |  |   /* make sure they don't overlap if they are accessed alternatingly in  | 
770  |  |    * BuildAdaptiveExcitation() */  | 
771  | 0  | #if (COD_BITS == FRACT_BITS)  | 
772  | 0  |   code = (FIXP_COD *)(tmp_buf + L_SUBFR / 2);  | 
773  |  | #elif (COD_BITS == DFRACT_BITS)  | 
774  |  |   code = (FIXP_COD *)tmp_buf;  | 
775  |  | #endif  | 
776  | 0  |   exc2 = (FIXP_DBL *)tmp_buf;  | 
777  |  | 
  | 
778  | 0  |   syn = syn_buf + M_LP_FILTER_ORDER;  | 
779  | 0  |   exc = exc_buf + PIT_MAX_MAX + L_INTERPOL;  | 
780  |  | 
  | 
781  | 0  |   FDKmemcpy(syn_buf, acelp_mem->old_syn_mem,  | 
782  | 0  |             M_LP_FILTER_ORDER * sizeof(FIXP_DBL));  | 
783  | 0  |   FDKmemcpy(exc_buf, acelp_mem->old_exc_mem,  | 
784  | 0  |             (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));  | 
785  |  | 
  | 
786  | 0  |   FDKmemclear(exc_buf + (PIT_MAX_MAX + L_INTERPOL),  | 
787  | 0  |               (L_DIV + 1) * sizeof(FIXP_DBL));  | 
788  |  | 
  | 
789  | 0  |   l_div = coreCoderFrameLength / NB_DIV;  | 
790  |  | 
  | 
791  | 0  |   for (i_subfr = 0, subfr_nr = 0; i_subfr < l_div;  | 
792  | 0  |        i_subfr += L_SUBFR, subfr_nr++) { | 
793  |  |     /*-------------------------------------------------*  | 
794  |  |      * - Decode pitch lag (T0 and T0_frac)             *  | 
795  |  |      *-------------------------------------------------*/  | 
796  | 0  |     if (bfi) { | 
797  | 0  |       ConcealPitchLag(acelp_mem, PIT_MAX, &T0, &T0_frac);  | 
798  | 0  |     } else { | 
799  | 0  |       T0 = (int)pAcelpData->T0[subfr_nr];  | 
800  | 0  |       T0_frac = (int)pAcelpData->T0_frac[subfr_nr];  | 
801  | 0  |     }  | 
802  |  |  | 
803  |  |     /*-------------------------------------------------*  | 
804  |  |      * - Find the pitch gain, the interpolation filter *  | 
805  |  |      *   and the adaptive codebook vector.             *  | 
806  |  |      *-------------------------------------------------*/  | 
807  | 0  |     Pred_lt4(&exc[i_subfr], T0, T0_frac);  | 
808  |  | 
  | 
809  | 0  |     if ((!bfi && pAcelpData->ltp_filtering_flag[subfr_nr] == 0) ||  | 
810  | 0  |         (bfi && numLostSubframes == 1 && stab_fac < FL2FXCONST_SGL(0.25f))) { | 
811  |  |       /* find pitch excitation with lp filter: v'(n) => v(n) */  | 
812  | 0  |       Pred_lt4_postfilter(&exc[i_subfr]);  | 
813  | 0  |     }  | 
814  |  |  | 
815  |  |     /*-------------------------------------------------------*  | 
816  |  |      * - Decode innovative codebook.                         *  | 
817  |  |      * - Add the fixed-gain pitch contribution to code[].    *  | 
818  |  |      *-------------------------------------------------------*/  | 
819  | 0  |     if (bfi) { | 
820  | 0  |       for (n = 0; n < L_SUBFR; n++) { | 
821  | 0  |         code[n] =  | 
822  | 0  |             FX_SGL2FX_COD((FIXP_SGL)E_UTIL_random(&acelp_mem->seed_ace)) >> 4;  | 
823  | 0  |       }  | 
824  | 0  |     } else { | 
825  | 0  |       int nbits = MapCoreMode2NBits((int)pAcelpData->acelp_core_mode);  | 
826  | 0  |       D_ACELP_decode_4t64(pAcelpData->icb_index[subfr_nr], nbits, &code[0]);  | 
827  | 0  |     }  | 
828  |  | 
  | 
829  | 0  |     T = T0;  | 
830  | 0  |     if (T0_frac > 2) { | 
831  | 0  |       T += 1;  | 
832  | 0  |     }  | 
833  |  | 
  | 
834  | 0  |     Preemph_code(code);  | 
835  | 0  |     Pit_shrp(code, T);  | 
836  |  |  | 
837  |  |     /* Output pitch lag for bass post-filter */  | 
838  | 0  |     if (T > PIT_MAX) { | 
839  | 0  |       pT[subfr_nr] = PIT_MAX;  | 
840  | 0  |     } else { | 
841  | 0  |       pT[subfr_nr] = T;  | 
842  | 0  |     }  | 
843  | 0  |     D_gain2_plus(  | 
844  | 0  |         pAcelpData->gains[subfr_nr],  | 
845  | 0  |         code,       /* (i)  : Innovative code vector, exponent = SF_CODE */  | 
846  | 0  |         &gain_pit,  /* (o)  : Quantized pitch gain, exponent = SF_GAIN_P */  | 
847  | 0  |         &gain_code, /* (o)  : Quantized codebook gain                    */  | 
848  | 0  |         pAcelpData  | 
849  | 0  |             ->mean_energy, /* (i)  : mean_ener defined in open-loop (2 bits) */  | 
850  | 0  |         bfi, &acelp_mem->past_gpit, &acelp_mem->past_gcode,  | 
851  | 0  |         &Ener_code,    /* (o)  : Innovative code vector energy              */  | 
852  | 0  |         &Ener_code_e); /* (o)  : Innovative code vector energy exponent     */  | 
853  |  | 
  | 
854  | 0  |     pit_gain[pit_gain_index++] = FX_SGL2FX_DBL(gain_pit);  | 
855  |  |  | 
856  |  |     /* calc periodicity factor r_v */  | 
857  | 0  |     period_fac =  | 
858  | 0  |         calc_period_factor(/* (o) : factor (-1=unvoiced to 1=voiced)    */  | 
859  | 0  |                            &exc[i_subfr], /* (i) : pitch excitation, exponent =  | 
860  |  |                                              SF_EXC */  | 
861  | 0  |                            gain_pit,      /* (i) : gain of pitch, exponent =  | 
862  |  |                                              SF_GAIN_P */  | 
863  | 0  |                            gain_code,     /* (i) : gain of code     */  | 
864  | 0  |                            Ener_code,     /* (i) : Energy of code[]     */  | 
865  | 0  |                            Ener_code_e);  /* (i) : Exponent of energy of code[]  | 
866  |  |                                            */  | 
867  |  | 
  | 
868  | 0  |     if (lastLpcLost && frameCnt == 0) { | 
869  | 0  |       if (gain_pit > FL2FXCONST_SGL(1.0f / (1 << SF_GAIN_P))) { | 
870  | 0  |         gain_pit = FL2FXCONST_SGL(1.0f / (1 << SF_GAIN_P));  | 
871  | 0  |       }  | 
872  | 0  |     }  | 
873  |  | 
  | 
874  | 0  |     gain_code_smooth =  | 
875  | 0  |         noise_enhancer(/* (o) : smoothed gain g_sc exponent = SF_GAIN_C */  | 
876  | 0  |                        gain_code,  /* (i) : Quantized codebook gain  */  | 
877  | 0  |                        period_fac, /* (i) : periodicity factor (-1=unvoiced to  | 
878  |  |                                       1=voiced)  */  | 
879  | 0  |                        stab_fac,   /* (i) : stability factor (0 <= ... < 1),  | 
880  |  |                                       exponent = 1 */  | 
881  | 0  |                        &acelp_mem->gc_threshold);  | 
882  |  |  | 
883  |  |     /* Compute adaptive codebook update u'(n), pitch enhancement c'(n) and  | 
884  |  |      * post-processed excitation u(n). */  | 
885  | 0  |     BuildAdaptiveExcitation(code, exc + i_subfr, gain_pit, gain_code,  | 
886  | 0  |                             gain_code_smooth, period_fac, exc2);  | 
887  |  |  | 
888  |  |     /* Interpolate filter coeffs for current subframe in lsp domain and convert  | 
889  |  |      * to LP domain */  | 
890  | 0  |     int_lpc_acelp(lsp_old,  /* input : LSPs from past frame              */  | 
891  | 0  |                   lsp_new,  /* input : LSPs from present frame           */  | 
892  | 0  |                   subfr_nr, /* input : ACELP subframe index              */  | 
893  | 0  |                   coreCoderFrameLength / L_DIV,  | 
894  | 0  |                   A, /* output: LP coefficients of this subframe  */  | 
895  | 0  |                   &A_exp);  | 
896  |  | 
  | 
897  | 0  |     Syn_filt(A, /* (i) : a[m] prediction coefficients               */  | 
898  | 0  |              A_exp, L_SUBFR, /* (i) : length */  | 
899  | 0  |              exc2, /* (i) : input signal                               */  | 
900  | 0  |              &syn[i_subfr] /* (i/o) : filter states / output signal */  | 
901  | 0  |     );  | 
902  |  | 
  | 
903  | 0  |   } /* end of subframe loop */  | 
904  |  |  | 
905  |  |   /* update pitch value for bfi procedure */  | 
906  | 0  |   acelp_mem->old_T0_frac = T0_frac;  | 
907  | 0  |   acelp_mem->old_T0 = T0;  | 
908  |  |  | 
909  |  |   /* save old excitation and old synthesis memory for next ACELP frame */  | 
910  | 0  |   FDKmemcpy(acelp_mem->old_exc_mem, exc + l_div - (PIT_MAX_MAX + L_INTERPOL),  | 
911  | 0  |             sizeof(FIXP_DBL) * (PIT_MAX_MAX + L_INTERPOL));  | 
912  | 0  |   FDKmemcpy(acelp_mem->old_syn_mem, syn_buf + l_div,  | 
913  | 0  |             sizeof(FIXP_DBL) * M_LP_FILTER_ORDER);  | 
914  |  | 
  | 
915  | 0  |   Deemph(syn, synth, l_div,  | 
916  | 0  |          &acelp_mem->de_emph_mem); /* ref soft: mem = synth[-1] */  | 
917  |  | 
  | 
918  | 0  |   scaleValues(synth, l_div, -ACELP_OUTSCALE);  | 
919  | 0  |   acelp_mem->deemph_mem_wsyn = acelp_mem->de_emph_mem;  | 
920  |  | 
  | 
921  | 0  |   C_ALLOC_SCRATCH_END(tmp_buf, FIXP_DBL, L_SUBFR);  | 
922  | 0  |   C_ALLOC_SCRATCH_END(syn_buf, FIXP_DBL, M_LP_FILTER_ORDER + L_DIV);  | 
923  | 0  |   C_ALLOC_SCRATCH_END(exc_buf, FIXP_DBL, PIT_MAX_MAX + L_INTERPOL + L_DIV + 1);  | 
924  | 0  |   return;  | 
925  | 0  | }  | 
926  |  |  | 
927  | 0  | void CLpd_AcelpReset(CAcelpStaticMem *acelp) { | 
928  | 0  |   acelp->gc_threshold = (FIXP_DBL)0;  | 
929  |  | 
  | 
930  | 0  |   acelp->past_gpit = (FIXP_SGL)0;  | 
931  | 0  |   acelp->past_gcode = (FIXP_DBL)0;  | 
932  | 0  |   acelp->old_T0 = 64;  | 
933  | 0  |   acelp->old_T0_frac = 0;  | 
934  | 0  |   acelp->deemph_mem_wsyn = (FIXP_DBL)0;  | 
935  | 0  |   acelp->wsyn_rms = (FIXP_DBL)0;  | 
936  | 0  |   acelp->seed_ace = 0;  | 
937  | 0  | }  | 
938  |  |  | 
939  |  | /* TCX time domain concealment */  | 
940  |  | /*   Compare to figure 13a on page 54 in 3GPP TS 26.290 */  | 
941  |  | void CLpd_TcxTDConceal(CAcelpStaticMem *acelp_mem, SHORT *pitch,  | 
942  |  |                        const FIXP_LPC lsp_old[M_LP_FILTER_ORDER],  | 
943  |  |                        const FIXP_LPC lsp_new[M_LP_FILTER_ORDER],  | 
944  |  |                        const FIXP_SGL stab_fac, INT nLostSf, FIXP_DBL synth[],  | 
945  | 0  |                        INT coreCoderFrameLength, UCHAR last_tcx_noise_factor) { | 
946  |  |   /* repeat past excitation with pitch from previous decoded TCX frame */  | 
947  | 0  |   C_ALLOC_SCRATCH_START(  | 
948  | 0  |       exc_buf, FIXP_DBL,  | 
949  | 0  |       PIT_MAX_MAX + L_INTERPOL + L_DIV); /* 411 +  17 + 256 + 1 =  */  | 
950  | 0  |   C_ALLOC_SCRATCH_START(syn_buf, FIXP_DBL,  | 
951  | 0  |                         M_LP_FILTER_ORDER + L_DIV); /* 256 +  16           =  */  | 
952  |  |                                                     /*                    +=  */  | 
953  | 0  |   FIXP_DBL ns_buf[L_DIV + 1];  | 
954  | 0  |   FIXP_DBL *syn = syn_buf + M_LP_FILTER_ORDER;  | 
955  | 0  |   FIXP_DBL *exc = exc_buf + PIT_MAX_MAX + L_INTERPOL;  | 
956  | 0  |   FIXP_DBL *ns = ns_buf + 1;  | 
957  | 0  |   FIXP_DBL tmp, fact_exc;  | 
958  | 0  |   INT T = fMin(*pitch, (SHORT)PIT_MAX_MAX);  | 
959  | 0  |   int i, i_subfr, subfr_nr;  | 
960  | 0  |   int lDiv = coreCoderFrameLength / NB_DIV;  | 
961  |  | 
  | 
962  | 0  |   FDKmemcpy(syn_buf, acelp_mem->old_syn_mem,  | 
963  | 0  |             M_LP_FILTER_ORDER * sizeof(FIXP_DBL));  | 
964  | 0  |   FDKmemcpy(exc_buf, acelp_mem->old_exc_mem,  | 
965  | 0  |             (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));  | 
966  |  |  | 
967  |  |   /* if we lost all packets (i.e. 1 packet of TCX-20 ms, 2 packets of  | 
968  |  |      the TCX-40 ms or 4 packets of the TCX-80ms), we lost the whole  | 
969  |  |      coded frame extrapolation strategy: repeat lost excitation and  | 
970  |  |      use extrapolated LSFs */  | 
971  |  |  | 
972  |  |   /* AMR-WB+ like TCX TD concealment */  | 
973  |  |  | 
974  |  |   /* number of lost frame cmpt */  | 
975  | 0  |   if (nLostSf < 2) { | 
976  | 0  |     fact_exc = FL2FXCONST_DBL(0.8f);  | 
977  | 0  |   } else { | 
978  | 0  |     fact_exc = FL2FXCONST_DBL(0.4f);  | 
979  | 0  |   }  | 
980  |  |  | 
981  |  |   /* repeat past excitation */  | 
982  | 0  |   for (i = 0; i < lDiv; i++) { | 
983  | 0  |     exc[i] = fMult(fact_exc, exc[i - T]);  | 
984  | 0  |   }  | 
985  |  | 
  | 
986  | 0  |   tmp = fMult(fact_exc, acelp_mem->wsyn_rms);  | 
987  | 0  |   acelp_mem->wsyn_rms = tmp;  | 
988  |  |  | 
989  |  |   /* init deemph_mem_wsyn */  | 
990  | 0  |   acelp_mem->deemph_mem_wsyn = exc[-1];  | 
991  |  | 
  | 
992  | 0  |   ns[-1] = acelp_mem->deemph_mem_wsyn;  | 
993  |  | 
  | 
994  | 0  |   for (i_subfr = 0, subfr_nr = 0; i_subfr < lDiv;  | 
995  | 0  |        i_subfr += L_SUBFR, subfr_nr++) { | 
996  | 0  |     FIXP_DBL tRes[L_SUBFR];  | 
997  | 0  |     FIXP_LPC A[M_LP_FILTER_ORDER];  | 
998  | 0  |     INT A_exp;  | 
999  |  |  | 
1000  |  |     /* interpolate LPC coefficients */  | 
1001  | 0  |     int_lpc_acelp(lsp_old, lsp_new, subfr_nr, lDiv / L_SUBFR, A, &A_exp);  | 
1002  |  | 
  | 
1003  | 0  |     Syn_filt(A,              /* (i) : a[m] prediction coefficients         */  | 
1004  | 0  |              A_exp, L_SUBFR, /* (i) : length                               */  | 
1005  | 0  |              &exc[i_subfr],  /* (i) : input signal                         */  | 
1006  | 0  |              &syn[i_subfr]   /* (i/o) : filter states / output signal      */  | 
1007  | 0  |     );  | 
1008  |  | 
  | 
1009  | 0  |     E_LPC_a_weight(  | 
1010  | 0  |         A, A,  | 
1011  | 0  |         M_LP_FILTER_ORDER); /* overwrite A as it is not needed any longer */  | 
1012  |  | 
  | 
1013  | 0  |     E_UTIL_residu(A, A_exp, &syn[i_subfr], tRes, L_SUBFR);  | 
1014  |  | 
  | 
1015  | 0  |     Deemph(tRes, &ns[i_subfr], L_SUBFR, &acelp_mem->deemph_mem_wsyn);  | 
1016  |  |  | 
1017  |  |     /* Amplitude limiter (saturate at wsyn_rms) */  | 
1018  | 0  |     for (i = i_subfr; i < i_subfr + L_SUBFR; i++) { | 
1019  | 0  |       if (ns[i] > tmp) { | 
1020  | 0  |         ns[i] = tmp;  | 
1021  | 0  |       } else { | 
1022  | 0  |         if (ns[i] < -tmp) { | 
1023  | 0  |           ns[i] = -tmp;  | 
1024  | 0  |         }  | 
1025  | 0  |       }  | 
1026  | 0  |     }  | 
1027  |  | 
  | 
1028  | 0  |     E_UTIL_preemph(&ns[i_subfr], tRes, L_SUBFR);  | 
1029  |  | 
  | 
1030  | 0  |     Syn_filt(A,              /* (i) : a[m] prediction coefficients         */  | 
1031  | 0  |              A_exp, L_SUBFR, /* (i) : length                               */  | 
1032  | 0  |              tRes,           /* (i) : input signal                         */  | 
1033  | 0  |              &syn[i_subfr]   /* (i/o) : filter states / output signal      */  | 
1034  | 0  |     );  | 
1035  |  | 
  | 
1036  | 0  |     FDKmemmove(&synth[i_subfr], &syn[i_subfr], L_SUBFR * sizeof(FIXP_DBL));  | 
1037  | 0  |   }  | 
1038  |  |  | 
1039  |  |   /* save old excitation and old synthesis memory for next ACELP frame */  | 
1040  | 0  |   FDKmemcpy(acelp_mem->old_exc_mem, exc + lDiv - (PIT_MAX_MAX + L_INTERPOL),  | 
1041  | 0  |             sizeof(FIXP_DBL) * (PIT_MAX_MAX + L_INTERPOL));  | 
1042  | 0  |   FDKmemcpy(acelp_mem->old_syn_mem, syn_buf + lDiv,  | 
1043  | 0  |             sizeof(FIXP_DBL) * M_LP_FILTER_ORDER);  | 
1044  | 0  |   acelp_mem->de_emph_mem = acelp_mem->deemph_mem_wsyn;  | 
1045  |  | 
  | 
1046  | 0  |   C_ALLOC_SCRATCH_END(syn_buf, FIXP_DBL, M_LP_FILTER_ORDER + L_DIV);  | 
1047  | 0  |   C_ALLOC_SCRATCH_END(exc_buf, FIXP_DBL, PIT_MAX_MAX + L_INTERPOL + L_DIV);  | 
1048  | 0  | }  | 
1049  |  |  | 
1050  |  | void Acelp_PreProcessing(FIXP_DBL *synth_buf, FIXP_DBL *old_synth, INT *pitch,  | 
1051  |  |                          INT *old_T_pf, FIXP_DBL *pit_gain,  | 
1052  |  |                          FIXP_DBL *old_gain_pf, INT samplingRate, INT *i_offset,  | 
1053  |  |                          INT coreCoderFrameLength, INT synSfd,  | 
1054  | 0  |                          INT nbSubfrSuperfr) { | 
1055  | 0  |   int n;  | 
1056  |  |  | 
1057  |  |   /* init beginning of synth_buf with old synthesis from previous frame */  | 
1058  | 0  |   FDKmemcpy(synth_buf, old_synth, sizeof(FIXP_DBL) * (PIT_MAX_MAX - BPF_DELAY));  | 
1059  |  |  | 
1060  |  |   /* calculate pitch lag offset for ACELP decoder */  | 
1061  | 0  |   *i_offset =  | 
1062  | 0  |       (samplingRate * PIT_MIN_12k8 + (FSCALE_DENOM / 2)) / FSCALE_DENOM -  | 
1063  | 0  |       PIT_MIN_12k8;  | 
1064  |  |  | 
1065  |  |   /* for bass postfilter */  | 
1066  | 0  |   for (n = 0; n < synSfd; n++) { | 
1067  | 0  |     pitch[n] = old_T_pf[n];  | 
1068  | 0  |     pit_gain[n] = old_gain_pf[n];  | 
1069  | 0  |   }  | 
1070  | 0  |   for (n = 0; n < nbSubfrSuperfr; n++) { | 
1071  | 0  |     pitch[n + synSfd] = L_SUBFR;  | 
1072  | 0  |     pit_gain[n + synSfd] = (FIXP_DBL)0;  | 
1073  | 0  |   }  | 
1074  | 0  | }  | 
1075  |  |  | 
1076  |  | void Acelp_PostProcessing(FIXP_DBL *synth_buf, FIXP_DBL *old_synth, INT *pitch,  | 
1077  |  |                           INT *old_T_pf, INT coreCoderFrameLength, INT synSfd,  | 
1078  | 0  |                           INT nbSubfrSuperfr) { | 
1079  | 0  |   int n;  | 
1080  |  |  | 
1081  |  |   /* store last part of synth_buf (which is not handled by the IMDCT overlap)  | 
1082  |  |    * for next frame */  | 
1083  | 0  |   FDKmemcpy(old_synth, synth_buf + coreCoderFrameLength,  | 
1084  | 0  |             sizeof(FIXP_DBL) * (PIT_MAX_MAX - BPF_DELAY));  | 
1085  |  |  | 
1086  |  |   /* for bass postfilter */  | 
1087  | 0  |   for (n = 0; n < synSfd; n++) { | 
1088  | 0  |     old_T_pf[n] = pitch[nbSubfrSuperfr + n];  | 
1089  | 0  |   }  | 
1090  | 0  | }  | 
1091  |  |  | 
1092  | 0  | #define L_FAC_ZIR (LFAC)  | 
1093  |  |  | 
1094  |  | void CLpd_Acelp_Zir(const FIXP_LPC A[], const INT A_exp,  | 
1095  |  |                     CAcelpStaticMem *acelp_mem, const INT length,  | 
1096  | 0  |                     FIXP_DBL zir[], int doDeemph) { | 
1097  | 0  |   C_ALLOC_SCRATCH_START(tmp_buf, FIXP_DBL, L_FAC_ZIR + M_LP_FILTER_ORDER);  | 
1098  | 0  |   FDK_ASSERT(length <= L_FAC_ZIR);  | 
1099  |  |  | 
1100  | 0  |   FDKmemcpy(tmp_buf, acelp_mem->old_syn_mem,  | 
1101  | 0  |             M_LP_FILTER_ORDER * sizeof(FIXP_DBL));  | 
1102  | 0  |   FDKmemset(tmp_buf + M_LP_FILTER_ORDER, 0, L_FAC_ZIR * sizeof(FIXP_DBL));  | 
1103  |  | 
  | 
1104  | 0  |   Syn_filt(A, A_exp, length, &tmp_buf[M_LP_FILTER_ORDER],  | 
1105  | 0  |            &tmp_buf[M_LP_FILTER_ORDER]);  | 
1106  | 0  |   if (!doDeemph) { | 
1107  |  |     /* if last lpd mode was TD concealment, then bypass deemph */  | 
1108  | 0  |     FDKmemcpy(zir, tmp_buf, length * sizeof(*zir));  | 
1109  | 0  |   } else { | 
1110  | 0  |     Deemph(&tmp_buf[M_LP_FILTER_ORDER], &zir[0], length,  | 
1111  | 0  |            &acelp_mem->de_emph_mem);  | 
1112  | 0  |     scaleValues(zir, length, -ACELP_OUTSCALE);  | 
1113  | 0  |   }  | 
1114  | 0  |   C_ALLOC_SCRATCH_END(tmp_buf, FIXP_DBL, L_FAC_ZIR + M_LP_FILTER_ORDER);  | 
1115  | 0  | }  | 
1116  |  |  | 
1117  |  | void CLpd_AcelpPrepareInternalMem(const FIXP_DBL *synth, UCHAR last_lpd_mode,  | 
1118  |  |                                   UCHAR last_last_lpd_mode,  | 
1119  |  |                                   const FIXP_LPC *A_new, const INT A_new_exp,  | 
1120  |  |                                   const FIXP_LPC *A_old, const INT A_old_exp,  | 
1121  |  |                                   CAcelpStaticMem *acelp_mem,  | 
1122  |  |                                   INT coreCoderFrameLength, INT clearOldExc,  | 
1123  | 0  |                                   UCHAR lpd_mode) { | 
1124  | 0  |   int l_div =  | 
1125  | 0  |       coreCoderFrameLength / NB_DIV; /* length of one ACELP/TCX20 frame */  | 
1126  | 0  |   int l_div_partial;  | 
1127  | 0  |   FIXP_DBL *syn, *old_exc_mem;  | 
1128  |  | 
  | 
1129  | 0  |   C_ALLOC_SCRATCH_START(synth_buf, FIXP_DBL,  | 
1130  | 0  |                         PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);  | 
1131  | 0  |   syn = &synth_buf[M_LP_FILTER_ORDER];  | 
1132  |  | 
  | 
1133  | 0  |   l_div_partial = PIT_MAX_MAX + L_INTERPOL - l_div;  | 
1134  | 0  |   old_exc_mem = acelp_mem->old_exc_mem;  | 
1135  |  | 
  | 
1136  | 0  |   if (lpd_mode == 4) { | 
1137  |  |     /* Bypass Domain conversion. TCXTD Concealment does no deemphasis in the  | 
1138  |  |      * end. */  | 
1139  | 0  |     FDKmemcpy(  | 
1140  | 0  |         synth_buf, &synth[-(PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER)],  | 
1141  | 0  |         (PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER) * sizeof(FIXP_DBL));  | 
1142  |  |     /* Set deemphasis memory state for TD concealment */  | 
1143  | 0  |     acelp_mem->deemph_mem_wsyn = scaleValueSaturate(synth[-1], ACELP_OUTSCALE);  | 
1144  | 0  |   } else { | 
1145  |  |     /* convert past [PIT_MAX_MAX+L_INTERPOL+M_LP_FILTER_ORDER] synthesis to  | 
1146  |  |      * preemph domain */  | 
1147  | 0  |     E_UTIL_preemph(&synth[-(PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER)],  | 
1148  | 0  |                    synth_buf, PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);  | 
1149  | 0  |     scaleValuesSaturate(synth_buf, PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER,  | 
1150  | 0  |                         ACELP_OUTSCALE);  | 
1151  | 0  |   }  | 
1152  |  |  | 
1153  |  |   /* Set deemphasis memory state */  | 
1154  | 0  |   acelp_mem->de_emph_mem = scaleValueSaturate(synth[-1], ACELP_OUTSCALE);  | 
1155  |  |  | 
1156  |  |   /* update acelp synth filter memory */  | 
1157  | 0  |   FDKmemcpy(acelp_mem->old_syn_mem,  | 
1158  | 0  |             &syn[PIT_MAX_MAX + L_INTERPOL - M_LP_FILTER_ORDER],  | 
1159  | 0  |             M_LP_FILTER_ORDER * sizeof(FIXP_DBL));  | 
1160  |  | 
  | 
1161  | 0  |   if (clearOldExc) { | 
1162  | 0  |     FDKmemclear(old_exc_mem, (PIT_MAX_MAX + L_INTERPOL) * sizeof(FIXP_DBL));  | 
1163  | 0  |     C_ALLOC_SCRATCH_END(synth_buf, FIXP_DBL,  | 
1164  | 0  |                         PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);  | 
1165  | 0  |     return;  | 
1166  | 0  |   }  | 
1167  |  |  | 
1168  |  |   /* update past [PIT_MAX_MAX+L_INTERPOL] samples of exc memory */  | 
1169  | 0  |   if (last_lpd_mode == 1) {        /* last frame was TCX20 */ | 
1170  | 0  |     if (last_last_lpd_mode == 0) { /* ACELP -> TCX20 -> ACELP transition */ | 
1171  |  |       /* Delay valid part of excitation buffer (from previous ACELP frame) by  | 
1172  |  |        * l_div samples */  | 
1173  | 0  |       FDKmemmove(old_exc_mem, old_exc_mem + l_div,  | 
1174  | 0  |                  sizeof(FIXP_DBL) * l_div_partial);  | 
1175  | 0  |     } else if (last_last_lpd_mode > 0) { /* TCX -> TCX20 -> ACELP transition */ | 
1176  | 0  |       E_UTIL_residu(A_old, A_old_exp, syn, old_exc_mem, l_div_partial);  | 
1177  | 0  |     }  | 
1178  | 0  |     E_UTIL_residu(A_new, A_new_exp, syn + l_div_partial,  | 
1179  | 0  |                   old_exc_mem + l_div_partial, l_div);  | 
1180  | 0  |   } else { /* prev frame was FD, TCX40 or TCX80 */ | 
1181  | 0  |     int exc_A_new_length = (coreCoderFrameLength / 2 > PIT_MAX_MAX + L_INTERPOL)  | 
1182  | 0  |                                ? PIT_MAX_MAX + L_INTERPOL  | 
1183  | 0  |                                : coreCoderFrameLength / 2;  | 
1184  | 0  |     int exc_A_old_length = PIT_MAX_MAX + L_INTERPOL - exc_A_new_length;  | 
1185  | 0  |     E_UTIL_residu(A_old, A_old_exp, syn, old_exc_mem, exc_A_old_length);  | 
1186  | 0  |     E_UTIL_residu(A_new, A_new_exp, &syn[exc_A_old_length],  | 
1187  | 0  |                   &old_exc_mem[exc_A_old_length], exc_A_new_length);  | 
1188  | 0  |   }  | 
1189  | 0  |   C_ALLOC_SCRATCH_END(synth_buf, FIXP_DBL,  | 
1190  | 0  |                       PIT_MAX_MAX + L_INTERPOL + M_LP_FILTER_ORDER);  | 
1191  |  | 
  | 
1192  | 0  |   return;  | 
1193  | 0  | }  | 
1194  |  |  | 
1195  | 0  | FIXP_DBL *CLpd_ACELP_GetFreeExcMem(CAcelpStaticMem *acelp_mem, INT length) { | 
1196  | 0  |   FDK_ASSERT(length <= PIT_MAX_MAX + L_INTERPOL);  | 
1197  | 0  |   return acelp_mem->old_exc_mem;  | 
1198  | 0  | }  | 
1199  |  |  | 
1200  |  | INT CLpd_AcelpRead(HANDLE_FDK_BITSTREAM hBs, CAcelpChannelData *acelp,  | 
1201  |  |                    INT acelp_core_mode, INT coreCoderFrameLength,  | 
1202  | 0  |                    INT i_offset) { | 
1203  | 0  |   int nb_subfr = coreCoderFrameLength / L_DIV;  | 
1204  | 0  |   const UCHAR *num_acb_index_bits =  | 
1205  | 0  |       (nb_subfr == 4) ? num_acb_idx_bits_table[0] : num_acb_idx_bits_table[1];  | 
1206  | 0  |   int nbits;  | 
1207  | 0  |   int error = 0;  | 
1208  |  | 
  | 
1209  | 0  |   const int PIT_MIN = PIT_MIN_12k8 + i_offset;  | 
1210  | 0  |   const int PIT_FR2 = PIT_FR2_12k8 - i_offset;  | 
1211  | 0  |   const int PIT_FR1 = PIT_FR1_12k8;  | 
1212  | 0  |   const int PIT_MAX = PIT_MAX_12k8 + (6 * i_offset);  | 
1213  | 0  |   int T0, T0_frac, T0_min = 0, T0_max;  | 
1214  |  | 
  | 
1215  | 0  |   if (PIT_MAX > PIT_MAX_MAX) { | 
1216  | 0  |     error = AAC_DEC_DECODE_FRAME_ERROR;  | 
1217  | 0  |     goto bail;  | 
1218  | 0  |   }  | 
1219  |  |  | 
1220  | 0  |   acelp->acelp_core_mode = acelp_core_mode;  | 
1221  |  | 
  | 
1222  | 0  |   nbits = MapCoreMode2NBits(acelp_core_mode);  | 
1223  |  |  | 
1224  |  |   /* decode mean energy with 2 bits : 18, 30, 42 or 54 dB */  | 
1225  | 0  |   acelp->mean_energy = FDKreadBits(hBs, 2);  | 
1226  |  | 
  | 
1227  | 0  |   for (int sfr = 0; sfr < nb_subfr; sfr++) { | 
1228  |  |     /* read ACB index and store T0 and T0_frac for each ACELP subframe. */  | 
1229  | 0  |     error = DecodePitchLag(hBs, num_acb_index_bits[sfr], PIT_MIN, PIT_FR2,  | 
1230  | 0  |                            PIT_FR1, PIT_MAX, &T0, &T0_frac, &T0_min, &T0_max);  | 
1231  | 0  |     if (error) { | 
1232  | 0  |       goto bail;  | 
1233  | 0  |     }  | 
1234  | 0  |     acelp->T0[sfr] = (USHORT)T0;  | 
1235  | 0  |     acelp->T0_frac[sfr] = (UCHAR)T0_frac;  | 
1236  | 0  |     acelp->ltp_filtering_flag[sfr] = FDKreadBits(hBs, 1);  | 
1237  | 0  |     switch (nbits) { | 
1238  | 0  |       case 12: /* 12 bits AMR-WB codebook is used */  | 
1239  | 0  |         acelp->icb_index[sfr][0] = FDKreadBits(hBs, 1);  | 
1240  | 0  |         acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);  | 
1241  | 0  |         acelp->icb_index[sfr][2] = FDKreadBits(hBs, 1);  | 
1242  | 0  |         acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);  | 
1243  | 0  |         break;  | 
1244  | 0  |       case 16: /* 16 bits AMR-WB codebook is used */  | 
1245  | 0  |         acelp->icb_index[sfr][0] = FDKreadBits(hBs, 1);  | 
1246  | 0  |         acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);  | 
1247  | 0  |         acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);  | 
1248  | 0  |         acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);  | 
1249  | 0  |         break;  | 
1250  | 0  |       case 20: /* 20 bits AMR-WB codebook is used */  | 
1251  | 0  |         acelp->icb_index[sfr][0] = FDKreadBits(hBs, 5);  | 
1252  | 0  |         acelp->icb_index[sfr][1] = FDKreadBits(hBs, 5);  | 
1253  | 0  |         acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);  | 
1254  | 0  |         acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);  | 
1255  | 0  |         break;  | 
1256  | 0  |       case 28: /* 28 bits AMR-WB codebook is used */  | 
1257  | 0  |         acelp->icb_index[sfr][0] = FDKreadBits(hBs, 9);  | 
1258  | 0  |         acelp->icb_index[sfr][1] = FDKreadBits(hBs, 9);  | 
1259  | 0  |         acelp->icb_index[sfr][2] = FDKreadBits(hBs, 5);  | 
1260  | 0  |         acelp->icb_index[sfr][3] = FDKreadBits(hBs, 5);  | 
1261  | 0  |         break;  | 
1262  | 0  |       case 36: /* 36 bits AMR-WB codebook is used */  | 
1263  | 0  |         acelp->icb_index[sfr][0] = FDKreadBits(hBs, 9);  | 
1264  | 0  |         acelp->icb_index[sfr][1] = FDKreadBits(hBs, 9);  | 
1265  | 0  |         acelp->icb_index[sfr][2] = FDKreadBits(hBs, 9);  | 
1266  | 0  |         acelp->icb_index[sfr][3] = FDKreadBits(hBs, 9);  | 
1267  | 0  |         break;  | 
1268  | 0  |       case 44: /* 44 bits AMR-WB codebook is used */  | 
1269  | 0  |         acelp->icb_index[sfr][0] = FDKreadBits(hBs, 13);  | 
1270  | 0  |         acelp->icb_index[sfr][1] = FDKreadBits(hBs, 13);  | 
1271  | 0  |         acelp->icb_index[sfr][2] = FDKreadBits(hBs, 9);  | 
1272  | 0  |         acelp->icb_index[sfr][3] = FDKreadBits(hBs, 9);  | 
1273  | 0  |         break;  | 
1274  | 0  |       case 52: /* 52 bits AMR-WB codebook is used */  | 
1275  | 0  |         acelp->icb_index[sfr][0] = FDKreadBits(hBs, 13);  | 
1276  | 0  |         acelp->icb_index[sfr][1] = FDKreadBits(hBs, 13);  | 
1277  | 0  |         acelp->icb_index[sfr][2] = FDKreadBits(hBs, 13);  | 
1278  | 0  |         acelp->icb_index[sfr][3] = FDKreadBits(hBs, 13);  | 
1279  | 0  |         break;  | 
1280  | 0  |       case 64: /* 64 bits AMR-WB codebook is used */  | 
1281  | 0  |         acelp->icb_index[sfr][0] = FDKreadBits(hBs, 2);  | 
1282  | 0  |         acelp->icb_index[sfr][1] = FDKreadBits(hBs, 2);  | 
1283  | 0  |         acelp->icb_index[sfr][2] = FDKreadBits(hBs, 2);  | 
1284  | 0  |         acelp->icb_index[sfr][3] = FDKreadBits(hBs, 2);  | 
1285  | 0  |         acelp->icb_index[sfr][4] = FDKreadBits(hBs, 14);  | 
1286  | 0  |         acelp->icb_index[sfr][5] = FDKreadBits(hBs, 14);  | 
1287  | 0  |         acelp->icb_index[sfr][6] = FDKreadBits(hBs, 14);  | 
1288  | 0  |         acelp->icb_index[sfr][7] = FDKreadBits(hBs, 14);  | 
1289  | 0  |         break;  | 
1290  | 0  |       default:  | 
1291  | 0  |         FDK_ASSERT(0);  | 
1292  | 0  |         break;  | 
1293  | 0  |     }  | 
1294  | 0  |     acelp->gains[sfr] = FDKreadBits(hBs, 7);  | 
1295  | 0  |   }  | 
1296  |  |  | 
1297  | 0  | bail:  | 
1298  | 0  |   return error;  | 
1299  | 0  | }  |