Coverage Report

Created: 2026-06-10 06:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/aac/libFDK/src/qmf.cpp
Line
Count
Source
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
 */
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
1.10M
{
162
1.10M
  int i;
163
1.10M
  int L = anaQmf->no_channels;
164
1.10M
  int M = L >> 1;
165
1.10M
  int scale = 0;
166
1.10M
  FIXP_DBL accu;
167
168
1.10M
  const FIXP_DBL *timeInTmp1 = (FIXP_DBL *)&timeIn[3 * M];
169
1.10M
  const FIXP_DBL *timeInTmp2 = timeInTmp1;
170
1.10M
  FIXP_DBL *rSubbandTmp = rSubband;
171
172
1.10M
  rSubband[0] = timeIn[3 * M] >> 1;
173
174
17.7M
  for (i = M - 1; i != 0; i--) {
175
16.6M
    accu = ((*--timeInTmp1) >> 1) + ((*++timeInTmp2) >> 1);
176
16.6M
    *++rSubbandTmp = accu;
177
16.6M
  }
178
179
1.10M
  timeInTmp1 = &timeIn[2 * M];
180
1.10M
  timeInTmp2 = &timeIn[0];
181
1.10M
  rSubbandTmp = &rSubband[M];
182
183
18.8M
  for (i = L - M; i != 0; i--) {
184
17.7M
    accu = ((*timeInTmp1--) >> 1) - ((*timeInTmp2++) >> 1);
185
17.7M
    *rSubbandTmp++ = accu;
186
17.7M
  }
187
188
1.10M
  dct_III(rSubband, timeIn, L, &scale);
189
1.10M
}
190
191
#if !defined(FUNCTION_qmfForwardModulationLP_odd)
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
2.07M
{
197
2.07M
  int i;
198
2.07M
  int L = anaQmf->no_channels;
199
2.07M
  int M = L >> 1;
200
2.07M
  int shift = (anaQmf->no_channels >> 6) + 1;
201
202
33.9M
  for (i = 0; i < M; i++) {
203
31.8M
    rSubband[M + i] = (timeIn[L - 1 - i] >> 1) - (timeIn[i] >> shift);
204
31.8M
    rSubband[M - 1 - i] =
205
31.8M
        (timeIn[L + i] >> 1) + (timeIn[2 * L - 1 - i] >> shift);
206
31.8M
  }
207
208
2.07M
  dct_IV(rSubband, L, &shift);
209
2.07M
}
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)
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
12.7M
) {
227
12.7M
  int i;
228
12.7M
  int L = anaQmf->no_channels;
229
12.7M
  int L2 = L << 1;
230
12.7M
  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
12.7M
  if ((L == 64) && !(anaQmf->flags & (QMF_FLAG_CLDFB | QMF_FLAG_MPSLDFB))) {
235
0
    FIXP_DBL x, y;
236
237
    /*rSubband[0] = u[1] + u[0]*/
238
    /*iSubband[0] = u[1] - u[0]*/
239
0
    x = timeIn[1] >> 1;
240
0
    y = timeIn[0];
241
0
    rSubband[0] = x + (y >> 1);
242
0
    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
0
    for (i = 1; i < L; i++) {
247
0
      x = timeIn[i + 1] >> 1; /*u[n+1]  */
248
0
      y = timeIn[L2 - i];     /*u[2M-n] */
249
0
      rSubband[i] = x - (y >> 1);
250
0
      iSubband[i] = x + (y >> 1);
251
0
    }
252
12.7M
  } else {
253
174M
    for (i = 0; i < L; i += 2) {
254
161M
      FIXP_DBL x0, x1, y0, y1;
255
256
161M
      x0 = timeIn[i + 0] >> 1;
257
161M
      x1 = timeIn[i + 1] >> 1;
258
161M
      y0 = timeIn[L2 - 1 - i];
259
161M
      y1 = timeIn[L2 - 2 - i];
260
261
161M
      rSubband[i + 0] = x0 - (y0 >> 1);
262
161M
      rSubband[i + 1] = x1 - (y1 >> 1);
263
161M
      iSubband[i + 0] = x0 + (y0 >> 1);
264
161M
      iSubband[i + 1] = x1 + (y1 >> 1);
265
161M
    }
266
12.7M
  }
267
268
12.7M
  dct_IV(rSubband, L, &shift);
269
12.7M
  dst_IV(iSubband, L, &shift);
270
271
  /* Do the complex rotation except for the case of 64 bands (in STD mode). */
272
12.7M
  if ((L != 64) || (anaQmf->flags & (QMF_FLAG_CLDFB | QMF_FLAG_MPSLDFB))) {
273
12.7M
    if (anaQmf->flags & QMF_FLAG_MPSLDFB_OPTIMIZE_MODULATION) {
274
556k
      FIXP_DBL iBand;
275
9.55M
      for (i = 0; i < fMin(anaQmf->lsb, L); i += 2) {
276
9.00M
        iBand = rSubband[i];
277
9.00M
        rSubband[i] = -iSubband[i];
278
9.00M
        iSubband[i] = iBand;
279
280
9.00M
        iBand = -rSubband[i + 1];
281
9.00M
        rSubband[i + 1] = iSubband[i + 1];
282
9.00M
        iSubband[i + 1] = iBand;
283
9.00M
      }
284
12.2M
    } else {
285
12.2M
      const FIXP_QTW *sbr_t_cos;
286
12.2M
      const FIXP_QTW *sbr_t_sin;
287
12.2M
      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
12.2M
      sbr_t_cos = anaQmf->t_cos;
291
12.2M
      sbr_t_sin = anaQmf->t_sin;
292
293
318M
      for (i = 0; i < len; i++) {
294
305M
        cplxMult(&iSubband[i], &rSubband[i], iSubband[i], rSubband[i],
295
305M
                 sbr_t_cos[i], sbr_t_sin[i]);
296
305M
      }
297
12.2M
    }
298
12.7M
  }
299
12.7M
}
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
 */
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
5.65M
) {
316
5.65M
  int i;
317
5.65M
  int L = synQmf->no_channels;
318
5.65M
  int M = L >> 1;
319
5.65M
  int scale = 0;
320
5.65M
  FIXP_DBL tmp;
321
5.65M
  FIXP_DBL *RESTRICT tReal = pTimeOut;
322
5.65M
  FIXP_DBL *RESTRICT tImag = pTimeOut + L;
323
324
  /* Move input to output vector with offset */
325
5.65M
  scaleValuesSaturate(&tReal[0], &qmfReal[0], synQmf->lsb, scaleFactorLowBand);
326
5.65M
  scaleValuesSaturate(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
327
5.65M
                      synQmf->usb - synQmf->lsb, scaleFactorHighBand);
328
5.65M
  FDKmemclear(&tReal[0 + synQmf->usb], (L - synQmf->usb) * sizeof(FIXP_DBL));
329
330
  /* Dct type-2 transform */
331
5.65M
  dct_II(tReal, tImag, L, &scale);
332
333
  /* Expand output and replace inplace the output buffers */
334
5.65M
  tImag[0] = tReal[M];
335
5.65M
  tImag[M] = (FIXP_DBL)0;
336
5.65M
  tmp = tReal[0];
337
5.65M
  tReal[0] = tReal[M];
338
5.65M
  tReal[M] = tmp;
339
340
31.7M
  for (i = 1; i < M / 2; i++) {
341
    /* Imag */
342
26.0M
    tmp = tReal[L - i];
343
26.0M
    tImag[M - i] = tmp;
344
26.0M
    tImag[i + M] = -tmp;
345
346
26.0M
    tmp = tReal[M + i];
347
26.0M
    tImag[i] = tmp;
348
26.0M
    tImag[L - i] = -tmp;
349
350
    /* Real */
351
26.0M
    tReal[M + i] = tReal[i];
352
26.0M
    tReal[L - i] = tReal[M - i];
353
26.0M
    tmp = tReal[i];
354
26.0M
    tReal[i] = tReal[M - i];
355
26.0M
    tReal[M - i] = tmp;
356
26.0M
  }
357
  /* Remaining odd terms */
358
5.65M
  tmp = tReal[M + M / 2];
359
5.65M
  tImag[M / 2] = tmp;
360
5.65M
  tImag[M / 2 + M] = -tmp;
361
362
5.65M
  tReal[M + M / 2] = tReal[M / 2];
363
5.65M
}
364
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
2.07M
) {
372
2.07M
  int i;
373
2.07M
  int L = synQmf->no_channels;
374
2.07M
  int M = L >> 1;
375
2.07M
  int shift = 0;
376
377
  /* Move input to output vector with offset */
378
2.07M
  scaleValuesSaturate(pTimeOut + M, qmfReal, synQmf->lsb, scaleFactorLowBand);
379
2.07M
  scaleValuesSaturate(pTimeOut + M + synQmf->lsb, qmfReal + synQmf->lsb,
380
2.07M
                      synQmf->usb - synQmf->lsb, scaleFactorHighBand);
381
2.07M
  FDKmemclear(pTimeOut + M + synQmf->usb, (L - synQmf->usb) * sizeof(FIXP_DBL));
382
383
2.07M
  dct_IV(pTimeOut + M, L, &shift);
384
53.4M
  for (i = 0; i < M; i++) {
385
51.4M
    pTimeOut[i] = pTimeOut[L - 1 - i];
386
51.4M
    pTimeOut[2 * L - 1 - i] = -pTimeOut[L + i];
387
51.4M
  }
388
2.07M
}
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
 */
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
14.7M
) {
406
14.7M
  int i;
407
14.7M
  int L = synQmf->no_channels;
408
14.7M
  int M = L >> 1;
409
14.7M
  int shift = 0;
410
14.7M
  FIXP_DBL *RESTRICT tReal = pWorkBuffer;
411
14.7M
  FIXP_DBL *RESTRICT tImag = pWorkBuffer + L;
412
413
14.7M
  if (synQmf->flags & QMF_FLAG_CLDFB) {
414
891k
    for (i = 0; i < synQmf->usb; i++) {
415
866k
      cplxMultDiv2(&tImag[i], &tReal[i], qmfImag[i], qmfReal[i],
416
866k
                   synQmf->t_cos[i], synQmf->t_sin[i]);
417
866k
    }
418
24.8k
    scaleValuesSaturate(&tReal[0], synQmf->lsb, scaleFactorLowBand + 1);
419
24.8k
    scaleValuesSaturate(&tReal[0 + synQmf->lsb], synQmf->usb - synQmf->lsb,
420
24.8k
                        scaleFactorHighBand + 1);
421
24.8k
    scaleValuesSaturate(&tImag[0], synQmf->lsb, scaleFactorLowBand + 1);
422
24.8k
    scaleValuesSaturate(&tImag[0 + synQmf->lsb], synQmf->usb - synQmf->lsb,
423
24.8k
                        scaleFactorHighBand + 1);
424
24.8k
  }
425
426
14.7M
  if ((synQmf->flags & QMF_FLAG_CLDFB) == 0) {
427
14.7M
    scaleValuesSaturate(&tReal[0], &qmfReal[0], synQmf->lsb,
428
14.7M
                        scaleFactorLowBand);
429
14.7M
    scaleValuesSaturate(&tReal[0 + synQmf->lsb], &qmfReal[0 + synQmf->lsb],
430
14.7M
                        synQmf->usb - synQmf->lsb, scaleFactorHighBand);
431
14.7M
    scaleValuesSaturate(&tImag[0], &qmfImag[0], synQmf->lsb,
432
14.7M
                        scaleFactorLowBand);
433
14.7M
    scaleValuesSaturate(&tImag[0 + synQmf->lsb], &qmfImag[0 + synQmf->lsb],
434
14.7M
                        synQmf->usb - synQmf->lsb, scaleFactorHighBand);
435
14.7M
  }
436
437
14.7M
  FDKmemclear(&tReal[synQmf->usb],
438
14.7M
              (synQmf->no_channels - synQmf->usb) * sizeof(FIXP_DBL));
439
14.7M
  FDKmemclear(&tImag[synQmf->usb],
440
14.7M
              (synQmf->no_channels - synQmf->usb) * sizeof(FIXP_DBL));
441
442
14.7M
  dct_IV(tReal, L, &shift);
443
14.7M
  dst_IV(tImag, L, &shift);
444
445
14.7M
  if (synQmf->flags & QMF_FLAG_CLDFB) {
446
589k
    for (i = 0; i < M; i++) {
447
564k
      FIXP_DBL r1, i1, r2, i2;
448
564k
      r1 = tReal[i];
449
564k
      i2 = tImag[L - 1 - i];
450
564k
      r2 = tReal[L - i - 1];
451
564k
      i1 = tImag[i];
452
453
564k
      tReal[i] = (r1 - i1) >> 1;
454
564k
      tImag[L - 1 - i] = -(r1 + i1) >> 1;
455
564k
      tReal[L - i - 1] = (r2 - i2) >> 1;
456
564k
      tImag[i] = -(r2 + i2) >> 1;
457
564k
    }
458
14.7M
  } 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
468M
    for (i = 0; i < M; i++) {
463
453M
      FIXP_DBL r1, i1, r2, i2;
464
453M
      r1 = -tReal[i];
465
453M
      i2 = -tImag[L - 1 - i];
466
453M
      r2 = -tReal[L - i - 1];
467
453M
      i1 = -tImag[i];
468
469
453M
      tReal[i] = (r1 - i1) >> 1;
470
453M
      tImag[L - 1 - i] = -(r1 + i1) >> 1;
471
453M
      tReal[L - i - 1] = (r2 - i2) >> 1;
472
453M
      tImag[i] = -(r2 + i2) >> 1;
473
453M
    }
474
14.7M
  }
