1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
18 /****************************************************************************************
19 Portions of this file are derived from the following 3GPP standard:
22 ANSI-C code for the Adaptive Multi-Rate - Wideband (AMR-WB) speech codec
23 Available from http://www.3gpp.org
25 (C) 2007, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
26 Permission to distribute, modify and use this file under the standard license
27 terms listed above has been obtained from the copyright holder.
28 ****************************************************************************************/
30 ------------------------------------------------------------------------------
34 Filename: dec_gain2_amr_wb.cpp
36 ------------------------------------------------------------------------------
37 INPUT AND OUTPUT DEFINITIONS
39 int16 index, (i) : index of quantization.
40 int16 nbits, (i) : number of bits (6 or 7)
41 int16 code[], (i) Q9 : Innovative vector.
42 int16 L_subfr, (i) : Subframe lenght.
43 int16 * gain_pit, (o) Q14 : Pitch gain.
44 int32 * gain_cod, (o) Q16 : Code gain.
45 int16 bfi, (i) : bad frame indicator
46 int16 prev_bfi, (i) : Previous BF indicator
47 int16 state, (i) : State of BFH
48 int16 unusable_frame, (i) : UF indicator
49 int16 vad_hist, (i) : number of non-speech frames
50 int16 * mem (i/o) : static memory (4 words)
52 ------------------------------------------------------------------------------
55 Decode the pitch and codebook gains
57 ------------------------------------------------------------------------------
61 ------------------------------------------------------------------------------
64 ------------------------------------------------------------------------------
67 ------------------------------------------------------------------------------
71 /*----------------------------------------------------------------------------
73 ----------------------------------------------------------------------------*/
76 #include "pv_amr_wb_type_defs.h"
77 #include "pvamrwbdecoder_basic_op.h"
78 #include "pvamrwb_math_op.h"
79 #include "pvamrwbdecoder_cnst.h"
80 #include "pvamrwbdecoder_acelp.h"
84 /*----------------------------------------------------------------------------
86 ; Define module specific macros here
87 ----------------------------------------------------------------------------*/
90 /*----------------------------------------------------------------------------
92 ; Include all pre-processor statements here. Include conditional
93 ; compile variables also.
94 ----------------------------------------------------------------------------*/
101 /*----------------------------------------------------------------------------
102 ; LOCAL FUNCTION DEFINITIONS
103 ; Function Prototype declaration
104 ----------------------------------------------------------------------------*/
106 /*----------------------------------------------------------------------------
107 ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
108 ; Variable declaration - defined here and used outside this module
109 ----------------------------------------------------------------------------*/
111 const int16 pdown_unusable[7] = {32767, 31130, 29491, 24576, 7537, 1638, 328};
112 const int16 cdown_unusable[7] = {32767, 16384, 8192, 8192, 8192, 4915, 3277};
114 const int16 pdown_usable[7] = {32767, 32113, 31457, 24576, 7537, 1638, 328};
115 const int16 cdown_usable[7] = {32767, 32113, 32113, 32113, 32113, 32113, 22938};
118 /* MA prediction coeff ={0.5, 0.4, 0.3, 0.2} in Q13 */
119 const int16 pred[PRED_ORDER] = {4096, 3277, 2458, 1638};
121 /*----------------------------------------------------------------------------
122 ; EXTERNAL FUNCTION REFERENCES
123 ; Declare functions defined elsewhere and referenced in this module
124 ----------------------------------------------------------------------------*/
126 /*----------------------------------------------------------------------------
127 ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
128 ; Declare variables used in this module but defined elsewhere
129 ----------------------------------------------------------------------------*/
131 /*----------------------------------------------------------------------------
133 ----------------------------------------------------------------------------*/
136 /* output :static memory (4 words) */
137 void dec_gain2_amr_wb_init(int16 * mem)
140 /* 4nd order quantizer energy predictor (init to -14.0 in Q10) */
141 mem[0] = -14336; /* past_qua_en[0] */
142 mem[1] = -14336; /* past_qua_en[1] */
143 mem[2] = -14336; /* past_qua_en[2] */
144 mem[3] = -14336; /* past_qua_en[3] */
145 /* 4 *past_gain_pit */
146 /* 5 *past_gain_code */
151 pv_memset((void *)&mem[4], 0, 18*sizeof(*mem));
157 /*----------------------------------------------------------------------------
159 ----------------------------------------------------------------------------*/
161 void dec_gain2_amr_wb(
162 int16 index, /* (i) : index of quantization. */
163 int16 nbits, /* (i) : number of bits (6 or 7) */
164 int16 code[], /* (i) Q9 : Innovative vector. */
165 int16 L_subfr, /* (i) : Subframe lenght. */
166 int16 * gain_pit, /* (o) Q14 : Pitch gain. */
167 int32 * gain_cod, /* (o) Q16 : Code gain. */
168 int16 bfi, /* (i) : bad frame indicator */
169 int16 prev_bfi, /* (i) : Previous BF indicator */
170 int16 state, /* (i) : State of BFH */
171 int16 unusable_frame, /* (i) : UF indicator */
172 int16 vad_hist, /* (i) : number of non-speech frames */
173 int16 * mem /* (i/o) : static memory (4 words) */
177 int16 *past_gain_pit, *past_gain_code, *past_qua_en, *gbuf, *pbuf, *prev_gc;
179 int16 i, tmp, exp, frac, gcode0, exp_gcode0, qua_ener, gcode_inov;
185 past_gain_pit = mem + 4;
186 past_gain_code = mem + 5;
193 * Find energy of code and compute:
195 * L_tmp = 1.0 / sqrt(energy of code/ L_subfr)
198 L_tmp = Dot_product12(code, code, L_subfr, &exp);
199 exp -= 24; /* exp: -18 (code in Q9), -6 (/L_subfr) */
201 one_ov_sqrt_norm(&L_tmp, &exp);
203 gcode_inov = extract_h(shl_int32(L_tmp, exp - 3)); /* g_code_inov in Q12 */
211 tmp = median5(&pbuf[2]);
212 *past_gain_pit = tmp;
214 if (*past_gain_pit > 15565)
216 *past_gain_pit = 15565; /* 0.95 in Q14 */
220 if (unusable_frame != 0)
222 *gain_pit = mult_int16(pdown_unusable[state], *past_gain_pit);
226 *gain_pit = mult_int16(pdown_usable[state], *past_gain_pit);
228 tmp = median5(&gbuf[2]);
232 *past_gain_code = tmp;
237 if (unusable_frame != 0)
239 *past_gain_code = mult_int16(cdown_unusable[state], tmp);
243 *past_gain_code = mult_int16(cdown_usable[state], tmp);
247 /* update table of past quantized energies */
249 tmp = past_qua_en[3];
250 tmp1 = past_qua_en[2];
253 past_qua_en[3] = tmp;
254 tmp = past_qua_en[1];
255 tmp1 = past_qua_en[0];
258 past_qua_en[2] = tmp;
259 qua_ener = (int16)(L_tmp >> 3);
260 past_qua_en[1] = tmp1;
263 qua_ener -= 3072; /* -3 in Q10 */
265 if (qua_ener < -14336)
267 qua_ener = -14336; /* -14 in Q10 */
270 past_qua_en[0] = qua_ener;
273 for (i = 1; i < 5; i++)
275 gbuf[i - 1] = gbuf[i];
276 pbuf[i - 1] = pbuf[i];
278 gbuf[4] = *past_gain_code;
279 pbuf[4] = *past_gain_pit;
282 /* adjust gain according to energy of code */
283 /* past_gain_code(Q3) * gcode_inov(Q12) => Q16 */
284 *gain_cod = mul_16by16_to_int32(*past_gain_code, gcode_inov);
290 * = Sum(i=0,1) pred[i]*past_qua_en[i] + mean_ener - ener_code
293 L_tmp = L_deposit_h(MEAN_ENER); /* MEAN_ENER in Q16 */
294 L_tmp = shl_int32(L_tmp, 8); /* From Q16 to Q24 */
295 L_tmp = mac_16by16_to_int32(L_tmp, pred[0], past_qua_en[0]); /* Q13*Q10 -> Q24 */
296 L_tmp = mac_16by16_to_int32(L_tmp, pred[1], past_qua_en[1]); /* Q13*Q10 -> Q24 */
297 L_tmp = mac_16by16_to_int32(L_tmp, pred[2], past_qua_en[2]); /* Q13*Q10 -> Q24 */
298 L_tmp = mac_16by16_to_int32(L_tmp, pred[3], past_qua_en[3]); /* Q13*Q10 -> Q24 */
300 gcode0 = extract_h(L_tmp); /* From Q24 to Q8 */
303 * gcode0 = pow(10.0, gcode0/20)
304 * = pow(2, 3.321928*gcode0/20)
305 * = pow(2, 0.166096*gcode0)
308 L_tmp = ((int32)gcode0 * 5443) >> 7; /* *0.166096 in Q15 -> Q24 */
310 int32_to_dpf(L_tmp, &exp_gcode0, &frac); /* Extract exponant of gcode0 */
312 gcode0 = (int16)(power_of_2(14, frac)); /* Put 14 as exponant so that */
313 /* output of Pow2() will be: */
314 /* 16384 < Pow2() <= 32767 */
317 /* Read the quantized gains */
321 p = &t_qua_gain6b[index<<1];
325 p = &t_qua_gain7b[index<<1];
327 *gain_pit = *p++; /* selected pitch gain in Q14 */
328 g_code = *p++; /* selected code gain in Q11 */
330 L_tmp = mul_16by16_to_int32(g_code, gcode0); /* Q11*Q0 -> Q12 */
331 L_tmp = shl_int32(L_tmp, exp_gcode0 + 4); /* Q12 -> Q16 */
333 *gain_cod = L_tmp; /* gain of code in Q16 */
337 L_tmp = mul_16by16_to_int32(*prev_gc, 5120); /* prev_gc(Q3) * 1.25(Q12) = Q16 */
338 /* if((*gain_cod > ((*prev_gc) * 1.25)) && (*gain_cod > 100.0)) */
340 if ((*gain_cod > L_tmp) && (*gain_cod > 6553600))
345 /* keep past gain code in Q3 for frame erasure (can saturate) */
346 *past_gain_code = amr_wb_round(shl_int32(*gain_cod, 3));
347 *past_gain_pit = *gain_pit;
350 *prev_gc = *past_gain_code;
354 for (i = 1; i < 5; i++)
363 gbuf[4] = *past_gain_code;
364 pbuf[4] = *past_gain_pit;
365 pbuf2[4] = *past_gain_pit;
368 /* adjust gain according to energy of code */
369 int32_to_dpf(*gain_cod, &exp, &frac);
370 L_tmp = mul_32by16(exp, frac, gcode_inov);
372 *gain_cod = shl_int32(L_tmp, 3); /* gcode_inov in Q12 */
375 past_qua_en[3] = past_qua_en[2];
376 past_qua_en[2] = past_qua_en[1];
377 past_qua_en[1] = past_qua_en[0];
380 * qua_ener = 20*log10(g_code)
381 * = 6.0206*log2(g_code)
382 * = 6.0206*(log2(g_codeQ11) - 11)
384 L_tmp = (int32)g_code;
385 amrwb_log_2(L_tmp, &exp, &frac);
387 L_tmp = mul_32by16(exp, frac, 24660); /* x 6.0206 in Q12 */
389 /* update table of past quantized energies */
391 past_qua_en[0] = (int16)(L_tmp >> 3); /* result in Q10 */