blob: 43f4a5e1eb5d8535b84764cccbff0a14a89c95d4
1 | /* ***** BEGIN LICENSE BLOCK ***** |
2 | * Source last modified: $Id: dequant.c,v 1.2 2005/05/20 18:05:41 jrecker Exp $ |
3 | * |
4 | * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved. |
5 | * |
6 | * The contents of this file, and the files included with this file, |
7 | * are subject to the current version of the RealNetworks Public |
8 | * Source License (the "RPSL") available at |
9 | * http://www.helixcommunity.org/content/rpsl unless you have licensed |
10 | * the file under the current version of the RealNetworks Community |
11 | * Source License (the "RCSL") available at |
12 | * http://www.helixcommunity.org/content/rcsl, in which case the RCSL |
13 | * will apply. You may also obtain the license terms directly from |
14 | * RealNetworks. You may not use this file except in compliance with |
15 | * the RPSL or, if you have a valid RCSL with RealNetworks applicable |
16 | * to this file, the RCSL. Please see the applicable RPSL or RCSL for |
17 | * the rights, obligations and limitations governing use of the |
18 | * contents of the file. |
19 | * |
20 | * This file is part of the Helix DNA Technology. RealNetworks is the |
21 | * developer of the Original Code and owns the copyrights in the |
22 | * portions it created. |
23 | * |
24 | * This file, and the files included with this file, is distributed |
25 | * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY |
26 | * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS |
27 | * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES |
28 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET |
29 | * ENJOYMENT OR NON-INFRINGEMENT. |
30 | * |
31 | * Technology Compatibility Kit Test Suite(s) Location: |
32 | * http://www.helixcommunity.org/content/tck |
33 | * |
34 | * Contributor(s): |
35 | * |
36 | * ***** END LICENSE BLOCK ***** */ |
37 | |
38 | /************************************************************************************** |
39 | * Fixed-point HE-AAC decoder |
40 | * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com) |
41 | * February 2005 |
42 | * |
43 | * dequant.c - transform coefficient dequantization and short-block deinterleaving |
44 | **************************************************************************************/ |
45 | |
46 | #include "coder.h" |
47 | #include "assembly.h" |
48 | #include <stdio.h> |
49 | |
50 | |
51 | #define SF_OFFSET 100 |
52 | |
53 | /* pow(2, i/4.0) for i = [0,1,2,3], format = Q30 */ |
54 | static const int pow14[4] = { |
55 | 0x40000000, 0x4c1bf829, 0x5a82799a, 0x6ba27e65 |
56 | }; |
57 | |
58 | /* pow(2, i/4.0) * pow(j, 4.0/3.0) for i = [0,1,2,3], j = [0,1,2,...,15] |
59 | * format = Q28 for j = [0-3], Q25 for j = [4-15] |
60 | */ |
61 | static const int pow43_14[4][16] = { |
62 | { |
63 | 0x00000000, 0x10000000, 0x285145f3, 0x453a5cdb, /* Q28 */ |
64 | 0x0cb2ff53, 0x111989d6, 0x15ce31c8, 0x1ac7f203, /* Q25 */ |
65 | 0x20000000, 0x257106b9, 0x2b16b4a3, 0x30ed74b4, /* Q25 */ |
66 | 0x36f23fa5, 0x3d227bd3, 0x437be656, 0x49fc823c, /* Q25 */ |
67 | }, |
68 | { |
69 | 0x00000000, 0x1306fe0a, 0x2ff221af, 0x52538f52, |
70 | 0x0f1a1bf4, 0x1455ccc2, 0x19ee62a8, 0x1fd92396, |
71 | 0x260dfc14, 0x2c8694d8, 0x333dcb29, 0x3a2f5c7a, |
72 | 0x4157aed5, 0x48b3aaa3, 0x50409f76, 0x57fc3010, |
73 | }, |
74 | { |
75 | 0x00000000, 0x16a09e66, 0x39047c0f, 0x61e734aa, |
76 | 0x11f59ac4, 0x182ec633, 0x1ed66a45, 0x25dfc55a, |
77 | 0x2d413ccd, 0x34f3462d, 0x3cefc603, 0x4531ab69, |
78 | 0x4db4adf8, 0x56752054, 0x5f6fcfcd, 0x68a1eca1, |
79 | }, |
80 | { |
81 | 0x00000000, 0x1ae89f99, 0x43ce3e4b, 0x746d57b2, |
82 | 0x155b8109, 0x1cc21cdc, 0x24ac1839, 0x2d0a479e, |
83 | 0x35d13f33, 0x3ef80748, 0x48775c93, 0x524938cd, |
84 | 0x5c68841d, 0x66d0df0a, 0x717e7bfe, 0x7c6e0305, |
85 | }, |
86 | }; |
87 | |
88 | /* pow(j, 4.0 / 3.0) for j = [16,17,18,...,63], format = Q23 */ |
89 | static const int pow43[48] = { |
90 | 0x1428a2fa, 0x15db1bd6, 0x1796302c, 0x19598d85, |
91 | 0x1b24e8bb, 0x1cf7fcfa, 0x1ed28af2, 0x20b4582a, |
92 | 0x229d2e6e, 0x248cdb55, 0x26832fda, 0x28800000, |
93 | 0x2a832287, 0x2c8c70a8, 0x2e9bc5d8, 0x30b0ff99, |
94 | 0x32cbfd4a, 0x34eca001, 0x3712ca62, 0x393e6088, |
95 | 0x3b6f47e0, 0x3da56717, 0x3fe0a5fc, 0x4220ed72, |
96 | 0x44662758, 0x46b03e7c, 0x48ff1e87, 0x4b52b3f3, |
97 | 0x4daaebfd, 0x5007b497, 0x5268fc62, 0x54ceb29c, |
98 | 0x5738c721, 0x59a72a59, 0x5c19cd35, 0x5e90a129, |
99 | 0x610b9821, 0x638aa47f, 0x660db90f, 0x6894c90b, |
100 | 0x6b1fc80c, 0x6daeaa0d, 0x70416360, 0x72d7e8b0, |
101 | 0x75722ef9, 0x78102b85, 0x7ab1d3ec, 0x7d571e09, |
102 | }; |
103 | |
104 | /* sqrt(0.5), format = Q31 */ |
105 | #define SQRTHALF 0x5a82799a |
106 | |
107 | /* Minimax polynomial approximation to pow(x, 4/3), over the range |
108 | * poly43lo: x = [0.5, 0.7071] |
109 | * poly43hi: x = [0.7071, 1.0] |
110 | * |
111 | * Relative error < 1E-7 |
112 | * Coefs are scaled by 4, 2, 1, 0.5, 0.25 |
113 | */ |
114 | static const int poly43lo[5] = { 0x29a0bda9, 0xb02e4828, 0x5957aa1b, 0x236c498d, 0xff581859 }; |
115 | static const int poly43hi[5] = { 0x10852163, 0xd333f6a4, 0x46e9408b, 0x27c2cef0, 0xfef577b4 }; |
116 | |
117 | /* pow2exp[i] = pow(2, i*4/3) exponent */ |
118 | static const int pow2exp[8] = { 14, 13, 11, 10, 9, 7, 6, 5 }; |
119 | |
120 | /* pow2exp[i] = pow(2, i*4/3) fraction */ |
121 | static const int pow2frac[8] = { |
122 | 0x6597fa94, 0x50a28be6, 0x7fffffff, 0x6597fa94, |
123 | 0x50a28be6, 0x7fffffff, 0x6597fa94, 0x50a28be6 |
124 | }; |
125 | |
126 | /************************************************************************************** |
127 | * Function: DequantBlock |
128 | * |
129 | * Description: dequantize one block of transform coefficients (in-place) |
130 | * |
131 | * Inputs: quantized transform coefficients, range = [0, 8191] |
132 | * number of samples to dequantize |
133 | * scalefactor for this block of data, range = [0, 256] |
134 | * |
135 | * Outputs: dequantized transform coefficients in Q(FBITS_OUT_DQ_OFF) |
136 | * |
137 | * Return: guard bit mask (OR of abs value of all dequantized coefs) |
138 | * |
139 | * Notes: applies dequant formula y = pow(x, 4.0/3.0) * pow(2, (scale - 100)/4.0) |
140 | * * pow(2, FBITS_OUT_DQ_OFF) |
141 | * clips outputs to Q(FBITS_OUT_DQ_OFF) |
142 | * output has no minimum number of guard bits |
143 | **************************************************************************************/ |
144 | static int DequantBlock(int *inbuf, int nSamps, int scale) |
145 | { |
146 | int iSamp, scalef, scalei, x, y, gbMask, shift, tab4[4]; |
147 | const int *tab16, *coef; |
148 | |
149 | if (nSamps <= 0) { |
150 | return 0; |
151 | } |
152 | |
153 | scale -= SF_OFFSET; /* new range = [-100, 156] */ |
154 | |
155 | /* with two's complement numbers, scalei/scalef factorization works for pos and neg values of scale: |
156 | * [+4...+7] >> 2 = +1, [ 0...+3] >> 2 = 0, [-4...-1] >> 2 = -1, [-8...-5] >> 2 = -2 ... |
157 | * (-1 & 0x3) = 3, (-2 & 0x3) = 2, (-3 & 0x3) = 1, (0 & 0x3) = 0 |
158 | * |
159 | * Example: 2^(-5/4) = 2^(-1) * 2^(-1/4) = 2^-2 * 2^(3/4) |
160 | */ |
161 | tab16 = pow43_14[scale & 0x3]; |
162 | scalef = pow14[scale & 0x3]; |
163 | scalei = (scale >> 2) + FBITS_OUT_DQ_OFF; |
164 | |
165 | /* cache first 4 values: |
166 | * tab16[j] = Q28 for j = [0,3] |
167 | * tab4[x] = x^(4.0/3.0) * 2^(0.25*scale), Q(FBITS_OUT_DQ_OFF) |
168 | */ |
169 | shift = 28 - scalei; |
170 | if (shift > 31) { |
171 | tab4[0] = tab4[1] = tab4[2] = tab4[3] = 0; |
172 | } else if (shift <= 0) { |
173 | shift = -shift; |
174 | if (shift > 31) { |
175 | shift = 31; |
176 | } |
177 | for (x = 0; x < 4; x++) { |
178 | y = tab16[x]; |
179 | if (y > (0x7fffffff >> shift)) { |
180 | y = 0x7fffffff; /* clip (rare) */ |
181 | } else { |
182 | y <<= shift; |
183 | } |
184 | tab4[x] = y; |
185 | } |
186 | } else { |
187 | tab4[0] = 0; |
188 | tab4[1] = tab16[1] >> shift; |
189 | tab4[2] = tab16[2] >> shift; |
190 | tab4[3] = tab16[3] >> shift; |
191 | } |
192 | |
193 | gbMask = 0; |
194 | do { |
195 | iSamp = *inbuf; |
196 | x = FASTABS(iSamp); |
197 | |
198 | if (x < 4) { |
199 | y = tab4[x]; |
200 | } else { |
201 | |
202 | if (x < 16) { |
203 | /* result: y = Q25 (tab16 = Q25) */ |
204 | y = tab16[x]; |
205 | shift = 25 - scalei; |
206 | } else if (x < 64) { |
207 | /* result: y = Q21 (pow43tab[j] = Q23, scalef = Q30) */ |
208 | y = pow43[x - 16]; |
209 | shift = 21 - scalei; |
210 | y = MULSHIFT32(y, scalef); |
211 | } else { |
212 | /* normalize to [0x40000000, 0x7fffffff] |
213 | * input x = [64, 8191] = [64, 2^13-1] |
214 | * ranges: |
215 | * shift = 7: 64 - 127 |
216 | * shift = 6: 128 - 255 |
217 | * shift = 5: 256 - 511 |
218 | * shift = 4: 512 - 1023 |
219 | * shift = 3: 1024 - 2047 |
220 | * shift = 2: 2048 - 4095 |
221 | * shift = 1: 4096 - 8191 |
222 | */ |
223 | x <<= 17; |
224 | shift = 0; |
225 | if (x < 0x08000000) { |
226 | x <<= 4, shift += 4; |
227 | } |
228 | if (x < 0x20000000) { |
229 | x <<= 2, shift += 2; |
230 | } |
231 | if (x < 0x40000000) { |
232 | x <<= 1, shift += 1; |
233 | } |
234 | |
235 | coef = (x < SQRTHALF) ? poly43lo : poly43hi; |
236 | |
237 | /* polynomial */ |
238 | y = coef[0]; |
239 | y = MULSHIFT32(y, x) + coef[1]; |
240 | y = MULSHIFT32(y, x) + coef[2]; |
241 | y = MULSHIFT32(y, x) + coef[3]; |
242 | y = MULSHIFT32(y, x) + coef[4]; |
243 | y = MULSHIFT32(y, pow2frac[shift]) << 3; |
244 | |
245 | /* fractional scale |
246 | * result: y = Q21 (pow43tab[j] = Q23, scalef = Q30) |
247 | */ |
248 | y = MULSHIFT32(y, scalef); /* now y is Q24 */ |
249 | shift = 24 - scalei - pow2exp[shift]; |
250 | } |
251 | |
252 | /* integer scale */ |
253 | if (shift <= 0) { |
254 | shift = -shift; |
255 | if (shift > 31) { |
256 | shift = 31; |
257 | } |
258 | |
259 | if (y > (0x7fffffff >> shift)) { |
260 | y = 0x7fffffff; /* clip (rare) */ |
261 | } else { |
262 | y <<= shift; |
263 | } |
264 | } else { |
265 | if (shift > 31) { |
266 | shift = 31; |
267 | } |
268 | y >>= shift; |
269 | } |
270 | } |
271 | |
272 | /* sign and store (gbMask used to count GB's) */ |
273 | gbMask |= y; |
274 | |
275 | /* apply sign */ |
276 | iSamp >>= 31; |
277 | y ^= iSamp; |
278 | y -= iSamp; |
279 | |
280 | *inbuf++ = y; |
281 | } while (--nSamps); |
282 | |
283 | return gbMask; |
284 | } |
285 | |
286 | /************************************************************************************** |
287 | * Function: Dequantize |
288 | * |
289 | * Description: dequantize all transform coefficients for one channel |
290 | * |
291 | * Inputs: valid AACDecInfo struct (including unpacked, quantized coefficients) |
292 | * index of current channel |
293 | * |
294 | * Outputs: dequantized coefficients, including short-block deinterleaving |
295 | * flags indicating if intensity and/or PNS is active |
296 | * minimum guard bit count for dequantized coefficients |
297 | * |
298 | * Return: 0 if successful, error code (< 0) if error |
299 | **************************************************************************************/ |
300 | int Dequantize(AACDecInfo *aacDecInfo, int ch) |
301 | { |
302 | int gp, cb, sfb, win, width, nSamps, gbMask; |
303 | int *coef; |
304 | const short *sfbTab; |
305 | unsigned char *sfbCodeBook; |
306 | short *scaleFactors; |
307 | PSInfoBase *psi; |
308 | ICSInfo *icsInfo; |
309 | |
310 | /* validate pointers */ |
311 | if (!aacDecInfo || !aacDecInfo->psInfoBase) { |
312 | return ERR_AAC_NULL_POINTER; |
313 | } |
314 | psi = (PSInfoBase *)(aacDecInfo->psInfoBase); |
315 | icsInfo = (ch == 1 && psi->commonWin == 1) ? &(psi->icsInfo[0]) : &(psi->icsInfo[ch]); |
316 | |
317 | if (icsInfo->winSequence == 2) { |
318 | sfbTab = sfBandTabShort + sfBandTabShortOffset[psi->sampRateIdx]; |
319 | nSamps = NSAMPS_SHORT; |
320 | } else { |
321 | sfbTab = sfBandTabLong + sfBandTabLongOffset[psi->sampRateIdx]; |
322 | nSamps = NSAMPS_LONG; |
323 | } |
324 | coef = psi->coef[ch]; |
325 | sfbCodeBook = psi->sfbCodeBook[ch]; |
326 | scaleFactors = psi->scaleFactors[ch]; |
327 | |
328 | psi->intensityUsed[ch] = 0; |
329 | psi->pnsUsed[ch] = 0; |
330 | gbMask = 0; |
331 | for (gp = 0; gp < icsInfo->numWinGroup; gp++) { |
332 | for (win = 0; win < icsInfo->winGroupLen[gp]; win++) { |
333 | for (sfb = 0; sfb < icsInfo->maxSFB; sfb++) { |
334 | /* dequantize one scalefactor band (not necessary if codebook is intensity or PNS) |
335 | * for zero codebook, still run dequantizer in case non-zero pulse data was added |
336 | */ |
337 | cb = (int)(sfbCodeBook[sfb]); |
338 | width = sfbTab[sfb + 1] - sfbTab[sfb]; |
339 | if (cb >= 0 && cb <= 11) { |
340 | gbMask |= DequantBlock(coef, width, scaleFactors[sfb]); |
341 | } else if (cb == 13) { |
342 | psi->pnsUsed[ch] = 1; |
343 | } else if (cb == 14 || cb == 15) { |
344 | psi->intensityUsed[ch] = 1; /* should only happen if ch == 1 */ |
345 | } |
346 | coef += width; |
347 | } |
348 | coef += (nSamps - sfbTab[icsInfo->maxSFB]); |
349 | } |
350 | sfbCodeBook += icsInfo->maxSFB; |
351 | scaleFactors += icsInfo->maxSFB; |
352 | } |
353 | aacDecInfo->pnsUsed |= psi->pnsUsed[ch]; /* set flag if PNS used for any channel */ |
354 | |
355 | /* calculate number of guard bits in dequantized data */ |
356 | psi->gbCurrent[ch] = CLZ(gbMask) - 1; |
357 | |
358 | return ERR_AAC_NONE; |
359 | } |
360 | |
361 | /************************************************************************************** |
362 | * Function: DeinterleaveShortBlocks |
363 | * |
364 | * Description: deinterleave transform coefficients in short blocks for one channel |
365 | * |
366 | * Inputs: valid AACDecInfo struct (including unpacked, quantized coefficients) |
367 | * index of current channel |
368 | * |
369 | * Outputs: deinterleaved coefficients (window groups into 8 separate windows) |
370 | * |
371 | * Return: 0 if successful, error code (< 0) if error |
372 | * |
373 | * Notes: only necessary if deinterleaving not part of Huffman decoding |
374 | **************************************************************************************/ |
375 | int DeinterleaveShortBlocks(AACDecInfo *aacDecInfo, int ch) |
376 | { |
377 | /* not used for this implementation - short block deinterleaving performed during Huffman decoding */ |
378 | return ERR_AAC_NONE; |
379 | } |
380 |