diff options
author | Jean-Michel Trivi <jmtrivi@google.com> | 2016-04-09 00:36:07 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2016-04-09 00:36:07 +0000 |
commit | 3fbcee802021fc12db8fd6e9e346a2111fe333a9 (patch) | |
tree | 359ed01256a717b0161bfba21783634f1250471a /libSBRdec/src/sbr_dec.cpp | |
parent | 125815b0ed558c72bb019a2d36c662e5e7f7c030 (diff) | |
parent | 203e3f28fbebec7011342017fafc2a0bda0ce530 (diff) | |
download | fdk-aac-3fbcee802021fc12db8fd6e9e346a2111fe333a9.tar.gz fdk-aac-3fbcee802021fc12db8fd6e9e346a2111fe333a9.tar.bz2 fdk-aac-3fbcee802021fc12db8fd6e9e346a2111fe333a9.zip |
AAC/SBR decoder improvements and bugfixes
am: 203e3f2
* commit '203e3f28fbebec7011342017fafc2a0bda0ce530':
AAC/SBR decoder improvements and bugfixes
Change-Id: I2f7f5bb7f4c486347a1fdbd7c481cde33037441e
Diffstat (limited to 'libSBRdec/src/sbr_dec.cpp')
-rw-r--r-- | libSBRdec/src/sbr_dec.cpp | 62 |
1 files changed, 55 insertions, 7 deletions
diff --git a/libSBRdec/src/sbr_dec.cpp b/libSBRdec/src/sbr_dec.cpp index 1282338..0864348 100644 --- a/libSBRdec/src/sbr_dec.cpp +++ b/libSBRdec/src/sbr_dec.cpp @@ -2,7 +2,7 @@ /* ----------------------------------------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2013 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. +© Copyright 1995 - 2015 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -225,7 +225,14 @@ static void changeQmfType( HANDLE_SBR_DEC hSbrDec, /*!< hand } if (resetAnaQmf) { - int qmfErr = qmfInitAnalysisFilterBank ( + QMF_FILTER_BANK prvAnaQmf; + int qmfErr; + + /* Store current configuration */ + FDKmemcpy(&prvAnaQmf, &hSbrDec->AnalysiscQMF, sizeof(QMF_FILTER_BANK)); + + /* Reset analysis QMF */ + qmfErr = qmfInitAnalysisFilterBank ( &hSbrDec->AnalysiscQMF, hSbrDec->anaQmfStates, hSbrDec->AnalysiscQMF.no_col, @@ -234,13 +241,22 @@ static void changeQmfType( HANDLE_SBR_DEC hSbrDec, /*!< hand hSbrDec->AnalysiscQMF.no_channels, anaQmfFlags | QMF_FLAG_KEEP_STATES ); + if (qmfErr != 0) { - FDK_ASSERT(0); + /* Restore old configuration of analysis QMF */ + FDKmemcpy(&hSbrDec->AnalysiscQMF, &prvAnaQmf, sizeof(QMF_FILTER_BANK)); } } if (resetSynQmf) { - int qmfErr = qmfInitSynthesisFilterBank ( + QMF_FILTER_BANK prvSynQmf; + int qmfErr; + + /* Store current configuration */ + FDKmemcpy(&prvSynQmf, &hSbrDec->SynthesisQMF, sizeof(QMF_FILTER_BANK)); + + /* Reset synthesis QMF */ + qmfErr = qmfInitSynthesisFilterBank ( &hSbrDec->SynthesisQMF, hSbrDec->pSynQmfStates, hSbrDec->SynthesisQMF.no_col, @@ -251,7 +267,8 @@ static void changeQmfType( HANDLE_SBR_DEC hSbrDec, /*!< hand ); if (qmfErr != 0) { - FDK_ASSERT(0); + /* Restore old configuration of synthesis QMF */ + FDKmemcpy(&hSbrDec->SynthesisQMF, &prvSynQmf, sizeof(QMF_FILTER_BANK)); } } } @@ -321,7 +338,8 @@ sbr_dec ( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */ HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, /*!< Some control data of last frame */ const int applyProcessing, /*!< Flag for SBR operation */ HANDLE_PS_DEC h_ps_d, - const UINT flags + const UINT flags, + const int codecFrameSize ) { int i, slot, reserve; @@ -348,6 +366,33 @@ sbr_dec ( HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */ if (flags & SBRDEC_ELD_GRID) { /* Choose the right low delay filter bank */ changeQmfType( hSbrDec, (flags & SBRDEC_LD_MPS_QMF) ? 1 : 0 ); + + /* If the LD-MPS QMF is not available delay the signal by (96-48*ldSbrSamplingRate) + * samples according to ISO/IEC 14496-3:2009/FDAM 2:2010(E) chapter 4.5.2.13. */ + if ( (flags & SBRDEC_LD_MPS_QMF) + && (hSbrDec->AnalysiscQMF.flags & QMF_FLAG_CLDFB) ) + { + INT_PCM *pDlyBuf = hSbrDec->coreDelayBuf; /* DLYBUF */ + int smpl, delay = 96 >> (!(flags & SBRDEC_DOWNSAMPLE) ? 1 : 0); + /* Create TMPBUF */ + C_AALLOC_SCRATCH_START(pcmTemp, INT_PCM, (96)); + /* Copy delay samples from INBUF to TMPBUF */ + for (smpl = 0; smpl < delay; smpl += 1) { + pcmTemp[smpl] = timeIn[(codecFrameSize-delay+smpl)*strideIn]; + } + /* Move input signal remainder to the very end of INBUF */ + for (smpl = (codecFrameSize-delay-1)*strideIn; smpl >= 0; smpl -= strideIn) { + timeIn[smpl+delay] = timeIn[smpl]; + } + /* Copy delayed samples from last frame from DLYBUF to the very beginning of INBUF */ + for (smpl = 0; smpl < delay; smpl += 1) { + timeIn[smpl*strideIn] = pDlyBuf[smpl]; + } + /* Copy TMPBUF to DLYBUF */ + FDKmemcpy(pDlyBuf, pcmTemp, delay*sizeof(INT_PCM)); + /* Destory TMPBUF */ + C_AALLOC_SCRATCH_END(pcmTemp, INT_PCM, (96)); + } } /* @@ -761,7 +806,7 @@ createSbrDec (SBR_CHANNEL * hSbrChannel, { int qmfErr; /* Adapted QMF analysis post-twiddles for down-sampled HQ SBR */ - const UINT downSampledFlag = (downsampleFac==2) ? QMF_FLAG_DOWNSAMPLED : 0; + const UINT downSampledFlag = (flags & SBRDEC_DOWNSAMPLE) ? QMF_FLAG_DOWNSAMPLED : 0; qmfErr = qmfInitAnalysisFilterBank ( &hs->AnalysiscQMF, @@ -836,6 +881,9 @@ createSbrDec (SBR_CHANNEL * hSbrChannel, } } + /* Clear input delay line */ + FDKmemclear(hs->coreDelayBuf, (96)*sizeof(INT_PCM)); + /* assign qmf time slots */ assignTimeSlots( &hSbrChannel->SbrDec, hHeaderData->numberTimeSlots * hHeaderData->timeStep, qmfFlags & QMF_FLAG_LP); |