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( 485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 * mem /* output :static memory (2 words) */ 495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 50e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 i; 52e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* 4nd order quantizer energy predictor (init to -14.0 in Q10) */ 545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < PRED_ORDER; i++) 555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen mem[i] = -14336; /* past_qua_en[i] */ 575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 58e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen return; 60e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 61e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 62e2e838afcf03e603a41a0455846eaf9614537c16Mans RullgardWord16 Q_gain2( /* Return index of quantization. */ 635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 xn[], /* (i) Q_xn: Target vector. */ 645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 y1[], /* (i) Q_xn: Adaptive codebook. */ 655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 Q_xn, /* (i) : xn and y1 format */ 665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 y2[], /* (i) Q9 : Filtered innovative vector. */ 675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 code[], /* (i) Q9 : Innovative vector. */ 685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 g_coeff[], /* (i) : Correlations <xn y1> <y1 y1> */ 695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Compute in G_pitch(). */ 705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 L_subfr, /* (i) : Subframe lenght. */ 715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 nbits, /* (i) : number of bits (6 or 7) */ 725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 * gain_pit, /* (i/o)Q14: Pitch gain. */ 735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 * gain_cod, /* (o) Q16 : Code gain. */ 745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 gp_clip, /* (i) : Gp Clipping flag */ 755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 * mem /* (i/o) : static memory (2 words) */ 765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen ) 77e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard{ 785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 index, *p, min_ind, size; 795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 exp, frac, gcode0, exp_gcode0, e_max, exp_code, qua_ener; 805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 g_pitch, g2_pitch, g_code, g_pit_cod, g2_code, g2_code_lo; 815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 coeff[5], coeff_lo[5], exp_coeff[5]; 825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 exp_max[5]; 835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word32 i, j, L_tmp, dist_min; 845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Word16 *past_qua_en, *t_qua_gain; 855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen past_qua_en = mem; 875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /*-----------------------------------------------------------------* 895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * - Find the initial quantization pitch index * 905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * - Set gains search range * 915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *-----------------------------------------------------------------*/ 925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (nbits == 6) 935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen t_qua_gain = t_qua_gain6b; 955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen min_ind = 0; 965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen size = RANGE; 975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(gp_clip == 1) 995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 1005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen size = size - 16; /* limit gain pitch to 1.0 */ 1015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 1025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } else 1035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 1045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen t_qua_gain = t_qua_gain7b; 1055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen p = t_qua_gain7b + RANGE; /* pt at 1/4th of table */ 1075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen j = nb_qua_gain7b - RANGE; 1095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (gp_clip == 1) 1115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 1125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen j = j - 27; /* limit gain pitch to 1.0 */ 1135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 1145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen min_ind = 0; 1155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen g_pitch = *gain_pit; 1165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < j; i++, p += 2) 1185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 1195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if (g_pitch > *p) 1205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 1215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen min_ind = min_ind + 1; 1225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 1235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 1245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen size = RANGE; 1255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 1265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /*------------------------------------------------------------------* 1285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * Compute coefficient need for the quantization. * 1295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * * 1305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * coeff[0] = y1 y1 * 1315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * coeff[1] = -2 xn y1 * 1325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * coeff[2] = y2 y2 * 1335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * coeff[3] = -2 xn y2 * 1345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * coeff[4] = 2 y1 y2 * 1355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * * 1365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * Product <y1 y1> and <xn y1> have been compute in G_pitch() and * 1375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * are in vector g_coeff[]. * 1385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *------------------------------------------------------------------*/ 1395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen coeff[0] = g_coeff[0]; 1415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp_coeff[0] = g_coeff[1]; 1425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen coeff[1] = negate(g_coeff[2]); /* coeff[1] = -2 xn y1 */ 1435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp_coeff[1] = g_coeff[3] + 1; 1445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Compute scalar product <y2[],y2[]> */ 146e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT /* asm optimization branch */ 1475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen coeff[2] = extract_h(Dot_product12_asm(y2, y2, L_subfr, &exp)); 148e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else 1495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen coeff[2] = extract_h(Dot_product12(y2, y2, L_subfr, &exp)); 150e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif 1515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp_coeff[2] = (exp - 18) + (Q_xn << 1); /* -18 (y2 Q9) */ 152e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 1535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Compute scalar product -2*<xn[],y2[]> */ 154e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT /* asm optimization branch */ 1555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen coeff[3] = extract_h(L_negate(Dot_product12_asm(xn, y2, L_subfr, &exp))); 156e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else 1575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen coeff[3] = extract_h(L_negate(Dot_product12(xn, y2, L_subfr, &exp))); 158e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif 159e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 1605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp_coeff[3] = (exp - 8) + Q_xn; /* -9 (y2 Q9), +1 (2 xn y2) */ 161e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 1625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Compute scalar product 2*<y1[],y2[]> */ 163e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT /* asm optimization branch */ 1645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen coeff[4] = extract_h(Dot_product12_asm(y1, y2, L_subfr, &exp)); 165e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else 1665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen coeff[4] = extract_h(Dot_product12(y1, y2, L_subfr, &exp)); 167e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif 1685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp_coeff[4] = (exp - 8) + Q_xn; /* -9 (y2 Q9), +1 (2 y1 y2) */ 1695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /*-----------------------------------------------------------------* 1715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * Find energy of code and compute: * 1725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * * 1735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * L_tmp = MEAN_ENER - 10log10(energy of code/ L_subfr) * 1745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * = MEAN_ENER - 3.0103*log2(energy of code/ L_subfr) * 1755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *-----------------------------------------------------------------*/ 176e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#ifdef ASM_OPT /* asm optimization branch */ 1775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = Dot_product12_asm(code, code, L_subfr, &exp_code); 178e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#else 1795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = Dot_product12(code, code, L_subfr, &exp_code); 180e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#endif 1815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* exp_code: -18 (code in Q9), -6 (/L_subfr), -31 (L_tmp Q31->Q0) */ 1825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp_code = (exp_code - (18 + 6 + 31)); 1835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Log2(L_tmp, &exp, &frac); 1855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp += exp_code; 1865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = Mpy_32_16(exp, frac, -24660); /* x -3.0103(Q13) -> Q14 */ 1875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp += (MEAN_ENER * 8192)<<1; /* + MEAN_ENER in Q14 */ 1895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 1905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /*-----------------------------------------------------------------* 1915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * Compute gcode0. * 1925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * = Sum(i=0,1) pred[i]*past_qua_en[i] + mean_ener - ener_code * 1935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *-----------------------------------------------------------------*/ 1945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = (L_tmp << 10); /* From Q14 to Q24 */ 1955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp += (pred[0] * past_qua_en[0])<<1; /* Q13*Q10 -> Q24 */ 1965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp += (pred[1] * past_qua_en[1])<<1; /* Q13*Q10 -> Q24 */ 1975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp += (pred[2] * past_qua_en[2])<<1; /* Q13*Q10 -> Q24 */ 1985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp += (pred[3] * past_qua_en[3])<<1; /* Q13*Q10 -> Q24 */ 1995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen gcode0 = extract_h(L_tmp); /* From Q24 to Q8 */ 2015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /*-----------------------------------------------------------------* 2035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * gcode0 = pow(10.0, gcode0/20) * 2045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * = pow(2, 3.321928*gcode0/20) * 2055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * = pow(2, 0.166096*gcode0) * 2065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *-----------------------------------------------------------------*/ 2075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = vo_L_mult(gcode0, 5443); /* *0.166096 in Q15 -> Q24 */ 2095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = L_tmp >> 8; /* From Q24 to Q16 */ 2105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen VO_L_Extract(L_tmp, &exp_gcode0, &frac); /* Extract exponent of gcode0 */ 2115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen gcode0 = (Word16)(Pow2(14, frac)); /* Put 14 as exponent so that */ 2135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* output of Pow2() will be: */ 2145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* 16384 < Pow2() <= 32767 */ 2155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp_gcode0 -= 14; 2165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /*-------------------------------------------------------------------------* 2185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * Find the best quantizer * 2195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * ~~~~~~~~~~~~~~~~~~~~~~~ * 2205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * Before doing the computation we need to aling exponents of coeff[] * 2215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * to be sure to have the maximum precision. * 2225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * * 2235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * In the table the pitch gains are in Q14, the code gains are in Q11 and * 2245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * are multiply by gcode0 which have been multiply by 2^exp_gcode0. * 2255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * Also when we compute g_pitch*g_pitch, g_code*g_code and g_pitch*g_code * 2265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * we divide by 2^15. * 2275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * Considering all the scaling above we have: * 2285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * * 2295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * exp_code = exp_gcode0-11+15 = exp_gcode0+4 * 2305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * * 2315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * g_pitch*g_pitch = -14-14+15 * 2325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * g_pitch = -14 * 2335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * g_code*g_code = (2*exp_code)+15 * 2345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * g_code = exp_code * 2355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * g_pitch*g_code = -14 + exp_code +15 * 2365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * * 2375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * g_pitch*g_pitch * coeff[0] ;exp_max0 = exp_coeff[0] - 13 * 2385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * g_pitch * coeff[1] ;exp_max1 = exp_coeff[1] - 14 * 2395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * g_code*g_code * coeff[2] ;exp_max2 = exp_coeff[2] +15+(2*exp_code) * 2405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * g_code * coeff[3] ;exp_max3 = exp_coeff[3] + exp_code * 2415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * g_pitch*g_code * coeff[4] ;exp_max4 = exp_coeff[4] + 1 + exp_code * 2425d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *-------------------------------------------------------------------------*/ 2435d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2445d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp_code = (exp_gcode0 + 4); 2455d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp_max[0] = (exp_coeff[0] - 13); 2465d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp_max[1] = (exp_coeff[1] - 14); 2475d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp_max[2] = (exp_coeff[2] + (15 + (exp_code << 1))); 2485d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp_max[3] = (exp_coeff[3] + exp_code); 2495d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp_max[4] = (exp_coeff[4] + (1 + exp_code)); 2505d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2515d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Find maximum exponant */ 2525d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2535d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen e_max = exp_max[0]; 2545d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 1; i < 5; i++) 2555d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2565d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(exp_max[i] > e_max) 2575d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2585d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen e_max = exp_max[i]; 2595d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 2605d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 2615d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2625d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* align coeff[] and save in special 32 bit double precision */ 2635d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2645d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < 5; i++) 2655d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2665d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen j = add1(vo_sub(e_max, exp_max[i]), 2);/* /4 to avoid overflow */ 2675d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = L_deposit_h(coeff[i]); 2685d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = L_shr(L_tmp, j); 2695d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen VO_L_Extract(L_tmp, &coeff[i], &coeff_lo[i]); 2705d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen coeff_lo[i] = (coeff_lo[i] >> 3); /* lo >> 3 */ 2715d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 2725d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2735d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Codebook search */ 2745d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen dist_min = MAX_32; 2755d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen p = &t_qua_gain[min_ind << 1]; 2765d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2775d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen index = 0; 2785d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen for (i = 0; i < size; i++) 2795d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 2805d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen g_pitch = *p++; 2815d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen g_code = *p++; 2825d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2835d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen g_code = ((g_code * gcode0) + 0x4000)>>15; 2845d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen g2_pitch = ((g_pitch * g_pitch) + 0x4000)>>15; 2855d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen g_pit_cod = ((g_code * g_pitch) + 0x4000)>>15; 2865d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = (g_code * g_code)<<1; 2875d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen VO_L_Extract(L_tmp, &g2_code, &g2_code_lo); 2885d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 2895d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = (coeff[2] * g2_code_lo)<<1; 2905d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = (L_tmp >> 3); 2915d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp += (coeff_lo[0] * g2_pitch)<<1; 2925d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp += (coeff_lo[1] * g_pitch)<<1; 2935d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp += (coeff_lo[2] * g2_code)<<1; 2945d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp += (coeff_lo[3] * g_code)<<1; 2955d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp += (coeff_lo[4] * g_pit_cod)<<1; 2965d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = (L_tmp >> 12); 2975d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp += (coeff[0] * g2_pitch)<<1; 2985d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp += (coeff[1] * g_pitch)<<1; 2995d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp += (coeff[2] * g2_code)<<1; 3005d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp += (coeff[3] * g_code)<<1; 3015d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp += (coeff[4] * g_pit_cod)<<1; 3025d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3035d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen if(L_tmp < dist_min) 3045d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen { 3055d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen dist_min = L_tmp; 3065d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen index = i; 3075d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 3085d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen } 3095d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3105d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* Read the quantized gains */ 3115d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen index = index + min_ind; 3125d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen p = &t_qua_gain[(index + index)]; 3135d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *gain_pit = *p++; /* selected pitch gain in Q14 */ 3145d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen g_code = *p++; /* selected code gain in Q11 */ 3155d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3165d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = vo_L_mult(g_code, gcode0); /* Q11*Q0 -> Q12 */ 3175d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = L_shl(L_tmp, (exp_gcode0 + 4)); /* Q12 -> Q16 */ 3185d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3195d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *gain_cod = L_tmp; /* gain of code in Q16 */ 3205d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3215d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /*---------------------------------------------------* 3225d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * qua_ener = 20*log10(g_code) * 3235d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * = 6.0206*log2(g_code) * 3245d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen * = 6.0206*(log2(g_codeQ11) - 11) * 3255d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen *---------------------------------------------------*/ 3265d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3275d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = L_deposit_l(g_code); 3285d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen Log2(L_tmp, &exp, &frac); 3295d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen exp -= 11; 3305d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen L_tmp = Mpy_32_16(exp, frac, 24660); /* x 6.0206 in Q12 */ 3315d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3325d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen qua_ener = (Word16)(L_tmp >> 3); /* result in Q10 */ 3335d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3345d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen /* update table of past quantized energies */ 3355d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3365d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen past_qua_en[3] = past_qua_en[2]; 3375d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen past_qua_en[2] = past_qua_en[1]; 3385d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen past_qua_en[1] = past_qua_en[0]; 3395d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen past_qua_en[0] = qua_ener; 3405d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen 3415d5c3a132bb446ac78a37dfaac24a46cacf0dd73Marco Nelissen return (index); 342e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard} 343e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 344e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 345e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 346e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 347