475
14.7M
}
476
#endif /* #ifndef FUNCTION_qmfInverseModulationHQ */
477
478
/*!
479
 *
480
 * \brief Create QMF filter bank instance
481
 *
482
 * \return 0 if successful
483
 *
484
 */
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
277k
{
495
277k
  FDKmemclear(h_Qmf, sizeof(QMF_FILTER_BANK));
496
497
277k
  if (flags & QMF_FLAG_MPSLDFB) {
498
14.9k
    flags |= QMF_FLAG_NONSYMMETRIC;
499
14.9k
    flags |= QMF_FLAG_MPSLDFB_OPTIMIZE_MODULATION;
500
501
14.9k
    h_Qmf->t_cos = NULL;
502
14.9k
    h_Qmf->t_sin = NULL;
503
14.9k
    h_Qmf->filterScale = QMF_MPSLDFB_PFT_SCALE;
504
14.9k
    h_Qmf->p_stride = 1;
505
506
14.9k
    switch (no_channels) {
507
2.84k
      case 64:
508
2.84k
        h_Qmf->p_filter = qmf_mpsldfb_640;
509
2.84k
        h_Qmf->FilterSize = 640;
510
2.84k
        break;
511
12.1k
      case 32:
512
12.1k
        h_Qmf->p_filter = qmf_mpsldfb_320;
513
12.1k
        h_Qmf->FilterSize = 320;
514
12.1k
        break;
515
0
      default:
516
0
        return -1;
517
14.9k
    }
518
14.9k
  }
519
520
277k
  if (!(flags & QMF_FLAG_MPSLDFB) && (flags & QMF_FLAG_CLDFB)) {
521
117k
    flags |= QMF_FLAG_NONSYMMETRIC;
522
117k
    h_Qmf->filterScale = QMF_CLDFB_PFT_SCALE;
523
524
117k
    h_Qmf->p_stride = 1;
525
117k
    switch (no_channels) {
526
8.07k
      case 64:
527
8.07k
        h_Qmf->t_cos = qmf_phaseshift_cos64_cldfb;
528
8.07k
        h_Qmf->t_sin = qmf_phaseshift_sin64_cldfb;
529
8.07k
        h_Qmf->p_filter = qmf_cldfb_640;
530
8.07k
        h_Qmf->FilterSize = 640;
531
8.07k
        break;
532
81.9k
      case 32:
533
81.9k
        h_Qmf->t_cos = (synflag) ? qmf_phaseshift_cos32_cldfb_syn
534
81.9k
                                 : qmf_phaseshift_cos32_cldfb_ana;
535
81.9k
        h_Qmf->t_sin = qmf_phaseshift_sin32_cldfb;
536
81.9k
        h_Qmf->p_filter = qmf_cldfb_320;
537
81.9k
        h_Qmf->FilterSize = 320;
538
81.9k
        break;
539
23.5k
      case 16:
540
23.5k
        h_Qmf->t_cos = (synflag) ? qmf_phaseshift_cos16_cldfb_syn
541
23.5k
                                 : qmf_phaseshift_cos16_cldfb_ana;
542
23.5k
        h_Qmf->t_sin = qmf_phaseshift_sin16_cldfb;
543
23.5k
        h_Qmf->p_filter = qmf_cldfb_160;
544
23.5k
        h_Qmf->FilterSize = 160;
545
23.5k
        break;
546
4.03k
      case 8:
547
4.03k
        h_Qmf->t_cos = (synflag) ? qmf_phaseshift_cos8_cldfb_syn
548
4.03k
                                 : qmf_phaseshift_cos8_cldfb_ana;
549
4.03k
        h_Qmf->t_sin = qmf_phaseshift_sin8_cldfb;
550
4.03k
        h_Qmf->p_filter = qmf_cldfb_80;
551
4.03k
        h_Qmf->FilterSize = 80;
552
4.03k
        break;
553
0
      default:
554
0
        return -1;
555
117k
    }
556
117k
  }
557
558
277k
  if (!(flags & QMF_FLAG_MPSLDFB) && ((flags & QMF_FLAG_CLDFB) == 0)) {
559
144k
    switch (no_channels) {
560
45.6k
      case 64:
561
45.6k
        h_Qmf->p_filter = qmf_pfilt640;
562
45.6k
        h_Qmf->t_cos = qmf_phaseshift_cos64;
563
45.6k
        h_Qmf->t_sin = qmf_phaseshift_sin64;
564
45.6k
        h_Qmf->p_stride = 1;
565
45.6k
        h_Qmf->FilterSize = 640;
566
45.6k
        h_Qmf->filterScale = 0;
567
45.6k
        break;
568
1.17k
      case 40:
569
1.17k
        if (synflag) {
570
0
          break;
571
1.17k
        } else {
572
1.17k
          h_Qmf->p_filter = qmf_pfilt400; /* Scaling factor 0.8 */
573
1.17k
          h_Qmf->t_cos = qmf_phaseshift_cos40;
574
1.17k
          h_Qmf->t_sin = qmf_phaseshift_sin40;
575
1.17k
          h_Qmf->filterScale = 1;
576
1.17k
          h_Qmf->p_stride = 1;
577
1.17k
          h_Qmf->FilterSize = no_channels * 10;
578
1.17k
        }
579
1.17k
        break;
580
34.2k
      case 32:
581
34.2k
        h_Qmf->p_filter = qmf_pfilt640;
582
34.2k
        if (flags & QMF_FLAG_DOWNSAMPLED) {
583
1.02k
          h_Qmf->t_cos = qmf_phaseshift_cos_downsamp32;
584
1.02k
          h_Qmf->t_sin = qmf_phaseshift_sin_downsamp32;
585
33.1k
        } else {
586
33.1k
          h_Qmf->t_cos = qmf_phaseshift_cos32;
587
33.1k
          h_Qmf->t_sin = qmf_phaseshift_sin32;
588
33.1k
        }
589
34.2k
        h_Qmf->p_stride = 2;
590
34.2k
        h_Qmf->FilterSize = 640;
591
34.2k
        h_Qmf->filterScale = 0;
592
34.2k
        break;
593
1.17k
      case 20:
594
1.17k
        h_Qmf->p_filter = qmf_pfilt200;
595
1.17k
        h_Qmf->p_stride = 1;
596
1.17k
        h_Qmf->FilterSize = 200;
597
1.17k
        h_Qmf->filterScale = 0;
598
1.17k
        break;
599
13.9k
      case 12:
600
13.9k
        h_Qmf->p_filter = qmf_pfilt120;
601
13.9k
        h_Qmf->p_stride = 1;
602
13.9k
        h_Qmf->FilterSize = 120;
603
13.9k
        h_Qmf->filterScale = 0;
604
13.9k
        break;
605
3.84k
      case 8:
606
3.84k
        h_Qmf->p_filter = qmf_pfilt640;
607
3.84k
        h_Qmf->p_stride = 8;
608
3.84k
        h_Qmf->FilterSize = 640;
609
3.84k
        h_Qmf->filterScale = 0;
610
3.84k
        break;
611
19.2k
      case 16:
612
19.2k
        h_Qmf->p_filter = qmf_pfilt640;
613
19.2k
        h_Qmf->t_cos = qmf_phaseshift_cos16;
614
19.2k
        h_Qmf->t_sin = qmf_phaseshift_sin16;
615
19.2k
        h_Qmf->p_stride = 4;
616
19.2k
        h_Qmf->FilterSize = 640;
617
19.2k
        h_Qmf->filterScale = 0;
618
19.2k
        break;
619
25.2k
      case 24:
620
25.2k
        h_Qmf->p_filter = qmf_pfilt240;
621
25.2k
        h_Qmf->t_cos = qmf_phaseshift_cos24;
622
25.2k
        h_Qmf->t_sin = qmf_phaseshift_sin24;
623
25.2k
        h_Qmf->p_stride = 1;
624
25.2k
        h_Qmf->FilterSize = 240;
625
25.2k
        h_Qmf->filterScale = 1;
626
25.2k
        break;
627
14
      default:
628
14
        return -1;
629
144k
    }
630
144k
  }
631
632
277k
  h_Qmf->synScalefactor = h_Qmf->filterScale;
633
  // DCT|DST dependency
634
277k
  switch (no_channels) {
635
0
    case 128:
636
0
      h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK + 1;
637
0
      break;
638
1.17k
    case 40: {
639
1.17k
      h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK - 1;
640
1.17k
    } break;
641
56.5k
    case 64:
642
56.5k
      h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK;
643
56.5k
      break;
644
7.88k
    case 8:
645
7.88k
      h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK - 3;
646
7.88k
      break;
647
13.9k
    case 12:
648
13.9k
      h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK;
649
13.9k
      break;
650
1.17k
    case 20:
651
1.17k
      h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK + 1;
652
1.17k
      break;
653
128k
    case 32:
654
128k
      h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK - 1;
655
128k
      break;
656
42.7k
    case 16:
657
42.7k
      h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK - 2;
658
42.7k
      break;
659
25.2k
    case 24:
660
25.2k
      h_Qmf->synScalefactor += ALGORITHMIC_SCALING_IN_SYNTHESIS_FILTERBANK - 1;
661
25.2k
      break;
662
0
    default:
663
0
      return -1;
664
277k
  }
665
666
277k
  h_Qmf->flags = flags;
667
668
277k
  h_Qmf->no_channels = no_channels;
669
277k
  h_Qmf->no_col = noCols;
670
671
277k
  h_Qmf->lsb = fMin(lsb, h_Qmf->no_channels);
672
277k
  h_Qmf->usb = synflag
673
277k
                   ? fMin(usb, h_Qmf->no_channels)
674
277k
                   : usb; /* was: h_Qmf->usb = fMin(usb, h_Qmf->no_channels); */
675
676
277k
  h_Qmf->FilterStates = (void *)pFilterStates;
677
678
277k
  h_Qmf->outScalefactor =
679
277k
      (ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + h_Qmf->filterScale) +
680
277k
      h_Qmf->synScalefactor;
681
682
277k
  h_Qmf->outGain_m =
683
277k
      (FIXP_DBL)0x80000000; /* default init value will be not applied */
684
277k
  h_Qmf->outGain_e = 0;
685
686
277k
  return (0);
687
277k
}
688
689
/*!
690
 *
691
 * \brief Adjust synthesis qmf filter states
692
 *
693
 * \return void
694
 *
695
 */
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
138k
{
700
138k
  if (synQmf == NULL || synQmf->FilterStates == NULL) {
701
0
    return;
702
0
  }
703
138k
  if (scaleFactorDiff > 0) {
704
86.9k
    scaleValuesSaturate((FIXP_QSS *)synQmf->FilterStates,
705
86.9k
                        synQmf->no_channels * (QMF_NO_POLY * 2 - 1),
706
86.9k
                        scaleFactorDiff);
707
86.9k
  } else {
708
51.9k
    scaleValues((FIXP_QSS *)synQmf->FilterStates,
709
51.9k
                synQmf->no_channels * (QMF_NO_POLY * 2 - 1), scaleFactorDiff);
710
51.9k
  }
711
138k
}
712
713
/*!
714
 *
715
 * \brief Create QMF filter bank instance
716
 *
717
 *
718
 * \return 0 if succesful
719
 *
720
 */
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
143k
{
730
143k
  int oldOutScale = h_Qmf->outScalefactor;
731
143k
  int err = qmfInitFilterBank(h_Qmf, pFilterStates, noCols, lsb, usb,
732
143k
                              no_channels, flags, 1);
733
143k
  if (h_Qmf->FilterStates != NULL) {
734
143k
    if (!(flags & QMF_FLAG_KEEP_STATES)) {
735
97.0k
      FDKmemclear(
736
97.0k
          h_Qmf->FilterStates,
737
97.0k
          (2 * QMF_NO_POLY - 1) * h_Qmf->no_channels * sizeof(FIXP_QSS));
738
97.0k
    } else {
739
46.7k
      qmfAdaptFilterStates(h_Qmf, oldOutScale - h_Qmf->outScalefactor);
740
46.7k
    }
741
143k
  }
742
743
143k
  FDK_ASSERT(h_Qmf->no_channels >= h_Qmf->lsb);
744
143k
  FDK_ASSERT(h_Qmf->no_channels >= h_Qmf->usb);
745
746
143k
  return err;
747
143k
}
748
749
/*!
750
 *
751
 * \brief Change scale factor for output data and adjust qmf filter states
752
 *
753
 * \return void
754
 *
755
 */
