blob: e2742f6db624c2e4a47e4866f09b653e30e1b3cf
1 | /* ***** BEGIN LICENSE BLOCK ***** |
2 | * Source last modified: $Id: sbrside.c,v 1.2 2005/05/24 16:01:55 albertofloyd 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) |
41 | * February 2005 |
42 | * |
43 | * sbrside.c - functions for unpacking side info from SBR bitstream |
44 | **************************************************************************************/ |
45 | |
46 | #include "sbr.h" |
47 | |
48 | /************************************************************************************** |
49 | * Function: GetSampRateIdx |
50 | * |
51 | * Description: get index of given sample rate |
52 | * |
53 | * Inputs: sample rate (in Hz) |
54 | * |
55 | * Outputs: none |
56 | * |
57 | * Return: index of sample rate (table 1.15 in 14496-3:2001(E)) |
58 | * -1 if sample rate not found in table |
59 | **************************************************************************************/ |
60 | int GetSampRateIdx(int sampRate) |
61 | { |
62 | int idx; |
63 | |
64 | for (idx = 0; idx < NUM_SAMPLE_RATES; idx++) { |
65 | if (sampRate == sampRateTab[idx]) { |
66 | return idx; |
67 | } |
68 | } |
69 | |
70 | return -1; |
71 | } |
72 | |
73 | /************************************************************************************** |
74 | * Function: UnpackSBRHeader |
75 | * |
76 | * Description: unpack SBR header (table 4.56) |
77 | * |
78 | * Inputs: BitStreamInfo struct pointing to start of SBR header |
79 | * |
80 | * Outputs: initialized SBRHeader struct for this SCE/CPE block |
81 | * |
82 | * Return: non-zero if frame reset is triggered, zero otherwise |
83 | **************************************************************************************/ |
84 | int UnpackSBRHeader(BitStreamInfo *bsi, SBRHeader *sbrHdr) |
85 | { |
86 | SBRHeader sbrHdrPrev; |
87 | |
88 | /* save previous values so we know whether to reset decoder */ |
89 | sbrHdrPrev.startFreq = sbrHdr->startFreq; |
90 | sbrHdrPrev.stopFreq = sbrHdr->stopFreq; |
91 | sbrHdrPrev.freqScale = sbrHdr->freqScale; |
92 | sbrHdrPrev.alterScale = sbrHdr->alterScale; |
93 | sbrHdrPrev.crossOverBand = sbrHdr->crossOverBand; |
94 | sbrHdrPrev.noiseBands = sbrHdr->noiseBands; |
95 | |
96 | sbrHdr->ampRes = GetBits(bsi, 1); |
97 | sbrHdr->startFreq = GetBits(bsi, 4); |
98 | sbrHdr->stopFreq = GetBits(bsi, 4); |
99 | sbrHdr->crossOverBand = GetBits(bsi, 3); |
100 | sbrHdr->resBitsHdr = GetBits(bsi, 2); |
101 | sbrHdr->hdrExtra1 = GetBits(bsi, 1); |
102 | sbrHdr->hdrExtra2 = GetBits(bsi, 1); |
103 | |
104 | if (sbrHdr->hdrExtra1) { |
105 | sbrHdr->freqScale = GetBits(bsi, 2); |
106 | sbrHdr->alterScale = GetBits(bsi, 1); |
107 | sbrHdr->noiseBands = GetBits(bsi, 2); |
108 | } else { |
109 | /* defaults */ |
110 | sbrHdr->freqScale = 2; |
111 | sbrHdr->alterScale = 1; |
112 | sbrHdr->noiseBands = 2; |
113 | } |
114 | |
115 | if (sbrHdr->hdrExtra2) { |
116 | sbrHdr->limiterBands = GetBits(bsi, 2); |
117 | sbrHdr->limiterGains = GetBits(bsi, 2); |
118 | sbrHdr->interpFreq = GetBits(bsi, 1); |
119 | sbrHdr->smoothMode = GetBits(bsi, 1); |
120 | } else { |
121 | /* defaults */ |
122 | sbrHdr->limiterBands = 2; |
123 | sbrHdr->limiterGains = 2; |
124 | sbrHdr->interpFreq = 1; |
125 | sbrHdr->smoothMode = 1; |
126 | } |
127 | sbrHdr->count++; |
128 | |
129 | /* if any of these have changed from previous frame, reset the SBR module */ |
130 | if (sbrHdr->startFreq != sbrHdrPrev.startFreq || sbrHdr->stopFreq != sbrHdrPrev.stopFreq || |
131 | sbrHdr->freqScale != sbrHdrPrev.freqScale || sbrHdr->alterScale != sbrHdrPrev.alterScale || |
132 | sbrHdr->crossOverBand != sbrHdrPrev.crossOverBand || sbrHdr->noiseBands != sbrHdrPrev.noiseBands |
133 | ) { |
134 | return -1; |
135 | } else { |
136 | return 0; |
137 | } |
138 | } |
139 | |
140 | /* cLog2[i] = ceil(log2(i)) (disregard i == 0) */ |
141 | static const unsigned char cLog2[9] = {0, 0, 1, 2, 2, 3, 3, 3, 3}; |
142 | |
143 | /************************************************************************************** |
144 | * Function: UnpackSBRGrid |
145 | * |
146 | * Description: unpack SBR grid (table 4.62) |
147 | * |
148 | * Inputs: BitStreamInfo struct pointing to start of SBR grid |
149 | * initialized SBRHeader struct for this SCE/CPE block |
150 | * |
151 | * Outputs: initialized SBRGrid struct for this channel |
152 | * |
153 | * Return: none |
154 | **************************************************************************************/ |
155 | static void UnpackSBRGrid(BitStreamInfo *bsi, SBRHeader *sbrHdr, SBRGrid *sbrGrid) |
156 | { |
157 | int numEnvRaw, env, rel, pBits, border, middleBorder = 0; |
158 | unsigned char relBordLead[MAX_NUM_ENV], relBordTrail[MAX_NUM_ENV]; |
159 | unsigned char relBorder0[3], relBorder1[3], relBorder[3]; |
160 | unsigned char numRelBorder0, numRelBorder1, numRelBorder, numRelLead = 0, numRelTrail; |
161 | unsigned char absBordLead = 0, absBordTrail = 0, absBorder; |
162 | |
163 | sbrGrid->ampResFrame = sbrHdr->ampRes; |
164 | sbrGrid->frameClass = GetBits(bsi, 2); |
165 | switch (sbrGrid->frameClass) { |
166 | |
167 | case SBR_GRID_FIXFIX: |
168 | numEnvRaw = GetBits(bsi, 2); |
169 | sbrGrid->numEnv = (1 << numEnvRaw); |
170 | if (sbrGrid->numEnv == 1) { |
171 | sbrGrid->ampResFrame = 0; |
172 | } |
173 | |
174 | ASSERT(sbrGrid->numEnv == 1 || sbrGrid->numEnv == 2 || sbrGrid->numEnv == 4); |
175 | |
176 | sbrGrid->freqRes[0] = GetBits(bsi, 1); |
177 | for (env = 1; env < sbrGrid->numEnv; env++) { |
178 | sbrGrid->freqRes[env] = sbrGrid->freqRes[0]; |
179 | } |
180 | |
181 | absBordLead = 0; |
182 | absBordTrail = NUM_TIME_SLOTS; |
183 | numRelLead = sbrGrid->numEnv - 1; |
184 | numRelTrail = 0; |
185 | |
186 | /* numEnv = 1, 2, or 4 */ |
187 | if (sbrGrid->numEnv == 1) { |
188 | border = NUM_TIME_SLOTS / 1; |
189 | } else if (sbrGrid->numEnv == 2) { |
190 | border = NUM_TIME_SLOTS / 2; |
191 | } else { |
192 | border = NUM_TIME_SLOTS / 4; |
193 | } |
194 | |
195 | for (rel = 0; rel < numRelLead; rel++) { |
196 | relBordLead[rel] = border; |
197 | } |
198 | |
199 | middleBorder = (sbrGrid->numEnv >> 1); |
200 | |
201 | break; |
202 | |
203 | case SBR_GRID_FIXVAR: |
204 | absBorder = GetBits(bsi, 2) + NUM_TIME_SLOTS; |
205 | numRelBorder = GetBits(bsi, 2); |
206 | sbrGrid->numEnv = numRelBorder + 1; |
207 | for (rel = 0; rel < numRelBorder; rel++) { |
208 | relBorder[rel] = 2 * GetBits(bsi, 2) + 2; |
209 | } |
210 | |
211 | pBits = cLog2[sbrGrid->numEnv + 1]; |
212 | sbrGrid->pointer = GetBits(bsi, pBits); |
213 | |
214 | for (env = sbrGrid->numEnv - 1; env >= 0; env--) { |
215 | sbrGrid->freqRes[env] = GetBits(bsi, 1); |
216 | } |
217 | |
218 | absBordLead = 0; |
219 | absBordTrail = absBorder; |
220 | numRelLead = 0; |
221 | numRelTrail = numRelBorder; |
222 | |
223 | for (rel = 0; rel < numRelTrail; rel++) { |
224 | relBordTrail[rel] = relBorder[rel]; |
225 | } |
226 | |
227 | if (sbrGrid->pointer > 1) { |
228 | middleBorder = sbrGrid->numEnv + 1 - sbrGrid->pointer; |
229 | } else { |
230 | middleBorder = sbrGrid->numEnv - 1; |
231 | } |
232 | |
233 | break; |
234 | |
235 | case SBR_GRID_VARFIX: |
236 | absBorder = GetBits(bsi, 2); |
237 | numRelBorder = GetBits(bsi, 2); |
238 | sbrGrid->numEnv = numRelBorder + 1; |
239 | for (rel = 0; rel < numRelBorder; rel++) { |
240 | relBorder[rel] = 2 * GetBits(bsi, 2) + 2; |
241 | } |
242 | |
243 | pBits = cLog2[sbrGrid->numEnv + 1]; |
244 | sbrGrid->pointer = GetBits(bsi, pBits); |
245 | |
246 | for (env = 0; env < sbrGrid->numEnv; env++) { |
247 | sbrGrid->freqRes[env] = GetBits(bsi, 1); |
248 | } |
249 | |
250 | absBordLead = absBorder; |
251 | absBordTrail = NUM_TIME_SLOTS; |
252 | numRelLead = numRelBorder; |
253 | numRelTrail = 0; |
254 | |
255 | for (rel = 0; rel < numRelLead; rel++) { |
256 | relBordLead[rel] = relBorder[rel]; |
257 | } |
258 | |
259 | if (sbrGrid->pointer == 0) { |
260 | middleBorder = 1; |
261 | } else if (sbrGrid->pointer == 1) { |
262 | middleBorder = sbrGrid->numEnv - 1; |
263 | } else { |
264 | middleBorder = sbrGrid->pointer - 1; |
265 | } |
266 | |
267 | break; |
268 | |
269 | case SBR_GRID_VARVAR: |
270 | absBordLead = GetBits(bsi, 2); /* absBorder0 */ |
271 | absBordTrail = GetBits(bsi, 2) + NUM_TIME_SLOTS; /* absBorder1 */ |
272 | numRelBorder0 = GetBits(bsi, 2); |
273 | numRelBorder1 = GetBits(bsi, 2); |
274 | |
275 | sbrGrid->numEnv = numRelBorder0 + numRelBorder1 + 1; |
276 | ASSERT(sbrGrid->numEnv <= 5); |
277 | |
278 | for (rel = 0; rel < numRelBorder0; rel++) { |
279 | relBorder0[rel] = 2 * GetBits(bsi, 2) + 2; |
280 | } |
281 | |
282 | for (rel = 0; rel < numRelBorder1; rel++) { |
283 | relBorder1[rel] = 2 * GetBits(bsi, 2) + 2; |
284 | } |
285 | |
286 | pBits = cLog2[numRelBorder0 + numRelBorder1 + 2]; |
287 | sbrGrid->pointer = GetBits(bsi, pBits); |
288 | |
289 | for (env = 0; env < sbrGrid->numEnv; env++) { |
290 | sbrGrid->freqRes[env] = GetBits(bsi, 1); |
291 | } |
292 | |
293 | numRelLead = numRelBorder0; |
294 | numRelTrail = numRelBorder1; |
295 | |
296 | for (rel = 0; rel < numRelLead; rel++) { |
297 | relBordLead[rel] = relBorder0[rel]; |
298 | } |
299 | |
300 | for (rel = 0; rel < numRelTrail; rel++) { |
301 | relBordTrail[rel] = relBorder1[rel]; |
302 | } |
303 | |
304 | if (sbrGrid->pointer > 1) { |
305 | middleBorder = sbrGrid->numEnv + 1 - sbrGrid->pointer; |
306 | } else { |
307 | middleBorder = sbrGrid->numEnv - 1; |
308 | } |
309 | |
310 | break; |
311 | } |
312 | |
313 | /* build time border vector */ |
314 | sbrGrid->envTimeBorder[0] = absBordLead * SAMPLES_PER_SLOT; |
315 | |
316 | rel = 0; |
317 | border = absBordLead; |
318 | for (env = 1; env <= numRelLead; env++) { |
319 | border += relBordLead[rel++]; |
320 | sbrGrid->envTimeBorder[env] = border * SAMPLES_PER_SLOT; |
321 | } |
322 | |
323 | rel = 0; |
324 | border = absBordTrail; |
325 | for (env = sbrGrid->numEnv - 1; env > numRelLead; env--) { |
326 | border -= relBordTrail[rel++]; |
327 | sbrGrid->envTimeBorder[env] = border * SAMPLES_PER_SLOT; |
328 | } |
329 | |
330 | sbrGrid->envTimeBorder[sbrGrid->numEnv] = absBordTrail * SAMPLES_PER_SLOT; |
331 | |
332 | if (sbrGrid->numEnv > 1) { |
333 | sbrGrid->numNoiseFloors = 2; |
334 | sbrGrid->noiseTimeBorder[0] = sbrGrid->envTimeBorder[0]; |
335 | sbrGrid->noiseTimeBorder[1] = sbrGrid->envTimeBorder[middleBorder]; |
336 | sbrGrid->noiseTimeBorder[2] = sbrGrid->envTimeBorder[sbrGrid->numEnv]; |
337 | } else { |
338 | sbrGrid->numNoiseFloors = 1; |
339 | sbrGrid->noiseTimeBorder[0] = sbrGrid->envTimeBorder[0]; |
340 | sbrGrid->noiseTimeBorder[1] = sbrGrid->envTimeBorder[1]; |
341 | } |
342 | } |
343 | |
344 | /************************************************************************************** |
345 | * Function: UnpackDeltaTimeFreq |
346 | * |
347 | * Description: unpack time/freq flags for delta coding of SBR envelopes (table 4.63) |
348 | * |
349 | * Inputs: BitStreamInfo struct pointing to start of dt/df flags |
350 | * number of envelopes |
351 | * number of noise floors |
352 | * |
353 | * Outputs: delta flags for envelope and noise floors |
354 | * |
355 | * Return: none |
356 | **************************************************************************************/ |
357 | static void UnpackDeltaTimeFreq(BitStreamInfo *bsi, int numEnv, unsigned char *deltaFlagEnv, |
358 | int numNoiseFloors, unsigned char *deltaFlagNoise) |
359 | { |
360 | int env, noiseFloor; |
361 | |
362 | for (env = 0; env < numEnv; env++) { |
363 | deltaFlagEnv[env] = GetBits(bsi, 1); |
364 | } |
365 | |
366 | for (noiseFloor = 0; noiseFloor < numNoiseFloors; noiseFloor++) { |
367 | deltaFlagNoise[noiseFloor] = GetBits(bsi, 1); |
368 | } |
369 | } |
370 | |
371 | /************************************************************************************** |
372 | * Function: UnpackInverseFilterMode |
373 | * |
374 | * Description: unpack invf flags for chirp factor calculation (table 4.64) |
375 | * |
376 | * Inputs: BitStreamInfo struct pointing to start of invf flags |
377 | * number of noise floor bands |
378 | * |
379 | * Outputs: invf flags for noise floor bands |
380 | * |
381 | * Return: none |
382 | **************************************************************************************/ |
383 | static void UnpackInverseFilterMode(BitStreamInfo *bsi, int numNoiseFloorBands, unsigned char *mode) |
384 | { |
385 | int n; |
386 | |
387 | for (n = 0; n < numNoiseFloorBands; n++) { |
388 | mode[n] = GetBits(bsi, 2); |
389 | } |
390 | } |
391 | |
392 | /************************************************************************************** |
393 | * Function: UnpackSinusoids |
394 | * |
395 | * Description: unpack sinusoid (harmonic) flags for each SBR subband (table 4.67) |
396 | * |
397 | * Inputs: BitStreamInfo struct pointing to start of sinusoid flags |
398 | * number of high resolution SBR subbands (nHigh) |
399 | * |
400 | * Outputs: sinusoid flags for each SBR subband, zero-filled above nHigh |
401 | * |
402 | * Return: none |
403 | **************************************************************************************/ |
404 | static void UnpackSinusoids(BitStreamInfo *bsi, int nHigh, int addHarmonicFlag, unsigned char *addHarmonic) |
405 | { |
406 | int n; |
407 | |
408 | n = 0; |
409 | if (addHarmonicFlag) { |
410 | for (; n < nHigh; n++) { |
411 | addHarmonic[n] = GetBits(bsi, 1); |
412 | } |
413 | } |
414 | |
415 | /* zero out unused bands */ |
416 | for (; n < MAX_QMF_BANDS; n++) { |
417 | addHarmonic[n] = 0; |
418 | } |
419 | } |
420 | |
421 | /************************************************************************************** |
422 | * Function: CopyCouplingGrid |
423 | * |
424 | * Description: copy grid parameters from left to right for channel coupling |
425 | * |
426 | * Inputs: initialized SBRGrid struct for left channel |
427 | * |
428 | * Outputs: initialized SBRGrid struct for right channel |
429 | * |
430 | * Return: none |
431 | **************************************************************************************/ |
432 | static void CopyCouplingGrid(SBRGrid *sbrGridLeft, SBRGrid *sbrGridRight) |
433 | { |
434 | int env, noiseFloor; |
435 | |
436 | sbrGridRight->frameClass = sbrGridLeft->frameClass; |
437 | sbrGridRight->ampResFrame = sbrGridLeft->ampResFrame; |
438 | sbrGridRight->pointer = sbrGridLeft->pointer; |
439 | |
440 | sbrGridRight->numEnv = sbrGridLeft->numEnv; |
441 | for (env = 0; env < sbrGridLeft->numEnv; env++) { |
442 | sbrGridRight->envTimeBorder[env] = sbrGridLeft->envTimeBorder[env]; |
443 | sbrGridRight->freqRes[env] = sbrGridLeft->freqRes[env]; |
444 | } |
445 | sbrGridRight->envTimeBorder[env] = sbrGridLeft->envTimeBorder[env]; /* borders are [0, numEnv] inclusive */ |
446 | |
447 | sbrGridRight->numNoiseFloors = sbrGridLeft->numNoiseFloors; |
448 | for (noiseFloor = 0; noiseFloor <= sbrGridLeft->numNoiseFloors; noiseFloor++) { |
449 | sbrGridRight->noiseTimeBorder[noiseFloor] = sbrGridLeft->noiseTimeBorder[noiseFloor]; |
450 | } |
451 | |
452 | /* numEnvPrev, numNoiseFloorsPrev, freqResPrev are updated in DecodeSBREnvelope() and DecodeSBRNoise() */ |
453 | } |
454 | |
455 | /************************************************************************************** |
456 | * Function: CopyCouplingInverseFilterMode |
457 | * |
458 | * Description: copy invf flags from left to right for channel coupling |
459 | * |
460 | * Inputs: invf flags for left channel |
461 | * number of noise floor bands |
462 | * |
463 | * Outputs: invf flags for right channel |
464 | * |
465 | * Return: none |
466 | **************************************************************************************/ |
467 | static void CopyCouplingInverseFilterMode(int numNoiseFloorBands, unsigned char *modeLeft, unsigned char *modeRight) |
468 | { |
469 | int band; |
470 | |
471 | for (band = 0; band < numNoiseFloorBands; band++) { |
472 | modeRight[band] = modeLeft[band]; |
473 | } |
474 | } |
475 | |
476 | /************************************************************************************** |
477 | * Function: UnpackSBRSingleChannel |
478 | * |
479 | * Description: unpack sideband info (grid, delta flags, invf flags, envelope and |
480 | * noise floor configuration, sinusoids) for a single channel |
481 | * |
482 | * Inputs: BitStreamInfo struct pointing to start of sideband info |
483 | * initialized PSInfoSBR struct (after parsing SBR header and building |
484 | * frequency tables) |
485 | * base output channel (range = [0, nChans-1]) |
486 | * |
487 | * Outputs: updated PSInfoSBR struct (SBRGrid and SBRChan) |
488 | * |
489 | * Return: none |
490 | **************************************************************************************/ |
491 | void UnpackSBRSingleChannel(BitStreamInfo *bsi, PSInfoSBR *psi, int chBase) |
492 | { |
493 | int bitsLeft; |
494 | SBRHeader *sbrHdr = &(psi->sbrHdr[chBase]); |
495 | SBRGrid *sbrGridL = &(psi->sbrGrid[chBase + 0]); |
496 | SBRFreq *sbrFreq = &(psi->sbrFreq[chBase]); |
497 | SBRChan *sbrChanL = &(psi->sbrChan[chBase + 0]); |
498 | |
499 | psi->dataExtra = GetBits(bsi, 1); |
500 | if (psi->dataExtra) { |
501 | psi->resBitsData = GetBits(bsi, 4); |
502 | } |
503 | |
504 | UnpackSBRGrid(bsi, sbrHdr, sbrGridL); |
505 | UnpackDeltaTimeFreq(bsi, sbrGridL->numEnv, sbrChanL->deltaFlagEnv, sbrGridL->numNoiseFloors, sbrChanL->deltaFlagNoise); |
506 | UnpackInverseFilterMode(bsi, sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1]); |
507 | |
508 | DecodeSBREnvelope(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0); |
509 | DecodeSBRNoise(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0); |
510 | |
511 | sbrChanL->addHarmonicFlag[1] = GetBits(bsi, 1); |
512 | UnpackSinusoids(bsi, sbrFreq->nHigh, sbrChanL->addHarmonicFlag[1], sbrChanL->addHarmonic[1]); |
513 | |
514 | psi->extendedDataPresent = GetBits(bsi, 1); |
515 | if (psi->extendedDataPresent) { |
516 | psi->extendedDataSize = GetBits(bsi, 4); |
517 | if (psi->extendedDataSize == 15) { |
518 | psi->extendedDataSize += GetBits(bsi, 8); |
519 | } |
520 | |
521 | bitsLeft = 8 * psi->extendedDataSize; |
522 | |
523 | /* get ID, unpack extension info, do whatever is necessary with it... */ |
524 | while (bitsLeft > 0) { |
525 | GetBits(bsi, 8); |
526 | bitsLeft -= 8; |
527 | } |
528 | } |
529 | } |
530 | |
531 | /************************************************************************************** |
532 | * Function: UnpackSBRChannelPair |
533 | * |
534 | * Description: unpack sideband info (grid, delta flags, invf flags, envelope and |
535 | * noise floor configuration, sinusoids) for a channel pair |
536 | * |
537 | * Inputs: BitStreamInfo struct pointing to start of sideband info |
538 | * initialized PSInfoSBR struct (after parsing SBR header and building |
539 | * frequency tables) |
540 | * base output channel (range = [0, nChans-1]) |
541 | * |
542 | * Outputs: updated PSInfoSBR struct (SBRGrid and SBRChan for both channels) |
543 | * |
544 | * Return: none |
545 | **************************************************************************************/ |
546 | void UnpackSBRChannelPair(BitStreamInfo *bsi, PSInfoSBR *psi, int chBase) |
547 | { |
548 | int bitsLeft; |
549 | SBRHeader *sbrHdr = &(psi->sbrHdr[chBase]); |
550 | SBRGrid *sbrGridL = &(psi->sbrGrid[chBase + 0]), *sbrGridR = &(psi->sbrGrid[chBase + 1]); |
551 | SBRFreq *sbrFreq = &(psi->sbrFreq[chBase]); |
552 | SBRChan *sbrChanL = &(psi->sbrChan[chBase + 0]), *sbrChanR = &(psi->sbrChan[chBase + 1]); |
553 | |
554 | psi->dataExtra = GetBits(bsi, 1); |
555 | if (psi->dataExtra) { |
556 | psi->resBitsData = GetBits(bsi, 4); |
557 | psi->resBitsData = GetBits(bsi, 4); |
558 | } |
559 | |
560 | psi->couplingFlag = GetBits(bsi, 1); |
561 | if (psi->couplingFlag) { |
562 | UnpackSBRGrid(bsi, sbrHdr, sbrGridL); |
563 | CopyCouplingGrid(sbrGridL, sbrGridR); |
564 | |
565 | UnpackDeltaTimeFreq(bsi, sbrGridL->numEnv, sbrChanL->deltaFlagEnv, sbrGridL->numNoiseFloors, sbrChanL->deltaFlagNoise); |
566 | UnpackDeltaTimeFreq(bsi, sbrGridR->numEnv, sbrChanR->deltaFlagEnv, sbrGridR->numNoiseFloors, sbrChanR->deltaFlagNoise); |
567 | |
568 | UnpackInverseFilterMode(bsi, sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1]); |
569 | CopyCouplingInverseFilterMode(sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1], sbrChanR->invfMode[1]); |
570 | |
571 | DecodeSBREnvelope(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0); |
572 | DecodeSBRNoise(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0); |
573 | DecodeSBREnvelope(bsi, psi, sbrGridR, sbrFreq, sbrChanR, 1); |
574 | DecodeSBRNoise(bsi, psi, sbrGridR, sbrFreq, sbrChanR, 1); |
575 | |
576 | /* pass RIGHT sbrChan struct */ |
577 | UncoupleSBREnvelope(psi, sbrGridL, sbrFreq, sbrChanR); |
578 | UncoupleSBRNoise(psi, sbrGridL, sbrFreq, sbrChanR); |
579 | |
580 | } else { |
581 | UnpackSBRGrid(bsi, sbrHdr, sbrGridL); |
582 | UnpackSBRGrid(bsi, sbrHdr, sbrGridR); |
583 | UnpackDeltaTimeFreq(bsi, sbrGridL->numEnv, sbrChanL->deltaFlagEnv, sbrGridL->numNoiseFloors, sbrChanL->deltaFlagNoise); |
584 | UnpackDeltaTimeFreq(bsi, sbrGridR->numEnv, sbrChanR->deltaFlagEnv, sbrGridR->numNoiseFloors, sbrChanR->deltaFlagNoise); |
585 | UnpackInverseFilterMode(bsi, sbrFreq->numNoiseFloorBands, sbrChanL->invfMode[1]); |
586 | UnpackInverseFilterMode(bsi, sbrFreq->numNoiseFloorBands, sbrChanR->invfMode[1]); |
587 | |
588 | DecodeSBREnvelope(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0); |
589 | DecodeSBREnvelope(bsi, psi, sbrGridR, sbrFreq, sbrChanR, 1); |
590 | DecodeSBRNoise(bsi, psi, sbrGridL, sbrFreq, sbrChanL, 0); |
591 | DecodeSBRNoise(bsi, psi, sbrGridR, sbrFreq, sbrChanR, 1); |
592 | } |
593 | |
594 | sbrChanL->addHarmonicFlag[1] = GetBits(bsi, 1); |
595 | UnpackSinusoids(bsi, sbrFreq->nHigh, sbrChanL->addHarmonicFlag[1], sbrChanL->addHarmonic[1]); |
596 | |
597 | sbrChanR->addHarmonicFlag[1] = GetBits(bsi, 1); |
598 | UnpackSinusoids(bsi, sbrFreq->nHigh, sbrChanR->addHarmonicFlag[1], sbrChanR->addHarmonic[1]); |
599 | |
600 | psi->extendedDataPresent = GetBits(bsi, 1); |
601 | if (psi->extendedDataPresent) { |
602 | psi->extendedDataSize = GetBits(bsi, 4); |
603 | if (psi->extendedDataSize == 15) { |
604 | psi->extendedDataSize += GetBits(bsi, 8); |
605 | } |
606 | |
607 | bitsLeft = 8 * psi->extendedDataSize; |
608 | |
609 | /* get ID, unpack extension info, do whatever is necessary with it... */ |
610 | while (bitsLeft > 0) { |
611 | GetBits(bsi, 8); |
612 | bitsLeft -= 8; |
613 | } |
614 | } |
615 | } |
616 |