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