Coverage Report

Created: 2026-01-16 07:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fdk-aac/libSBRdec/src/sbrdec_drc.cpp
Line
Count
Source
1
/* -----------------------------------------------------------------------------
2
Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4
© Copyright  1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten
5
Forschung e.V. All rights reserved.
6
7
 1.    INTRODUCTION
8
The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9
that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10
scheme for digital audio. This FDK AAC Codec software is intended to be used on
11
a wide variety of Android devices.
12
13
AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14
general perceptual audio codecs. AAC-ELD is considered the best-performing
15
full-bandwidth communications codec by independent studies and is widely
16
deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17
specifications.
18
19
Patent licenses for necessary patent claims for the FDK AAC Codec (including
20
those of Fraunhofer) may be obtained through Via Licensing
21
(www.vialicensing.com) or through the respective patent owners individually for
22
the purpose of encoding or decoding bit streams in products that are compliant
23
with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24
Android devices already license these patent claims through Via Licensing or
25
directly from the patent owners, and therefore FDK AAC Codec software may
26
already be covered under those patent licenses when it is used for those
27
licensed purposes only.
28
29
Commercially-licensed AAC software libraries, including floating-point versions
30
with enhanced sound quality, are also available from Fraunhofer. Users are
31
encouraged to check the Fraunhofer website for additional applications
32
information and documentation.
33
34
2.    COPYRIGHT LICENSE
35
36
Redistribution and use in source and binary forms, with or without modification,
37
are permitted without payment of copyright license fees provided that you
38
satisfy the following conditions:
39
40
You must retain the complete text of this software license in redistributions of
41
the FDK AAC Codec or your modifications thereto in source code form.
42
43
You must retain the complete text of this software license in the documentation
44
and/or other materials provided with redistributions of the FDK AAC Codec or
45
your modifications thereto in binary form. You must make available free of
46
charge copies of the complete source code of the FDK AAC Codec and your
47
modifications thereto to recipients of copies in binary form.
48
49
The name of Fraunhofer may not be used to endorse or promote products derived
50
from this library without prior written permission.
51
52
You may not charge copyright license fees for anyone to use, copy or distribute
53
the FDK AAC Codec software or your modifications thereto.
54
55
Your modified versions of the FDK AAC Codec must carry prominent notices stating
56
that you changed the software and the date of any change. For modified versions
57
of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58
must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59
AAC Codec Library for Android."
60
61
3.    NO PATENT LICENSE
62
63
NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64
limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65
Fraunhofer provides no warranty of patent non-infringement with respect to this
66
software.
67
68
You may use this FDK AAC Codec software or modifications thereto only for
69
purposes that are authorized by appropriate patent licenses.
70
71
4.    DISCLAIMER
72
73
This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74
holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75
including but not limited to the implied warranties of merchantability and
76
fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77
CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78
or consequential damages, including but not limited to procurement of substitute
79
goods or services; loss of use, data, or profits, or business interruption,
80
however caused and on any theory of liability, whether in contract, strict
81
liability, or tort (including negligence), arising in any way out of the use of
82
this software, even if advised of the possibility of such damage.
83
84
5.    CONTACT INFORMATION
85
86
Fraunhofer Institute for Integrated Circuits IIS
87
Attention: Audio and Multimedia Departments - FDK AAC LL
88
Am Wolfsmantel 33
89
91058 Erlangen, Germany
90
91
www.iis.fraunhofer.de/amm
92
amm-info@iis.fraunhofer.de
93
----------------------------------------------------------------------------- */
94
95
/**************************** SBR decoder library ******************************
96
97
   Author(s):   Christian Griebel
98
99
   Description: Dynamic range control (DRC) decoder tool for SBR
100
101
*******************************************************************************/
102
103
#include "sbrdec_drc.h"
104
105
/* DRC - Offset table for QMF interpolation. Shifted by one index position.
106
   The table defines the (short) window borders rounded to the nearest QMF
107
   timeslot. It has the size 16 because it is accessed with the
108
   drcInterpolationScheme that is read from the bitstream with 4 bit. */
