quantize.c revision 956c553ab0ce72f8074ad0fda2ffd66a0305700c
1956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/* 2956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ** Copyright 2003-2010, VisualOn, Inc. 3956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ** 4956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ** Licensed under the Apache License, Version 2.0 (the "License"); 5956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ** you may not use this file except in compliance with the License. 6956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ** You may obtain a copy of the License at 7956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ** 8956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ** http://www.apache.org/licenses/LICENSE-2.0 9956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ** 10956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ** Unless required by applicable law or agreed to in writing, software 11956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ** distributed under the License is distributed on an "AS IS" BASIS, 12956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ** See the License for the specific language governing permissions and 14956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong ** limitations under the License. 15956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong */ 16956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/******************************************************************************* 17956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong File: quantize.c 18956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 19956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Content: quantization functions 20956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 21956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong*******************************************************************************/ 22956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 23956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#include "typedef.h" 24956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong#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* 37956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name:pow34 38956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 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 44956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 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* 51956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name:quantizeSingleLine 52956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: quantizes spectrum 53956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 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; 60956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 qua = 0; 61956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 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; 74956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 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 80956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* shift and quantize */ 81956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong finalShift--; 82956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 83956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if(finalShift >= 0) 84956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong x >>= finalShift; 85956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else 86956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong x <<= (-finalShift); 87956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 88956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qua = saturate(x); 89956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 90956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 91956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 92956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return qua; 93956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 94956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 95956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 96956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 97956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name:quantizeLines 98956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: quantizes spectrum lines 99956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* quaSpectrum = mdctSpectrum^3/4*2^(-(3/16)*gain) 100956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 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; 111956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 g = (gain >> 2) + 4; 112956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 mdctSpeL; 113956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 *pquat; 114956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* gain&3 */ 115956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 116956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pquat = quantBorders[m]; 117956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 118956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong g += 16; 119956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 120956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if(g >= 0) 121956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong { 122956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (line=0; line<noOfLines; line++) { 123956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 qua; 124956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qua = 0; 125956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 126956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong mdctSpeL = mdctSpectrum[line]; 127956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 128956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (mdctSpeL) { 129956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sa; 130956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 saShft; 131956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 132956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sa = L_abs(mdctSpeL); 133956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong //saShft = L_shr(sa, 16 + g); 134956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong saShft = sa >> g; 135956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 136956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft > pquat[0]) { 137956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 138956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft < pquat[1]) { 139956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 140956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qua = mdctSpeL>0 ? 1 : -1; 141956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 142956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 143956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 144956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft < pquat[2]) { 145956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 146956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qua = mdctSpeL>0 ? 2 : -2; 147956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 148956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 149956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 150956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft < pquat[3]) { 151956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 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. */ 157956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 158956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (mdctSpeL < 0) 159956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qua = -qua; 160956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 161956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 162956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 163956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 164956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 165956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong quaSpectrum[line] = qua ; 166956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 167956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 168956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else 169956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong { 170956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (line=0; line<noOfLines; line++) { 171956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 qua; 172956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qua = 0; 173956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 174956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong mdctSpeL = mdctSpectrum[line]; 175956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 176956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (mdctSpeL) { 177956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sa; 178956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 saShft; 179956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 180956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sa = L_abs(mdctSpeL); 181956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong saShft = sa << g; 182956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 183956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft > pquat[0]) { 184956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 185956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft < pquat[1]) { 186956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 187956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qua = mdctSpeL>0 ? 1 : -1; 188956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 189956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 190956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 191956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft < pquat[2]) { 192956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 193956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qua = mdctSpeL>0 ? 2 : -2; 194956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 195956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 196956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 197956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft < pquat[3]) { 198956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 199956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qua = mdctSpeL>0 ? 3 : -3; 200956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 201956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 202956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qua = quantizeSingleLine(gain, sa); 203956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* adjust the sign. Since 0 < qua < 1, this cannot overflow. */ 204956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 205956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (mdctSpeL < 0) 206956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong qua = -qua; 207956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 208956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 209956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 210956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 211956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 212956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong quaSpectrum[line] = qua ; 213956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 214956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 215956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 216956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 217956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 218956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 219956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong/***************************************************************************** 220956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 221956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* function name:iquantizeLines 222956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* description: iquantizes spectrum lines without sign 223956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* mdctSpectrum = iquaSpectrum^4/3 *2^(0.25*gain) 224956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 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 237956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong iquantizermod = gain & 3; 238956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong iquantizershift = gain >> 2; 239956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 240956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for (line=0; line<noOfLines; line++) { 241956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 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 255956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong tabIndex = (accu >> (INT_BITS-2-MANT_DIGITS)) & (~MANT_SIZE); 256956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 257956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* calculate "mantissa" ^4/3 */ 258956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong s = mTab_4_3[tabIndex]; 259956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 260956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* get approperiate exponent multiplier for specExp^3/4 combined with scfMod */ 261956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 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 */ 267956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong specExp = specExpTableComb_enc[iquantizermod][specExp]; 268956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 269956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong specExp += iquantizershift + 1; 270956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if(specExp >= 0) 271956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong mdctSpectrum[line] = accu << specExp; 272956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else 273956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong mdctSpectrum[line] = accu >> (-specExp); 274956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 275956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 276956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 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) { 304956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 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* 321956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong* 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; 334956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 g = (gain >> 2) + 4; 335956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 g2 = (g << 1) + 1; 336956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 *pquat, *repquat; 337956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* gain&3 */ 338956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 339956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong pquat = quantBorders[m]; 340956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong repquat = quantRecon[m]; 341956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 342956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong dist = 0; 343956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong g += 16; 344956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if(g2 < 0 && g >= 0) 345956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong { 346956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong g2 = -g2; 347956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(line=0; line<sfbWidth; line++) { 348956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (spec[line]) { 349956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 diff; 350956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 distSingle; 351956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 sa; 352956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 saShft; 353956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong sa = L_abs(spec[line]); 354956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong //saShft = round16(L_shr(sa, g)); 355956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong //saShft = L_shr(sa, 16+g); 356956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong saShft = sa >> g; 357956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 358956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft < pquat[0]) { 359956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong distSingle = (saShft * saShft) >> g2; 360956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 361956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 362956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 363956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft < pquat[1]) { 364956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong diff = saShft - repquat[0]; 365956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong distSingle = (diff * diff) >> g2; 366956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 367956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 368956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 369956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft < pquat[2]) { 370956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong diff = saShft - repquat[1]; 371956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong distSingle = (diff * diff) >> g2; 372956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 373956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 374956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 375956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft < pquat[3]) { 376956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong diff = saShft - repquat[2]; 377956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong distSingle = (diff * diff) >> g2; 378956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 379956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 380956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 qua = quantizeSingleLine(gain, sa); 381956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 iqval, diff32; 382956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* now that we have quantized x, re-quantize it. */ 383956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong iquantizeLines(gain, 1, &qua, &iqval); 384956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong diff32 = sa - iqval; 385956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong distSingle = fixmul(diff32, diff32); 386956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 387956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 388956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 389956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 390956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 391956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong dist = L_add(dist, distSingle); 392956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 393956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 394956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 395956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else 396956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong { 397956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong for(line=0; line<sfbWidth; line++) { 398956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 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)); 405956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong saShft = L_shr(sa, g); 406956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 407956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft < pquat[0]) { 408956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong distSingle = L_shl((saShft * saShft), g2); 409956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 410956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 411956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 412956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft < pquat[1]) { 413956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong diff = saShft - repquat[0]; 414956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong distSingle = L_shl((diff * diff), g2); 415956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 416956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 417956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 418956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft < pquat[2]) { 419956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong diff = saShft - repquat[1]; 420956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong distSingle = L_shl((diff * diff), g2); 421956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 422956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 423956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 424956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong if (saShft < pquat[3]) { 425956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong diff = saShft - repquat[2]; 426956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong distSingle = L_shl((diff * diff), g2); 427956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 428956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong else { 429956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word16 qua = quantizeSingleLine(gain, sa); 430956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong Word32 iqval, diff32; 431956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong /* now that we have quantized x, re-quantize it. */ 432956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong iquantizeLines(gain, 1, &qua, &iqval); 433956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong diff32 = sa - iqval; 434956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong distSingle = fixmul(diff32, diff32); 435956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 436956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 437956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 438956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 439956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong dist = L_add(dist, distSingle); 440956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 441956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 442956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong } 443956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong 444956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong return dist; 445956c553ab0ce72f8074ad0fda2ffd66a0305700cJames Dong} 446