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 ----------------------------------------------------------------------------------------------------------- */
86 \brief Low Power Profile Transposer,
87 This module provides the transposer. The main entry point is lppTransposer(). The function generates
88 high frequency content by copying data from the low band (provided by core codec) into the high band.
89 This process is also referred to as "patching". The function also implements spectral whitening by means of
90 inverse filtering based on LPC coefficients.
92 Together with the QMF filterbank the transposer can be tested using a supplied test program. See main_audio.cpp for details.
93 This module does use fractional arithmetic and the accuracy of the computations has an impact on the overall sound quality.
94 The module also needs to take into account the different scaling of spectral data.
96 \sa lppTransposer(), main_audio.cpp, sbr_scale.h, \ref documentationOverview
104 #include "genericStds.h"
105 #include "autocorr2nd.h"
110 #include "arm/lpp_tran_arm.cpp"
115 #define LPC_SCALE_FACTOR 2
120 * \brief Get bandwidth expansion factor from filtering level
122 * Returns a filter parameter (bandwidth expansion factor) depending on
123 * the desired filtering level signalled in the bitstream.
124 * When switching the filtering level from LOW to OFF, an additional
125 * level is being inserted to achieve a smooth transition.
128 #ifndef FUNCTION_mapInvfMode
130 mapInvfMode (INVF_MODE mode
,
132 WHITENING_FACTORS whFactors
)
136 if(prevMode
== INVF_OFF
)
137 return whFactors
.transitionLevel
;
139 return whFactors
.lowLevel
;
142 return whFactors
.midLevel
;
144 case INVF_HIGH_LEVEL
:
145 return whFactors
.highLevel
;
148 if(prevMode
== INVF_LOW_LEVEL
)
149 return whFactors
.transitionLevel
;
151 return whFactors
.off
;
154 #endif /* #ifndef FUNCTION_mapInvfMode */
158 * \brief Perform inverse filtering level emphasis
160 * Retrieve bandwidth expansion factor and apply smoothing for each filter band
164 #ifndef FUNCTION_inverseFilteringLevelEmphasis
166 inverseFilteringLevelEmphasis(HANDLE_SBR_LPP_TRANS hLppTrans
,/*!< Handle of lpp transposer */
167 UCHAR nInvfBands
, /*!< Number of bands for inverse filtering */
168 INVF_MODE
*sbr_invf_mode
, /*!< Current inverse filtering modes */
169 INVF_MODE
*sbr_invf_mode_prev
, /*!< Previous inverse filtering modes */
170 FIXP_DBL
* bwVector
/*!< Resulting filtering levels */
173 for(int i
= 0; i
< nInvfBands
; i
++) {
175 FIXP_DBL bwTmp
= mapInvfMode (sbr_invf_mode
[i
],
176 sbr_invf_mode_prev
[i
],
177 hLppTrans
->pSettings
->whFactors
);
179 if(bwTmp
< hLppTrans
->bwVectorOld
[i
]) {
180 accu
= fMultDiv2(FL2FXCONST_DBL(0.75f
),bwTmp
) +
181 fMultDiv2(FL2FXCONST_DBL(0.25f
),hLppTrans
->bwVectorOld
[i
]);
184 accu
= fMultDiv2(FL2FXCONST_DBL(0.90625f
),bwTmp
) +
185 fMultDiv2(FL2FXCONST_DBL(0.09375f
),hLppTrans
->bwVectorOld
[i
]);
188 if (accu
< FL2FXCONST_DBL(0.015625f
)>>1)
189 bwVector
[i
] = FL2FXCONST_DBL(0.0f
);
191 bwVector
[i
] = fixMin(accu
<<1,FL2FXCONST_DBL(0.99609375f
));
194 #endif /* #ifndef FUNCTION_inverseFilteringLevelEmphasis */
196 /* Resulting autocorrelation determinant exponent */
197 #define ACDET_EXP (2*(DFRACT_BITS+sbrScaleFactor->lb_scale+10-ac.det_scale))
198 #define AC_EXP (-sbrScaleFactor->lb_scale+LPC_SCALE_FACTOR)
199 #define ALPHA_EXP (-sbrScaleFactor->lb_scale+LPC_SCALE_FACTOR+1)
200 /* Resulting transposed QMF values exponent 16 bit normalized samplebits assumed. */
201 #define QMFOUT_EXP ((SAMPLE_BITS-15)-sbrScaleFactor->lb_scale)
205 * \brief Perform transposition by patching of subband samples.
206 * This function serves as the main entry point into the module. The function determines the areas for the
207 * patching process (these are the source range as well as the target range) and implements spectral whitening
208 * by means of inverse filtering. The function autoCorrelation2nd() is an auxiliary function for calculating the
209 * LPC coefficients for the filtering. The actual calculation of the LPC coefficients and the implementation
210 * of the filtering are done as part of lppTransposer().
212 * Note that the filtering is done on all available QMF subsamples, whereas the patching is only done on those QMF
213 * subsamples that will be used in the next QMF synthesis. The filtering is also implemented before the patching
214 * includes further dependencies on parameters from the SBR data.
218 void lppTransposer (HANDLE_SBR_LPP_TRANS hLppTrans
, /*!< Handle of lpp transposer */
219 QMF_SCALE_FACTOR
*sbrScaleFactor
, /*!< Scaling factors */
220 FIXP_DBL
**qmfBufferReal
, /*!< Pointer to pointer to real part of subband samples (source) */
222 FIXP_DBL
*degreeAlias
, /*!< Vector for results of aliasing estimation */
223 FIXP_DBL
**qmfBufferImag
, /*!< Pointer to pointer to imaginary part of subband samples (source) */
225 const int timeStep
, /*!< Time step of envelope */
226 const int firstSlotOffs
, /*!< Start position in time */
227 const int lastSlotOffs
, /*!< Number of overlap-slots into next frame */
228 const int nInvfBands
, /*!< Number of bands for inverse filtering */
229 INVF_MODE
*sbr_invf_mode
, /*!< Current inverse filtering modes */
230 INVF_MODE
*sbr_invf_mode_prev
/*!< Previous inverse filtering modes */
233 INT bwIndex
[MAX_NUM_PATCHES
];
234 FIXP_DBL bwVector
[MAX_NUM_PATCHES
]; /*!< pole moving factors */
237 int loBand
, start
, stop
;
238 TRANSPOSER_SETTINGS
*pSettings
= hLppTrans
->pSettings
;
239 PATCH_PARAM
*patchParam
= pSettings
->patchParam
;
242 FIXP_SGL alphar
[LPC_ORDER
], a0r
, a1r
;
243 FIXP_SGL alphai
[LPC_ORDER
], a0i
=0, a1i
=0;
244 FIXP_SGL bw
= FL2FXCONST_SGL(0.0f
);
248 FIXP_DBL k1
, k1_below
=0, k1_below2
=0;
258 /* int ovHighBandShift;*/
262 alphai
[0] = FL2FXCONST_SGL(0.0f
);
263 alphai
[1] = FL2FXCONST_SGL(0.0f
);
266 startSample
= firstSlotOffs
* timeStep
;
267 stopSample
= pSettings
->nCols
+ lastSlotOffs
* timeStep
;
270 inverseFilteringLevelEmphasis(hLppTrans
, nInvfBands
, sbr_invf_mode
, sbr_invf_mode_prev
, bwVector
);
272 stopSampleClear
= stopSample
;
274 autoCorrLength
= pSettings
->nCols
+ pSettings
->overlap
;
276 /* Set upper subbands to zero:
277 This is required in case that the patches do not cover the complete highband
278 (because the last patch would be too short).
279 Possible optimization: Clearing bands up to usb would be sufficient here. */
280 targetStopBand
= patchParam
[pSettings
->noOfPatches
-1].targetStartBand
281 + patchParam
[pSettings
->noOfPatches
-1].numBandsInPatch
;
283 int memSize
= ((64) - targetStopBand
) * sizeof(FIXP_DBL
);
286 for (i
= startSample
; i
< stopSampleClear
; i
++) {
287 FDKmemclear(&qmfBufferReal
[i
][targetStopBand
], memSize
);
288 FDKmemclear(&qmfBufferImag
[i
][targetStopBand
], memSize
);
291 for (i
= startSample
; i
< stopSampleClear
; i
++) {
292 FDKmemclear(&qmfBufferReal
[i
][targetStopBand
], memSize
);
295 /* init bwIndex for each patch */
296 FDKmemclear(bwIndex
, pSettings
->noOfPatches
*sizeof(INT
));
299 Calc common low band scale factor
301 comLowBandScale
= fixMin(sbrScaleFactor
->ov_lb_scale
,sbrScaleFactor
->lb_scale
);
303 ovLowBandShift
= sbrScaleFactor
->ov_lb_scale
- comLowBandScale
;
304 lowBandShift
= sbrScaleFactor
->lb_scale
- comLowBandScale
;
305 /* ovHighBandShift = firstSlotOffs == 0 ? ovLowBandShift:0;*/
307 /* outer loop over bands to do analysis only once for each band */
310 start
= pSettings
->lbStartPatching
;
311 stop
= pSettings
->lbStopPatching
;
314 start
= fixMax(1, pSettings
->lbStartPatching
- 2);
315 stop
= patchParam
[0].targetStartBand
;
319 for ( loBand
= start
; loBand
< stop
; loBand
++ ) {
321 FIXP_DBL lowBandReal
[(((1024)/(32))+(6))+LPC_ORDER
];
322 FIXP_DBL
*plowBandReal
= lowBandReal
;
323 FIXP_DBL
**pqmfBufferReal
= qmfBufferReal
;
324 FIXP_DBL lowBandImag
[(((1024)/(32))+(6))+LPC_ORDER
];
325 FIXP_DBL
*plowBandImag
= lowBandImag
;
326 FIXP_DBL
**pqmfBufferImag
= qmfBufferImag
;
327 int resetLPCCoeffs
=0;
328 int dynamicScale
= DFRACT_BITS
-1-LPC_SCALE_FACTOR
;
329 int acDetScale
= 0; /* scaling of autocorrelation determinant */
331 for(i
=0;i
<LPC_ORDER
;i
++){
332 *plowBandReal
++ = hLppTrans
->lpcFilterStatesReal
[i
][loBand
];
334 *plowBandImag
++ = hLppTrans
->lpcFilterStatesImag
[i
][loBand
];
338 Take old slope length qmf slot source values out of (overlap)qmf buffer
341 for(i
=0;i
<pSettings
->nCols
+pSettings
->overlap
;i
++){
342 *plowBandReal
++ = (*pqmfBufferReal
++)[loBand
];
343 *plowBandImag
++ = (*pqmfBufferImag
++)[loBand
];
347 /* pSettings->overlap is always even */
348 FDK_ASSERT((pSettings
->overlap
& 1) == 0);
350 for(i
=0;i
<((pSettings
->overlap
+pSettings
->nCols
)>>1);i
++) {
351 *plowBandReal
++ = (*pqmfBufferReal
++)[loBand
];
352 *plowBandReal
++ = (*pqmfBufferReal
++)[loBand
];
354 if (pSettings
->nCols
& 1) {
355 *plowBandReal
++ = (*pqmfBufferReal
++)[loBand
];
360 Determine dynamic scaling value.
362 dynamicScale
= fixMin(dynamicScale
, getScalefactor(lowBandReal
, LPC_ORDER
+pSettings
->overlap
) + ovLowBandShift
);
363 dynamicScale
= fixMin(dynamicScale
, getScalefactor(&lowBandReal
[LPC_ORDER
+pSettings
->overlap
], pSettings
->nCols
) + lowBandShift
);
365 dynamicScale
= fixMin(dynamicScale
, getScalefactor(lowBandImag
, LPC_ORDER
+pSettings
->overlap
) + ovLowBandShift
);
366 dynamicScale
= fixMin(dynamicScale
, getScalefactor(&lowBandImag
[LPC_ORDER
+pSettings
->overlap
], pSettings
->nCols
) + lowBandShift
);
368 dynamicScale
= fixMax(0, dynamicScale
-1); /* one additional bit headroom to prevent -1.0 */
371 Scale temporal QMF buffer.
373 scaleValues(&lowBandReal
[0], LPC_ORDER
+pSettings
->overlap
, dynamicScale
-ovLowBandShift
);
374 scaleValues(&lowBandReal
[LPC_ORDER
+pSettings
->overlap
], pSettings
->nCols
, dynamicScale
-lowBandShift
);
377 scaleValues(&lowBandImag
[0], LPC_ORDER
+pSettings
->overlap
, dynamicScale
-ovLowBandShift
);
378 scaleValues(&lowBandImag
[LPC_ORDER
+pSettings
->overlap
], pSettings
->nCols
, dynamicScale
-lowBandShift
);
383 acDetScale
+= autoCorr2nd_cplx(&ac
, lowBandReal
+LPC_ORDER
, lowBandImag
+LPC_ORDER
, autoCorrLength
);
387 acDetScale
+= autoCorr2nd_real(&ac
, lowBandReal
+LPC_ORDER
, autoCorrLength
);
390 /* Examine dynamic of determinant in autocorrelation. */
391 acDetScale
+= 2*(comLowBandScale
+ dynamicScale
);
392 acDetScale
*= 2; /* two times reflection coefficent scaling */
393 acDetScale
+= ac
.det_scale
; /* ac scaling of determinant */
395 /* In case of determinant < 10^-38, resetLPCCoeffs=1 has to be enforced. */
396 if (acDetScale
>126 ) {
401 alphar
[1] = FL2FXCONST_SGL(0.0f
);
403 alphai
[1] = FL2FXCONST_SGL(0.0f
);
405 if (ac
.det
!= FL2FXCONST_DBL(0.0f
)) {
406 FIXP_DBL tmp
,absTmp
,absDet
;
408 absDet
= fixp_abs(ac
.det
);
411 tmp
= ( fMultDiv2(ac
.r01r
,ac
.r12r
) >> (LPC_SCALE_FACTOR
-1) ) -
412 ( (fMultDiv2(ac
.r01i
,ac
.r12i
) + fMultDiv2(ac
.r02r
,ac
.r11r
)) >> (LPC_SCALE_FACTOR
-1) );
415 tmp
= ( fMultDiv2(ac
.r01r
,ac
.r12r
) >> (LPC_SCALE_FACTOR
-1) ) -
416 ( fMultDiv2(ac
.r02r
,ac
.r11r
) >> (LPC_SCALE_FACTOR
-1) );
418 absTmp
= fixp_abs(tmp
);
421 Quick check: is first filter coeff >= 1(4)
425 FIXP_DBL result
= fDivNorm(absTmp
, absDet
, &scale
);
426 scale
= scale
+ac
.det_scale
;
428 if ( (scale
> 0) && (result
>= (FIXP_DBL
)MAXVAL_DBL
>>scale
) ) {
432 alphar
[1] = FX_DBL2FX_SGL(scaleValue(result
,scale
));
433 if((tmp
<FL2FX_DBL(0.0f
)) ^ (ac
.det
<FL2FX_DBL(0.0f
))) {
434 alphar
[1] = -alphar
[1];
441 tmp
= ( fMultDiv2(ac
.r01i
,ac
.r12r
) >> (LPC_SCALE_FACTOR
-1) ) +
442 ( (fMultDiv2(ac
.r01r
,ac
.r12i
) - (FIXP_DBL
)fMultDiv2(ac
.r02i
,ac
.r11r
)) >> (LPC_SCALE_FACTOR
-1) ) ;
444 absTmp
= fixp_abs(tmp
);
447 Quick check: is second filter coeff >= 1(4)
451 FIXP_DBL result
= fDivNorm(absTmp
, absDet
, &scale
);
452 scale
= scale
+ac
.det_scale
;
454 if ( (scale
> 0) && (result
>= /*FL2FXCONST_DBL(1.f)*/ (FIXP_DBL
)MAXVAL_DBL
>>scale
) ) {
458 alphai
[1] = FX_DBL2FX_SGL(scaleValue(result
,scale
));
459 if((tmp
<FL2FX_DBL(0.0f
)) ^ (ac
.det
<FL2FX_DBL(0.0f
))) {
460 alphai
[1] = -alphai
[1];
467 alphar
[0] = FL2FXCONST_SGL(0.0f
);
469 alphai
[0] = FL2FXCONST_SGL(0.0f
);
471 if ( ac
.r11r
!= FL2FXCONST_DBL(0.0f
) ) {
473 /* ac.r11r is always >=0 */
477 tmp
= (ac
.r01r
>>(LPC_SCALE_FACTOR
+1)) +
478 (fMultDiv2(alphar
[1],ac
.r12r
) + fMultDiv2(alphai
[1],ac
.r12i
));
481 if(ac
.r01r
>=FL2FXCONST_DBL(0.0f
))
482 tmp
= (ac
.r01r
>>(LPC_SCALE_FACTOR
+1)) + fMultDiv2(alphar
[1],ac
.r12r
);
484 tmp
= -((-ac
.r01r
)>>(LPC_SCALE_FACTOR
+1)) + fMultDiv2(alphar
[1],ac
.r12r
);
487 absTmp
= fixp_abs(tmp
);
490 Quick check: is first filter coeff >= 1(4)
493 if (absTmp
>= (ac
.r11r
>>1)) {
498 FIXP_DBL result
= fDivNorm(absTmp
, fixp_abs(ac
.r11r
), &scale
);
499 alphar
[0] = FX_DBL2FX_SGL(scaleValue(result
,scale
+1));
501 if((tmp
>FL2FX_DBL(0.0f
)) ^ (ac
.r11r
<FL2FX_DBL(0.0f
)))
502 alphar
[0] = -alphar
[0];
507 tmp
= (ac
.r01i
>>(LPC_SCALE_FACTOR
+1)) +
508 (fMultDiv2(alphai
[1],ac
.r12r
) - fMultDiv2(alphar
[1],ac
.r12i
));
510 absTmp
= fixp_abs(tmp
);
513 Quick check: is second filter coeff >= 1(4)
515 if (absTmp
>= (ac
.r11r
>>1)) {
520 FIXP_DBL result
= fDivNorm(absTmp
, fixp_abs(ac
.r11r
), &scale
);
521 alphai
[0] = FX_DBL2FX_SGL(scaleValue(result
,scale
+1));
522 if((tmp
>FL2FX_DBL(0.0f
)) ^ (ac
.r11r
<FL2FX_DBL(0.0f
)))
523 alphai
[0] = -alphai
[0];
531 /* Now check the quadratic criteria */
532 if( (fMultDiv2(alphar
[0],alphar
[0]) + fMultDiv2(alphai
[0],alphai
[0])) >= FL2FXCONST_DBL(0.5f
) )
534 if( (fMultDiv2(alphar
[1],alphar
[1]) + fMultDiv2(alphai
[1],alphai
[1])) >= FL2FXCONST_DBL(0.5f
) )
539 alphar
[0] = FL2FXCONST_SGL(0.0f
);
540 alphar
[1] = FL2FXCONST_SGL(0.0f
);
543 alphai
[0] = FL2FXCONST_SGL(0.0f
);
544 alphai
[1] = FL2FXCONST_SGL(0.0f
);
551 /* Aliasing detection */
552 if(ac
.r11r
==FL2FXCONST_DBL(0.0f
)) {
553 k1
= FL2FXCONST_DBL(0.0f
);
556 if ( fixp_abs(ac
.r01r
) >= fixp_abs(ac
.r11r
) ) {
557 if ( fMultDiv2(ac
.r01r
,ac
.r11r
) < FL2FX_DBL(0.0f
)) {
558 k1
= (FIXP_DBL
)MAXVAL_DBL
/*FL2FXCONST_SGL(1.0f)*/;
560 /* Since this value is squared later, it must not ever become -1.0f. */
561 k1
= (FIXP_DBL
)(MINVAL_DBL
+1) /*FL2FXCONST_SGL(-1.0f)*/;
566 FIXP_DBL result
= fDivNorm(fixp_abs(ac
.r01r
), fixp_abs(ac
.r11r
), &scale
);
567 k1
= scaleValue(result
,scale
);
569 if(!((ac
.r01r
<FL2FX_DBL(0.0f
)) ^ (ac
.r11r
<FL2FX_DBL(0.0f
)))) {
575 /* Check if the gain should be locked */
576 FIXP_DBL deg
= /*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL
)MAXVAL_DBL
- fPow2(k1_below
);
577 degreeAlias
[loBand
] = FL2FXCONST_DBL(0.0f
);
578 if (((loBand
& 1) == 0) && (k1
< FL2FXCONST_DBL(0.0f
))){
579 if (k1_below
< FL2FXCONST_DBL(0.0f
)) { /* 2-Ch Aliasing Detection */
580 degreeAlias
[loBand
] = (FIXP_DBL
)MAXVAL_DBL
/*FL2FXCONST_DBL(1.0f)*/;
581 if ( k1_below2
> FL2FXCONST_DBL(0.0f
) ) { /* 3-Ch Aliasing Detection */
582 degreeAlias
[loBand
-1] = deg
;
585 else if ( k1_below2
> FL2FXCONST_DBL(0.0f
) ) { /* 3-Ch Aliasing Detection */
586 degreeAlias
[loBand
] = deg
;
589 if (((loBand
& 1) == 1) && (k1
> FL2FXCONST_DBL(0.0f
))){
590 if (k1_below
> FL2FXCONST_DBL(0.0f
)) { /* 2-CH Aliasing Detection */
591 degreeAlias
[loBand
] = (FIXP_DBL
)MAXVAL_DBL
/*FL2FXCONST_DBL(1.0f)*/;
592 if ( k1_below2
< FL2FXCONST_DBL(0.0f
) ) { /* 3-CH Aliasing Detection */
593 degreeAlias
[loBand
-1] = deg
;
596 else if ( k1_below2
< FL2FXCONST_DBL(0.0f
) ) { /* 3-CH Aliasing Detection */
597 degreeAlias
[loBand
] = deg
;
601 /* remember k1 values of the 2 QMF channels below the current channel */
602 k1_below2
= k1_below
;
608 while ( patch
< pSettings
->noOfPatches
) { /* inner loop over every patch */
610 int hiBand
= loBand
+ patchParam
[patch
].targetBandOffs
;
612 if ( loBand
< patchParam
[patch
].sourceStartBand
613 || loBand
>= patchParam
[patch
].sourceStopBand
614 //|| hiBand >= hLppTrans->pSettings->noChannels
616 /* Lowband not in current patch - proceed */
621 FDK_ASSERT( hiBand
< (64) );
623 /* bwIndex[patch] is already initialized with value from previous band inside this patch */
624 while (hiBand
>= pSettings
->bwBorders
[bwIndex
[patch
]])
629 Filter Step 2: add the left slope with the current filter to the buffer
630 pure source values are already in there
632 bw
= FX_DBL2FX_SGL(bwVector
[bwIndex
[patch
]]);
634 a0r
= FX_DBL2FX_SGL(fMult(bw
,alphar
[0])); /* Apply current bandwidth expansion factor */
638 a0i
= FX_DBL2FX_SGL(fMult(bw
,alphai
[0]));
639 bw
= FX_DBL2FX_SGL(fPow2(bw
));
640 a1r
= FX_DBL2FX_SGL(fMult(bw
,alphar
[1]));
642 a1i
= FX_DBL2FX_SGL(fMult(bw
,alphai
[1]));
647 Filter Step 3: insert the middle part which won't be windowed
650 if ( bw
<= FL2FXCONST_SGL(0.0f
) ) {
652 int descale
= fixMin(DFRACT_BITS
-1, (LPC_SCALE_FACTOR
+dynamicScale
));
653 for(i
= startSample
; i
< stopSample
; i
++ ) {
654 qmfBufferReal
[i
][hiBand
] = lowBandReal
[LPC_ORDER
+i
]>>descale
;
655 qmfBufferImag
[i
][hiBand
] = lowBandImag
[LPC_ORDER
+i
]>>descale
;
659 int descale
= fixMin(DFRACT_BITS
-1, (LPC_SCALE_FACTOR
+dynamicScale
));
660 for(i
= startSample
; i
< stopSample
; i
++ ) {
661 qmfBufferReal
[i
][hiBand
] = lowBandReal
[LPC_ORDER
+i
]>>descale
;
668 int descale
= fixMin(DFRACT_BITS
-1, (LPC_SCALE_FACTOR
+dynamicScale
));
669 #ifdef FUNCTION_LPPTRANSPOSER_func1
670 lppTransposer_func1(lowBandReal
+LPC_ORDER
+startSample
,lowBandImag
+LPC_ORDER
+startSample
,
671 qmfBufferReal
+startSample
,qmfBufferImag
+startSample
,
672 stopSample
-startSample
, (int) hiBand
,
673 dynamicScale
,descale
,
676 for(i
= startSample
; i
< stopSample
; i
++ ) {
677 FIXP_DBL accu1
, accu2
;
679 accu1
= (fMultDiv2(a0r
,lowBandReal
[LPC_ORDER
+i
-1]) - fMultDiv2(a0i
,lowBandImag
[LPC_ORDER
+i
-1]) +
680 fMultDiv2(a1r
,lowBandReal
[LPC_ORDER
+i
-2]) - fMultDiv2(a1i
,lowBandImag
[LPC_ORDER
+i
-2]))>>dynamicScale
;
681 accu2
= (fMultDiv2(a0i
,lowBandReal
[LPC_ORDER
+i
-1]) + fMultDiv2(a0r
,lowBandImag
[LPC_ORDER
+i
-1]) +
682 fMultDiv2(a1i
,lowBandReal
[LPC_ORDER
+i
-2]) + fMultDiv2(a1r
,lowBandImag
[LPC_ORDER
+i
-2]))>>dynamicScale
;
684 qmfBufferReal
[i
][hiBand
] = (lowBandReal
[LPC_ORDER
+i
]>>descale
) + (accu1
<<1);
685 qmfBufferImag
[i
][hiBand
] = (lowBandImag
[LPC_ORDER
+i
]>>descale
) + (accu2
<<1);
690 int descale
= fixMin(DFRACT_BITS
-1, (LPC_SCALE_FACTOR
+dynamicScale
));
692 FDK_ASSERT(dynamicScale
>= 0);
693 for(i
= startSample
; i
< stopSample
; i
++ ) {
696 accu1
= (fMultDiv2(a0r
,lowBandReal
[LPC_ORDER
+i
-1]) + fMultDiv2(a1r
,lowBandReal
[LPC_ORDER
+i
-2]))>>dynamicScale
;
698 qmfBufferReal
[i
][hiBand
] = (lowBandReal
[LPC_ORDER
+i
]>>descale
) + (accu1
<<1);
705 } /* inner loop over patches */
708 * store the unmodified filter coefficients if there is
709 * an overlapping envelope
710 *****************************************************************/
713 } /* outer loop over bands (loBand) */
717 for ( loBand
= pSettings
->lbStartPatching
; loBand
< pSettings
->lbStopPatching
; loBand
++ ) {
719 while ( patch
< pSettings
->noOfPatches
) {
721 UCHAR hiBand
= loBand
+ patchParam
[patch
].targetBandOffs
;
723 if ( loBand
< patchParam
[patch
].sourceStartBand
724 || loBand
>= patchParam
[patch
].sourceStopBand
725 || hiBand
>= (64) /* Highband out of range (biterror) */
727 /* Lowband not in current patch or highband out of range (might be caused by biterrors)- proceed */
732 if(hiBand
!= patchParam
[patch
].targetStartBand
)
733 degreeAlias
[hiBand
] = degreeAlias
[loBand
];
740 for (i
= 0; i
< nInvfBands
; i
++ ) {
741 hLppTrans
->bwVectorOld
[i
] = bwVector
[i
];
745 set high band scale factor
747 sbrScaleFactor
->hb_scale
= comLowBandScale
-(LPC_SCALE_FACTOR
);
753 * \brief Initialize one low power transposer instance
758 createLppTransposer (HANDLE_SBR_LPP_TRANS hs
, /*!< Handle of low power transposer */
759 TRANSPOSER_SETTINGS
*pSettings
, /*!< Pointer to settings */
760 const int highBandStartSb
, /*!< ? */
761 UCHAR
*v_k_master
, /*!< Master table */
762 const int numMaster
, /*!< Valid entries in master table */
763 const int usb
, /*!< Highband area stop subband */
764 const int timeSlots
, /*!< Number of time slots */
765 const int nCols
, /*!< Number of colums (codec qmf bank) */
766 UCHAR
*noiseBandTable
, /*!< Mapping of SBR noise bands to QMF bands */
767 const int noNoiseBands
, /*!< Number of noise bands */
768 UINT fs
, /*!< Sample Frequency */
769 const int chan
, /*!< Channel number */
773 /* FB inverse filtering settings */
774 hs
->pSettings
= pSettings
;
776 pSettings
->nCols
= nCols
;
777 pSettings
->overlap
= overlap
;
786 return SBRDEC_UNSUPPORTED_CONFIG
; /* Unimplemented */
790 /* Init common data only once */
791 hs
->pSettings
->nCols
= nCols
;
793 return resetLppTransposer (hs
,
806 static int findClosestEntry(UCHAR goalSb
, UCHAR
*v_k_master
, UCHAR numMaster
, UCHAR direction
)
810 if( goalSb
<= v_k_master
[0] )
811 return v_k_master
[0];
813 if( goalSb
>= v_k_master
[numMaster
] )
814 return v_k_master
[numMaster
];
818 while( v_k_master
[index
] < goalSb
) {
823 while( v_k_master
[index
] > goalSb
) {
828 return v_k_master
[index
];
834 * \brief Reset memory for one lpp transposer instance
836 * \return SBRDEC_OK on success, SBRDEC_UNSUPPORTED_CONFIG on error
839 resetLppTransposer (HANDLE_SBR_LPP_TRANS hLppTrans
, /*!< Handle of lpp transposer */
840 UCHAR highBandStartSb
, /*!< High band area: start subband */
841 UCHAR
*v_k_master
, /*!< Master table */
842 UCHAR numMaster
, /*!< Valid entries in master table */
843 UCHAR
*noiseBandTable
, /*!< Mapping of SBR noise bands to QMF bands */
844 UCHAR noNoiseBands
, /*!< Number of noise bands */
845 UCHAR usb
, /*!< High band area: stop subband */
846 UINT fs
/*!< SBR output sampling frequency */
849 TRANSPOSER_SETTINGS
*pSettings
= hLppTrans
->pSettings
;
850 PATCH_PARAM
*patchParam
= pSettings
->patchParam
;
858 int lsb
= v_k_master
[0]; /* Start subband expressed in "non-critical" sampling terms*/
859 int xoverOffset
= highBandStartSb
- lsb
; /* Calculate distance in QMF bands between k0 and kx */
864 usb
= fixMin(usb
, v_k_master
[numMaster
]); /* Avoid endless loops (compare with float code). */
870 if ( lsb
- SHIFT_START_SB
< 4 ) {
871 return SBRDEC_UNSUPPORTED_CONFIG
;
876 * Initialize the patching parameter
878 /* ISO/IEC 14496-3 (Figure 4.48): goalSb = round( 2.048e6 / fs ) */
879 desiredBorder
= (((2048000*2) / fs
) + 1) >> 1;
881 desiredBorder
= findClosestEntry(desiredBorder
, v_k_master
, numMaster
, 1); /* Adapt region to master-table */
884 sourceStartBand
= SHIFT_START_SB
+ xoverOffset
;
885 targetStopBand
= lsb
+ xoverOffset
; /* upperBand */
887 /* Even (odd) numbered channel must be patched to even (odd) numbered channel */
889 while(targetStopBand
< usb
) {
892 Allow MAX_NUM_PATCHES+1 patches here.
893 we need to check later again, since patch might be the highest patch
894 AND contain less than 3 bands => actual number of patches will be reduced by 1.
896 if (patch
> MAX_NUM_PATCHES
) {
897 return SBRDEC_UNSUPPORTED_CONFIG
;
900 patchParam
[patch
].guardStartBand
= targetStopBand
;
901 patchParam
[patch
].targetStartBand
= targetStopBand
;
903 numBandsInPatch
= desiredBorder
- targetStopBand
; /* Get the desired range of the patch */
905 if ( numBandsInPatch
>= lsb
- sourceStartBand
) {
906 /* Desired number bands are not available -> patch whole source range */
907 patchDistance
= targetStopBand
- sourceStartBand
; /* Get the targetOffset */
908 patchDistance
= patchDistance
& ~1; /* Rounding off odd numbers and make all even */
909 numBandsInPatch
= lsb
- (targetStopBand
- patchDistance
); /* Update number of bands to be patched */
910 numBandsInPatch
= findClosestEntry(targetStopBand
+ numBandsInPatch
, v_k_master
, numMaster
, 0) -
911 targetStopBand
; /* Adapt region to master-table */
914 /* Desired number bands are available -> get the minimal even patching distance */
915 patchDistance
= numBandsInPatch
+ targetStopBand
- lsb
; /* Get minimal distance */
916 patchDistance
= (patchDistance
+ 1) & ~1; /* Rounding up odd numbers and make all even */
918 if (numBandsInPatch
> 0) {
919 patchParam
[patch
].sourceStartBand
= targetStopBand
- patchDistance
;
920 patchParam
[patch
].targetBandOffs
= patchDistance
;
921 patchParam
[patch
].numBandsInPatch
= numBandsInPatch
;
922 patchParam
[patch
].sourceStopBand
= patchParam
[patch
].sourceStartBand
+ numBandsInPatch
;
924 targetStopBand
+= patchParam
[patch
].numBandsInPatch
;
928 /* All patches but first */
929 sourceStartBand
= SHIFT_START_SB
;
931 /* Check if we are close to desiredBorder */
932 if( desiredBorder
- targetStopBand
< 3) /* MPEG doc */
941 /* If highest patch contains less than three subband: skip it */
942 if ( (patch
>0) && (patchParam
[patch
].numBandsInPatch
< 3) ) {
944 targetStopBand
= patchParam
[patch
].targetStartBand
+ patchParam
[patch
].numBandsInPatch
;
947 /* now check if we don't have one too many */
948 if (patch
>= MAX_NUM_PATCHES
) {
949 return SBRDEC_UNSUPPORTED_CONFIG
;
952 pSettings
->noOfPatches
= patch
+ 1;
954 /* Check lowest and highest source subband */
955 pSettings
->lbStartPatching
= targetStopBand
;
956 pSettings
->lbStopPatching
= 0;
957 for ( patch
= 0; patch
< pSettings
->noOfPatches
; patch
++ ) {
958 pSettings
->lbStartPatching
= fixMin( pSettings
->lbStartPatching
, patchParam
[patch
].sourceStartBand
);
959 pSettings
->lbStopPatching
= fixMax( pSettings
->lbStopPatching
, patchParam
[patch
].sourceStopBand
);
962 for(i
= 0 ; i
< noNoiseBands
; i
++){
963 pSettings
->bwBorders
[i
] = noiseBandTable
[i
+1];
967 * Choose whitening factors
970 startFreqHz
= ( (lsb
+ xoverOffset
)*fs
) >> 7; /* Shift does a division by 2*(64) */
972 for( i
= 1; i
< NUM_WHFACTOR_TABLE_ENTRIES
; i
++ )
974 if( startFreqHz
< FDK_sbrDecoder_sbr_whFactorsIndex
[i
])
979 pSettings
->whFactors
.off
= FDK_sbrDecoder_sbr_whFactorsTable
[i
][0];
980 pSettings
->whFactors
.transitionLevel
= FDK_sbrDecoder_sbr_whFactorsTable
[i
][1];
981 pSettings
->whFactors
.lowLevel
= FDK_sbrDecoder_sbr_whFactorsTable
[i
][2];
982 pSettings
->whFactors
.midLevel
= FDK_sbrDecoder_sbr_whFactorsTable
[i
][3];
983 pSettings
->whFactors
.highLevel
= FDK_sbrDecoder_sbr_whFactorsTable
[i
][4];