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