1 /* -----------------------------------------------------------------------------
2 Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4 © Copyright 1995 - 2019 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 /******************* Library for basic calculation routines ********************
96
97 Author(s): Markus Lohwasser, Josef Hoepfl, Manuel Jander
98
99 Description: QMF filterbank
100
101 *******************************************************************************/
102
103 /*!
104 \file
105 \brief Complex qmf analysis/synthesis
106 This module contains the qmf filterbank for analysis [
107 cplxAnalysisQmfFiltering() ] and synthesis [ cplxSynthesisQmfFiltering() ]. It
108 is a polyphase implementation of a complex exponential modulated filter bank.
109 The analysis part usually runs at half the sample rate than the synthesis
110 part. (So called "dual-rate" mode.)
111
112 The coefficients of the prototype filter are specified in #qmf_pfilt640 (in
113 sbr_rom.cpp). Thus only a 64 channel version (32 on the analysis side) with a
114 640 tap prototype filter are used.
115
116 \anchor PolyphaseFiltering <h2>About polyphase filtering</h2>
117 The polyphase implementation of a filterbank requires filtering at the input
118 and output. This is implemented as part of cplxAnalysisQmfFiltering() and
119 cplxSynthesisQmfFiltering(). The implementation requires the filter
120 coefficients in a specific structure as described in #sbr_qmf_64_640_qmf (in
121 sbr_rom.cpp).
122
123 This module comprises the computationally most expensive functions of the SBR
124 decoder. The accuracy of computations is also important and has a direct
125 impact on the overall sound quality. Therefore a special test program is
126 available which can be used to only test the filterbank: main_audio.cpp
127
128 This modules also uses scaling of data to provide better SNR on fixed-point
129 processors. See #QMF_SCALE_FACTOR (in sbr_scale.h) for details. An interesting
130 note: The function getScalefactor() can constitute a significant amount of
131 computational complexity - very much depending on the bitrate. Since it is a
132 rather small function, effective assembler optimization might be possible.
133
134 */
135
136 #include "qmf.h"
137
138 #include "FDK_trigFcts.h"
139 #include "fixpoint_math.h"
140 #include "dct.h"
141
142 #define QSSCALE (0)
143 #define FX_DBL2FX_QSS(x) (x)
144 #define FX_QSS2FX_DBL(x) (x)
145
146 /* moved to qmf_pcm.h: -> qmfSynPrototypeFirSlot */
147 /* moved to qmf_pcm.h: -> qmfSynPrototypeFirSlot_NonSymmetric */
148 /* moved to qmf_pcm.h: -> qmfSynthesisFilteringSlot */
149
150 /*!
151 *
152 * \brief Perform real-valued forward modulation of the time domain
153 * data of timeIn and stores the real part of the subband
154 * samples in rSubband
155 *
156 */
qmfForwardModulationLP_even(HANDLE_QMF_FILTER_BANK anaQmf,FIXP_DBL * timeIn,FIXP_DBL * rSubband)157 static void qmfForwardModulationLP_even(
158 HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
159 FIXP_DBL *timeIn, /*!< Time Signal */
160 FIXP_DBL *rSubband) /*!< Real Output */
161 {
162 int i;
163 int L = anaQmf->no_channels;
164 int M = L >> 1;
165 int scale = 0;
166 FIXP_DBL accu;
167
168 const FIXP_DBL *timeInTmp1 = (FIXP_DBL *)&timeIn[3 * M];
169 const FIXP_DBL *timeInTmp2 = timeInTmp1;
170 FIXP_DBL *rSubbandTmp = rSubband;
171
172 rSubband[0] = timeIn[3 * M] >> 1;
173
174 for (i = M - 1; i != 0; i--) {
175 accu = ((*--timeInTmp1) >> 1) + ((*++timeInTmp2) >> 1);
176 *++rSubbandTmp = accu;
177 }
178
179 timeInTmp1 = &timeIn[2 * M];
180 timeInTmp2 = &timeIn[0];
181 rSubbandTmp = &rSubband[M];
182
183 for (i = L - M; i != 0; i--) {
184 accu = ((*timeInTmp1--) >> 1) - ((*timeInTmp2++) >> 1);
185 *rSubbandTmp++ = accu;
186 }
187
188 dct_III(rSubband, timeIn, L, &scale);
189 }
190
191 #if !defined(FUNCTION_qmfForwardModulationLP_odd)
qmfForwardModulationLP_odd(HANDLE_QMF_FILTER_BANK anaQmf,const FIXP_DBL * timeIn,FIXP_DBL * rSubband)192 static void qmfForwardModulationLP_odd(
193 HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
194 const FIXP_DBL *timeIn, /*!< Time Signal */
195 FIXP_DBL *rSubband) /*!< Real Output */
196 {
197 int i;
198 int L = anaQmf->no_channels;
199 int M = L >> 1;
200 int shift = (anaQmf->no_channels >> 6) + 1;
201
202 for (i = 0; i < M; i++) {
203 rSubband[M + i] = (timeIn[L - 1 - i] >> 1) - (timeIn[i] >> shift);
204 rSubband[M - 1 - i] =
205 (timeIn[L + i] >> 1) + (timeIn[2 * L - 1 - i] >> shift);
206 }
207
208 dct_IV(rSubband, L, &shift);
209 }
210 #endif /* !defined(FUNCTION_qmfForwardModulationLP_odd) */
211
212 /*!
213 *
214 * \brief Perform complex-valued forward modulation of the time domain
215 * data of timeIn and stores the real part of the subband
216 * samples in rSubband, and the imaginary part in iSubband
217 *
218 *
219 */
220 #if !defined(FUNCTION_qmfForwardModulationHQ)
qmfForwardModulationHQ(HANDLE_QMF_FILTER_BANK anaQmf,const FIXP_DBL * RESTRICT timeIn,FIXP_DBL * RESTRICT rSubband,FIXP_DBL * RESTRICT iSubband)221 static void qmfForwardModulationHQ(
222 HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */
223 const FIXP_DBL *RESTRICT timeIn, /*!< Time Signal */
224 FIXP_DBL *RESTRICT rSubband, /*!< Real Output */
225 FIXP_DBL *RESTRICT iSubband /*!< Imaginary Output */
226 ) {
227 int i;
228 int L = anaQmf->no_channels;
229 int L2 = L << 1;
230 int shift = 0;
231
232 /* Time advance by one sample, which is equivalent to the complex
233 rotation at the end of the analysis. Works only for STD mode. */
234 if ((L == 64) && !(anaQmf->flags & (QMF_FLAG_CLDFB | QMF_FLAG_MPSLDFB))) {
235 FIXP_DBL x, y;
236
237 /*rSubband[0] = u[1] + u[0]*/
238 /*iSubband[0] = u[1] - u[0]*/
239 x = timeIn[1] >> 1;
240 y = timeIn[0];
241 rSubband[0] = x + (y >> 1);
242 iSubband[0] = x - (y >> 1);
243
244 /*rSubband[n] = u[n+1] - u[2M-n], n=1,...,M-1*/
245 /*iSubband[n] = u[n+1] + u[2M-n], n=1,...,M-1*/
246 for (i = 1; i < L; i++) {
247 x = timeIn[i + 1] >> 1; /*u[n+1] */
248 y = timeIn[L2 - i]; /*u[2M-n] */
249 rSubband[i] = x - (y >> 1);
250 iSubband[i] = x + (y >> 1);
251 }
252 } else {
253 for (i = 0; i < L; i += 2) {
254 FIXP_DBL x0, x1, y0, y1;
255
256 x0 = timeIn[i + 0] >> 1;
257 x1 = timeIn[i + 1] >> 1;
258 y0 = timeIn[L2 - 1 - i];
259 y1 = timeIn[L2 - 2 - i];
260
261 rSubband[i + 0] = x0 - (y0 >> 1);
262 rSubband[i + 1] = x1 - (y1 >> 1);
263 iSubband[i + 0] = x0 + (y0 >> 1);
264 iSubband[i + 1] = x1 + (y1 >> 1);
265 }
266 }
267
268 dct_IV(rSubband, L, &shift);
269 dst_IV(iSubband, L, &shift);
270
271 /* Do the complex rotation except for the case of 64 bands (in STD mode). */
272 if ((L != 64) || (anaQmf->flags & (QMF_FLAG_CLDFB | QMF_FLAG_MPSLDFB))) {
273 if (anaQmf->flags & QMF_FLAG_MPSLDFB_OPTIMIZE_MODULATION) {
274 FIXP_DBL iBand;
275 for (i = 0; i < fMin(anaQmf->lsb, L); i += 2) {
276 iBand = rSubband[i];
277 rSubband[i] = -iSubband[i];
278 iSubband[i] = iBand;
279
280 iBand = -rSubband[i + 1];
281 rSubband[i + 1] = iSubband[i + 1];
282 iSubband[i + 1] = iBand;
283 }
284 } else {
285 const FIXP_QTW *sbr_t_cos;
286 const FIXP_QTW *sbr_t_sin;
287 const int len = L; /* was len = fMin(anaQmf->lsb, L) but in case of USAC
288 the signal above lsb is actually needed in some
289 cases (HBE?) */
290 sbr_t_cos = anaQmf->t_cos;
291 sbr_t_sin = anaQmf->t_sin;
292
293 for (i = 0; i < len; i++) {
294 cplxMult(&iSubband[i], &rSubband[i], iSubband[i], rSubband[i],
295 sbr_t_cos[i], sbr_t_sin[i]);
296 }
297 }
298 }
299 }
300 #endif /* FUNCTION_qmfForwardModulationHQ */
301
302 /*!
303 *
304 * \brief Perform low power inverse modulation of the subband
305 * samples stored in rSubband (real part) and iSubband (imaginary
306 * part) and stores the result in pWorkBuffer.
307 *
308 */
qmfInverseModulationLP_even(HANDLE_QMF_FILTER_BANK synQmf,const FIXP_DBL * qmfReal,const int scaleFactorLowBand,const int scaleFactorHighBand,FIXP_DBL * pTimeOut)309 inline static void qmfInverseModulationLP_even(
310 HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
311 const FIXP_DBL *qmfReal, /*!< Pointer to qmf real subband slot (input) */
312 const int scaleFactorLowBand, /*!< Scalefactor for Low band */
313 const int scaleFactorHighBand, /*!< Scalefactor for High band */
314 FIXP_DBL *pTimeOut /*!< Pointer to qmf subband slot (output)*/
315 ) {
316 int i;
317 int L = synQmf->no_channels;
318 int M = L >> 1;
319 int scale = 0;
320 FIXP_DBL tmp;
321 FIXP_DBL *RESTRICT tReal = pTimeOut;
322 FIXP_DBL *RESTRICT tImag = pTimeOut + L;
323
324 /* Move input to output vector with offset */
325 scaleValuesSaturate(&tReal[0], &qmfReal[0], synQmf->lsb, scaleFactorLowBand);
326 scaleValuesSaturate(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
327 synQmf->usb - synQmf->lsb, scaleFactorHighBand);
328 FDKmemclear(&tReal[0 + synQmf->usb], (L - synQmf->usb) * sizeof(FIXP_DBL));
329
330 /* Dct type-2 transform */
331 dct_II(tReal, tImag, L, &scale);
332
333 /* Expand output and replace inplace the output buffers */
334 tImag[0] = tReal[M];
335 tImag[M] = (FIXP_DBL)0;
336 tmp = tReal[0];
337 tReal[0] = tReal[M];
338 tReal[M] = tmp;
339
340 for (i = 1; i < M / 2; i++) {
341 /* Imag */
342 tmp = tReal[L - i];
343 tImag[M - i] = tmp;
344 tImag[i + M] = -tmp;
345
346 tmp = tReal[M + i];
347 tImag[i] = tmp;
348 tImag[L - i] = -tmp;
349
350 /* Real */
351 tReal[M + i] = tReal[i];
352 tReal[L - i] = tReal[M - i];
353 tmp = tReal[i];
354 tReal[i] = tReal[M - i];
355 tReal[M - i] = tmp;
356 }
357 /* Remaining odd terms */
358 tmp = tReal[M + M / 2];
359 tImag[M / 2] = tmp;
360 tImag[M / 2 + M] = -tmp;
361
362 tReal[M + M / 2] = tReal[M / 2];
363 }
364
qmfInverseModulationLP_odd(HANDLE_QMF_FILTER_BANK synQmf,const FIXP_DBL * qmfReal,const int scaleFactorLowBand,const int scaleFactorHighBand,FIXP_DBL * pTimeOut)365 inline static void qmfInverseModulationLP_odd(
366 HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
367 const FIXP_DBL *qmfReal, /*!< Pointer to qmf real subband slot (input) */
368 const int scaleFactorLowBand, /*!< Scalefactor for Low band */
369 const int scaleFactorHighBand, /*!< Scalefactor for High band */
370 FIXP_DBL *pTimeOut /*!< Pointer to qmf subband slot (output)*/
371 ) {
372 int i;
373 int L = synQmf->no_channels;
374 int M = L >> 1;
375 int shift = 0;
376
377 /* Move input to output vector with offset */
378 scaleValuesSaturate(pTimeOut + M, qmfReal, synQmf->lsb, scaleFactorLowBand);
379 scaleValuesSaturate(pTimeOut + M + synQmf->lsb, qmfReal + synQmf->lsb,
380 synQmf->usb - synQmf->lsb, scaleFactorHighBand);
381 FDKmemclear(pTimeOut + M + synQmf->usb, (L - synQmf->usb) * sizeof(FIXP_DBL));
382
383 dct_IV(pTimeOut + M, L, &shift);
384 for (i = 0; i < M; i++) {
385 pTimeOut[i] = pTimeOut[L - 1 - i];
386 pTimeOut[2 * L - 1 - i] = -pTimeOut[L + i];
387 }
388 }
389
390 #ifndef FUNCTION_qmfInverseModulationHQ
391 /*!
392 *
393 * \brief Perform complex-valued inverse modulation of the subband
394 * samples stored in rSubband (real part) and iSubband (imaginary
395 * part) and stores the result in pWorkBuffer.
396 *
397 */
qmfInverseModulationHQ(HANDLE_QMF_FILTER_BANK synQmf,const FIXP_DBL * qmfReal,const FIXP_DBL * qmfImag,const int scaleFactorLowBand,const int scaleFactorHighBand,FIXP_DBL * pWorkBuffer)398 inline static void qmfInverseModulationHQ(
399 HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
400 const FIXP_DBL *qmfReal, /*!< Pointer to qmf real subband slot */
401 const FIXP_DBL *qmfImag, /*!< Pointer to qmf imag subband slot */
402 const int scaleFactorLowBand, /*!< Scalefactor for Low band */
403 const int scaleFactorHighBand, /*!< Scalefactor for High band */
404 FIXP_DBL *pWorkBuffer /*!< WorkBuffer (output) */
405 ) {
406 int i;
407 int L = synQmf->no_channels;
408 int M = L >> 1;
409 int shift = 0;
410 FIXP_DBL *RESTRICT tReal = pWorkBuffer;
411 FIXP_DBL *RESTRICT tImag = pWorkBuffer + L;
412
413 if (synQmf->flags & QMF_FLAG_CLDFB) {
414 for (i = 0; i < synQmf->usb; i++) {
415 cplxMultDiv2(&tImag[i], &tReal[i], qmfImag[i], qmfReal[i],
416 synQmf->t_cos[i], synQmf->t_sin[i]);
417 }
418 scaleValuesSaturate(&tReal[0], synQmf->lsb, scaleFactorLowBand + 1);
419 scaleValuesSaturate(&tReal[0 + synQmf->lsb], synQmf->usb - synQmf->lsb,
420 scaleFactorHighBand + 1);
421 scaleValuesSaturate(&tImag[0], synQmf->lsb, scaleFactorLowBand + 1);
422 scaleValuesSaturate(&tImag[0 + synQmf->lsb], synQmf->usb - synQmf->lsb,
423 scaleFactorHighBand + 1);
424 }
425
426 if ((synQmf->flags & QMF_FLAG_CLDFB) == 0) {
427 scaleValuesSaturate(&tReal[0], &qmfReal[0], synQmf->lsb,
428 scaleFactorLowBand);
429 scaleValuesSaturate(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
430 synQmf->usb - synQmf->lsb, scaleFactorHighBand);
431 scaleValuesSaturate(&tImag[0], &qmfImag[0], synQmf->lsb,
432 scaleFactorLowBand);
433 scaleValuesSaturate(&tImag[0 + synQmf->lsb], &qmfImag[0 + synQmf->lsb],
434 synQmf->usb - synQmf->lsb, scaleFactorHighBand);
435 }
436
437 FDKmemclear(&tReal[synQmf->usb],
438 (synQmf->no_channels - synQmf->usb) * sizeof(FIXP_DBL));
439 FDKmemclear(&tImag[synQmf->usb],
440 (synQmf->no_channels - synQmf->usb) * sizeof(FIXP_DBL));
441
442 dct_IV(tReal, L, &shift);
443 dst_IV(tImag, L, &shift);
444
445 if (synQmf->flags & QMF_FLAG_CLDFB) {
446 for (i = 0; i < M; i++) {
447 FIXP_DBL r1, i1, r2, i2;
448 r1 = tReal[i];
449 i2 = tImag[L - 1 - i];
450 r2 = tReal[L - i - 1];
451 i1 = tImag[i];
452
453 tReal[i] = (r1 - i1) >> 1;
454 tImag[L - 1 - i] = -(r1 + i1) >> 1;
455 tReal[L - i - 1] = (r2 - i2) >> 1;
456 tImag[i] = -(r2 + i2) >> 1;
457 }
458 } else {
459 /* The array accesses are negative to compensate the missing minus sign in
460 * the low and hi band gain. */
461 /* 26 cycles on ARM926 */
462 for (i = 0; i < M; i++) {
463 FIXP_DBL r1, i1, r2, i2;
464 r1 = -tReal[i];
465 i2 = -tImag[L - 1 - i];
466 r2 = -tReal[L - i - 1];
467 i1 = -tImag[i];
468
469 tReal[i] = (r1 - i1) >> 1;
470 tImag[L - 1 - i] = -(r1 + i1) >> 1;
471 tReal[L - i - 1] = (r2 - i2) >> 1;
472 tImag[i] = -(r2 + i2) >> 1;
473 }
474 }
475 }
476 #endif /* #ifndef FUNCTION_qmfInverseModulationHQ */
477
478 /*!
479 *
480 * \brief Create QMF filter bank instance
481 *
482 * \return 0 if successful
483 *
484 */
qmfInitFilterBank(HANDLE_QMF_FILTER_BANK h_Qmf,void * pFilterStates,int noCols,int lsb,int usb,int no_channels,UINT flags,int synflag)485 static int qmfInitFilterBank(
486 HANDLE_QMF_FILTER_BANK h_Qmf, /*!< Handle to return */
487 void *pFilterStates, /*!< Handle to filter states */
488 int noCols, /*!< Number of timeslots per frame */
489 int lsb, /*!< Lower end of QMF frequency range */
490 int usb, /*!< Upper end of QMF frequency range */
491 int no_channels, /*!< Number of channels (bands) */
492 UINT flags, /*!< flags */
493 int synflag) /*!< 1: synthesis; 0: analysis */
494 {
495 FDKmemclear(h_Qmf, sizeof(QMF_FILTER_BANK));
496
497 if (flags & QMF_FLAG_MPSLDFB) {
498 flags |= QMF_FLAG_NONSYMMETRIC;
499 flags |= QMF_FLAG_MPSLDFB_OPTIMIZE_MODULATION;
500
501 h_Qmf->t_cos = NULL;
502 h_Qmf->t_sin = NULL;
503 h_Qmf->filterScale = QMF_MPSLDFB_PFT_SCALE;
504 h_Qmf->p_stride = 1;
505
506 switch (no_channels) {
507 case 64:
508 h_Qmf->p_filter = qmf_mpsldfb_640;
509 h_Qmf->FilterSize = 640;
510 break;
511 case 32:
512 h_Qmf->p_filter = qmf_mpsldfb_320;
513 h_Qmf->FilterSize = 320;
514 break;
515 default:
516 return -1;
517 }
518 }
519
520 if (!(flags & QMF_FLAG_MPSLDFB) && (flags & QMF_FLAG_CLDFB)) {
521 flags |= QMF_FLAG_NONSYMMETRIC;
522 h_Qmf->filterScale = QMF_CLDFB_PFT_SCALE;
523
524 h_Qmf->p_stride = 1;
525 switch (no_channels) {
526 case 64:
527 h_Qmf->t_cos = qmf_phaseshift_cos64_cldfb;
528 h_Qmf->t_sin = qmf_phaseshift_sin64_cldfb;
529 h_Qmf->p_filter = qmf_cldfb_640;
530 h_Qmf->FilterSize = 640;
531 break;
532 case 32:
533 h_Qmf->t_cos = (synflag) ? qmf_phaseshift_cos32_cldfb_syn
534 : qmf_phaseshift_cos32_cldfb_ana;
535 h_Qmf->t_sin = qmf_phaseshift_sin32_cldfb;
536 h_Qmf->p_filter = qmf_cldfb_320;
537 h_Qmf->FilterSize = 320;
538 break;
539 case 16:
540 h_Qmf->t_cos = (synflag) ? qmf_phaseshift_cos16_cldfb_syn
541 : qmf_phaseshift_cos16_cldfb_ana;
542 h_Qmf->t_sin = qmf_phaseshift_sin16_cldfb;
543 h_Qmf->p_filter = qmf_cldfb_160;
544 h_Qmf->FilterSize = 160;
545 break;
546 case 8:
547 h_Qmf->t_cos = (synflag) ? qmf_phaseshift_cos8_cldfb_syn
548 : qmf_phaseshift_cos8_cldfb_ana;
549 h_Qmf->t_sin = qmf_phaseshift_sin8_cldfb;
550 h_Qmf->p_filter = qmf_cldfb_80;
551 h_Qmf->FilterSize = 80;
552 break;
553 default:
554 return -1;
555 }
556 }
557
558 if (!(flags & QMF_FLAG_MPSLDFB) && ((flags & QMF_FLAG_CLDFB) == 0)) {
559 switch (no_channels) {
560 case 64:
561 h_Qmf->p_filter = qmf_pfilt640;
562 h_Qmf->t_cos = qmf_phaseshift_cos64;
563 h_Qmf->t_sin = qmf_phaseshift_sin64;
564 h_Qmf->p_stride = 1;
565 h_Qmf->FilterSize = 640;
566 h_Qmf->filterScale = 0;
567 break;
568 case 40:
569 if (synflag) {
570 break;
571 } else {
572 h_Qmf->p_filter = qmf_pfilt400; /* Scaling factor 0.8 */
573 h_Qmf->t_cos = qmf_phaseshift_cos40;
574 h_Qmf->t_sin = qmf_phaseshift_sin40;
575 h_Qmf->filterScale = 1;
576 h_Qmf->p_stride = 1;
577 h_Qmf->FilterSize = no_channels * 10;
578 }
579 break;
580 case 32:
581 h_Qmf->p_filter = qmf_pfilt640;
582 if (flags & QMF_FLAG_DOWNSAMPLED) {
583 h_Qmf->t_cos = qmf_phaseshift_cos_downsamp32;
584 h_Qmf->t_sin = qmf_phaseshift_sin_downsamp32;
585 } else {
586 h_Qmf->t_cos = qmf_phaseshift_cos32;
587 h_Qmf->t_sin = qmf_phaseshift_sin32;
588 }
589 h_Qmf->p_stride = 2;
590 h_Qmf->FilterSize = 640;
591 h_Qmf->filterScale = 0;
592 break;
593 case 20:
594 h_Qmf->p_filter = qmf_pfilt200;
595 h_Qmf->p_stride = 1;
596 h_Qmf->FilterSize = 200;
597 h_Qmf->filterScale = 0;
598 break;
599 case 12:
600 h_Qmf->p_filter = qmf_pfilt120;
601 h_Qmf->p_stride = 1;
602 h_Qmf->FilterSize = 120;
603 h_Qmf->filterScale = 0;
604 break;
605 case 8:
606 h_Qmf->p_filter = qmf_pfilt640;
607 h_Qmf->p_stride = 8;
608 h_Qmf->FilterSize = 640;
609 h_Qmf->filterScale = 0;
610 break;
611 case 16:
612 h_Qmf->p_filter = qmf_pfilt640;
613 h_Qmf->t_cos = qmf_phaseshift_cos16;
614 h_Qmf->t_sin = qmf_phaseshift_sin16;
615 h_Qmf->p_stride = 4;
616 h_Qmf->FilterSize = 640;
617 h_Qmf->filterScale = 0;
618 break;
619 case 24:
620 h_Qmf->p_filter = qmf_pfilt240;
621 h_Qmf->t_cos = qmf_phaseshift_cos24;
622 h_Qmf->t_sin = qmf_phaseshift_sin24;
623 h_Qmf->p_stride = 1;
624 h_Qmf->FilterSize = 240;
625 h_Qmf->filterScale = 1;
626 break;
627 default:
628 return -1;
629 }
630 }
631
632 h_Qmf->synScalefactor = h_Qmf->filterScale;
633 // DCT|DST dependency
634 switch (no_channels) {
635 case 128:
636 h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK + 1;
637 break;
638 case 40: {
639 h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK - 1;
640 } break;
641 case 64:
642 h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK;
643 break;
644 case 8:
645 h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK - 3;
646 break;
647 case 12:
648 h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK;
649 break;
650 case 20:
651 h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK + 1;
652 break;
653 case 32:
654 h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK - 1;
655 break;
656 case 16:
657 h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK - 2;
658 break;
659 case 24:
660 h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK - 1;
661 break;
662 default:
663 return -1;
664 }
665
666 h_Qmf->flags = flags;
667
668 h_Qmf->no_channels = no_channels;
669 h_Qmf->no_col = noCols;
670
671 h_Qmf->lsb = fMin(lsb, h_Qmf->no_channels);
672 h_Qmf->usb = synflag
673 ? fMin(usb, h_Qmf->no_channels)
674 : usb; /* was: h_Qmf->usb = fMin(usb, h_Qmf->no_channels); */
675
676 h_Qmf->FilterStates = (void *)pFilterStates;
677
678 h_Qmf->outScalefactor =
679 (ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + h_Qmf->filterScale) +
680 h_Qmf->synScalefactor;
681
682 h_Qmf->outGain_m =
683 (FIXP_DBL)0x80000000; /* default init value will be not applied */
684 h_Qmf->outGain_e = 0;
685
686 return (0);
687 }
688
689 /*!
690 *
691 * \brief Adjust synthesis qmf filter states
692 *
693 * \return void
694 *
695 */
qmfAdaptFilterStates(HANDLE_QMF_FILTER_BANK synQmf,int scaleFactorDiff)696 static inline void qmfAdaptFilterStates(
697 HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Filter Bank */
698 int scaleFactorDiff) /*!< Scale factor difference to be applied */
699 {
700 if (synQmf == NULL || synQmf->FilterStates == NULL) {
701 return;
702 }
703 if (scaleFactorDiff > 0) {
704 scaleValuesSaturate((FIXP_QSS *)synQmf->FilterStates,
705 synQmf->no_channels * (QMF_NO_POLY * 2 - 1),
706 scaleFactorDiff);
707 } else {
708 scaleValues((FIXP_QSS *)synQmf->FilterStates,
709 synQmf->no_channels * (QMF_NO_POLY * 2 - 1), scaleFactorDiff);
710 }
711 }
712
713 /*!
714 *
715 * \brief Create QMF filter bank instance
716 *
717 *
718 * \return 0 if succesful
719 *
720 */
qmfInitSynthesisFilterBank(HANDLE_QMF_FILTER_BANK h_Qmf,FIXP_QSS * pFilterStates,int noCols,int lsb,int usb,int no_channels,int flags)721 int qmfInitSynthesisFilterBank(
722 HANDLE_QMF_FILTER_BANK h_Qmf, /*!< Returns handle */
723 FIXP_QSS *pFilterStates, /*!< Handle to filter states */
724 int noCols, /*!< Number of timeslots per frame */
725 int lsb, /*!< lower end of QMF */
726 int usb, /*!< upper end of QMF */
727 int no_channels, /*!< Number of channels (bands) */
728 int flags) /*!< Low Power flag */
729 {
730 int oldOutScale = h_Qmf->outScalefactor;
731 int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb,
732 no_channels, flags, 1);
733 if (h_Qmf->FilterStates != NULL) {
734 if (!(flags & QMF_FLAG_KEEP_STATES)) {
735 FDKmemclear(
736 h_Qmf->FilterStates,
737 (2 * QMF_NO_POLY - 1) * h_Qmf->no_channels * sizeof(FIXP_QSS));
738 } else {
739 qmfAdaptFilterStates(h_Qmf, oldOutScale - h_Qmf->outScalefactor);
740 }
741 }
742
743 FDK_ASSERT(h_Qmf->no_channels >= h_Qmf->lsb);
744 FDK_ASSERT(h_Qmf->no_channels >= h_Qmf->usb);
745
746 return err;
747 }
748
749 /*!
750 *
751 * \brief Change scale factor for output data and adjust qmf filter states
752 *
753 * \return void
754 *
755 */
qmfChangeOutScalefactor(HANDLE_QMF_FILTER_BANK synQmf,int outScalefactor)756 void qmfChangeOutScalefactor(
757 HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
758 int outScalefactor /*!< New scaling factor for output data */
759 ) {
760 if (synQmf == NULL) {
761 return;
762 }
763
764 /* Add internal filterbank scale */
765 outScalefactor +=
766 (ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + synQmf->filterScale) +
767 synQmf->synScalefactor;
768
769 /* adjust filter states when scale factor has been changed */
770 if (synQmf->outScalefactor != outScalefactor) {
771 int diff;
772
773 diff = synQmf->outScalefactor - outScalefactor;
774
775 qmfAdaptFilterStates(synQmf, diff);
776
777 /* save new scale factor */
778 synQmf->outScalefactor = outScalefactor;
779 }
780 }
781
782 /*!
783 *
784 * \brief Get scale factor change which was set by qmfChangeOutScalefactor()
785 *
786 * \return scaleFactor
787 *
788 */
qmfGetOutScalefactor(HANDLE_QMF_FILTER_BANK synQmf)789 int qmfGetOutScalefactor(
790 HANDLE_QMF_FILTER_BANK synQmf) /*!< Handle of Qmf Synthesis Bank */
791 {
792 int scaleFactor = synQmf->outScalefactor
793 ? (synQmf->outScalefactor -
794 (ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK +
795 synQmf->filterScale + synQmf->synScalefactor))
796 : 0;
797 return scaleFactor;
798 }
799
800 /*!
801 *
802 * \brief Change gain for output data
803 *
804 * \return void
805 *
806 */
qmfChangeOutGain(HANDLE_QMF_FILTER_BANK synQmf,FIXP_DBL outputGain,int outputGainScale)807 void qmfChangeOutGain(
808 HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
809 FIXP_DBL outputGain, /*!< New gain for output data (mantissa) */
810 int outputGainScale /*!< New gain for output data (exponent) */
811 ) {
812 synQmf->outGain_m = outputGain;
813 synQmf->outGain_e = outputGainScale;
814 }
815
816 #define INT_PCM_QMFOUT INT_PCM
817 #define SAMPLE_BITS_QMFOUT SAMPLE_BITS
818 #include "qmf_pcm.h"
819 #if SAMPLE_BITS == 16
820 /* also create a 32 bit output version */
821 #undef INT_PCM_QMFOUT
822 #undef SAMPLE_BITS_QMFOUT
823 #undef QMF_PCM_H
824 #undef FIXP_QAS
825 #undef QAS_BITS
826 #undef INT_PCM_QMFIN
827 #define INT_PCM_QMFOUT LONG
828 #define SAMPLE_BITS_QMFOUT 32
829 #define FIXP_QAS FIXP_DBL
830 #define QAS_BITS 32
831 #define INT_PCM_QMFIN LONG
832 #include "qmf_pcm.h"
833 #endif
834