/**************************************************************************** (C) Copyright Fraunhofer IIS (2005) All Rights Reserved Please be advised that this software and/or program delivery is Confidential Information of Fraunhofer and subject to and covered by the Fraunhofer IIS Software Evaluation Agreement between Google Inc. and Fraunhofer effective and in full force since March 1, 2012. You may use this software and/or program only under the terms and conditions described in the above mentioned Fraunhofer IIS Software Evaluation Agreement. Any other and/or further use requires a separate agreement. This software and/or program is protected by copyright law and international treaties. Any reproduction or distribution of this software and/or program, or any portion of it, may result in severe civil and criminal penalties, and will be prosecuted to the maximum extent possible under law. $Id$ *******************************************************************************/ /*! \file \brief Sbr decoder $Revision: 36841 $ */ #ifndef __PSDEC_H #define __PSDEC_H #include "sbrdecoder.h" /* This PS decoder implements the baseline version. So it always uses the */ /* hybrid filter structure for 20 stereo bands and does not implemet IPD/OPD */ /* synthesis. The baseline version has to support the complete PS bitstream */ /* syntax. But IPD/OPD data is ignored and set to 0. If 34 stereo band config */ /* is used in the bitstream for IIS/ICC the decoded parameters are mapped to */ /* 20 stereo bands. */ #include "FDK_bitstream.h" #include "psdec_hybrid.h" #define SCAL_HEADROOM ( 2 ) #define PS_EXTENSION_SIZE_BITS ( 4 ) #define PS_EXTENSION_ESC_COUNT_BITS ( 8 ) #define NO_QMF_CHANNELS ( 64 ) #define MAX_NUM_COL ( 32 ) #define NO_QMF_BANDS_HYBRID20 ( 3 ) #define NO_SUB_QMF_CHANNELS ( 12 ) #define NRG_INT_COEFF ( 0.75f ) #define INT_FILTER_COEFF (FL2FXCONST_DBL( 1.0f - NRG_INT_COEFF )) #define PEAK_DECAY_FACTOR (FL2FXCONST_DBL( 0.765928338364649f )) #define TRANSIENT_IMPACT_FACTOR (FL2FXCONST_DBL( 2.0 / 3.0 )) #define NO_SERIAL_ALLPASS_LINKS ( 3 ) #define MAX_NO_PS_ENV ( 4 + 1 ) /* +1 needed for VAR_BORDER */ #define MAX_DELAY_BUFFER_SIZE ( 14 ) #define NO_DELAY_BUFFER_BANDS ( 35 ) #define NO_HI_RES_BINS ( 34 ) #define NO_MID_RES_BINS ( 20 ) #define NO_LOW_RES_BINS ( 10 ) #define FIRST_DELAY_SB ( 23 ) #define NO_SAMPLE_DELAY_ALLPASS ( 2 ) #define NO_DELAY_LENGTH_VECTORS ( 12 ) /* d(m): d(0)=3 + d(1)=4 + d(2)=5 */ #define NO_HI_RES_IID_BINS ( NO_HI_RES_BINS ) #define NO_HI_RES_ICC_BINS ( NO_HI_RES_BINS ) #define NO_MID_RES_IID_BINS ( NO_MID_RES_BINS ) #define NO_MID_RES_ICC_BINS ( NO_MID_RES_BINS ) #define NO_LOW_RES_IID_BINS ( NO_LOW_RES_BINS ) #define NO_LOW_RES_ICC_BINS ( NO_LOW_RES_BINS ) #define SUBQMF_GROUPS ( 10 ) #define QMF_GROUPS ( 12 ) #define SUBQMF_GROUPS_HI_RES ( 32 ) #define QMF_GROUPS_HI_RES ( 18 ) #define NO_IID_GROUPS ( SUBQMF_GROUPS + QMF_GROUPS ) #define NO_IID_GROUPS_HI_RES ( SUBQMF_GROUPS_HI_RES + QMF_GROUPS_HI_RES ) #define NO_IID_STEPS ( 7 ) /* 1 .. + 7 */ #define NO_IID_STEPS_FINE ( 15 ) /* 1 .. +15 */ #define NO_ICC_STEPS ( 8 ) /* 0 .. + 7 */ #define NO_IID_LEVELS ( 2 * NO_IID_STEPS + 1 ) /* - 7 .. + 7 */ #define NO_IID_LEVELS_FINE ( 2 * NO_IID_STEPS_FINE + 1 ) /* -15 .. +15 */ #define NO_ICC_LEVELS ( NO_ICC_STEPS ) /* 0 .. + 7 */ #define FIXP_SQRT05 ((FIXP_DBL)0x5a827980) /* 1/SQRT2 */ struct PS_DEC_COEFFICIENTS { FIXP_DBL H11r[NO_IID_GROUPS]; /*!< coefficients of the sub-subband groups */ FIXP_DBL H12r[NO_IID_GROUPS]; /*!< coefficients of the sub-subband groups */ FIXP_DBL H21r[NO_IID_GROUPS]; /*!< coefficients of the sub-subband groups */ FIXP_DBL H22r[NO_IID_GROUPS]; /*!< coefficients of the sub-subband groups */ FIXP_DBL DeltaH11r[NO_IID_GROUPS]; /*!< coefficients of the sub-subband groups */ FIXP_DBL DeltaH12r[NO_IID_GROUPS]; /*!< coefficients of the sub-subband groups */ FIXP_DBL DeltaH21r[NO_IID_GROUPS]; /*!< coefficients of the sub-subband groups */ FIXP_DBL DeltaH22r[NO_IID_GROUPS]; /*!< coefficients of the sub-subband groups */ SCHAR aaIidIndexMapped[MAX_NO_PS_ENV][NO_HI_RES_IID_BINS]; /*!< The mapped IID index for all envelopes and all IID bins */ SCHAR aaIccIndexMapped[MAX_NO_PS_ENV][NO_HI_RES_ICC_BINS]; /*!< The mapped ICC index for all envelopes and all ICC bins */ }; typedef enum { ppt_none = 0, ppt_mpeg = 1, ppt_drm = 2 } PS_PAYLOAD_TYPE; typedef struct { UCHAR bPsHeaderValid; /*!< set if new header is available from bitstream */ UCHAR bEnableIid; /*!< One bit denoting the presence of IID parameters */ UCHAR bEnableIcc; /*!< One bit denoting the presence of ICC parameters */ UCHAR bEnableExt; /*!< The PS extension layer is enabled using the enable_ext bit. If it is set to %1 the IPD and OPD parameters are sent. If it is disabled, i.e. %0, the extension layer is skipped. */ UCHAR modeIid; /*!< The configuration of IID parameters (number of bands and quantisation grid, iid_quant) is determined by iid_mode. */ UCHAR modeIcc; /*!< The configuration of Inter-channel Coherence parameters (number of bands and quantisation grid) is determined by icc_mode. */ UCHAR freqResIid; /*!< 0=low, 1=mid or 2=high frequency resolution for iid */ UCHAR freqResIcc; /*!< 0=low, 1=mid or 2=high frequency resolution for icc */ UCHAR bFineIidQ; /*!< Use fine Iid quantisation. */ UCHAR bFrameClass; /*!< The frame_class bit determines whether the parameter positions of the current frame are uniformly spaced accross the frame or they are defined using the positions described by border_position. */ UCHAR noEnv; /*!< The number of envelopes per frame */ UCHAR aEnvStartStop[MAX_NO_PS_ENV+1]; /*!< In case of variable parameter spacing the parameter positions are determined by border_position */ SCHAR abIidDtFlag[MAX_NO_PS_ENV]; /*!< Deltacoding time/freq flag for IID, 0 => freq */ SCHAR abIccDtFlag[MAX_NO_PS_ENV]; /*!< Deltacoding time/freq flag for ICC, 0 => freq */ SCHAR aaIidIndex[MAX_NO_PS_ENV][NO_HI_RES_IID_BINS]; /*!< The IID index for all envelopes and all IID bins */ SCHAR aaIccIndex[MAX_NO_PS_ENV][NO_HI_RES_ICC_BINS]; /*!< The ICC index for all envelopes and all ICC bins */ } MPEG_PS_BS_DATA; struct PS_DEC { SCHAR noSubSamples; SCHAR noChannels; SCHAR procFrameBased; /*!< Helper to detected switching from frame based to slot based processing */ PS_PAYLOAD_TYPE bPsDataAvail[(1)+1]; /*!< set if new data available from bitstream */ UCHAR psDecodedPrv; /*!< set if PS has been processed in the last frame */ /* helpers for frame delay line */ UCHAR bsLastSlot; /*!< Index of last read slot. */ UCHAR bsReadSlot; /*!< Index of current read slot for additional delay. */ UCHAR processSlot; /*!< Index of current slot for processing (need for add. delay). */ INT rescal; INT sf_IntBuffer; union { /* Bitstream data */ MPEG_PS_BS_DATA mpeg; /*!< Struct containing all MPEG specific PS data from bitstream. */ } bsData[(1)+1]; shouldBeUnion { /* Static data */ struct { SCHAR aIidPrevFrameIndex[NO_HI_RES_IID_BINS]; /*!< The IID index for previous frame */ SCHAR aIccPrevFrameIndex[NO_HI_RES_ICC_BINS]; /*!< The ICC index for previous frame */ UCHAR delayBufIndex; /*!< Pointer to where the latest sample is in buffer */ UCHAR noSampleDelay; /*!< How many QMF samples delay is used. */ UCHAR lastUsb; /*!< uppermost WMF delay band of last frame */ UCHAR aDelayRBufIndexSer[NO_SERIAL_ALLPASS_LINKS]; /*!< Delay buffer for reverb filter */ UCHAR aDelayBufIndexDelayQmf[NO_QMF_CHANNELS-FIRST_DELAY_SB]; /*!< Delay buffer for ICC group 20 & 21 */ SCHAR scaleFactorPsDelayBuffer; /*!< Scale factor for ps delay buffer */ /* hybrid filter bank delay lines */ FIXP_DBL aaQmfDelayBufReal[(NO_QMF_CHANNELS-FIRST_DELAY_SB) + (MAX_DELAY_BUFFER_SIZE-1)*(NO_DELAY_BUFFER_BANDS-FIRST_DELAY_SB)]; FIXP_DBL aaQmfDelayBufImag[(NO_QMF_CHANNELS-FIRST_DELAY_SB) + (MAX_DELAY_BUFFER_SIZE-1)*(NO_DELAY_BUFFER_BANDS-FIRST_DELAY_SB)]; FIXP_DBL *pAaRealDelayBufferQmf[MAX_DELAY_BUFFER_SIZE]; /*!< Real part delay buffer */ FIXP_DBL *pAaImagDelayBufferQmf[MAX_DELAY_BUFFER_SIZE]; /*!< Imaginary part delay buffer */ FIXP_DBL aaRealDelayBufferQmf[NO_SAMPLE_DELAY_ALLPASS][FIRST_DELAY_SB]; /*!< Real part delay buffer */ FIXP_DBL aaImagDelayBufferQmf[NO_SAMPLE_DELAY_ALLPASS][FIRST_DELAY_SB]; /*!< Imaginary part delay buffer*/ FIXP_DBL aaRealDelayBufferSubQmf[NO_SAMPLE_DELAY_ALLPASS][NO_SUB_QMF_CHANNELS]; /*!< Real part delay buffer */ FIXP_DBL aaImagDelayBufferSubQmf[NO_SAMPLE_DELAY_ALLPASS][NO_SUB_QMF_CHANNELS]; /*!< Imaginary part delay buffer */ FIXP_DBL aaaRealDelayRBufferSerQmf[FIRST_DELAY_SB][NO_DELAY_LENGTH_VECTORS]; /*!< Real part delay buffer */ FIXP_DBL aaaImagDelayRBufferSerQmf[FIRST_DELAY_SB][NO_DELAY_LENGTH_VECTORS]; /*!< Imaginary part delay buffer */ FIXP_DBL aaaRealDelayRBufferSerSubQmf[NO_SUB_QMF_CHANNELS][NO_DELAY_LENGTH_VECTORS]; /*!< Real part delay buffer */ FIXP_DBL aaaImagDelayRBufferSerSubQmf[NO_SUB_QMF_CHANNELS][NO_DELAY_LENGTH_VECTORS]; /*!< Imaginary part delay buffer */ HYBRID hybrid; /*!< hybrid filter bank struct 1 or 2. */ FIXP_DBL aPrevNrgBin[NO_MID_RES_BINS]; /*!< energy of previous frame */ FIXP_DBL aPrevPeakDiffBin[NO_MID_RES_BINS]; /*!< peak difference of previous frame */ FIXP_DBL aPeakDecayFastBin[NO_MID_RES_BINS]; /*!< Saved max. peak decay value per bin */ SCHAR aPowerPrevScal[NO_MID_RES_BINS]; /*!< Last power value (each bin) of previous frame */ FIXP_DBL h11rPrev[NO_IID_GROUPS]; /*!< previous calculated h(xy) coefficients */ FIXP_DBL h12rPrev[NO_IID_GROUPS]; /*!< previous calculated h(xy) coefficients */ FIXP_DBL h21rPrev[NO_IID_GROUPS]; /*!< previous calculated h(xy) coefficients */ FIXP_DBL h22rPrev[NO_IID_GROUPS]; /*!< previous calculated h(xy) coefficients */ PS_DEC_COEFFICIENTS coef; /*!< temporal coefficients (reusable scratch memory) */ } mpeg; } specificTo; }; typedef struct PS_DEC *HANDLE_PS_DEC; int CreatePsDec(HANDLE_PS_DEC *h_PS_DEC, int aacSamplesPerFrame); int DeletePsDec(HANDLE_PS_DEC *h_PS_DEC); void scalFilterBankValues( HANDLE_PS_DEC h_ps_d, /* parametric stereo decoder handle */ FIXP_DBL **fixpQmfReal, /* qmf filterbank values */ FIXP_DBL **fixpQmfImag, /* qmf filterbank values */ int lsb, /* sbr start subband */ int scaleFactorLowBandSplitLow, int scaleFactorLowBandSplitHigh, SCHAR *scaleFactorLowBand_lb, SCHAR *scaleFactorLowBand_hb, int scaleFactorHighBands, INT *scaleFactorHighBand, INT noCols); 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); void initSlotBasedRotation( HANDLE_PS_DEC h_ps_d, int env, int usb); void ApplyPsSlot( HANDLE_PS_DEC h_ps_d, /* parametric stereo decoder handle */ FIXP_DBL **rIntBufferLeft, /* real values of left qmf timeslot */ FIXP_DBL **iIntBufferLeft, /* imag values of left qmf timeslot */ FIXP_DBL *rIntBufferRight, /* real values of right qmf timeslot */ FIXP_DBL *iIntBufferRight); /* imag values of right qmf timeslot */ #endif /* __PSDEC_H */