1 /* ----------------------------------------------------------------------------- 2 Software License for The Fraunhofer FDK AAC Codec Library for Android 3 4 Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Frderung 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 (at) 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 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 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 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