109
static const UCHAR winBorderToColMappingTab[2][16] = {
110
    /*-1, 0, 1, 2,  3,  4,  5,  6,  7,  8 */
111
    {0, 0, 4, 8, 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32,
112
     32}, /* 1024 framing */
113
    {0, 0, 4, 8, 11, 15, 19, 23, 26, 30, 30, 30, 30, 30, 30,
114
     30} /*  960 framing */
115
};
116
117
/*!
118
  \brief Initialize DRC QMF factors
119
120
  \hDrcData Handle to DRC channel data.
121
122
  \return none
123
*/
124
1.44M
void sbrDecoder_drcInitChannel(HANDLE_SBR_DRC_CHANNEL hDrcData) {
125
1.44M
  int band;
126
127
1.44M
  if (hDrcData == NULL) {
128
0
    return;
129
0
  }
130
131
94.1M
  for (band = 0; band < (64); band++) {
132
92.6M
    hDrcData->prevFact_mag[band] = FL2FXCONST_DBL(0.5f);
133
92.6M
  }
134
135
24.6M
  for (band = 0; band < SBRDEC_MAX_DRC_BANDS; band++) {
136
23.1M
    hDrcData->currFact_mag[band] = FL2FXCONST_DBL(0.5f);
137
23.1M
    hDrcData->nextFact_mag[band] = FL2FXCONST_DBL(0.5f);
138
23.1M
  }
139
140
1.44M
  hDrcData->prevFact_exp = 1;
141
1.44M
  hDrcData->currFact_exp = 1;
142
1.44M
  hDrcData->nextFact_exp = 1;
143
144
1.44M
  hDrcData->numBandsCurr = 1;
145
1.44M
  hDrcData->numBandsNext = 1;
146
147
1.44M
  hDrcData->winSequenceCurr = 0;
148
1.44M
  hDrcData->winSequenceNext = 0;
149
150
1.44M
  hDrcData->drcInterpolationSchemeCurr = 0;
151
1.44M
  hDrcData->drcInterpolationSchemeNext = 0;
152
153
1.44M
  hDrcData->enable = 0;
154
1.44M
}
155
156
/*!
157
  \brief Swap DRC QMF scaling factors after they have been applied.
158
159
  \hDrcData Handle to DRC channel data.
160
161
  \return none
162
*/
163
2.49M
void sbrDecoder_drcUpdateChannel(HANDLE_SBR_DRC_CHANNEL hDrcData) {
164
2.49M
  if (hDrcData == NULL) {
165
0
    return;
166
0
  }
167
2.49M
  if (hDrcData->enable != 1) {
168
2.24M
    return;
169
2.24M
  }
170
171
  /* swap previous data */
172
255k
  FDKmemcpy(hDrcData->currFact_mag, hDrcData->nextFact_mag,
173
255k
            SBRDEC_MAX_DRC_BANDS * sizeof(FIXP_DBL));
174
175
255k
  hDrcData->currFact_exp = hDrcData->nextFact_exp;
176
177
255k
  hDrcData->numBandsCurr = hDrcData->numBandsNext;
178
179
255k
  FDKmemcpy(hDrcData->bandTopCurr, hDrcData->bandTopNext,
180
255k
            SBRDEC_MAX_DRC_BANDS * sizeof(USHORT));
181
182
255k
  hDrcData->drcInterpolationSchemeCurr = hDrcData->drcInterpolationSchemeNext;
183
184
255k
  hDrcData->winSequenceCurr = hDrcData->winSequenceNext;
185
255k
}
186
187
/*!
188
  \brief Apply DRC factors slot based.
189
190
  \hDrcData Handle to DRC channel data.
191
  \qmfRealSlot Pointer to real valued QMF data of one time slot.
192
  \qmfImagSlot Pointer to the imaginary QMF data of one time slot.
193
  \col Number of the time slot.
194
  \numQmfSubSamples Total number of time slots for one frame.
195
  \scaleFactor Pointer to the out scale factor of the time slot.
196
197
  \return None.
198
*/
199
void sbrDecoder_drcApplySlot(HANDLE_SBR_DRC_CHANNEL hDrcData,
200
                             FIXP_DBL *qmfRealSlot, FIXP_DBL *qmfImagSlot,
201
8.30M
                             int col, int numQmfSubSamples, int maxShift) {
202
8.30M
  const UCHAR *winBorderToColMap;
203
204
8.30M
  int band, bottomMdct, topMdct, bin, useLP;
205
8.30M
  int indx = numQmfSubSamples - (numQmfSubSamples >> 1) - 10; /* l_border */
206
8.30M
  int frameLenFlag = (numQmfSubSamples == 30) ? 1 : 0;
207
8.30M
  int frameSize = (frameLenFlag == 1) ? 960 : 1024;
208
209
8.30M
  const FIXP_DBL *fact_mag = NULL;
210
8.30M
  INT fact_exp = 0;
211
8.30M
  UINT numBands = 0;
212
8.30M
  USHORT *bandTop = NULL;
213
8.30M
  int shortDrc = 0;
214
215
8.30M
  FIXP_DBL alphaValue = FL2FXCONST_DBL(0.0f);
216
217
8.30M
  if (hDrcData == NULL) {
218
0
    return;
219
0
  }
220
8.30M
  if (hDrcData->enable != 1) {
221
792k
    return;
222
792k
  }
223
224
7.50M
  winBorderToColMap = winBorderToColMappingTab[frameLenFlag];
225
226
7.50M
  useLP = (qmfImagSlot == NULL) ? 1 : 0;
227
228
7.50M
  col += indx;
229
7.50M
  bottomMdct = 0;
230
231
  /* get respective data and calc interpolation factor */
232
7.50M
  if (col < (numQmfSubSamples >> 1)) {    /* first half of current frame */
233
2.55M
    if (hDrcData->winSequenceCurr != 2) { /* long window */
234
2.45M
      int j = col + (numQmfSubSamples >> 1);
235
236
2.45M
      if (j < winBorderToColMap[15]) {
237
2.45M
        if (hDrcData->drcInterpolationSchemeCurr == 0) {
238
1.32M
          INT k = (frameLenFlag) ? 0x4444445 : 0x4000000;
239
240
1.32M
          alphaValue = (FIXP_DBL)(j * k);
241
1.32M
        } else {
242
1.13M
          if (j >=
243
1.13M
              (int)winBorderToColMap[hDrcData->drcInterpolationSchemeCurr]) {
244
462k
            alphaValue = (FIXP_DBL)MAXVAL_DBL;
245
462k
          }
246
1.13M
        }
247
2.45M
      } else {
248
0
        alphaValue = (FIXP_DBL)MAXVAL_DBL;
249
0
      }
250
2.45M
    } else { /* short windows */
251
96.2k
      shortDrc = 1;
252
96.2k
    }
253
254
2.55M
    fact_mag = hDrcData->currFact_mag;
255
2.55M
    fact_exp = hDrcData->currFact_exp;
256
2.55M
    numBands = hDrcData->numBandsCurr;
257
2.55M
    bandTop = hDrcData->bandTopCurr;
258
4.95M
  } else if (col < numQmfSubSamples) {    /* second half of current frame */
259
3.72M
    if (hDrcData->winSequenceNext != 2) { /* next: long window */
260
3.46M
      int j = col - (numQmfSubSamples >> 1);
261
262
3.46M
      if (j < winBorderToColMap[15]) {
263
3.46M
        if (hDrcData->drcInterpolationSchemeNext == 0) {
264
1.79M
          INT k = (frameLenFlag) ? 0x4444445 : 0x4000000;
265
266
1.79M
          alphaValue = (FIXP_DBL)(j * k);
267
1.79M
        } else {
268
1.67M
          if (j >=
269
1.67M
              (int)winBorderToColMap[hDrcData->drcInterpolationSchemeNext]) {
270
53.3k
            alphaValue = (FIXP_DBL)MAXVAL_DBL;
271
53.3k
          }
272
1.67M
        }
273
3.46M
      } else {
274
0
        alphaValue = (FIXP_DBL)MAXVAL_DBL;
275
0
      }
276
277
3.46M
      fact_mag = hDrcData->nextFact_mag;
278
3.46M
      fact_exp = hDrcData->nextFact_exp;
279
3.46M
      numBands = hDrcData->numBandsNext;
280
3.46M
      bandTop = hDrcData->bandTopNext;
281
3.46M
    } else {                                /* next: short windows */
282
256k
      if (hDrcData->winSequenceCurr != 2) { /* current: long window */
283
118k
        alphaValue = (FIXP_DBL)0;
284
285
118k
        fact_mag = hDrcData->nextFact_mag;
286
118k
        fact_exp = hDrcData->nextFact_exp;
287
118k
        numBands = hDrcData->numBandsNext;
288
118k
        bandTop = hDrcData->bandTopNext;
289
137k
      } else { /* current: short windows */
290
137k
        shortDrc = 1;
291
292
137k
        fact_mag = hDrcData->currFact_mag;
293
137k
        fact_exp = hDrcData->currFact_exp;
294
137k
        numBands = hDrcData->numBandsCurr;
295
137k
        bandTop = hDrcData->bandTopCurr;
296
137k
      }
297
256k
    }
298
3.72M
  } else {                                /* first half of next frame */
299
1.23M
    if (hDrcData->winSequenceNext != 2) { /* long window */
300
1.13M
      int j = col - (numQmfSubSamples >> 1);
301
302
1.13M
      if (j < winBorderToColMap[15]) {
303
1.13M
        if (hDrcData->drcInterpolationSchemeNext == 0) {
304
599k
          INT k = (frameLenFlag) ? 0x4444445 : 0x4000000;
305
306
599k
          alphaValue = (FIXP_DBL)(j * k);
307
599k
        } else {
308
535k
          if (j >=
309
535k
              (int)winBorderToColMap[hDrcData->drcInterpolationSchemeNext]) {
310
18.4k
            alphaValue = (FIXP_DBL)MAXVAL_DBL;
311
18.4k
          }
312
535k
        }
313
1.13M
      } else {
314
0
        alphaValue = (FIXP_DBL)MAXVAL_DBL;
315
0
      }
316
1.13M
    } else { /* short windows */
317
95.1k
      shortDrc = 1;
318
95.1k
    }
319
320
1.23M
    fact_mag = hDrcData->nextFact_mag;
321
1.23M
    fact_exp = hDrcData->nextFact_exp;
322
1.23M
    numBands = hDrcData->numBandsNext;
323
1.23M
    bandTop = hDrcData->bandTopNext;
324
325
1.23M
    col -= numQmfSubSamples;
326
1.23M
  }
327
328
  /* process bands */
329
83.7M
  for (band = 0; band < (int)numBands; band++) {
330
76.1M
    int bottomQmf, topQmf;
331
332
76.1M
    FIXP_DBL drcFact_mag = (FIXP_DBL)MAXVAL_DBL;
333
334
76.1M
    topMdct = (bandTop[band] + 1) << 2;
335
336
76.1M
    if (!shortDrc) { /* long window */
337
73.5M
      if (frameLenFlag) {
338
        /* 960 framing */
339
66.4M
        bottomQmf = fMultIfloor((FIXP_DBL)0x4444445, bottomMdct);
340
66.4M
        topQmf = fMultIfloor((FIXP_DBL)0x4444445, topMdct);
341
342
66.4M
        topMdct = 30 * topQmf;
343
66.4M
      } else {
344
        /* 1024 framing */
345
7.03M
        topMdct &= ~0x1f;
346
347
7.03M
        bottomQmf = bottomMdct >> 5;
348
7.03M
        topQmf = topMdct >> 5;
349
7.03M
      }
350
351
73.5M
      if (band == ((int)numBands - 1)) {
352
7.17M
        topQmf = (64);
353
7.17M
      }
354
355
728M
      for (bin = bottomQmf; bin < topQmf; bin++) {
356
654M
        FIXP_DBL drcFact1_mag = hDrcData->prevFact_mag[bin];
357
654M
        FIXP_DBL drcFact2_mag = fact_mag[band];
358
359
        /* normalize scale factors */
360
654M
        if (hDrcData->prevFact_exp < maxShift) {
361
41.7M
          drcFact1_mag >>= maxShift - hDrcData->prevFact_exp;
362
41.7M
        }
363
654M
        if (fact_exp < maxShift) {
364
16.4M
          drcFact2_mag >>= maxShift - fact_exp;
365
16.4M
        }
366
367
        /* interpolate */
368
654M
        if (alphaValue == (FIXP_DBL)0) {
369
272M
          drcFact_mag = drcFact1_mag;
370
382M
        } else if (alphaValue == (FIXP_DBL)MAXVAL_DBL) {
371
45.3M
          drcFact_mag = drcFact2_mag;
372
337M
        } else {
373
337M
          drcFact_mag =
374
337M
              fMult(alphaValue, drcFact2_mag) +
375
337M
              fMult(((FIXP_DBL)MAXVAL_DBL - alphaValue), drcFact1_mag);
376
337M
        }
377
378
        /* apply scaling */
379
654M
        qmfRealSlot[bin] = fMult(qmfRealSlot[bin], drcFact_mag);
380
654M
        if (!useLP) {
381
15.8M
          qmfImagSlot[bin] = fMult(qmfImagSlot[bin], drcFact_mag);
382
15.8M
        }
383
384
        /* save previous factors */
385
654M
        if (col == (numQmfSubSamples >> 1) - 1) {
386
22.2M
          hDrcData->prevFact_mag[bin] = fact_mag[band];
387
22.2M
        }
388
654M
      }
389
73.5M
    } else { /* short windows */
390
2.69M
      unsigned startWinIdx, stopWinIdx;
391
2.69M
      int startCol, stopCol;
392
2.69M
      FIXP_DBL invFrameSizeDiv8 =
393
2.69M
          (frameLenFlag) ? (FIXP_DBL)0x1111112 : (FIXP_DBL)0x1000000;
394
395
      /* limit top at the frame borders */
396
2.69M
      if (topMdct < 0) {
397
0
        topMdct = 0;
398
0
      }
399
2.69M
      if (topMdct >= frameSize) {
400
99.1k
        topMdct = frameSize - 1;
401
99.1k
      }
402
403
2.69M
      if (frameLenFlag) {
404
        /*  960 framing */
405
386k
        topMdct = fMultIfloor((FIXP_DBL)0x78000000,
406
386k
                              fMultIfloor((FIXP_DBL)0x22222223, topMdct) << 2);
407
408
386k
        startWinIdx = fMultIfloor(invFrameSizeDiv8, bottomMdct) +
409
386k
                      1; /* winBorderToColMap table has offset of 1 */
410
386k
        stopWinIdx = fMultIceil(invFrameSizeDiv8 - (FIXP_DBL)1, topMdct) + 1;
411
2.31M
      } else {
412
        /* 1024 framing */
413
2.31M
        topMdct &= ~0x03;
414
415
2.31M
        startWinIdx = fMultIfloor(invFrameSizeDiv8, bottomMdct) + 1;
416
2.31M
        stopWinIdx = fMultIceil(invFrameSizeDiv8, topMdct) + 1;
417
2.31M
      }
418
419
      /* startCol is truncated to the nearest corresponding start subsample in
420
         the QMF of the short window bottom is present in:*/
421
2.69M
      startCol = (int)winBorderToColMap[startWinIdx];
422
423
      /* stopCol is rounded upwards to the nearest corresponding stop subsample
424
         in the QMF of the short window top is present in. */
425
2.69M
      stopCol = (int)winBorderToColMap[stopWinIdx];
426
427
2.69M
      bottomQmf = fMultIfloor(invFrameSizeDiv8,
428
2.69M
                              ((bottomMdct % (numQmfSubSamples << 2)) << 5));
429
2.69M
      topQmf = fMultIfloor(invFrameSizeDiv8,
430
2.69M
                           ((topMdct % (numQmfSubSamples << 2)) << 5));
431
432
      /* extend last band */
433
2.69M
      if (band == ((int)numBands - 1)) {
434
329k
        topQmf = (64);
435
329k
        stopCol = numQmfSubSamples;
436
329k
        stopWinIdx = 10;
437
329k
      }
438
439
2.69M
      if (topQmf == 0) {
440
93.3k
        if (frameLenFlag) {
441
83.8k
          FIXP_DBL rem = fMult(invFrameSizeDiv8,
442
83.8k
                               (FIXP_DBL)(topMdct << (DFRACT_BITS - 12)));
443
83.8k
          if ((LONG)rem & (LONG)0x1F) {
444
83.8k
            stopWinIdx -= 1;
445
83.8k
            stopCol = (int)winBorderToColMap[stopWinIdx];
446
83.8k
          }
447
83.8k
        }
448
93.3k
        topQmf = (64);
449
93.3k
      }
450
451
      /* save previous factors */
452
2.69M
      if (stopCol == numQmfSubSamples) {
453
470k
        int tmpBottom = bottomQmf;
454
455
470k
        if ((int)winBorderToColMap[8] > startCol) {
456
385k
          tmpBottom = 0; /* band starts in previous short window */
457
385k
        }
458
459
22.7M
        for (bin = tmpBottom; bin < topQmf; bin++) {
460
22.3M
          hDrcData->prevFact_mag[bin] = fact_mag[band];
461
22.3M
        }
462
470k
      }
463
464
      /* apply */
465
2.69M
      if ((col >= startCol) && (col < stopCol)) {
466
804k
        if (col >= (int)winBorderToColMap[startWinIdx + 1]) {
467
426k
          bottomQmf = 0; /* band starts in previous short window */
468
426k
        }
469
804k
        if (col < (int)winBorderToColMap[stopWinIdx - 1]) {
470
533k
          topQmf = (64); /* band ends in next short window */
471
533k
        }
472
473
804k
        drcFact_mag = fact_mag[band];
474
475
        /* normalize scale factor */
476
804k
        if (fact_exp < maxShift) {
477
714
          drcFact_mag >>= maxShift - fact_exp;
478
714
        }
479
480
        /* apply scaling */
481
36.0M
        for (bin = bottomQmf; bin < topQmf; bin++) {
482
35.2M
          qmfRealSlot[bin] = fMult(qmfRealSlot[bin], drcFact_mag);
483
35.2M
          if (!useLP) {
484
2.32M
            qmfImagSlot[bin] = fMult(qmfImagSlot[bin], drcFact_mag);
485
2.32M
          }
486
35.2M
        }
487
804k
      }
488
2.69M
    }
489
490
76.1M
    bottomMdct = topMdct;
491
76.1M
  } /* end of bands loop */
492
493
7.50M
  if (col == (numQmfSubSamples >> 1) - 1) {
494
256k
    hDrcData->prevFact_exp = fact_exp;
495
256k
  }
496
7.50M
}
497
498
/*!
499
  \brief Apply DRC factors frame based.
500
501
  \hDrcData Handle to DRC channel data.
502
  \qmfRealSlot Pointer to real valued QMF data of the whole frame.
503
  \qmfImagSlot Pointer to the imaginary QMF data of the whole frame.
504
  \numQmfSubSamples Total number of time slots for one frame.
505
  \scaleFactor Pointer to the out scale factor of the frame.
506
507
  \return None.
508
*/
509
void sbrDecoder_drcApply(HANDLE_SBR_DRC_CHANNEL hDrcData,
510
                         FIXP_DBL **QmfBufferReal, FIXP_DBL **QmfBufferImag,
511
2.40M
                         int numQmfSubSamples, int *scaleFactor) {
512
2.40M
  int col;
513
2.40M
  int maxShift = 0;
514
515
2.40M
  if (hDrcData == NULL) {
516
0
    return;
517
0
  }
518
2.40M
  if (hDrcData->enable == 0) {
519
2.15M
    return; /* Avoid changing the scaleFactor even though the processing is
520
               disabled. */
521
2.15M
  }
522
523
  /* get max scale factor */
524
254k
  if (hDrcData->prevFact_exp > maxShift) {
525
254k
    maxShift = hDrcData->prevFact_exp;
526
254k
  }
527
254k
  if (hDrcData->currFact_exp > maxShift) {
528
13.8k
    maxShift = hDrcData->currFact_exp;
529
13.8k
  }
530
254k
  if (hDrcData->nextFact_exp > maxShift) {
531
16.1k
    maxShift = hDrcData->nextFact_exp;
532
16.1k
  }
533
534
7.68M
  for (col = 0; col < numQmfSubSamples; col++) {
535
7.42M
    FIXP_DBL *qmfSlotReal = QmfBufferReal[col];
536
7.42M
    FIXP_DBL *qmfSlotImag = (QmfBufferImag == NULL) ? NULL : QmfBufferImag[col];
537
538
7.42M
    sbrDecoder_drcApplySlot(hDrcData, qmfSlotReal, qmfSlotImag, col,
539
7.42M
                            numQmfSubSamples, maxShift);
540
7.42M
  }
541
542
254k
  *scaleFactor += maxShift;
543
254k
}