/src/aac/libAACdec/src/usacdec_acelp.cpp
Line | Count | Source (jump to first uncovered line) |
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 | } |