diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2016-09-10 20:15:44 +0200 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2016-09-10 20:15:44 +0200 |
commit | 14c7b800eaa23e9da7c92c7c4df397d0c191f097 (patch) | |
tree | d840b6ec41ff74d1184ca1dcd7731d08f1e9ebbb /libSBRdec/src/psdec.cpp | |
parent | 78a801e4d716c6f2403cc56cf6c5b6f138f24b2f (diff) | |
download | ODR-AudioEnc-14c7b800eaa23e9da7c92c7c4df397d0c191f097.tar.gz ODR-AudioEnc-14c7b800eaa23e9da7c92c7c4df397d0c191f097.tar.bz2 ODR-AudioEnc-14c7b800eaa23e9da7c92c7c4df397d0c191f097.zip |
Remove FDK-AAC
Diffstat (limited to 'libSBRdec/src/psdec.cpp')
-rw-r--r-- | libSBRdec/src/psdec.cpp | 1414 |
1 files changed, 0 insertions, 1414 deletions
diff --git a/libSBRdec/src/psdec.cpp b/libSBRdec/src/psdec.cpp deleted file mode 100644 index 965917a..0000000 --- a/libSBRdec/src/psdec.cpp +++ /dev/null @@ -1,1414 +0,0 @@ - -/* ----------------------------------------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. - All rights reserved. - - 1. INTRODUCTION -The Fraunhofer FDK AAC Codec Library for Android ("FDK AAC Codec") is software that implements -the MPEG Advanced Audio Coding ("AAC") encoding and decoding scheme for digital audio. -This FDK AAC Codec software is intended to be used on a wide variety of Android devices. - -AAC's HE-AAC and HE-AAC v2 versions are regarded as today's most efficient general perceptual -audio codecs. AAC-ELD is considered the best-performing full-bandwidth communications codec by -independent studies and is widely deployed. AAC has been standardized by ISO and IEC as part -of the MPEG specifications. - -Patent licenses for necessary patent claims for the FDK AAC Codec (including those of Fraunhofer) -may be obtained through Via Licensing (www.vialicensing.com) or through the respective patent owners -individually for the purpose of encoding or decoding bit streams in products that are compliant with -the ISO/IEC MPEG audio standards. Please note that most manufacturers of Android devices already license -these patent claims through Via Licensing or directly from the patent owners, and therefore FDK AAC Codec -software may already be covered under those patent licenses when it is used for those licensed purposes only. - -Commercially-licensed AAC software libraries, including floating-point versions with enhanced sound quality, -are also available from Fraunhofer. Users are encouraged to check the Fraunhofer website for additional -applications information and documentation. - -2. COPYRIGHT LICENSE - -Redistribution and use in source and binary forms, with or without modification, are permitted without -payment of copyright license fees provided that you satisfy the following conditions: - -You must retain the complete text of this software license in redistributions of the FDK AAC Codec or -your modifications thereto in source code form. - -You must retain the complete text of this software license in the documentation and/or other materials -provided with redistributions of the FDK AAC Codec or your modifications thereto in binary form. -You must make available free of charge copies of the complete source code of the FDK AAC Codec and your -modifications thereto to recipients of copies in binary form. - -The name of Fraunhofer may not be used to endorse or promote products derived from this library without -prior written permission. - -You may not charge copyright license fees for anyone to use, copy or distribute the FDK AAC Codec -software or your modifications thereto. - -Your modified versions of the FDK AAC Codec must carry prominent notices stating that you changed the software -and the date of any change. For modified versions of the FDK AAC Codec, the term -"Fraunhofer FDK AAC Codec Library for Android" must be replaced by the term -"Third-Party Modified Version of the Fraunhofer FDK AAC Codec Library for Android." - -3. NO PATENT LICENSE - -NO EXPRESS OR IMPLIED LICENSES TO ANY PATENT CLAIMS, including without limitation the patents of Fraunhofer, -ARE GRANTED BY THIS SOFTWARE LICENSE. Fraunhofer provides no warranty of patent non-infringement with -respect to this software. - -You may use this FDK AAC Codec software or modifications thereto only for purposes that are authorized -by appropriate patent licenses. - -4. DISCLAIMER - -This FDK AAC Codec software is provided by Fraunhofer on behalf of the copyright holders and contributors -"AS IS" and WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, including but not limited to the implied warranties -of merchantability and fitness for a particular purpose. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR -CONTRIBUTORS BE LIABLE for any direct, indirect, incidental, special, exemplary, or consequential damages, -including but not limited to procurement of substitute goods or services; loss of use, data, or profits, -or business interruption, however caused and on any theory of liability, whether in contract, strict -liability, or tort (including negligence), arising in any way out of the use of this software, even if -advised of the possibility of such damage. - -5. CONTACT INFORMATION - -Fraunhofer Institute for Integrated Circuits IIS -Attention: Audio and Multimedia Departments - FDK AAC LL -Am Wolfsmantel 33 -91058 Erlangen, Germany - -www.iis.fraunhofer.de/amm -amm-info@iis.fraunhofer.de ------------------------------------------------------------------------------------------------------------ */ - -/*! - \file - \brief parametric stereo decoder -*/ - -#include "psdec.h" - - - -#include "FDK_bitbuffer.h" -#include "psdec_hybrid.h" - -#include "sbr_rom.h" -#include "sbr_ram.h" - -#include "FDK_tools_rom.h" - -#include "genericStds.h" - -#include "FDK_trigFcts.h" - - -/********************************************************************/ -/* MLQUAL DEFINES */ -/********************************************************************/ - - #define FRACT_ZERO FRACT_BITS-1 -/********************************************************************/ - -SBR_ERROR ResetPsDec( HANDLE_PS_DEC h_ps_d ); - -void ResetPsDeCor( HANDLE_PS_DEC h_ps_d ); - - -/***** HELPERS *****/ - -static void assignTimeSlotsPS (FIXP_DBL *bufAdr, FIXP_DBL **bufPtr, const int numSlots, const int numChan); - - - -/*******************/ - -#define DIV3 FL2FXCONST_DBL(1.f/3.f) /* division 3.0 */ -#define DIV1_5 FL2FXCONST_DBL(2.f/3.f) /* division 1.5 */ - -/***************************************************************************/ -/*! - \brief Creates one instance of the PS_DEC struct - - \return Error info - -****************************************************************************/ -int -CreatePsDec( HANDLE_PS_DEC *h_PS_DEC, /*!< pointer to the module state */ - int aacSamplesPerFrame - ) -{ - SBR_ERROR errorInfo = SBRDEC_OK; - HANDLE_PS_DEC h_ps_d; - int i; - - if (*h_PS_DEC == NULL) { - /* Get ps dec ram */ - h_ps_d = GetRam_ps_dec(); - if (h_ps_d == NULL) { - errorInfo = SBRDEC_MEM_ALLOC_FAILED; - goto bail; - } - } else { - /* Reset an open instance */ - h_ps_d = *h_PS_DEC; - } - - /* initialisation */ - switch (aacSamplesPerFrame) { - case 960: - h_ps_d->noSubSamples = 30; /* col */ - break; - case 1024: - h_ps_d->noSubSamples = 32; /* col */ - break; - default: - h_ps_d->noSubSamples = -1; - break; - } - - if (h_ps_d->noSubSamples > MAX_NUM_COL - || h_ps_d->noSubSamples <= 0) - { - goto bail; - } - h_ps_d->noChannels = NO_QMF_CHANNELS; /* row */ - - h_ps_d->psDecodedPrv = 0; - h_ps_d->procFrameBased = -1; - for (i = 0; i < (1)+1; i++) { - h_ps_d->bPsDataAvail[i] = ppt_none; - } - - - for (i = 0; i < (1)+1; i++) { - FDKmemclear(&h_ps_d->bsData[i].mpeg, sizeof(MPEG_PS_BS_DATA)); - } - - errorInfo = ResetPsDec( h_ps_d ); - - if ( errorInfo != SBRDEC_OK ) - goto bail; - - ResetPsDeCor( h_ps_d ); - - *h_PS_DEC = h_ps_d; - - - - return 0; - -bail: - DeletePsDec(&h_ps_d); - - return -1; -} /*END CreatePsDec */ - -/***************************************************************************/ -/*! - \brief Delete one instance of the PS_DEC struct - - \return Error info - -****************************************************************************/ -int -DeletePsDec( HANDLE_PS_DEC *h_PS_DEC) /*!< pointer to the module state */ -{ - if (*h_PS_DEC == NULL) { - return -1; - } - - - FreeRam_ps_dec(h_PS_DEC); - - - return 0; -} /*END DeletePsDec */ - -/***************************************************************************/ -/*! - \brief resets some values of the PS handle to default states - - \return - -****************************************************************************/ -SBR_ERROR ResetPsDec( HANDLE_PS_DEC h_ps_d ) /*!< pointer to the module state */ -{ - SBR_ERROR errorInfo = SBRDEC_OK; - INT i; - - const UCHAR noQmfBandsInHybrid20 = 3; - /* const UCHAR noQmfBandsInHybrid34 = 5; */ - - const UCHAR aHybridResolution20[] = { HYBRID_8_CPLX, - HYBRID_2_REAL, - HYBRID_2_REAL }; - - h_ps_d->specificTo.mpeg.delayBufIndex = 0; - - /* explicitly init state variables to safe values (until first ps header arrives) */ - - h_ps_d->specificTo.mpeg.lastUsb = 0; - - h_ps_d->specificTo.mpeg.scaleFactorPsDelayBuffer = -(DFRACT_BITS-1); - - FDKmemclear(h_ps_d->specificTo.mpeg.aDelayBufIndexDelayQmf, (NO_QMF_CHANNELS-FIRST_DELAY_SB)*sizeof(UCHAR)); - h_ps_d->specificTo.mpeg.noSampleDelay = delayIndexQmf[0]; - - for (i=0 ; i < NO_SERIAL_ALLPASS_LINKS; i++) { - h_ps_d->specificTo.mpeg.aDelayRBufIndexSer[i] = 0; - } - - h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[0] = h_ps_d->specificTo.mpeg.aaQmfDelayBufReal; - - assignTimeSlotsPS ( h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[0] + (NO_QMF_CHANNELS-FIRST_DELAY_SB), - &h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[1], - h_ps_d->specificTo.mpeg.noSampleDelay-1, - (NO_DELAY_BUFFER_BANDS-FIRST_DELAY_SB)); - - h_ps_d->specificTo.mpeg.pAaImagDelayBufferQmf[0] = h_ps_d->specificTo.mpeg.aaQmfDelayBufImag; - - assignTimeSlotsPS ( h_ps_d->specificTo.mpeg.pAaImagDelayBufferQmf[0] + (NO_QMF_CHANNELS-FIRST_DELAY_SB), - &h_ps_d->specificTo.mpeg.pAaImagDelayBufferQmf[1], - h_ps_d->specificTo.mpeg.noSampleDelay-1, - (NO_DELAY_BUFFER_BANDS-FIRST_DELAY_SB)); - - /* Hybrid Filter Bank 1 creation. */ - errorInfo = InitHybridFilterBank ( &h_ps_d->specificTo.mpeg.hybrid, - h_ps_d->noSubSamples, - noQmfBandsInHybrid20, - aHybridResolution20 ); - - for ( i = 0; i < NO_IID_GROUPS; i++ ) - { - h_ps_d->specificTo.mpeg.h11rPrev[i] = FL2FXCONST_DBL(0.5f); - h_ps_d->specificTo.mpeg.h12rPrev[i] = FL2FXCONST_DBL(0.5f); - } - - FDKmemclear( h_ps_d->specificTo.mpeg.h21rPrev, sizeof( h_ps_d->specificTo.mpeg.h21rPrev ) ); - FDKmemclear( h_ps_d->specificTo.mpeg.h22rPrev, sizeof( h_ps_d->specificTo.mpeg.h22rPrev ) ); - - return errorInfo; -} - -/***************************************************************************/ -/*! - \brief clear some buffers used in decorrelation process - - \return - -****************************************************************************/ -void ResetPsDeCor( HANDLE_PS_DEC h_ps_d ) /*!< pointer to the module state */ -{ - INT i; - - FDKmemclear(h_ps_d->specificTo.mpeg.aPeakDecayFastBin, NO_MID_RES_BINS*sizeof(FIXP_DBL)); - FDKmemclear(h_ps_d->specificTo.mpeg.aPrevNrgBin, NO_MID_RES_BINS*sizeof(FIXP_DBL)); - FDKmemclear(h_ps_d->specificTo.mpeg.aPrevPeakDiffBin, NO_MID_RES_BINS*sizeof(FIXP_DBL)); - FDKmemclear(h_ps_d->specificTo.mpeg.aPowerPrevScal, NO_MID_RES_BINS*sizeof(SCHAR)); - - for (i=0 ; i < FIRST_DELAY_SB ; i++) { - FDKmemclear(h_ps_d->specificTo.mpeg.aaaRealDelayRBufferSerQmf[i], NO_DELAY_LENGTH_VECTORS*sizeof(FIXP_DBL)); - FDKmemclear(h_ps_d->specificTo.mpeg.aaaImagDelayRBufferSerQmf[i], NO_DELAY_LENGTH_VECTORS*sizeof(FIXP_DBL)); - } - for (i=0 ; i < NO_SUB_QMF_CHANNELS ; i++) { - FDKmemclear(h_ps_d->specificTo.mpeg.aaaRealDelayRBufferSerSubQmf[i], NO_DELAY_LENGTH_VECTORS*sizeof(FIXP_DBL)); - FDKmemclear(h_ps_d->specificTo.mpeg.aaaImagDelayRBufferSerSubQmf[i], NO_DELAY_LENGTH_VECTORS*sizeof(FIXP_DBL)); - } - -} - -/*******************************************************************************/ - -/* slot based funcion prototypes */ - -static void deCorrelateSlotBased( HANDLE_PS_DEC h_ps_d, - - FIXP_DBL *mHybridRealLeft, - FIXP_DBL *mHybridImagLeft, - SCHAR sf_mHybridLeft, - - FIXP_DBL *rIntBufferLeft, - FIXP_DBL *iIntBufferLeft, - SCHAR sf_IntBuffer, - - FIXP_DBL *mHybridRealRight, - FIXP_DBL *mHybridImagRight, - - FIXP_DBL *rIntBufferRight, - FIXP_DBL *iIntBufferRight ); - -static void applySlotBasedRotation( HANDLE_PS_DEC h_ps_d, - - FIXP_DBL *mHybridRealLeft, - FIXP_DBL *mHybridImagLeft, - - FIXP_DBL *QmfLeftReal, - FIXP_DBL *QmfLeftImag, - - FIXP_DBL *mHybridRealRight, - FIXP_DBL *mHybridImagRight, - - FIXP_DBL *QmfRightReal, - FIXP_DBL *QmfRightImag - ); - - -/***************************************************************************/ -/*! - \brief Get scale factor for all ps delay buffer. - - \return - -****************************************************************************/ -static -int getScaleFactorPsStatesBuffer(HANDLE_PS_DEC h_ps_d) -{ - INT i; - int scale = DFRACT_BITS-1; - - for (i=0; i<NO_QMF_BANDS_HYBRID20; i++) { - scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.hybrid.mQmfBufferRealSlot[i], NO_SUB_QMF_CHANNELS)); - scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.hybrid.mQmfBufferImagSlot[i], NO_SUB_QMF_CHANNELS)); - } - - for (i=0; i<NO_SAMPLE_DELAY_ALLPASS; i++) { - scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.aaRealDelayBufferQmf[i], FIRST_DELAY_SB)); - scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.aaImagDelayBufferQmf[i], FIRST_DELAY_SB)); - } - - for (i=0; i<NO_SAMPLE_DELAY_ALLPASS; i++) { - scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.aaRealDelayBufferSubQmf[i], NO_SUB_QMF_CHANNELS)); - scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.aaImagDelayBufferSubQmf[i], NO_SUB_QMF_CHANNELS)); - } - - for (i=0; i<FIRST_DELAY_SB; i++) { - scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.aaaRealDelayRBufferSerQmf[i], NO_DELAY_LENGTH_VECTORS)); - scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.aaaImagDelayRBufferSerQmf[i], NO_DELAY_LENGTH_VECTORS)); - } - - for (i=0; i<NO_SUB_QMF_CHANNELS; i++) { - scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.aaaRealDelayRBufferSerSubQmf[i], NO_DELAY_LENGTH_VECTORS)); - scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.aaaImagDelayRBufferSerSubQmf[i], NO_DELAY_LENGTH_VECTORS)); - } - - for (i=0; i<MAX_DELAY_BUFFER_SIZE; i++) - { - INT len; - if (i==0) - len = NO_QMF_CHANNELS-FIRST_DELAY_SB; - else - len = NO_DELAY_BUFFER_BANDS-FIRST_DELAY_SB; - - scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[i], len)); - scale = fMin(scale, getScalefactor(h_ps_d->specificTo.mpeg.pAaImagDelayBufferQmf[i], len)); - } - - return (scale); -} - -/***************************************************************************/ -/*! - \brief Rescale all ps delay buffer. - - \return - -****************************************************************************/ -static -void scalePsStatesBuffer(HANDLE_PS_DEC h_ps_d, - int scale) -{ - INT i; - - if (scale < 0) - scale = fixMax((INT)scale,(INT)-(DFRACT_BITS-1)); - else - scale = fixMin((INT)scale,(INT)DFRACT_BITS-1); - - for (i=0; i<NO_QMF_BANDS_HYBRID20; i++) { - scaleValues( h_ps_d->specificTo.mpeg.hybrid.mQmfBufferRealSlot[i], NO_SUB_QMF_CHANNELS, scale ); - scaleValues( h_ps_d->specificTo.mpeg.hybrid.mQmfBufferImagSlot[i], NO_SUB_QMF_CHANNELS, scale ); - } - - for (i=0; i<NO_SAMPLE_DELAY_ALLPASS; i++) { - scaleValues( h_ps_d->specificTo.mpeg.aaRealDelayBufferQmf[i], FIRST_DELAY_SB, scale ); - scaleValues( h_ps_d->specificTo.mpeg.aaImagDelayBufferQmf[i], FIRST_DELAY_SB, scale ); - } - - for (i=0; i<NO_SAMPLE_DELAY_ALLPASS; i++) { - scaleValues( h_ps_d->specificTo.mpeg.aaRealDelayBufferSubQmf[i], NO_SUB_QMF_CHANNELS, scale ); - scaleValues( h_ps_d->specificTo.mpeg.aaImagDelayBufferSubQmf[i], NO_SUB_QMF_CHANNELS, scale ); - } - - for (i=0; i<FIRST_DELAY_SB; i++) { - scaleValues( h_ps_d->specificTo.mpeg.aaaRealDelayRBufferSerQmf[i], NO_DELAY_LENGTH_VECTORS, scale ); - scaleValues( h_ps_d->specificTo.mpeg.aaaImagDelayRBufferSerQmf[i], NO_DELAY_LENGTH_VECTORS, scale ); - } - - for (i=0; i<NO_SUB_QMF_CHANNELS; i++) { - scaleValues( h_ps_d->specificTo.mpeg.aaaRealDelayRBufferSerSubQmf[i], NO_DELAY_LENGTH_VECTORS, scale ); - scaleValues( h_ps_d->specificTo.mpeg.aaaImagDelayRBufferSerSubQmf[i], NO_DELAY_LENGTH_VECTORS, scale ); - } - - for (i=0; i<MAX_DELAY_BUFFER_SIZE; i++) { - INT len; - if (i==0) - len = NO_QMF_CHANNELS-FIRST_DELAY_SB; - else - len = NO_DELAY_BUFFER_BANDS-FIRST_DELAY_SB; - - scaleValues( h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[i], len, scale ); - scaleValues( h_ps_d->specificTo.mpeg.pAaImagDelayBufferQmf[i], len, scale ); - } - - scale <<= 1; - - scaleValues( h_ps_d->specificTo.mpeg.aPeakDecayFastBin, NO_MID_RES_BINS, scale ); - scaleValues( h_ps_d->specificTo.mpeg.aPrevPeakDiffBin, NO_MID_RES_BINS, scale ); - scaleValues( h_ps_d->specificTo.mpeg.aPrevNrgBin, NO_MID_RES_BINS, scale ); -} - -/***************************************************************************/ -/*! - \brief Scale input channel to the same scalefactor and rescale hybrid - filterbank values - - \return - -****************************************************************************/ - -void scalFilterBankValues( HANDLE_PS_DEC h_ps_d, - FIXP_DBL **fixpQmfReal, - FIXP_DBL **fixpQmfImag, - int lsb, - int scaleFactorLowBandSplitLow, - int scaleFactorLowBandSplitHigh, - SCHAR *scaleFactorLowBand_lb, - SCHAR *scaleFactorLowBand_hb, - int scaleFactorHighBands, - INT *scaleFactorHighBand, - INT noCols - ) -{ - INT maxScal; - - INT i; - - scaleFactorHighBands = -scaleFactorHighBands; - scaleFactorLowBandSplitLow = -scaleFactorLowBandSplitLow; - scaleFactorLowBandSplitHigh = -scaleFactorLowBandSplitHigh; - - /* get max scale factor */ - maxScal = fixMax(scaleFactorHighBands,fixMax(scaleFactorLowBandSplitLow, scaleFactorLowBandSplitHigh )); - - { - int headroom = getScaleFactorPsStatesBuffer(h_ps_d); - maxScal = fixMax(maxScal,(INT)(h_ps_d->specificTo.mpeg.scaleFactorPsDelayBuffer-headroom)); - maxScal += 1; - } - - /* scale whole left channel to the same scale factor */ - - /* low band ( overlap buffer ) */ - if ( maxScal != scaleFactorLowBandSplitLow ) { - INT scale = scaleFactorLowBandSplitLow - maxScal; - for ( i=0; i<(6); i++ ) { - scaleValues( fixpQmfReal[i], lsb, scale ); - scaleValues( fixpQmfImag[i], lsb, scale ); - } - } - /* low band ( current frame ) */ - if ( maxScal != scaleFactorLowBandSplitHigh ) { - INT scale = scaleFactorLowBandSplitHigh - maxScal; - /* for ( i=(6); i<(6)+MAX_NUM_COL; i++ ) { */ - for ( i=(6); i<(6)+noCols; i++ ) { - scaleValues( fixpQmfReal[i], lsb, scale ); - scaleValues( fixpQmfImag[i], lsb, scale ); - } - } - /* high band */ - if ( maxScal != scaleFactorHighBands ) { - INT scale = scaleFactorHighBands - maxScal; - /* for ( i=0; i<MAX_NUM_COL; i++ ) { */ - for ( i=0; i<noCols; i++ ) { - scaleValues( &fixpQmfReal[i][lsb], (64)-lsb, scale ); - scaleValues( &fixpQmfImag[i][lsb], (64)-lsb, scale ); - } - } - - if ( maxScal != h_ps_d->specificTo.mpeg.scaleFactorPsDelayBuffer ) - scalePsStatesBuffer(h_ps_d,(h_ps_d->specificTo.mpeg.scaleFactorPsDelayBuffer-maxScal)); - - h_ps_d->specificTo.mpeg.hybrid.sf_mQmfBuffer = maxScal; - h_ps_d->specificTo.mpeg.scaleFactorPsDelayBuffer = maxScal; - - *scaleFactorHighBand += maxScal - scaleFactorHighBands; - - h_ps_d->rescal = maxScal - scaleFactorLowBandSplitHigh; - h_ps_d->sf_IntBuffer = maxScal; - - *scaleFactorLowBand_lb += maxScal - scaleFactorLowBandSplitLow; - *scaleFactorLowBand_hb += maxScal - scaleFactorLowBandSplitHigh; -} - -void rescalFilterBankValues( HANDLE_PS_DEC h_ps_d, /* parametric stereo decoder handle */ - FIXP_DBL **QmfBufferReal, /* qmf filterbank values */ - FIXP_DBL **QmfBufferImag, /* qmf filterbank values */ - int lsb, /* sbr start subband */ - INT noCols) -{ - int i; - /* scale back 6 timeslots look ahead for hybrid filterbank to original value */ - for ( i=noCols; i<noCols + (6); i++ ) { - scaleValues( QmfBufferReal[i], lsb, h_ps_d->rescal ); - scaleValues( QmfBufferImag[i], lsb, h_ps_d->rescal ); - } -} - -/***************************************************************************/ -/*! - \brief Generate decorrelated side channel using allpass/delay - - \return - -****************************************************************************/ -static void -deCorrelateSlotBased( HANDLE_PS_DEC h_ps_d, /*!< pointer to the module state */ - - FIXP_DBL *mHybridRealLeft, /*!< left (mono) hybrid values real */ - FIXP_DBL *mHybridImagLeft, /*!< left (mono) hybrid values imag */ - SCHAR sf_mHybridLeft, /*!< scalefactor for left (mono) hybrid bands */ - - FIXP_DBL *rIntBufferLeft, /*!< real qmf bands left (mono) (38x64) */ - FIXP_DBL *iIntBufferLeft, /*!< real qmf bands left (mono) (38x64) */ - SCHAR sf_IntBuffer, /*!< scalefactor for all left and right qmf bands */ - - FIXP_DBL *mHybridRealRight, /*!< right (decorrelated) hybrid values real */ - FIXP_DBL *mHybridImagRight, /*!< right (decorrelated) hybrid values imag */ - - FIXP_DBL *rIntBufferRight, /*!< real qmf bands right (decorrelated) (38x64) */ - FIXP_DBL *iIntBufferRight ) /*!< real qmf bands right (decorrelated) (38x64) */ -{ - - INT i, m, sb, gr, bin; - - FIXP_DBL peakDiff, nrg, transRatio; - - FIXP_DBL *RESTRICT aaLeftReal; - FIXP_DBL *RESTRICT aaLeftImag; - - FIXP_DBL *RESTRICT aaRightReal; - FIXP_DBL *RESTRICT aaRightImag; - - FIXP_DBL *RESTRICT pRealDelayBuffer; - FIXP_DBL *RESTRICT pImagDelayBuffer; - - C_ALLOC_SCRATCH_START(aaPowerSlot, FIXP_DBL, NO_MID_RES_BINS); - C_ALLOC_SCRATCH_START(aaTransRatioSlot, FIXP_DBL, NO_MID_RES_BINS); - -/*! -<pre> - parameter index qmf bands hybrid bands - ---------------------------------------------------------------------------- - 0 0 0,7 - 1 0 1,6 - 2 0 2 - 3 0 3 HYBRID BANDS - 4 1 9 - 5 1 8 - 6 2 10 - 7 2 11 - ---------------------------------------------------------------------------- - 8 3 - 9 4 - 10 5 - 11 6 - 12 7 - 13 8 - 14 9,10 (2 ) QMF BANDS - 15 11 - 13 (3 ) - 16 14 - 17 (4 ) - 17 18 - 22 (5 ) - 18 23 - 34 (12) - 19 35 - 63 (29) - ---------------------------------------------------------------------------- -</pre> -*/ - - #define FLTR_SCALE 3 - - /* hybrid bands (parameter index 0 - 7) */ - aaLeftReal = mHybridRealLeft; - aaLeftImag = mHybridImagLeft; - - aaPowerSlot[0] = ( fMultAddDiv2( fMultDiv2(aaLeftReal[0], aaLeftReal[0]), aaLeftImag[0], aaLeftImag[0] ) >> FLTR_SCALE ) + - ( fMultAddDiv2( fMultDiv2(aaLeftReal[7], aaLeftReal[7]), aaLeftImag[7], aaLeftImag[7] ) >> FLTR_SCALE ); - - aaPowerSlot[1] = ( fMultAddDiv2( fMultDiv2(aaLeftReal[1], aaLeftReal[1]), aaLeftImag[1], aaLeftImag[1] ) >> FLTR_SCALE ) + - ( fMultAddDiv2( fMultDiv2(aaLeftReal[6], aaLeftReal[6]), aaLeftImag[6], aaLeftImag[6] ) >> FLTR_SCALE ); - - aaPowerSlot[2] = fMultAddDiv2( fMultDiv2(aaLeftReal[2], aaLeftReal[2]), aaLeftImag[2], aaLeftImag[2] ) >> FLTR_SCALE; - aaPowerSlot[3] = fMultAddDiv2( fMultDiv2(aaLeftReal[3], aaLeftReal[3]), aaLeftImag[3], aaLeftImag[3] ) >> FLTR_SCALE; - - aaPowerSlot[4] = fMultAddDiv2( fMultDiv2(aaLeftReal[9], aaLeftReal[9]), aaLeftImag[9], aaLeftImag[9] ) >> FLTR_SCALE; - aaPowerSlot[5] = fMultAddDiv2( fMultDiv2(aaLeftReal[8], aaLeftReal[8]), aaLeftImag[8], aaLeftImag[8] ) >> FLTR_SCALE; - - aaPowerSlot[6] = fMultAddDiv2( fMultDiv2(aaLeftReal[10], aaLeftReal[10]), aaLeftImag[10], aaLeftImag[10] ) >> FLTR_SCALE; - aaPowerSlot[7] = fMultAddDiv2( fMultDiv2(aaLeftReal[11], aaLeftReal[11]), aaLeftImag[11], aaLeftImag[11] ) >> FLTR_SCALE; - - /* qmf bands (parameter index 8 - 19) */ - for ( bin = 8; bin < NO_MID_RES_BINS; bin++ ) { - FIXP_DBL slotNrg = FL2FXCONST_DBL(0.f); - - for ( i = groupBorders20[bin+2]; i < groupBorders20[bin+3]; i++ ) { /* max loops: 29 */ - slotNrg += fMultAddDiv2 ( fMultDiv2(rIntBufferLeft[i], rIntBufferLeft[i]), iIntBufferLeft[i], iIntBufferLeft[i]) >> FLTR_SCALE; - } - aaPowerSlot[bin] = slotNrg; - - } - - - /* calculation of transient ratio */ - for (bin=0; bin < NO_MID_RES_BINS; bin++) { /* noBins = 20 ( BASELINE_PS ) */ - - h_ps_d->specificTo.mpeg.aPeakDecayFastBin[bin] = fMult( h_ps_d->specificTo.mpeg.aPeakDecayFastBin[bin], PEAK_DECAY_FACTOR ); - - if (h_ps_d->specificTo.mpeg.aPeakDecayFastBin[bin] < aaPowerSlot[bin]) { - h_ps_d->specificTo.mpeg.aPeakDecayFastBin[bin] = aaPowerSlot[bin]; - } - - /* calculate PSmoothPeakDecayDiffNrg */ - peakDiff = fMultAdd ( (h_ps_d->specificTo.mpeg.aPrevPeakDiffBin[bin]>>1), - INT_FILTER_COEFF, h_ps_d->specificTo.mpeg.aPeakDecayFastBin[bin] - aaPowerSlot[bin] - h_ps_d->specificTo.mpeg.aPrevPeakDiffBin[bin]); - - /* save peakDiff for the next frame */ - h_ps_d->specificTo.mpeg.aPrevPeakDiffBin[bin] = peakDiff; - - nrg = h_ps_d->specificTo.mpeg.aPrevNrgBin[bin] + fMult( INT_FILTER_COEFF, aaPowerSlot[bin] - h_ps_d->specificTo.mpeg.aPrevNrgBin[bin] ); - - /* Negative energies don't exist. But sometimes they appear due to rounding. */ - - nrg = fixMax(nrg,FL2FXCONST_DBL(0.f)); - - /* save nrg for the next frame */ - h_ps_d->specificTo.mpeg.aPrevNrgBin[bin] = nrg; - - nrg = fMult( nrg, TRANSIENT_IMPACT_FACTOR ); - - /* save transient impact factor */ - if ( peakDiff <= nrg || peakDiff == FL2FXCONST_DBL(0.0) ) { - aaTransRatioSlot[bin] = (FIXP_DBL)MAXVAL_DBL /* FL2FXCONST_DBL(1.0f)*/; - } - else if ( nrg <= FL2FXCONST_DBL(0.0f) ) { - aaTransRatioSlot[bin] = FL2FXCONST_DBL(0.f); - } - else { - /* scale to denominator */ - INT scale_left = fixMax(0, CntLeadingZeros(peakDiff) - 1); - aaTransRatioSlot[bin] = schur_div( nrg<<scale_left, peakDiff<<scale_left, 16); - } - } /* bin */ - - - - - #define DELAY_GROUP_OFFSET 20 - #define NR_OF_DELAY_GROUPS 2 - - FIXP_DBL rTmp, iTmp, rTmp0, iTmp0, rR0, iR0; - - INT TempDelay = h_ps_d->specificTo.mpeg.delayBufIndex; /* set delay indices */ - - pRealDelayBuffer = h_ps_d->specificTo.mpeg.aaRealDelayBufferSubQmf[TempDelay]; - pImagDelayBuffer = h_ps_d->specificTo.mpeg.aaImagDelayBufferSubQmf[TempDelay]; - - aaLeftReal = mHybridRealLeft; - aaLeftImag = mHybridImagLeft; - aaRightReal = mHybridRealRight; - aaRightImag = mHybridImagRight; - - /************************/ - /* ICC groups : 0 - 9 */ - /************************/ - - /* gr = ICC groups */ - for (gr=0; gr < SUBQMF_GROUPS; gr++) { - - transRatio = aaTransRatioSlot[bins2groupMap20[gr]]; - - /* sb = subQMF/QMF subband */ - sb = groupBorders20[gr]; - - /* Update delay buffers, sample delay allpass = 2 */ - rTmp0 = pRealDelayBuffer[sb]; - iTmp0 = pImagDelayBuffer[sb]; - - pRealDelayBuffer[sb] = aaLeftReal[sb]; - pImagDelayBuffer[sb] = aaLeftImag[sb]; - - /* delay by fraction */ - cplxMultDiv2(&rR0, &iR0, rTmp0, iTmp0, aaFractDelayPhaseFactorReSubQmf20[sb], aaFractDelayPhaseFactorImSubQmf20[sb]); - rR0<<=1; - iR0<<=1; - - FIXP_DBL *pAaaRealDelayRBufferSerSubQmf = h_ps_d->specificTo.mpeg.aaaRealDelayRBufferSerSubQmf[sb]; - FIXP_DBL *pAaaImagDelayRBufferSerSubQmf = h_ps_d->specificTo.mpeg.aaaImagDelayRBufferSerSubQmf[sb]; - - for (m=0; m<NO_SERIAL_ALLPASS_LINKS ; m++) { - - INT tmpDelayRSer = h_ps_d->specificTo.mpeg.aDelayRBufIndexSer[m]; - - /* get delayed values from according buffer : m(0)=3; m(1)=4; m(2)=5; */ - rTmp0 = pAaaRealDelayRBufferSerSubQmf[tmpDelayRSer]; - iTmp0 = pAaaImagDelayRBufferSerSubQmf[tmpDelayRSer]; - - /* delay by fraction */ - cplxMultDiv2(&rTmp, &iTmp, rTmp0, iTmp0, aaFractDelayPhaseFactorSerReSubQmf20[sb][m], aaFractDelayPhaseFactorSerImSubQmf20[sb][m]); - - rTmp = (rTmp - fMultDiv2(aAllpassLinkDecaySer[m], rR0)) << 1; - iTmp = (iTmp - fMultDiv2(aAllpassLinkDecaySer[m], iR0)) << 1; - - pAaaRealDelayRBufferSerSubQmf[tmpDelayRSer] = rR0 + fMult(aAllpassLinkDecaySer[m], rTmp); - pAaaImagDelayRBufferSerSubQmf[tmpDelayRSer] = iR0 + fMult(aAllpassLinkDecaySer[m], iTmp); - - rR0 = rTmp; - iR0 = iTmp; - - pAaaRealDelayRBufferSerSubQmf += aAllpassLinkDelaySer[m]; - pAaaImagDelayRBufferSerSubQmf += aAllpassLinkDelaySer[m]; - - } /* m */ - - /* duck if a past transient is found */ - aaRightReal[sb] = fMult(transRatio, rR0); - aaRightImag[sb] = fMult(transRatio, iR0); - - } /* gr */ - - - scaleValues( mHybridRealLeft, NO_SUB_QMF_CHANNELS, -SCAL_HEADROOM ); - scaleValues( mHybridImagLeft, NO_SUB_QMF_CHANNELS, -SCAL_HEADROOM ); - scaleValues( mHybridRealRight, NO_SUB_QMF_CHANNELS, -SCAL_HEADROOM ); - scaleValues( mHybridImagRight, NO_SUB_QMF_CHANNELS, -SCAL_HEADROOM ); - - - /************************/ - - aaLeftReal = rIntBufferLeft; - aaLeftImag = iIntBufferLeft; - aaRightReal = rIntBufferRight; - aaRightImag = iIntBufferRight; - - pRealDelayBuffer = h_ps_d->specificTo.mpeg.aaRealDelayBufferQmf[TempDelay]; - pImagDelayBuffer = h_ps_d->specificTo.mpeg.aaImagDelayBufferQmf[TempDelay]; - - /************************/ - /* ICC groups : 10 - 19 */ - /************************/ - - - /* gr = ICC groups */ - for (gr=SUBQMF_GROUPS; gr < NO_IID_GROUPS - NR_OF_DELAY_GROUPS; gr++) { - - transRatio = aaTransRatioSlot[bins2groupMap20[gr]]; - - /* sb = subQMF/QMF subband */ - for (sb = groupBorders20[gr]; sb < groupBorders20[gr+1]; sb++) { - FIXP_DBL resR, resI; - - /* decayScaleFactor = 1.0f + decay_cutoff * DECAY_SLOPE - DECAY_SLOPE * sb; DECAY_SLOPE = 0.05 */ - FIXP_DBL decayScaleFactor = decayScaleFactTable[sb]; - - /* Update delay buffers, sample delay allpass = 2 */ - rTmp0 = pRealDelayBuffer[sb]; - iTmp0 = pImagDelayBuffer[sb]; - - pRealDelayBuffer[sb] = aaLeftReal[sb]; - pImagDelayBuffer[sb] = aaLeftImag[sb]; - - /* delay by fraction */ - cplxMultDiv2(&rR0, &iR0, rTmp0, iTmp0, aaFractDelayPhaseFactorReQmf[sb], aaFractDelayPhaseFactorImQmf[sb]); - rR0<<=1; - iR0<<=1; - - resR = fMult(decayScaleFactor, rR0); - resI = fMult(decayScaleFactor, iR0); - - FIXP_DBL *pAaaRealDelayRBufferSerQmf = h_ps_d->specificTo.mpeg.aaaRealDelayRBufferSerQmf[sb]; - FIXP_DBL *pAaaImagDelayRBufferSerQmf = h_ps_d->specificTo.mpeg.aaaImagDelayRBufferSerQmf[sb]; - - for (m=0; m<NO_SERIAL_ALLPASS_LINKS ; m++) { - - INT tmpDelayRSer = h_ps_d->specificTo.mpeg.aDelayRBufIndexSer[m]; - - /* get delayed values from according buffer : m(0)=3; m(1)=4; m(2)=5; */ - rTmp0 = pAaaRealDelayRBufferSerQmf[tmpDelayRSer]; - iTmp0 = pAaaImagDelayRBufferSerQmf[tmpDelayRSer]; - - /* delay by fraction */ - cplxMultDiv2(&rTmp, &iTmp, rTmp0, iTmp0, aaFractDelayPhaseFactorSerReQmf[sb][m], aaFractDelayPhaseFactorSerImQmf[sb][m]); - - rTmp = (rTmp - fMultDiv2(aAllpassLinkDecaySer[m], resR))<<1; - iTmp = (iTmp - fMultDiv2(aAllpassLinkDecaySer[m], resI))<<1; - - resR = fMult(decayScaleFactor, rTmp); - resI = fMult(decayScaleFactor, iTmp); - - pAaaRealDelayRBufferSerQmf[tmpDelayRSer] = rR0 + fMult(aAllpassLinkDecaySer[m], resR); - pAaaImagDelayRBufferSerQmf[tmpDelayRSer] = iR0 + fMult(aAllpassLinkDecaySer[m], resI); - - rR0 = rTmp; - iR0 = iTmp; - - pAaaRealDelayRBufferSerQmf += aAllpassLinkDelaySer[m]; - pAaaImagDelayRBufferSerQmf += aAllpassLinkDelaySer[m]; - - } /* m */ - - /* duck if a past transient is found */ - aaRightReal[sb] = fMult(transRatio, rR0); - aaRightImag[sb] = fMult(transRatio, iR0); - - } /* sb */ - } /* gr */ - - /************************/ - /* ICC groups : 20, 21 */ - /************************/ - - - /* gr = ICC groups */ - for (gr=DELAY_GROUP_OFFSET; gr < NO_IID_GROUPS; gr++) { - - INT sbStart = groupBorders20[gr]; - INT sbStop = groupBorders20[gr+1]; - - UCHAR *pDelayBufIdx = &h_ps_d->specificTo.mpeg.aDelayBufIndexDelayQmf[sbStart-FIRST_DELAY_SB]; - - transRatio = aaTransRatioSlot[bins2groupMap20[gr]]; - - /* sb = subQMF/QMF subband */ - for (sb = sbStart; sb < sbStop; sb++) { - - /* Update delay buffers */ - rR0 = h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[*pDelayBufIdx][sb-FIRST_DELAY_SB]; - iR0 = h_ps_d->specificTo.mpeg.pAaImagDelayBufferQmf[*pDelayBufIdx][sb-FIRST_DELAY_SB]; - - h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[*pDelayBufIdx][sb-FIRST_DELAY_SB] = aaLeftReal[sb]; - h_ps_d->specificTo.mpeg.pAaImagDelayBufferQmf[*pDelayBufIdx][sb-FIRST_DELAY_SB] = aaLeftImag[sb]; - - /* duck if a past transient is found */ - aaRightReal[sb] = fMult(transRatio, rR0); - aaRightImag[sb] = fMult(transRatio, iR0); - - if (++(*pDelayBufIdx) >= delayIndexQmf[sb]) { - *pDelayBufIdx = 0; - } - pDelayBufIdx++; - - } /* sb */ - } /* gr */ - - - /* Update delay buffer index */ - if (++h_ps_d->specificTo.mpeg.delayBufIndex >= NO_SAMPLE_DELAY_ALLPASS) - h_ps_d->specificTo.mpeg.delayBufIndex = 0; - - for (m=0; m<NO_SERIAL_ALLPASS_LINKS ; m++) { - if (++h_ps_d->specificTo.mpeg.aDelayRBufIndexSer[m] >= aAllpassLinkDelaySer[m]) - h_ps_d->specificTo.mpeg.aDelayRBufIndexSer[m] = 0; - } - - - scaleValues( &rIntBufferLeft[NO_QMF_BANDS_HYBRID20], NO_QMF_CHANNELS-NO_QMF_BANDS_HYBRID20, -SCAL_HEADROOM ); - scaleValues( &iIntBufferLeft[NO_QMF_BANDS_HYBRID20], NO_QMF_CHANNELS-NO_QMF_BANDS_HYBRID20, -SCAL_HEADROOM ); - scaleValues( &rIntBufferRight[NO_QMF_BANDS_HYBRID20], NO_QMF_CHANNELS-NO_QMF_BANDS_HYBRID20, -SCAL_HEADROOM ); - scaleValues( &iIntBufferRight[NO_QMF_BANDS_HYBRID20], NO_QMF_CHANNELS-NO_QMF_BANDS_HYBRID20, -SCAL_HEADROOM ); - - /* free memory on scratch */ - C_ALLOC_SCRATCH_END(aaTransRatioSlot, FIXP_DBL, NO_MID_RES_BINS); - C_ALLOC_SCRATCH_END(aaPowerSlot, FIXP_DBL, NO_MID_RES_BINS); -} - - -void initSlotBasedRotation( HANDLE_PS_DEC h_ps_d, /*!< pointer to the module state */ - int env, - int usb - ) { - - INT group = 0; - INT bin = 0; - INT noIidSteps; - -/* const UCHAR *pQuantizedIIDs;*/ - - FIXP_SGL invL; - FIXP_DBL ScaleL, ScaleR; - FIXP_DBL Alpha, Beta; - FIXP_DBL h11r, h12r, h21r, h22r; - - const FIXP_DBL *PScaleFactors; - - /* Overwrite old values in delay buffers when upper subband is higher than in last frame */ - if (env == 0) { - - if ((usb > h_ps_d->specificTo.mpeg.lastUsb) && h_ps_d->specificTo.mpeg.lastUsb) { - - INT i,k,length; - - for (i=h_ps_d->specificTo.mpeg.lastUsb ; i < FIRST_DELAY_SB; i++) { - FDKmemclear(h_ps_d->specificTo.mpeg.aaaRealDelayRBufferSerQmf[i], NO_DELAY_LENGTH_VECTORS*sizeof(FIXP_DBL)); - FDKmemclear(h_ps_d->specificTo.mpeg.aaaImagDelayRBufferSerQmf[i], NO_DELAY_LENGTH_VECTORS*sizeof(FIXP_DBL)); - } - - for (k=0 ; k<NO_SAMPLE_DELAY_ALLPASS; k++) { - FDKmemclear(h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[k], FIRST_DELAY_SB*sizeof(FIXP_DBL)); - } - length = (usb-FIRST_DELAY_SB)*sizeof(FIXP_DBL); - if(length>0) { - FDKmemclear(h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[0], length); - FDKmemclear(h_ps_d->specificTo.mpeg.pAaImagDelayBufferQmf[0], length); - } - length = (fixMin(NO_DELAY_BUFFER_BANDS,(INT)usb)-FIRST_DELAY_SB)*sizeof(FIXP_DBL); - if(length>0) { - for (k=1 ; k < h_ps_d->specificTo.mpeg.noSampleDelay; k++) { - FDKmemclear(h_ps_d->specificTo.mpeg.pAaRealDelayBufferQmf[k], length); - FDKmemclear(h_ps_d->specificTo.mpeg.pAaImagDelayBufferQmf[k], length); - } - } - } - h_ps_d->specificTo.mpeg.lastUsb = usb; - } /* env == 0 */ - - if (h_ps_d->bsData[h_ps_d->processSlot].mpeg.bFineIidQ) - { - PScaleFactors = ScaleFactorsFine; /* values are shiftet right by one */ - noIidSteps = NO_IID_STEPS_FINE; - /*pQuantizedIIDs = quantizedIIDsFine;*/ - } - - else - { - PScaleFactors = ScaleFactors; /* values are shiftet right by one */ - noIidSteps = NO_IID_STEPS; - /*pQuantizedIIDs = quantizedIIDs;*/ - } - - - /* dequantize and decode */ - for ( group = 0; group < NO_IID_GROUPS; group++ ) { - - bin = bins2groupMap20[group]; - - /*! - <h3> type 'A' rotation </h3> - mixing procedure R_a, used in baseline version<br> - - Scale-factor vectors c1 and c2 are precalculated in initPsTables () and stored in - scaleFactors[] and scaleFactorsFine[] = pScaleFactors []. - From the linearized IID parameters (intensity differences), two scale factors are - calculated. They are used to obtain the coefficients h11... h22. - */ - - /* ScaleR and ScaleL are scaled by 1 shift right */ - - ScaleR = PScaleFactors[noIidSteps + h_ps_d->specificTo.mpeg.coef.aaIidIndexMapped[env][bin]]; - ScaleL = PScaleFactors[noIidSteps - h_ps_d->specificTo.mpeg.coef.aaIidIndexMapped[env][bin]]; - - Beta = fMult (fMult( Alphas[h_ps_d->specificTo.mpeg.coef.aaIccIndexMapped[env][bin]], ( ScaleR - ScaleL )), FIXP_SQRT05); - Alpha = Alphas[h_ps_d->specificTo.mpeg.coef.aaIccIndexMapped[env][bin]]>>1; - - /* Alpha and Beta are now both scaled by 2 shifts right */ - - /* calculate the coefficients h11... h22 from scale-factors and ICC parameters */ - - /* h values are scaled by 1 shift right */ - { - FIXP_DBL trigData[4]; - - inline_fixp_cos_sin(Beta + Alpha, Beta - Alpha, 2, trigData); - h11r = fMult( ScaleL, trigData[0]); - h12r = fMult( ScaleR, trigData[2]); - h21r = fMult( ScaleL, trigData[1]); - h22r = fMult( ScaleR, trigData[3]); - } - /*****************************************************************************************/ - /* Interpolation of the matrices H11... H22: */ - /* */ - /* H11(k,n) = H11(k,n[e]) + (n-n[e]) * (H11(k,n[e+1] - H11(k,n[e])) / (n[e+1] - n[e]) */ - /* ... */ - /*****************************************************************************************/ - - /* invL = 1/(length of envelope) */ - 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])); - - h_ps_d->specificTo.mpeg.coef.H11r[group] = h_ps_d->specificTo.mpeg.h11rPrev[group]; - h_ps_d->specificTo.mpeg.coef.H12r[group] = h_ps_d->specificTo.mpeg.h12rPrev[group]; - h_ps_d->specificTo.mpeg.coef.H21r[group] = h_ps_d->specificTo.mpeg.h21rPrev[group]; - h_ps_d->specificTo.mpeg.coef.H22r[group] = h_ps_d->specificTo.mpeg.h22rPrev[group]; - - h_ps_d->specificTo.mpeg.coef.DeltaH11r[group] = fMult ( h11r - h_ps_d->specificTo.mpeg.coef.H11r[group], invL ); - h_ps_d->specificTo.mpeg.coef.DeltaH12r[group] = fMult ( h12r - h_ps_d->specificTo.mpeg.coef.H12r[group], invL ); - h_ps_d->specificTo.mpeg.coef.DeltaH21r[group] = fMult ( h21r - h_ps_d->specificTo.mpeg.coef.H21r[group], invL ); - h_ps_d->specificTo.mpeg.coef.DeltaH22r[group] = fMult ( h22r - h_ps_d->specificTo.mpeg.coef.H22r[group], invL ); - - /* update prev coefficients for interpolation in next envelope */ - - h_ps_d->specificTo.mpeg.h11rPrev[group] = h11r; - h_ps_d->specificTo.mpeg.h12rPrev[group] = h12r; - h_ps_d->specificTo.mpeg.h21rPrev[group] = h21r; - h_ps_d->specificTo.mpeg.h22rPrev[group] = h22r; - - } /* group loop */ -} - - -static void applySlotBasedRotation( HANDLE_PS_DEC h_ps_d, /*!< pointer to the module state */ - - FIXP_DBL *mHybridRealLeft, /*!< hybrid values real left */ - FIXP_DBL *mHybridImagLeft, /*!< hybrid values imag left */ - - FIXP_DBL *QmfLeftReal, /*!< real bands left qmf channel */ - FIXP_DBL *QmfLeftImag, /*!< imag bands left qmf channel */ - - FIXP_DBL *mHybridRealRight, /*!< hybrid values real right */ - FIXP_DBL *mHybridImagRight, /*!< hybrid values imag right */ - - FIXP_DBL *QmfRightReal, /*!< real bands right qmf channel */ - FIXP_DBL *QmfRightImag /*!< imag bands right qmf channel */ - ) -{ - INT group; - INT subband; - - FIXP_DBL *RESTRICT HybrLeftReal; - FIXP_DBL *RESTRICT HybrLeftImag; - FIXP_DBL *RESTRICT HybrRightReal; - FIXP_DBL *RESTRICT HybrRightImag; - - FIXP_DBL tmpLeft, tmpRight; - - - /**********************************************************************************************/ - /*! - <h2> Mapping </h2> - - The number of stereo bands that is actually used depends on the number of availble - parameters for IID and ICC: - <pre> - nr. of IID para.| nr. of ICC para. | nr. of Stereo bands - ----------------|------------------|------------------- - 10,20 | 10,20 | 20 - 10,20 | 34 | 34 - 34 | 10,20 | 34 - 34 | 34 | 34 - </pre> - In the case the number of parameters for IIS and ICC differs from the number of stereo - bands, a mapping from the lower number to the higher number of parameters is applied. - Index mapping of IID and ICC parameters is already done in psbitdec.cpp. Further mapping is - not needed here in baseline version. - **********************************************************************************************/ - - /************************************************************************************************/ - /*! - <h2> Mixing </h2> - - To generate the QMF subband signals for the subband samples n = n[e]+1 ,,, n_[e+1] the - parameters at position n[e] and n[e+1] are required as well as the subband domain signals - s_k(n) and d_k(n) for n = n[e]+1... n_[e+1]. n[e] represents the start position for - envelope e. The border positions n[e] are handled in DecodePS(). - - The stereo sub subband signals are constructed as: - <pre> - l_k(n) = H11(k,n) s_k(n) + H21(k,n) d_k(n) - r_k(n) = H21(k,n) s_k(n) + H22(k,n) d_k(n) - </pre> - In order to obtain the matrices H11(k,n)... H22 (k,n), the vectors h11(b)... h22(b) need to - be calculated first (b: parameter index). Depending on ICC mode either mixing procedure R_a - or R_b is used for that. For both procedures, the parameters for parameter position n[e+1] - is used. - ************************************************************************************************/ - - - /************************************************************************************************/ - /*! - <h2>Phase parameters </h2> - With disabled phase parameters (which is the case in baseline version), the H-matrices are - just calculated by: - - <pre> - H11(k,n[e+1] = h11(b(k)) - (...) - b(k): parameter index according to mapping table - </pre> - - <h2>Processing of the samples in the sub subbands </h2> - this loop includes the interpolation of the coefficients Hxx - ************************************************************************************************/ - - - /* loop thru all groups ... */ - HybrLeftReal = mHybridRealLeft; - HybrLeftImag = mHybridImagLeft; - HybrRightReal = mHybridRealRight; - HybrRightImag = mHybridImagRight; - - /******************************************************/ - /* construct stereo sub subband signals according to: */ - /* */ - /* l_k(n) = H11(k,n) s_k(n) + H21(k,n) d_k(n) */ - /* r_k(n) = H12(k,n) s_k(n) + H22(k,n) d_k(n) */ - /******************************************************/ - for ( group = 0; group < SUBQMF_GROUPS; group++ ) { - - h_ps_d->specificTo.mpeg.coef.H11r[group] += h_ps_d->specificTo.mpeg.coef.DeltaH11r[group]; - h_ps_d->specificTo.mpeg.coef.H12r[group] += h_ps_d->specificTo.mpeg.coef.DeltaH12r[group]; - h_ps_d->specificTo.mpeg.coef.H21r[group] += h_ps_d->specificTo.mpeg.coef.DeltaH21r[group]; - h_ps_d->specificTo.mpeg.coef.H22r[group] += h_ps_d->specificTo.mpeg.coef.DeltaH22r[group]; - - subband = groupBorders20[group]; - - tmpLeft = fMultAddDiv2( fMultDiv2(h_ps_d->specificTo.mpeg.coef.H11r[group], HybrLeftReal[subband]), h_ps_d->specificTo.mpeg.coef.H21r[group], HybrRightReal[subband]); - tmpRight = fMultAddDiv2( fMultDiv2(h_ps_d->specificTo.mpeg.coef.H12r[group], HybrLeftReal[subband]), h_ps_d->specificTo.mpeg.coef.H22r[group], HybrRightReal[subband]); - HybrLeftReal [subband] = tmpLeft<<1; - HybrRightReal[subband] = tmpRight<<1; - - tmpLeft = fMultAdd( fMultDiv2(h_ps_d->specificTo.mpeg.coef.H11r[group], HybrLeftImag[subband]), h_ps_d->specificTo.mpeg.coef.H21r[group], HybrRightImag[subband]); - tmpRight = fMultAdd( fMultDiv2(h_ps_d->specificTo.mpeg.coef.H12r[group], HybrLeftImag[subband]), h_ps_d->specificTo.mpeg.coef.H22r[group], HybrRightImag[subband]); - HybrLeftImag [subband] = tmpLeft; - HybrRightImag[subband] = tmpRight; - } - - /* continue in the qmf buffers */ - HybrLeftReal = QmfLeftReal; - HybrLeftImag = QmfLeftImag; - HybrRightReal = QmfRightReal; - HybrRightImag = QmfRightImag; - - for (; group < NO_IID_GROUPS; group++ ) { - - h_ps_d->specificTo.mpeg.coef.H11r[group] += h_ps_d->specificTo.mpeg.coef.DeltaH11r[group]; - h_ps_d->specificTo.mpeg.coef.H12r[group] += h_ps_d->specificTo.mpeg.coef.DeltaH12r[group]; - h_ps_d->specificTo.mpeg.coef.H21r[group] += h_ps_d->specificTo.mpeg.coef.DeltaH21r[group]; - h_ps_d->specificTo.mpeg.coef.H22r[group] += h_ps_d->specificTo.mpeg.coef.DeltaH22r[group]; - - for ( subband = groupBorders20[group]; subband < groupBorders20[group + 1]; subband++ ) - { - tmpLeft = fMultAdd( fMultDiv2(h_ps_d->specificTo.mpeg.coef.H11r[group], HybrLeftReal[subband]), h_ps_d->specificTo.mpeg.coef.H21r[group], HybrRightReal[subband]); - tmpRight = fMultAdd( fMultDiv2(h_ps_d->specificTo.mpeg.coef.H12r[group], HybrLeftReal[subband]), h_ps_d->specificTo.mpeg.coef.H22r[group], HybrRightReal[subband]); - HybrLeftReal [subband] = tmpLeft; - HybrRightReal[subband] = tmpRight; - - tmpLeft = fMultAdd( fMultDiv2(h_ps_d->specificTo.mpeg.coef.H11r[group], HybrLeftImag[subband]), h_ps_d->specificTo.mpeg.coef.H21r[group], HybrRightImag[subband]); - tmpRight = fMultAdd( fMultDiv2(h_ps_d->specificTo.mpeg.coef.H12r[group], HybrLeftImag[subband]), h_ps_d->specificTo.mpeg.coef.H22r[group], HybrRightImag[subband]); - HybrLeftImag [subband] = tmpLeft; - HybrRightImag[subband] = tmpRight; - - } /* subband */ - } -} - - -/***************************************************************************/ -/*! - \brief Applies IID, ICC, IPD and OPD parameters to the current frame. - - \return none - -****************************************************************************/ -void -ApplyPsSlot( HANDLE_PS_DEC h_ps_d, /*!< handle PS_DEC*/ - FIXP_DBL **rIntBufferLeft, /*!< real bands left qmf channel (38x64) */ - FIXP_DBL **iIntBufferLeft, /*!< imag bands left qmf channel (38x64) */ - FIXP_DBL *rIntBufferRight, /*!< real bands right qmf channel (38x64) */ - FIXP_DBL *iIntBufferRight /*!< imag bands right qmf channel (38x64) */ - ) -{ - - /*! - The 64-band QMF representation of the monaural signal generated by the SBR tool - is used as input of the PS tool. After the PS processing, the outputs of the left - and right hybrid synthesis filterbanks are used to generate the stereo output - signal. - - <pre> - - ------------- ---------- ------------- - | Hybrid | M_n[k,m] | | L_n[k,m] | Hybrid | l[n] - m[n] --->| analysis |--------->| |--------->| synthesis |-----> - | filter bank | | | | filter bank | - ------------- | Stereo | ------------- - | | recon- | - | | stuction | - \|/ | | - ------------- | | - | De- | D_n[k,m] | | - | correlation |--------->| | - ------------- | | ------------- - | | R_n[k,m] | Hybrid | r[n] - | |--------->| synthesis |-----> - IID, ICC ------------------------>| | | filter bank | - (IPD, OPD) ---------- ------------- - - m[n]: QMF represantation of the mono input - M_n[k,m]: (sub-)sub-band domain signals of the mono input - D_n[k,m]: decorrelated (sub-)sub-band domain signals - L_n[k,m]: (sub-)sub-band domain signals of the left output - R_n[k,m]: (sub-)sub-band domain signals of the right output - l[n],r[n]: left/right output signals - - </pre> - */ - - /* get temporary hybrid qmf values of one timeslot */ - C_ALLOC_SCRATCH_START(hybridRealLeft, FIXP_DBL, NO_SUB_QMF_CHANNELS); - C_ALLOC_SCRATCH_START(hybridImagLeft, FIXP_DBL, NO_SUB_QMF_CHANNELS); - C_ALLOC_SCRATCH_START(hybridRealRight, FIXP_DBL, NO_SUB_QMF_CHANNELS); - C_ALLOC_SCRATCH_START(hybridImagRight, FIXP_DBL, NO_SUB_QMF_CHANNELS); - - SCHAR sf_IntBuffer = h_ps_d->sf_IntBuffer; - - /* clear workbuffer */ - FDKmemclear(hybridRealLeft, NO_SUB_QMF_CHANNELS*sizeof(FIXP_DBL)); - FDKmemclear(hybridImagLeft, NO_SUB_QMF_CHANNELS*sizeof(FIXP_DBL)); - FDKmemclear(hybridRealRight, NO_SUB_QMF_CHANNELS*sizeof(FIXP_DBL)); - FDKmemclear(hybridImagRight, NO_SUB_QMF_CHANNELS*sizeof(FIXP_DBL)); - - - /*! - Hybrid analysis filterbank: - The lower 3 (5) of the 64 QMF subbands are further split to provide better frequency resolution. - for PS processing. - For the 10 and 20 stereo bands configuration, the QMF band H_0(w) is split - up into 8 (sub-) sub-bands and the QMF bands H_1(w) and H_2(w) are spit into 2 (sub-) - 4th. (See figures 8.20 and 8.22 of ISO/IEC 14496-3:2001/FDAM 2:2004(E) ) - */ - - - if (h_ps_d->procFrameBased == 1) /* If we have switched from frame to slot based processing */ - { /* fill hybrid delay buffer. */ - h_ps_d->procFrameBased = 0; - - fillHybridDelayLine( rIntBufferLeft, - iIntBufferLeft, - hybridRealLeft, - hybridImagLeft, - hybridRealRight, - hybridImagRight, - &h_ps_d->specificTo.mpeg.hybrid ); - } - - slotBasedHybridAnalysis ( rIntBufferLeft[HYBRID_FILTER_DELAY], /* qmf filterbank values */ - iIntBufferLeft[HYBRID_FILTER_DELAY], /* qmf filterbank values */ - hybridRealLeft, /* hybrid filterbank values */ - hybridImagLeft, /* hybrid filterbank values */ - &h_ps_d->specificTo.mpeg.hybrid); /* hybrid filterbank handle */ - - - SCHAR hybridScal = h_ps_d->specificTo.mpeg.hybrid.sf_mQmfBuffer; - - - /*! - Decorrelation: - By means of all-pass filtering and delaying, the (sub-)sub-band samples s_k(n) are - converted into de-correlated (sub-)sub-band samples d_k(n). - - k: frequency in hybrid spectrum - - n: time index - */ - - deCorrelateSlotBased( h_ps_d, /* parametric stereo decoder handle */ - hybridRealLeft, /* left hybrid time slot */ - hybridImagLeft, - hybridScal, /* scale factor of left hybrid time slot */ - rIntBufferLeft[0], /* left qmf time slot */ - iIntBufferLeft[0], - sf_IntBuffer, /* scale factor of left and right qmf time slot */ - hybridRealRight, /* right hybrid time slot */ - hybridImagRight, - rIntBufferRight, /* right qmf time slot */ - iIntBufferRight ); - - - - /*! - Stereo Processing: - The sets of (sub-)sub-band samples s_k(n) and d_k(n) are processed according to - the stereo cues which are defined per stereo band. - */ - - - applySlotBasedRotation( h_ps_d, /* parametric stereo decoder handle */ - hybridRealLeft, /* left hybrid time slot */ - hybridImagLeft, - rIntBufferLeft[0], /* left qmf time slot */ - iIntBufferLeft[0], - hybridRealRight, /* right hybrid time slot */ - hybridImagRight, - rIntBufferRight, /* right qmf time slot */ - iIntBufferRight ); - - - - - /*! - Hybrid synthesis filterbank: - The stereo processed hybrid subband signals l_k(n) and r_k(n) are fed into the hybrid synthesis - filterbanks which are identical to the 64 complex synthesis filterbank of the SBR tool. The - input to the filterbank are slots of 64 QMF samples. For each slot the filterbank outputs one - block of 64 samples of one reconstructed stereo channel. The hybrid synthesis filterbank is - computed seperatly for the left and right channel. - */ - - - /* left channel */ - slotBasedHybridSynthesis ( hybridRealLeft, /* one timeslot of hybrid filterbank values */ - hybridImagLeft, - rIntBufferLeft[0], /* one timeslot of qmf filterbank values */ - iIntBufferLeft[0], - &h_ps_d->specificTo.mpeg.hybrid ); /* hybrid filterbank handle */ - - /* right channel */ - slotBasedHybridSynthesis ( hybridRealRight, /* one timeslot of hybrid filterbank values */ - hybridImagRight, - rIntBufferRight, /* one timeslot of qmf filterbank values */ - iIntBufferRight, - &h_ps_d->specificTo.mpeg.hybrid ); /* hybrid filterbank handle */ - - - - - - - - /* free temporary hybrid qmf values of one timeslot */ - C_ALLOC_SCRATCH_END(hybridImagRight, FIXP_DBL, NO_SUB_QMF_CHANNELS); - C_ALLOC_SCRATCH_END(hybridRealRight, FIXP_DBL, NO_SUB_QMF_CHANNELS); - C_ALLOC_SCRATCH_END(hybridImagLeft, FIXP_DBL, NO_SUB_QMF_CHANNELS); - C_ALLOC_SCRATCH_END(hybridRealLeft, FIXP_DBL, NO_SUB_QMF_CHANNELS); - -}/* END ApplyPsSlot */ - - -/***************************************************************************/ -/*! - - \brief assigns timeslots to an array - - \return - -****************************************************************************/ - -static void assignTimeSlotsPS (FIXP_DBL *bufAdr, - FIXP_DBL **bufPtr, - const int numSlots, - const int numChan) -{ - FIXP_DBL *ptr; - int slot; - ptr = bufAdr; - for(slot=0; slot < numSlots; slot++) { - bufPtr [slot] = ptr; - ptr += numChan; - } -} - |