Coverage Report

Created: 2025-12-31 06:47

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