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 parametric stereo decoder
93 #include "FDK_bitbuffer.h"
94 #include "psdec_hybrid.h"
99 #include "FDK_tools_rom.h"
101 #include "genericStds.h"
103 #include "FDK_trigFcts.h"
106 /********************************************************************/
108 /********************************************************************/
110 #define FRACT_ZERO FRACT_BITS-1
111 /********************************************************************/
113 SBR_ERROR
ResetPsDec( HANDLE_PS_DEC h_ps_d
);
115 void ResetPsDeCor( HANDLE_PS_DEC h_ps_d
);
118 /***** HELPERS *****/
120 static void assignTimeSlotsPS (FIXP_DBL
*bufAdr
, FIXP_DBL
**bufPtr
, const int numSlots
, const int numChan
);
124 /*******************/
126 #define DIV3 FL2FXCONST_DBL(1.f/3.f) /* division 3.0 */
127 #define DIV1_5 FL2FXCONST_DBL(2.f/3.f) /* division 1.5 */
129 /***************************************************************************/
131 \brief Creates one instance of the PS_DEC struct
135 ****************************************************************************/
137 CreatePsDec( HANDLE_PS_DEC
*h_PS_DEC
, /*!< pointer to the module state */
138 int aacSamplesPerFrame
141 SBR_ERROR errorInfo
= SBRDEC_OK
;
142 HANDLE_PS_DEC h_ps_d
;
145 if (*h_PS_DEC
== NULL
) {
147 h_ps_d
= GetRam_ps_dec();
148 if (h_ps_d
== NULL
) {
149 errorInfo
= SBRDEC_MEM_ALLOC_FAILED
;
153 /* Reset an open instance */
158 switch (aacSamplesPerFrame
) {
160 h_ps_d
->noSubSamples
= 30; /* col */
163 h_ps_d
->noSubSamples
= 32; /* col */
166 h_ps_d
->noSubSamples
= -1;
170 if (h_ps_d
->noSubSamples
> MAX_NUM_COL
171 || h_ps_d
->noSubSamples
<= 0)
175 h_ps_d
->noChannels
= NO_QMF_CHANNELS
; /* row */
177 h_ps_d
->psDecodedPrv
= 0;
178 h_ps_d
->procFrameBased
= -1;
179 for (i
= 0; i
< (1)+1; i
++) {
180 h_ps_d
->bPsDataAvail
[i
] = ppt_none
;
184 for (i
= 0; i
< (1)+1; i
++) {
185 FDKmemclear(&h_ps_d
->bsData
[i
].mpeg
, sizeof(MPEG_PS_BS_DATA
));
188 errorInfo
= ResetPsDec( h_ps_d
);
190 if ( errorInfo
!= SBRDEC_OK
)
193 ResetPsDeCor( h_ps_d
);
202 DeletePsDec(&h_ps_d
);
205 } /*END CreatePsDec */
207 /***************************************************************************/
209 \brief Delete one instance of the PS_DEC struct
213 ****************************************************************************/
215 DeletePsDec( HANDLE_PS_DEC
*h_PS_DEC
) /*!< pointer to the module state */
217 if (*h_PS_DEC
== NULL
) {
222 FreeRam_ps_dec(h_PS_DEC
);
226 } /*END DeletePsDec */
228 /***************************************************************************/
230 \brief resets some values of the PS handle to default states
234 ****************************************************************************/
235 SBR_ERROR
ResetPsDec( HANDLE_PS_DEC h_ps_d
) /*!< pointer to the module state */
237 SBR_ERROR errorInfo
= SBRDEC_OK
;
240 const UCHAR noQmfBandsInHybrid20
= 3;
241 /* const UCHAR noQmfBandsInHybrid34 = 5; */
243 const UCHAR aHybridResolution20
[] = { HYBRID_8_CPLX
,
247 h_ps_d
->specificTo
.mpeg
.delayBufIndex
= 0;
249 /* explicitly init state variables to safe values (until first ps header arrives) */
251 h_ps_d
->specificTo
.mpeg
.lastUsb
= 0;
253 h_ps_d
->specificTo
.mpeg
.scaleFactorPsDelayBuffer
= -(DFRACT_BITS
-1);
255 FDKmemclear(h_ps_d
->specificTo
.mpeg
.aDelayBufIndexDelayQmf
, (NO_QMF_CHANNELS
-FIRST_DELAY_SB
)*sizeof(UCHAR
));
256 h_ps_d
->specificTo
.mpeg
.noSampleDelay
= delayIndexQmf
[0];
258 for (i
=0 ; i
< NO_SERIAL_ALLPASS_LINKS
; i
++) {
259 h_ps_d
->specificTo
.mpeg
.aDelayRBufIndexSer
[i
] = 0;
262 h_ps_d
->specificTo
.mpeg
.pAaRealDelayBufferQmf
[0] = h_ps_d
->specificTo
.mpeg
.aaQmfDelayBufReal
;
264 assignTimeSlotsPS ( h_ps_d
->specificTo
.mpeg
.pAaRealDelayBufferQmf
[0] + (NO_QMF_CHANNELS
-FIRST_DELAY_SB
),
265 &h_ps_d
->specificTo
.mpeg
.pAaRealDelayBufferQmf
[1],
266 h_ps_d
->specificTo
.mpeg
.noSampleDelay
-1,
267 (NO_DELAY_BUFFER_BANDS
-FIRST_DELAY_SB
));
269 h_ps_d
->specificTo
.mpeg
.pAaImagDelayBufferQmf
[0] = h_ps_d
->specificTo
.mpeg
.aaQmfDelayBufImag
;
271 assignTimeSlotsPS ( h_ps_d
->specificTo
.mpeg
.pAaImagDelayBufferQmf
[0] + (NO_QMF_CHANNELS
-FIRST_DELAY_SB
),
272 &h_ps_d
->specificTo
.mpeg
.pAaImagDelayBufferQmf
[1],
273 h_ps_d
->specificTo
.mpeg
.noSampleDelay
-1,
274 (NO_DELAY_BUFFER_BANDS
-FIRST_DELAY_SB
));
276 /* Hybrid Filter Bank 1 creation. */
277 errorInfo
= InitHybridFilterBank ( &h_ps_d
->specificTo
.mpeg
.hybrid
,
278 h_ps_d
->noSubSamples
,
279 noQmfBandsInHybrid20
,
280 aHybridResolution20
);
282 for ( i
= 0; i
< NO_IID_GROUPS
; i
++ )
284 h_ps_d
->specificTo
.mpeg
.h11rPrev
[i
] = FL2FXCONST_DBL(0.5f
);
285 h_ps_d
->specificTo
.mpeg
.h12rPrev
[i
] = FL2FXCONST_DBL(0.5f
);
288 FDKmemclear( h_ps_d
->specificTo
.mpeg
.h21rPrev
, sizeof( h_ps_d
->specificTo
.mpeg
.h21rPrev
) );
289 FDKmemclear( h_ps_d
->specificTo
.mpeg
.h22rPrev
, sizeof( h_ps_d
->specificTo
.mpeg
.h22rPrev
) );
294 /***************************************************************************/
296 \brief clear some buffers used in decorrelation process
300 ****************************************************************************/
301 void ResetPsDeCor( HANDLE_PS_DEC h_ps_d
) /*!< pointer to the module state */
305 FDKmemclear(h_ps_d
->specificTo
.mpeg
.aPeakDecayFastBin
, NO_MID_RES_BINS
*sizeof(FIXP_DBL
));
306 FDKmemclear(h_ps_d
->specificTo
.mpeg
.aPrevNrgBin
, NO_MID_RES_BINS
*sizeof(FIXP_DBL
));
307 FDKmemclear(h_ps_d
->specificTo
.mpeg
.aPrevPeakDiffBin
, NO_MID_RES_BINS
*sizeof(FIXP_DBL
));
308 FDKmemclear(h_ps_d
->specificTo
.mpeg
.aPowerPrevScal
, NO_MID_RES_BINS
*sizeof(SCHAR
));
310 for (i
=0 ; i
< FIRST_DELAY_SB
; i
++) {
311 FDKmemclear(h_ps_d
->specificTo
.mpeg
.aaaRealDelayRBufferSerQmf
[i
], NO_DELAY_LENGTH_VECTORS
*sizeof(FIXP_DBL
));
312 FDKmemclear(h_ps_d
->specificTo
.mpeg
.aaaImagDelayRBufferSerQmf
[i
], NO_DELAY_LENGTH_VECTORS
*sizeof(FIXP_DBL
));
314 for (i
=0 ; i
< NO_SUB_QMF_CHANNELS
; i
++) {
315 FDKmemclear(h_ps_d
->specificTo
.mpeg
.aaaRealDelayRBufferSerSubQmf
[i
], NO_DELAY_LENGTH_VECTORS
*sizeof(FIXP_DBL
));
316 FDKmemclear(h_ps_d
->specificTo
.mpeg
.aaaImagDelayRBufferSerSubQmf
[i
], NO_DELAY_LENGTH_VECTORS
*sizeof(FIXP_DBL
));
321 /*******************************************************************************/
323 /* slot based funcion prototypes */
325 static void deCorrelateSlotBased( HANDLE_PS_DEC h_ps_d
,
327 FIXP_DBL
*mHybridRealLeft
,
328 FIXP_DBL
*mHybridImagLeft
,
329 SCHAR sf_mHybridLeft
,
331 FIXP_DBL
*rIntBufferLeft
,
332 FIXP_DBL
*iIntBufferLeft
,
335 FIXP_DBL
*mHybridRealRight
,
336 FIXP_DBL
*mHybridImagRight
,
338 FIXP_DBL
*rIntBufferRight
,
339 FIXP_DBL
*iIntBufferRight
);
341 static void applySlotBasedRotation( HANDLE_PS_DEC h_ps_d
,
343 FIXP_DBL
*mHybridRealLeft
,
344 FIXP_DBL
*mHybridImagLeft
,
346 FIXP_DBL
*QmfLeftReal
,
347 FIXP_DBL
*QmfLeftImag
,
349 FIXP_DBL
*mHybridRealRight
,
350 FIXP_DBL
*mHybridImagRight
,
352 FIXP_DBL
*QmfRightReal
,
353 FIXP_DBL
*QmfRightImag
357 /***************************************************************************/
359 \brief Get scale factor for all ps delay buffer.
363 ****************************************************************************/
365 int getScaleFactorPsStatesBuffer(HANDLE_PS_DEC h_ps_d
)
368 int scale
= DFRACT_BITS
-1;
370 for (i
=0; i
<NO_QMF_BANDS_HYBRID20
; i
++) {
371 scale
= fMin(scale
, getScalefactor(h_ps_d
->specificTo
.mpeg
.hybrid
.mQmfBufferRealSlot
[i
], NO_SUB_QMF_CHANNELS
));
372 scale
= fMin(scale
, getScalefactor(h_ps_d
->specificTo
.mpeg
.hybrid
.mQmfBufferImagSlot
[i
], NO_SUB_QMF_CHANNELS
));
375 for (i
=0; i
<NO_SAMPLE_DELAY_ALLPASS
; i
++) {
376 scale
= fMin(scale
, getScalefactor(h_ps_d
->specificTo
.mpeg
.aaRealDelayBufferQmf
[i
], FIRST_DELAY_SB
));
377 scale
= fMin(scale
, getScalefactor(h_ps_d
->specificTo
.mpeg
.aaImagDelayBufferQmf
[i
], FIRST_DELAY_SB
));
380 for (i
=0; i
<NO_SAMPLE_DELAY_ALLPASS
; i
++) {
381 scale
= fMin(scale
, getScalefactor(h_ps_d
->specificTo
.mpeg
.aaRealDelayBufferSubQmf
[i
], NO_SUB_QMF_CHANNELS
));
382 scale
= fMin(scale
, getScalefactor(h_ps_d
->specificTo
.mpeg
.aaImagDelayBufferSubQmf
[i
], NO_SUB_QMF_CHANNELS
));
385 for (i
=0; i
<FIRST_DELAY_SB
; i
++) {
386 scale
= fMin(scale
, getScalefactor(h_ps_d
->specificTo
.mpeg
.aaaRealDelayRBufferSerQmf
[i
], NO_DELAY_LENGTH_VECTORS
));
387 scale
= fMin(scale
, getScalefactor(h_ps_d
->specificTo
.mpeg
.aaaImagDelayRBufferSerQmf
[i
], NO_DELAY_LENGTH_VECTORS
));
390 for (i
=0; i
<NO_SUB_QMF_CHANNELS
; i
++) {
391 scale
= fMin(scale
, getScalefactor(h_ps_d
->specificTo
.mpeg
.aaaRealDelayRBufferSerSubQmf
[i
], NO_DELAY_LENGTH_VECTORS
));
392 scale
= fMin(scale
, getScalefactor(h_ps_d
->specificTo
.mpeg
.aaaImagDelayRBufferSerSubQmf
[i
], NO_DELAY_LENGTH_VECTORS
));
395 for (i
=0; i
<MAX_DELAY_BUFFER_SIZE
; i
++)
399 len
= NO_QMF_CHANNELS
-FIRST_DELAY_SB
;
401 len
= NO_DELAY_BUFFER_BANDS
-FIRST_DELAY_SB
;
403 scale
= fMin(scale
, getScalefactor(h_ps_d
->specificTo
.mpeg
.pAaRealDelayBufferQmf
[i
], len
));
404 scale
= fMin(scale
, getScalefactor(h_ps_d
->specificTo
.mpeg
.pAaImagDelayBufferQmf
[i
], len
));
410 /***************************************************************************/
412 \brief Rescale all ps delay buffer.
416 ****************************************************************************/
418 void scalePsStatesBuffer(HANDLE_PS_DEC h_ps_d
,
424 scale
= fixMax((INT
)scale
,(INT
)-(DFRACT_BITS
-1));
426 scale
= fixMin((INT
)scale
,(INT
)DFRACT_BITS
-1);
428 for (i
=0; i
<NO_QMF_BANDS_HYBRID20
; i
++) {
429 scaleValues( h_ps_d
->specificTo
.mpeg
.hybrid
.mQmfBufferRealSlot
[i
], NO_SUB_QMF_CHANNELS
, scale
);
430 scaleValues( h_ps_d
->specificTo
.mpeg
.hybrid
.mQmfBufferImagSlot
[i
], NO_SUB_QMF_CHANNELS
, scale
);
433 for (i
=0; i
<NO_SAMPLE_DELAY_ALLPASS
; i
++) {
434 scaleValues( h_ps_d
->specificTo
.mpeg
.aaRealDelayBufferQmf
[i
], FIRST_DELAY_SB
, scale
);
435 scaleValues( h_ps_d
->specificTo
.mpeg
.aaImagDelayBufferQmf
[i
], FIRST_DELAY_SB
, scale
);
438 for (i
=0; i
<NO_SAMPLE_DELAY_ALLPASS
; i
++) {
439 scaleValues( h_ps_d
->specificTo
.mpeg
.aaRealDelayBufferSubQmf
[i
], NO_SUB_QMF_CHANNELS
, scale
);
440 scaleValues( h_ps_d
->specificTo
.mpeg
.aaImagDelayBufferSubQmf
[i
], NO_SUB_QMF_CHANNELS
, scale
);
443 for (i
=0; i
<FIRST_DELAY_SB
; i
++) {
444 scaleValues( h_ps_d
->specificTo
.mpeg
.aaaRealDelayRBufferSerQmf
[i
], NO_DELAY_LENGTH_VECTORS
, scale
);
445 scaleValues( h_ps_d
->specificTo
.mpeg
.aaaImagDelayRBufferSerQmf
[i
], NO_DELAY_LENGTH_VECTORS
, scale
);
448 for (i
=0; i
<NO_SUB_QMF_CHANNELS
; i
++) {
449 scaleValues( h_ps_d
->specificTo
.mpeg
.aaaRealDelayRBufferSerSubQmf
[i
], NO_DELAY_LENGTH_VECTORS
, scale
);
450 scaleValues( h_ps_d
->specificTo
.mpeg
.aaaImagDelayRBufferSerSubQmf
[i
], NO_DELAY_LENGTH_VECTORS
, scale
);
453 for (i
=0; i
<MAX_DELAY_BUFFER_SIZE
; i
++) {
456 len
= NO_QMF_CHANNELS
-FIRST_DELAY_SB
;
458 len
= NO_DELAY_BUFFER_BANDS
-FIRST_DELAY_SB
;
460 scaleValues( h_ps_d
->specificTo
.mpeg
.pAaRealDelayBufferQmf
[i
], len
, scale
);
461 scaleValues( h_ps_d
->specificTo
.mpeg
.pAaImagDelayBufferQmf
[i
], len
, scale
);
466 scaleValues( h_ps_d
->specificTo
.mpeg
.aPeakDecayFastBin
, NO_MID_RES_BINS
, scale
);
467 scaleValues( h_ps_d
->specificTo
.mpeg
.aPrevPeakDiffBin
, NO_MID_RES_BINS
, scale
);
468 scaleValues( h_ps_d
->specificTo
.mpeg
.aPrevNrgBin
, NO_MID_RES_BINS
, scale
);
471 /***************************************************************************/
473 \brief Scale input channel to the same scalefactor and rescale hybrid
478 ****************************************************************************/
480 void scalFilterBankValues( HANDLE_PS_DEC h_ps_d
,
481 FIXP_DBL
**fixpQmfReal
,
482 FIXP_DBL
**fixpQmfImag
,
484 int scaleFactorLowBandSplitLow
,
485 int scaleFactorLowBandSplitHigh
,
486 SCHAR
*scaleFactorLowBand_lb
,
487 SCHAR
*scaleFactorLowBand_hb
,
488 int scaleFactorHighBands
,
489 INT
*scaleFactorHighBand
,
497 scaleFactorHighBands
= -scaleFactorHighBands
;
498 scaleFactorLowBandSplitLow
= -scaleFactorLowBandSplitLow
;
499 scaleFactorLowBandSplitHigh
= -scaleFactorLowBandSplitHigh
;
501 /* get max scale factor */
502 maxScal
= fixMax(scaleFactorHighBands
,fixMax(scaleFactorLowBandSplitLow
, scaleFactorLowBandSplitHigh
));
505 int headroom
= getScaleFactorPsStatesBuffer(h_ps_d
);
506 maxScal
= fixMax(maxScal
,(INT
)(h_ps_d
->specificTo
.mpeg
.scaleFactorPsDelayBuffer
-headroom
));
510 /* scale whole left channel to the same scale factor */
512 /* low band ( overlap buffer ) */
513 if ( maxScal
!= scaleFactorLowBandSplitLow
) {
514 INT scale
= scaleFactorLowBandSplitLow
- maxScal
;
515 for ( i
=0; i
<(6); i
++ ) {
516 scaleValues( fixpQmfReal
[i
], lsb
, scale
);
517 scaleValues( fixpQmfImag
[i
], lsb
, scale
);
520 /* low band ( current frame ) */
521 if ( maxScal
!= scaleFactorLowBandSplitHigh
) {
522 INT scale
= scaleFactorLowBandSplitHigh
- maxScal
;
523 /* for ( i=(6); i<(6)+MAX_NUM_COL; i++ ) { */
524 for ( i
=(6); i
<(6)+noCols
; i
++ ) {
525 scaleValues( fixpQmfReal
[i
], lsb
, scale
);
526 scaleValues( fixpQmfImag
[i
], lsb
, scale
);
530 if ( maxScal
!= scaleFactorHighBands
) {
531 INT scale
= scaleFactorHighBands
- maxScal
;
532 /* for ( i=0; i<MAX_NUM_COL; i++ ) { */
533 for ( i
=0; i
<noCols
; i
++ ) {
534 scaleValues( &fixpQmfReal
[i
][lsb
], (64)-lsb
, scale
);
535 scaleValues( &fixpQmfImag
[i
][lsb
], (64)-lsb
, scale
);
539 if ( maxScal
!= h_ps_d
->specificTo
.mpeg
.scaleFactorPsDelayBuffer
)
540 scalePsStatesBuffer(h_ps_d
,(h_ps_d
->specificTo
.mpeg
.scaleFactorPsDelayBuffer
-maxScal
));
542 h_ps_d
->specificTo
.mpeg
.hybrid
.sf_mQmfBuffer
= maxScal
;
543 h_ps_d
->specificTo
.mpeg
.scaleFactorPsDelayBuffer
= maxScal
;
545 *scaleFactorHighBand
+= maxScal
- scaleFactorHighBands
;
547 h_ps_d
->rescal
= maxScal
- scaleFactorLowBandSplitHigh
;
548 h_ps_d
->sf_IntBuffer
= maxScal
;
550 *scaleFactorLowBand_lb
+= maxScal
- scaleFactorLowBandSplitLow
;
551 *scaleFactorLowBand_hb
+= maxScal
- scaleFactorLowBandSplitHigh
;
554 void rescalFilterBankValues( HANDLE_PS_DEC h_ps_d
, /* parametric stereo decoder handle */
555 FIXP_DBL
**QmfBufferReal
, /* qmf filterbank values */
556 FIXP_DBL
**QmfBufferImag
, /* qmf filterbank values */
557 int lsb
, /* sbr start subband */
561 /* scale back 6 timeslots look ahead for hybrid filterbank to original value */
562 for ( i
=noCols
; i
<noCols
+ (6); i
++ ) {
563 scaleValues( QmfBufferReal
[i
], lsb
, h_ps_d
->rescal
);
564 scaleValues( QmfBufferImag
[i
], lsb
, h_ps_d
->rescal
);
568 /***************************************************************************/
570 \brief Generate decorrelated side channel using allpass/delay
574 ****************************************************************************/
576 deCorrelateSlotBased( HANDLE_PS_DEC h_ps_d
, /*!< pointer to the module state */
578 FIXP_DBL
*mHybridRealLeft
, /*!< left (mono) hybrid values real */
579 FIXP_DBL
*mHybridImagLeft
, /*!< left (mono) hybrid values imag */
580 SCHAR sf_mHybridLeft
, /*!< scalefactor for left (mono) hybrid bands */
582 FIXP_DBL
*rIntBufferLeft
, /*!< real qmf bands left (mono) (38x64) */
583 FIXP_DBL
*iIntBufferLeft
, /*!< real qmf bands left (mono) (38x64) */
584 SCHAR sf_IntBuffer
, /*!< scalefactor for all left and right qmf bands */
586 FIXP_DBL
*mHybridRealRight
, /*!< right (decorrelated) hybrid values real */
587 FIXP_DBL
*mHybridImagRight
, /*!< right (decorrelated) hybrid values imag */
589 FIXP_DBL
*rIntBufferRight
, /*!< real qmf bands right (decorrelated) (38x64) */
590 FIXP_DBL
*iIntBufferRight
) /*!< real qmf bands right (decorrelated) (38x64) */
593 INT i
, m
, sb
, gr
, bin
;
595 FIXP_DBL peakDiff
, nrg
, transRatio
;
597 FIXP_DBL
*RESTRICT aaLeftReal
;
598 FIXP_DBL
*RESTRICT aaLeftImag
;
600 FIXP_DBL
*RESTRICT aaRightReal
;
601 FIXP_DBL
*RESTRICT aaRightImag
;
603 FIXP_DBL
*RESTRICT pRealDelayBuffer
;
604 FIXP_DBL
*RESTRICT pImagDelayBuffer
;
606 C_ALLOC_SCRATCH_START(aaPowerSlot
, FIXP_DBL
, NO_MID_RES_BINS
);
607 C_ALLOC_SCRATCH_START(aaTransRatioSlot
, FIXP_DBL
, NO_MID_RES_BINS
);
611 parameter index qmf bands hybrid bands
612 ----------------------------------------------------------------------------
621 ----------------------------------------------------------------------------
628 14 9,10 (2 ) QMF BANDS
634 ----------------------------------------------------------------------------
640 /* hybrid bands (parameter index 0 - 7) */
641 aaLeftReal
= mHybridRealLeft
;
642 aaLeftImag
= mHybridImagLeft
;
644 aaPowerSlot
[0] = ( fMultAddDiv2( fMultDiv2(aaLeftReal
[0], aaLeftReal
[0]), aaLeftImag
[0], aaLeftImag
[0] ) >> FLTR_SCALE
) +
645 ( fMultAddDiv2( fMultDiv2(aaLeftReal
[7], aaLeftReal
[7]), aaLeftImag
[7], aaLeftImag
[7] ) >> FLTR_SCALE
);
647 aaPowerSlot
[1] = ( fMultAddDiv2( fMultDiv2(aaLeftReal
[1], aaLeftReal
[1]), aaLeftImag
[1], aaLeftImag
[1] ) >> FLTR_SCALE
) +
648 ( fMultAddDiv2( fMultDiv2(aaLeftReal
[6], aaLeftReal
[6]), aaLeftImag
[6], aaLeftImag
[6] ) >> FLTR_SCALE
);
650 aaPowerSlot
[2] = fMultAddDiv2( fMultDiv2(aaLeftReal
[2], aaLeftReal
[2]), aaLeftImag
[2], aaLeftImag
[2] ) >> FLTR_SCALE
;
651 aaPowerSlot
[3] = fMultAddDiv2( fMultDiv2(aaLeftReal
[3], aaLeftReal
[3]), aaLeftImag
[3], aaLeftImag
[3] ) >> FLTR_SCALE
;
653 aaPowerSlot
[4] = fMultAddDiv2( fMultDiv2(aaLeftReal
[9], aaLeftReal
[9]), aaLeftImag
[9], aaLeftImag
[9] ) >> FLTR_SCALE
;
654 aaPowerSlot
[5] = fMultAddDiv2( fMultDiv2(aaLeftReal
[8], aaLeftReal
[8]), aaLeftImag
[8], aaLeftImag
[8] ) >> FLTR_SCALE
;
656 aaPowerSlot
[6] = fMultAddDiv2( fMultDiv2(aaLeftReal
[10], aaLeftReal
[10]), aaLeftImag
[10], aaLeftImag
[10] ) >> FLTR_SCALE
;
657 aaPowerSlot
[7] = fMultAddDiv2( fMultDiv2(aaLeftReal
[11], aaLeftReal
[11]), aaLeftImag
[11], aaLeftImag
[11] ) >> FLTR_SCALE
;
659 /* qmf bands (parameter index 8 - 19) */
660 for ( bin
= 8; bin
< NO_MID_RES_BINS
; bin
++ ) {
661 FIXP_DBL slotNrg
= FL2FXCONST_DBL(0.f
);
663 for ( i
= groupBorders20
[bin
+2]; i
< groupBorders20
[bin
+3]; i
++ ) { /* max loops: 29 */
664 slotNrg
+= fMultAddDiv2 ( fMultDiv2(rIntBufferLeft
[i
], rIntBufferLeft
[i
]), iIntBufferLeft
[i
], iIntBufferLeft
[i
]) >> FLTR_SCALE
;
666 aaPowerSlot
[bin
] = slotNrg
;
671 /* calculation of transient ratio */
672 for (bin
=0; bin
< NO_MID_RES_BINS
; bin
++) { /* noBins = 20 ( BASELINE_PS ) */
674 h_ps_d
->specificTo
.mpeg
.aPeakDecayFastBin
[bin
] = fMult( h_ps_d
->specificTo
.mpeg
.aPeakDecayFastBin
[bin
], PEAK_DECAY_FACTOR
);
676 if (h_ps_d
->specificTo
.mpeg
.aPeakDecayFastBin
[bin
] < aaPowerSlot
[bin
]) {
677 h_ps_d
->specificTo
.mpeg
.aPeakDecayFastBin
[bin
] = aaPowerSlot
[bin
];
680 /* calculate PSmoothPeakDecayDiffNrg */
681 peakDiff
= fMultAdd ( (h_ps_d
->specificTo
.mpeg
.aPrevPeakDiffBin
[bin
]>>1),
682 INT_FILTER_COEFF
, h_ps_d
->specificTo
.mpeg
.aPeakDecayFastBin
[bin
] - aaPowerSlot
[bin
] - h_ps_d
->specificTo
.mpeg
.aPrevPeakDiffBin
[bin
]);
684 /* save peakDiff for the next frame */
685 h_ps_d
->specificTo
.mpeg
.aPrevPeakDiffBin
[bin
] = peakDiff
;
687 nrg
= h_ps_d
->specificTo
.mpeg
.aPrevNrgBin
[bin
] + fMult( INT_FILTER_COEFF
, aaPowerSlot
[bin
] - h_ps_d
->specificTo
.mpeg
.aPrevNrgBin
[bin
] );
689 /* Negative energies don't exist. But sometimes they appear due to rounding. */
691 nrg
= fixMax(nrg
,FL2FXCONST_DBL(0.f
));
693 /* save nrg for the next frame */
694 h_ps_d
->specificTo
.mpeg
.aPrevNrgBin
[bin
] = nrg
;
696 nrg
= fMult( nrg
, TRANSIENT_IMPACT_FACTOR
);
698 /* save transient impact factor */
699 if ( peakDiff
<= nrg
|| peakDiff
== FL2FXCONST_DBL(0.0) ) {
700 aaTransRatioSlot
[bin
] = (FIXP_DBL
)MAXVAL_DBL
/* FL2FXCONST_DBL(1.0f)*/;
702 else if ( nrg
<= FL2FXCONST_DBL(0.0f
) ) {
703 aaTransRatioSlot
[bin
] = FL2FXCONST_DBL(0.f
);
706 /* scale to denominator */
707 INT scale_left
= fixMax(0, CntLeadingZeros(peakDiff
) - 1);
708 aaTransRatioSlot
[bin
] = schur_div( nrg
<<scale_left
, peakDiff
<<scale_left
, 16);
715 #define DELAY_GROUP_OFFSET 20
716 #define NR_OF_DELAY_GROUPS 2
718 FIXP_DBL rTmp
, iTmp
, rTmp0
, iTmp0
, rR0
, iR0
;
720 INT TempDelay
= h_ps_d
->specificTo
.mpeg
.delayBufIndex
; /* set delay indices */
722 pRealDelayBuffer
= h_ps_d
->specificTo
.mpeg
.aaRealDelayBufferSubQmf
[TempDelay
];
723 pImagDelayBuffer
= h_ps_d
->specificTo
.mpeg
.aaImagDelayBufferSubQmf
[TempDelay
];
725 aaLeftReal
= mHybridRealLeft
;
726 aaLeftImag
= mHybridImagLeft
;
727 aaRightReal
= mHybridRealRight
;
728 aaRightImag
= mHybridImagRight
;
730 /************************/
731 /* ICC groups : 0 - 9 */
732 /************************/
734 /* gr = ICC groups */
735 for (gr
=0; gr
< SUBQMF_GROUPS
; gr
++) {
737 transRatio
= aaTransRatioSlot
[bins2groupMap20
[gr
]];
739 /* sb = subQMF/QMF subband */
740 sb
= groupBorders20
[gr
];
742 /* Update delay buffers, sample delay allpass = 2 */
743 rTmp0
= pRealDelayBuffer
[sb
];
744 iTmp0
= pImagDelayBuffer
[sb
];
746 pRealDelayBuffer
[sb
] = aaLeftReal
[sb
];
747 pImagDelayBuffer
[sb
] = aaLeftImag
[sb
];
749 /* delay by fraction */
750 cplxMultDiv2(&rR0
, &iR0
, rTmp0
, iTmp0
, aaFractDelayPhaseFactorReSubQmf20
[sb
], aaFractDelayPhaseFactorImSubQmf20
[sb
]);
754 FIXP_DBL
*pAaaRealDelayRBufferSerSubQmf
= h_ps_d
->specificTo
.mpeg
.aaaRealDelayRBufferSerSubQmf
[sb
];
755 FIXP_DBL
*pAaaImagDelayRBufferSerSubQmf
= h_ps_d
->specificTo
.mpeg
.aaaImagDelayRBufferSerSubQmf
[sb
];
757 for (m
=0; m
<NO_SERIAL_ALLPASS_LINKS
; m
++) {
759 INT tmpDelayRSer
= h_ps_d
->specificTo
.mpeg
.aDelayRBufIndexSer
[m
];
761 /* get delayed values from according buffer : m(0)=3; m(1)=4; m(2)=5; */
762 rTmp0
= pAaaRealDelayRBufferSerSubQmf
[tmpDelayRSer
];
763 iTmp0
= pAaaImagDelayRBufferSerSubQmf
[tmpDelayRSer
];
765 /* delay by fraction */
766 cplxMultDiv2(&rTmp
, &iTmp
, rTmp0
, iTmp0
, aaFractDelayPhaseFactorSerReSubQmf20
[sb
][m
], aaFractDelayPhaseFactorSerImSubQmf20
[sb
][m
]);
768 rTmp
= (rTmp
- fMultDiv2(aAllpassLinkDecaySer
[m
], rR0
)) << 1;
769 iTmp
= (iTmp
- fMultDiv2(aAllpassLinkDecaySer
[m
], iR0
)) << 1;
771 pAaaRealDelayRBufferSerSubQmf
[tmpDelayRSer
] = rR0
+ fMult(aAllpassLinkDecaySer
[m
], rTmp
);
772 pAaaImagDelayRBufferSerSubQmf
[tmpDelayRSer
] = iR0
+ fMult(aAllpassLinkDecaySer
[m
], iTmp
);
777 pAaaRealDelayRBufferSerSubQmf
+= aAllpassLinkDelaySer
[m
];
778 pAaaImagDelayRBufferSerSubQmf
+= aAllpassLinkDelaySer
[m
];
782 /* duck if a past transient is found */
783 aaRightReal
[sb
] = fMult(transRatio
, rR0
);
784 aaRightImag
[sb
] = fMult(transRatio
, iR0
);
789 scaleValues( mHybridRealLeft
, NO_SUB_QMF_CHANNELS
, -SCAL_HEADROOM
);
790 scaleValues( mHybridImagLeft
, NO_SUB_QMF_CHANNELS
, -SCAL_HEADROOM
);
791 scaleValues( mHybridRealRight
, NO_SUB_QMF_CHANNELS
, -SCAL_HEADROOM
);
792 scaleValues( mHybridImagRight
, NO_SUB_QMF_CHANNELS
, -SCAL_HEADROOM
);
795 /************************/
797 aaLeftReal
= rIntBufferLeft
;
798 aaLeftImag
= iIntBufferLeft
;
799 aaRightReal
= rIntBufferRight
;
800 aaRightImag
= iIntBufferRight
;
802 pRealDelayBuffer
= h_ps_d
->specificTo
.mpeg
.aaRealDelayBufferQmf
[TempDelay
];
803 pImagDelayBuffer
= h_ps_d
->specificTo
.mpeg
.aaImagDelayBufferQmf
[TempDelay
];
805 /************************/
806 /* ICC groups : 10 - 19 */
807 /************************/
810 /* gr = ICC groups */
811 for (gr
=SUBQMF_GROUPS
; gr
< NO_IID_GROUPS
- NR_OF_DELAY_GROUPS
; gr
++) {
813 transRatio
= aaTransRatioSlot
[bins2groupMap20
[gr
]];
815 /* sb = subQMF/QMF subband */
816 for (sb
= groupBorders20
[gr
]; sb
< groupBorders20
[gr
+1]; sb
++) {
819 /* decayScaleFactor = 1.0f + decay_cutoff * DECAY_SLOPE - DECAY_SLOPE * sb; DECAY_SLOPE = 0.05 */
820 FIXP_DBL decayScaleFactor
= decayScaleFactTable
[sb
];
822 /* Update delay buffers, sample delay allpass = 2 */
823 rTmp0
= pRealDelayBuffer
[sb
];
824 iTmp0
= pImagDelayBuffer
[sb
];
826 pRealDelayBuffer
[sb
] = aaLeftReal
[sb
];
827 pImagDelayBuffer
[sb
] = aaLeftImag
[sb
];
829 /* delay by fraction */
830 cplxMultDiv2(&rR0
, &iR0
, rTmp0
, iTmp0
, aaFractDelayPhaseFactorReQmf
[sb
], aaFractDelayPhaseFactorImQmf
[sb
]);
834 resR
= fMult(decayScaleFactor
, rR0
);
835 resI
= fMult(decayScaleFactor
, iR0
);
837 FIXP_DBL
*pAaaRealDelayRBufferSerQmf
= h_ps_d
->specificTo
.mpeg
.aaaRealDelayRBufferSerQmf
[sb
];
838 FIXP_DBL
*pAaaImagDelayRBufferSerQmf
= h_ps_d
->specificTo
.mpeg
.aaaImagDelayRBufferSerQmf
[sb
];
840 for (m
=0; m
<NO_SERIAL_ALLPASS_LINKS
; m
++) {
842 INT tmpDelayRSer
= h_ps_d
->specificTo
.mpeg
.aDelayRBufIndexSer
[m
];
844 /* get delayed values from according buffer : m(0)=3; m(1)=4; m(2)=5; */
845 rTmp0
= pAaaRealDelayRBufferSerQmf
[tmpDelayRSer
];
846 iTmp0
= pAaaImagDelayRBufferSerQmf
[tmpDelayRSer
];
848 /* delay by fraction */
849 cplxMultDiv2(&rTmp
, &iTmp
, rTmp0
, iTmp0
, aaFractDelayPhaseFactorSerReQmf
[sb
][m
], aaFractDelayPhaseFactorSerImQmf
[sb
][m
]);
851 rTmp
= (rTmp
- fMultDiv2(aAllpassLinkDecaySer
[m
], resR
))<<1;
852 iTmp
= (iTmp
- fMultDiv2(aAllpassLinkDecaySer
[m
], resI
))<<1;
854 resR
= fMult(decayScaleFactor
, rTmp
);
855 resI
= fMult(decayScaleFactor
, iTmp
);
857 pAaaRealDelayRBufferSerQmf
[tmpDelayRSer
] = rR0
+ fMult(aAllpassLinkDecaySer
[m
], resR
);
858 pAaaImagDelayRBufferSerQmf
[tmpDelayRSer
] = iR0
+ fMult(aAllpassLinkDecaySer
[m
], resI
);
863 pAaaRealDelayRBufferSerQmf
+= aAllpassLinkDelaySer
[m
];
864 pAaaImagDelayRBufferSerQmf
+= aAllpassLinkDelaySer
[m
];
868 /* duck if a past transient is found */
869 aaRightReal
[sb
] = fMult(transRatio
, rR0
);
870 aaRightImag
[sb
] = fMult(transRatio
, iR0
);
875 /************************/
876 /* ICC groups : 20, 21 */
877 /************************/
880 /* gr = ICC groups */
881 for (gr
=DELAY_GROUP_OFFSET
; gr
< NO_IID_GROUPS
; gr
++) {
883 INT sbStart
= groupBorders20
[gr
];
884 INT sbStop
= groupBorders20
[gr
+1];
886 UCHAR
*pDelayBufIdx
= &h_ps_d
->specificTo
.mpeg
.aDelayBufIndexDelayQmf
[sbStart
-FIRST_DELAY_SB
];
888 transRatio
= aaTransRatioSlot
[bins2groupMap20
[gr
]];
890 /* sb = subQMF/QMF subband */
891 for (sb
= sbStart
; sb
< sbStop
; sb
++) {
893 /* Update delay buffers */
894 rR0
= h_ps_d
->specificTo
.mpeg
.pAaRealDelayBufferQmf
[*pDelayBufIdx
][sb
-FIRST_DELAY_SB
];
895 iR0
= h_ps_d
->specificTo
.mpeg
.pAaImagDelayBufferQmf
[*pDelayBufIdx
][sb
-FIRST_DELAY_SB
];
897 h_ps_d
->specificTo
.mpeg
.pAaRealDelayBufferQmf
[*pDelayBufIdx
][sb
-FIRST_DELAY_SB
] = aaLeftReal
[sb
];
898 h_ps_d
->specificTo
.mpeg
.pAaImagDelayBufferQmf
[*pDelayBufIdx
][sb
-FIRST_DELAY_SB
] = aaLeftImag
[sb
];
900 /* duck if a past transient is found */
901 aaRightReal
[sb
] = fMult(transRatio
, rR0
);
902 aaRightImag
[sb
] = fMult(transRatio
, iR0
);
904 if (++(*pDelayBufIdx
) >= delayIndexQmf
[sb
]) {
913 /* Update delay buffer index */
914 if (++h_ps_d
->specificTo
.mpeg
.delayBufIndex
>= NO_SAMPLE_DELAY_ALLPASS
)
915 h_ps_d
->specificTo
.mpeg
.delayBufIndex
= 0;
917 for (m
=0; m
<NO_SERIAL_ALLPASS_LINKS
; m
++) {
918 if (++h_ps_d
->specificTo
.mpeg
.aDelayRBufIndexSer
[m
] >= aAllpassLinkDelaySer
[m
])
919 h_ps_d
->specificTo
.mpeg
.aDelayRBufIndexSer
[m
] = 0;
923 scaleValues( &rIntBufferLeft
[NO_QMF_BANDS_HYBRID20
], NO_QMF_CHANNELS
-NO_QMF_BANDS_HYBRID20
, -SCAL_HEADROOM
);
924 scaleValues( &iIntBufferLeft
[NO_QMF_BANDS_HYBRID20
], NO_QMF_CHANNELS
-NO_QMF_BANDS_HYBRID20
, -SCAL_HEADROOM
);
925 scaleValues( &rIntBufferRight
[NO_QMF_BANDS_HYBRID20
], NO_QMF_CHANNELS
-NO_QMF_BANDS_HYBRID20
, -SCAL_HEADROOM
);
926 scaleValues( &iIntBufferRight
[NO_QMF_BANDS_HYBRID20
], NO_QMF_CHANNELS
-NO_QMF_BANDS_HYBRID20
, -SCAL_HEADROOM
);
928 /* free memory on scratch */
929 C_ALLOC_SCRATCH_END(aaTransRatioSlot
, FIXP_DBL
, NO_MID_RES_BINS
);
930 C_ALLOC_SCRATCH_END(aaPowerSlot
, FIXP_DBL
, NO_MID_RES_BINS
);
934 void initSlotBasedRotation( HANDLE_PS_DEC h_ps_d
, /*!< pointer to the module state */
943 /* const UCHAR *pQuantizedIIDs;*/
946 FIXP_DBL ScaleL
, ScaleR
;
947 FIXP_DBL Alpha
, Beta
;
948 FIXP_DBL h11r
, h12r
, h21r
, h22r
;
950 const FIXP_DBL
*PScaleFactors
;
952 /* Overwrite old values in delay buffers when upper subband is higher than in last frame */
955 if ((usb
> h_ps_d
->specificTo
.mpeg
.lastUsb
) && h_ps_d
->specificTo
.mpeg
.lastUsb
) {
959 for (i
=h_ps_d
->specificTo
.mpeg
.lastUsb
; i
< FIRST_DELAY_SB
; i
++) {
960 FDKmemclear(h_ps_d
->specificTo
.mpeg
.aaaRealDelayRBufferSerQmf
[i
], NO_DELAY_LENGTH_VECTORS
*sizeof(FIXP_DBL
));
961 FDKmemclear(h_ps_d
->specificTo
.mpeg
.aaaImagDelayRBufferSerQmf
[i
], NO_DELAY_LENGTH_VECTORS
*sizeof(FIXP_DBL
));
964 for (k
=0 ; k
<NO_SAMPLE_DELAY_ALLPASS
; k
++) {
965 FDKmemclear(h_ps_d
->specificTo
.mpeg
.pAaRealDelayBufferQmf
[k
], FIRST_DELAY_SB
*sizeof(FIXP_DBL
));
967 length
= (usb
-FIRST_DELAY_SB
)*sizeof(FIXP_DBL
);
969 FDKmemclear(h_ps_d
->specificTo
.mpeg
.pAaRealDelayBufferQmf
[0], length
);
970 FDKmemclear(h_ps_d
->specificTo
.mpeg
.pAaImagDelayBufferQmf
[0], length
);
972 length
= (fixMin(NO_DELAY_BUFFER_BANDS
,(INT
)usb
)-FIRST_DELAY_SB
)*sizeof(FIXP_DBL
);
974 for (k
=1 ; k
< h_ps_d
->specificTo
.mpeg
.noSampleDelay
; k
++) {
975 FDKmemclear(h_ps_d
->specificTo
.mpeg
.pAaRealDelayBufferQmf
[k
], length
);
976 FDKmemclear(h_ps_d
->specificTo
.mpeg
.pAaImagDelayBufferQmf
[k
], length
);
980 h_ps_d
->specificTo
.mpeg
.lastUsb
= usb
;
983 if (h_ps_d
->bsData
[h_ps_d
->processSlot
].mpeg
.bFineIidQ
)
985 PScaleFactors
= ScaleFactorsFine
; /* values are shiftet right by one */
986 noIidSteps
= NO_IID_STEPS_FINE
;
987 /*pQuantizedIIDs = quantizedIIDsFine;*/
992 PScaleFactors
= ScaleFactors
; /* values are shiftet right by one */
993 noIidSteps
= NO_IID_STEPS
;
994 /*pQuantizedIIDs = quantizedIIDs;*/
998 /* dequantize and decode */
999 for ( group
= 0; group
< NO_IID_GROUPS
; group
++ ) {
1001 bin
= bins2groupMap20
[group
];
1004 <h3> type 'A' rotation </h3>
1005 mixing procedure R_a, used in baseline version<br>
1007 Scale-factor vectors c1 and c2 are precalculated in initPsTables () and stored in
1008 scaleFactors[] and scaleFactorsFine[] = pScaleFactors [].
1009 From the linearized IID parameters (intensity differences), two scale factors are
1010 calculated. They are used to obtain the coefficients h11... h22.
1013 /* ScaleR and ScaleL are scaled by 1 shift right */
1015 ScaleR
= PScaleFactors
[noIidSteps
+ h_ps_d
->specificTo
.mpeg
.coef
.aaIidIndexMapped
[env
][bin
]];
1016 ScaleL
= PScaleFactors
[noIidSteps
- h_ps_d
->specificTo
.mpeg
.coef
.aaIidIndexMapped
[env
][bin
]];
1018 Beta
= fMult (fMult( Alphas
[h_ps_d
->specificTo
.mpeg
.coef
.aaIccIndexMapped
[env
][bin
]], ( ScaleR
- ScaleL
)), FIXP_SQRT05
);
1019 Alpha
= Alphas
[h_ps_d
->specificTo
.mpeg
.coef
.aaIccIndexMapped
[env
][bin
]]>>1;
1021 /* Alpha and Beta are now both scaled by 2 shifts right */
1023 /* calculate the coefficients h11... h22 from scale-factors and ICC parameters */
1025 /* h values are scaled by 1 shift right */
1027 FIXP_DBL trigData
[4];
1029 inline_fixp_cos_sin(Beta
+ Alpha
, Beta
- Alpha
, 2, trigData
);
1030 h11r
= fMult( ScaleL
, trigData
[0]);
1031 h12r
= fMult( ScaleR
, trigData
[2]);
1032 h21r
= fMult( ScaleL
, trigData
[1]);
1033 h22r
= fMult( ScaleR
, trigData
[3]);
1035 /*****************************************************************************************/
1036 /* Interpolation of the matrices H11... H22: */
1038 /* H11(k,n) = H11(k,n[e]) + (n-n[e]) * (H11(k,n[e+1] - H11(k,n[e])) / (n[e+1] - n[e]) */
1040 /*****************************************************************************************/
1042 /* invL = 1/(length of envelope) */
1043 invL
= FX_DBL2FX_SGL(GetInvInt(h_ps_d
->bsData
[h_ps_d
->processSlot
].mpeg
.aEnvStartStop
[env
+ 1] - h_ps_d
->bsData
[h_ps_d
->processSlot
].mpeg
.aEnvStartStop
[env
]));
1045 h_ps_d
->specificTo
.mpeg
.coef
.H11r
[group
] = h_ps_d
->specificTo
.mpeg
.h11rPrev
[group
];
1046 h_ps_d
->specificTo
.mpeg
.coef
.H12r
[group
] = h_ps_d
->specificTo
.mpeg
.h12rPrev
[group
];
1047 h_ps_d
->specificTo
.mpeg
.coef
.H21r
[group
] = h_ps_d
->specificTo
.mpeg
.h21rPrev
[group
];
1048 h_ps_d
->specificTo
.mpeg
.coef
.H22r
[group
] = h_ps_d
->specificTo
.mpeg
.h22rPrev
[group
];
1050 h_ps_d
->specificTo
.mpeg
.coef
.DeltaH11r
[group
] = fMult ( h11r
- h_ps_d
->specificTo
.mpeg
.coef
.H11r
[group
], invL
);
1051 h_ps_d
->specificTo
.mpeg
.coef
.DeltaH12r
[group
] = fMult ( h12r
- h_ps_d
->specificTo
.mpeg
.coef
.H12r
[group
], invL
);
1052 h_ps_d
->specificTo
.mpeg
.coef
.DeltaH21r
[group
] = fMult ( h21r
- h_ps_d
->specificTo
.mpeg
.coef
.H21r
[group
], invL
);
1053 h_ps_d
->specificTo
.mpeg
.coef
.DeltaH22r
[group
] = fMult ( h22r
- h_ps_d
->specificTo
.mpeg
.coef
.H22r
[group
], invL
);
1055 /* update prev coefficients for interpolation in next envelope */
1057 h_ps_d
->specificTo
.mpeg
.h11rPrev
[group
] = h11r
;
1058 h_ps_d
->specificTo
.mpeg
.h12rPrev
[group
] = h12r
;
1059 h_ps_d
->specificTo
.mpeg
.h21rPrev
[group
] = h21r
;
1060 h_ps_d
->specificTo
.mpeg
.h22rPrev
[group
] = h22r
;
1066 static void applySlotBasedRotation( HANDLE_PS_DEC h_ps_d
, /*!< pointer to the module state */
1068 FIXP_DBL
*mHybridRealLeft
, /*!< hybrid values real left */
1069 FIXP_DBL
*mHybridImagLeft
, /*!< hybrid values imag left */
1071 FIXP_DBL
*QmfLeftReal
, /*!< real bands left qmf channel */
1072 FIXP_DBL
*QmfLeftImag
, /*!< imag bands left qmf channel */
1074 FIXP_DBL
*mHybridRealRight
, /*!< hybrid values real right */
1075 FIXP_DBL
*mHybridImagRight
, /*!< hybrid values imag right */
1077 FIXP_DBL
*QmfRightReal
, /*!< real bands right qmf channel */
1078 FIXP_DBL
*QmfRightImag
/*!< imag bands right qmf channel */
1084 FIXP_DBL
*RESTRICT HybrLeftReal
;
1085 FIXP_DBL
*RESTRICT HybrLeftImag
;
1086 FIXP_DBL
*RESTRICT HybrRightReal
;
1087 FIXP_DBL
*RESTRICT HybrRightImag
;
1089 FIXP_DBL tmpLeft
, tmpRight
;
1092 /**********************************************************************************************/
1096 The number of stereo bands that is actually used depends on the number of availble
1097 parameters for IID and ICC:
1099 nr. of IID para.| nr. of ICC para. | nr. of Stereo bands
1100 ----------------|------------------|-------------------
1106 In the case the number of parameters for IIS and ICC differs from the number of stereo
1107 bands, a mapping from the lower number to the higher number of parameters is applied.
1108 Index mapping of IID and ICC parameters is already done in psbitdec.cpp. Further mapping is
1109 not needed here in baseline version.
1110 **********************************************************************************************/
1112 /************************************************************************************************/
1116 To generate the QMF subband signals for the subband samples n = n[e]+1 ,,, n_[e+1] the
1117 parameters at position n[e] and n[e+1] are required as well as the subband domain signals
1118 s_k(n) and d_k(n) for n = n[e]+1... n_[e+1]. n[e] represents the start position for
1119 envelope e. The border positions n[e] are handled in DecodePS().
1121 The stereo sub subband signals are constructed as:
1123 l_k(n) = H11(k,n) s_k(n) + H21(k,n) d_k(n)
1124 r_k(n) = H21(k,n) s_k(n) + H22(k,n) d_k(n)
1126 In order to obtain the matrices H11(k,n)... H22 (k,n), the vectors h11(b)... h22(b) need to
1127 be calculated first (b: parameter index). Depending on ICC mode either mixing procedure R_a
1128 or R_b is used for that. For both procedures, the parameters for parameter position n[e+1]
1130 ************************************************************************************************/
1133 /************************************************************************************************/
1135 <h2>Phase parameters </h2>
1136 With disabled phase parameters (which is the case in baseline version), the H-matrices are
1140 H11(k,n[e+1] = h11(b(k))
1142 b(k): parameter index according to mapping table
1145 <h2>Processing of the samples in the sub subbands </h2>
1146 this loop includes the interpolation of the coefficients Hxx
1147 ************************************************************************************************/
1150 /* loop thru all groups ... */
1151 HybrLeftReal
= mHybridRealLeft
;
1152 HybrLeftImag
= mHybridImagLeft
;
1153 HybrRightReal
= mHybridRealRight
;
1154 HybrRightImag
= mHybridImagRight
;
1156 /******************************************************/
1157 /* construct stereo sub subband signals according to: */
1159 /* l_k(n) = H11(k,n) s_k(n) + H21(k,n) d_k(n) */
1160 /* r_k(n) = H12(k,n) s_k(n) + H22(k,n) d_k(n) */
1161 /******************************************************/
1162 for ( group
= 0; group
< SUBQMF_GROUPS
; group
++ ) {
1164 h_ps_d
->specificTo
.mpeg
.coef
.H11r
[group
] += h_ps_d
->specificTo
.mpeg
.coef
.DeltaH11r
[group
];
1165 h_ps_d
->specificTo
.mpeg
.coef
.H12r
[group
] += h_ps_d
->specificTo
.mpeg
.coef
.DeltaH12r
[group
];
1166 h_ps_d
->specificTo
.mpeg
.coef
.H21r
[group
] += h_ps_d
->specificTo
.mpeg
.coef
.DeltaH21r
[group
];
1167 h_ps_d
->specificTo
.mpeg
.coef
.H22r
[group
] += h_ps_d
->specificTo
.mpeg
.coef
.DeltaH22r
[group
];
1169 subband
= groupBorders20
[group
];
1171 tmpLeft
= fMultAddDiv2( fMultDiv2(h_ps_d
->specificTo
.mpeg
.coef
.H11r
[group
], HybrLeftReal
[subband
]), h_ps_d
->specificTo
.mpeg
.coef
.H21r
[group
], HybrRightReal
[subband
]);
1172 tmpRight
= fMultAddDiv2( fMultDiv2(h_ps_d
->specificTo
.mpeg
.coef
.H12r
[group
], HybrLeftReal
[subband
]), h_ps_d
->specificTo
.mpeg
.coef
.H22r
[group
], HybrRightReal
[subband
]);
1173 HybrLeftReal
[subband
] = tmpLeft
<<1;
1174 HybrRightReal
[subband
] = tmpRight
<<1;
1176 tmpLeft
= fMultAdd( fMultDiv2(h_ps_d
->specificTo
.mpeg
.coef
.H11r
[group
], HybrLeftImag
[subband
]), h_ps_d
->specificTo
.mpeg
.coef
.H21r
[group
], HybrRightImag
[subband
]);
1177 tmpRight
= fMultAdd( fMultDiv2(h_ps_d
->specificTo
.mpeg
.coef
.H12r
[group
], HybrLeftImag
[subband
]), h_ps_d
->specificTo
.mpeg
.coef
.H22r
[group
], HybrRightImag
[subband
]);
1178 HybrLeftImag
[subband
] = tmpLeft
;
1179 HybrRightImag
[subband
] = tmpRight
;
1182 /* continue in the qmf buffers */
1183 HybrLeftReal
= QmfLeftReal
;
1184 HybrLeftImag
= QmfLeftImag
;
1185 HybrRightReal
= QmfRightReal
;
1186 HybrRightImag
= QmfRightImag
;
1188 for (; group
< NO_IID_GROUPS
; group
++ ) {
1190 h_ps_d
->specificTo
.mpeg
.coef
.H11r
[group
] += h_ps_d
->specificTo
.mpeg
.coef
.DeltaH11r
[group
];
1191 h_ps_d
->specificTo
.mpeg
.coef
.H12r
[group
] += h_ps_d
->specificTo
.mpeg
.coef
.DeltaH12r
[group
];
1192 h_ps_d
->specificTo
.mpeg
.coef
.H21r
[group
] += h_ps_d
->specificTo
.mpeg
.coef
.DeltaH21r
[group
];
1193 h_ps_d
->specificTo
.mpeg
.coef
.H22r
[group
] += h_ps_d
->specificTo
.mpeg
.coef
.DeltaH22r
[group
];
1195 for ( subband
= groupBorders20
[group
]; subband
< groupBorders20
[group
+ 1]; subband
++ )
1197 tmpLeft
= fMultAdd( fMultDiv2(h_ps_d
->specificTo
.mpeg
.coef
.H11r
[group
], HybrLeftReal
[subband
]), h_ps_d
->specificTo
.mpeg
.coef
.H21r
[group
], HybrRightReal
[subband
]);
1198 tmpRight
= fMultAdd( fMultDiv2(h_ps_d
->specificTo
.mpeg
.coef
.H12r
[group
], HybrLeftReal
[subband
]), h_ps_d
->specificTo
.mpeg
.coef
.H22r
[group
], HybrRightReal
[subband
]);
1199 HybrLeftReal
[subband
] = tmpLeft
;
1200 HybrRightReal
[subband
] = tmpRight
;
1202 tmpLeft
= fMultAdd( fMultDiv2(h_ps_d
->specificTo
.mpeg
.coef
.H11r
[group
], HybrLeftImag
[subband
]), h_ps_d
->specificTo
.mpeg
.coef
.H21r
[group
], HybrRightImag
[subband
]);
1203 tmpRight
= fMultAdd( fMultDiv2(h_ps_d
->specificTo
.mpeg
.coef
.H12r
[group
], HybrLeftImag
[subband
]), h_ps_d
->specificTo
.mpeg
.coef
.H22r
[group
], HybrRightImag
[subband
]);
1204 HybrLeftImag
[subband
] = tmpLeft
;
1205 HybrRightImag
[subband
] = tmpRight
;
1212 /***************************************************************************/
1214 \brief Applies IID, ICC, IPD and OPD parameters to the current frame.
1218 ****************************************************************************/
1220 ApplyPsSlot( HANDLE_PS_DEC h_ps_d
, /*!< handle PS_DEC*/
1221 FIXP_DBL
**rIntBufferLeft
, /*!< real bands left qmf channel (38x64) */
1222 FIXP_DBL
**iIntBufferLeft
, /*!< imag bands left qmf channel (38x64) */
1223 FIXP_DBL
*rIntBufferRight
, /*!< real bands right qmf channel (38x64) */
1224 FIXP_DBL
*iIntBufferRight
/*!< imag bands right qmf channel (38x64) */
1229 The 64-band QMF representation of the monaural signal generated by the SBR tool
1230 is used as input of the PS tool. After the PS processing, the outputs of the left
1231 and right hybrid synthesis filterbanks are used to generate the stereo output
1236 ------------- ---------- -------------
1237 | Hybrid | M_n[k,m] | | L_n[k,m] | Hybrid | l[n]
1238 m[n] --->| analysis |--------->| |--------->| synthesis |----->
1239 | filter bank | | | | filter bank |
1240 ------------- | Stereo | -------------
1245 | De- | D_n[k,m] | |
1246 | correlation |--------->| |
1247 ------------- | | -------------
1248 | | R_n[k,m] | Hybrid | r[n]
1249 | |--------->| synthesis |----->
1250 IID, ICC ------------------------>| | | filter bank |
1251 (IPD, OPD) ---------- -------------
1253 m[n]: QMF represantation of the mono input
1254 M_n[k,m]: (sub-)sub-band domain signals of the mono input
1255 D_n[k,m]: decorrelated (sub-)sub-band domain signals
1256 L_n[k,m]: (sub-)sub-band domain signals of the left output
1257 R_n[k,m]: (sub-)sub-band domain signals of the right output
1258 l[n],r[n]: left/right output signals
1263 /* get temporary hybrid qmf values of one timeslot */
1264 C_ALLOC_SCRATCH_START(hybridRealLeft
, FIXP_DBL
, NO_SUB_QMF_CHANNELS
);
1265 C_ALLOC_SCRATCH_START(hybridImagLeft
, FIXP_DBL
, NO_SUB_QMF_CHANNELS
);
1266 C_ALLOC_SCRATCH_START(hybridRealRight
, FIXP_DBL
, NO_SUB_QMF_CHANNELS
);
1267 C_ALLOC_SCRATCH_START(hybridImagRight
, FIXP_DBL
, NO_SUB_QMF_CHANNELS
);
1269 SCHAR sf_IntBuffer
= h_ps_d
->sf_IntBuffer
;
1271 /* clear workbuffer */
1272 FDKmemclear(hybridRealLeft
, NO_SUB_QMF_CHANNELS
*sizeof(FIXP_DBL
));
1273 FDKmemclear(hybridImagLeft
, NO_SUB_QMF_CHANNELS
*sizeof(FIXP_DBL
));
1274 FDKmemclear(hybridRealRight
, NO_SUB_QMF_CHANNELS
*sizeof(FIXP_DBL
));
1275 FDKmemclear(hybridImagRight
, NO_SUB_QMF_CHANNELS
*sizeof(FIXP_DBL
));
1279 Hybrid analysis filterbank:
1280 The lower 3 (5) of the 64 QMF subbands are further split to provide better frequency resolution.
1282 For the 10 and 20 stereo bands configuration, the QMF band H_0(w) is split
1283 up into 8 (sub-) sub-bands and the QMF bands H_1(w) and H_2(w) are spit into 2 (sub-)
1284 4th. (See figures 8.20 and 8.22 of ISO/IEC 14496-3:2001/FDAM 2:2004(E) )
1288 if (h_ps_d
->procFrameBased
== 1) /* If we have switched from frame to slot based processing */
1289 { /* fill hybrid delay buffer. */
1290 h_ps_d
->procFrameBased
= 0;
1292 fillHybridDelayLine( rIntBufferLeft
,
1298 &h_ps_d
->specificTo
.mpeg
.hybrid
);
1301 slotBasedHybridAnalysis ( rIntBufferLeft
[HYBRID_FILTER_DELAY
], /* qmf filterbank values */
1302 iIntBufferLeft
[HYBRID_FILTER_DELAY
], /* qmf filterbank values */
1303 hybridRealLeft
, /* hybrid filterbank values */
1304 hybridImagLeft
, /* hybrid filterbank values */
1305 &h_ps_d
->specificTo
.mpeg
.hybrid
); /* hybrid filterbank handle */
1308 SCHAR hybridScal
= h_ps_d
->specificTo
.mpeg
.hybrid
.sf_mQmfBuffer
;
1313 By means of all-pass filtering and delaying, the (sub-)sub-band samples s_k(n) are
1314 converted into de-correlated (sub-)sub-band samples d_k(n).
1315 - k: frequency in hybrid spectrum
1319 deCorrelateSlotBased( h_ps_d
, /* parametric stereo decoder handle */
1320 hybridRealLeft
, /* left hybrid time slot */
1322 hybridScal
, /* scale factor of left hybrid time slot */
1323 rIntBufferLeft
[0], /* left qmf time slot */
1325 sf_IntBuffer
, /* scale factor of left and right qmf time slot */
1326 hybridRealRight
, /* right hybrid time slot */
1328 rIntBufferRight
, /* right qmf time slot */
1335 The sets of (sub-)sub-band samples s_k(n) and d_k(n) are processed according to
1336 the stereo cues which are defined per stereo band.
1340 applySlotBasedRotation( h_ps_d
, /* parametric stereo decoder handle */
1341 hybridRealLeft
, /* left hybrid time slot */
1343 rIntBufferLeft
[0], /* left qmf time slot */
1345 hybridRealRight
, /* right hybrid time slot */
1347 rIntBufferRight
, /* right qmf time slot */
1354 Hybrid synthesis filterbank:
1355 The stereo processed hybrid subband signals l_k(n) and r_k(n) are fed into the hybrid synthesis
1356 filterbanks which are identical to the 64 complex synthesis filterbank of the SBR tool. The
1357 input to the filterbank are slots of 64 QMF samples. For each slot the filterbank outputs one
1358 block of 64 samples of one reconstructed stereo channel. The hybrid synthesis filterbank is
1359 computed seperatly for the left and right channel.
1364 slotBasedHybridSynthesis ( hybridRealLeft
, /* one timeslot of hybrid filterbank values */
1366 rIntBufferLeft
[0], /* one timeslot of qmf filterbank values */
1368 &h_ps_d
->specificTo
.mpeg
.hybrid
); /* hybrid filterbank handle */
1371 slotBasedHybridSynthesis ( hybridRealRight
, /* one timeslot of hybrid filterbank values */
1373 rIntBufferRight
, /* one timeslot of qmf filterbank values */
1375 &h_ps_d
->specificTo
.mpeg
.hybrid
); /* hybrid filterbank handle */
1383 /* free temporary hybrid qmf values of one timeslot */
1384 C_ALLOC_SCRATCH_END(hybridImagRight
, FIXP_DBL
, NO_SUB_QMF_CHANNELS
);
1385 C_ALLOC_SCRATCH_END(hybridRealRight
, FIXP_DBL
, NO_SUB_QMF_CHANNELS
);
1386 C_ALLOC_SCRATCH_END(hybridImagLeft
, FIXP_DBL
, NO_SUB_QMF_CHANNELS
);
1387 C_ALLOC_SCRATCH_END(hybridRealLeft
, FIXP_DBL
, NO_SUB_QMF_CHANNELS
);
1389 }/* END ApplyPsSlot */
1392 /***************************************************************************/
1395 \brief assigns timeslots to an array
1399 ****************************************************************************/
1401 static void assignTimeSlotsPS (FIXP_DBL
*bufAdr
,
1409 for(slot
=0; slot
< numSlots
; slot
++) {
1410 bufPtr
[slot
] = ptr
;