1/* -----------------------------------------------------------------------------
2Software License for The Fraunhofer FDK AAC Codec Library for Android
3
4© Copyright  1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten
5Forschung e.V. All rights reserved.
6
7 1.    INTRODUCTION
8The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software
9that implements the MPEG Advanced Audio Coding ("AAC") encoding and decoding
10scheme for digital audio. This FDK AAC Codec software is intended to be used on
11a wide variety of Android devices.
12
13AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient
14general perceptual audio codecs. AAC-ELD is considered the best-performing
15full-bandwidth communications codec by independent studies and is widely
16deployed. AAC has been standardized by ISO and IEC as part of the MPEG
17specifications.
18
19Patent licenses for necessary patent claims for the FDK AAC Codec (including
20those of Fraunhofer) may be obtained through Via Licensing
21(www.vialicensing.com) or through the respective patent owners individually for
22the purpose of encoding or decoding bit streams in products that are compliant
23with the ISO/IEC MPEG audio standards. Please note that most manufacturers of
24Android devices already license these patent claims through Via Licensing or
25directly from the patent owners, and therefore FDK AAC Codec software may
26already be covered under those patent licenses when it is used for those
27licensed purposes only.
28
29Commercially-licensed AAC software libraries, including floating-point versions
30with enhanced sound quality, are also available from Fraunhofer. Users are
31encouraged to check the Fraunhofer website for additional applications
32information and documentation.
33
342.    COPYRIGHT LICENSE
35
36Redistribution and use in source and binary forms, with or without modification,
37are permitted without payment of copyright license fees provided that you
38satisfy the following conditions:
39
40You must retain the complete text of this software license in redistributions of
41the FDK AAC Codec or your modifications thereto in source code form.
42
43You must retain the complete text of this software license in the documentation
44and/or other materials provided with redistributions of the FDK AAC Codec or
45your modifications thereto in binary form. You must make available free of
46charge copies of the complete source code of the FDK AAC Codec and your
47modifications thereto to recipients of copies in binary form.
48
49The name of Fraunhofer may not be used to endorse or promote products derived
50from this library without prior written permission.
51
52You may not charge copyright license fees for anyone to use, copy or distribute
53the FDK AAC Codec software or your modifications thereto.
54
55Your modified versions of the FDK AAC Codec must carry prominent notices stating
56that you changed the software and the date of any change. For modified versions
57of the FDK AAC Codec, the term "Fraunhofer FDK AAC Codec Library for Android"
58must be replaced by the term "Third-Party Modified Version of the Fraunhofer FDK
59AAC Codec Library for Android."
60
613.    NO PATENT LICENSE
62
63NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without
64limitation the patents of Fraunhofer, ARE GRANTED BY THIS SOFTWARE LICENSE.
65Fraunhofer provides no warranty of patent non-infringement with respect to this
66software.
67
68You may use this FDK AAC Codec software or modifications thereto only for
69purposes that are authorized by appropriate patent licenses.
70
714.    DISCLAIMER
72
73This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright
74holders and contributors "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
75including but not limited to the implied warranties of merchantability and
76fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
77CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary,
78or consequential damages, including but not limited to procurement of substitute
79goods or services; loss of use, data, or profits, or business interruption,
80however caused and on any theory of liability, whether in contract, strict
81liability, or tort (including negligence), arising in any way out of the use of
82this software, even if advised of the possibility of such damage.
83
845.    CONTACT INFORMATION
85
86Fraunhofer Institute for Integrated Circuits IIS
87Attention: Audio and Multimedia Departments - FDK AAC LL
88Am Wolfsmantel 33
8991058 Erlangen, Germany
90
91www.iis.fraunhofer.de/amm
92amm-info@iis.fraunhofer.de
93----------------------------------------------------------------------------- */
94
95/**************************** SBR encoder library ******************************
96
97   Author(s):
98
99   Description:
100
101*******************************************************************************/
102
103/*!
104  \file
105  \brief  FDK resampler tool box:$Revision: 91655 $
106  \author M. Werner
107*/
108
109#include "resampler.h"
110
111#include "genericStds.h"
112
113/**************************************************************************/
114/*                   BIQUAD Filter Specifications                         */
115/**************************************************************************/
116
117#define B1 0
118#define B2 1
119#define A1 2
120#define A2 3
121
122#define BQC(x) FL2FXCONST_SGL(x / 2)
123
124struct FILTER_PARAM {
125  const FIXP_SGL *coeffa; /*! SOS matrix One row/section. Scaled using BQC().
126                             Order of coefficients: B1,B2,A1,A2. B0=A0=1.0 */
127  FIXP_DBL g;             /*! overall gain */
128  int Wc;       /*! normalized passband bandwidth at input samplerate * 1000 */
129  int noCoeffs; /*! number of filter coeffs */
130  int delay;    /*! delay in samples at input samplerate */
131};
132
133#define BIQUAD_COEFSTEP 4
134
135/**
136 *\brief Low Pass
137 Wc = 0,5, order 30, Stop Band -96dB. Wc criteria is "almost 0dB passband", not
138 the usual -3db gain point. [b,a]=cheby2(30,96,0.505) [sos,g]=tf2sos(b,a)
139 bandwidth 0.48
140 */
141static const FIXP_SGL sos48[] = {
142    BQC(1.98941075681938),      BQC(0.999999996890811),
143    BQC(0.863264527201963),     BQC(0.189553799960663),
144    BQC(1.90733804822445),      BQC(1.00000001736189),
145    BQC(0.836321575841691),     BQC(0.203505809266564),
146    BQC(1.75616665495325),      BQC(0.999999946079721),
147    BQC(0.784699225121588),     BQC(0.230471265506986),
148    BQC(1.55727745512726),      BQC(1.00000011737815),
149    BQC(0.712515423588351),     BQC(0.268752723900498),
150    BQC(1.33407591943643),      BQC(0.999999795953228),
151    BQC(0.625059117330989),     BQC(0.316194685288965),
152    BQC(1.10689898412458),      BQC(1.00000035057114),
153    BQC(0.52803514366398),      BQC(0.370517843224669),
154    BQC(0.89060371078454),      BQC(0.999999343962822),
155    BQC(0.426920462165257),     BQC(0.429608200207746),
156    BQC(0.694438261209433),     BQC(1.0000008629792),
157    BQC(0.326530699561716),     BQC(0.491714450654174),
158    BQC(0.523237800935322),     BQC(1.00000101349782),
159    BQC(0.230829556274851),     BQC(0.555559034843281),
160    BQC(0.378631165929563),     BQC(0.99998986482665),
161    BQC(0.142906422036095),     BQC(0.620338874442411),
162    BQC(0.260786911308437),     BQC(1.00003261460178),
163    BQC(0.0651008576256505),    BQC(0.685759923926262),
164    BQC(0.168409429188098),     BQC(0.999933049695828),
165    BQC(-0.000790067789975562), BQC(0.751905896602325),
166    BQC(0.100724533818628),     BQC(1.00009472669872),
167    BQC(-0.0533772830257041),   BQC(0.81930744384525),
168    BQC(0.0561434357867363),    BQC(0.999911636304276),
169    BQC(-0.0913550299236405),   BQC(0.88883625875915),
170    BQC(0.0341680678662057),    BQC(1.00003667508676),
171    BQC(-0.113405185536697),    BQC(0.961756638268446)};
172
173static const FIXP_DBL g48 =
174    FL2FXCONST_DBL(0.002712866530047) - (FIXP_DBL)0x8000;
175
176static const struct FILTER_PARAM param_set48 = {
177    sos48, g48, 480, 15, 4 /* LF 2 */
178};
179
180/**
181 *\brief Low Pass
182 Wc = 0,5, order 24, Stop Band -96dB. Wc criteria is "almost 0dB passband", not
183 the usual -3db gain point. [b,a]=cheby2(24,96,0.5) [sos,g]=tf2sos(b,a)
184 bandwidth 0.45
185 */
186static const FIXP_SGL sos45[] = {
187    BQC(1.982962601444),     BQC(1.00000000007504),    BQC(0.646113303737836),
188    BQC(0.10851149979981),   BQC(1.85334094281111),    BQC(0.999999999677192),
189    BQC(0.612073220102006),  BQC(0.130022141698044),   BQC(1.62541051415425),
190    BQC(1.00000000080398),   BQC(0.547879702855959),   BQC(0.171165825133192),
191    BQC(1.34554656923247),   BQC(0.9999999980169),     BQC(0.460373914508491),
192    BQC(0.228677463376354),  BQC(1.05656568503116),    BQC(1.00000000569363),
193    BQC(0.357891894038287),  BQC(0.298676843912185),   BQC(0.787967587877312),
194    BQC(0.999999984415017),  BQC(0.248826893211877),   BQC(0.377441803512978),
195    BQC(0.555480971120497),  BQC(1.00000003583307),    BQC(0.140614263345315),
196    BQC(0.461979302213679),  BQC(0.364986207070964),   BQC(0.999999932084303),
197    BQC(0.0392669446074516), BQC(0.55033451180825),    BQC(0.216827267631558),
198    BQC(1.00000010534682),   BQC(-0.0506232228865103), BQC(0.641691581560946),
199    BQC(0.108951672277119),  BQC(0.999999871167516),   BQC(-0.125584840183225),
200    BQC(0.736367748771803),  BQC(0.0387988607229035),  BQC(1.00000011205574),
201    BQC(-0.182814849097974), BQC(0.835802108714964),   BQC(0.0042866175809225),
202    BQC(0.999999954830813),  BQC(-0.21965740617151),   BQC(0.942623047782363)};
203
204static const FIXP_DBL g45 =
205    FL2FXCONST_DBL(0.00242743980909524) - (FIXP_DBL)0x8000;
206
207static const struct FILTER_PARAM param_set45 = {
208    sos45, g45, 450, 12, 4 /* LF 2 */
209};
210
211/*
212 Created by Octave 2.1.73, Mon Oct 13 17:31:32 2008 CEST
213 Wc = 0,5, order 16, Stop Band -96dB damping.
214 [b,a]=cheby2(16,96,0.5)
215 [sos,g]=tf2sos(b,a)
216 bandwidth = 0.41
217 */
218
219static const FIXP_SGL sos41[] = {
220    BQC(1.96193625292),      BQC(0.999999999999964),   BQC(0.169266178786789),
221    BQC(0.0128823300475907), BQC(1.68913437662092),    BQC(1.00000000000053),
222    BQC(0.124751503206552),  BQC(0.0537472273950989),  BQC(1.27274692366017),
223    BQC(0.999999999995674),  BQC(0.0433108625178357),  BQC(0.131015753236317),
224    BQC(0.85214175088395),   BQC(1.00000000001813),    BQC(-0.0625658152550408),
225    BQC(0.237763778993806),  BQC(0.503841579939009),   BQC(0.999999999953223),
226    BQC(-0.179176128722865), BQC(0.367475236424474),   BQC(0.249990711986162),
227    BQC(1.00000000007952),   BQC(-0.294425165824676),  BQC(0.516594857170212),
228    BQC(0.087971668680286),  BQC(0.999999999915528),   BQC(-0.398956566777928),
229    BQC(0.686417767801123),  BQC(0.00965373325350294), BQC(1.00000000003744),
230    BQC(-0.48579173764817),  BQC(0.884931534239068)};
231
232static const FIXP_DBL g41 = FL2FXCONST_DBL(0.00155956951169248);
233
234static const struct FILTER_PARAM param_set41 = {
235    sos41, g41, 410, 8, 5 /* LF 3 */
236};
237
238/*
239 # Created by Octave 2.1.73, Mon Oct 13 17:55:33 2008 CEST
240 Wc = 0,5, order 12, Stop Band -96dB damping.
241 [b,a]=cheby2(12,96,0.5);
242 [sos,g]=tf2sos(b,a)
243*/
244static const FIXP_SGL sos35[] = {
245    BQC(1.93299325235762),   BQC(0.999999999999985),  BQC(-0.140733187246596),
246    BQC(0.0124139497836062), BQC(1.4890416764109),    BQC(1.00000000000011),
247    BQC(-0.198215402588504), BQC(0.0746730616584138), BQC(0.918450161309795),
248    BQC(0.999999999999619),  BQC(-0.30133912791941),  BQC(0.192276468839529),
249    BQC(0.454877024246818),  BQC(1.00000000000086),   BQC(-0.432337328809815),
250    BQC(0.356852933642815),  BQC(0.158017147118507),  BQC(0.999999999998876),
251    BQC(-0.574817494249777), BQC(0.566380436970833),  BQC(0.0171834649478749),
252    BQC(1.00000000000055),   BQC(-0.718581178041165), BQC(0.83367484487889)};
253
254static const FIXP_DBL g35 = FL2FXCONST_DBL(0.00162580994125131);
255
256static const struct FILTER_PARAM param_set35 = {sos35, g35, 350, 6, 4};
257
258/*
259 # Created by Octave 2.1.73, Mon Oct 13 18:15:38 2008 CEST
260 Wc = 0,5, order 8, Stop Band -96dB damping.
261 [b,a]=cheby2(8,96,0.5);
262 [sos,g]=tf2sos(b,a)
263*/
264static const FIXP_SGL sos25[] = {
265    BQC(1.85334094301225),   BQC(1.0),
266    BQC(-0.702127214212663), BQC(0.132452403998767),
267    BQC(1.056565682167),     BQC(0.999999999999997),
268    BQC(-0.789503667880785), BQC(0.236328693569128),
269    BQC(0.364986307455489),  BQC(0.999999999999996),
270    BQC(-0.955191189843375), BQC(0.442966457936379),
271    BQC(0.0387985751642125), BQC(1.0),
272    BQC(-1.19817786088084),  BQC(0.770493895456328)};
273
274static const FIXP_DBL g25 = FL2FXCONST_DBL(0.000945182835294559);
275
276static const struct FILTER_PARAM param_set25 = {sos25, g25, 250, 4, 5};
277
278/* Must be sorted in descending order */
279static const struct FILTER_PARAM *const filter_paramSet[] = {
280    &param_set48, &param_set45, &param_set41, &param_set35, &param_set25};
281
282/**************************************************************************/
283/*                         Resampler Functions                            */
284/**************************************************************************/
285
286/*!
287  \brief   Reset downsampler instance and clear delay lines
288
289  \return  success of operation
290*/
291
292INT FDKaacEnc_InitDownsampler(
293    DOWNSAMPLER *DownSampler, /*!< pointer to downsampler instance */
294    int Wc,                   /*!< normalized cutoff freq * 1000*  */
295    int ratio)                /*!< downsampler ratio */
296
297{
298  UINT i;
299  const struct FILTER_PARAM *currentSet = NULL;
300
301  FDKmemclear(DownSampler->downFilter.states,
302              sizeof(DownSampler->downFilter.states));
303  DownSampler->downFilter.ptr = 0;
304
305  /*
306    find applicable parameter set
307  */
308  currentSet = filter_paramSet[0];
309  for (i = 1; i < sizeof(filter_paramSet) / sizeof(struct FILTER_PARAM *);
310       i++) {
311    if (filter_paramSet[i]->Wc <= Wc) {
312      break;
313    }
314    currentSet = filter_paramSet[i];
315  }
316
317  DownSampler->downFilter.coeffa = currentSet->coeffa;
318
319  DownSampler->downFilter.gain = currentSet->g;
320  FDK_ASSERT(currentSet->noCoeffs <= MAXNR_SECTIONS * 2);
321
322  DownSampler->downFilter.noCoeffs = currentSet->noCoeffs;
323  DownSampler->delay = currentSet->delay;
324  DownSampler->downFilter.Wc = currentSet->Wc;
325
326  DownSampler->ratio = ratio;
327  DownSampler->pending = ratio - 1;
328  return (1);
329}
330
331/*!
332  \brief   faster simple folding operation
333           Filter:
334           H(z) = A(z)/B(z)
335           with
336           A(z) = a[0]*z^0 + a[1]*z^1 + a[2]*z^2 ... a[n]*z^n
337
338  \return  filtered value
339*/
340
341static inline INT_PCM AdvanceFilter(
342    LP_FILTER *downFilter, /*!< pointer to iir filter instance */
343    INT_PCM *pInput,       /*!< input of filter                */
344    int downRatio) {
345  INT_PCM output;
346  int i, n;
347
348#define BIQUAD_SCALE 12
349
350  FIXP_DBL y = FL2FXCONST_DBL(0.0f);
351  FIXP_DBL input;
352
353  for (n = 0; n < downRatio; n++) {
354    FIXP_BQS(*states)[2] = downFilter->states;
355    const FIXP_SGL *coeff = downFilter->coeffa;
356    int s1, s2;
357
358    s1 = downFilter->ptr;
359    s2 = s1 ^ 1;
360
361#if (SAMPLE_BITS == 16)
362    input = ((FIXP_DBL)pInput[n]) << (DFRACT_BITS - SAMPLE_BITS - BIQUAD_SCALE);
363#elif (SAMPLE_BITS == 32)
364    input = pInput[n] >> BIQUAD_SCALE;
365#else
366#error NOT IMPLEMENTED
367#endif
368
369    FIXP_BQS state1, state2, state1b, state2b;
370
371    state1 = states[0][s1];
372    state2 = states[0][s2];
373
374    /* Loop over sections */
375    for (i = 0; i < downFilter->noCoeffs; i++) {
376      FIXP_DBL state0;
377
378      /* Load merged states (from next section) */
379      state1b = states[i + 1][s1];
380      state2b = states[i + 1][s2];
381
382      state0 = input + fMult(state1, coeff[B1]) + fMult(state2, coeff[B2]);
383      y = state0 - fMult(state1b, coeff[A1]) - fMult(state2b, coeff[A2]);
384
385      /* Store new feed forward merge state */
386      states[i + 1][s2] = y << 1;
387      /* Store new feed backward state */
388      states[i][s2] = input << 1;
389
390      /* Feedback output to next section. */
391      input = y;
392
393      /* Transfer merged states */
394      state1 = state1b;
395      state2 = state2b;
396
397      /* Step to next coef set */
398      coeff += BIQUAD_COEFSTEP;
399    }
400    downFilter->ptr ^= 1;
401  }
402  /* Apply global gain */
403  y = fMult(y, downFilter->gain);
404
405  /* Apply final gain/scaling to output */
406#if (SAMPLE_BITS == 16)
407  output = (INT_PCM)SATURATE_RIGHT_SHIFT(
408      y + (FIXP_DBL)(1 << (DFRACT_BITS - SAMPLE_BITS - BIQUAD_SCALE - 1)),
409      DFRACT_BITS - SAMPLE_BITS - BIQUAD_SCALE, SAMPLE_BITS);
410  // output = (INT_PCM) SATURATE_RIGHT_SHIFT(y,
411  // DFRACT_BITS-SAMPLE_BITS-BIQUAD_SCALE, SAMPLE_BITS);
412#else
413  output = SATURATE_LEFT_SHIFT(y, BIQUAD_SCALE, SAMPLE_BITS);
414#endif
415
416  return output;
417}
418
419/*!
420  \brief   FDKaacEnc_Downsample numInSamples of type INT_PCM
421           Returns number of output samples in numOutSamples
422
423  \return  success of operation
424*/
425
426INT FDKaacEnc_Downsample(
427    DOWNSAMPLER *DownSampler, /*!< pointer to downsampler instance */
428    INT_PCM *inSamples,       /*!< pointer to input samples */
429    INT numInSamples,         /*!< number  of input samples  */
430    INT_PCM *outSamples,      /*!< pointer to output samples */
431    INT *numOutSamples        /*!< pointer tp number of output samples */
432) {
433  INT i;
434  *numOutSamples = 0;
435
436  for (i = 0; i < numInSamples; i += DownSampler->ratio) {
437    *outSamples = AdvanceFilter(&(DownSampler->downFilter), &inSamples[i],
438                                DownSampler->ratio);
439    outSamples++;
440  }
441  *numOutSamples = numInSamples / DownSampler->ratio;
442
443  return 0;
444}
445