2 /* -----------------------------------------------------------------------------------------------------------
3 Software License for The Fraunhofer FDK AAC Codec Library for Android
5 © Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
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.
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.
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.
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.
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:
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.
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.
42 The name of Fraunhofer may not be used to endorse or promote products derived from this library without
43 prior written permission.
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.
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."
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.
59 You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized
60 by appropriate patent licenses.
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.
73 5. CONTACT INFORMATION
75 Fraunhofer Institute for Integrated Circuits IIS
76 Attention: Audio and Multimedia Departments - FDK AAC LL
78 91058 Erlangen, Germany
80 www.iis.fraunhofer.de/amm
81 amm-info@iis.fraunhofer.de
82 ----------------------------------------------------------------------------------------------------------- */
84 #include "psdec_hybrid.h"
90 #include "FDK_tools_rom.h"
93 /*******************************************************************************
94 Functionname: InitHybridFilterBank
95 *******************************************************************************
97 Description: Init one instance of HANDLE_HYBRID stuct
103 *******************************************************************************/
107 InitHybridFilterBank ( HANDLE_HYBRID hs
, /*!< Handle to HYBRID struct. */
108 SCHAR frameSize
, /*!< Framesize (in Qmf súbband samples). */
109 SCHAR noBands
, /*!< Number of Qmf bands for hybrid filtering. */
110 const UCHAR
*pResolution
) /*!< Resolution in Qmf bands (length noBands). */
113 UCHAR maxNoChannels
= 0;
115 for (i
= 0; i
< noBands
; i
++) {
116 hs
->pResolution
[i
] = pResolution
[i
];
117 if(pResolution
[i
] > maxNoChannels
)
118 maxNoChannels
= pResolution
[i
];
121 hs
->nQmfBands
= noBands
;
122 hs
->frameSize
= frameSize
;
123 hs
->qmfBufferMove
= HYBRID_FILTER_LENGTH
- 1;
125 hs
->sf_mQmfBuffer
= 0;
130 /*******************************************************************************
131 Functionname: dualChannelFiltering
132 *******************************************************************************
134 Description: fast 2-channel real-valued filtering with 6-tap delay.
140 *******************************************************************************/
162 h[q,n] = g[n] * cos(2pi/2 * q * (n-6) ); n = 0..12, q = 0,1;
164 -> h[0,n] = g[n] * 1;
165 -> h[1,n] = g[n] * pow(-1,n);
169 static void slotBasedDualChannelFiltering( const FIXP_DBL
*pQmfReal
,
170 const FIXP_DBL
*pQmfImag
,
172 FIXP_DBL
*mHybridReal
,
173 FIXP_DBL
*mHybridImag
)
176 FIXP_DBL t1
, t3
, t5
, t6
;
178 /* symmetric filter coefficients */
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) );
186 mHybridReal
[0] = (t1
+ t3
+ t5
+ t6
) << 2;
187 mHybridReal
[1] = (- t1
- t3
- t5
+ t6
) << 2;
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 );
194 mHybridImag
[0] = (t1
+ t3
+ t5
+ t6
) << 2;
195 mHybridImag
[1] = (- t1
- t3
- t5
+ t6
) << 2;
199 /*******************************************************************************
200 Functionname: eightChannelFiltering
201 *******************************************************************************
203 Description: fast 8-channel complex-valued filtering with 6-tap delay.
209 *******************************************************************************/
213 Implementation using a FFT of length 8
215 prototype filter coefficients:
216 0.00746082949812 0.02270420949825 0.04546865930473 0.07266113929591 0.09885108575264 0.11793710567217
218 0.11793710567217 0.09885108575264 0.07266113929591 0.04546865930473 0.02270420949825 0.00746082949812
222 h[q,n] = g[n] * exp(j * 2 * pi / Q * (q + .5) * (n - 6)); n = 0..(N-1), q = 0..(Q-1);
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);
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]
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];
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);
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]
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];
242 Try to split off FFT Modulation Term:
243 FFT(x[t], q) = sum(x[t+k]*exp(-j*2*pi/N *q * k))
245 Step 1: h'[q,n] = g[n] * ( exp(j * 2 * pi / 8 * .5 * (6 - n)) ) * ( exp (j * 2 * pi / 8 * q * (6 - n)) );
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) );
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];
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
272 now use fft modulation coefficients
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]
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];
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) | |
302 /* defining rotation factors for *ChannelFiltering */
304 #define cos0Pi FL2FXCONST_DBL( 1.f)
305 #define sin0Pi FL2FXCONST_DBL( 0.f)
307 #define cos1Pi FL2FXCONST_DBL(-1.f)
308 #define sin1Pi FL2FXCONST_DBL( 0.f)
310 #define cos1Pi_2 FL2FXCONST_DBL( 0.f)
311 #define sin1Pi_2 FL2FXCONST_DBL( 1.f)
313 #define cos1Pi_3 FL2FXCONST_DBL( 0.5f)
314 #define sin1Pi_3 FL2FXCONST_DBL( 0.86602540378444f)
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
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)
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)
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
348 #if defined(ARCH_PREFER_MULT_32x16)
349 #define FIXP_HYB FIXP_SGL
350 #define FIXP_CAST FX_DBL2FX_SGL
352 #define FIXP_HYB FIXP_DBL
356 static const FIXP_HYB cr
[13] =
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
),
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
)
365 static const FIXP_HYB ci
[13] =
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
)
374 static void slotBasedEightChannelFiltering( const FIXP_DBL
*pQmfReal
,
375 const FIXP_DBL
*pQmfImag
,
377 FIXP_DBL
*mHybridReal
,
378 FIXP_DBL
*mHybridImag
)
382 FIXP_DBL _fft
[128 + ALIGNMENT_DEFAULT
- 1];
383 FIXP_DBL
*fft
= (FIXP_DBL
*)ALIGN_PTR(_fft
);
385 #if defined(ARCH_PREFER_MULT_32x16)
386 const FIXP_SGL
*p
= p8_13_20
; /* BASELINE_PS */
388 const FIXP_DBL
*p
= p8_13_20
; /* BASELINE_PS */
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
;
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;
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);
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;
433 /*******************************************************************************
434 Functionname: fillHybridDelayLine
435 *******************************************************************************
437 Description: The delay line of the hybrid filter is filled and copied from
442 *******************************************************************************/
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
)
455 for (i
= 0; i
< HYBRID_FILTER_DELAY
; i
++) {
456 slotBasedHybridAnalysis ( fixpQmfReal
[i
],
463 FDKmemcpy(fixpHybridRightR
, fixpHybridLeftR
, sizeof(FIXP_DBL
)*NO_SUB_QMF_CHANNELS
);
464 FDKmemcpy(fixpHybridRightI
, fixpHybridLeftI
, sizeof(FIXP_DBL
)*NO_SUB_QMF_CHANNELS
);
468 /*******************************************************************************
469 Functionname: slotBasedHybridAnalysis
470 *******************************************************************************
472 Description: The lower QMF subbands are further split to provide better
473 frequency resolution for PS processing.
477 *******************************************************************************/
481 slotBasedHybridAnalysis ( FIXP_DBL
*fixpQmfReal
, /*!< Qmf real Values */
482 FIXP_DBL
*fixpQmfImag
, /*!< Qmf imag Values */
484 FIXP_DBL fixpHybridReal
[12], /*!< Hybrid real Values */
485 FIXP_DBL fixpHybridImag
[12], /*!< Hybrid imag Values */
487 HANDLE_HYBRID hHybrid
)
490 HYBRID_RES hybridRes
;
493 C_ALLOC_SCRATCH_START(pTempRealSlot
, FIXP_DBL
, 4*HYBRID_FILTER_LENGTH
);
495 FIXP_DBL
*pTempImagSlot
= pTempRealSlot
+ HYBRID_FILTER_LENGTH
;
496 FIXP_DBL
*pWorkRealSlot
= pTempImagSlot
+ HYBRID_FILTER_LENGTH
;
497 FIXP_DBL
*pWorkImagSlot
= pWorkRealSlot
+ HYBRID_FILTER_LENGTH
;
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.
506 for(band
= 0; band
< hHybrid
->nQmfBands
; band
++) {
508 /* get hybrid resolution per qmf band */
509 /* in case of baseline ps 10/20 band stereo mode : */
511 /* qmfBand[0] : 8 ( HYBRID_8_CPLX ) */
512 /* qmfBand[1] : 2 ( HYBRID_2_REAL ) */
513 /* qmfBand[2] : 2 ( HYBRID_2_REAL ) */
515 /* (split the 3 lower qmf band to 12 hybrid bands) */
517 hybridRes
= (HYBRID_RES
)hHybrid
->pResolution
[band
];
519 FDKmemcpy(pWorkRealSlot
, hHybrid
->mQmfBufferRealSlot
[band
], hHybrid
->qmfBufferMove
* sizeof(FIXP_DBL
));
520 FDKmemcpy(pWorkImagSlot
, hHybrid
->mQmfBufferImagSlot
[band
], hHybrid
->qmfBufferMove
* sizeof(FIXP_DBL
));
522 pWorkRealSlot
[hHybrid
->qmfBufferMove
] = fixpQmfReal
[band
];
523 pWorkImagSlot
[hHybrid
->qmfBufferMove
] = fixpQmfImag
[band
];
525 FDKmemcpy(hHybrid
->mQmfBufferRealSlot
[band
], pWorkRealSlot
+ 1, hHybrid
->qmfBufferMove
* sizeof(FIXP_DBL
));
526 FDKmemcpy(hHybrid
->mQmfBufferImagSlot
[band
], pWorkImagSlot
+ 1, hHybrid
->qmfBufferMove
* sizeof(FIXP_DBL
));
530 /* actual filtering only if output signal requested */
531 switch( hybridRes
) {
533 /* HYBRID_2_REAL & HYBRID_8_CPLX are only needful for baseline ps */
536 slotBasedDualChannelFiltering( pWorkRealSlot
,
544 slotBasedEightChannelFiltering( pWorkRealSlot
,
554 for(k
= 0; k
< (SCHAR
)hybridRes
; k
++) {
555 fixpHybridReal
[chOffset
+ k
] = pTempRealSlot
[k
];
556 fixpHybridImag
[chOffset
+ k
] = pTempImagSlot
[k
];
558 chOffset
+= hybridRes
;
559 } /* if (mHybridReal) */
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;
568 fixpHybridReal
[2] += fixpHybridReal
[5];
569 fixpHybridImag
[2] += fixpHybridImag
[5];
570 fixpHybridReal
[5] = (FIXP_DBL
)0;
571 fixpHybridImag
[5] = (FIXP_DBL
)0;
573 /* free memory on scratch */
574 C_ALLOC_SCRATCH_END(pTempRealSlot
, FIXP_DBL
, 4*HYBRID_FILTER_LENGTH
);
579 /*******************************************************************************
580 Functionname: slotBasedHybridSynthesis
581 *******************************************************************************
583 Description: The coefficients offering higher resolution for the lower QMF
584 channel are simply added prior to the synthesis with the 54
591 *******************************************************************************/
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.
617 [see ISO/IEC 14496-3:2001/FDAM 2:2004(E) - Page 52]
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. */
630 HYBRID_RES hybridRes
;
633 for(band
= 0; band
< hHybrid
->nQmfBands
; band
++) {
635 FIXP_DBL qmfReal
= FL2FXCONST_DBL(0.f
);
636 FIXP_DBL qmfImag
= FL2FXCONST_DBL(0.f
);
637 hybridRes
= (HYBRID_RES
)hHybrid
->pResolution
[band
];
639 for(k
= 0; k
< (SCHAR
)hybridRes
; k
++) {
640 qmfReal
+= fixpHybridReal
[chOffset
+ k
];
641 qmfImag
+= fixpHybridImag
[chOffset
+ k
];
644 fixpQmfReal
[band
] = qmfReal
;
645 fixpQmfImag
[band
] = qmfImag
;
647 chOffset
+= hybridRes
;