Coverage Report

Created: 2026-09-07 07:09

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