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