Coverage Report

Created: 2026-02-26 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/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
454k
void sbrDecoder_drcInitChannel(HANDLE_SBR_DRC_CHANNEL hDrcData) {
125
454k
  int band;
126
127
454k
  if (hDrcData == NULL) {
128
0
    return;
129
0
  }
130
131
29.5M
  for (band = 0; band < (64); band++) {
132
29.0M
    hDrcData->prevFact_mag[band] = FL2FXCONST_DBL(0.5f);
133
29.0M
  }
134
135
7.72M
  for (band = 0; band < SBRDEC_MAX_DRC_BANDS; band++) {
136
7.26M
    hDrcData->currFact_mag[band] = FL2FXCONST_DBL(0.5f);
137
7.26M
    hDrcData->nextFact_mag[band] = FL2FXCONST_DBL(0.5f);
138
7.26M
  }
139
140
454k
  hDrcData->prevFact_exp = 1;
141
454k
  hDrcData->currFact_exp = 1;
142
454k
  hDrcData->nextFact_exp = 1;
143
144
454k
  hDrcData->numBandsCurr = 1;
145
454k
  hDrcData->numBandsNext = 1;
146
147
454k
  hDrcData->winSequenceCurr = 0;
148
454k
  hDrcData->winSequenceNext = 0;
149
150
454k
  hDrcData->drcInterpolationSchemeCurr = 0;
151
454k
  hDrcData->drcInterpolationSchemeNext = 0;
152
153
454k
  hDrcData->enable = 0;
154
454k
}
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
409k
void sbrDecoder_drcUpdateChannel(HANDLE_SBR_DRC_CHANNEL hDrcData) {
164
409k
  if (hDrcData == NULL) {
165
0
    return;
166
0
  }
167
409k
  if (hDrcData->enable != 1) {
168
395k
    return;
169
395k
  }
170
171
  /* swap previous data */
172
14.7k
  FDKmemcpy(hDrcData->currFact_mag, hDrcData->nextFact_mag,
173
14.7k
            SBRDEC_MAX_DRC_BANDS * sizeof(FIXP_DBL));
174
175
14.7k
  hDrcData->currFact_exp = hDrcData->nextFact_exp;
176
177
14.7k
  hDrcData->numBandsCurr = hDrcData->numBandsNext;
178
179
14.7k
  FDKmemcpy(hDrcData->bandTopCurr, hDrcData->bandTopNext,
180
14.7k
            SBRDEC_MAX_DRC_BANDS * sizeof(USHORT));
181
182
14.7k
  hDrcData->drcInterpolationSchemeCurr = hDrcData->drcInterpolationSchemeNext;
183
184
14.7k
  hDrcData->winSequenceCurr = hDrcData->winSequenceNext;
185
14.7k
}
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
609k
                             int col, int numQmfSubSamples, int maxShift) {
202
609k
  const UCHAR *winBorderToColMap;
203
204
609k
  int band, bottomMdct, topMdct, bin, useLP;
205
609k
  int indx = numQmfSubSamples - (numQmfSubSamples >> 1) - 10; /* l_border */
206
609k
  int frameLenFlag = (numQmfSubSamples == 30) ? 1 : 0;
207
609k
  int frameSize = (frameLenFlag == 1) ? 960 : 1024;
208
209
609k
  const FIXP_DBL *fact_mag = NULL;
210
609k
  INT fact_exp = 0;
211
609k
  UINT numBands = 0;
212
609k
  USHORT *bandTop = NULL;
213
609k
  int shortDrc = 0;
214
215
609k
  FIXP_DBL alphaValue = FL2FXCONST_DBL(0.0f);
216
217
609k
  if (hDrcData == NULL) {
218
0
    return;
219
0
  }
220
609k
  if (hDrcData->enable != 1) {
221
137k
    return;
222
137k
  }
223
224
472k
  winBorderToColMap = winBorderToColMappingTab[frameLenFlag];
225
226
472k
  useLP = (qmfImagSlot == NULL) ? 1 : 0;
227
228
472k
  col += indx;
229
472k
  bottomMdct = 0;
230
231
  /* get respective data and calc interpolation factor */
232
472k
  if (col < (numQmfSubSamples >> 1)) {    /* first half of current frame */
233
155k
    if (hDrcData->winSequenceCurr != 2) { /* long window */
234
62.8k
      int j = col + (numQmfSubSamples >> 1);
235
236
62.8k
      if (j < winBorderToColMap[15]) {
237
62.8k
        if (hDrcData->drcInterpolationSchemeCurr == 0) {
238
50.0k
          INT k = (frameLenFlag) ? 0x4444445 : 0x4000000;
239
240
50.0k
          alphaValue = (FIXP_DBL)(j * k);
241
50.0k
        } else {
242
12.7k
          if (j >=
243
12.7k
              (int)winBorderToColMap[hDrcData->drcInterpolationSchemeCurr]) {
244
8.34k
            alphaValue = (FIXP_DBL)MAXVAL_DBL;
245
8.34k
          }
246
12.7k
        }
247
62.8k
      } else {
248
0
        alphaValue = (FIXP_DBL)MAXVAL_DBL;
249
0
      }
250
92.3k
    } else { /* short windows */
251
92.3k
      shortDrc = 1;
252
92.3k
    }
253
254
155k
    fact_mag = hDrcData->currFact_mag;
255
155k
    fact_exp = hDrcData->currFact_exp;
256
155k
    numBands = hDrcData->numBandsCurr;
257
155k
    bandTop = hDrcData->bandTopCurr;
258
317k
  } else if (col < numQmfSubSamples) {    /* second half of current frame */
259
235k
    if (hDrcData->winSequenceNext != 2) { /* next: long window */
260
77.0k
      int j = col - (numQmfSubSamples >> 1);
261
262
77.0k
      if (j < winBorderToColMap[15]) {
263
77.0k
        if (hDrcData->drcInterpolationSchemeNext == 0) {
264
53.4k
          INT k = (frameLenFlag) ? 0x4444445 : 0x4000000;
265
266
53.4k
          alphaValue = (FIXP_DBL)(j * k);
267
53.4k
        } else {
268
23.5k
          if (j >=
269
23.5k
              (int)winBorderToColMap[hDrcData->drcInterpolationSchemeNext]) {
270
1.75k
            alphaValue = (FIXP_DBL)MAXVAL_DBL;
271
1.75k
          }
272
23.5k
        }
273
77.0k
      } else {
274
0
        alphaValue = (FIXP_DBL)MAXVAL_DBL;
275
0
      }
276
277
77.0k
      fact_mag = hDrcData->nextFact_mag;
278
77.0k
      fact_exp = hDrcData->nextFact_exp;
279
77.0k
      numBands = hDrcData->numBandsNext;
280
77.0k
      bandTop = hDrcData->bandTopNext;
281
157k
    } else {                                /* next: short windows */
282
157k
      if (hDrcData->winSequenceCurr != 2) { /* current: long window */
283
51.1k
        alphaValue = (FIXP_DBL)0;
284
285
51.1k
        fact_mag = hDrcData->nextFact_mag;
286
51.1k
        fact_exp = hDrcData->nextFact_exp;
287
51.1k
        numBands = hDrcData->numBandsNext;
288
51.1k
        bandTop = hDrcData->bandTopNext;
289
106k
      } else { /* current: short windows */
290
106k
        shortDrc = 1;
291
292
106k
        fact_mag = hDrcData->currFact_mag;
293
106k
        fact_exp = hDrcData->currFact_exp;
294
106k
        numBands = hDrcData->numBandsCurr;
295
106k
        bandTop = hDrcData->bandTopCurr;
296
106k
      }
297
157k
    }
298
235k
  } else {                                /* first half of next frame */
299
82.3k
    if (hDrcData->winSequenceNext != 2) { /* long window */
300
25.3k
      int j = col - (numQmfSubSamples >> 1);
301
302
25.3k
      if (j < winBorderToColMap[15]) {
303
25.3k
        if (hDrcData->drcInterpolationSchemeNext == 0) {
304
17.3k
          INT k = (frameLenFlag) ? 0x4444445 : 0x4000000;
305
306
17.3k
          alphaValue = (FIXP_DBL)(j * k);
307
17.3k
        } else {
308
8.03k
          if (j >=
309
8.03k
              (int)winBorderToColMap[hDrcData->drcInterpolationSchemeNext]) {
310
675
            alphaValue = (FIXP_DBL)MAXVAL_DBL;
311
675
          }
312
8.03k
        }
313
25.3k
      } else {
314
0
        alphaValue = (FIXP_DBL)MAXVAL_DBL;
315
0
      }
316
56.9k
    } else { /* short windows */
317
56.9k
      shortDrc = 1;
318
56.9k
    }
319
320
82.3k
    fact_mag = hDrcData->nextFact_mag;
321
82.3k
    fact_exp = hDrcData->nextFact_exp;
322
82.3k
    numBands = hDrcData->numBandsNext;
323
82.3k
    bandTop = hDrcData->bandTopNext;
324
325
82.3k
    col -= numQmfSubSamples;
326
82.3k
  }
327
328
  /* process bands */
329
2.17M
  for (band = 0; band < (int)numBands; band++) {
330
1.69M
    int bottomQmf, topQmf;
331
332
1.69M
    FIXP_DBL drcFact_mag = (FIXP_DBL)MAXVAL_DBL;
333
334
1.69M
    topMdct = (bandTop[band] + 1) << 2;
335
336
1.69M
    if (!shortDrc) { /* long window */
337
587k
      if (frameLenFlag) {
338
        /* 960 framing */
339
245k
        bottomQmf = fMultIfloor((FIXP_DBL)0x4444445, bottomMdct);
340
245k
        topQmf = fMultIfloor((FIXP_DBL)0x4444445, topMdct);
341
342
245k
        topMdct = 30 * topQmf;
343
341k
      } else {
344
        /* 1024 framing */
345
341k
        topMdct &= ~0x1f;
346
347
341k
        bottomQmf = bottomMdct >> 5;
348
341k
        topQmf = topMdct >> 5;
349
341k
      }
350
351
587k
      if (band == ((int)numBands - 1)) {
352
216k
        topQmf = (64);
353
216k
      }
354
355
16.4M
      for (bin = bottomQmf; bin < topQmf; bin++) {
356
15.8M
        FIXP_DBL drcFact1_mag = hDrcData->prevFact_mag[bin];
357
15.8M
        FIXP_DBL drcFact2_mag = fact_mag[band];
358
359
        /* normalize scale factors */
360
15.8M
        if (hDrcData->prevFact_exp < maxShift) {
361
4.71M
          drcFact1_mag >>= maxShift - hDrcData->prevFact_exp;
362
4.71M
        }
363
15.8M
        if (fact_exp < maxShift) {
364
2.37M
          drcFact2_mag >>= maxShift - fact_exp;
365
2.37M
        }
366
367
        /* interpolate */
368
15.8M
        if (alphaValue == (FIXP_DBL)0) {
369
7.23M
          drcFact_mag = drcFact1_mag;
370
8.58M
        } else if (alphaValue == (FIXP_DBL)MAXVAL_DBL) {
371
920k
          drcFact_mag = drcFact2_mag;
372
7.66M
        } else {
373
7.66M
          drcFact_mag =
374
7.66M
              fMult(alphaValue, drcFact2_mag) +
375
7.66M
              fMult(((FIXP_DBL)MAXVAL_DBL - alphaValue), drcFact1_mag);
376
7.66M
        }
377
378
        /* apply scaling */
379
15.8M
        qmfRealSlot[bin] = fMult(qmfRealSlot[bin], drcFact_mag);
380
15.8M
        if (!useLP) {
381
4.31M
          qmfImagSlot[bin] = fMult(qmfImagSlot[bin], drcFact_mag);
382
4.31M
        }
383
384
        /* save previous factors */
385
15.8M
        if (col == (numQmfSubSamples >> 1) - 1) {
386
443k
          hDrcData->prevFact_mag[bin] = fact_mag[band];
387
443k
        }
388
15.8M
      }
389
1.11M
    } else { /* short windows */
390
1.11M
      unsigned startWinIdx, stopWinIdx;
391
1.11M
      int startCol, stopCol;
392
1.11M
      FIXP_DBL invFrameSizeDiv8 =
393
1.11M
          (frameLenFlag) ? (FIXP_DBL)0x1111112 : (FIXP_DBL)0x1000000;
394
395
      /* limit top at the frame borders */
396
1.11M
      if (topMdct < 0) {
397
0
        topMdct = 0;
398
0
      }
399
1.11M
      if (topMdct >= frameSize) {
400
163k
        topMdct = frameSize - 1;
401
163k
      }
402
403
1.11M
      if (frameLenFlag) {
404
        /*  960 framing */
405
480k
        topMdct = fMultIfloor((FIXP_DBL)0x78000000,
406
480k
                              fMultIfloor((FIXP_DBL)0x22222223, topMdct) << 2);
407
408
480k
        startWinIdx = fMultIfloor(invFrameSizeDiv8, bottomMdct) +
409
480k
                      1; /* winBorderToColMap table has offset of 1 */
410
480k
        stopWinIdx = fMultIceil(invFrameSizeDiv8 - (FIXP_DBL)1, topMdct) + 1;
411
630k
      } else {
412
        /* 1024 framing */
413
630k
        topMdct &= ~0x03;
414
415
630k
        startWinIdx = fMultIfloor(invFrameSizeDiv8, bottomMdct) + 1;
416
630k
        stopWinIdx = fMultIceil(invFrameSizeDiv8, topMdct) + 1;
417
630k
      }
418
419
      /* startCol is truncated to the nearest corresponding start subsample in
420
         the QMF of the short window bottom is present in:*/
421
1.11M
      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
1.11M
      stopCol = (int)winBorderToColMap[stopWinIdx];
426
427
1.11M
      bottomQmf = fMultIfloor(invFrameSizeDiv8,
428
1.11M
                              ((bottomMdct % (numQmfSubSamples << 2)) << 5));
429
1.11M
      topQmf = fMultIfloor(invFrameSizeDiv8,
430
1.11M
                           ((topMdct % (numQmfSubSamples << 2)) << 5));
431
432
      /* extend last band */
433
1.11M
      if (band == ((int)numBands - 1)) {
434
256k
        topQmf = (64);
435
256k
        stopCol = numQmfSubSamples;
436
256k
        stopWinIdx = 10;
437
256k
      }
438
439
1.11M
      if (topQmf == 0) {
440
154k
        if (frameLenFlag) {
441
66.8k
          FIXP_DBL rem = fMult(invFrameSizeDiv8,
442
66.8k
                               (FIXP_DBL)(topMdct << (DFRACT_BITS - 12)));
443
66.8k
          if ((LONG)rem & (LONG)0x1F) {
444
32.5k
            stopWinIdx -= 1;
445
32.5k
            stopCol = (int)winBorderToColMap[stopWinIdx];
446
32.5k
          }
447
66.8k
        }
448
154k
        topQmf = (64);
449
154k
      }
450
451
      /* save previous factors */
452
1.11M
      if (stopCol == numQmfSubSamples) {
453
391k
        int tmpBottom = bottomQmf;
454
455
391k
        if ((int)winBorderToColMap[8] > startCol) {
456
330k
          tmpBottom = 0; /* band starts in previous short window */
457
330k
        }
458
459
18.2M
        for (bin = tmpBottom; bin < topQmf; bin++) {
460
17.8M
          hDrcData->prevFact_mag[bin] = fact_mag[band];
461
17.8M
        }
462
391k
      }
463
464
      /* apply */
465
1.11M
      if ((col >= startCol) && (col < stopCol)) {
466
432k
        if (col >= (int)winBorderToColMap[startWinIdx + 1]) {
467
317k
          bottomQmf = 0; /* band starts in previous short window */
468
317k
        }
469
432k
        if (col < (int)winBorderToColMap[stopWinIdx - 1]) {
470
362k
          topQmf = (64); /* band ends in next short window */
471
362k
        }
472
473
432k
        drcFact_mag = fact_mag[band];
474
475
        /* normalize scale factor */
476
432k
        if (fact_exp < maxShift) {
477
57.6k
          drcFact_mag >>= maxShift - fact_exp;
478
57.6k
        }
479
480
        /* apply scaling */
481
24.7M
        for (bin = bottomQmf; bin < topQmf; bin++) {
482
24.3M
          qmfRealSlot[bin] = fMult(qmfRealSlot[bin], drcFact_mag);
483
24.3M
          if (!useLP) {
484
5.16M
            qmfImagSlot[bin] = fMult(qmfImagSlot[bin], drcFact_mag);
485
5.16M
          }
486
24.3M
        }
487
432k
      }
488
1.11M
    }
489
490
1.69M
    bottomMdct = topMdct;
491
1.69M
  } /* end of bands loop */
492
493
472k
  if (col == (numQmfSubSamples >> 1) - 1) {
494
15.6k
    hDrcData->prevFact_exp = fact_exp;
495
15.6k
  }
496
472k
}
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
295k
                         int numQmfSubSamples, int *scaleFactor) {
512
295k
  int col;
513
295k
  int maxShift = 0;
514
515
295k
  if (hDrcData == NULL) {
516
0
    return;
517
0
  }
518
295k
  if (hDrcData->enable == 0) {
519
281k
    return; /* Avoid changing the scaleFactor even though the processing is
520
               disabled. */
521
281k
  }
522
523
  /* get max scale factor */
524
13.8k
  if (hDrcData->prevFact_exp > maxShift) {
525
13.7k
    maxShift = hDrcData->prevFact_exp;
526
13.7k
  }
527
13.8k
  if (hDrcData->currFact_exp > maxShift) {
528
1.73k
    maxShift = hDrcData->currFact_exp;
529
1.73k
  }
530
13.8k
  if (hDrcData->nextFact_exp > maxShift) {
531
2.17k
    maxShift = hDrcData->nextFact_exp;
532
2.17k
  }
533
534
433k
  for (col = 0; col < numQmfSubSamples; col++) {
535
419k
    FIXP_DBL *qmfSlotReal = QmfBufferReal[col];
536
419k
    FIXP_DBL *qmfSlotImag = (QmfBufferImag == NULL) ? NULL : QmfBufferImag[col];
537
538
419k
    sbrDecoder_drcApplySlot(hDrcData, qmfSlotReal, qmfSlotImag, col,
539
419k
                            numQmfSubSamples, maxShift);
540
419k
  }
541
542
13.8k
  *scaleFactor += maxShift;
543
13.8k
}