• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3 
4 © Copyright  1995 - 2018 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 /*********************** MPEG surround encoder library *************************
96 
97    Author(s):   M. Multrus
98 
99    Description: Parameter Extraction
100 
101 *******************************************************************************/
102 
103 /* Includes ******************************************************************/
104 #include "sacenc_paramextract.h"
105 #include "sacenc_tree.h"
106 #include "sacenc_vectorfunctions.h"
107 
108 /* Defines *******************************************************************/
109 #define LOG10_2_10 (3.01029995664f) /* 10.0f*log10(2.f) */
110 #define SCALE_CLDE_SF (7)           /* maxVal in Quant tab is +/-  50 */
111 #define SCALE_CLDD_SF (8)           /* maxVal in Quant tab is +/- 150 */
112 
113 /* Data Types ****************************************************************/
114 typedef struct T_TTO_BOX {
115   FIXP_DBL pCld__FDK[MAX_NUM_PARAM_BANDS];
116   FIXP_DBL pIcc__FDK[MAX_NUM_PARAM_BANDS];
117   FIXP_DBL pCldQuant__FDK[MAX_NUM_PARAM_BANDS];
118 
119   const FIXP_DBL *pIccQuantTable__FDK;
120   const FIXP_DBL *pCldQuantTableDec__FDK;
121   const FIXP_DBL *pCldQuantTableEnc__FDK;
122 
123   SCHAR pCldEbQIdx[MAX_NUM_PARAM_BANDS];
124   SCHAR pIccDownmixIdx[MAX_NUM_PARAM_BANDS];
125 
126   UCHAR *pParameterBand2HybridBandOffset;
127   const INT *pSubbandImagSign;
128   UCHAR nHybridBandsMax;
129   UCHAR nParameterBands;
130   UCHAR bFrameKeep;
131 
132   UCHAR iccCorrelationCoherenceBorder;
133   BOX_QUANTMODE boxQuantMode;
134 
135   UCHAR nIccQuantSteps;
136   UCHAR nIccQuantOffset;
137 
138   UCHAR nCldQuantSteps;
139   UCHAR nCldQuantOffset;
140 
141   UCHAR bUseCoarseQuantCld;
142   UCHAR bUseCoarseQuantIcc;
143 
144 } TTO_BOX;
145 
146 struct BOX_SUBBAND_SETUP {
147   BOX_SUBBAND_CONFIG subbandConfig;
148   UCHAR nParameterBands;
149   const UCHAR *pSubband2ParameterIndexLd;
150   UCHAR iccCorrelationCoherenceBorder;
151 };
152 
153 /* Constants *****************************************************************/
154 static const UCHAR subband2Parameter4_Ld[NUM_QMF_BANDS] = {
155     0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
156     2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
157     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3};
158 
159 static const UCHAR subband2Parameter5_Ld[NUM_QMF_BANDS] = {
160     0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
161     3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
162     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4};
163 
164 static const UCHAR subband2Parameter7_Ld[NUM_QMF_BANDS] = {
165     0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
166     5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
167     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
168 
169 static const UCHAR subband2Parameter9_Ld[NUM_QMF_BANDS] = {
170     0, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7,
171     7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
172     8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};
173 
174 static const UCHAR subband2Parameter12_Ld[NUM_QMF_BANDS] = {
175     0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  7,  7,  7,  8,  8,
176     8,  8,  9,  9,  9,  9,  9,  10, 10, 10, 10, 10, 10, 10, 10, 10,
177     10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
178     11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11};
179 
180 static const UCHAR subband2Parameter15_Ld[NUM_QMF_BANDS] = {
181     0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  9,  10, 10, 10, 11, 11,
182     11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13,
183     13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
184     14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14};
185 
186 static const UCHAR subband2Parameter23_Ld[NUM_QMF_BANDS] = {
187     0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 12, 13, 13,
188     14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 18, 19, 19,
189     19, 19, 19, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21,
190     22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22};
191 
192 static const INT subbandImagSign_Ld[NUM_QMF_BANDS] = {
193     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
194     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
195     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
196 };
197 
198 #define SCALE_CLDE(a) (FL2FXCONST_DBL(a / (float)(1 << SCALE_CLDE_SF)))
199 static const FIXP_DBL cldQuantTableFineEnc__FDK[MAX_CLD_QUANT_FINE] = {
200     SCALE_CLDE(-50.0), SCALE_CLDE(-45.0), SCALE_CLDE(-40.0), SCALE_CLDE(-35.0),
201     SCALE_CLDE(-30.0), SCALE_CLDE(-25.0), SCALE_CLDE(-22.0), SCALE_CLDE(-19.0),
202     SCALE_CLDE(-16.0), SCALE_CLDE(-13.0), SCALE_CLDE(-10.0), SCALE_CLDE(-8.0),
203     SCALE_CLDE(-6.0),  SCALE_CLDE(-4.0),  SCALE_CLDE(-2.0),  SCALE_CLDE(0.0),
204     SCALE_CLDE(2.0),   SCALE_CLDE(4.0),   SCALE_CLDE(6.0),   SCALE_CLDE(8.0),
205     SCALE_CLDE(10.0),  SCALE_CLDE(13.0),  SCALE_CLDE(16.0),  SCALE_CLDE(19.0),
206     SCALE_CLDE(22.0),  SCALE_CLDE(25.0),  SCALE_CLDE(30.0),  SCALE_CLDE(35.0),
207     SCALE_CLDE(40.0),  SCALE_CLDE(45.0),  SCALE_CLDE(50.0)};
208 
209 static const FIXP_DBL cldQuantTableCoarseEnc__FDK[MAX_CLD_QUANT_COARSE] = {
210     SCALE_CLDE(-50.0), SCALE_CLDE(-35.0), SCALE_CLDE(-25.0), SCALE_CLDE(-19.0),
211     SCALE_CLDE(-13.0), SCALE_CLDE(-8.0),  SCALE_CLDE(-4.0),  SCALE_CLDE(0.0),
212     SCALE_CLDE(4.0),   SCALE_CLDE(8.0),   SCALE_CLDE(13.0),  SCALE_CLDE(19.0),
213     SCALE_CLDE(25.0),  SCALE_CLDE(35.0),  SCALE_CLDE(50.0)};
214 
215 #define SCALE_CLDD(a) (FL2FXCONST_DBL(a / (float)(1 << SCALE_CLDD_SF)))
216 static const FIXP_DBL cldQuantTableFineDec__FDK[MAX_CLD_QUANT_FINE] = {
217     SCALE_CLDD(-150.0), SCALE_CLDD(-45.0), SCALE_CLDD(-40.0), SCALE_CLDD(-35.0),
218     SCALE_CLDD(-30.0),  SCALE_CLDD(-25.0), SCALE_CLDD(-22.0), SCALE_CLDD(-19.0),
219     SCALE_CLDD(-16.0),  SCALE_CLDD(-13.0), SCALE_CLDD(-10.0), SCALE_CLDD(-8.0),
220     SCALE_CLDD(-6.0),   SCALE_CLDD(-4.0),  SCALE_CLDD(-2.0),  SCALE_CLDD(0.0),
221     SCALE_CLDD(2.0),    SCALE_CLDD(4.0),   SCALE_CLDD(6.0),   SCALE_CLDD(8.0),
222     SCALE_CLDD(10.0),   SCALE_CLDD(13.0),  SCALE_CLDD(16.0),  SCALE_CLDD(19.0),
223     SCALE_CLDD(22.0),   SCALE_CLDD(25.0),  SCALE_CLDD(30.0),  SCALE_CLDD(35.0),
224     SCALE_CLDD(40.0),   SCALE_CLDD(45.0),  SCALE_CLDD(150.0)};
225 
226 static const FIXP_DBL cldQuantTableCoarseDec__FDK[MAX_CLD_QUANT_COARSE] = {
227     SCALE_CLDD(-150.0), SCALE_CLDD(-35.0), SCALE_CLDD(-25.0), SCALE_CLDD(-19.0),
228     SCALE_CLDD(-13.0),  SCALE_CLDD(-8.0),  SCALE_CLDD(-4.0),  SCALE_CLDD(0.0),
229     SCALE_CLDD(4.0),    SCALE_CLDD(8.0),   SCALE_CLDD(13.0),  SCALE_CLDD(19.0),
230     SCALE_CLDD(25.0),   SCALE_CLDD(35.0),  SCALE_CLDD(150.0)};
231 
232 #define SCALE_ICC(a) (FL2FXCONST_DBL(a))
233 static const FIXP_DBL iccQuantTableFine__FDK[MAX_ICC_QUANT_FINE] = {
234     SCALE_ICC(0.99999999953), SCALE_ICC(0.937f),   SCALE_ICC(0.84118f),
235     SCALE_ICC(0.60092f),      SCALE_ICC(0.36764f), SCALE_ICC(0.0f),
236     SCALE_ICC(-0.589f),       SCALE_ICC(-0.99f)};
237 
238 static const FIXP_DBL iccQuantTableCoarse__FDK[MAX_ICC_QUANT_COARSE] = {
239     SCALE_ICC(0.99999999953), SCALE_ICC(0.84118f), SCALE_ICC(0.36764f),
240     SCALE_ICC(-0.5890f)};
241 
242 static const BOX_SUBBAND_SETUP boxSubbandSetup[] = {
243     {BOX_SUBBANDS_4, 4, subband2Parameter4_Ld, 1},
244     {BOX_SUBBANDS_5, 5, subband2Parameter5_Ld, 2},
245     {BOX_SUBBANDS_7, 7, subband2Parameter7_Ld, 3},
246     {BOX_SUBBANDS_9, 9, subband2Parameter9_Ld, 4},
247     {BOX_SUBBANDS_12, 12, subband2Parameter12_Ld, 4},
248     {BOX_SUBBANDS_15, 15, subband2Parameter15_Ld, 5},
249     {BOX_SUBBANDS_23, 23, subband2Parameter23_Ld, 8}};
250 
251 /* Function / Class Declarations *********************************************/
252 
253 /* Function / Class Definition ***********************************************/
getBoxSubbandSetup(const BOX_SUBBAND_CONFIG subbandConfig)254 static const BOX_SUBBAND_SETUP *getBoxSubbandSetup(
255     const BOX_SUBBAND_CONFIG subbandConfig) {
256   int i;
257   const BOX_SUBBAND_SETUP *setup = NULL;
258 
259   for (i = 0; i < (int)(sizeof(boxSubbandSetup) / sizeof(BOX_SUBBAND_SETUP));
260        i++) {
261     if (boxSubbandSetup[i].subbandConfig == subbandConfig) {
262       setup = &boxSubbandSetup[i];
263       break;
264     }
265   }
266   return setup;
267 }
268 
ApplyBBCuesFDK(FIXP_DBL * const pData,const INT nParamBands)269 static inline void ApplyBBCuesFDK(FIXP_DBL *const pData,
270                                   const INT nParamBands) {
271   int i, s;
272   FIXP_DBL tmp, invParamBands;
273 
274   invParamBands = fDivNormHighPrec((FIXP_DBL)1, (FIXP_DBL)nParamBands, &s);
275   s = -s;
276 
277   tmp = fMult(pData[0], invParamBands) >> s;
278   for (i = 1; i < nParamBands; i++) {
279     tmp += fMult(pData[i], invParamBands) >> s;
280   }
281 
282   for (i = 0; i < nParamBands; i++) {
283     pData[i] = tmp;
284   }
285 }
286 
getNumberParameterBands(const BOX_SUBBAND_CONFIG subbandConfig)287 static INT getNumberParameterBands(const BOX_SUBBAND_CONFIG subbandConfig) {
288   const BOX_SUBBAND_SETUP *setup = getBoxSubbandSetup(subbandConfig);
289   return ((setup == NULL) ? 0 : setup->nParameterBands);
290 }
291 
getSubband2ParameterIndex(const BOX_SUBBAND_CONFIG subbandConfig)292 static const UCHAR *getSubband2ParameterIndex(
293     const BOX_SUBBAND_CONFIG subbandConfig) {
294   const BOX_SUBBAND_SETUP *setup = getBoxSubbandSetup(subbandConfig);
295 
296   return ((setup == NULL) ? NULL : (setup->pSubband2ParameterIndexLd));
297 }
298 
fdk_sacenc_calcParameterBand2HybridBandOffset(const BOX_SUBBAND_CONFIG subbandConfig,const INT nHybridBands,UCHAR * pParameterBand2HybridBandOffset)299 void fdk_sacenc_calcParameterBand2HybridBandOffset(
300     const BOX_SUBBAND_CONFIG subbandConfig, const INT nHybridBands,
301     UCHAR *pParameterBand2HybridBandOffset) {
302   const BOX_SUBBAND_SETUP *setup = getBoxSubbandSetup(subbandConfig);
303   const UCHAR *pSubband2ParameterIndex;
304 
305   int i, pb;
306 
307   pSubband2ParameterIndex = setup->pSubband2ParameterIndexLd;
308 
309   for (pb = 0, i = 0; i < nHybridBands - 1; i++) {
310     if (pSubband2ParameterIndex[i + 1] - pSubband2ParameterIndex[i]) {
311       pParameterBand2HybridBandOffset[pb++] = (i + 1);
312     }
313   }
314   pParameterBand2HybridBandOffset[pb++] = (i + 1);
315 }
316 
fdk_sacenc_getSubbandImagSign()317 const INT *fdk_sacenc_getSubbandImagSign() {
318   const INT *pImagSign = NULL;
319 
320   pImagSign = subbandImagSign_Ld;
321 
322   return (pImagSign);
323 }
324 
getIccCorrelationCoherenceBorder(const BOX_SUBBAND_CONFIG subbandConfig,const INT bUseCoherenceOnly)325 static INT getIccCorrelationCoherenceBorder(
326     const BOX_SUBBAND_CONFIG subbandConfig, const INT bUseCoherenceOnly) {
327   const BOX_SUBBAND_SETUP *setup = getBoxSubbandSetup(subbandConfig);
328   return (
329       (setup == NULL)
330           ? 0
331           : ((bUseCoherenceOnly) ? 0 : setup->iccCorrelationCoherenceBorder));
332 }
333 
fdk_sacenc_createTtoBox(HANDLE_TTO_BOX * hTtoBox)334 FDK_SACENC_ERROR fdk_sacenc_createTtoBox(HANDLE_TTO_BOX *hTtoBox) {
335   FDK_SACENC_ERROR error = SACENC_OK;
336 
337   if (NULL == hTtoBox) {
338     error = SACENC_INVALID_HANDLE;
339   } else {
340     FDK_ALLOCATE_MEMORY_1D(*hTtoBox, 1, TTO_BOX);
341   }
342   return error;
343 
344 bail:
345   fdk_sacenc_destroyTtoBox(hTtoBox);
346   return ((SACENC_OK == error) ? SACENC_MEMORY_ERROR : error);
347 }
348 
fdk_sacenc_initTtoBox(HANDLE_TTO_BOX hTtoBox,const TTO_BOX_CONFIG * const ttoBoxConfig,UCHAR * pParameterBand2HybridBandOffset)349 FDK_SACENC_ERROR fdk_sacenc_initTtoBox(HANDLE_TTO_BOX hTtoBox,
350                                        const TTO_BOX_CONFIG *const ttoBoxConfig,
351                                        UCHAR *pParameterBand2HybridBandOffset) {
352   FDK_SACENC_ERROR error = SACENC_OK;
353 
354   if ((hTtoBox == NULL) || (ttoBoxConfig == NULL) ||
355       (pParameterBand2HybridBandOffset == NULL)) {
356     error = SACENC_INVALID_HANDLE;
357   } else {
358     FDKmemclear(hTtoBox, sizeof(TTO_BOX));
359 
360     hTtoBox->bUseCoarseQuantCld = ttoBoxConfig->bUseCoarseQuantCld;
361     hTtoBox->bUseCoarseQuantIcc = ttoBoxConfig->bUseCoarseQuantIcc;
362     hTtoBox->boxQuantMode = ttoBoxConfig->boxQuantMode;
363     hTtoBox->iccCorrelationCoherenceBorder = getIccCorrelationCoherenceBorder(
364         ttoBoxConfig->subbandConfig, ttoBoxConfig->bUseCoherenceIccOnly);
365     hTtoBox->nHybridBandsMax = ttoBoxConfig->nHybridBandsMax;
366     hTtoBox->nParameterBands =
367         getNumberParameterBands(ttoBoxConfig->subbandConfig);
368     hTtoBox->bFrameKeep = ttoBoxConfig->bFrameKeep;
369 
370     hTtoBox->nIccQuantSteps =
371         fdk_sacenc_getNumberIccQuantLevels(hTtoBox->bUseCoarseQuantIcc);
372     hTtoBox->nIccQuantOffset =
373         fdk_sacenc_getIccQuantOffset(hTtoBox->bUseCoarseQuantIcc);
374 
375     hTtoBox->pIccQuantTable__FDK = hTtoBox->bUseCoarseQuantIcc
376                                        ? iccQuantTableCoarse__FDK
377                                        : iccQuantTableFine__FDK;
378     hTtoBox->pCldQuantTableDec__FDK = hTtoBox->bUseCoarseQuantCld
379                                           ? cldQuantTableCoarseDec__FDK
380                                           : cldQuantTableFineDec__FDK;
381     hTtoBox->pCldQuantTableEnc__FDK = hTtoBox->bUseCoarseQuantCld
382                                           ? cldQuantTableCoarseEnc__FDK
383                                           : cldQuantTableFineEnc__FDK;
384 
385     hTtoBox->nCldQuantSteps =
386         fdk_sacenc_getNumberCldQuantLevels(hTtoBox->bUseCoarseQuantCld);
387     hTtoBox->nCldQuantOffset =
388         fdk_sacenc_getCldQuantOffset(hTtoBox->bUseCoarseQuantCld);
389 
390     /* sanity */
391     if (NULL == (hTtoBox->pParameterBand2HybridBandOffset =
392                      pParameterBand2HybridBandOffset)) {
393       error = SACENC_INIT_ERROR;
394       goto bail;
395     }
396 
397     if (NULL == (hTtoBox->pSubbandImagSign = fdk_sacenc_getSubbandImagSign())) {
398       error = SACENC_INIT_ERROR;
399     }
400 
401     if ((hTtoBox->boxQuantMode != BOX_QUANTMODE_FINE) &&
402         (hTtoBox->boxQuantMode != BOX_QUANTMODE_EBQ1) &&
403         (hTtoBox->boxQuantMode != BOX_QUANTMODE_EBQ2)) {
404       error = SACENC_INIT_ERROR;
405       goto bail;
406     }
407   }
408 bail:
409   return error;
410 }
411 
fdk_sacenc_destroyTtoBox(HANDLE_TTO_BOX * hTtoBox)412 FDK_SACENC_ERROR fdk_sacenc_destroyTtoBox(HANDLE_TTO_BOX *hTtoBox) {
413   FDK_SACENC_ERROR error = SACENC_OK;
414 
415   if (*hTtoBox != NULL) {
416     FDKfree(*hTtoBox);
417     *hTtoBox = NULL;
418   }
419 
420   return error;
421 }
422 
calculateIccFDK(const INT nParamBand,const INT correlationCoherenceBorder,const FIXP_DBL * const pPwr1,const FIXP_DBL * const pPwr2,const FIXP_DBL * const pProdReal,FIXP_DBL const * const pProdImag,FIXP_DBL * const pIcc)423 static FDK_SACENC_ERROR calculateIccFDK(const INT nParamBand,
424                                         const INT correlationCoherenceBorder,
425                                         const FIXP_DBL *const pPwr1,
426                                         const FIXP_DBL *const pPwr2,
427                                         const FIXP_DBL *const pProdReal,
428                                         FIXP_DBL const *const pProdImag,
429                                         FIXP_DBL *const pIcc) {
430   FDK_SACENC_ERROR error = SACENC_OK;
431 
432   if ((pPwr1 == NULL) || (pPwr2 == NULL) || (pProdReal == NULL) ||
433       (pProdImag == NULL) || (pIcc == NULL)) {
434     error = SACENC_INVALID_HANDLE;
435   } else {
436     /* sanity check border */
437     if (correlationCoherenceBorder > nParamBand) {
438       error = SACENC_INVALID_CONFIG;
439     } else {
440       /* correlation */
441       FDKcalcCorrelationVec(pIcc, pProdReal, pPwr1, pPwr2,
442                             correlationCoherenceBorder);
443 
444       /* coherence */
445       calcCoherenceVec(&pIcc[correlationCoherenceBorder],
446                        &pProdReal[correlationCoherenceBorder],
447                        &pProdImag[correlationCoherenceBorder],
448                        &pPwr1[correlationCoherenceBorder],
449                        &pPwr2[correlationCoherenceBorder], 0, 0,
450                        nParamBand - correlationCoherenceBorder);
451 
452     } /* valid configuration */
453   }   /* valid handle */
454 
455   return error;
456 }
457 
QuantizeCoefFDK(const FIXP_DBL * const input,const INT nBands,const FIXP_DBL * const quantTable,const INT idxOffset,const INT nQuantSteps,SCHAR * const quantOut)458 static void QuantizeCoefFDK(const FIXP_DBL *const input, const INT nBands,
459                             const FIXP_DBL *const quantTable,
460                             const INT idxOffset, const INT nQuantSteps,
461                             SCHAR *const quantOut) {
462   int band;
463   const int reverse = (quantTable[0] > quantTable[1]);
464 
465   for (band = 0; band < nBands; band++) {
466     FIXP_DBL qVal;
467     FIXP_DBL curVal = input[band];
468 
469     int lower = 0;
470     int upper = nQuantSteps - 1;
471 
472     if (reverse) {
473       while (upper - lower > 1) {
474         int idx = (lower + upper) >> 1;
475         qVal = quantTable[idx];
476         if (curVal >= qVal) {
477           upper = idx;
478         } else {
479           lower = idx;
480         }
481       } /* while */
482 
483       if ((curVal - quantTable[lower]) >= (quantTable[upper] - curVal)) {
484         quantOut[band] = lower - idxOffset;
485       } else {
486         quantOut[band] = upper - idxOffset;
487       }
488     } /* if reverse */
489     else {
490       while (upper - lower > 1) {
491         int idx = (lower + upper) >> 1;
492         qVal = quantTable[idx];
493         if (curVal <= qVal) {
494           upper = idx;
495         } else {
496           lower = idx;
497         }
498       } /* while */
499 
500       if ((curVal - quantTable[lower]) <= (quantTable[upper] - curVal)) {
501         quantOut[band] = lower - idxOffset;
502       } else {
503         quantOut[band] = upper - idxOffset;
504       }
505     } /* else reverse */
506   }   /* for band */
507 }
508 
deQuantizeCoefFDK(const SCHAR * const input,const INT nBands,const FIXP_DBL * const quantTable,const INT idxOffset,FIXP_DBL * const dequantOut)509 static void deQuantizeCoefFDK(const SCHAR *const input, const INT nBands,
510                               const FIXP_DBL *const quantTable,
511                               const INT idxOffset, FIXP_DBL *const dequantOut) {
512   int band;
513 
514   for (band = 0; band < nBands; band++) {
515     dequantOut[band] = quantTable[input[band] + idxOffset];
516   }
517 }
518 
CalculateCldFDK(FIXP_DBL * const pCld,const FIXP_DBL * const pPwr1,const FIXP_DBL * const pPwr2,const INT scaleCh1,const INT * const pbScaleCh1,const INT scaleCh2,const INT * const pbScaleCh2,const int nParamBand)519 static void CalculateCldFDK(FIXP_DBL *const pCld, const FIXP_DBL *const pPwr1,
520                             const FIXP_DBL *const pPwr2, const INT scaleCh1,
521                             const INT *const pbScaleCh1, const INT scaleCh2,
522                             const INT *const pbScaleCh2, const int nParamBand) {
523   INT i;
524   FIXP_DBL ldPwr1, ldPwr2, cld;
525   FIXP_DBL maxPwr = FL2FXCONST_DBL(
526       30.0f /
527       (1 << (LD_DATA_SHIFT +
528              1))); /* consider SACENC_FLOAT_EPSILON in power calculation */
529 
530   for (i = 0; i < nParamBand; i++) {
531     ldPwr1 =
532         (CalcLdData(pPwr1[i]) >> 1) + ((FIXP_DBL)(scaleCh1 + pbScaleCh1[i])
533                                        << (DFRACT_BITS - 1 - LD_DATA_SHIFT));
534     ldPwr2 =
535         (CalcLdData(pPwr2[i]) >> 1) + ((FIXP_DBL)(scaleCh2 + pbScaleCh2[i])
536                                        << (DFRACT_BITS - 1 - LD_DATA_SHIFT));
537 
538     ldPwr1 = fixMax(fixMin(ldPwr1, maxPwr), -maxPwr);
539     ldPwr2 = fixMax(fixMin(ldPwr2, maxPwr), -maxPwr);
540 
541     /* ldPwr1 and ldPwr2 are scaled by LD_DATA_SHIFT and additional 1 bit; 1 bit
542      * scale by fMultDiv2() */
543     cld = fMultDiv2(FL2FXCONST_DBL(LOG10_2_10 / (1 << SCALE_CLDE_SF)),
544                     ldPwr1 - ldPwr2);
545 
546     cld =
547         fixMin(cld, (FIXP_DBL)(((FIXP_DBL)MAXVAL_DBL) >> (LD_DATA_SHIFT + 2)));
548     cld =
549         fixMax(cld, (FIXP_DBL)(((FIXP_DBL)MINVAL_DBL) >> (LD_DATA_SHIFT + 2)));
550     pCld[i] = cld << (LD_DATA_SHIFT + 2);
551   }
552 }
553 
fdk_sacenc_applyTtoBox(HANDLE_TTO_BOX hTtoBox,const INT nTimeSlots,const INT startTimeSlot,const INT nHybridBands,const FIXP_DPK * const * const ppHybridData1__FDK,const FIXP_DPK * const * const ppHybridData2__FDK,SCHAR * const pIccIdx,UCHAR * const pbIccQuantCoarse,SCHAR * const pCldIdx,UCHAR * const pbCldQuantCoarse,const INT bUseBBCues,INT * scaleCh1,INT * scaleCh2)554 FDK_SACENC_ERROR fdk_sacenc_applyTtoBox(
555     HANDLE_TTO_BOX hTtoBox, const INT nTimeSlots, const INT startTimeSlot,
556     const INT nHybridBands, const FIXP_DPK *const *const ppHybridData1__FDK,
557     const FIXP_DPK *const *const ppHybridData2__FDK, SCHAR *const pIccIdx,
558     UCHAR *const pbIccQuantCoarse, SCHAR *const pCldIdx,
559     UCHAR *const pbCldQuantCoarse, const INT bUseBBCues, INT *scaleCh1,
560     INT *scaleCh2) {
561   FDK_SACENC_ERROR error = SACENC_OK;
562 
563   C_ALLOC_SCRATCH_START(powerHybridData1__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
564   C_ALLOC_SCRATCH_START(powerHybridData2__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
565   C_ALLOC_SCRATCH_START(prodHybridDataReal__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
566   C_ALLOC_SCRATCH_START(prodHybridDataImag__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
567 
568   C_ALLOC_SCRATCH_START(IccDownmix__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
569   C_ALLOC_SCRATCH_START(IccDownmixQuant__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
570   C_ALLOC_SCRATCH_START(pbScaleCh1, INT, MAX_NUM_PARAM_BANDS)
571   C_ALLOC_SCRATCH_START(pbScaleCh2, INT, MAX_NUM_PARAM_BANDS)
572 
573   if ((hTtoBox == NULL) || (pCldIdx == NULL) || (pbCldQuantCoarse == NULL) ||
574       (ppHybridData1__FDK == NULL) || (ppHybridData2__FDK == NULL) ||
575       (pIccIdx == NULL) || (pbIccQuantCoarse == NULL)) {
576     error = SACENC_INVALID_HANDLE;
577   } else {
578     int j, pb;
579     const int nParamBands = hTtoBox->nParameterBands;
580     const int bUseEbQ = (hTtoBox->boxQuantMode == BOX_QUANTMODE_EBQ1) ||
581                         (hTtoBox->boxQuantMode == BOX_QUANTMODE_EBQ2);
582 
583     /* sanity check */
584     if ((nHybridBands < 0) || (nHybridBands > hTtoBox->nHybridBandsMax)) {
585       error = SACENC_INVALID_CONFIG;
586       goto bail;
587     }
588 
589     int outScale;    /* scalefactor will not be evaluated */
590     int inScale = 5; /* scale factor determined empirically */
591 
592     /* calculate the headroom of the hybrid data for each parameter band */
593     FDKcalcPbScaleFactor(ppHybridData1__FDK,
594                          hTtoBox->pParameterBand2HybridBandOffset, pbScaleCh1,
595                          startTimeSlot, nTimeSlots, nParamBands);
596     FDKcalcPbScaleFactor(ppHybridData2__FDK,
597                          hTtoBox->pParameterBand2HybridBandOffset, pbScaleCh2,
598                          startTimeSlot, nTimeSlots, nParamBands);
599 
600     for (j = 0, pb = 0; pb < nParamBands; pb++) {
601       FIXP_DBL data1, data2;
602       data1 = data2 = (FIXP_DBL)0;
603       for (; j < hTtoBox->pParameterBand2HybridBandOffset[pb]; j++) {
604         data1 += sumUpCplxPow2Dim2(ppHybridData1__FDK, SUM_UP_STATIC_SCALE,
605                                    inScale + pbScaleCh1[pb], &outScale,
606                                    startTimeSlot, nTimeSlots, j, j + 1);
607         data2 += sumUpCplxPow2Dim2(ppHybridData2__FDK, SUM_UP_STATIC_SCALE,
608                                    inScale + pbScaleCh2[pb], &outScale,
609                                    startTimeSlot, nTimeSlots, j, j + 1);
610       } /* for j */
611       powerHybridData1__FDK[pb] = data1;
612       powerHybridData2__FDK[pb] = data2;
613     } /* pb */
614 
615     {
616       for (j = 0, pb = 0; pb < nParamBands; pb++) {
617         FIXP_DBL dataReal, dataImag;
618         dataReal = dataImag = (FIXP_DBL)0;
619         for (; j < hTtoBox->pParameterBand2HybridBandOffset[pb]; j++) {
620           FIXP_DPK scalarProd;
621           cplx_cplxScalarProduct(&scalarProd, ppHybridData1__FDK,
622                                  ppHybridData2__FDK, inScale + pbScaleCh1[pb],
623                                  inScale + pbScaleCh2[pb], &outScale,
624                                  startTimeSlot, nTimeSlots, j, j + 1);
625           dataReal += scalarProd.v.re;
626           if (hTtoBox->pSubbandImagSign[j] < 0) {
627             dataImag -= scalarProd.v.im;
628           } else {
629             dataImag += scalarProd.v.im;
630           }
631         } /* for j */
632         prodHybridDataReal__FDK[pb] = dataReal;
633         prodHybridDataImag__FDK[pb] = dataImag;
634       } /* pb */
635 
636       if (SACENC_OK != (error = calculateIccFDK(
637                             nParamBands, hTtoBox->iccCorrelationCoherenceBorder,
638                             powerHybridData1__FDK, powerHybridData2__FDK,
639                             prodHybridDataReal__FDK, prodHybridDataImag__FDK,
640                             hTtoBox->pIcc__FDK))) {
641         goto bail;
642       }
643 
644       /* calculate correlation based Icc for downmix */
645       if (SACENC_OK != (error = calculateIccFDK(
646                             nParamBands, nParamBands, powerHybridData1__FDK,
647                             powerHybridData2__FDK, prodHybridDataReal__FDK,
648                             prodHybridDataImag__FDK, IccDownmix__FDK))) {
649         goto bail;
650       }
651     }
652 
653     if (!bUseEbQ) {
654       CalculateCldFDK(hTtoBox->pCld__FDK, powerHybridData1__FDK,
655                       powerHybridData2__FDK, *scaleCh1 + inScale + 1,
656                       pbScaleCh1, *scaleCh2 + inScale + 1, pbScaleCh2,
657                       nParamBands);
658     }
659 
660     if (bUseBBCues) {
661       ApplyBBCuesFDK(&hTtoBox->pCld__FDK[0], nParamBands);
662 
663       { ApplyBBCuesFDK(&hTtoBox->pIcc__FDK[0], nParamBands); }
664 
665     } /* bUseBBCues */
666 
667     /* quantize/de-quantize icc */
668     {
669       QuantizeCoefFDK(hTtoBox->pIcc__FDK, nParamBands,
670                       hTtoBox->pIccQuantTable__FDK, hTtoBox->nIccQuantOffset,
671                       hTtoBox->nIccQuantSteps, pIccIdx);
672       QuantizeCoefFDK(IccDownmix__FDK, nParamBands,
673                       hTtoBox->pIccQuantTable__FDK, hTtoBox->nIccQuantOffset,
674                       hTtoBox->nIccQuantSteps, hTtoBox->pIccDownmixIdx);
675       deQuantizeCoefFDK(hTtoBox->pIccDownmixIdx, nParamBands,
676                         hTtoBox->pIccQuantTable__FDK, hTtoBox->nIccQuantOffset,
677                         IccDownmixQuant__FDK);
678 
679       *pbIccQuantCoarse = hTtoBox->bUseCoarseQuantIcc;
680     }
681 
682     /* quantize/de-quantize cld */
683     if (!bUseEbQ) {
684       QuantizeCoefFDK(hTtoBox->pCld__FDK, nParamBands,
685                       hTtoBox->pCldQuantTableEnc__FDK, hTtoBox->nCldQuantOffset,
686                       hTtoBox->nCldQuantSteps, pCldIdx);
687       deQuantizeCoefFDK(pCldIdx, nParamBands, hTtoBox->pCldQuantTableDec__FDK,
688                         hTtoBox->nCldQuantOffset, hTtoBox->pCldQuant__FDK);
689     } else {
690       FDKmemcpy(pCldIdx, hTtoBox->pCldEbQIdx, nParamBands * sizeof(SCHAR));
691     }
692     *pbCldQuantCoarse = hTtoBox->bUseCoarseQuantCld;
693 
694   } /* valid handle */
695 
696 bail:
697   C_ALLOC_SCRATCH_END(pbScaleCh2, INT, MAX_NUM_PARAM_BANDS)
698   C_ALLOC_SCRATCH_END(pbScaleCh1, INT, MAX_NUM_PARAM_BANDS)
699   C_ALLOC_SCRATCH_END(IccDownmixQuant__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
700   C_ALLOC_SCRATCH_END(IccDownmix__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
701 
702   C_ALLOC_SCRATCH_END(prodHybridDataImag__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
703   C_ALLOC_SCRATCH_END(prodHybridDataReal__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
704   C_ALLOC_SCRATCH_END(powerHybridData2__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
705   C_ALLOC_SCRATCH_END(powerHybridData1__FDK, FIXP_DBL, MAX_NUM_PARAM_BANDS)
706 
707   return error;
708 }
709 
fdk_sacenc_subband2ParamBand(const BOX_SUBBAND_CONFIG boxSubbandConfig,const INT nSubband)710 INT fdk_sacenc_subband2ParamBand(const BOX_SUBBAND_CONFIG boxSubbandConfig,
711                                  const INT nSubband) {
712   INT nParamBand = -1;
713   const UCHAR *pSubband2ParameterIndex =
714       getSubband2ParameterIndex(boxSubbandConfig);
715 
716   if (pSubband2ParameterIndex != NULL) {
717     const int hybrid_resolution = 64;
718 
719     if ((nSubband > -1) && (nSubband < hybrid_resolution)) {
720       nParamBand = pSubband2ParameterIndex[nSubband];
721     }
722   }
723 
724   return nParamBand;
725 }
726