756
void qmfChangeOutScalefactor(
757
    HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */
758
    int outScalefactor             /*!< New scaling factor for output data */
759
657k
) {
760
657k
  if (synQmf == NULL) {
761
0
    return;
762
0
  }
763
764
  /* Add internal filterbank scale */
765
657k
  outScalefactor +=
766
657k
      (ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + synQmf->filterScale) +
767
657k
      synQmf->synScalefactor;
768
769
  /* adjust filter states when scale factor has been changed */
770
657k
  if (synQmf->outScalefactor != outScalefactor) {
771
92.2k
    int diff;
772
773
92.2k
    diff = synQmf->outScalefactor - outScalefactor;
774
775
92.2k
    qmfAdaptFilterStates(synQmf, diff);
776
777
    /* save new scale factor */
778
92.2k
    synQmf->outScalefactor = outScalefactor;
779
92.2k
  }
780
657k
}
781
782
/*!
783
 *
784
 * \brief Get scale factor change which was set by qmfChangeOutScalefactor()
785
 *
786
 * \return scaleFactor
787
 *
788
 */
789
int qmfGetOutScalefactor(
790
    HANDLE_QMF_FILTER_BANK synQmf) /*!< Handle of Qmf Synthesis Bank */
791
114k
{
792
114k
  int scaleFactor = synQmf->outScalefactor
793
114k
                        ? (synQmf->outScalefactor -
794
45.2k
                           (ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK +
795
45.2k
                            synQmf->filterScale + synQmf->synScalefactor))
796
114k
                        : 0;
797
114k
  return scaleFactor;
798
114k
}
799
800
/*!
801
 *
802
 * \brief Change gain for output data
803
 *
804
 * \return void
805
 *
806
 */
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
150k
) {
812
150k
  synQmf->outGain_m = outputGain;
813
150k
  synQmf->outGain_e = outputGainScale;
814
150k
}
815
816
0
#define INT_PCM_QMFOUT INT_PCM
817
0
#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
1.13G
#define INT_PCM_QMFOUT LONG
828
22.4M
#define SAMPLE_BITS_QMFOUT 32
829
42.5M
#define FIXP_QAS FIXP_DBL
830
#define QAS_BITS 32
831
#define INT_PCM_QMFIN LONG
832
#include "qmf_pcm.h"
833
#endif