FastLED 3.9.15
Loading...
Searching...
No Matches
scalfact.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 * June 2003
40 *
41 * scalfact.c - scalefactor unpacking functions
42 **************************************************************************************/
43
44#include "coder.h"
45#include "fl/stl/stdint.h"
46
47namespace fl {
48namespace third_party {
49
50/* scale factor lengths (num bits) */
51static const char SFLenTab[16][2] = {
52 {0, 0}, {0, 1},
53 {0, 2}, {0, 3},
54 {3, 0}, {1, 1},
55 {1, 2}, {1, 3},
56 {2, 1}, {2, 2},
57 {2, 3}, {3, 1},
58 {3, 2}, {3, 3},
59 {4, 2}, {4, 3},
60};
61
62/**************************************************************************************
63 * Function: UnpackSFMPEG1
64 *
65 * Description: unpack MPEG 1 scalefactors from bitstream
66 *
67 * Inputs: BitStreamInfo, SideInfoSub, ScaleFactorInfoSub structs for this
68 * granule/channel
69 * vector of scfsi flags from side info, length = 4 (MAX_SCFBD)
70 * index of current granule
71 * ScaleFactorInfoSub from granule 0 (for granule 1, if scfsi[i] is set,
72 * then we just replicate the scale factors from granule 0 in the
73 * i'th set of scalefactor bands)
74 *
75 * Outputs: updated BitStreamInfo struct
76 * scalefactors in sfis (short and/or long arrays, as appropriate)
77 *
78 * Return: none
79 *
80 * Notes: set order of short blocks to s[band][window] instead of s[window][band]
81 * so that we index through consectutive memory locations when unpacking
82 * (make sure dequantizer follows same convention)
83 * Illegal Intensity Position = 7 (always) for MPEG1 scale factors
84 **************************************************************************************/
85static void UnpackSFMPEG1(BitStreamInfo *bsi, SideInfoSub *sis, ScaleFactorInfoSub *sfis, int32_t *scfsi, int gr, ScaleFactorInfoSub *sfisGr0) FL_NOEXCEPT
86{
87 int sfb;
88 int slen0, slen1;
89
90 /* these can be 0, so make sure GetBits(bsi, 0) returns 0 (no >> 32 or anything) */
91 slen0 = (int)SFLenTab[sis->sfCompress][0];
92 slen1 = (int)SFLenTab[sis->sfCompress][1];
93
94 if (sis->blockType == 2) {
95 /* short block, type 2 (implies winSwitchFlag == 1) */
96 if (sis->mixedBlock) {
97 /* do long block portion */
98 for (sfb = 0; sfb < 8; sfb++)
99 sfis->l[sfb] = (char)GetBits(bsi, slen0);
100 sfb = 3;
101 } else {
102 /* all short blocks */
103 sfb = 0;
104 }
105
106 for ( ; sfb < 6; sfb++) {
107 sfis->s[sfb][0] = (char)GetBits(bsi, slen0);
108 sfis->s[sfb][1] = (char)GetBits(bsi, slen0);
109 sfis->s[sfb][2] = (char)GetBits(bsi, slen0);
110 }
111
112 for ( ; sfb < 12; sfb++) {
113 sfis->s[sfb][0] = (char)GetBits(bsi, slen1);
114 sfis->s[sfb][1] = (char)GetBits(bsi, slen1);
115 sfis->s[sfb][2] = (char)GetBits(bsi, slen1);
116 }
117
118 /* last sf band not transmitted */
119 sfis->s[12][0] = sfis->s[12][1] = sfis->s[12][2] = 0;
120 } else {
121 /* long blocks, type 0, 1, or 3 */
122 if(gr == 0) {
123 /* first granule */
124 for (sfb = 0; sfb < 11; sfb++)
125 sfis->l[sfb] = (char)GetBits(bsi, slen0);
126 for (sfb = 11; sfb < 21; sfb++)
127 sfis->l[sfb] = (char)GetBits(bsi, slen1);
128 return;
129 } else {
130 /* second granule
131 * scfsi: 0 = different scalefactors for each granule, 1 = copy sf's from granule 0 into granule 1
132 * for block type == 2, scfsi is always 0
133 */
134 sfb = 0;
135 if(scfsi[0]) for( ; sfb < 6 ; sfb++) sfis->l[sfb] = sfisGr0->l[sfb];
136 else for( ; sfb < 6 ; sfb++) sfis->l[sfb] = (char)GetBits(bsi, slen0);
137 if(scfsi[1]) for( ; sfb <11 ; sfb++) sfis->l[sfb] = sfisGr0->l[sfb];
138 else for( ; sfb <11 ; sfb++) sfis->l[sfb] = (char)GetBits(bsi, slen0);
139 if(scfsi[2]) for( ; sfb <16 ; sfb++) sfis->l[sfb] = sfisGr0->l[sfb];
140 else for( ; sfb <16 ; sfb++) sfis->l[sfb] = (char)GetBits(bsi, slen1);
141 if(scfsi[3]) for( ; sfb <21 ; sfb++) sfis->l[sfb] = sfisGr0->l[sfb];
142 else for( ; sfb <21 ; sfb++) sfis->l[sfb] = (char)GetBits(bsi, slen1);
143 }
144 /* last sf band not transmitted */
145 sfis->l[21] = 0;
146 sfis->l[22] = 0;
147 }
148}
149
150/* NRTab[size + 3*is_right][block type][partition]
151 * block type index: 0 = (bt0,bt1,bt3), 1 = bt2 non-mixed, 2 = bt2 mixed
152 * partition: scale factor groups (sfb1 through sfb4)
153 * for block type = 2 (mixed or non-mixed) / by 3 is rolled into this table
154 * (for 3 short blocks per long block)
155 * see 2.4.3.2 in MPEG 2 (low sample rate) spec
156 * stuff rolled into this table:
157 * NRTab[x][1][y] --> (NRTab[x][1][y]) / 3
158 * NRTab[x][2][>=1] --> (NRTab[x][2][>=1]) / 3 (first partition is long block)
159 */
160static const char NRTab[6][3][4] = {
161 /* non-intensity stereo */
162 { {6, 5, 5, 5},
163 {3, 3, 3, 3}, /* includes / 3 */
164 {6, 3, 3, 3}, /* includes / 3 except for first entry */
165 },
166 { {6, 5, 7, 3},
167 {3, 3, 4, 2},
168 {6, 3, 4, 2},
169 },
170 { {11, 10, 0, 0},
171 {6, 6, 0, 0},
172 {6, 3, 6, 0}, /* spec = [15,18,0,0], but 15 = 6L + 9S, so move 9/3=3 into col 1, 18/3=6 into col 2 and adj. slen[1,2] below */
173 },
174 /* intensity stereo, right chan */
175 { {7, 7, 7, 0},
176 {4, 4, 4, 0},
177 {6, 5, 4, 0},
178 },
179 { {6, 6, 6, 3},
180 {4, 3, 3, 2},
181 {6, 4, 3, 2},
182 },
183 { {8, 8, 5, 0},
184 {5, 4, 3, 0},
185 {6, 6, 3, 0},
186 }
187};
188
189/**************************************************************************************
190 * Function: UnpackSFMPEG2
191 *
192 * Description: unpack MPEG 2 scalefactors from bitstream
193 *
194 * Inputs: BitStreamInfo, SideInfoSub, ScaleFactorInfoSub structs for this
195 * granule/channel
196 * index of current granule and channel
197 * ScaleFactorInfoSub from this granule
198 * modeExt field from frame header, to tell whether intensity stereo is on
199 * ScaleFactorJS struct for storing IIP info used in Dequant()
200 *
201 * Outputs: updated BitStreamInfo struct
202 * scalefactors in sfis (short and/or long arrays, as appropriate)
203 * updated intensityScale and preFlag flags
204 *
205 * Return: none
206 *
207 * Notes: Illegal Intensity Position = (2^slen) - 1 for MPEG2 scale factors
208 *
209 * TODO: optimize the / and % stuff (only do one divide, get modulo x
210 * with (x / m) * m, etc.)
211 **************************************************************************************/
212static void UnpackSFMPEG2(BitStreamInfo *bsi, SideInfoSub *sis, ScaleFactorInfoSub *sfis, int gr, int ch, int modeExt, ScaleFactorJS *sfjs) FL_NOEXCEPT
213{
214 (void)gr; // Unused parameter - kept for API consistency
215
216 int i, sfb, sfcIdx, btIdx, nrIdx;
217 int slen[4], nr[4];
218 int sfCompress, preFlag, intensityScale;
219
220 sfCompress = sis->sfCompress;
221 preFlag = 0;
222 intensityScale = 0;
223
224 /* stereo mode bits (1 = on): bit 1 = mid-side on/off, bit 0 = intensity on/off */
225 if (! ((modeExt & 0x01) && (ch == 1)) ) {
226 /* in other words: if ((modeExt & 0x01) == 0 || ch == 0) */
227 if (sfCompress < 400) {
228 /* max slen = floor[(399/16) / 5] = 4 */
229 slen[0] = (sfCompress >> 4) / 5;
230 slen[1]= (sfCompress >> 4) % 5;
231 slen[2]= (sfCompress & 0x0f) >> 2;
232 slen[3]= (sfCompress & 0x03);
233 sfcIdx = 0;
234 } else if (sfCompress < 500) {
235 /* max slen = floor[(99/4) / 5] = 4 */
236 sfCompress -= 400;
237 slen[0] = (sfCompress >> 2) / 5;
238 slen[1]= (sfCompress >> 2) % 5;
239 slen[2]= (sfCompress & 0x03);
240 slen[3]= 0;
241 sfcIdx = 1;
242 } else {
243 /* max slen = floor[11/3] = 3 (sfCompress = 9 bits in MPEG2) */
244 sfCompress -= 500;
245 slen[0] = sfCompress / 3;
246 slen[1] = sfCompress % 3;
247 slen[2] = slen[3] = 0;
248 if (sis->mixedBlock) {
249 /* adjust for long/short mix logic (see comment above in NRTab[] definition) */
250 slen[2] = slen[1];
251 slen[1] = slen[0];
252 }
253 preFlag = 1;
254 sfcIdx = 2;
255 }
256 } else {
257 /* intensity stereo ch = 1 (right) */
258 intensityScale = sfCompress & 0x01;
259 sfCompress >>= 1;
260 if (sfCompress < 180) {
261 /* max slen = floor[35/6] = 5 (from mod 36) */
262 slen[0] = (sfCompress / 36);
263 slen[1] = (sfCompress % 36) / 6;
264 slen[2] = (sfCompress % 36) % 6;
265 slen[3] = 0;
266 sfcIdx = 3;
267 } else if (sfCompress < 244) {
268 /* max slen = floor[63/16] = 3 */
269 sfCompress -= 180;
270 slen[0] = (sfCompress & 0x3f) >> 4;
271 slen[1] = (sfCompress & 0x0f) >> 2;
272 slen[2] = (sfCompress & 0x03);
273 slen[3] = 0;
274 sfcIdx = 4;
275 } else {
276 /* max slen = floor[11/3] = 3 (max sfCompress >> 1 = 511/2 = 255) */
277 sfCompress -= 244;
278 slen[0] = (sfCompress / 3);
279 slen[1] = (sfCompress % 3);
280 slen[2] = slen[3] = 0;
281 sfcIdx = 5;
282 }
283 }
284
285 /* set index based on block type: (0,1,3) --> 0, (2 non-mixed) --> 1, (2 mixed) ---> 2 */
286 btIdx = 0;
287 if (sis->blockType == 2)
288 btIdx = (sis->mixedBlock ? 2 : 1);
289 for (i = 0; i < 4; i++)
290 nr[i] = (int)NRTab[sfcIdx][btIdx][i];
291
292 /* save intensity stereo scale factor info */
293 if( (modeExt & 0x01) && (ch == 1) ) {
294 for (i = 0; i < 4; i++) {
295 sfjs->slen[i] = slen[i];
296 sfjs->nr[i] = nr[i];
297 }
298 sfjs->intensityScale = intensityScale;
299 }
300 sis->preFlag = preFlag;
301
302 /* short blocks */
303 if(sis->blockType == 2) {
304 if(sis->mixedBlock) {
305 /* do long block portion */
306 for (sfb=0; sfb < 6; sfb++) {
307 sfis->l[sfb] = (char)GetBits(bsi, slen[0]);
308 }
309 sfb = 3; /* start sfb for short */
310 nrIdx = 1;
311 } else {
312 /* all short blocks, so start nr, sfb at 0 */
313 sfb = 0;
314 nrIdx = 0;
315 }
316
317 /* remaining short blocks, sfb just keeps incrementing */
318 for ( ; nrIdx <= 3; nrIdx++) {
319 for (i=0; i < nr[nrIdx]; i++, sfb++) {
320 sfis->s[sfb][0] = (char)GetBits(bsi, slen[nrIdx]);
321 sfis->s[sfb][1] = (char)GetBits(bsi, slen[nrIdx]);
322 sfis->s[sfb][2] = (char)GetBits(bsi, slen[nrIdx]);
323 }
324 }
325 /* last sf band not transmitted */
326 sfis->s[12][0] = sfis->s[12][1] = sfis->s[12][2] = 0;
327 } else {
328 /* long blocks */
329 sfb = 0;
330 for (nrIdx = 0; nrIdx <= 3; nrIdx++) {
331 for(i=0; i < nr[nrIdx]; i++, sfb++) {
332 sfis->l[sfb] = (char)GetBits(bsi, slen[nrIdx]);
333 }
334 }
335 /* last sf band not transmitted */
336 sfis->l[21] = sfis->l[22] = 0;
337
338 }
339}
340
341/**************************************************************************************
342 * Function: UnpackScaleFactors
343 *
344 * Description: parse the fields of the MP3 scale factor data section
345 *
346 * Inputs: MP3DecInfo structure filled by UnpackFrameHeader() and UnpackSideInfo()
347 * buffer pointing to the MP3 scale factor data
348 * pointer to bit offset (0-7) indicating starting bit in buf[0]
349 * number of bits available in data buffer
350 * index of current granule and channel
351 *
352 * Outputs: updated platform-specific ScaleFactorInfo struct
353 * updated bitOffset
354 *
355 * Return: length (in bytes) of scale factor data, -1 if null input pointers
356 **************************************************************************************/
357int UnpackScaleFactors(MP3DecInfo *mp3DecInfo, const unsigned char *buf, int *bitOffset, int bitsAvail, int gr, int ch) FL_NOEXCEPT
358{
359 int bitsUsed;
360 const unsigned char *startBuf;
361 BitStreamInfo bitStreamInfo, *bsi;
362 FrameHeader *fh;
363 SideInfo *si;
364 ScaleFactorInfo *sfi;
365
366 /* validate pointers */
367 if (!mp3DecInfo || !mp3DecInfo->FrameHeaderPS || !mp3DecInfo->SideInfoPS || !mp3DecInfo->ScaleFactorInfoPS)
368 return -1;
369 fh = ((FrameHeader *)(mp3DecInfo->FrameHeaderPS));
370 si = ((SideInfo *)(mp3DecInfo->SideInfoPS));
371 sfi = ((ScaleFactorInfo *)(mp3DecInfo->ScaleFactorInfoPS));
372
373 /* init GetBits reader */
374 startBuf = buf;
375 bsi = &bitStreamInfo;
376 SetBitstreamPointer(bsi, (bitsAvail + *bitOffset + 7) / 8, buf);
377 if (*bitOffset)
378 GetBits(bsi, *bitOffset);
379
380 if (fh->ver == MPEG1)
381 UnpackSFMPEG1(bsi, &si->sis[gr][ch], &sfi->sfis[gr][ch], si->scfsi[ch], gr, &sfi->sfis[0][ch]);
382 else
383 UnpackSFMPEG2(bsi, &si->sis[gr][ch], &sfi->sfis[gr][ch], gr, ch, fh->modeExt, &sfi->sfjs);
384
385 mp3DecInfo->part23Length[gr][ch] = si->sis[gr][ch].part23Length;
386
387 bitsUsed = CalcBitsUsed(bsi, buf, *bitOffset);
388 buf += (bitsUsed + *bitOffset) >> 3;
389 *bitOffset = (bitsUsed + *bitOffset) & 0x07;
390
391 return (buf - startBuf);
392}
393
394} // namespace third_party
395} // namespace fl
struct _MP3DecInfo MP3DecInfo
@ MPEG1
Definition mp3dec.h:83
struct fl::third_party::_BitStreamInfo BitStreamInfo
int UnpackScaleFactors(MP3DecInfo *mp3DecInfo, const unsigned char *buf, int *bitOffset, int bitsAvail, int gr, int ch) FL_NOEXCEPT
Definition scalfact.hpp:357
static const char SFLenTab[16][2]
Definition scalfact.hpp:51
struct fl::third_party::_ScaleFactorInfoSub ScaleFactorInfoSub
struct fl::third_party::_FrameHeader FrameHeader
uint32_t GetBits(BitStreamInfo *bsi, int32_t nBits) FL_NOEXCEPT
void SetBitstreamPointer(BitStreamInfo *bsi, int32_t nBytes, const unsigned char *buf) FL_NOEXCEPT
Definition bitstream.hpp:65
struct fl::third_party::_SideInfo SideInfo
static void UnpackSFMPEG1(BitStreamInfo *bsi, SideInfoSub *sis, ScaleFactorInfoSub *sfis, int32_t *scfsi, int gr, ScaleFactorInfoSub *sfisGr0) FL_NOEXCEPT
Definition scalfact.hpp:85
fl::i32 int32_t
Definition coder.h:220
struct fl::third_party::_SideInfoSub SideInfoSub
struct fl::third_party::_ScaleFactorJS ScaleFactorJS
static const char NRTab[6][3][4]
Definition scalfact.hpp:160
struct fl::third_party::_ScaleFactorInfo ScaleFactorInfo
static void UnpackSFMPEG2(BitStreamInfo *bsi, SideInfoSub *sis, ScaleFactorInfoSub *sfis, int gr, int ch, int modeExt, ScaleFactorJS *sfjs) FL_NOEXCEPT
Definition scalfact.hpp:212
int32_t CalcBitsUsed(BitStreamInfo *bsi, const unsigned char *startBuf, int32_t startOffset) FL_NOEXCEPT
ScaleFactorInfoSub sfis[MAX_NGRAN][MAX_NCHAN]
Definition coder.h:270
SideInfoSub sis[MAX_NGRAN][MAX_NCHAN]
Definition coder.h:200
int32_t scfsi[MAX_NCHAN][MAX_SCFBD]
Definition coder.h:198
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_NOEXCEPT