1 2 /* ----------------------------------------------------------------------------------------------------------- 3 Software License for The Fraunhofer FDK AAC Codec Library for Android 4 5 Copyright 1995 - 2012 Fraunhofer-Gesellschaft zur Frderung der angewandten Forschung e.V. 6 All rights reserved. 7 8 1. INTRODUCTION 9 The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements 10 the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. 11 This FDK AAC Codec software is intended to be used on a wide variety of Android devices. 12 13 AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual 14 audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by 15 independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part 16 of the MPEG specifications. 17 18 Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) 19 may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners 20 individually for the purpose of encoding or decoding bit streams in products that are compliant with 21 the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license 22 these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec 23 software may already be covered under those patent licenses when it is used for those licensed purposes only. 24 25 Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, 26 are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional 27 applications information and documentation. 28 29 2. COPYRIGHT LICENSE 30 31 Redistribution and use in source and binary forms, with or without modification, are permitted without 32 payment of copyright license fees provided that you satisfy the following conditions: 33 34 You must retain the complete text of this software license in redistributions of the FDK AAC Codec or 35 your modifications thereto in source code form. 36 37 You must retain the complete text of this software license in the documentation and/or other materials 38 provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. 39 You must make available free of charge copies of the complete source code of the FDK AAC Codec and your 40 modifications thereto to recipients of copies in binary form. 41 42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without 43 prior written permission. 44 45 You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec 46 software or your modifications thereto. 47 48 Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software 49 and the date of any change. For modified versions of the FDK AAC Codec, the term 50 "Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term 51 "Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." 52 53 3. NO PATENT LICENSE 54 55 NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, 56 ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with 57 respect to this software. 58 59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized 60 by appropriate patent licenses. 61 62 4. DISCLAIMER 63 64 This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors 65 "AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties 66 of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 67 CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, 68 including but not limited to procurement of substitute goods or services; loss of use, data, or profits, 69 or business interruption, however caused and on any theory of liability, whether in contract, strict 70 liability, or tort (including negligence), arising in any way out of the use of this software, even if 71 advised of the possibility of such damage. 72 73 5. CONTACT INFORMATION 74 75 Fraunhofer Institute for Integrated Circuits IIS 76 Attention: Audio and Multimedia Departments - FDK AAC LL 77 Am Wolfsmantel 33 78 91058 Erlangen, Germany 79 80 www.iis.fraunhofer.de/amm 81 amm-info (at) iis.fraunhofer.de 82 ----------------------------------------------------------------------------------------------------------- */ 83 84 #include "psdec_hybrid.h" 85 86 87 #include "fft.h" 88 #include "sbr_ram.h" 89 90 #include "FDK_tools_rom.h" 91 #include "sbr_rom.h" 92 93 /******************************************************************************* 94 Functionname: InitHybridFilterBank 95 ******************************************************************************* 96 97 Description: Init one instance of HANDLE_HYBRID stuct 98 99 Arguments: 100 101 Return: none 102 103 *******************************************************************************/ 104 105 106 SBR_ERROR 107 InitHybridFilterBank ( HANDLE_HYBRID hs, /*!< Handle to HYBRID struct. */ 108 SCHAR frameSize, /*!< Framesize (in Qmf sbband samples). */ 109 SCHAR noBands, /*!< Number of Qmf bands for hybrid filtering. */ 110 const UCHAR *pResolution ) /*!< Resolution in Qmf bands (length noBands). */ 111 { 112 SCHAR i; 113 UCHAR maxNoChannels = 0; 114 115 for (i = 0; i < noBands; i++) { 116 hs->pResolution[i] = pResolution[i]; 117 if(pResolution[i] > maxNoChannels) 118 maxNoChannels = pResolution[i]; 119 } 120 121 hs->nQmfBands = noBands; 122 hs->frameSize = frameSize; 123 hs->qmfBufferMove = HYBRID_FILTER_LENGTH - 1; 124 125 hs->sf_mQmfBuffer = 0; 126 127 return SBRDEC_OK; 128 } 129 130 /******************************************************************************* 131 Functionname: dualChannelFiltering 132 ******************************************************************************* 133 134 Description: fast 2-channel real-valued filtering with 6-tap delay. 135 136 Arguments: 137 138 Return: none 139 140 *******************************************************************************/ 141 142 /*! 143 2 channel filter 144 <pre> 145 Filter Coefs: 146 0.0, 147 0.01899487526049, 148 0.0, 149 -0.07293139167538, 150 0.0, 151 0.30596630545168, 152 0.5, 153 0.30596630545168, 154 0.0, 155 -0.07293139167538, 156 0.0, 157 0.01899487526049, 158 0.0 159 160 161 Filter design: 162 h[q,n] = g[n] * cos(2pi/2 * q * (n-6) ); n = 0..12, q = 0,1; 163 164 -> h[0,n] = g[n] * 1; 165 -> h[1,n] = g[n] * pow(-1,n); 166 </pre> 167 */ 168 169 static void slotBasedDualChannelFiltering( const FIXP_DBL *pQmfReal, 170 const FIXP_DBL *pQmfImag, 171 172 FIXP_DBL *mHybridReal, 173 FIXP_DBL *mHybridImag) 174 { 175 176 FIXP_DBL t1, t3, t5, t6; 177 178 /* symmetric filter coefficients */ 179 180 /* you don't have to shift the result after fMult because of p2_13_20 <= 0.5 */ 181 t1 = fMultDiv2(p2_13_20[1] , ( (pQmfReal[1] >> 1) + (pQmfReal[11] >> 1))); 182 t3 = fMultDiv2(p2_13_20[3] , ( (pQmfReal[3] >> 1) + (pQmfReal[ 9] >> 1))); 183 t5 = fMultDiv2(p2_13_20[5] , ( (pQmfReal[5] >> 1) + (pQmfReal[ 7] >> 1))); 184 t6 = fMultDiv2(p2_13_20[6] , (pQmfReal[6] >> 1) ); 185 186 mHybridReal[0] = (t1 + t3 + t5 + t6) << 2; 187 mHybridReal[1] = (- t1 - t3 - t5 + t6) << 2; 188 189 t1 = fMultDiv2(p2_13_20[1] , ( (pQmfImag[1] >> 1) + (pQmfImag[11] >> 1))); 190 t3 = fMultDiv2(p2_13_20[3] , ( (pQmfImag[3] >> 1) + (pQmfImag[ 9] >> 1))); 191 t5 = fMultDiv2(p2_13_20[5] , ( (pQmfImag[5] >> 1) + (pQmfImag[ 7] >> 1))); 192 t6 = fMultDiv2(p2_13_20[6] , pQmfImag[6] >> 1 ); 193 194 mHybridImag[0] = (t1 + t3 + t5 + t6) << 2; 195 mHybridImag[1] = (- t1 - t3 - t5 + t6) << 2; 196 } 197 198 199 /******************************************************************************* 200 Functionname: eightChannelFiltering 201 ******************************************************************************* 202 203 Description: fast 8-channel complex-valued filtering with 6-tap delay. 204 205 Arguments: 206 207 Return: none 208 209 *******************************************************************************/ 210 /*! 211 8 channel filter 212 213 Implementation using a FFT of length 8 214 <pre> 215 prototype filter coefficients: 216 0.00746082949812 0.02270420949825 0.04546865930473 0.07266113929591 0.09885108575264 0.11793710567217 217 0.125 218 0.11793710567217 0.09885108575264 0.07266113929591 0.04546865930473 0.02270420949825 0.00746082949812 219 220 Filter design: 221 N = 13; Q = 8; 222 h[q,n] = g[n] * exp(j * 2 * pi / Q * (q + .5) * (n - 6)); n = 0..(N-1), q = 0..(Q-1); 223 224 Time Signal: x[t]; 225 Filter Bank Output 226 y[q,t] = conv(x[t],h[q,t]) = conv(h[q,t],x[t]) = sum(x[k] * h[q, t - k] ) = sum(h[q, k] * x[t - k] ); k = 0..(N-1); 227 228 y[q,t] = x[t - 12]*h[q, 12] + x[t - 11]*h[q, 11] + x[t - 10]*h[q, 10] + x[t - 9]*h[q, 9] 229 + x[t - 8]*h[q, 8] + x[t - 7]*h[q, 7] 230 + x[t - 6]*h[q, 6] 231 + x[t - 5]*h[q, 5] + x[t - 4]*h[q, 4] 232 + x[t - 3]*h[q, 3] + x[t - 2]*h[q, 2] + x[t - 1]*h[q, 1] + x[t - 0]*h[q, 0]; 233 234 h'[q, n] = h[q,(N-1)-n] = g[n] * exp(j * 2 * pi / Q * (q + .5) * (6 - n)); n = 0..(N-1), q = 0..(Q-1); 235 236 y[q,t] = x[t - 12]*h'[q, 0] + x[t - 11]*h'[q, 1] + x[t - 10]*h'[q, 2] + x[t - 9]*h'[q, 3] 237 + x[t - 8]*h'[q, 4] + x[t - 7]*h'[q, 5] 238 + x[t - 6]*h'[q, 6] 239 + x[t - 5]*h'[q, 7] + x[t - 4]*h'[q, 8] 240 + x[t - 3]*h'[q, 9] + x[t - 2]*h'[q, 10] + x[t - 1]*h'[q, 11] + x[t - 0]*h'[q, 12]; 241 242 Try to split off FFT Modulation Term: 243 FFT(x[t], q) = sum(x[t+k]*exp(-j*2*pi/N *q * k)) 244 c m 245 Step 1: h'[q,n] = g[n] * ( exp(j * 2 * pi / 8 * .5 * (6 - n)) ) * ( exp (j * 2 * pi / 8 * q * (6 - n)) ); 246 247 h'[q,n] = g[n] *c[n] * m[q,n]; (see above) 248 c[n] = exp( j * 2 * pi / 8 * .5 * (6 - n) ); 249 m[q,n] = exp( j * 2 * pi / 8 * q * (6 - n) ); 250 251 y[q,t] = x[t - 0]*g[0]*c[0]*m[q,0] + x[t - 1]*g[1]*c[ 1]*m[q, 1] + ... 252 ... + x[t - 12]*g[2]*c[12]*m[q,12]; 253 254 | 255 n m *exp(-j*2*pi) | n' fft 256 ------------------------------------------------------------------------------------------------------------------------- 257 0 exp( j * 2 * pi / 8 * q * 6) -> exp(-j * 2 * pi / 8 * q * 2) | 2 exp(-j * 2 * pi / 8 * q * 0) 258 1 exp( j * 2 * pi / 8 * q * 5) -> exp(-j * 2 * pi / 8 * q * 3) | 3 exp(-j * 2 * pi / 8 * q * 1) 259 2 exp( j * 2 * pi / 8 * q * 4) -> exp(-j * 2 * pi / 8 * q * 4) | 4 exp(-j * 2 * pi / 8 * q * 2) 260 3 exp( j * 2 * pi / 8 * q * 3) -> exp(-j * 2 * pi / 8 * q * 5) | 5 exp(-j * 2 * pi / 8 * q * 3) 261 4 exp( j * 2 * pi / 8 * q * 2) -> exp(-j * 2 * pi / 8 * q * 6) | 6 exp(-j * 2 * pi / 8 * q * 4) 262 5 exp( j * 2 * pi / 8 * q * 1) -> exp(-j * 2 * pi / 8 * q * 7) | 7 exp(-j * 2 * pi / 8 * q * 5) 263 6 exp( j * 2 * pi / 8 * q * 0) | 0 exp(-j * 2 * pi / 8 * q * 6) 264 7 exp(-j * 2 * pi / 8 * q * 1) | 1 exp(-j * 2 * pi / 8 * q * 7) 265 8 exp(-j * 2 * pi / 8 * q * 2) | 2 266 9 exp(-j * 2 * pi / 8 * q * 3) | 3 267 10 exp(-j * 2 * pi / 8 * q * 4) | 4 268 11 exp(-j * 2 * pi / 8 * q * 5) | 5 269 12 exp(-j * 2 * pi / 8 * q * 6) | 6 270 271 272 now use fft modulation coefficients 273 m[6] = = fft[0] 274 m[7] = = fft[1] 275 m[8] = m[ 0] = fft[2] 276 m[9] = m[ 1] = fft[3] 277 m[10] = m[ 2] = fft[4] 278 m[11] = m[ 3] = fft[5] 279 m[12] = m[ 4] = fft[6] 280 m[ 5] = fft[7] 281 282 y[q,t] = ( x[t- 6]*g[ 6]*c[ 6] ) * fft[q,0] + 283 ( x[t- 7]*g[ 7]*c[ 7] ) * fft[q,1] + 284 ( x[t- 0]*g[ 0]*c[ 0] + x[t- 8]*g[ 8]*c[ 8] ) * fft[q,2] + 285 ( x[t- 1]*g[ 1]*c[ 1] + x[t- 9]*g[ 9]*c[ 9] ) * fft[q,3] + 286 ( x[t- 2]*g[ 2]*c[ 2] + x[t-10]*g[10]*c[10] ) * fft[q,4] + 287 ( x[t- 3]*g[ 3]*c[ 3] + x[t-11]*g[11]*c[11] ) * fft[q,5] + 288 ( x[t- 4]*g[ 4]*c[ 4] + x[t-12]*g[12]*c[12] ) * fft[q,6] + 289 ( x[t- 5]*g[ 5]*c[ 5] ) * fft[q,7]; 290 291 pre twiddle factors c[n] = exp(j * 2 * pi / 8 * .5 * (6 - n)); 292 n c] | n c[n] | n c[n] 293 --------------------------------------------------------------------------------------------------- 294 0 exp( j * 6 * pi / 8) | 1 exp( j * 5 * pi / 8) | 2 exp( j * 4 * pi / 8) 295 3 exp( j * 3 * pi / 8) | 4 exp( j * 2 * pi / 8) | 5 exp( j * 1 * pi / 8) 296 6 exp( j * 0 * pi / 8) | 7 exp(-j * 1 * pi / 8) | 8 exp(-j * 2 * pi / 8) 297 9 exp(-j * 3 * pi / 8) | 10 exp(-j * 4 * pi / 8) | 11 exp(-j * 5 * pi / 8) 298 12 exp(-j * 6 * pi / 8) | | 299 </pre> 300 */ 301 302 /* defining rotation factors for *ChannelFiltering */ 303 304 #define cos0Pi FL2FXCONST_DBL( 1.f) 305 #define sin0Pi FL2FXCONST_DBL( 0.f) 306 307 #define cos1Pi FL2FXCONST_DBL(-1.f) 308 #define sin1Pi FL2FXCONST_DBL( 0.f) 309 310 #define cos1Pi_2 FL2FXCONST_DBL( 0.f) 311 #define sin1Pi_2 FL2FXCONST_DBL( 1.f) 312 313 #define cos1Pi_3 FL2FXCONST_DBL( 0.5f) 314 #define sin1Pi_3 FL2FXCONST_DBL( 0.86602540378444f) 315 316 #define cos0Pi_4 cos0Pi 317 #define cos1Pi_4 FL2FXCONST_DBL(0.70710678118655f) 318 #define cos2Pi_4 cos1Pi_2 319 #define cos3Pi_4 (-cos1Pi_4) 320 #define cos4Pi_4 (-cos0Pi_4) 321 #define cos5Pi_4 cos3Pi_4 322 #define cos6Pi_4 cos2Pi_4 323 324 #define sin0Pi_4 sin0Pi 325 #define sin1Pi_4 FL2FXCONST_DBL(0.70710678118655f) 326 #define sin2Pi_4 sin1Pi_2 327 #define sin3Pi_4 sin1Pi_4 328 #define sin4Pi_4 sin0Pi_4 329 #define sin5Pi_4 (-sin3Pi_4) 330 #define sin6Pi_4 (-sin2Pi_4) 331 332 #define cos0Pi_8 cos0Pi 333 #define cos1Pi_8 FL2FXCONST_DBL(0.92387953251129f) 334 #define cos2Pi_8 cos1Pi_4 335 #define cos3Pi_8 FL2FXCONST_DBL(0.38268343236509f) 336 #define cos4Pi_8 cos2Pi_4 337 #define cos5Pi_8 (-cos3Pi_8) 338 #define cos6Pi_8 (-cos2Pi_8) 339 340 #define sin0Pi_8 sin0Pi 341 #define sin1Pi_8 cos3Pi_8 342 #define sin2Pi_8 sin1Pi_4 343 #define sin3Pi_8 cos1Pi_8 344 #define sin4Pi_8 sin2Pi_4 345 #define sin5Pi_8 sin3Pi_8 346 #define sin6Pi_8 sin1Pi_4 347 348 #if defined(ARCH_PREFER_MULT_32x16) 349 #define FIXP_HYB FIXP_SGL 350 #define FIXP_CAST FX_DBL2FX_SGL 351 #else 352 #define FIXP_HYB FIXP_DBL 353 #define FIXP_CAST 354 #endif 355 356 static const FIXP_HYB cr[13] = 357 { 358 FIXP_CAST(cos6Pi_8), FIXP_CAST(cos5Pi_8), FIXP_CAST(cos4Pi_8), 359 FIXP_CAST(cos3Pi_8), FIXP_CAST(cos2Pi_8), FIXP_CAST(cos1Pi_8), 360 FIXP_CAST(cos0Pi_8), 361 FIXP_CAST(cos1Pi_8), FIXP_CAST(cos2Pi_8), FIXP_CAST(cos3Pi_8), 362 FIXP_CAST(cos4Pi_8), FIXP_CAST(cos5Pi_8), FIXP_CAST(cos6Pi_8) 363 }; 364 365 static const FIXP_HYB ci[13] = 366 { 367 FIXP_CAST( sin6Pi_8), FIXP_CAST( sin5Pi_8), FIXP_CAST( sin4Pi_8), 368 FIXP_CAST( sin3Pi_8), FIXP_CAST( sin2Pi_8), FIXP_CAST( sin1Pi_8), 369 FIXP_CAST( sin0Pi_8) , 370 FIXP_CAST(-sin1Pi_8), FIXP_CAST(-sin2Pi_8), FIXP_CAST(-sin3Pi_8), 371 FIXP_CAST(-sin4Pi_8), FIXP_CAST(-sin5Pi_8), FIXP_CAST(-sin6Pi_8) 372 }; 373 374 static void slotBasedEightChannelFiltering( const FIXP_DBL *pQmfReal, 375 const FIXP_DBL *pQmfImag, 376 377 FIXP_DBL *mHybridReal, 378 FIXP_DBL *mHybridImag) 379 { 380 381 int bin; 382 FIXP_DBL _fft[128 + ALIGNMENT_DEFAULT - 1]; 383 FIXP_DBL *fft = (FIXP_DBL *)ALIGN_PTR(_fft); 384 385 #if defined(ARCH_PREFER_MULT_32x16) 386 const FIXP_SGL *p = p8_13_20; /* BASELINE_PS */ 387 #else 388 const FIXP_DBL *p = p8_13_20; /* BASELINE_PS */ 389 #endif 390 391 /* pre twiddeling */ 392 393 /* x*(a*b + c*d) = fMultDiv2(x, fMultAddDiv2(fMultDiv2(a, b), c, d)) */ 394 /* x*(a*b - c*d) = fMultDiv2(x, fMultSubDiv2(fMultDiv2(a, b), c, d)) */ 395 FIXP_DBL accu1, accu2, accu3, accu4; 396 397 #define TWIDDLE_1(n_0,n_1,n_2) \ 398 cplxMultDiv2(&accu1, &accu2, pQmfReal[n_0], pQmfImag[n_0], cr[n_0], ci[n_0]); \ 399 accu1 = fMultDiv2(p[n_0], accu1); \ 400 accu2 = fMultDiv2(p[n_0], accu2); \ 401 cplxMultDiv2(&accu3, &accu4, pQmfReal[n_1], pQmfImag[n_1], cr[n_1], ci[n_1]); \ 402 accu3 = fMultDiv2(p[n_1], accu3); \ 403 accu4 = fMultDiv2(p[n_1], accu4); \ 404 fft[FIXP_FFT_IDX_R(n_2)] = accu1 + accu3; \ 405 fft[FIXP_FFT_IDX_I(n_2)] = accu2 + accu4; 406 407 #define TWIDDLE_0(n_0,n_1) \ 408 cplxMultDiv2(&accu1, &accu2, pQmfReal[n_0], pQmfImag[n_0], cr[n_0], ci[n_0]); \ 409 fft[FIXP_FFT_IDX_R(n_1)] = fMultDiv2(p[n_0], accu1); \ 410 fft[FIXP_FFT_IDX_I(n_1)] = fMultDiv2(p[n_0], accu2); 411 412 TWIDDLE_0( 6, 0) 413 TWIDDLE_0( 7, 1) 414 415 TWIDDLE_1( 0, 8, 2) 416 TWIDDLE_1( 1, 9, 3) 417 TWIDDLE_1( 2,10, 4) 418 TWIDDLE_1( 3,11, 5) 419 TWIDDLE_1( 4,12, 6) 420 421 TWIDDLE_0( 5, 7) 422 423 fft_8 (fft); 424 425 /* resort fft data into output array*/ 426 for(bin=0; bin<8;bin++ ) { 427 mHybridReal[bin] = fft[FIXP_FFT_IDX_R(bin)] << 4; 428 mHybridImag[bin] = fft[FIXP_FFT_IDX_I(bin)] << 4; 429 } 430 } 431 432 433 /******************************************************************************* 434 Functionname: fillHybridDelayLine 435 ******************************************************************************* 436 437 Description: The delay line of the hybrid filter is filled and copied from 438 left to right. 439 440 Return: none 441 442 *******************************************************************************/ 443 444 void 445 fillHybridDelayLine( FIXP_DBL **fixpQmfReal, /*!< Qmf real Values */ 446 FIXP_DBL **fixpQmfImag, /*!< Qmf imag Values */ 447 FIXP_DBL fixpHybridLeftR[12], /*!< Hybrid real Values left channel */ 448 FIXP_DBL fixpHybridLeftI[12], /*!< Hybrid imag Values left channel */ 449 FIXP_DBL fixpHybridRightR[12], /*!< Hybrid real Values right channel */ 450 FIXP_DBL fixpHybridRightI[12], /*!< Hybrid imag Values right channel */ 451 HANDLE_HYBRID hHybrid ) 452 { 453 int i; 454 455 for (i = 0; i < HYBRID_FILTER_DELAY; i++) { 456 slotBasedHybridAnalysis ( fixpQmfReal[i], 457 fixpQmfReal[i], 458 fixpHybridLeftR, 459 fixpHybridLeftI, 460 hHybrid ); 461 } 462 463 FDKmemcpy(fixpHybridRightR, fixpHybridLeftR, sizeof(FIXP_DBL)*NO_SUB_QMF_CHANNELS); 464 FDKmemcpy(fixpHybridRightI, fixpHybridLeftI, sizeof(FIXP_DBL)*NO_SUB_QMF_CHANNELS); 465 } 466 467 468 /******************************************************************************* 469 Functionname: slotBasedHybridAnalysis 470 ******************************************************************************* 471 472 Description: The lower QMF subbands are further split to provide better 473 frequency resolution for PS processing. 474 475 Return: none 476 477 *******************************************************************************/ 478 479 480 void 481 slotBasedHybridAnalysis ( FIXP_DBL *fixpQmfReal, /*!< Qmf real Values */ 482 FIXP_DBL *fixpQmfImag, /*!< Qmf imag Values */ 483 484 FIXP_DBL fixpHybridReal[12], /*!< Hybrid real Values */ 485 FIXP_DBL fixpHybridImag[12], /*!< Hybrid imag Values */ 486 487 HANDLE_HYBRID hHybrid) 488 { 489 int k, band; 490 HYBRID_RES hybridRes; 491 int chOffset = 0; 492 493 C_ALLOC_SCRATCH_START(pTempRealSlot, FIXP_DBL, 4*HYBRID_FILTER_LENGTH); 494 495 FIXP_DBL *pTempImagSlot = pTempRealSlot + HYBRID_FILTER_LENGTH; 496 FIXP_DBL *pWorkRealSlot = pTempImagSlot + HYBRID_FILTER_LENGTH; 497 FIXP_DBL *pWorkImagSlot = pWorkRealSlot + HYBRID_FILTER_LENGTH; 498 499 /*! 500 Hybrid filtering is applied to the first hHybrid->nQmfBands QMF bands (3 when 10 or 20 stereo bands 501 are used, 5 when 34 stereo bands are used). For the remaining QMF bands a delay would be necessary. 502 But there is no need to implement a delay because there is a look-ahead of HYBRID_FILTER_DELAY = 6 503 QMF samples in the low-band buffer. 504 */ 505 506 for(band = 0; band < hHybrid->nQmfBands; band++) { 507 508 /* get hybrid resolution per qmf band */ 509 /* in case of baseline ps 10/20 band stereo mode : */ 510 /* */ 511 /* qmfBand[0] : 8 ( HYBRID_8_CPLX ) */ 512 /* qmfBand[1] : 2 ( HYBRID_2_REAL ) */ 513 /* qmfBand[2] : 2 ( HYBRID_2_REAL ) */ 514 /* */ 515 /* (split the 3 lower qmf band to 12 hybrid bands) */ 516 517 hybridRes = (HYBRID_RES)hHybrid->pResolution[band]; 518 519 FDKmemcpy(pWorkRealSlot, hHybrid->mQmfBufferRealSlot[band], hHybrid->qmfBufferMove * sizeof(FIXP_DBL)); 520 FDKmemcpy(pWorkImagSlot, hHybrid->mQmfBufferImagSlot[band], hHybrid->qmfBufferMove * sizeof(FIXP_DBL)); 521 522 pWorkRealSlot[hHybrid->qmfBufferMove] = fixpQmfReal[band]; 523 pWorkImagSlot[hHybrid->qmfBufferMove] = fixpQmfImag[band]; 524 525 FDKmemcpy(hHybrid->mQmfBufferRealSlot[band], pWorkRealSlot + 1, hHybrid->qmfBufferMove * sizeof(FIXP_DBL)); 526 FDKmemcpy(hHybrid->mQmfBufferImagSlot[band], pWorkImagSlot + 1, hHybrid->qmfBufferMove * sizeof(FIXP_DBL)); 527 528 if (fixpQmfReal) { 529 530 /* actual filtering only if output signal requested */ 531 switch( hybridRes ) { 532 533 /* HYBRID_2_REAL & HYBRID_8_CPLX are only needful for baseline ps */ 534 case HYBRID_2_REAL: 535 536 slotBasedDualChannelFiltering( pWorkRealSlot, 537 pWorkImagSlot, 538 pTempRealSlot, 539 pTempImagSlot); 540 break; 541 542 case HYBRID_8_CPLX: 543 544 slotBasedEightChannelFiltering( pWorkRealSlot, 545 pWorkImagSlot, 546 pTempRealSlot, 547 pTempImagSlot); 548 break; 549 550 default: 551 FDK_ASSERT(0); 552 } 553 554 for(k = 0; k < (SCHAR)hybridRes; k++) { 555 fixpHybridReal [chOffset + k] = pTempRealSlot[k]; 556 fixpHybridImag [chOffset + k] = pTempImagSlot[k]; 557 } 558 chOffset += hybridRes; 559 } /* if (mHybridReal) */ 560 } 561 562 /* group hybrid channels 3+4 -> 3 and 2+5 -> 2 */ 563 fixpHybridReal[3] += fixpHybridReal[4]; 564 fixpHybridImag[3] += fixpHybridImag[4]; 565 fixpHybridReal[4] = (FIXP_DBL)0; 566 fixpHybridImag[4] = (FIXP_DBL)0; 567 568 fixpHybridReal[2] += fixpHybridReal[5]; 569 fixpHybridImag[2] += fixpHybridImag[5]; 570 fixpHybridReal[5] = (FIXP_DBL)0; 571 fixpHybridImag[5] = (FIXP_DBL)0; 572 573 /* free memory on scratch */ 574 C_ALLOC_SCRATCH_END(pTempRealSlot, FIXP_DBL, 4*HYBRID_FILTER_LENGTH); 575 576 } 577 578 579 /******************************************************************************* 580 Functionname: slotBasedHybridSynthesis 581 ******************************************************************************* 582 583 Description: The coefficients offering higher resolution for the lower QMF 584 channel are simply added prior to the synthesis with the 54 585 subbands QMF. 586 587 Arguments: 588 589 Return: none 590 591 *******************************************************************************/ 592 593 /*! <pre> 594 l,r0(n) ---\ 595 l,r1(n) ---- + --\ 596 l,r2(n) ---/ \ 597 + --> F0(w) 598 l,r3(n) ---\ / 599 l,r4(n) ---- + --/ 600 l,r5(n) ---/ 601 602 603 l,r6(n) ---\ 604 + ---------> F1(w) 605 l,r7(n) ---/ 606 607 608 l,r8(n) ---\ 609 + ---------> F2(w) 610 l,r9(n) ---/ 611 612 </pre> 613 Hybrid QMF synthesis filterbank for the 10 and 20 stereo-bands configurations. The 614 coefficients offering higher resolution for the lower QMF channel are simply added 615 prior to the synthesis with the 54 subbands QMF. 616 617 [see ISO/IEC 14496-3:2001/FDAM 2:2004(E) - Page 52] 618 */ 619 620 621 void 622 slotBasedHybridSynthesis ( FIXP_DBL *fixpHybridReal, /*!< Hybrid real Values */ 623 FIXP_DBL *fixpHybridImag, /*!< Hybrid imag Values */ 624 FIXP_DBL *fixpQmfReal, /*!< Qmf real Values */ 625 FIXP_DBL *fixpQmfImag, /*!< Qmf imag Values */ 626 HANDLE_HYBRID hHybrid ) /*!< Handle to HYBRID struct. */ 627 { 628 int k, band; 629 630 HYBRID_RES hybridRes; 631 int chOffset = 0; 632 633 for(band = 0; band < hHybrid->nQmfBands; band++) { 634 635 FIXP_DBL qmfReal = FL2FXCONST_DBL(0.f); 636 FIXP_DBL qmfImag = FL2FXCONST_DBL(0.f); 637 hybridRes = (HYBRID_RES)hHybrid->pResolution[band]; 638 639 for(k = 0; k < (SCHAR)hybridRes; k++) { 640 qmfReal += fixpHybridReal[chOffset + k]; 641 qmfImag += fixpHybridImag[chOffset + k]; 642 } 643 644 fixpQmfReal[band] = qmfReal; 645 fixpQmfImag[band] = qmfImag; 646 647 chOffset += hybridRes; 648 } 649 } 650 651 652 653