aboutsummaryrefslogtreecommitdiffstats
path: root/libSBRdec/src/sbr_dec.cpp
diff options
context:
space:
mode:
authorJean-Michel Trivi <jmtrivi@google.com>2016-04-08 12:05:12 -0700
committerJean-Michel Trivi <jmtrivi@google.com>2016-04-08 19:10:30 +0000
commit203e3f28fbebec7011342017fafc2a0bda0ce530 (patch)
tree359ed01256a717b0161bfba21783634f1250471a /libSBRdec/src/sbr_dec.cpp
parent46ba3676b854acbc69a4c7845f578d4c2886377b (diff)
downloadfdk-aac-203e3f28fbebec7011342017fafc2a0bda0ce530.tar.gz
fdk-aac-203e3f28fbebec7011342017fafc2a0bda0ce530.tar.bz2
fdk-aac-203e3f28fbebec7011342017fafc2a0bda0ce530.zip
AAC/SBR decoder improvements and bugfixes
* AAC-Decoder - Add support for AOT 20 (ER-AAC scalable) (base layer only) - Add support for AAC as used in Digital Radio Mondiale (DRM30/DRM+) Modified file(s): libAACdec/src/aacdecoder.cpp libAACdec/src/aacdecoder_lib.cpp libFDK/src/FDK_core.cpp libFDK/src/FDK_tools_rom.cpp libMpegTPDec/src/tpdec_asc.cpp libMpegTPDec/src/tpdec_lib.cpp libMpegTPDec/src/version libSBRdec/include/sbrdecoder.h libSBRdec/src/env_extr.h libSBRdec/src/sbrdecoder.cpp Added file(s): libMpegTPDec/src/tpdec_drm.cpp libMpegTPDec/src/tpdec_drm.h - Fix sanity check in HCR module that was performed at the wrong point in time. Modified file(s): libAACdec/src/aacdecoder_lib.cpp libAACdec/src/block.cpp - Extend core sampling rate support up to 96 kHz. Modified file(s): libAACdec/src/aac_rom.cpp libAACdec/src/aacdecoder.cpp libAACdec/src/aacdecoder_lib.cpp - Return correct audio output channel description according number of output channels. Modified file(s): libAACdec/src/aacdecoder_lib.cpp - Indroduce decoder intern output buffer. This change allows to use framework output buffer with the actual size of the deocder output channels. Modified file(s): libAACdec/include/aacdecoder_lib.h libAACdec/src/aacdecoder.h libAACdec/src/aacdecoder_lib.cpp * SBR-Decoder - Increase robustness for erroneous input data. - Improve error concealment performance. - Fix handling of lowest sub-band for LD-SBR Modified file(s): libAACdec/src/aacdecoder.cpp libAACdec/src/aacdecoder_lib.cpp libSBRdec/src/env_calc.cpp libSBRdec/src/env_dec.cpp libSBRdec/src/env_extr.cpp libSBRdec/src/env_extr.h libSBRdec/src/sbr_dec.cpp libSBRdec/src/sbr_rom.cpp libSBRdec/src/sbr_rom.h libSBRdec/src/sbrdecoder.cpp - Add QMF delay compensation for ELD v2 streams decoded with the complex low delay filter-bank. Modified file(s): libSBRdec/src/sbr_dec.cpp libSBRdec/src/sbr_dec.h libSBRdec/src/sbrdecoder.cpp - Introduce a different handling of frames to be flushed dependent on whether there are delayed frames available or not. Modified file(s): libSBRdec/src/sbr_ram.h libSBRdec/src/sbrdecoder.cpp - Calculate the correct number of samples for dual-mono copy in case of no available PS data. Modified file(s): libSBRdec/src/sbrdecoder.cpp * SYS-Library - Change include order of genericStds.h to prevent conflict with definitions which are also used in math.h. Modified file(s): libSYS/src/genericStds.cpp Change-Id: I3ecffbad85f39b056213107955cfadbeb3f4b6e1
Diffstat (limited to 'libSBRdec/src/sbr_dec.cpp')
-rw-r--r--libSBRdec/src/sbr_dec.cpp62
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);