FastLED 3.9.15
Loading...
Searching...
No Matches
dqchan.hpp
Go to the documentation of this file.
1/* ***** BEGIN LICENSE BLOCK *****
2 * Version: RCSL 1.0/RPSL 1.0
3 *
4 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
5 *
6 * The contents of this file, and the files included with this file, are
7 * subject to the current version of the RealNetworks Public Source License
8 * Version 1.0 (the "RPSL") available at
9 * http://www.helixcommunity.org/content/rpsl unless you have licensed
10 * the file under the RealNetworks Community Source License Version 1.0
11 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
12 * in which case the RCSL will apply. You may also obtain the license terms
13 * directly from RealNetworks. You may not use this file except in
14 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
15 * applicable to this file, the RCSL. Please see the applicable RPSL or
16 * RCSL for the rights, obligations and limitations governing use of the
17 * contents of the file.
18 *
19 * This file is part of the Helix DNA Technology. RealNetworks is the
20 * developer of the Original Code and owns the copyrights in the portions
21 * it created.
22 *
23 * This file, and the files included with this file, is distributed and made
24 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
25 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
26 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
27 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
28 *
29 * Technology Compatibility Kit Test Suite(s) Location:
30 * http://www.helixcommunity.org/content/tck
31 *
32 * Contributor(s):
33 *
34 * ***** END LICENSE BLOCK ***** */
35
36/**************************************************************************************
37 * Fixed-point MP3 decoder
38 * Jon Recker (jrecker@real.com), Ken Cooke (kenc@real.com)
39 * August 2003
40 *
41 * dqchan.c - dequantization of transform coefficients
42 **************************************************************************************/
43
44#include "coder.h"
45#include "assembly.h"
46#include "fl/stl/stdint.h"
47#include "fl/stl/noexcept.h"
48
49namespace fl {
50namespace third_party {
51
52
53
54
55typedef int ARRAY3[3]; /* for short-block reordering */
56
57/* optional pre-emphasis for high-frequency scale factor bands */
58static const char preTab[22] = { 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0 };
59
60/* pow(2,-i/4) for i=0..3, Q31 format */
62 0x7fffffff, (int32_t)0x6ba27e65, (int32_t)0x5a82799a, 0x4c1bf829
63};
64
65/* pow(2,-i/4) * pow(j,4/3) for i=0..3 j=0..15, Q25 format */
66int32_t pow43_14[4][16] = {
67{ 0x00000000, 0x10000000, 0x285145f3, (int32_t)0x453a5cdb, /* Q28 */
68 0x0cb2ff53, 0x111989d6, 0x15ce31c8, 0x1ac7f203,
69 0x20000000, 0x257106b9, 0x2b16b4a3, (int32_t)0x30ed74b4,
70 (int32_t)0x36f23fa5, (int32_t)0x3d227bd3, (int32_t)0x437be656, (int32_t)0x49fc823c, },
71
72{ 0x00000000, 0x0d744fcd, 0x21e71f26, (int32_t)0x3a36abd9,
73 0x0aadc084, 0x0e610e6e, 0x12560c1d, 0x168523cf,
74 0x1ae89f99, 0x1f7c03a4, 0x243bae49, 0x29249c67,
75 0x2e34420f, (int32_t)0x33686f85, (int32_t)0x38bf3dff, (int32_t)0x3e370182, },
76
77{ 0x00000000, 0x0b504f33, 0x1c823e07, (int32_t)0x30f39a55,
78 0x08facd62, 0x0c176319, 0x0f6b3522, 0x12efe2ad,
79 0x16a09e66, 0x1a79a317, 0x1e77e301, 0x2298d5b4,
80 0x26da56fc, 0x2b3a902a, 0x2fb7e7e7, (int32_t)0x3450f650, },
81
82{ 0x00000000, 0x09837f05, 0x17f910d7, 0x2929c7a9,
83 0x078d0dfa, 0x0a2ae661, 0x0cf73154, 0x0fec91cb,
84 0x1306fe0a, 0x16434a6c, 0x199ee595, 0x1d17ae3d,
85 0x20abd76a, 0x2459d551, 0x28204fbb, 0x2bfe1808, },
86};
87
88/* pow(j,4/3) for j=16..63, Q23 format */
90 0x1428a2fa, 0x15db1bd6, 0x1796302c, 0x19598d85,
91 0x1b24e8bb, 0x1cf7fcfa, 0x1ed28af2, 0x20b4582a,
92 0x229d2e6e, 0x248cdb55, 0x26832fda, 0x28800000,
93 0x2a832287, 0x2c8c70a8, 0x2e9bc5d8, (int32_t)0x30b0ff99,
94 (int32_t)0x32cbfd4a, (int32_t)0x34eca001, (int32_t)0x3712ca62, (int32_t)0x393e6088,
95 (int32_t)0x3b6f47e0, (int32_t)0x3da56717, (int32_t)0x3fe0a5fc, (int32_t)0x4220ed72,
96 (int32_t)0x44662758, (int32_t)0x46b03e7c, (int32_t)0x48ff1e87, (int32_t)0x4b52b3f3,
97 (int32_t)0x4daaebfd, (int32_t)0x5007b497, (int32_t)0x5268fc62, (int32_t)0x54ceb29c,
98 (int32_t)0x5738c721, (int32_t)0x59a72a59, (int32_t)0x5c19cd35, (int32_t)0x5e90a129,
99 (int32_t)0x610b9821, (int32_t)0x638aa47f, (int32_t)0x660db90f, (int32_t)0x6894c90b,
100 (int32_t)0x6b1fc80c, (int32_t)0x6daeaa0d, (int32_t)0x70416360, (int32_t)0x72d7e8b0,
101 (int32_t)0x75722ef9, (int32_t)0x78102b85, (int32_t)0x7ab1d3ec, (int32_t)0x7d571e09,
102};
103
104/* sqrt(0.5) in Q31 format */
105#define SQRTHALF 0x5a82799a
106
107/*
108 * Minimax polynomial approximation to pow(x, 4/3), over the range
109 * poly43lo: x = [0.5, 0.7071]
110 * poly43hi: x = [0.7071, 1.0]
111 *
112 * Relative error < 1E-7
113 * Coefs are scaled by 4, 2, 1, 0.5, 0.25
114 */
115int32_t poly43lo[5] = { (int32_t)0x29a0bda9, (int32_t)0xb02e4828, (int32_t)0x5957aa1b, (int32_t)0x236c498d, (int32_t)0xff581859 };
116int32_t poly43hi[5] = { (int32_t)0x10852163, (int32_t)0xd333f6a4, (int32_t)0x46e9408b, (int32_t)0x27c2cef0, (int32_t)0xfef577b4 };
117
118/* pow(2, i*4/3) as exp and frac */
119int pow2exp[8] = { 14, 13, 11, 10, 9, 7, 6, 5 };
120
122 (int32_t)0x6597fa94, (int32_t)0x50a28be6, 0x7fffffff, (int32_t)0x6597fa94,
123 (int32_t)0x50a28be6, 0x7fffffff, (int32_t)0x6597fa94, (int32_t)0x50a28be6
124};
125
126/**************************************************************************************
127 * Function: DequantBlock
128 *
129 * Description: Ken's highly-optimized, low memory dequantizer performing the operation
130 * y = pow(x, 4.0/3.0) * pow(2, 25 - scale/4.0)
131 *
132 * Inputs: input buffer of decode Huffman codewords (signed-magnitude)
133 * output buffer of same length (in-place (outbuf = inbuf) is allowed)
134 * number of samples
135 *
136 * Outputs: dequantized samples in Q25 format
137 *
138 * Return: bitwise-OR of the unsigned outputs (for guard bit calculations)
139 **************************************************************************************/
140static int DequantBlock(int32_t *inbuf, int32_t *outbuf, int num, int scale) FL_NOEXCEPT
141{
142 int tab4[4];
143 int32_t scalef, scalei, shift;
144 int32_t sx, x, y;
145 int32_t mask = 0;
146 const int32_t *tab16, *coef;
147
148 tab16 = pow43_14[scale & 0x3];
149 scalef = pow14[scale & 0x3];
150 scalei = MIN(scale >> 2, 31); /* smallest input scale = -47, so smallest scalei = -12 */
151
152 /* cache first 4 values */
153 shift = MIN(scalei + 3, 31);
154 shift = MAX(shift, 0);
155 tab4[0] = 0;
156 tab4[1] = tab16[1] >> shift;
157 tab4[2] = tab16[2] >> shift;
158 tab4[3] = tab16[3] >> shift;
159
160 do {
161
162 sx = *inbuf++;
163 x = sx & 0x7fffffff; /* sx = sign|mag */
164
165 if (x < 4) {
166
167 y = tab4[x];
168
169 } else if (x < 16) {
170
171 y = tab16[x];
172 y = (scalei < 0) ? y << -scalei : y >> scalei;
173
174 } else {
175
176 if (x < 64) {
177
178 y = pow43[x-16];
179
180 /* fractional scale */
181 y = MULSHIFT32(y, scalef);
182 shift = scalei - 3;
183
184 } else {
185
186 /* normalize to [0x40000000, 0x7fffffff] */
187 x <<= 17;
188 shift = 0;
189 if (x < 0x08000000)
190 x <<= 4, shift += 4;
191 if (x < 0x20000000)
192 x <<= 2, shift += 2;
193 if (x < 0x40000000)
194 x <<= 1, shift += 1;
195
196 coef = (x < SQRTHALF) ? poly43lo : poly43hi;
197
198 /* polynomial */
199 y = coef[0];
200 y = MULSHIFT32(y, x) + coef[1];
201 y = MULSHIFT32(y, x) + coef[2];
202 y = MULSHIFT32(y, x) + coef[3];
203 y = MULSHIFT32(y, x) + coef[4];
204 y = MULSHIFT32(y, pow2frac[shift]) << 3;
205
206 /* fractional scale */
207 y = MULSHIFT32(y, scalef);
208 shift = scalei - pow2exp[shift];
209 }
210
211 /* integer scale */
212 if (shift < 0) {
213 shift = -shift;
214 if (y > ((int32_t)0x7fffffff >> shift))
215 y = (int32_t)0x7fffffff; /* clip */
216 else
217 y <<= shift;
218 } else {
219 y >>= shift;
220 }
221 }
222
223 /* sign and store */
224 mask |= y;
225 *outbuf++ = (sx < 0) ? -y : y;
226
227 } while (--num);
228
229 return mask;
230}
231
232/**************************************************************************************
233 * Function: DequantChannel
234 *
235 * Description: dequantize one granule, one channel worth of decoded Huffman codewords
236 *
237 * Inputs: sample buffer (decoded Huffman codewords), length = MAX_NSAMP samples
238 * work buffer for reordering short-block, length = MAX_REORDER_SAMPS
239 * samples (3 * width of largest short-block critical band)
240 * non-zero bound for this channel/granule
241 * valid FrameHeader, SideInfoSub, ScaleFactorInfoSub, and CriticalBandInfo
242 * structures for this channel/granule
243 *
244 * Outputs: MAX_NSAMP dequantized samples in sampleBuf
245 * updated non-zero bound (indicating which samples are != 0 after DQ)
246 * filled-in cbi structure indicating start and end critical bands
247 *
248 * Return: minimum number of guard bits in dequantized sampleBuf
249 *
250 * Notes: dequantized samples in Q(DQ_FRACBITS_OUT) format
251 **************************************************************************************/
252int32_t DequantChannel(int32_t *sampleBuf, int32_t *workBuf, int32_t *nonZeroBound, FrameHeader *fh, SideInfoSub *sis,
254{
255 int32_t i, j, w, cb;
256 int32_t cbEndL, cbStartS, cbEndS;
257 int32_t nSamps, nonZero, sfactMultiplier, gbMask;
258 int32_t globalGain, gainI;
259 int32_t cbMax[3];
260 ARRAY3 *buf; /* short block reorder */
261
262 /* set default start/end points for short/long blocks - will update with non-zero cb info */
263 if (sis->blockType == 2) {
264 if (sis->mixedBlock) {
265 cbEndL = (fh->ver == MPEG1 ? 8 : 6);
266 cbStartS = 3;
267 } else {
268 cbEndL = 0;
269 cbStartS = 0;
270 }
271 cbEndS = 13;
272 } else {
273 /* long block */
274 cbEndL = 22;
275 cbStartS = 13;
276 cbEndS = 13;
277 }
278 cbMax[2] = cbMax[1] = cbMax[0] = 0;
279 gbMask = 0;
280 i = 0;
281
282 /* sfactScale = 0 --> quantizer step size = 2
283 * sfactScale = 1 --> quantizer step size = sqrt(2)
284 * so sfactMultiplier = 2 or 4 (jump through globalGain by powers of 2 or sqrt(2))
285 */
286 sfactMultiplier = 2 * (sis->sfactScale + 1);
287
288 /* offset globalGain by -2 if midSide enabled, for 1/sqrt(2) used in MidSideProc()
289 * (DequantBlock() does 0.25 * gainI so knocking it down by two is the same as
290 * dividing every sample by sqrt(2) = multiplying by 2^-.5)
291 */
292 globalGain = sis->globalGain;
293 if (fh->modeExt >> 1)
294 globalGain -= 2;
295 globalGain += IMDCT_SCALE; /* scale everything by sqrt(2), for fast IMDCT36 */
296
297 /* long blocks */
298 for (cb = 0; cb < cbEndL; cb++) {
299
300 nonZero = 0;
301 nSamps = fh->sfBand->l[cb + 1] - fh->sfBand->l[cb];
302 gainI = 210 - globalGain + sfactMultiplier * (sfis->l[cb] + (sis->preFlag ? (int)preTab[cb] : 0));
303
304 nonZero |= DequantBlock(sampleBuf + i, sampleBuf + i, nSamps, gainI);
305 i += nSamps;
306
307 /* update highest non-zero critical band */
308 if (nonZero)
309 cbMax[0] = cb;
310 gbMask |= nonZero;
311
312 if (i >= *nonZeroBound)
313 break;
314 }
315
316 /* set cbi (Type, EndS[], EndSMax will be overwritten if we proceed to do short blocks) */
317 cbi->cbType = 0; /* long only */
318 cbi->cbEndL = cbMax[0];
319 cbi->cbEndS[0] = cbi->cbEndS[1] = cbi->cbEndS[2] = 0;
320 cbi->cbEndSMax = 0;
321
322 /* early exit if no short blocks */
323 if (cbStartS >= 12)
324 return CLZ(gbMask) - 1;
325
326 /* short blocks */
327 cbMax[2] = cbMax[1] = cbMax[0] = cbStartS;
328 for (cb = cbStartS; cb < cbEndS; cb++) {
329
330 nSamps = fh->sfBand->s[cb + 1] - fh->sfBand->s[cb];
331 for (w = 0; w < 3; w++) {
332 nonZero = 0;
333 gainI = 210 - globalGain + 8*sis->subBlockGain[w] + sfactMultiplier*(sfis->s[cb][w]);
334
335 nonZero |= DequantBlock(sampleBuf + i + nSamps*w, workBuf + nSamps*w, nSamps, gainI);
336
337 /* update highest non-zero critical band */
338 if (nonZero)
339 cbMax[w] = cb;
340 gbMask |= nonZero;
341 }
342
343 /* reorder blocks */
344 buf = (ARRAY3 *)(sampleBuf + i);
345 i += 3*nSamps;
346 for (j = 0; j < nSamps; j++) {
347 buf[j][0] = workBuf[0*nSamps + j];
348 buf[j][1] = workBuf[1*nSamps + j];
349 buf[j][2] = workBuf[2*nSamps + j];
350 }
351
352 ASSERT(3*nSamps <= MAX_REORDER_SAMPS);
353
354 if (i >= *nonZeroBound)
355 break;
356 }
357
358 /* i = last non-zero INPUT sample processed, which corresponds to highest possible non-zero
359 * OUTPUT sample (after reorder)
360 * however, the original nzb is no longer necessarily true
361 * for each cb, buf[][] is updated with 3*nSamps samples (i increases 3*nSamps each time)
362 * (buf[j + 1][0] = 3 (input) samples ahead of buf[j][0])
363 * so update nonZeroBound to i
364 */
365 *nonZeroBound = i;
366
367 ASSERT(*nonZeroBound <= MAX_NSAMP);
368
369 cbi->cbType = (sis->mixedBlock ? 2 : 1); /* 2 = mixed short/long, 1 = short only */
370
371 cbi->cbEndS[0] = cbMax[0];
372 cbi->cbEndS[1] = cbMax[1];
373 cbi->cbEndS[2] = cbMax[2];
374
375 cbi->cbEndSMax = cbMax[0];
376 cbi->cbEndSMax = MAX(cbi->cbEndSMax, cbMax[1]);
377 cbi->cbEndSMax = MAX(cbi->cbEndSMax, cbMax[2]);
378
379 return CLZ(gbMask) - 1;
380}
381
382} // namespace third_party
383} // namespace fl
fl::UISlider scale("Scale", 4,.1, 4,.1)
#define MIN(a, b)
Definition coder.h:64
#define MAX_REORDER_SAMPS
Definition coder.h:108
#define ASSERT(x)
Definition coder.h:56
#define IMDCT_SCALE
Definition coder.h:103
#define MAX(a, b)
Definition coder.h:60
#define SQRTHALF
Definition dqchan.hpp:105
@ MPEG1
Definition mp3dec.h:83
#define MAX_NSAMP
Definition mp3dec.h:79
static int DequantBlock(int32_t *inbuf, int32_t *outbuf, int num, int scale) FL_NOEXCEPT
Definition dqchan.hpp:140
int32_t pow43_14[4][16]
Definition dqchan.hpp:66
__inline int32_t MULSHIFT32(int32_t x, int32_t y) FL_NOEXCEPT
Multiply together two 32-bit numbers and return the top 32-bits of the result.
Definition assembly.h:503
int32_t poly43lo[5]
Definition dqchan.hpp:115
int32_t pow14[4]
Definition dqchan.hpp:61
int32_t poly43hi[5]
Definition dqchan.hpp:116
static const char preTab[22]
Definition dqchan.hpp:58
int ARRAY3[3]
Definition dqchan.hpp:55
struct fl::third_party::_ScaleFactorInfoSub ScaleFactorInfoSub
struct fl::third_party::_FrameHeader FrameHeader
fl::i32 int32_t
Definition coder.h:220
struct fl::third_party::_SideInfoSub SideInfoSub
__inline int32_t CLZ(int32_t x) FL_NOEXCEPT
Leading zeros.
Definition assembly.h:527
int32_t DequantChannel(int32_t *sampleBuf, int32_t *workBuf, int32_t *nonZeroBound, FrameHeader *fh, SideInfoSub *sis, ScaleFactorInfoSub *sfis, CriticalBandInfo *cbi) FL_NOEXCEPT
Definition dqchan.hpp:252
int32_t pow2frac[8]
Definition dqchan.hpp:121
int32_t pow43[]
Definition dqchan.hpp:89
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_NOEXCEPT