Coverage Report

Created: 2025-10-28 06:45

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