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 File: quantize.c 18e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 19e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Content: quantization functions 20e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 21956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*******************************************************************************/ 22956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 23e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "typedef.h" 24e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard#include "basic_op.h" 25956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "oper_32b.h" 26956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "quantize.h" 27956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "aac_rom.h" 28956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 29956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#define MANT_DIGITS 9 30956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#define MANT_SIZE (1<<MANT_DIGITS) 31956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 32956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic const Word32 XROUND = 0x33e425af; /* final rounding constant (-0.0946f+ 0.5f) */ 33956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 34956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 35956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 36956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 37b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* function name:pow34 38b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* description: calculate $x^{\frac{3}{4}}, for 0.5 < x < 1.0$. 39956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 40956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 41956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong__inline Word32 pow34(Word32 x) 42956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 43956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* index table using MANT_DIGITS bits, but mask out the sign bit and the MSB 44b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard which is always one */ 45956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return mTab_3_4[(x >> (INT_BITS-2-MANT_DIGITS)) & (MANT_SIZE-1)]; 46956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 47956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 48956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 49956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 50956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 51b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* function name:quantizeSingleLine 52b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* description: quantizes spectrum 53b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* quaSpectrum = mdctSpectrum^3/4*2^(-(3/16)*gain) 54956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 55956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 56956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic Word16 quantizeSingleLine(const Word16 gain, const Word32 absSpectrum) 57956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 58956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 e, minusFinalExp, finalShift; 59956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 x; 60b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word16 qua = 0; 61b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 62956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 63956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (absSpectrum) { 64956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong e = norm_l(absSpectrum); 65956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong x = pow34(absSpectrum << e); 66956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 67956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* calculate the final fractional exponent times 16 (was 3*(4*e + gain) + (INT_BITS-1)*16) */ 68956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong minusFinalExp = (e << 2) + gain; 69956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong minusFinalExp = (minusFinalExp << 1) + minusFinalExp; 70956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong minusFinalExp = minusFinalExp + ((INT_BITS-1) << 4); 71956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 72956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* separate the exponent into a shift, and a multiply */ 73956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong finalShift = minusFinalExp >> 4; 74b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 75956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (finalShift < INT_BITS) { 76956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong x = L_mpy_wx(x, pow2tominusNover16[minusFinalExp & 15]); 77956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 78956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong x += XROUND >> (INT_BITS - finalShift); 79956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 80e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* shift and quantize */ 81e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard finalShift--; 82e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 83e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(finalShift >= 0) 84e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard x >>= finalShift; 85e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard else 86e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard x <<= (-finalShift); 87b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 88956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qua = saturate(x); 89956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 90956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 91956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 92956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return qua; 93956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 94956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 95956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 96956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 97b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* function name:quantizeLines 98b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* description: quantizes spectrum lines 99b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* quaSpectrum = mdctSpectrum^3/4*2^(-(3/16)*gain) 100b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* input: global gain, number of lines to process, spectral data 101956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* output: quantized spectrum 102956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 103956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 104956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void quantizeLines(const Word16 gain, 105956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word16 noOfLines, 106956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word32 *mdctSpectrum, 107956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 *quaSpectrum) 108956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 109956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 line; 110956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 m = gain&3; 111e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 g = (gain >> 2) + 4; 112e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 mdctSpeL; 1139fc4dfb69df0b5a13b7a1904272eb1dcf8113d0cMartin Storsjo const Word16 *pquat; 114e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* gain&3 */ 115e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 116e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard pquat = quantBorders[m]; 117e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 118e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard g += 16; 119b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 120e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(g >= 0) 121e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 122956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (line=0; line<noOfLines; line++) { 123956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 qua; 124b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qua = 0; 125b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 126e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mdctSpeL = mdctSpectrum[line]; 127b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 128956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (mdctSpeL) { 129956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sa; 130956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 saShft; 131956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 132956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sa = L_abs(mdctSpeL); 133e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard //saShft = L_shr(sa, 16 + g); 134956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong saShft = sa >> g; 135956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 136956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft > pquat[0]) { 137b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 138956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft < pquat[1]) { 139b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 140956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qua = mdctSpeL>0 ? 1 : -1; 141956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 142956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 143b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 144956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft < pquat[2]) { 145b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 146956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qua = mdctSpeL>0 ? 2 : -2; 147956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 148956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 149b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 150956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft < pquat[3]) { 151b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 152956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qua = mdctSpeL>0 ? 3 : -3; 153956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 154956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 155956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qua = quantizeSingleLine(gain, sa); 156956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* adjust the sign. Since 0 < qua < 1, this cannot overflow. */ 157b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 158956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (mdctSpeL < 0) 159956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qua = -qua; 160956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 161956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 162956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 163956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 164956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 165b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard quaSpectrum[line] = qua ; 166e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 167e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 168e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard else 169e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 170e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard for (line=0; line<noOfLines; line++) { 171e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 qua; 172b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard qua = 0; 173b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 174e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mdctSpeL = mdctSpectrum[line]; 175b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 176e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (mdctSpeL) { 177e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 sa; 178e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 saShft; 179e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 180e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard sa = L_abs(mdctSpeL); 181e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard saShft = sa << g; 182e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 183e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (saShft > pquat[0]) { 184b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 185e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (saShft < pquat[1]) { 186b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 187e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard qua = mdctSpeL>0 ? 1 : -1; 188e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 189e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard else { 190b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 191e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (saShft < pquat[2]) { 192b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 193e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard qua = mdctSpeL>0 ? 2 : -2; 194e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 195e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard else { 196b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 197e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (saShft < pquat[3]) { 198b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 199e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard qua = mdctSpeL>0 ? 3 : -3; 200e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 201e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard else { 202e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard qua = quantizeSingleLine(gain, sa); 203e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* adjust the sign. Since 0 < qua < 1, this cannot overflow. */ 204b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 205e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (mdctSpeL < 0) 206e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard qua = -qua; 207e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 208e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 209e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 210e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 211e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 212b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard quaSpectrum[line] = qua ; 213b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard } 214956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 215956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 216956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 217956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 218956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 219956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 220956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 221b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* function name:iquantizeLines 222956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: iquantizes spectrum lines without sign 223b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* mdctSpectrum = iquaSpectrum^4/3 *2^(0.25*gain) 224b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* input: global gain, number of lines to process,quantized spectrum 225956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* output: spectral data 226956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 227956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 228956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongstatic void iquantizeLines(const Word16 gain, 229956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word16 noOfLines, 230956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong const Word16 *quantSpectrum, 231956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *mdctSpectrum) 232956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 233956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 iquantizermod; 234956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 iquantizershift; 235956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 line; 236956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 237b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard iquantizermod = gain & 3; 238956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong iquantizershift = gain >> 2; 239956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 240956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (line=0; line<noOfLines; line++) { 241b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 242956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if( quantSpectrum[line] != 0 ) { 243956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 accu; 244956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 ex; 245956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 tabIndex; 246956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 specExp; 247956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 s,t; 248956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 249956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong accu = quantSpectrum[line]; 250956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 251956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ex = norm_l(accu); 252956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong accu = accu << ex; 253956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong specExp = INT_BITS-1 - ex; 254956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 255b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard tabIndex = (accu >> (INT_BITS-2-MANT_DIGITS)) & (~MANT_SIZE); 256956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 257956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* calculate "mantissa" ^4/3 */ 258b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard s = mTab_4_3[tabIndex]; 259956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 260956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* get approperiate exponent multiplier for specExp^3/4 combined with scfMod */ 261b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard t = specExpMantTableComb_enc[iquantizermod][specExp]; 262956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 263956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* multiply "mantissa" ^4/3 with exponent multiplier */ 264956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong accu = MULHIGH(s, t); 265956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 266956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* get approperiate exponent shifter */ 267b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard specExp = specExpTableComb_enc[iquantizermod][specExp]; 268956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 269e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard specExp += iquantizershift + 1; 270e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(specExp >= 0) 271e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard mdctSpectrum[line] = accu << specExp; 272e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard else 273956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong mdctSpectrum[line] = accu >> (-specExp); 274956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 275956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 276b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard mdctSpectrum[line] = 0; 277956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 278956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 279956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 280956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 281956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 282956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 283956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name: QuantizeSpectrum 284956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: quantizes the entire spectrum 285956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* returns: 286956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* input: number of scalefactor bands to be quantized, ... 287956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* output: quantized spectrum 288956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 289956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 290956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dongvoid QuantizeSpectrum(Word16 sfbCnt, 291956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 maxSfbPerGroup, 292956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 sfbPerGroup, 293956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 *sfbOffset, 294956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 *mdctSpectrum, 295956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 globalGain, 296956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 *scalefactors, 297956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 *quantizedSpectrum) 298956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 299956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sfbOffs, sfb; 300956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 301956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(sfbOffs=0;sfbOffs<sfbCnt;sfbOffs+=sfbPerGroup) { 302956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sfbNext ; 303956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (sfb = 0; sfb < maxSfbPerGroup; sfb = sfbNext) { 304b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard Word16 scalefactor = scalefactors[sfbOffs+sfb]; 305956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* coalesce sfbs with the same scalefactor */ 306956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (sfbNext = sfb+1; 307956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sfbNext < maxSfbPerGroup && scalefactor == scalefactors[sfbOffs+sfbNext]; 308956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sfbNext++) ; 309956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 310956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong quantizeLines(globalGain - scalefactor, 311956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sfbOffset[sfbOffs+sfbNext] - sfbOffset[sfbOffs+sfb], 312956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong mdctSpectrum + sfbOffset[sfbOffs+sfb], 313956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong quantizedSpectrum + sfbOffset[sfbOffs+sfb]); 314956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 315956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 316956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 317956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 318956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 319956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 320956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 321b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard* function name:calcSfbDist 322956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: quantizes and requantizes lines to calculate distortion 323956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* input: number of lines to be quantized, ... 324956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* output: distortion 325956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 326956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*****************************************************************************/ 327956c553ab0ce72f8074ad0fda2ffd66a0305700cJames DongWord32 calcSfbDist(const Word32 *spec, 328956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 sfbWidth, 329956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 gain) 330956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong{ 331956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 line; 332956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 dist; 333956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 m = gain&3; 334e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 g = (gain >> 2) + 4; 335e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 g2 = (g << 1) + 1; 3369fc4dfb69df0b5a13b7a1904272eb1dcf8113d0cMartin Storsjo const Word16 *pquat, *repquat; 337956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* gain&3 */ 338e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 339e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard pquat = quantBorders[m]; 340956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong repquat = quantRecon[m]; 341b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 342b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard dist = 0; 343e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard g += 16; 344e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if(g2 < 0 && g >= 0) 345b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard { 346e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard g2 = -g2; 347b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard for(line=0; line<sfbWidth; line++) { 348b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard if (spec[line]) { 349e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 diff; 350e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 distSingle; 351e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 sa; 352e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 saShft; 353e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard sa = L_abs(spec[line]); 354e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard //saShft = round16(L_shr(sa, g)); 355e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard //saShft = L_shr(sa, 16+g); 356e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard saShft = sa >> g; 357e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 358e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (saShft < pquat[0]) { 359e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard distSingle = (saShft * saShft) >> g2; 360e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 361e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard else { 362b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 363e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (saShft < pquat[1]) { 364e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard diff = saShft - repquat[0]; 365e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard distSingle = (diff * diff) >> g2; 366e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 367e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard else { 368b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 369e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (saShft < pquat[2]) { 370e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard diff = saShft - repquat[1]; 371e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard distSingle = (diff * diff) >> g2; 372e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 373e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard else { 374b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 375e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (saShft < pquat[3]) { 376e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard diff = saShft - repquat[2]; 377e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard distSingle = (diff * diff) >> g2; 378e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 379e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard else { 380e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 qua = quantizeSingleLine(gain, sa); 381e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 iqval, diff32; 382e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* now that we have quantized x, re-quantize it. */ 383e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard iquantizeLines(gain, 1, &qua, &iqval); 384e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard diff32 = sa - iqval; 385e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard distSingle = fixmul(diff32, diff32); 386e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 387e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 388e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 389e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 390b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 391e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard dist = L_add(dist, distSingle); 392e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 393e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 394e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 395e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard else 396e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard { 397b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard for(line=0; line<sfbWidth; line++) { 398b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard if (spec[line]) { 399956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 diff; 400956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 distSingle; 401956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sa; 402956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 saShft; 403956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sa = L_abs(spec[line]); 404956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong //saShft = round16(L_shr(sa, g)); 405e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard saShft = L_shr(sa, g); 406e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard 407e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (saShft < pquat[0]) { 408e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard distSingle = L_shl((saShft * saShft), g2); 409e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 410e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard else { 411b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 412e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (saShft < pquat[1]) { 413e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard diff = saShft - repquat[0]; 414e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard distSingle = L_shl((diff * diff), g2); 415e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 416e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard else { 417b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 418e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (saShft < pquat[2]) { 419e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard diff = saShft - repquat[1]; 420e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard distSingle = L_shl((diff * diff), g2); 421e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 422e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard else { 423b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard 424e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard if (saShft < pquat[3]) { 425e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard diff = saShft - repquat[2]; 426e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard distSingle = L_shl((diff * diff), g2); 427e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 428e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard else { 429e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word16 qua = quantizeSingleLine(gain, sa); 430e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard Word32 iqval, diff32; 431e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard /* now that we have quantized x, re-quantize it. */ 432e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard iquantizeLines(gain, 1, &qua, &iqval); 433e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard diff32 = sa - iqval; 434e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard distSingle = fixmul(diff32, diff32); 435e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 436e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 437e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 438e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard } 439e2e838afcf03e603a41a0455846eaf9614537c16Mans Rullgard dist = L_add(dist, distSingle); 440956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 441b676a05348e4c516fa8b57e33b10548e6142c3f8Mans Rullgard } 442956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 443956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 444956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return dist; 445956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 446