summaryrefslogtreecommitdiff
path: root/audio_codec/libraac/sbrside.c (plain)
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 **************************************************************************************/
60int 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 **************************************************************************************/
84int 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) */
141static 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 **************************************************************************************/
155static 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 **************************************************************************************/
357static 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 **************************************************************************************/
383static 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 **************************************************************************************/
404static 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 **************************************************************************************/
432static 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 **************************************************************************************/
467static 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 **************************************************************************************/
491void 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 **************************************************************************************/
546void 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