1e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/* 2e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Copyright 2003-2010, VisualOn, Inc. 3e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** 4e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Licensed under the Apache License, Version 2.0 (the "License"); 5e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** you may not use this file except in compliance with the License. 6e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** You may obtain a copy of the License at 7e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** 8e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** http://www.apache.org/licenses/LICENSE-2.0 9e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** 10e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** Unless required by applicable law or agreed to in writing, software 11e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** distributed under the License is distributed on an "AS IS" BASIS, 12e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** See the License for the specific language governing permissions and 14e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ** limitations under the License. 15e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard */ 16e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 17e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/************************************************************************** 18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* File: q_gain2.c * 19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* * 20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Description: * 21e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* Quantization of pitch and codebook gains. * 22e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* MA prediction is performed on the innovation energy (in dB with mean * 23e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* removed). * 24e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* An initial predicted gain, g_0, is first determined and the correction * 25e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* factor alpha = gain / g_0 is quantized. * 26e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* The pitch gain and the correction factor are vector quantized and the * 27e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard* mean-squared weighted error criterion is used in the quantizer search. * 28e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard****************************************************************************/ 29e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 30e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "typedef.h" 31e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "basic_op.h" 32e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "oper_32b.h" 33e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "math_op.h" 34e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "log2.h" 35e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "acelp.h" 36e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "q_gain2.tab" 37e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 38e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define MEAN_ENER 30 39e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define RANGE 64 40e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#define PRED_ORDER 4 41e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 42e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 43e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard/* MA prediction coeff ={0.5, 0.4, 0.3, 0.2} in Q13 */ 44e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardstatic Word16 pred[PRED_ORDER] = {4096, 3277, 2458, 1638}; 45e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 46e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 47e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgardvoid Init_Q_gain2( 48e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 * mem /* output :static memory (2 words) */ 49e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 50e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 51e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 i; 52e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 53e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* 4nd order quantizer energy predictor (init to -14.0 in Q10) */ 54e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < PRED_ORDER; i++) 55e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 56e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mem[i] = -14336; /* past_qua_en[i] */ 57e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 58e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 59e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return; 60e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 61e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 62e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardWord16 Q_gain2( /* Return index of quantization. */ 63e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 xn[], /* (i) Q_xn: Target vector. */ 64e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 y1[], /* (i) Q_xn: Adaptive codebook. */ 65e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 Q_xn, /* (i) : xn and y1 format */ 66e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 y2[], /* (i) Q9 : Filtered innovative vector. */ 67e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 code[], /* (i) Q9 : Innovative vector. */ 68e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 g_coeff[], /* (i) : Correlations <xn y1> <y1 y1> */ 69e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Compute in G_pitch(). */ 70e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 L_subfr, /* (i) : Subframe lenght. */ 71e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 nbits, /* (i) : number of bits (6 or 7) */ 72e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 * gain_pit, /* (i/o)Q14: Pitch gain. */ 73e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 * gain_cod, /* (o) Q16 : Code gain. */ 74e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 gp_clip, /* (i) : Gp Clipping flag */ 75e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 * mem /* (i/o) : static memory (2 words) */ 76e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard ) 77e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 78e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 index, *p, min_ind, size; 79e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 exp, frac, gcode0, exp_gcode0, e_max, exp_code, qua_ener; 80e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 g_pitch, g2_pitch, g_code, g_pit_cod, g2_code, g2_code_lo; 81e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 coeff[5], coeff_lo[5], exp_coeff[5]; 82e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 exp_max[5]; 83e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 i, j, L_tmp, dist_min; 84e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 *past_qua_en, *t_qua_gain; 85e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 86b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard past_qua_en = mem; 87e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 88e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /*-----------------------------------------------------------------* 89e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * - Find the initial quantization pitch index * 90e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * - Set gains search range * 91e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *-----------------------------------------------------------------*/ 92e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (nbits == 6) 93e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 94b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard t_qua_gain = t_qua_gain6b; 95b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard min_ind = 0; 96b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard size = RANGE; 97e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 98e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(gp_clip == 1) 99e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 100e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard size = size - 16; /* limit gain pitch to 1.0 */ 101e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 102e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } else 103e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 104b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard t_qua_gain = t_qua_gain7b; 105e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 106e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard p = t_qua_gain7b + RANGE; /* pt at 1/4th of table */ 107e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 108b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard j = nb_qua_gain7b - RANGE; 109e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 110e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (gp_clip == 1) 111e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 112e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard j = j - 27; /* limit gain pitch to 1.0 */ 113e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 114b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard min_ind = 0; 115b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard g_pitch = *gain_pit; 116e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 117e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < j; i++, p += 2) 118e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 119e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (g_pitch > *p) 120e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 121e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard min_ind = min_ind + 1; 122e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 123e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 124b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard size = RANGE; 125e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 126e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 127e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /*------------------------------------------------------------------* 128e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * Compute coefficient need for the quantization. * 129e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * * 130e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * coeff[0] = y1 y1 * 131e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * coeff[1] = -2 xn y1 * 132e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * coeff[2] = y2 y2 * 133e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * coeff[3] = -2 xn y2 * 134e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * coeff[4] = 2 y1 y2 * 135e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * * 136e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * Product <y1 y1> and <xn y1> have been compute in G_pitch() and * 137e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * are in vector g_coeff[]. * 138e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *------------------------------------------------------------------*/ 139e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 140b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard coeff[0] = g_coeff[0]; 141b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard exp_coeff[0] = g_coeff[1]; 142e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard coeff[1] = negate(g_coeff[2]); /* coeff[1] = -2 xn y1 */ 143b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard exp_coeff[1] = g_coeff[3] + 1; 144e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 145e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Compute scalar product <y2[],y2[]> */ 146e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT /* asm optimization branch */ 147e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard coeff[2] = extract_h(Dot_product12_asm(y2, y2, L_subfr, &exp)); 148e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else 149e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard coeff[2] = extract_h(Dot_product12(y2, y2, L_subfr, &exp)); 150e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif 151e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard exp_coeff[2] = (exp - 18) + (Q_xn << 1); /* -18 (y2 Q9) */ 152e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 153e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Compute scalar product -2*<xn[],y2[]> */ 154e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT /* asm optimization branch */ 155e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard coeff[3] = extract_h(L_negate(Dot_product12_asm(xn, y2, L_subfr, &exp))); 156e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else 157e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard coeff[3] = extract_h(L_negate(Dot_product12(xn, y2, L_subfr, &exp))); 158e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif 159e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 160e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard exp_coeff[3] = (exp - 8) + Q_xn; /* -9 (y2 Q9), +1 (2 xn y2) */ 161e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 162e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Compute scalar product 2*<y1[],y2[]> */ 163e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT /* asm optimization branch */ 164e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard coeff[4] = extract_h(Dot_product12_asm(y1, y2, L_subfr, &exp)); 165e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else 166e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard coeff[4] = extract_h(Dot_product12(y1, y2, L_subfr, &exp)); 167e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif 168e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard exp_coeff[4] = (exp - 8) + Q_xn; /* -9 (y2 Q9), +1 (2 y1 y2) */ 169e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 170e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /*-----------------------------------------------------------------* 171e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * Find energy of code and compute: * 172e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * * 173e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * L_tmp = MEAN_ENER - 10log10(energy of code/ L_subfr) * 174e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * = MEAN_ENER - 3.0103*log2(energy of code/ L_subfr) * 175e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *-----------------------------------------------------------------*/ 176e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT /* asm optimization branch */ 177e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = Dot_product12_asm(code, code, L_subfr, &exp_code); 178e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else 179e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = Dot_product12(code, code, L_subfr, &exp_code); 180e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif 181e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* exp_code: -18 (code in Q9), -6 (/L_subfr), -31 (L_tmp Q31->Q0) */ 182e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard exp_code = (exp_code - (18 + 6 + 31)); 183e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 184e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Log2(L_tmp, &exp, &frac); 185e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard exp += exp_code; 186e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = Mpy_32_16(exp, frac, -24660); /* x -3.0103(Q13) -> Q14 */ 187e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 188e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp += (MEAN_ENER * 8192)<<1; /* + MEAN_ENER in Q14 */ 189e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 190e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /*-----------------------------------------------------------------* 191e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * Compute gcode0. * 192e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * = Sum(i=0,1) pred[i]*past_qua_en[i] + mean_ener - ener_code * 193e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *-----------------------------------------------------------------*/ 194e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = (L_tmp << 10); /* From Q14 to Q24 */ 195e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp += (pred[0] * past_qua_en[0])<<1; /* Q13*Q10 -> Q24 */ 196e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp += (pred[1] * past_qua_en[1])<<1; /* Q13*Q10 -> Q24 */ 197e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp += (pred[2] * past_qua_en[2])<<1; /* Q13*Q10 -> Q24 */ 198e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp += (pred[3] * past_qua_en[3])<<1; /* Q13*Q10 -> Q24 */ 199e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 200e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard gcode0 = extract_h(L_tmp); /* From Q24 to Q8 */ 201e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 202e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /*-----------------------------------------------------------------* 203e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * gcode0 = pow(10.0, gcode0/20) * 204e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * = pow(2, 3.321928*gcode0/20) * 205e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * = pow(2, 0.166096*gcode0) * 206e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *-----------------------------------------------------------------*/ 207e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 208e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = vo_L_mult(gcode0, 5443); /* *0.166096 in Q15 -> Q24 */ 209e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = L_tmp >> 8; /* From Q24 to Q16 */ 210e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard VO_L_Extract(L_tmp, &exp_gcode0, &frac); /* Extract exponent of gcode0 */ 211e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 212e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard gcode0 = (Word16)(Pow2(14, frac)); /* Put 14 as exponent so that */ 213e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* output of Pow2() will be: */ 214e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* 16384 < Pow2() <= 32767 */ 215e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard exp_gcode0 -= 14; 216e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 217e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /*-------------------------------------------------------------------------* 218e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * Find the best quantizer * 219e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * ~~~~~~~~~~~~~~~~~~~~~~~ * 220e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * Before doing the computation we need to aling exponents of coeff[] * 221e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * to be sure to have the maximum precision. * 222e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * * 223e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * In the table the pitch gains are in Q14, the code gains are in Q11 and * 224e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * are multiply by gcode0 which have been multiply by 2^exp_gcode0. * 225e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code * 226e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * we divide by 2^15. * 227e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * Considering all the scaling above we have: * 228e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * * 229e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * exp_code = exp_gcode0-11+15 = exp_gcode0+4 * 230e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * * 231e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * g_pitch*g_pitch = -14-14+15 * 232e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * g_pitch = -14 * 233e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * g_code*g_code = (2*exp_code)+15 * 234e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * g_code = exp_code * 235e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * g_pitch*g_code = -14 + exp_code +15 * 236e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * * 237e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * g_pitch*g_pitch * coeff[0] ;exp_max0 = exp_coeff[0] - 13 * 238e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * g_pitch * coeff[1] ;exp_max1 = exp_coeff[1] - 14 * 239e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * g_code*g_code * coeff[2] ;exp_max2 = exp_coeff[2] +15+(2*exp_code) * 240e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * g_code * coeff[3] ;exp_max3 = exp_coeff[3] + exp_code * 241e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * g_pitch*g_code * coeff[4] ;exp_max4 = exp_coeff[4] + 1 + exp_code * 242e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *-------------------------------------------------------------------------*/ 243e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 244e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard exp_code = (exp_gcode0 + 4); 245b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard exp_max[0] = (exp_coeff[0] - 13); 246b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard exp_max[1] = (exp_coeff[1] - 14); 247b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard exp_max[2] = (exp_coeff[2] + (15 + (exp_code << 1))); 248b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard exp_max[3] = (exp_coeff[3] + exp_code); 249b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard exp_max[4] = (exp_coeff[4] + (1 + exp_code)); 250e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 251e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Find maximum exponant */ 252e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 253b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard e_max = exp_max[0]; 254e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 1; i < 5; i++) 255e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 256e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(exp_max[i] > e_max) 257e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 258b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard e_max = exp_max[i]; 259e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 260e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 261e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 262e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* align coeff[] and save in special 32 bit double precision */ 263e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 264e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < 5; i++) 265e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 266e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard j = add1(vo_sub(e_max, exp_max[i]), 2);/* /4 to avoid overflow */ 267e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = L_deposit_h(coeff[i]); 268e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = L_shr(L_tmp, j); 269e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard VO_L_Extract(L_tmp, &coeff[i], &coeff_lo[i]); 270e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard coeff_lo[i] = (coeff_lo[i] >> 3); /* lo >> 3 */ 271e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 272e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 273e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Codebook search */ 274b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard dist_min = MAX_32; 275b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard p = &t_qua_gain[min_ind << 1]; 276e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 277b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard index = 0; 278e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (i = 0; i < size; i++) 279e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 280b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard g_pitch = *p++; 281b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard g_code = *p++; 282e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 283e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard g_code = ((g_code * gcode0) + 0x4000)>>15; 284e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard g2_pitch = ((g_pitch * g_pitch) + 0x4000)>>15; 285e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard g_pit_cod = ((g_code * g_pitch) + 0x4000)>>15; 286e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = (g_code * g_code)<<1; 287e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard VO_L_Extract(L_tmp, &g2_code, &g2_code_lo); 288e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 289e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = (coeff[2] * g2_code_lo)<<1; 290e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = (L_tmp >> 3); 291e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp += (coeff_lo[0] * g2_pitch)<<1; 292e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp += (coeff_lo[1] * g_pitch)<<1; 293e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp += (coeff_lo[2] * g2_code)<<1; 294e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp += (coeff_lo[3] * g_code)<<1; 295e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp += (coeff_lo[4] * g_pit_cod)<<1; 296e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = (L_tmp >> 12); 297e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp += (coeff[0] * g2_pitch)<<1; 298e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp += (coeff[1] * g_pitch)<<1; 299e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp += (coeff[2] * g2_code)<<1; 300e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp += (coeff[3] * g_code)<<1; 301e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp += (coeff[4] * g_pit_cod)<<1; 302e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 303e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(L_tmp < dist_min) 304e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 305b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard dist_min = L_tmp; 306b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard index = i; 307e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 308e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 309e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 310e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* Read the quantized gains */ 311e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard index = index + min_ind; 312b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard p = &t_qua_gain[(index + index)]; 313e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *gain_pit = *p++; /* selected pitch gain in Q14 */ 314e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard g_code = *p++; /* selected code gain in Q11 */ 315e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 316e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = vo_L_mult(g_code, gcode0); /* Q11*Q0 -> Q12 */ 317e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = L_shl(L_tmp, (exp_gcode0 + 4)); /* Q12 -> Q16 */ 318e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 319e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *gain_cod = L_tmp; /* gain of code in Q16 */ 320e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 321e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /*---------------------------------------------------* 322e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * qua_ener = 20*log10(g_code) * 323e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * = 6.0206*log2(g_code) * 324e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard * = 6.0206*(log2(g_codeQ11) - 11) * 325e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard *---------------------------------------------------*/ 326e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 327e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = L_deposit_l(g_code); 328e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Log2(L_tmp, &exp, &frac); 329e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard exp -= 11; 330e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard L_tmp = Mpy_32_16(exp, frac, 24660); /* x 6.0206 in Q12 */ 331e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 332e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard qua_ener = (Word16)(L_tmp >> 3); /* result in Q10 */ 333e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 334e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* update table of past quantized energies */ 335e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 336b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard past_qua_en[3] = past_qua_en[2]; 337b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard past_qua_en[2] = past_qua_en[1]; 338b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard past_qua_en[1] = past_qua_en[0]; 339b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard past_qua_en[0] = qua_ener; 340e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 341e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard return (index); 342e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 343e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 344e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 345e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 346e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 347