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 /**************************** 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
124 struct 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 */
141 static 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
173 static const FIXP_DBL g48 =
174 FL2FXCONST_DBL(0.002712866530047) - (FIXP_DBL)0x8000;
175
176 static 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 */
186 static 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
204 static const FIXP_DBL g45 =
205 FL2FXCONST_DBL(0.00242743980909524) - (FIXP_DBL)0x8000;
206
207 static 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
219 static 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
232 static const FIXP_DBL g41 = FL2FXCONST_DBL(0.00155956951169248);
233
234 static 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 */
244 static 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
254 static const FIXP_DBL g35 = FL2FXCONST_DBL(0.00162580994125131);
255
256 static 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 */
264 static 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
274 static const FIXP_DBL g25 = FL2FXCONST_DBL(0.000945182835294559);
275
276 static const struct FILTER_PARAM param_set25 = {sos25, g25, 250, 4, 5};
277
278 /* Must be sorted in descending order */
279 static const struct FILTER_PARAM *const filter_paramSet[] = {
280 ¶m_set48, ¶m_set45, ¶m_set41, ¶m_set35, ¶m_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
FDKaacEnc_InitDownsampler(DOWNSAMPLER * DownSampler,int Wc,int ratio)292 INT 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
AdvanceFilter(LP_FILTER * downFilter,INT_PCM * pInput,int downRatio)341 static 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
FDKaacEnc_Downsample(DOWNSAMPLER * DownSampler,INT_PCM * inSamples,INT numInSamples,INT_PCM * outSamples,INT * numOutSamples)426 INT 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