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