From 612384d1b1c44d03f0185ef50c8b53fcb5fccfc3 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 24 Jun 2019 15:25:52 +0200 Subject: Remove SBR --- Android.bp | 4 - Makefile.am | 51 - Makefile.vc | 48 - libAACdec/src/aacdec_drc.cpp | 17 +- libAACdec/src/aacdec_drc.h | 10 +- libAACdec/src/aacdecoder.cpp | 185 +-- libAACdec/src/aacdecoder.h | 13 - libAACdec/src/aacdecoder_lib.cpp | 231 +-- libAACenc/src/aacenc.h | 4 - libAACenc/src/aacenc_lib.cpp | 562 +------ libMpegTPDec/include/tp_data.h | 11 - libMpegTPDec/include/tpdec_lib.h | 12 - libMpegTPDec/src/tpdec_asc.cpp | 107 -- libMpegTPDec/src/tpdec_lib.cpp | 10 - libMpegTPEnc/include/tpenc_lib.h | 12 - libMpegTPEnc/src/tpenc_asc.cpp | 19 - libSBRdec/include/sbrdecoder.h | 401 ----- libSBRdec/src/HFgen_preFlat.cpp | 993 ------------ libSBRdec/src/HFgen_preFlat.h | 132 -- libSBRdec/src/arm/lpp_tran_arm.cpp | 159 -- libSBRdec/src/env_calc.cpp | 3158 ------------------------------------ libSBRdec/src/env_calc.h | 182 --- libSBRdec/src/env_dec.cpp | 873 ---------- libSBRdec/src/env_dec.h | 119 -- libSBRdec/src/env_extr.cpp | 1728 -------------------- libSBRdec/src/env_extr.h | 415 ----- libSBRdec/src/hbe.cpp | 2202 ------------------------- libSBRdec/src/hbe.h | 200 --- libSBRdec/src/huff_dec.cpp | 137 -- libSBRdec/src/huff_dec.h | 117 -- libSBRdec/src/lpp_tran.cpp | 1471 ----------------- libSBRdec/src/lpp_tran.h | 275 ---- libSBRdec/src/psbitdec.cpp | 594 ------- libSBRdec/src/psbitdec.h | 116 -- libSBRdec/src/psdec.cpp | 722 --------- libSBRdec/src/psdec.h | 333 ---- libSBRdec/src/psdec_drm.cpp | 108 -- libSBRdec/src/psdec_drm.h | 113 -- libSBRdec/src/psdecrom_drm.cpp | 108 -- libSBRdec/src/pvc_dec.cpp | 683 -------- libSBRdec/src/pvc_dec.h | 238 --- libSBRdec/src/sbr_crc.cpp | 192 --- libSBRdec/src/sbr_crc.h | 138 -- libSBRdec/src/sbr_deb.cpp | 108 -- libSBRdec/src/sbr_deb.h | 113 -- libSBRdec/src/sbr_dec.cpp | 1480 ----------------- libSBRdec/src/sbr_dec.h | 204 --- libSBRdec/src/sbr_ram.cpp | 191 --- libSBRdec/src/sbr_ram.h | 186 --- libSBRdec/src/sbr_rom.cpp | 1705 ------------------- libSBRdec/src/sbr_rom.h | 216 --- libSBRdec/src/sbrdec_drc.cpp | 528 ------ libSBRdec/src/sbrdec_drc.h | 149 -- libSBRdec/src/sbrdec_freq_sca.cpp | 835 ---------- libSBRdec/src/sbrdec_freq_sca.h | 127 -- libSBRdec/src/sbrdecoder.cpp | 2023 ----------------------- libSBRdec/src/transcendent.h | 372 ----- libSBRenc/include/sbr_encoder.h | 483 ------ libSBRenc/src/bit_sbr.cpp | 1049 ------------ libSBRenc/src/bit_sbr.h | 267 --- libSBRenc/src/cmondata.h | 127 -- libSBRenc/src/code_env.cpp | 602 ------- libSBRenc/src/code_env.h | 161 -- libSBRenc/src/env_bit.cpp | 257 --- libSBRenc/src/env_bit.h | 135 -- libSBRenc/src/env_est.cpp | 1985 ---------------------- libSBRenc/src/env_est.h | 223 --- libSBRenc/src/fram_gen.cpp | 1965 ---------------------- libSBRenc/src/fram_gen.h | 343 ---- libSBRenc/src/invf_est.cpp | 610 ------- libSBRenc/src/invf_est.h | 181 --- libSBRenc/src/mh_det.cpp | 1396 ---------------- libSBRenc/src/mh_det.h | 204 --- libSBRenc/src/nf_est.cpp | 612 ------- libSBRenc/src/nf_est.h | 185 --- libSBRenc/src/ps_bitenc.cpp | 624 ------- libSBRenc/src/ps_bitenc.h | 173 -- libSBRenc/src/ps_const.h | 150 -- libSBRenc/src/ps_encode.cpp | 1031 ------------ libSBRenc/src/ps_encode.h | 185 --- libSBRenc/src/ps_main.cpp | 606 ------- libSBRenc/src/ps_main.h | 270 --- libSBRenc/src/resampler.cpp | 444 ----- libSBRenc/src/resampler.h | 159 -- libSBRenc/src/sbr.h | 194 --- libSBRenc/src/sbr_def.h | 276 ---- libSBRenc/src/sbr_encoder.cpp | 2577 ----------------------------- libSBRenc/src/sbr_misc.cpp | 265 --- libSBRenc/src/sbr_misc.h | 127 -- libSBRenc/src/sbrenc_freq_sca.cpp | 674 -------- libSBRenc/src/sbrenc_freq_sca.h | 132 -- libSBRenc/src/sbrenc_ram.cpp | 249 --- libSBRenc/src/sbrenc_ram.h | 199 --- libSBRenc/src/sbrenc_rom.cpp | 910 ----------- libSBRenc/src/sbrenc_rom.h | 145 -- libSBRenc/src/ton_corr.cpp | 891 ---------- libSBRenc/src/ton_corr.h | 258 --- libSBRenc/src/tran_det.cpp | 1092 ------------- libSBRenc/src/tran_det.h | 191 --- 99 files changed, 34 insertions(+), 48013 deletions(-) delete mode 100644 libSBRdec/include/sbrdecoder.h delete mode 100644 libSBRdec/src/HFgen_preFlat.cpp delete mode 100644 libSBRdec/src/HFgen_preFlat.h delete mode 100644 libSBRdec/src/arm/lpp_tran_arm.cpp delete mode 100644 libSBRdec/src/env_calc.cpp delete mode 100644 libSBRdec/src/env_calc.h delete mode 100644 libSBRdec/src/env_dec.cpp delete mode 100644 libSBRdec/src/env_dec.h delete mode 100644 libSBRdec/src/env_extr.cpp delete mode 100644 libSBRdec/src/env_extr.h delete mode 100644 libSBRdec/src/hbe.cpp delete mode 100644 libSBRdec/src/hbe.h delete mode 100644 libSBRdec/src/huff_dec.cpp delete mode 100644 libSBRdec/src/huff_dec.h delete mode 100644 libSBRdec/src/lpp_tran.cpp delete mode 100644 libSBRdec/src/lpp_tran.h delete mode 100644 libSBRdec/src/psbitdec.cpp delete mode 100644 libSBRdec/src/psbitdec.h delete mode 100644 libSBRdec/src/psdec.cpp delete mode 100644 libSBRdec/src/psdec.h delete mode 100644 libSBRdec/src/psdec_drm.cpp delete mode 100644 libSBRdec/src/psdec_drm.h delete mode 100644 libSBRdec/src/psdecrom_drm.cpp delete mode 100644 libSBRdec/src/pvc_dec.cpp delete mode 100644 libSBRdec/src/pvc_dec.h delete mode 100644 libSBRdec/src/sbr_crc.cpp delete mode 100644 libSBRdec/src/sbr_crc.h delete mode 100644 libSBRdec/src/sbr_deb.cpp delete mode 100644 libSBRdec/src/sbr_deb.h delete mode 100644 libSBRdec/src/sbr_dec.cpp delete mode 100644 libSBRdec/src/sbr_dec.h delete mode 100644 libSBRdec/src/sbr_ram.cpp delete mode 100644 libSBRdec/src/sbr_ram.h delete mode 100644 libSBRdec/src/sbr_rom.cpp delete mode 100644 libSBRdec/src/sbr_rom.h delete mode 100644 libSBRdec/src/sbrdec_drc.cpp delete mode 100644 libSBRdec/src/sbrdec_drc.h delete mode 100644 libSBRdec/src/sbrdec_freq_sca.cpp delete mode 100644 libSBRdec/src/sbrdec_freq_sca.h delete mode 100644 libSBRdec/src/sbrdecoder.cpp delete mode 100644 libSBRdec/src/transcendent.h delete mode 100644 libSBRenc/include/sbr_encoder.h delete mode 100644 libSBRenc/src/bit_sbr.cpp delete mode 100644 libSBRenc/src/bit_sbr.h delete mode 100644 libSBRenc/src/cmondata.h delete mode 100644 libSBRenc/src/code_env.cpp delete mode 100644 libSBRenc/src/code_env.h delete mode 100644 libSBRenc/src/env_bit.cpp delete mode 100644 libSBRenc/src/env_bit.h delete mode 100644 libSBRenc/src/env_est.cpp delete mode 100644 libSBRenc/src/env_est.h delete mode 100644 libSBRenc/src/fram_gen.cpp delete mode 100644 libSBRenc/src/fram_gen.h delete mode 100644 libSBRenc/src/invf_est.cpp delete mode 100644 libSBRenc/src/invf_est.h delete mode 100644 libSBRenc/src/mh_det.cpp delete mode 100644 libSBRenc/src/mh_det.h delete mode 100644 libSBRenc/src/nf_est.cpp delete mode 100644 libSBRenc/src/nf_est.h delete mode 100644 libSBRenc/src/ps_bitenc.cpp delete mode 100644 libSBRenc/src/ps_bitenc.h delete mode 100644 libSBRenc/src/ps_const.h delete mode 100644 libSBRenc/src/ps_encode.cpp delete mode 100644 libSBRenc/src/ps_encode.h delete mode 100644 libSBRenc/src/ps_main.cpp delete mode 100644 libSBRenc/src/ps_main.h delete mode 100644 libSBRenc/src/resampler.cpp delete mode 100644 libSBRenc/src/resampler.h delete mode 100644 libSBRenc/src/sbr.h delete mode 100644 libSBRenc/src/sbr_def.h delete mode 100644 libSBRenc/src/sbr_encoder.cpp delete mode 100644 libSBRenc/src/sbr_misc.cpp delete mode 100644 libSBRenc/src/sbr_misc.h delete mode 100644 libSBRenc/src/sbrenc_freq_sca.cpp delete mode 100644 libSBRenc/src/sbrenc_freq_sca.h delete mode 100644 libSBRenc/src/sbrenc_ram.cpp delete mode 100644 libSBRenc/src/sbrenc_ram.h delete mode 100644 libSBRenc/src/sbrenc_rom.cpp delete mode 100644 libSBRenc/src/sbrenc_rom.h delete mode 100644 libSBRenc/src/ton_corr.cpp delete mode 100644 libSBRenc/src/ton_corr.h delete mode 100644 libSBRenc/src/tran_det.cpp delete mode 100644 libSBRenc/src/tran_det.h --- a/Android.bp +++ b/Android.bp @@ -9,8 +9,6 @@ cc_library_static { "libSYS/src/*.cpp", "libMpegTPDec/src/*.cpp", "libMpegTPEnc/src/*.cpp", - "libSBRdec/src/*.cpp", - "libSBRenc/src/*.cpp", "libArithCoding/src/*.cpp", "libDRCdec/src/*.cpp", "libSACdec/src/*.cpp", @@ -43,8 +41,6 @@ cc_library_static { "libSYS/include", "libMpegTPDec/include", "libMpegTPEnc/include", - "libSBRdec/include", - "libSBRenc/include", "libArithCoding/include", "libDRCdec/include", "libSACdec/include", --- a/Makefile.am +++ b/Makefile.am @@ -8,8 +8,6 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/libDRCdec/include \ -I$(top_srcdir)/libSACdec/include \ -I$(top_srcdir)/libSACenc/include \ - -I$(top_srcdir)/libSBRdec/include \ - -I$(top_srcdir)/libSBRenc/include \ -I$(top_srcdir)/libMpegTPDec/include \ -I$(top_srcdir)/libMpegTPEnc/include \ -I$(top_srcdir)/libSYS/include \ @@ -197,49 +195,6 @@ SACENC_SRC = \ libSACenc/src/sacenc_tree.cpp \ libSACenc/src/sacenc_vectorfunctions.cpp -SBRDEC_SRC = \ - libSBRdec/src/HFgen_preFlat.cpp \ - libSBRdec/src/env_calc.cpp \ - libSBRdec/src/env_dec.cpp \ - libSBRdec/src/env_extr.cpp \ - libSBRdec/src/hbe.cpp \ - libSBRdec/src/huff_dec.cpp \ - libSBRdec/src/lpp_tran.cpp \ - libSBRdec/src/psbitdec.cpp \ - libSBRdec/src/psdec.cpp \ - libSBRdec/src/psdec_drm.cpp \ - libSBRdec/src/psdecrom_drm.cpp \ - libSBRdec/src/pvc_dec.cpp \ - libSBRdec/src/sbr_crc.cpp \ - libSBRdec/src/sbr_deb.cpp \ - libSBRdec/src/sbr_dec.cpp \ - libSBRdec/src/sbr_ram.cpp \ - libSBRdec/src/sbr_rom.cpp \ - libSBRdec/src/sbrdec_drc.cpp \ - libSBRdec/src/sbrdec_freq_sca.cpp \ - libSBRdec/src/sbrdecoder.cpp - -SBRENC_SRC = \ - libSBRenc/src/bit_sbr.cpp \ - libSBRenc/src/code_env.cpp \ - libSBRenc/src/env_bit.cpp \ - libSBRenc/src/env_est.cpp \ - libSBRenc/src/fram_gen.cpp \ - libSBRenc/src/invf_est.cpp \ - libSBRenc/src/mh_det.cpp \ - libSBRenc/src/nf_est.cpp \ - libSBRenc/src/ps_bitenc.cpp \ - libSBRenc/src/ps_encode.cpp \ - libSBRenc/src/ps_main.cpp \ - libSBRenc/src/resampler.cpp \ - libSBRenc/src/sbr_encoder.cpp \ - libSBRenc/src/sbr_misc.cpp \ - libSBRenc/src/sbrenc_freq_sca.cpp \ - libSBRenc/src/sbrenc_ram.cpp \ - libSBRenc/src/sbrenc_rom.cpp \ - libSBRenc/src/ton_corr.cpp \ - libSBRenc/src/tran_det.cpp - SYS_SRC = \ libSYS/src/genericStds.cpp \ libSYS/src/syslib_channelMapDescr.cpp @@ -250,7 +205,6 @@ libfdk_aac_la_SOURCES = \ $(DRCDEC_SRC) \ $(MPEGTPDEC_SRC) $(MPEGTPENC_SRC) \ $(SACDEC_SRC) $(SACENC_SRC) \ - $(SBRDEC_SRC) $(SBRENC_SRC) \ $(PCMUTILS_SRC) $(FDK_SRC) $(SYS_SRC) EXTRA_DIST = \ @@ -273,11 +227,6 @@ EXTRA_DIST = \ $(top_srcdir)/libSACdec/src/*.h \ $(top_srcdir)/libSACenc/include/*.h \ $(top_srcdir)/libSACenc/src/*.h \ - $(top_srcdir)/libSBRenc/src/*.h \ - $(top_srcdir)/libSBRenc/include/*.h \ - $(top_srcdir)/libSBRdec/src/*.h \ - $(top_srcdir)/libSBRdec/src/arm/*.cpp \ - $(top_srcdir)/libSBRdec/include/*.h \ $(top_srcdir)/libSYS/include/*.h \ $(top_srcdir)/libPCMutils/include/*.h \ $(top_srcdir)/libPCMutils/src/*.h \ --- a/Makefile.vc +++ b/Makefile.vc @@ -23,8 +23,6 @@ AM_CPPFLAGS = \ -IlibDRCdec/include \ -IlibSACdec/include \ -IlibSACenc/include \ - -IlibSBRdec/include \ - -IlibSBRenc/include \ -IlibMpegTPDec/include \ -IlibMpegTPEnc/include \ -IlibSYS/include \ @@ -181,49 +179,6 @@ SACENC_SRC = \ libSACenc/src/sacenc_tree.cpp \ libSACenc/src/sacenc_vectorfunctions.cpp -SBRDEC_SRC = \ - libSBRdec/src/HFgen_preFlat.cpp \ - libSBRdec/src/env_calc.cpp \ - libSBRdec/src/env_dec.cpp \ - libSBRdec/src/env_extr.cpp \ - libSBRdec/src/hbe.cpp \ - libSBRdec/src/huff_dec.cpp \ - libSBRdec/src/lpp_tran.cpp \ - libSBRdec/src/psbitdec.cpp \ - libSBRdec/src/psdec.cpp \ - libSBRdec/src/psdec_drm.cpp \ - libSBRdec/src/psdecrom_drm.cpp \ - libSBRdec/src/pvc_dec.cpp \ - libSBRdec/src/sbr_crc.cpp \ - libSBRdec/src/sbr_deb.cpp \ - libSBRdec/src/sbr_dec.cpp \ - libSBRdec/src/sbr_ram.cpp \ - libSBRdec/src/sbr_rom.cpp \ - libSBRdec/src/sbrdec_drc.cpp \ - libSBRdec/src/sbrdec_freq_sca.cpp \ - libSBRdec/src/sbrdecoder.cpp - -SBRENC_SRC = \ - libSBRenc/src/bit_sbr.cpp \ - libSBRenc/src/code_env.cpp \ - libSBRenc/src/env_bit.cpp \ - libSBRenc/src/env_est.cpp \ - libSBRenc/src/fram_gen.cpp \ - libSBRenc/src/invf_est.cpp \ - libSBRenc/src/mh_det.cpp \ - libSBRenc/src/nf_est.cpp \ - libSBRenc/src/ps_bitenc.cpp \ - libSBRenc/src/ps_encode.cpp \ - libSBRenc/src/ps_main.cpp \ - libSBRenc/src/resampler.cpp \ - libSBRenc/src/sbr_encoder.cpp \ - libSBRenc/src/sbr_misc.cpp \ - libSBRenc/src/sbrenc_freq_sca.cpp \ - libSBRenc/src/sbrenc_ram.cpp \ - libSBRenc/src/sbrenc_rom.cpp \ - libSBRenc/src/ton_corr.cpp \ - libSBRenc/src/tran_det.cpp - SYS_SRC = \ libSYS/src/genericStds.cpp \ libSYS/src/syslib_channelMapDescr.cpp @@ -234,7 +189,6 @@ libfdk_aac_SOURCES = \ $(DRCDEC_SRC) \ $(MPEGTPDEC_SRC) $(MPEGTPENC_SRC) \ $(SACDEC_SRC) $(SACENC_SRC) \ - $(SBRDEC_SRC) $(SBRENC_SRC) \ $(PCMUTILS_SRC) $(FDK_SRC) $(SYS_SRC) @@ -282,8 +236,6 @@ clean: del /f libPCMutils\src\*.obj 2>NUL del /f libSACdec\src\*.obj 2>NUL del /f libSACenc\src\*.obj 2>NUL - del /f libSBRdec\src\*.obj 2>NUL - del /f libSBRenc\src\*.obj 2>NUL del /f libSYS\src\*.obj 2>NUL install: $(INST_DIRS) --- a/libAACdec/src/aacdec_drc.cpp +++ b/libAACdec/src/aacdec_drc.cpp @@ -105,8 +105,6 @@ amm-info@iis.fraunhofer.de #include "channelinfo.h" #include "aac_rom.h" -#include "sbrdecoder.h" - /* * Dynamic Range Control */ @@ -832,11 +830,11 @@ static int aacDecoder_drcExtractAndMap( return result; } -void aacDecoder_drcApply(HANDLE_AAC_DRC self, void *pSbrDec, +void aacDecoder_drcApply(HANDLE_AAC_DRC self, CAacDecoderChannelInfo *pAacDecoderChannelInfo, CDrcChannelData *pDrcChData, FIXP_DBL *extGain, int ch, /* needed only for SBR */ - int aacFrameSize, int bSbrPresent) { + int aacFrameSize) { int band, bin, numBands; int bottom = 0; int modifyBins = 0; @@ -867,7 +865,6 @@ void aacDecoder_drcApply(HANDLE_AAC_DRC } if (self->enable != ON) { - sbrDecoder_drcDisable((HANDLE_SBRDECODER)pSbrDec, ch); if (extGain != NULL) { INT gainScale = (INT)*extGain; /* The gain scaling must be passed to the function in the buffer pointed @@ -1020,7 +1017,7 @@ void aacDecoder_drcApply(HANDLE_AAC_DRC * short blocks must take care that bands fall on * block boundaries! */ - if (!bSbrPresent) { + { bottom = 0; if (!modifyBins) { @@ -1058,14 +1055,6 @@ void aacDecoder_drcApply(HANDLE_AAC_DRC pSpecScale[win] += max_exponent; } } - } else { - HANDLE_SBRDECODER hSbrDecoder = (HANDLE_SBRDECODER)pSbrDec; - numBands = pDrcChData->numBands; - - /* feed factors into SBR decoder for application in QMF domain. */ - sbrDecoder_drcFeedChannel(hSbrDecoder, ch, numBands, fact_mantissa, - max_exponent, pDrcChData->drcInterpolationScheme, - winSeq, pDrcChData->bandTop); } return; --- a/libAACdec/src/aacdec_drc.h +++ b/libAACdec/src/aacdec_drc.h @@ -152,10 +152,8 @@ int aacDecoder_drcProlog( UCHAR pceInstanceTag, UCHAR channelMapping[], int validChannels); /** - * \brief Apply DRC. If SBR is present, DRC data is handed over to the SBR - * decoder. + * \brief Apply DRC. * \param self AAC decoder instance - * \param pSbrDec pointer to SBR decoder instance * \param pAacDecoderChannelInfo AAC decoder channel instance to be processed * \param pDrcDat DRC channel data * \param extGain Pointer to a FIXP_DBL where a externally applyable gain will @@ -164,13 +162,11 @@ int aacDecoder_drcProlog( * DFRACT_BITS) to be applied on the gain value. * \param ch channel index * \param aacFrameSize AAC frame size - * \param bSbrPresent flag indicating that SBR is present, in which case DRC is - * handed over to the SBR instance pSbrDec */ -void aacDecoder_drcApply(HANDLE_AAC_DRC self, void *pSbrDec, +void aacDecoder_drcApply(HANDLE_AAC_DRC self, CAacDecoderChannelInfo *pAacDecoderChannelInfo, CDrcChannelData *pDrcDat, FIXP_DBL *extGain, int ch, - int aacFrameSize, int bSbrPresent); + int aacFrameSize); int aacDecoder_drcEpilog( HANDLE_AAC_DRC self, HANDLE_FDK_BITSTREAM hBs, --- a/libAACdec/src/aacdecoder.cpp +++ b/libAACdec/src/aacdecoder.cpp @@ -161,8 +161,6 @@ amm-info@iis.fraunhofer.de #include "aacdec_pns.h" -#include "sbrdecoder.h" - #include "sac_dec_lib.h" #include "aacdec_hcr.h" @@ -249,9 +247,6 @@ void CAacDecoder_SyncQmfMode(HANDLE_AACD } } - /* Set SBR to current QMF mode. Error does not matter. */ - sbrDecoder_SetParam(self->hSbrDecoder, SBR_QMF_MODE, - (self->qmfModeCurr == MODE_LP)); self->psPossible = ((CAN_DO_PS(self->streamInfo.aot) && !PS_IS_EXPLICITLY_DISABLED(self->streamInfo.aot, self->flags[0]) && @@ -936,7 +931,6 @@ static AAC_DECODER_ERROR CAacDecoder_Ext FDK_FALLTHROUGH; case EXT_SBR_DATA: if (IS_CHANNEL_ELEMENT(previous_element)) { - SBR_ERROR sbrError; UCHAR configMode = 0; UCHAR configChanged = 0; @@ -944,29 +938,6 @@ static AAC_DECODER_ERROR CAacDecoder_Ext configMode |= AC_CM_ALLOC_MEM; - sbrError = sbrDecoder_InitElement( - self->hSbrDecoder, self->streamInfo.aacSampleRate, - self->streamInfo.extSamplingRate, - self->streamInfo.aacSamplesPerFrame, self->streamInfo.aot, - previous_element, elIndex, - 2, /* Signalize that harmonicSBR shall be ignored in the config - change detection */ - 0, configMode, &configChanged, self->downscaleFactor); - - if (sbrError == SBRDEC_OK) { - sbrError = sbrDecoder_Parse(self->hSbrDecoder, hBs, - self->pDrmBsBuffer, self->drmBsBufferSize, - count, *count, crcFlag, previous_element, - elIndex, self->flags[0], self->elFlags); - /* Enable SBR for implicit SBR signalling but only if no severe error - * happend. */ - if ((sbrError == SBRDEC_OK) || (sbrError == SBRDEC_PARSE_ERROR)) { - self->sbrEnabled = 1; - } - } else { - /* Do not try to apply SBR because initializing the element failed. */ - self->sbrEnabled = 0; - } /* Citation from ISO/IEC 14496-3 chapter 4.5.2.1.5.2 Fill elements containing an extension_payload() with an extension_type of EXT_SBR_DATA or EXT_SBR_DATA_CRC shall not contain any other @@ -978,9 +949,7 @@ static AAC_DECODER_ERROR CAacDecoder_Ext } else { /* If this is not a fill element with a known length, we are screwed * and further parsing makes no sense. */ - if (sbrError != SBRDEC_OK) { - self->frameOK = 0; - } + self->frameOK = 0; } } else { error = AAC_DEC_PARSE_ERROR; @@ -1107,54 +1076,10 @@ static AAC_DECODER_ERROR aacDecoder_Pars if ((self->flags[0] & AC_SBR_PRESENT) && (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_ELD | AC_DRM))) { - SBR_ERROR err = SBRDEC_OK; - int chElIdx, numChElements = el_cnt[ID_SCE] + el_cnt[ID_CPE] + - el_cnt[ID_LFE] + el_cnt[ID_USAC_SCE] + - el_cnt[ID_USAC_CPE] + el_cnt[ID_USAC_LFE]; - INT bitCntTmp = bitCnt; - - if (self->flags[0] & AC_USAC) { - chElIdx = numChElements - 1; - } else { - chElIdx = 0; /* ELD case */ - } - - for (; chElIdx < numChElements; chElIdx += 1) { - MP4_ELEMENT_ID sbrType; - SBR_ERROR errTmp; - if (self->flags[0] & (AC_USAC)) { - FDK_ASSERT((self->elements[element_index] == ID_USAC_SCE) || - (self->elements[element_index] == ID_USAC_CPE)); - sbrType = IS_STEREO_SBR(self->elements[element_index], - self->usacStereoConfigIndex[element_index]) - ? ID_CPE - : ID_SCE; - } else - sbrType = self->elements[chElIdx]; - errTmp = sbrDecoder_Parse(self->hSbrDecoder, bs, self->pDrmBsBuffer, - self->drmBsBufferSize, &bitCnt, -1, - self->flags[0] & AC_SBRCRC, sbrType, chElIdx, - self->flags[0], self->elFlags); - if (errTmp != SBRDEC_OK) { - err = errTmp; - bitCntTmp = bitCnt; - bitCnt = 0; - } - } - switch (err) { - case SBRDEC_PARSE_ERROR: - /* Can not go on parsing because we do not - know the length of the SBR extension data. */ - FDKpushFor(bs, bitCntTmp); - bitCnt = 0; - break; - case SBRDEC_OK: - self->sbrEnabled = 1; - break; - default: - self->frameOK = 0; - break; - } + /* Can not go on parsing because we do not + know the length of the SBR extension data. */ + FDKpushFor(bs, bitCnt); + bitCnt = 0; } if ((bitCnt > 0) && (self->flags[0] & (AC_USAC | AC_RSVD50))) { @@ -1827,14 +1752,8 @@ CAacDecoder_Init(HANDLE_AACDECODER self, } self->flags[streamIndex] |= (asc->m_sbrPresentFlag) ? AC_SBR_PRESENT : 0; self->flags[streamIndex] |= (asc->m_psPresentFlag) ? AC_PS_PRESENT : 0; - if (asc->m_sbrPresentFlag) { - self->sbrEnabled = 1; - self->sbrEnabledPrev = 1; - } else { - self->sbrEnabled = 0; - self->sbrEnabledPrev = 0; - } - if (self->sbrEnabled && asc->m_extensionSamplingFrequency) { + + if (asc->m_sbrPresentFlag && asc->m_extensionSamplingFrequency) { if (downscaleFactor != 1 && (downscaleFactor)&1) { return AAC_DEC_UNSUPPORTED_SAMPLINGRATE; /* SBR needs an even downscale factor */ @@ -1944,31 +1863,6 @@ CAacDecoder_Init(HANDLE_AACDECODER self, /* set AC_USAC_SCFGI3 globally if any usac element uses */ switch (asc->m_aot) { case AOT_USAC: - if (self->sbrEnabled) { - for (int _el = 0; - _el < (int)self->pUsacConfig[streamIndex]->m_usacNumElements; - _el++) { - int el = elementOffset + _el; - if (IS_USAC_CHANNEL_ELEMENT(self->elements[el])) { - if (usacStereoConfigIndex < 0) { - usacStereoConfigIndex = self->usacStereoConfigIndex[el]; - } else { - if ((usacStereoConfigIndex != self->usacStereoConfigIndex[el]) || - (self->usacStereoConfigIndex[el] > 0)) { - goto bail; - } - } - } - } - - if (usacStereoConfigIndex < 0) { - goto bail; - } - - if (usacStereoConfigIndex == 3) { - self->flags[streamIndex] |= AC_USAC_SCFGI3; - } - } break; default: break; @@ -1981,39 +1875,11 @@ CAacDecoder_Init(HANDLE_AACDECODER self, */ switch (asc->m_aot) { case AOT_USAC: - if (self->sbrEnabled) { - const UCHAR map_sbrRatio_2_nAnaBands[] = {16, 24, 32}; - - FDK_ASSERT(asc->m_sc.m_usacConfig.m_sbrRatioIndex > 0); - FDK_ASSERT(streamIndex == 0); - - self->qmfDomain.globalConf.nInputChannels_requested = ascChannels; - self->qmfDomain.globalConf.nOutputChannels_requested = - (usacStereoConfigIndex == 1) ? 2 : ascChannels; - self->qmfDomain.globalConf.flags_requested = 0; - self->qmfDomain.globalConf.nBandsAnalysis_requested = - map_sbrRatio_2_nAnaBands[asc->m_sc.m_usacConfig.m_sbrRatioIndex - - 1]; - self->qmfDomain.globalConf.nBandsSynthesis_requested = 64; - self->qmfDomain.globalConf.nQmfTimeSlots_requested = - (asc->m_sc.m_usacConfig.m_sbrRatioIndex == 1) ? 64 : 32; - self->qmfDomain.globalConf.nQmfOvTimeSlots_requested = - (asc->m_sc.m_usacConfig.m_sbrRatioIndex == 1) ? 12 : 6; - self->qmfDomain.globalConf.nQmfProcBands_requested = 64; - self->qmfDomain.globalConf.nQmfProcChannels_requested = 1; - self->qmfDomain.globalConf.parkChannel = - (usacStereoConfigIndex == 3) ? 1 : 0; - self->qmfDomain.globalConf.parkChannel_requested = - (usacStereoConfigIndex == 3) ? 1 : 0; - self->qmfDomain.globalConf.qmfDomainExplicitConfig = 1; - } break; case AOT_ER_AAC_ELD: if (self->mpsEnableCurr && asc->m_sc.m_eldSpecificConfig.m_useLdQmfTimeAlign) { - SAC_INPUT_CONFIG sac_interface = - (self->sbrEnabled && self->hSbrDecoder) ? SAC_INTERFACE_QMF - : SAC_INTERFACE_TIME; + SAC_INPUT_CONFIG sac_interface = SAC_INTERFACE_TIME; mpegSurroundDecoder_ConfigureQmfDomain( (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, sac_interface, (UINT)self->streamInfo.aacSampleRate, asc->m_aot); @@ -2625,34 +2491,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecod } else { self->frameOK = 0; } - /* Create SBR element for SBR for upsampling for LFE elements, - and if SBR was implicitly signaled, because the first frame(s) - may not contain SBR payload (broken encoder, bit errors). */ - if (self->frameOK && - ((self->flags[streamIndex] & AC_SBR_PRESENT) || - (self->sbrEnabled == 1)) && - !(self->flags[streamIndex] & - AC_USAC) /* Is done during explicit config set up */ - ) { - SBR_ERROR sbrError; - UCHAR configMode = 0; - UCHAR configChanged = 0; - configMode |= AC_CM_ALLOC_MEM; - - sbrError = sbrDecoder_InitElement( - self->hSbrDecoder, self->streamInfo.aacSampleRate, - self->streamInfo.extSamplingRate, - self->streamInfo.aacSamplesPerFrame, self->streamInfo.aot, type, - previous_element_index, 2, /* Signalize that harmonicSBR shall - be ignored in the config change - detection */ - 0, configMode, &configChanged, self->downscaleFactor); - if (sbrError != SBRDEC_OK) { - /* Do not try to apply SBR because initializing the element - * failed. */ - self->sbrEnabled = 0; - } - } } el_cnt[type]++; @@ -3047,7 +2885,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecod (8) * sizeof(AUDIO_CHANNEL_TYPE)); /* restore */ FDKmemcpy(self->channelIndices, self->channelIndicesPrev, (8) * sizeof(UCHAR)); /* restore */ - self->sbrEnabled = self->sbrEnabledPrev; } else { /* store or restore the number of channels and the corresponding info */ if (self->frameOK && !(flags & AACDEC_CONCEAL)) { @@ -3056,7 +2893,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecod (8) * sizeof(AUDIO_CHANNEL_TYPE)); /* store */ FDKmemcpy(self->channelIndicesPrev, self->channelIndices, (8) * sizeof(UCHAR)); /* store */ - self->sbrEnabledPrev = self->sbrEnabled; } else { if (self->aacChannels > 0) { if ((self->buildUpStatus == AACDEC_RSV60_BUILD_UP_ON) || @@ -3071,7 +2907,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecod (8) * sizeof(AUDIO_CHANNEL_TYPE)); /* restore */ FDKmemcpy(self->channelIndices, self->channelIndicesPrev, (8) * sizeof(UCHAR)); /* restore */ - self->sbrEnabled = self->sbrEnabledPrev; } } } @@ -3302,9 +3137,9 @@ LINKSPEC_CPP AAC_DECODER_ERROR CAacDecod self->extGain[0] = (FIXP_DBL)TDL_GAIN_SCALING; /* DRC processing */ aacDecoder_drcApply( - self->hDrcInfo, self->hSbrDecoder, pAacDecoderChannelInfo, + self->hDrcInfo, pAacDecoderChannelInfo, &pAacDecoderStaticChannelInfo->drcData, self->extGain, c, - self->streamInfo.aacSamplesPerFrame, self->sbrEnabled + self->streamInfo.aacSamplesPerFrame ); --- a/libAACdec/src/aacdecoder.h +++ b/libAACdec/src/aacdecoder.h @@ -118,8 +118,6 @@ amm-info@iis.fraunhofer.de #include "FDK_qmf_domain.h" -#include "sbrdecoder.h" - #include "aacdec_drc.h" #include "pcmdmx_lib.h" @@ -152,10 +150,6 @@ typedef struct { typedef enum { NOT_DEFINED = -1, MODE_HQ = 0, MODE_LP = 1 } QMF_MODE; -typedef struct { - int bsDelay; -} SBR_PARAMS; - enum { AACDEC_FLUSH_OFF = 0, AACDEC_RSV60_CFG_CHANGE_ATSC_FLUSH_ON = 1, @@ -224,8 +218,6 @@ struct AAC_DECODER_INSTANCE { UCHAR chMapIndex; /*!< Index to access one line of the channelOutputMapping table. This is required because not all 8 channel configurations have the same output mapping. */ - INT sbrDataLen; /*!< Expected length of the SBR remaining in bitbuffer after - the AAC payload has been pared. */ CProgramConfig pce; CStreamInfo @@ -272,12 +264,7 @@ This structure is allocated once for eac supported) ELD downscale factor discovered in the bitstream */ - HANDLE_SBRDECODER hSbrDecoder; /*!< SBR decoder handle. */ - UCHAR sbrEnabled; /*!< flag to store if SBR has been detected */ - UCHAR sbrEnabledPrev; /*!< flag to store if SBR has been detected from - previous frame */ UCHAR psPossible; /*!< flag to store if PS is possible */ - SBR_PARAMS sbrParams; /*!< struct to store all sbr parameters */ UCHAR *pDrmBsBuffer; /*!< Pointer to dynamic buffer which is used to reverse the bits of the DRM SBR payload */ --- a/libAACdec/src/aacdecoder_lib.cpp +++ b/libAACdec/src/aacdecoder_lib.cpp @@ -107,8 +107,6 @@ amm-info@iis.fraunhofer.de #include "tpdec_lib.h" #include "FDK_core.h" /* FDK_tools version info */ -#include "sbrdecoder.h" - #include "conceal.h" #include "aacdec_drc.h" @@ -330,13 +328,6 @@ static INT aacDecoder_FreeMemCallback(vo errTp = TRANSPORTDEC_UNKOWN_ERROR; } - /* free Ram_SbrDecoder and Ram_SbrDecChannel */ - if (self->hSbrDecoder != NULL) { - if (sbrDecoder_FreeMem(&self->hSbrDecoder) != SBRDEC_OK) { - errTp = TRANSPORTDEC_UNKOWN_ERROR; - } - } - /* free pSpatialDec and mpsData */ if (self->pMpegSurroundDecoder != NULL) { if (mpegSurroundDecoder_FreeMem( @@ -368,23 +359,6 @@ static INT aacDecoder_CtrlCFGChangeCallb return errTp; } -static INT aacDecoder_SbrCallback( - void *handle, HANDLE_FDK_BITSTREAM hBs, const INT sampleRateIn, - const INT sampleRateOut, const INT samplesPerFrame, - const AUDIO_OBJECT_TYPE coreCodec, const MP4_ELEMENT_ID elementID, - const INT elementIndex, const UCHAR harmonicSBR, - const UCHAR stereoConfigIndex, const UCHAR configMode, UCHAR *configChanged, - const INT downscaleFactor) { - HANDLE_SBRDECODER self = (HANDLE_SBRDECODER)handle; - - INT errTp = sbrDecoder_Header(self, hBs, sampleRateIn, sampleRateOut, - samplesPerFrame, coreCodec, elementID, - elementIndex, harmonicSBR, stereoConfigIndex, - configMode, configChanged, downscaleFactor); - - return errTp; -} - static INT aacDecoder_SscCallback(void *handle, HANDLE_FDK_BITSTREAM hBs, const AUDIO_OBJECT_TYPE coreCodec, const INT samplingRate, const INT frameSize, @@ -557,7 +531,6 @@ static AAC_DECODER_ERROR setConcealMetho AAC_DECODER_ERROR errorStatus = AAC_DEC_OK; CConcealParams *pConcealData = NULL; int method_revert = 0; - HANDLE_SBRDECODER hSbrDec = NULL; HANDLE_AAC_DRC hDrcInfo = NULL; HANDLE_PCM_DOWNMIX hPcmDmx = NULL; CConcealmentMethod backupMethod = ConcealMethodNone; @@ -567,7 +540,6 @@ static AAC_DECODER_ERROR setConcealMetho /* check decoder handle */ if (self != NULL) { pConcealData = &self->concealCommonData; - hSbrDec = self->hSbrDecoder; hDrcInfo = self->hDrcInfo; hPcmDmx = self->hPcmUtils; if (self->flags[0] & (AC_USAC | AC_RSVD50 | AC_RSV603DA) && method >= 2) { @@ -603,27 +575,6 @@ static AAC_DECODER_ERROR setConcealMetho /* Get new delay */ bsDelay = CConcealment_GetDelay(pConcealData); - { - SBR_ERROR sbrErr = SBRDEC_OK; - - /* set SBR bitstream delay */ - sbrErr = sbrDecoder_SetParam(hSbrDec, SBR_SYSTEM_BITSTREAM_DELAY, bsDelay); - - switch (sbrErr) { - case SBRDEC_OK: - case SBRDEC_NOT_INITIALIZED: - if (self != NULL) { - /* save the param value and set later - (when SBR has been initialized) */ - self->sbrParams.bsDelay = bsDelay; - } - break; - default: - errorStatus = AAC_DEC_SET_PARAM_FAIL; - goto bail; - } - } - errorStatus = aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, bsDelay); if ((errorStatus != AAC_DEC_OK) && (errorStatus != AAC_DEC_INVALID_HANDLE)) { goto bail; @@ -650,8 +601,6 @@ bail: pConcealData, (int)backupMethod, AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, AACDEC_CONCEAL_PARAM_NOT_SPECIFIED, AACDEC_CONCEAL_PARAM_NOT_SPECIFIED); - /* Revert SBR bitstream delay */ - sbrDecoder_SetParam(hSbrDec, SBR_SYSTEM_BITSTREAM_DELAY, backupDelay); /* Revert DRC bitstream delay */ aacDecoder_drcSetParam(hDrcInfo, DRC_BS_DELAY, backupDelay); /* Revert PCM mixdown bitstream delay */ @@ -973,14 +922,7 @@ LINKSPEC_CPP HANDLE_AACDECODER aacDecode pIn, aacDecoder_CtrlCFGChangeCallback, (void *)aacDec); FDKmemclear(&aacDec->qmfDomain, sizeof(FDK_QMF_DOMAIN)); - /* open SBR decoder */ - if (SBRDEC_OK != sbrDecoder_Open(&aacDec->hSbrDecoder, &aacDec->qmfDomain)) { - err = -1; - goto bail; - } aacDec->qmfModeUser = NOT_DEFINED; - transportDec_RegisterSbrCallback(aacDec->hInput, aacDecoder_SbrCallback, - (void *)aacDec->hSbrDecoder); if (mpegSurroundDecoder_Open( (CMpegSurroundDecoder **)&aacDec->pMpegSurroundDecoder, @@ -1067,9 +1009,6 @@ LINKSPEC_CPP AAC_DECODER_ERROR aacDecode static void aacDecoder_SignalInterruption(HANDLE_AACDECODER self) { CAacDecoder_SignalInterruption(self); - if (self->hSbrDecoder != NULL) { - sbrDecoder_SetParam(self->hSbrDecoder, SBR_BS_INTERRUPTION, 1); - } if (self->mpsEnableUser) { mpegSurroundDecoder_SetParam( (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, @@ -1274,7 +1213,6 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER Tell other modules to clear states if required. */ if (flags & AACDEC_CLRHIST) { if (!(self->flags[0] & AC_USAC)) { - sbrDecoder_SetParam(self->hSbrDecoder, SBR_CLEAR_HISTORY, 1); mpegSurroundDecoder_SetParam( (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, SACDEC_CLEAR_HISTORY, 1); @@ -1393,9 +1331,7 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER if (!self->qmfDomain.globalConf.qmfDomainExplicitConfig && self->mpsEnableCurr) { - SAC_INPUT_CONFIG sac_interface = (self->sbrEnabled && self->hSbrDecoder) - ? SAC_INTERFACE_QMF - : SAC_INTERFACE_TIME; + SAC_INPUT_CONFIG sac_interface = SAC_INTERFACE_TIME; /* needs to be done before first SBR apply. */ mpegSurroundDecoder_ConfigureQmfDomain( (CMpegSurroundDecoder *)self->pMpegSurroundDecoder, sac_interface, @@ -1423,8 +1359,6 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER break; } - /* sbr decoder */ - if ((ErrorStatus != AAC_DEC_OK) || (flags & AACDEC_CONCEAL) || self->pAacDecoderStaticChannelInfo[0]->concealmentInfo.concealState > ConcealState_FadeIn) { @@ -1432,110 +1366,6 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER decoder too */ } - if (self->sbrEnabled && (!(self->flags[0] & AC_USAC_SCFGI3))) { - SBR_ERROR sbrError = SBRDEC_OK; - int chIdx, numCoreChannel = self->streamInfo.numChannels; - - /* set params */ - sbrDecoder_SetParam(self->hSbrDecoder, SBR_SYSTEM_BITSTREAM_DELAY, - self->sbrParams.bsDelay); - sbrDecoder_SetParam( - self->hSbrDecoder, SBR_FLUSH_DATA, - (flags & AACDEC_FLUSH) | - ((self->flushStatus && !(flags & AACDEC_CONCEAL)) ? AACDEC_FLUSH - : 0)); - - if (self->streamInfo.aot == AOT_ER_AAC_ELD) { - /* Configure QMF */ - sbrDecoder_SetParam(self->hSbrDecoder, SBR_LD_QMF_TIME_ALIGN, - (self->flags[0] & AC_MPS_PRESENT) ? 1 : 0); - } - - { - PCMDMX_ERROR dmxErr; - INT maxOutCh = 0; - - dmxErr = pcmDmx_GetParam(self->hPcmUtils, - MAX_NUMBER_OF_OUTPUT_CHANNELS, &maxOutCh); - if ((dmxErr == PCMDMX_OK) && (maxOutCh == 1)) { - /* Disable PS processing if we have to create a mono output signal. - */ - self->psPossible = 0; - } - } - - sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF, - (self->mpsEnableCurr) ? 2 : 0); - - INT_PCM *input; - input = (INT_PCM *)self->workBufferCore2; - FDKmemcpy(input, pTimeData, - sizeof(INT_PCM) * (self->streamInfo.numChannels) * - (self->streamInfo.frameSize)); - - /* apply SBR processing */ - sbrError = sbrDecoder_Apply(self->hSbrDecoder, input, pTimeData, - timeDataSize, &self->streamInfo.numChannels, - &self->streamInfo.sampleRate, - &self->mapDescr, self->chMapIndex, - self->frameOK, &self->psPossible); - - if (sbrError == SBRDEC_OK) { - /* Update data in streaminfo structure. Assume that the SBR upsampling - factor is either 1, 2, 8/3 or 4. Maximum upsampling factor is 4 - (CELP+SBR or USAC 4:1 SBR) */ - self->flags[0] |= AC_SBR_PRESENT; - if (self->streamInfo.aacSampleRate != self->streamInfo.sampleRate) { - if (self->streamInfo.aacSampleRate >> 2 == - self->streamInfo.sampleRate) { - self->streamInfo.frameSize = - self->streamInfo.aacSamplesPerFrame >> 2; - self->streamInfo.outputDelay = self->streamInfo.outputDelay >> 2; - } else if (self->streamInfo.aacSampleRate >> 1 == - self->streamInfo.sampleRate) { - self->streamInfo.frameSize = - self->streamInfo.aacSamplesPerFrame >> 1; - self->streamInfo.outputDelay = self->streamInfo.outputDelay >> 1; - } else if (self->streamInfo.aacSampleRate << 1 == - self->streamInfo.sampleRate) { - self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame - << 1; - self->streamInfo.outputDelay = self->streamInfo.outputDelay << 1; - } else if (self->streamInfo.aacSampleRate << 2 == - self->streamInfo.sampleRate) { - self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame - << 2; - self->streamInfo.outputDelay = self->streamInfo.outputDelay << 2; - } else if (self->streamInfo.frameSize == 768) { - self->streamInfo.frameSize = - (self->streamInfo.aacSamplesPerFrame << 3) / 3; - self->streamInfo.outputDelay = - (self->streamInfo.outputDelay << 3) / 3; - } else { - ErrorStatus = AAC_DEC_SET_PARAM_FAIL; - goto bail; - } - } else { - self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame; - } - self->streamInfo.outputDelay += - sbrDecoder_GetDelay(self->hSbrDecoder); - - if (self->psPossible) { - self->flags[0] |= AC_PS_PRESENT; - } - for (chIdx = numCoreChannel; chIdx < self->streamInfo.numChannels; - chIdx += 1) { - self->channelType[chIdx] = ACT_FRONT; - self->channelIndices[chIdx] = chIdx; - } - } - if (sbrError == SBRDEC_OUTPUT_BUFFER_TOO_SMALL) { - ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL; - goto bail; - } - } - if (self->mpsEnableCurr) { int err, sac_interface, nChannels, frameSize; @@ -1543,8 +1373,6 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER frameSize = self->streamInfo.frameSize; sac_interface = SAC_INTERFACE_TIME; - if (self->sbrEnabled && self->hSbrDecoder) - sac_interface = SAC_INTERFACE_QMF; if (self->streamInfo.aot == AOT_USAC) { if (self->flags[0] & AC_USAC_SCFGI3) { sac_interface = SAC_INTERFACE_TIME; @@ -1593,50 +1421,6 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER } } - /* SBR decoder for Unified Stereo Config (stereoConfigIndex == 3) */ - - if (self->sbrEnabled && (self->flags[0] & AC_USAC_SCFGI3)) { - SBR_ERROR sbrError = SBRDEC_OK; - - /* set params */ - sbrDecoder_SetParam(self->hSbrDecoder, SBR_SYSTEM_BITSTREAM_DELAY, - self->sbrParams.bsDelay); - - sbrDecoder_SetParam(self->hSbrDecoder, SBR_SKIP_QMF, 1); - - /* apply SBR processing */ - sbrError = sbrDecoder_Apply(self->hSbrDecoder, pTimeData, pTimeData, - timeDataSize, &self->streamInfo.numChannels, - &self->streamInfo.sampleRate, - &self->mapDescr, self->chMapIndex, - self->frameOK, &self->psPossible); - - if (sbrError == SBRDEC_OK) { - /* Update data in streaminfo structure. Assume that the SBR upsampling - * factor is either 1,2 or 4 */ - self->flags[0] |= AC_SBR_PRESENT; - if (self->streamInfo.aacSampleRate != self->streamInfo.sampleRate) { - if (self->streamInfo.frameSize == 768) { - self->streamInfo.frameSize = - (self->streamInfo.aacSamplesPerFrame * 8) / 3; - } else if (self->streamInfo.aacSampleRate << 2 == - self->streamInfo.sampleRate) { - self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame - << 2; - } else { - self->streamInfo.frameSize = self->streamInfo.aacSamplesPerFrame - << 1; - } - } - - self->flags[0] &= ~AC_PS_PRESENT; - } - if (sbrError == SBRDEC_OUTPUT_BUFFER_TOO_SMALL) { - ErrorStatus = AAC_DEC_OUTPUT_BUFFER_TOO_SMALL; - goto bail; - } - } - /* Use dedicated memory for PCM postprocessing */ pTimeDataPcmPost = self->pTimeData2; timeDataPcmPostSize = self->timeData2Size; @@ -1672,7 +1456,6 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER /* If SBR and/or MPS is active, the DRC gains are aligned to the QMF domain signal before the QMF synthesis. Therefore the DRC gains need to be delayed by the QMF synthesis delay. */ - if (self->sbrEnabled) drcDelay = 257; if (self->mpsEnableCurr) drcDelay = 257; /* Take into account concealment delay */ drcDelay += CConcealment_GetDelay(&self->concealCommonData) * @@ -1693,7 +1476,7 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER * necessary for FDK_drcDec_ProcessTime, which accepts deinterleaved * audio only. */ if ((self->streamInfo.numChannels > 1) && - (0 || (self->sbrEnabled) || (self->mpsEnableCurr))) { + (0 || (self->mpsEnableCurr))) { /* interleaving/deinterleaving is performed on upper part of * pTimeDataPcmPost. Check if this buffer is large enough. */ if (timeDataPcmPostSize < @@ -1766,7 +1549,6 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER } INT interleaved = 0; - interleaved |= (self->sbrEnabled) ? 1 : 0; interleaved |= (self->mpsEnableCurr) ? 1 : 0; /* do PCM post processing */ @@ -1804,7 +1586,7 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER pcmLimiter_SetSampleRate(self->hLimiter, self->streamInfo.sampleRate); pcmLimiterScale += PCM_OUT_HEADROOM; - if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) || + if ((self->streamInfo.numChannels == 1) || (self->mpsEnableCurr)) { pInterleaveBuffer = (PCM_LIM *)pTimeDataPcmPost; } else { @@ -1828,7 +1610,7 @@ aacDecoder_DecodeFrame(HANDLE_AACDECODER /* If numChannels = 1 we do not need interleaving. The same applies if SBR or MPS are used, since their output is interleaved already (resampled or not) */ - if ((self->streamInfo.numChannels == 1) || (self->sbrEnabled) || + if ((self->streamInfo.numChannels == 1) || (self->mpsEnableCurr)) { scaleValuesSaturate( pTimeData, pTimeDataPcmPost, @@ -1972,10 +1754,6 @@ LINKSPEC_CPP void aacDecoder_Close(HANDL (CMpegSurroundDecoder *)self->pMpegSurroundDecoder); } - if (self->hSbrDecoder != NULL) { - sbrDecoder_Close(&self->hSbrDecoder); - } - if (self->hInput != NULL) { transportDec_Close(&self->hInput); } @@ -1994,7 +1772,6 @@ LINKSPEC_CPP INT aacDecoder_GetLibInfo(L return -1; } - sbrDecoder_GetLibInfo(info); mpegSurroundDecoder_GetLibInfo(info); transportDec_GetLibInfo(info); FDK_toolsGetLibInfo(info); --- a/libAACenc/src/aacenc.h +++ b/libAACenc/src/aacenc.h @@ -108,8 +108,6 @@ amm-info@iis.fraunhofer.de #include "tpenc_lib.h" -#include "sbr_encoder.h" - #define MIN_BUFSIZE_PER_EFF_CHAN 6144 #ifdef __cplusplus @@ -243,8 +241,6 @@ struct AACENC_CONFIG { INT audioMuxVersion; /* audio mux version in loas/latm transport format */ - UINT sbrRatio; /* sbr sampling rate ratio: dual- or single-rate */ - UCHAR useTns; /* flag: use temporal noise shaping */ UCHAR usePns; /* flag: use perceptual noise substitution */ UCHAR useIS; /* flag: use intensity coding */ --- a/libAACenc/src/aacenc_lib.cpp +++ b/libAACenc/src/aacenc_lib.cpp @@ -122,8 +122,6 @@ amm-info@iis.fraunhofer.de #include "pcm_utils.h" -#include "sbr_encoder.h" -#include "../src/sbrenc_ram.h" #include "channel_map.h" #include "psy_const.h" @@ -199,22 +197,10 @@ typedef struct { UCHAR userMetaDataMode; /*!< Meta data library configuration. */ - UCHAR userSbrEnabled; /*!< Enable SBR for ELD. */ - UINT userSbrRatio; /*!< SBR sampling rate ratio. Dual- or single-rate. */ - UINT userDownscaleFactor; } USER_PARAM; -/** - * SBR extenxion payload struct provides buffers to be filled in SBR encoder - * library. - */ -typedef struct { - UCHAR data[(1)][(8)][MAX_PAYLOAD_SIZE]; /*!< extension payload data buffer */ - UINT dataSize[(1)][(8)]; /*!< extension payload data size in bits */ -} SBRENC_EXT_PAYLOAD; - //////////////////////////////////////////////////////////////////////////////////// /**************************************************************************** @@ -231,10 +217,6 @@ struct AACENCODER { AACENC_CONFIG aacConfig; HANDLE_AAC_ENC hAacEnc; - /* SBR */ - HANDLE_SBR_ENCODER hEnvEnc; /* SBR encoder */ - SBRENC_EXT_PAYLOAD *pSbrPayload; /* SBR extension payload */ - /* Meta Data */ HANDLE_FDK_METADATA_ENCODER hMetadataEnc; INT metaDataAllowed; /* Signal whether chosen configuration allows metadata. @@ -270,8 +252,6 @@ struct AACENCODER { /* Memory allocation info. */ INT nMaxAacElements; INT nMaxAacChannels; - INT nMaxSbrElements; - INT nMaxSbrChannels; UINT encoder_modis; @@ -293,92 +273,6 @@ typedef struct { } ELD_SBR_CONFIGURATOR; -/** - * \brief This table defines ELD/SBR default configurations. - */ -static const ELD_SBR_CONFIGURATOR eldSbrAutoConfigTab[] = { - {1, 48000, 0, 2, MODE_1}, {1, 48000, 64000, 0, MODE_1}, - - {1, 44100, 0, 2, MODE_1}, {1, 44100, 64000, 0, MODE_1}, - - {1, 32000, 0, 2, MODE_1}, {1, 32000, 28000, 1, MODE_1}, - {1, 32000, 56000, 0, MODE_1}, - - {1, 24000, 0, 1, MODE_1}, {1, 24000, 40000, 0, MODE_1}, - - {1, 16000, 0, 1, MODE_1}, {1, 16000, 28000, 0, MODE_1}, - - {1, 15999, 0, 0, MODE_1}, - - {2, 48000, 0, 2, MODE_2}, {2, 48000, 44000, 2, MODE_2}, - {2, 48000, 128000, 0, MODE_2}, - - {2, 44100, 0, 2, MODE_2}, {2, 44100, 44000, 2, MODE_2}, - {2, 44100, 128000, 0, MODE_2}, - - {2, 32000, 0, 2, MODE_2}, {2, 32000, 32000, 2, MODE_2}, - {2, 32000, 68000, 1, MODE_2}, {2, 32000, 96000, 0, MODE_2}, - - {2, 24000, 0, 1, MODE_2}, {2, 24000, 48000, 1, MODE_2}, - {2, 24000, 80000, 0, MODE_2}, - - {2, 16000, 0, 1, MODE_2}, {2, 16000, 32000, 1, MODE_2}, - {2, 16000, 64000, 0, MODE_2}, - - {2, 15999, 0, 0, MODE_2} - -}; - -/* - * \brief Configure SBR for ELD configuration. - * - * This function finds default SBR configuration for ELD based on number of - * channels, sampling rate and bitrate. - * - * \param nChannels Number of audio channels. - * \param samplingRate Audio signal sampling rate. - * \param bitrate Encoder bitrate. - * - * \return - pointer to eld sbr configuration. - * - NULL, on failure. - */ -static const ELD_SBR_CONFIGURATOR *eldSbrConfigurator(const ULONG nChannels, - const ULONG samplingRate, - const ULONG bitrate) { - int i; - const ELD_SBR_CONFIGURATOR *pSetup = NULL; - - for (i = 0; - i < (int)(sizeof(eldSbrAutoConfigTab) / sizeof(ELD_SBR_CONFIGURATOR)); - i++) { - if ((nChannels == eldSbrAutoConfigTab[i].nChannels) && - (samplingRate <= eldSbrAutoConfigTab[i].samplingRate) && - (bitrate >= eldSbrAutoConfigTab[i].bitrateRange)) { - pSetup = &eldSbrAutoConfigTab[i]; - } - } - - return pSetup; -} - -static inline INT isSbrActive(const HANDLE_AACENC_CONFIG hAacConfig) { - INT sbrUsed = 0; - - /* Note: Even if implicit signalling was selected, The AOT itself here is not - * AOT_AAC_LC */ - if ((hAacConfig->audioObjectType == AOT_SBR) || - (hAacConfig->audioObjectType == AOT_PS) || - (hAacConfig->audioObjectType == AOT_MP2_SBR)) { - sbrUsed = 1; - } - if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD && - (hAacConfig->syntaxFlags & AC_SBR_PRESENT)) { - sbrUsed = 1; - } - - return (sbrUsed); -} - static inline INT isPsActive(const AUDIO_OBJECT_TYPE audioObjectType) { INT psUsed = 0; @@ -399,53 +293,6 @@ static CHANNEL_MODE GetCoreChannelMode( return mappedChannelMode; } -static SBR_PS_SIGNALING getSbrSignalingMode( - const AUDIO_OBJECT_TYPE audioObjectType, const TRANSPORT_TYPE transportType, - const UCHAR transportSignaling, const UINT sbrRatio) - -{ - SBR_PS_SIGNALING sbrSignaling; - - if (transportType == TT_UNKNOWN || sbrRatio == 0) { - sbrSignaling = SIG_UNKNOWN; /* Needed parameters have not been set */ - return sbrSignaling; - } else { - sbrSignaling = - SIG_EXPLICIT_HIERARCHICAL; /* default: explicit hierarchical signaling - */ - } - - if ((audioObjectType == AOT_AAC_LC) || (audioObjectType == AOT_SBR) || - (audioObjectType == AOT_PS) || (audioObjectType == AOT_MP2_AAC_LC) || - (audioObjectType == AOT_MP2_SBR)) { - switch (transportType) { - case TT_MP4_ADIF: - case TT_MP4_ADTS: - sbrSignaling = SIG_IMPLICIT; /* For MPEG-2 transport types, only - implicit signaling is possible */ - break; - - case TT_MP4_RAW: - case TT_MP4_LATM_MCP1: - case TT_MP4_LATM_MCP0: - case TT_MP4_LOAS: - default: - if (transportSignaling == 0xFF) { - /* Defaults */ - sbrSignaling = SIG_EXPLICIT_HIERARCHICAL; - } else { - /* User set parameters */ - /* Attention: Backward compatible explicit signaling does only work - * with AMV1 for LATM/LOAS */ - sbrSignaling = (SBR_PS_SIGNALING)transportSignaling; - } - break; - } - } - - return sbrSignaling; -} - /**************************************************************************** Allocate Encoder ****************************************************************************/ @@ -672,46 +519,14 @@ AAC_ENCODER_ERROR aacEncDefaultConfig(HA config->userAncDataRate = 0; - /* SBR rate is set to 0 here, which means it should be set automatically - in FDKaacEnc_AdjustEncSettings() if the user did not set a rate - expilicitely. */ - config->userSbrRatio = 0; - - /* SBR enable set to -1 means to inquire ELD audio configurator for reasonable - * configuration. */ - config->userSbrEnabled = (UCHAR)-1; - return AAC_ENC_OK; } -static void aacEncDistributeSbrBits(CHANNEL_MAPPING *channelMapping, - SBR_ELEMENT_INFO *sbrElInfo, INT bitRate) { - INT codebits = bitRate; - int el; - - /* Copy Element info */ - for (el = 0; el < channelMapping->nElements; el++) { - sbrElInfo[el].ChannelIndex[0] = channelMapping->elInfo[el].ChannelIndex[0]; - sbrElInfo[el].ChannelIndex[1] = channelMapping->elInfo[el].ChannelIndex[1]; - sbrElInfo[el].elType = channelMapping->elInfo[el].elType; - sbrElInfo[el].bitRate = - fMultIfloor(channelMapping->elInfo[el].relativeBits, bitRate); - sbrElInfo[el].instanceTag = channelMapping->elInfo[el].instanceTag; - sbrElInfo[el].nChannelsInEl = channelMapping->elInfo[el].nChannelsInEl; - sbrElInfo[el].fParametricStereo = 0; - sbrElInfo[el].fDualMono = 0; - - codebits -= sbrElInfo[el].bitRate; - } - sbrElInfo[0].bitRate += codebits; -} - static INT aacEncoder_LimitBitrate(const HANDLE_TRANSPORTENC hTpEnc, const INT samplingRate, const INT frameLength, const INT nChannels, const CHANNEL_MODE channelMode, INT bitRate, - const INT nSubFrames, const INT sbrActive, - const INT sbrDownSampleRate, + const INT nSubFrames, const UINT syntaxFlags, const AUDIO_OBJECT_TYPE aot) { INT coreSamplingRate; @@ -719,89 +534,18 @@ static INT aacEncoder_LimitBitrate(const FDKaacEnc_InitChannelMapping(channelMode, CH_ORDER_MPEG, &cm); - if (sbrActive) { - coreSamplingRate = - samplingRate >> - (sbrEncoder_IsSingleRatePossible(aot) ? (sbrDownSampleRate - 1) : 1); - } else { - coreSamplingRate = samplingRate; - } + coreSamplingRate = samplingRate; /* Limit bit rate in respect to the core coder */ bitRate = FDKaacEnc_LimitBitrate(hTpEnc, aot, coreSamplingRate, frameLength, nChannels, cm.nChannelsEff, bitRate, -1, NULL, AACENC_BR_MODE_INVALID, nSubFrames); - /* Limit bit rate in respect to available SBR modes if active */ - if (sbrActive) { - int numIterations = 0; - INT initialBitrate, adjustedBitrate; - adjustedBitrate = bitRate; - - /* Find total bitrate which provides valid configuration for each SBR - * element. */ - do { - int e; - SBR_ELEMENT_INFO sbrElInfo[((8))]; - FDK_ASSERT(cm.nElements <= ((8))); - - initialBitrate = adjustedBitrate; - - /* Get bit rate for each SBR element */ - aacEncDistributeSbrBits(&cm, sbrElInfo, initialBitrate); - - for (e = 0; e < cm.nElements; e++) { - INT sbrElementBitRateIn, sbrBitRateOut; - - if (cm.elInfo[e].elType != ID_SCE && cm.elInfo[e].elType != ID_CPE) { - continue; - } - sbrElementBitRateIn = sbrElInfo[e].bitRate; - - sbrBitRateOut = sbrEncoder_LimitBitRate(sbrElementBitRateIn, - cm.elInfo[e].nChannelsInEl, - coreSamplingRate, aot); - - if (sbrBitRateOut == 0) { - return 0; - } - - /* If bitrates don't match, distribution and limiting needs to be - determined again. Abort element loop and restart with adapted - bitrate. */ - if (sbrElementBitRateIn != sbrBitRateOut) { - if (sbrElementBitRateIn < sbrBitRateOut) { - adjustedBitrate = fMax(initialBitrate, - (INT)fDivNorm((FIXP_DBL)(sbrBitRateOut + 8), - cm.elInfo[e].relativeBits)); - break; - } - - if (sbrElementBitRateIn > sbrBitRateOut) { - adjustedBitrate = fMin(initialBitrate, - (INT)fDivNorm((FIXP_DBL)(sbrBitRateOut - 8), - cm.elInfo[e].relativeBits)); - break; - } - - } /* sbrElementBitRateIn != sbrBitRateOut */ - - } /* elements */ - - numIterations++; /* restrict iteration to worst case of num elements */ - - } while ((initialBitrate != adjustedBitrate) && - (numIterations <= cm.nElements)); - - /* Unequal bitrates mean that no reasonable bitrate configuration found. */ - bitRate = (initialBitrate == adjustedBitrate) ? adjustedBitrate : 0; - } - /* Limit bit rate in respect to available MPS modes if active */ if ((aot == AOT_ER_AAC_ELD) && (syntaxFlags & AC_LD_MPS) && (channelMode == MODE_1)) { bitRate = FDK_MpegsEnc_GetClosestBitRate( - aot, MODE_212, samplingRate, (sbrActive) ? sbrDownSampleRate : 0, + aot, MODE_212, samplingRate, 0, bitRate); } @@ -814,25 +558,13 @@ static INT aacEncoder_LimitBitrate(const * \hAacConfig Internal encoder config * \return Bitrate */ -static INT FDKaacEnc_GetCBRBitrate(const HANDLE_AACENC_CONFIG hAacConfig, - const INT userSbrRatio) { +static INT FDKaacEnc_GetCBRBitrate(const HANDLE_AACENC_CONFIG hAacConfig) { INT bitrate = FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode) ->nChannelsEff * hAacConfig->sampleRate; if (isPsActive(hAacConfig->audioObjectType)) { bitrate = 1 * bitrate; /* 0.5 bit per sample */ - } else if (isSbrActive(hAacConfig)) { - if ((userSbrRatio == 2) || - ((userSbrRatio == 0) && - (hAacConfig->audioObjectType != AOT_ER_AAC_ELD))) { - bitrate = (bitrate + (bitrate >> 2)) >> 1; /* 0.625 bits per sample */ - } - if ((userSbrRatio == 1) || - ((userSbrRatio == 0) && - (hAacConfig->audioObjectType == AOT_ER_AAC_ELD))) { - bitrate = (bitrate + (bitrate >> 3)); /* 1.125 bits per sample */ - } } else { bitrate = bitrate + (bitrate >> 1); /* 1.5 bits per sample */ } @@ -886,10 +618,6 @@ static AACENC_ERROR FDKaacEnc_AdjustEncS return AACENC_INVALID_CONFIG; /* downscaling only allowed for AOT_ER_AAC_ELD */ } - if (config->userDownscaleFactor > 1 && config->userSbrEnabled == 1) { - return AACENC_INVALID_CONFIG; /* downscaling only allowed for AOT_ER_AAC_ELD - w/o SBR */ - } if (config->userDownscaleFactor > 1 && config->userChannelMode == 128) { return AACENC_INVALID_CONFIG; /* disallow downscaling for AAC-ELDv2 */ } @@ -943,8 +671,6 @@ static AACENC_ERROR FDKaacEnc_AdjustEncS hAacConfig->syntaxFlags |= ((config->userErTools & 0x2) ? AC_ER_HCR : 0); hAacConfig->syntaxFlags |= ((config->userErTools & 0x4) ? AC_ER_RVLC : 0); hAacConfig->syntaxFlags |= - ((config->userSbrEnabled == 1) ? AC_SBR_PRESENT : 0); - hAacConfig->syntaxFlags |= ((config->userChannelMode == MODE_212) ? AC_LD_MPS : 0); config->userTpType = (config->userTpType != TT_UNKNOWN) ? config->userTpType : TT_MP4_LOAS; @@ -974,25 +700,6 @@ static AACENC_ERROR FDKaacEnc_AdjustEncS break; } - /* Initialize SBR parameters */ - if ((config->userSbrRatio == 0) && (isSbrActive(hAacConfig))) { - /* Automatic SBR ratio configuration - * - downsampled SBR for ELD - * - otherwise always dualrate SBR - */ - if (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) { - hAacConfig->sbrRatio = ((hAacConfig->syntaxFlags & AC_LD_MPS) && - (hAacConfig->sampleRate >= 27713)) - ? 2 - : 1; - } else { - hAacConfig->sbrRatio = 2; - } - } else { - /* SBR ratio has been set by the user, so use it. */ - hAacConfig->sbrRatio = isSbrActive(hAacConfig) ? config->userSbrRatio : 0; - } - /* Set default bitrate */ hAacConfig->bitRate = config->userBitrate; @@ -1001,7 +708,7 @@ static AACENC_ERROR FDKaacEnc_AdjustEncS /* Set default bitrate if no external bitrate declared. */ if (config->userBitrate == (UINT)-1) { hAacConfig->bitRate = - FDKaacEnc_GetCBRBitrate(hAacConfig, config->userSbrRatio); + FDKaacEnc_GetCBRBitrate(hAacConfig); } hAacConfig->averageBits = -1; break; @@ -1074,33 +781,8 @@ static AACENC_ERROR FDKaacEnc_AdjustEncS } } - if ((hAacConfig->audioObjectType == AOT_ER_AAC_ELD) && - !(hAacConfig->syntaxFlags & AC_ELD_DOWNSCALE) && - (config->userSbrEnabled == (UCHAR)-1) && (config->userSbrRatio == 0) && - ((hAacConfig->syntaxFlags & AC_LD_MPS) == 0)) { - const ELD_SBR_CONFIGURATOR *pConfig = NULL; - - if (NULL != - (pConfig = eldSbrConfigurator( - FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode) - ->nChannels, - hAacConfig->sampleRate, hAacConfig->bitRate))) { - hAacConfig->syntaxFlags |= (pConfig->sbrMode == 0) ? 0 : AC_SBR_PRESENT; - hAacConfig->syntaxFlags |= (pConfig->chMode == MODE_212) ? AC_LD_MPS : 0; - hAacConfig->channelMode = - GetCoreChannelMode(pConfig->chMode, hAacConfig->audioObjectType); - hAacConfig->nChannels = - FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode) - ->nChannels; - hAacConfig->sbrRatio = - (pConfig->sbrMode == 0) ? 0 : (pConfig->sbrMode == 1) ? 1 : 2; - } - } - { - UCHAR tpSignaling = - getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType, - config->userTpSignaling, hAacConfig->sbrRatio); + UCHAR tpSignaling = SIG_UNKNOWN; if ((hAacConfig->audioObjectType == AOT_AAC_LC || hAacConfig->audioObjectType == AOT_SBR || @@ -1112,15 +794,6 @@ static AACENC_ERROR FDKaacEnc_AdjustEncS /* For backward compatible explicit signaling, AMV1 has to be active */ return AACENC_INVALID_CONFIG; } - - if ((hAacConfig->audioObjectType == AOT_AAC_LC || - hAacConfig->audioObjectType == AOT_SBR || - hAacConfig->audioObjectType == AOT_PS) && - (tpSignaling == 0) && (hAacConfig->sbrRatio == 1)) { - /* Downsampled SBR has to be signaled explicitely (for transmission of SBR - * sampling fequency) */ - return AACENC_INVALID_CONFIG; - } } switch (hAacConfig->bitrateMode) { @@ -1135,7 +808,6 @@ static AACENC_ERROR FDKaacEnc_AdjustEncS NULL, hAacConfig->sampleRate, hAacConfig->framelength, hAacConfig->nChannels, hAacConfig->channelMode, hAacConfig->bitRate, hAacConfig->nSubFrames, - isSbrActive(hAacConfig), hAacConfig->sbrRatio, hAacConfig->syntaxFlags, hAacConfig->audioObjectType))) { return AACENC_INVALID_CONFIG; } @@ -1167,13 +839,6 @@ static AACENC_ERROR FDKaacEnc_AdjustEncS } } - if ((hAacConfig->nChannels > hAacEncoder->nMaxAacChannels) || - ((FDKaacEnc_GetChannelModeConfiguration(hAacConfig->channelMode) - ->nChannelsEff > hAacEncoder->nMaxSbrChannels) && - isSbrActive(hAacConfig))) { - return AACENC_INVALID_CONFIG; /* not enough channels allocated */ - } - /* Meta data restriction. */ switch (hAacConfig->audioObjectType) { /* Allow metadata support */ @@ -1198,22 +863,6 @@ static AACENC_ERROR FDKaacEnc_AdjustEncS return err; } -static INT aacenc_SbrCallback(void *self, HANDLE_FDK_BITSTREAM hBs, - const INT sampleRateIn, const INT sampleRateOut, - const INT samplesPerFrame, - const AUDIO_OBJECT_TYPE coreCodec, - const MP4_ELEMENT_ID elementID, - const INT elementIndex, const UCHAR harmonicSbr, - const UCHAR stereoConfigIndex, - const UCHAR configMode, UCHAR *configChanged, - const INT downscaleFactor) { - HANDLE_AACENCODER hAacEncoder = (HANDLE_AACENCODER)self; - - sbrEncoder_GetHeader(hAacEncoder->hEnvEnc, hBs, elementIndex, 0); - - return 0; -} - INT aacenc_SscCallback(void *self, HANDLE_FDK_BITSTREAM hBs, const AUDIO_OBJECT_TYPE coreCodec, const INT samplingRate, const INT frameSize, @@ -1230,7 +879,6 @@ static AACENC_ERROR aacEncInit(HANDLE_AA AACENC_ERROR err = AACENC_OK; INT aacBufferOffset = 0; - HANDLE_SBR_ENCODER *hSbrEncoder = &hAacEncoder->hEnvEnc; HANDLE_AACENC_CONFIG hAacConfig = &hAacEncoder->aacConfig; hAacEncoder->nZerosAppended = 0; /* count appended zeros */ @@ -1245,11 +893,6 @@ static AACENC_ERROR aacEncInit(HANDLE_AA return err; } frameLength = hAacConfig->framelength; /* adapt temporal framelength */ - - /* Seamless channel reconfiguration in sbr not fully implemented */ - if ((prevChMode != hAacConfig->channelMode) && isSbrActive(hAacConfig)) { - InitFlags |= AACENC_INIT_STATES; - } } /* Clear input buffer */ @@ -1275,78 +918,13 @@ static AACENC_ERROR aacEncInit(HANDLE_AA hAacConfig->ancDataBitRate = 0; } - if ((NULL != hAacEncoder->hEnvEnc) && isSbrActive(hAacConfig) && - ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES))) { - INT sbrError; - UINT initFlag = 0; - SBR_ELEMENT_INFO sbrElInfo[(8)]; - CHANNEL_MAPPING channelMapping; - CHANNEL_MODE channelMode = isPsActive(hAacConfig->audioObjectType) - ? config->userChannelMode - : hAacConfig->channelMode; - INT numChannels = isPsActive(hAacConfig->audioObjectType) - ? config->nChannels - : hAacConfig->nChannels; - - if (FDKaacEnc_InitChannelMapping(channelMode, hAacConfig->channelOrder, - &channelMapping) != AAC_ENC_OK) { - return AACENC_INIT_ERROR; - } - - /* Check return value and if the SBR encoder can handle enough elements */ - if (channelMapping.nElements > (8)) { - return AACENC_INIT_ERROR; - } - - aacEncDistributeSbrBits(&channelMapping, sbrElInfo, hAacConfig->bitRate); - - initFlag += (InitFlags & AACENC_INIT_STATES) ? 1 : 0; - - /* Let the SBR encoder take a look at the configuration and change if - * required. */ - sbrError = sbrEncoder_Init( - *hSbrEncoder, sbrElInfo, channelMapping.nElements, - hAacEncoder->inputBuffer, hAacEncoder->inputBufferSizePerChannel, - &hAacConfig->bandWidth, &aacBufferOffset, &numChannels, - hAacConfig->syntaxFlags, &hAacConfig->sampleRate, &hAacConfig->sbrRatio, - &frameLength, hAacConfig->audioObjectType, &hAacEncoder->nDelay, - (hAacConfig->audioObjectType == AOT_ER_AAC_ELD) ? 1 : TRANS_FAC, - (config->userTpHeaderPeriod != 0xFF) - ? config->userTpHeaderPeriod - : DEFAULT_HEADER_PERIOD_REPETITION_RATE, - initFlag); - - /* Suppress AOT reconfiguration and check error status. */ - if ((sbrError) || (numChannels != hAacConfig->nChannels)) { - return AACENC_INIT_SBR_ERROR; - } - - if (numChannels == 1) { - hAacConfig->channelMode = MODE_1; - } - - /* Never use PNS if SBR is active */ - if (hAacConfig->usePns) { - hAacConfig->usePns = 0; - } - - /* estimated bitrate consumed by SBR or PS */ - hAacConfig->ancDataBitRate = sbrEncoder_GetEstimateBitrate(*hSbrEncoder); - - } /* sbr initialization */ - if ((hAacEncoder->hMpsEnc != NULL) && (hAacConfig->syntaxFlags & AC_LD_MPS)) { int coreCoderDelay = DELAY_AACELD(hAacConfig->framelength); - if (isSbrActive(hAacConfig)) { - coreCoderDelay = hAacConfig->sbrRatio * coreCoderDelay + - sbrEncoder_GetInputDataDelay(*hSbrEncoder); - } - if (MPS_ENCODER_OK != FDK_MpegsEnc_Init(hAacEncoder->hMpsEnc, hAacConfig->audioObjectType, config->userSamplerate, hAacConfig->bitRate, - isSbrActive(hAacConfig) ? hAacConfig->sbrRatio : 0, + 0, frameLength, /* for dual rate sbr this value is already multiplied by 2 */ hAacEncoder->inputBufferSizePerChannel, @@ -1365,8 +943,7 @@ static AACENC_ERROR aacEncInit(HANDLE_AA FDKaacEnc_MapConfig( &hAacEncoder->coderConfig, config, - getSbrSignalingMode(hAacConfig->audioObjectType, config->userTpType, - config->userTpSignaling, hAacConfig->sbrRatio), + SIG_UNKNOWN, hAacConfig); /* create flags for transport encoder */ @@ -1405,11 +982,6 @@ static AACENC_ERROR aacEncInit(HANDLE_AA ((InitFlags & AACENC_INIT_CONFIG) || (InitFlags & AACENC_INIT_STATES))) { INT inputDataDelay = DELAY_AAC(hAacConfig->framelength); - if (isSbrActive(hAacConfig) && hSbrEncoder != NULL) { - inputDataDelay = hAacConfig->sbrRatio * inputDataDelay + - sbrEncoder_GetInputDataDelay(*hSbrEncoder); - } - if (FDK_MetadataEnc_Init(hAacEncoder->hMetadataEnc, ((InitFlags & AACENC_INIT_STATES) ? 1 : 0), config->userMetaDataMode, inputDataDelay, @@ -1428,10 +1000,6 @@ static AACENC_ERROR aacEncInit(HANDLE_AA hAacEncoder->nDelayCore = hAacEncoder->nDelay - fMax(0, FDK_MpegsEnc_GetDecDelay(hAacEncoder->hMpsEnc)); - } else if (isSbrActive(hAacConfig) && hSbrEncoder != NULL) { - hAacEncoder->nDelayCore = - hAacEncoder->nDelay - - fMax(0, sbrEncoder_GetSbrDecDelay(hAacEncoder->hEnvEnc)); } else { hAacEncoder->nDelayCore = hAacEncoder->nDelay; } @@ -1497,17 +1065,10 @@ AACENC_ERROR aacEncOpen(HANDLE_AACENCODE /* Determine max channel configuration. */ if (maxChannels == 0) { hAacEncoder->nMaxAacChannels = (8); - hAacEncoder->nMaxSbrChannels = (8); } else { hAacEncoder->nMaxAacChannels = (maxChannels & 0x00FF); - if ((hAacEncoder->encoder_modis & ENC_MODE_FLAG_SBR)) { - hAacEncoder->nMaxSbrChannels = (maxChannels & 0xFF00) - ? (maxChannels >> 8) - : hAacEncoder->nMaxAacChannels; - } - if ((hAacEncoder->nMaxAacChannels > (8)) || - (hAacEncoder->nMaxSbrChannels > (8))) { + if ((hAacEncoder->nMaxAacChannels > (8))) { err = AACENC_INVALID_CONFIG; goto bail; } @@ -1515,7 +1076,6 @@ AACENC_ERROR aacEncOpen(HANDLE_AACENCODE /* Max number of elements could be tuned any more. */ hAacEncoder->nMaxAacElements = fixMin(((8)), hAacEncoder->nMaxAacChannels); - hAacEncoder->nMaxSbrElements = fixMin((8), hAacEncoder->nMaxSbrChannels); /* In case of memory overlay, allocate memory out of libraries */ @@ -1533,23 +1093,6 @@ AACENC_ERROR aacEncOpen(HANDLE_AACENCODE goto bail; } - /* Open SBR Encoder */ - if (hAacEncoder->encoder_modis & ENC_MODE_FLAG_SBR) { - if (sbrEncoder_Open( - &hAacEncoder->hEnvEnc, hAacEncoder->nMaxSbrElements, - hAacEncoder->nMaxSbrChannels, - (hAacEncoder->encoder_modis & ENC_MODE_FLAG_PS) ? 1 : 0)) { - err = AACENC_MEMORY_ERROR; - goto bail; - } - - if (NULL == (hAacEncoder->pSbrPayload = (SBRENC_EXT_PAYLOAD *)FDKcalloc( - 1, sizeof(SBRENC_EXT_PAYLOAD)))) { - err = AACENC_MEMORY_ERROR; - goto bail; - } - } /* (encoder_modis&ENC_MODE_FLAG_SBR) */ - /* Open Aac Encoder */ if (FDKaacEnc_Open(&hAacEncoder->hAacEnc, hAacEncoder->nMaxAacElements, hAacEncoder->nMaxAacChannels, (1)) != AAC_ENC_OK) { @@ -1603,11 +1146,6 @@ AACENC_ERROR aacEncOpen(HANDLE_AACENCODE C_ALLOC_SCRATCH_END(_pLibInfo, LIB_INFO, FDK_MODULE_LAST) } - if (transportEnc_RegisterSbrCallback(hAacEncoder->hTpEnc, aacenc_SbrCallback, - hAacEncoder) != 0) { - err = AACENC_INIT_TP_ERROR; - goto bail; - } if (transportEnc_RegisterSscCallback(hAacEncoder->hTpEnc, aacenc_SscCallback, hAacEncoder) != 0) { err = AACENC_INIT_TP_ERROR; @@ -1655,13 +1193,6 @@ AACENC_ERROR aacEncClose(HANDLE_AACENCOD hAacEncoder->outBuffer = NULL; } - if (hAacEncoder->hEnvEnc) { - sbrEncoder_Close(&hAacEncoder->hEnvEnc); - } - if (hAacEncoder->pSbrPayload != NULL) { - FDKfree(hAacEncoder->pSbrPayload); - hAacEncoder->pSbrPayload = NULL; - } if (hAacEncoder->hAacEnc) { FDKaacEnc_Close(&hAacEncoder->hAacEnc); } @@ -1825,9 +1356,6 @@ AACENC_ERROR aacEncEncode(const HANDLE_A for (i = 0; i < MAX_TOTAL_EXT_PAYLOADS; i++) { hAacEncoder->extPayload[i].associatedChElement = -1; } - if (hAacEncoder->pSbrPayload != NULL) { - FDKmemclear(hAacEncoder->pSbrPayload, sizeof(*hAacEncoder->pSbrPayload)); - } /* * Calculate Meta Data info. @@ -1895,41 +1423,6 @@ AACENC_ERROR aacEncEncode(const HANDLE_A } } - if ((NULL != hAacEncoder->hEnvEnc) && (NULL != hAacEncoder->pSbrPayload) && - isSbrActive(&hAacEncoder->aacConfig)) { - INT nPayload = 0; - - /* - * Encode SBR data. - */ - if (sbrEncoder_EncodeFrame(hAacEncoder->hEnvEnc, hAacEncoder->inputBuffer, - hAacEncoder->inputBufferSizePerChannel, - hAacEncoder->pSbrPayload->dataSize[nPayload], - hAacEncoder->pSbrPayload->data[nPayload])) { - err = AACENC_ENCODE_ERROR; - goto bail; - } else { - /* Add SBR extension payload */ - for (i = 0; i < (8); i++) { - if (hAacEncoder->pSbrPayload->dataSize[nPayload][i] > 0) { - hAacEncoder->extPayload[nExtensions].pData = - hAacEncoder->pSbrPayload->data[nPayload][i]; - { - hAacEncoder->extPayload[nExtensions].dataSize = - hAacEncoder->pSbrPayload->dataSize[nPayload][i]; - hAacEncoder->extPayload[nExtensions].associatedChElement = i; - } - hAacEncoder->extPayload[nExtensions].dataType = - EXT_SBR_DATA; /* Once SBR Encoder supports SBR CRC set - EXT_SBR_DATA_CRC */ - nExtensions++; /* or EXT_SBR_DATA according to configuration. */ - FDK_ASSERT(nExtensions <= MAX_TOTAL_EXT_PAYLOADS); - } - } - nPayload++; - } - } /* sbrEnabled */ - if ((inargs->numAncBytes > 0) && (getBufDescIdx(inBufDesc, IN_ANCILLRY_DATA) != -1)) { INT idx = getBufDescIdx(inBufDesc, IN_ANCILLRY_DATA); @@ -1962,14 +1455,6 @@ AACENC_ERROR aacEncEncode(const HANDLE_A hAacEncoder->nSamplesRead -= hAacEncoder->nSamplesToRead; /* - * Delay balancing buffer handling - */ - if (isSbrActive(&hAacEncoder->aacConfig)) { - sbrEncoder_UpdateBuffers(hAacEncoder->hEnvEnc, hAacEncoder->inputBuffer, - hAacEncoder->inputBufferSizePerChannel); - } - - /* * Make bitstream public */ if ((outBufDesc != NULL) && (outBufDesc->numBufs >= 1)) { @@ -2043,7 +1528,6 @@ AACENC_ERROR aacEncGetLibInfo(LIB_INFO * FDK_toolsGetLibInfo(info); transportEnc_GetLibInfo(info); - sbrEncoder_GetLibInfo(info); FDK_MpegsEnc_GetLibInfo(info); /* search for next free tab */ @@ -2242,23 +1726,10 @@ AACENC_ERROR aacEncoder_SetParam(const H } break; case AACENC_SBR_RATIO: - if (settings->userSbrRatio != value) { - if (!((value == 0) || (value == 1) || (value == 2))) { - err = AACENC_INVALID_CONFIG; - break; - } - settings->userSbrRatio = value; - hAacEncoder->InitFlags |= - AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; - } + err = AACENC_INVALID_CONFIG; break; case AACENC_SBR_MODE: - if ((settings->userSbrEnabled != value) && - (NULL != hAacEncoder->hEnvEnc)) { - settings->userSbrEnabled = value; - hAacEncoder->InitFlags |= - AACENC_INIT_CONFIG | AACENC_INIT_STATES | AACENC_INIT_TRANSPORT; - } + err = AACENC_INVALID_CONFIG; break; case AACENC_TRANSMUX: if (settings->userTpType != (TRANSPORT_TYPE)value) { @@ -2421,21 +1892,16 @@ UINT aacEncoder_GetParam(const HANDLE_AA value = (UINT)hAacEncoder->aacConfig.framelength; break; case AACENC_SBR_RATIO: - value = isSbrActive(&hAacEncoder->aacConfig) - ? hAacEncoder->aacConfig.sbrRatio - : 0; + value = 0; break; case AACENC_SBR_MODE: - value = - (UINT)(hAacEncoder->aacConfig.syntaxFlags & AC_SBR_PRESENT) ? 1 : 0; + value = 0; break; case AACENC_TRANSMUX: value = (UINT)settings->userTpType; break; case AACENC_SIGNALING_MODE: - value = (UINT)getSbrSignalingMode( - hAacEncoder->aacConfig.audioObjectType, settings->userTpType, - settings->userTpSignaling, hAacEncoder->aacConfig.sbrRatio); + value = SIG_UNKNOWN; break; case AACENC_PROTECTION: value = (UINT)settings->userTpProtection; --- a/libMpegTPDec/include/tp_data.h +++ b/libMpegTPDec/include/tp_data.h @@ -372,15 +372,6 @@ typedef INT (*cbSsc_t)(void *, HANDLE_FD const INT coreSbrFrameLengthIndex, const INT configBytes, const UCHAR configMode, UCHAR *configChanged); -typedef INT (*cbSbr_t)(void *self, HANDLE_FDK_BITSTREAM hBs, - const INT sampleRateIn, const INT sampleRateOut, - const INT samplesPerFrame, - const AUDIO_OBJECT_TYPE coreCodec, - const MP4_ELEMENT_ID elementID, const INT elementIndex, - const UCHAR harmonicSbr, const UCHAR stereoConfigIndex, - const UCHAR configMode, UCHAR *configChanged, - const INT downscaleFactor); - typedef INT (*cbUsac_t)(void *self, HANDLE_FDK_BITSTREAM hBs); typedef INT (*cbUniDrc_t)(void *self, HANDLE_FDK_BITSTREAM hBs, @@ -401,8 +392,6 @@ typedef struct { callback. */ cbSsc_t cbSsc; /*!< Function pointer for SSC parser callback. */ void *cbSscData; /*!< User data pointer for SSC parser callback. */ - cbSbr_t cbSbr; /*!< Function pointer for SBR header parser callback. */ - void *cbSbrData; /*!< User data pointer for SBR header parser callback. */ cbUsac_t cbUsac; void *cbUsacData; cbUniDrc_t cbUniDrc; /*!< Function pointer for uniDrcConfig and --- a/libMpegTPDec/include/tpdec_lib.h +++ b/libMpegTPDec/include/tpdec_lib.h @@ -435,18 +435,6 @@ int transportDec_RegisterSscCallback(HAN const cbSsc_t cbSscParse, void *user_data); /** - * \brief Register SBR header parser callback. - * \param hTp Handle of transport decoder. - * \param cbUpdateConfig Pointer to a callback function to handle SBR header - * parsing. - * \param user_data void pointer for user data passed to the callback as - * first parameter. - * \return 0 on success. - */ -int transportDec_RegisterSbrCallback(HANDLE_TRANSPORTDEC hTpDec, - const cbSbr_t cbSbr, void *user_data); - -/** * \brief Register USAC SC parser callback. * \param hTp Handle of transport decoder. * \param cbUpdateConfig Pointer to a callback function to handle USAC SC --- a/libMpegTPDec/src/tpdec_asc.cpp +++ b/libMpegTPDec/src/tpdec_asc.cpp @@ -1296,27 +1296,6 @@ static INT ld_sbr_header(CSAudioSpecific 1)) { return TRANSPORTDEC_PARSE_ERROR; } - - /* read elements of the passed channel_configuration until there is ID_NONE */ - while ((element = channel_configuration_array[channelConfiguration][j]) != - ID_NONE) { - /* Setup LFE element for upsampling too. This is essential especially for - * channel configs where the LFE element is not at the last position for - * example in channel config 13 or 14. It leads to memory leaks if the setup - * of the LFE element would be done later in the core. */ - if (element == ID_SCE || element == ID_CPE || element == ID_LFE) { - error |= cb->cbSbr( - cb->cbSbrData, hBs, asc->m_samplingFrequency / dsFactor, - asc->m_extensionSamplingFrequency / dsFactor, - asc->m_samplesPerFrame / dsFactor, AOT_ER_AAC_ELD, element, i++, 0, 0, - asc->configMode, &asc->SbrConfigChanged, dsFactor); - if (error != TRANSPORTDEC_OK) { - goto bail; - } - } - j++; - } -bail: return error; } @@ -1353,40 +1332,6 @@ static TRANSPORTDEC_ERROR EldSpecificCon asc->m_extensionSamplingFrequency = asc->m_samplingFrequency << esc->m_sbrSamplingRate; - - if (cb->cbSbr != NULL) { - /* ELD reduced delay mode: LD-SBR initialization has to know the downscale - information. Postpone LD-SBR initialization and read ELD extension - information first. */ - switch (asc->m_channelConfiguration) { - case 1: - case 2: - numSbrHeader = 1; - break; - case 3: - numSbrHeader = 2; - break; - case 4: - case 5: - case 6: - numSbrHeader = 3; - break; - case 7: - case 11: - case 12: - case 14: - numSbrHeader = 4; - break; - default: - numSbrHeader = 0; - break; - } - for (sbrIndex = 0; sbrIndex < numSbrHeader; sbrIndex++) { - ldSbrLen += skipSbrHeader(hBs, 0); - } - } else { - return TRANSPORTDEC_UNSUPPORTED_FORMAT; - } } esc->m_useLdQmfTimeAlign = 0; @@ -1751,21 +1696,10 @@ static TRANSPORTDEC_ERROR UsacRsv60Decod usc->element[i].m_noiseFilling = FDKreadBits(hBs, 1); /* end of UsacCoreConfig() */ if (usc->m_sbrRatioIndex > 0) { - if (cb->cbSbr == NULL) { - return TRANSPORTDEC_UNKOWN_ERROR; - } /* SbrConfig() ISO/IEC FDIS 23003-3 Table 11 */ usc->element[i].m_harmonicSBR = FDKreadBit(hBs); usc->element[i].m_interTes = FDKreadBit(hBs); usc->element[i].m_pvc = FDKreadBit(hBs); - if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, - asc->m_extensionSamplingFrequency, - asc->m_samplesPerFrame, asc->m_aot, ID_SCE, - channelElementIdx, usc->element[i].m_harmonicSBR, - usc->element[i].m_stereoConfigIndex, asc->configMode, - &asc->SbrConfigChanged, 1)) { - return TRANSPORTDEC_PARSE_ERROR; - } /* end of SbrConfig() */ } usc->m_nUsacChannels += 1; @@ -1780,7 +1714,6 @@ static TRANSPORTDEC_ERROR UsacRsv60Decod usc->element[i].m_noiseFilling = FDKreadBits(hBs, 1); /* end of UsacCoreConfig() */ if (usc->m_sbrRatioIndex > 0) { - if (cb->cbSbr == NULL) return TRANSPORTDEC_UNKOWN_ERROR; /* SbrConfig() ISO/IEC FDIS 23003-3 */ usc->element[i].m_harmonicSBR = FDKreadBit(hBs); usc->element[i].m_interTes = FDKreadBit(hBs); @@ -1798,14 +1731,6 @@ static TRANSPORTDEC_ERROR UsacRsv60Decod usc->element[i].m_stereoConfigIndex == 2) ? ID_SCE : ID_CPE; - if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, - asc->m_extensionSamplingFrequency, - asc->m_samplesPerFrame, asc->m_aot, el_type, - channelElementIdx, usc->element[i].m_harmonicSBR, - usc->element[i].m_stereoConfigIndex, asc->configMode, - &asc->SbrConfigChanged, 1)) { - return TRANSPORTDEC_PARSE_ERROR; - } } /* end of SbrConfig() */ @@ -1847,19 +1772,9 @@ static TRANSPORTDEC_ERROR UsacRsv60Decod usc->element[i].m_noiseFilling = 0; usc->m_nUsacChannels += 1; if (usc->m_sbrRatioIndex > 0) { - /* Use SBR for upsampling */ - if (cb->cbSbr == NULL) return ErrorStatus = TRANSPORTDEC_UNKOWN_ERROR; usc->element[i].m_harmonicSBR = (UCHAR)0; usc->element[i].m_interTes = (UCHAR)0; usc->element[i].m_pvc = (UCHAR)0; - if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, - asc->m_extensionSamplingFrequency, - asc->m_samplesPerFrame, asc->m_aot, ID_LFE, - channelElementIdx, usc->element[i].m_harmonicSBR, - usc->element[i].m_stereoConfigIndex, asc->configMode, - &asc->SbrConfigChanged, 1)) { - return ErrorStatus = TRANSPORTDEC_PARSE_ERROR; - } } channelElementIdx++; break; @@ -2301,19 +2216,6 @@ static TRANSPORTDEC_ERROR Drm_xHEAACDeco if (cb == NULL) { return ErrorStatus; } - if (cb->cbSbr != NULL) { - usc->element[elemIdx].m_harmonicSBR = FDKreadBit(hBs); - usc->element[elemIdx].m_interTes = FDKreadBit(hBs); - usc->element[elemIdx].m_pvc = FDKreadBit(hBs); - if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, - asc->m_extensionSamplingFrequency, - asc->m_samplesPerFrame, asc->m_aot, ID_SCE, elemIdx, - usc->element[elemIdx].m_harmonicSBR, - usc->element[elemIdx].m_stereoConfigIndex, - asc->configMode, &asc->SbrConfigChanged, 1)) { - return ErrorStatus = TRANSPORTDEC_PARSE_ERROR; - } - } } break; case 2: /* stereo: ID_USAC_CPE */ @@ -2362,15 +2264,6 @@ static TRANSPORTDEC_ERROR Drm_xHEAACDeco usc->element[elemIdx].m_stereoConfigIndex == 2) ? ID_SCE : ID_CPE; - if (cb->cbSbr == NULL) return ErrorStatus = TRANSPORTDEC_UNKOWN_ERROR; - if (cb->cbSbr(cb->cbSbrData, hBs, asc->m_samplingFrequency, - asc->m_extensionSamplingFrequency, - asc->m_samplesPerFrame, asc->m_aot, el_type, elemIdx, - usc->element[elemIdx].m_harmonicSBR, - usc->element[elemIdx].m_stereoConfigIndex, - asc->configMode, &asc->SbrConfigChanged, 1)) { - return ErrorStatus = TRANSPORTDEC_PARSE_ERROR; - } } /*usc->element[elemIdx].m_stereoConfigIndex =*/FDKreadBits(hBs, 2); if (usc->element[elemIdx].m_stereoConfigIndex > 0) { --- a/libMpegTPDec/src/tpdec_lib.cpp +++ b/libMpegTPDec/src/tpdec_lib.cpp @@ -602,16 +602,6 @@ int transportDec_RegisterSscCallback(HAN return 0; } -int transportDec_RegisterSbrCallback(HANDLE_TRANSPORTDEC hTpDec, - const cbSbr_t cbSbr, void *user_data) { - if (hTpDec == NULL) { - return -1; - } - hTpDec->callbacks.cbSbr = cbSbr; - hTpDec->callbacks.cbSbrData = user_data; - return 0; -} - int transportDec_RegisterUsacCallback(HANDLE_TRANSPORTDEC hTpDec, const cbUsac_t cbUsac, void *user_data) { if (hTpDec == NULL) { --- a/libMpegTPEnc/include/tpenc_lib.h +++ b/libMpegTPEnc/include/tpenc_lib.h @@ -148,18 +148,6 @@ typedef struct TRANSPORTENC *HANDLE_TRAN CHANNEL_MODE transportEnc_GetChannelMode(int noChannels); /** - * \brief Register SBR heaqder writer callback. - * \param hTp Handle of transport decoder. - * \param cbUpdateConfig Pointer to a callback function to handle SBR header - * writing. - * \param user_data void pointer for user data passed to the callback as - * first parameter. - * \return 0 on success. - */ -int transportEnc_RegisterSbrCallback(HANDLE_TRANSPORTENC hTpEnc, - const cbSbr_t cbSbr, void *user_data); - -/** * \brief Register USAC SC writer callback. * \param hTp Handle of transport decoder. * \param cbUpdateConfig Pointer to a callback function to handle USAC --- a/libMpegTPEnc/src/tpenc_asc.cpp +++ b/libMpegTPEnc/src/tpenc_asc.cpp @@ -769,25 +769,6 @@ static int transportEnc_writeELDSpecific FDKwriteBits(hBs, (config->samplingRate == config->extSamplingRate) ? 0 : 1, 1); /* Samplerate Flag */ FDKwriteBits(hBs, (config->flags & CC_SBRCRC) ? 1 : 0, 1); /* SBR CRC flag*/ - - if (cb->cbSbr != NULL) { - const PCE_CONFIGURATION *pPce; - int e, sbrElementIndex = 0; - - pPce = getPceEntry(config->channelMode); - - for (e = 0; e < pPce->num_front_channel_elements + - pPce->num_side_channel_elements + - pPce->num_back_channel_elements + - pPce->num_lfe_channel_elements; - e++) { - if ((pPce->pEl_type[e] == ID_SCE) || (pPce->pEl_type[e] == ID_CPE)) { - cb->cbSbr(cb->cbSbrData, hBs, 0, 0, 0, config->aot, pPce->pEl_type[e], - sbrElementIndex, 0, 0, 0, NULL, 1); - sbrElementIndex++; - } - } - } } if ((config->flags & CC_SAC) && (cb->cbSsc != NULL)) { --- a/libSBRdec/include/sbrdecoder.h +++ /dev/null @@ -1,401 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: SBR decoder front-end prototypes and definitions. - -*******************************************************************************/ - -#ifndef SBRDECODER_H -#define SBRDECODER_H - -#include "common_fix.h" - -#include "FDK_bitstream.h" -#include "FDK_audio.h" - -#include "FDK_qmf_domain.h" - -#define SBR_DEBUG_EXTHLP \ - "\ ---- SBR ---\n\ - 0x00000010 Ancillary data and SBR-Header\n\ - 0x00000020 SBR-Side info\n\ - 0x00000040 Decoded SBR-bitstream data, e.g. envelope data\n\ - 0x00000080 SBR-Bitstream statistics\n\ - 0x00000100 Miscellaneous SBR-messages\n\ - 0x00000200 SBR-Energies and gains in the adjustor\n\ - 0x00000400 Fatal SBR errors\n\ - 0x00000800 Transposer coefficients for inverse filtering\n\ -" - -/* Capability flags */ -#define CAPF_SBR_LP \ - 0x00000001 /*!< Flag indicating library's capability of Low Power mode. */ -#define CAPF_SBR_HQ \ - 0x00000002 /*!< Flag indicating library's capability of High Quality mode. \ - */ -#define CAPF_SBR_DRM_BS \ - 0x00000004 /*!< Flag indicating library's capability to decode DRM SBR data. \ - */ -#define CAPF_SBR_CONCEALMENT \ - 0x00000008 /*!< Flag indicating library's capability to conceal erroneous \ - frames. */ -#define CAPF_SBR_DRC \ - 0x00000010 /*!< Flag indicating library's capability for Dynamic Range \ - Control. */ -#define CAPF_SBR_PS_MPEG \ - 0x00000020 /*!< Flag indicating library's capability to do MPEG Parametric \ - Stereo. */ -#define CAPF_SBR_PS_DRM \ - 0x00000040 /*!< Flag indicating library's capability to do DRM Parametric \ - Stereo. */ -#define CAPF_SBR_ELD_DOWNSCALE \ - 0x00000080 /*!< Flag indicating library's capability to do ELD decoding in \ - downscaled mode */ -#define CAPF_SBR_HBEHQ \ - 0x00000100 /*!< Flag indicating library's capability to do HQ Harmonic \ - transposing */ - -typedef enum { - SBRDEC_OK = 0, /*!< All fine. */ - /* SBRDEC_CONCEAL, */ - /* SBRDEC_NOSYNCH, */ - /* SBRDEC_ILLEGAL_PROGRAM, */ - /* SBRDEC_ILLEGAL_TAG, */ - /* SBRDEC_ILLEGAL_CHN_CONFIG, */ - /* SBRDEC_ILLEGAL_SECTION, */ - /* SBRDEC_ILLEGAL_SCFACTORS, */ - /* SBRDEC_ILLEGAL_PULSE_DATA, */ - /* SBRDEC_MAIN_PROFILE_NOT_IMPLEMENTED, */ - /* SBRDEC_GC_NOT_IMPLEMENTED, */ - /* SBRDEC_ILLEGAL_PLUS_ELE_ID, */ - SBRDEC_INVALID_ARGUMENT, /*!< */ - SBRDEC_CREATE_ERROR, /*!< */ - SBRDEC_NOT_INITIALIZED, /*!< */ - SBRDEC_MEM_ALLOC_FAILED, /*!< Memory allocation failed. Probably not enough - memory available. */ - SBRDEC_PARSE_ERROR, /*!< */ - SBRDEC_UNSUPPORTED_CONFIG, /*!< */ - SBRDEC_SET_PARAM_FAIL, /*!< */ - SBRDEC_OUTPUT_BUFFER_TOO_SMALL /*!< */ -} SBR_ERROR; - -typedef enum { - SBR_SYSTEM_BITSTREAM_DELAY, /*!< System: Switch to enable an additional SBR - bitstream delay of one frame. */ - SBR_QMF_MODE, /*!< Set QMF mode, either complex or low power. */ - SBR_LD_QMF_TIME_ALIGN, /*!< Set QMF type, either LD-MPS or CLDFB. Relevant for - ELD streams only. */ - SBR_FLUSH_DATA, /*!< Set internal state to flush the decoder with the next - process call. */ - SBR_CLEAR_HISTORY, /*!< Clear all internal states (delay lines, QMF states, - ...). */ - SBR_BS_INTERRUPTION /*!< Signal bit stream interruption. Value is ignored. */ - , - SBR_SKIP_QMF /*!< Enable skipping of QMF step: 1 skip analysis, 2 skip - synthesis */ -} SBRDEC_PARAM; - -typedef struct SBR_DECODER_INSTANCE *HANDLE_SBRDECODER; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief Allocates and initializes one SBR decoder instance. - * \param pSelf Pointer to where a SBR decoder handle is copied into. - * \param pQmfDomain Pointer to QMF domain data structure. - * - * \return Error code. - */ -SBR_ERROR sbrDecoder_Open(HANDLE_SBRDECODER *pSelf, - HANDLE_FDK_QMF_DOMAIN pQmfDomain); - -/** - * \brief Initialize a SBR decoder runtime instance. Must be called before - * decoding starts. - * - * \param self Handle to a SBR decoder instance. - * \param sampleRateIn Input samplerate of the SBR decoder instance. - * \param sampleRateOut Output samplerate of the SBR decoder instance. - * \param samplesPerFrame Number of samples per frames. - * \param coreCodec Audio Object Type (AOT) of the core codec. - * \param elementID Table with MPEG-4 element Ids in canonical order. - * \param elementIndex SBR element index - * \param harmonicSBR - * \param stereoConfigIndex - * \param downscaleFactor ELD downscale factor - * \param configMode Table with MPEG-4 element Ids in canonical order. - * \param configChanged Flag that enforces a complete decoder reset. - * - * \return Error code. - */ -SBR_ERROR sbrDecoder_InitElement( - HANDLE_SBRDECODER self, const int sampleRateIn, const int sampleRateOut, - const int samplesPerFrame, const AUDIO_OBJECT_TYPE coreCodec, - const MP4_ELEMENT_ID elementID, const int elementIndex, - const UCHAR harmonicSBR, const UCHAR stereoConfigIndex, - const UCHAR configMode, UCHAR *configChanged, const INT downscaleFactor); - -/** - * \brief Free config dependent SBR memory. - * \param self SBR decoder instance handle - */ -SBR_ERROR sbrDecoder_FreeMem(HANDLE_SBRDECODER *self); - -/** - * \brief pass out of band SBR header to SBR decoder - * - * \param self Handle to a SBR decoder instance. - * \param hBs bit stream handle data source. - * \param sampleRateIn SBR input sampling rate - * \param sampleRateOut SBR output sampling rate - * \param samplesPerFrame frame length - * \param elementID SBR element ID. - * \param elementIndex SBR element index. - * \param harmonicSBR - * \param stereoConfigIndex - * \param downscaleFactor ELD downscale factor - * - * \return Error code. - */ -INT sbrDecoder_Header(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, - const INT sampleRateIn, const INT sampleRateOut, - const INT samplesPerFrame, - const AUDIO_OBJECT_TYPE coreCodec, - const MP4_ELEMENT_ID elementID, const INT elementIndex, - const UCHAR harmonicSBR, const UCHAR stereoConfigIndex, - const UCHAR configMode, UCHAR *configChanged, - const INT downscaleFactor); - -/** - * \brief Set a parameter of the SBR decoder runtime instance. - * \param self SBR decoder handle. - * \param param Parameter which will be set if successfull. - * \param value New parameter value. - * \return Error code. - */ -SBR_ERROR sbrDecoder_SetParam(HANDLE_SBRDECODER self, const SBRDEC_PARAM param, - const INT value); - -/** - * \brief Feed DRC channel data into a SBR decoder runtime instance. - * - * \param self SBR decoder handle. - * \param ch Channel number to which the DRC data is - * associated to. - * \param numBands Number of DRC bands. - * \param pNextFact_mag Pointer to a table with the DRC factor - * magnitudes. - * \param nextFact_exp Exponent for all DRC factors. - * \param drcInterpolationScheme DRC interpolation scheme. - * \param winSequence Window sequence from core coder (eight short - * or one long window). - * \param pBandTop Pointer to a table with the top borders for - * all DRC bands. - * - * \return Error code. - */ -SBR_ERROR sbrDecoder_drcFeedChannel(HANDLE_SBRDECODER self, INT ch, - UINT numBands, FIXP_DBL *pNextFact_mag, - INT nextFact_exp, - SHORT drcInterpolationScheme, - UCHAR winSequence, USHORT *pBandTop); - -/** - * \brief Disable SBR DRC for a certain channel. - * - * \param hSbrDecoder SBR decoder handle. - * \param ch Number of the channel that has to be disabled. - * - * \return None. - */ -void sbrDecoder_drcDisable(HANDLE_SBRDECODER self, INT ch); - -/** - * \brief Parse one SBR element data extension data block. The bit stream - * position will be placed at the end of the SBR payload block. The remaining - * bits will be returned into *count if a payload length is given - * (byPayLen > 0). If no SBR payload length is given (bsPayLen < 0) then - * the bit stream position on return will be random after this function - * call in case of errors, and any further decoding will be completely - * pointless. This function accepts either normal ordered SBR data or reverse - * ordered DRM SBR data. - * - * \param self SBR decoder handle. - * \param hBs Bit stream handle as data source. - * \param count Pointer to an integer where the amount of parsed SBR - * payload bits is stored into. - * \param bsPayLen If > 0 this value is the SBR payload length. If < 0, - * the SBR payload length is unknown. - * \param flags CRC flag (0: EXT_SBR_DATA; 1: EXT_SBR_DATA_CRC) - * \param prev_element Previous MPEG-4 element ID. - * \param element_index Index of the current element. - * \param acFlags Audio codec flags - * - * \return Error code. - */ -SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, - UCHAR *pDrmBsBuffer, USHORT drmBsBufferSize, - int *count, int bsPayLen, int crcFlag, - MP4_ELEMENT_ID prev_element, int element_index, - UINT acFlags, UINT acElFlags[]); - -/** - * \brief This function decodes the given SBR bitstreams and applies SBR to the - * given time data. - * - * SBR-processing works InPlace. I.e. the calling function has to provide - * a time domain buffer timeData which can hold the completely decoded - * result. - * - * Left and right channel are read and stored according to the - * interleaving flag, frame length and number of channels. - * - * \param self Handle of an open SBR decoder instance. - * \param hSbrBs SBR Bitstream handle. - * \param input Pointer to input data. - * \param timeData Pointer to upsampled output data. - * \param timeDataSize Size of timeData. - * \param numChannels Pointer to a buffer holding the number of channels in - * time data buffer. - * \param sampleRate Output samplerate. - * \param channelMapping Channel mapping indices. - * \param coreDecodedOk Flag indicating if the core decoder did not find any - * error (0: core decoder found errors, 1: no errors). - * \param psDecoded Pointer to a buffer holding a flag. Input: PS is - * possible, Output: PS has been rendered. - * - * \return Error code. - */ -SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input, - INT_PCM *timeData, const int timeDataSize, - int *numChannels, int *sampleRate, - const FDK_channelMapDescr *const mapDescr, - const int mapIdx, const int coreDecodedOk, - UCHAR *psDecoded); - -/** - * \brief Close SBR decoder instance and free memory. - * \param self SBR decoder handle. - * \return Error Code. - */ -SBR_ERROR sbrDecoder_Close(HANDLE_SBRDECODER *self); - -/** - * \brief Get SBR decoder library information. - * \param info Pointer to a LIB_INFO struct, where library information is - * written to. - * \return 0 on success, -1 if invalid handle or if no free element is - * available to write information to. - */ -INT sbrDecoder_GetLibInfo(LIB_INFO *info); - -/** - * \brief Determine the modules output signal delay in samples. - * \param self SBR decoder handle. - * \return The number of samples signal delay added by the module. - */ -UINT sbrDecoder_GetDelay(const HANDLE_SBRDECODER self); - -#ifdef __cplusplus -} -#endif - -#endif --- a/libSBRdec/src/HFgen_preFlat.cpp +++ /dev/null @@ -1,993 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): Oliver Moser, Manuel Jander, Matthias Hildenbrand - - Description: QMF frequency pre-whitening for SBR. - In the documentation the terms "scale factor" and "exponent" - mean the same. Variables containing such information have - the suffix "_sf". - -*******************************************************************************/ - -#include "HFgen_preFlat.h" - -#define POLY_ORDER 3 -#define MAXLOWBANDS 32 -#define LOG10FAC 0.752574989159953f /* == 10/log2(10) * 2^-2 */ -#define LOG10FAC_INV 0.664385618977472f /* == log2(10)/20 * 2^2 */ - -#define FIXP_CHB FIXP_SGL /* STB sinus Tab used in transformation */ -#define CHC(a) (FX_DBL2FXCONST_SGL(a)) -#define FX_CHB2FX_DBL(a) FX_SGL2FX_DBL(a) - -typedef struct backsubst_data { - FIXP_CHB Lnorm1d[3]; /*!< Normalized L matrix */ - SCHAR Lnorm1d_sf[3]; - FIXP_CHB Lnormii - [3]; /*!< The diagonal data points [i][i] of the normalized L matrix */ - SCHAR Lnormii_sf[3]; - FIXP_CHB Bmul0 - [4]; /*!< To normalize L*x=b, Bmul0 is what we need to multiply b with. */ - SCHAR Bmul0_sf[4]; - FIXP_CHB LnormInv1d[6]; /*!< Normalized inverted L matrix (L') */ - SCHAR LnormInv1d_sf[6]; - FIXP_CHB - Bmul1[4]; /*!< To normalize L'*x=b, Bmul1 is what we need to multiply b - with. */ - SCHAR Bmul1_sf[4]; -} backsubst_data; - -/* for each element n do, f(n) = trunc(log2(n))+1 */ -const UCHAR getLog2[32] = {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}; - -/** \def BSD_IDX_OFFSET - * - * bsd[] begins at index 0 with data for numBands=5. The correct bsd[] is - * indexed like bsd[numBands-BSD_IDX_OFFSET]. - */ -#define BSD_IDX_OFFSET 5 - -#define N_NUMBANDS \ - MAXLOWBANDS - BSD_IDX_OFFSET + \ - 1 /*!< Number of backsubst_data elements in bsd */ - -const backsubst_data bsd[N_NUMBANDS] = { - { - /* numBands=5 */ - {CHC(0x66c85a52), CHC(0x4278e587), CHC(0x697dcaff)}, - {-1, 0, 0}, - {CHC(0x66a61789), CHC(0x5253b8e3), CHC(0x5addad81)}, - {3, 4, 1}, - {CHC(0x7525ee90), CHC(0x6e2a1210), CHC(0x6523bb40), CHC(0x59822ead)}, - {-6, -4, -2, 0}, - {CHC(0x609e4cad), CHC(0x59c7e312), CHC(0x681eecac), CHC(0x440ea893), - CHC(0x4a214bb3), CHC(0x53c345a1)}, - {1, 0, -1, -1, -3, -5}, - {CHC(0x7525ee90), CHC(0x58587936), CHC(0x410d0b38), CHC(0x7f1519d6)}, - {-6, -1, 2, 0}, - }, - { - /* numBands=6 */ - {CHC(0x68943285), CHC(0x4841d2c3), CHC(0x6a6214c7)}, - {-1, 0, 0}, - {CHC(0x63c5923e), CHC(0x4e906e18), CHC(0x6285af8a)}, - {3, 4, 1}, - {CHC(0x7263940b), CHC(0x424a69a5), CHC(0x4ae8383a), CHC(0x517b7730)}, - {-7, -4, -2, 0}, - {CHC(0x518aee5f), CHC(0x4823a096), CHC(0x43764a39), CHC(0x6e6faf23), - CHC(0x61bba44f), CHC(0x59d8b132)}, - {1, 0, -1, -2, -4, -6}, - {CHC(0x7263940b), CHC(0x6757bff2), CHC(0x5bf40fe0), CHC(0x7d6f4292)}, - {-7, -2, 1, 0}, - }, - { - /* numBands=7 */ - {CHC(0x699b4c3c), CHC(0x4b8b702f), CHC(0x6ae51a4f)}, - {-1, 0, 0}, - {CHC(0x623a7f49), CHC(0x4ccc91fc), CHC(0x68f048dd)}, - {3, 4, 1}, - {CHC(0x7e6ebe18), CHC(0x5701daf2), CHC(0x74a8198b), CHC(0x4b399aa1)}, - {-8, -5, -3, 0}, - {CHC(0x464a64a6), CHC(0x78e42633), CHC(0x5ee174ba), CHC(0x5d0008c8), - CHC(0x455cff0f), CHC(0x6b9100e7)}, - {1, -1, -2, -2, -4, -7}, - {CHC(0x7e6ebe18), CHC(0x42c52efe), CHC(0x45fe401f), CHC(0x7b5808ef)}, - {-8, -2, 1, 0}, - }, - { - /* numBands=8 */ - {CHC(0x6a3fd9b4), CHC(0x4d99823f), CHC(0x6b372a94)}, - {-1, 0, 0}, - {CHC(0x614c6ef7), CHC(0x4bd06699), CHC(0x6e59cfca)}, - {3, 4, 1}, - {CHC(0x4c389cc5), CHC(0x79686681), CHC(0x5e2544c2), CHC(0x46305b43)}, - {-8, -6, -3, 0}, - {CHC(0x7b4ca7c6), CHC(0x68270ac5), CHC(0x467c644c), CHC(0x505c1b0f), - CHC(0x67a14778), CHC(0x45801767)}, - {0, -1, -2, -2, -5, -7}, - {CHC(0x4c389cc5), CHC(0x5c499ceb), CHC(0x6f863c9f), CHC(0x79059bfc)}, - {-8, -3, 0, 0}, - }, - { - /* numBands=9 */ - {CHC(0x6aad9988), CHC(0x4ef8ac18), CHC(0x6b6df116)}, - {-1, 0, 0}, - {CHC(0x60b159b0), CHC(0x4b33f772), CHC(0x72f5573d)}, - {3, 4, 1}, - {CHC(0x6206cb18), CHC(0x58a7d8dc), CHC(0x4e0b2d0b), CHC(0x4207ad84)}, - {-9, -6, -3, 0}, - {CHC(0x6dadadae), CHC(0x5b8b2cfc), CHC(0x6cf61db2), CHC(0x46c3c90b), - CHC(0x506314ea), CHC(0x5f034acd)}, - {0, -1, -3, -2, -5, -8}, - {CHC(0x6206cb18), CHC(0x42f8b8de), CHC(0x5bb4776f), CHC(0x769acc79)}, - {-9, -3, 0, 0}, - }, - { - /* numBands=10 */ - {CHC(0x6afa7252), CHC(0x4feed3ed), CHC(0x6b94504d)}, - {-1, 0, 0}, - {CHC(0x60467899), CHC(0x4acbafba), CHC(0x76eb327f)}, - {3, 4, 1}, - {CHC(0x42415b15), CHC(0x431080da), CHC(0x420f1c32), CHC(0x7d0c1aeb)}, - {-9, -6, -3, -1}, - {CHC(0x62b2c7a4), CHC(0x51b040a6), CHC(0x56caddb4), CHC(0x7e74a2c8), - CHC(0x4030adf5), CHC(0x43d1dc4f)}, - {0, -1, -3, -3, -5, -8}, - {CHC(0x42415b15), CHC(0x64e299b3), CHC(0x4d33b5e8), CHC(0x742cee5f)}, - {-9, -4, 0, 0}, - }, - { - /* numBands=11 */ - {CHC(0x6b3258bb), CHC(0x50a21233), CHC(0x6bb03c19)}, - {-1, 0, 0}, - {CHC(0x5ff997c6), CHC(0x4a82706e), CHC(0x7a5aae36)}, - {3, 4, 1}, - {CHC(0x5d2fb4fb), CHC(0x685bddd8), CHC(0x71b5e983), CHC(0x7708c90b)}, - {-10, -7, -4, -1}, - {CHC(0x59aceea2), CHC(0x49c428a0), CHC(0x46ca5527), CHC(0x724be884), - CHC(0x68e586da), CHC(0x643485b6)}, - {0, -1, -3, -3, -6, -9}, - {CHC(0x5d2fb4fb), CHC(0x4e3fad1a), CHC(0x42310ba2), CHC(0x71c8b3ce)}, - {-10, -4, 0, 0}, - }, - { - /* numBands=12 */ - {CHC(0x6b5c4726), CHC(0x5128a4a8), CHC(0x6bc52ee1)}, - {-1, 0, 0}, - {CHC(0x5fc06618), CHC(0x4a4ce559), CHC(0x7d5c16e9)}, - {3, 4, 1}, - {CHC(0x43af8342), CHC(0x531533d3), CHC(0x633660a6), CHC(0x71ce6052)}, - {-10, -7, -4, -1}, - {CHC(0x522373d7), CHC(0x434150cb), CHC(0x75b58afc), CHC(0x68474f2d), - CHC(0x575348a5), CHC(0x4c20973f)}, - {0, -1, -4, -3, -6, -9}, - {CHC(0x43af8342), CHC(0x7c4d3d11), CHC(0x732e13db), CHC(0x6f756ac4)}, - {-10, -5, -1, 0}, - }, - { - /* numBands=13 */ - {CHC(0x6b7c8953), CHC(0x51903fcd), CHC(0x6bd54d2e)}, - {-1, 0, 0}, - {CHC(0x5f94abf0), CHC(0x4a2480fa), CHC(0x40013553)}, - {3, 4, 2}, - {CHC(0x6501236e), CHC(0x436b9c4e), CHC(0x578d7881), CHC(0x6d34f92e)}, - {-11, -7, -4, -1}, - {CHC(0x4bc0e2b2), CHC(0x7b9d12ac), CHC(0x636c1c1b), CHC(0x5fe15c2b), - CHC(0x49d54879), CHC(0x7662cfa5)}, - {0, -2, -4, -3, -6, -10}, - {CHC(0x6501236e), CHC(0x64b059fe), CHC(0x656d8359), CHC(0x6d370900)}, - {-11, -5, -1, 0}, - }, - { - /* numBands=14 */ - {CHC(0x6b95e276), CHC(0x51e1b637), CHC(0x6be1f7ed)}, - {-1, 0, 0}, - {CHC(0x5f727a1c), CHC(0x4a053e9c), CHC(0x412e528c)}, - {3, 4, 2}, - {CHC(0x4d178bd4), CHC(0x6f33b4e8), CHC(0x4e028f7f), CHC(0x691ee104)}, - {-11, -8, -4, -1}, - {CHC(0x46473d3f), CHC(0x725bd0a6), CHC(0x55199885), CHC(0x58bcc56b), - CHC(0x7e7e6288), CHC(0x5ddef6eb)}, - {0, -2, -4, -3, -7, -10}, - {CHC(0x4d178bd4), CHC(0x52ebd467), CHC(0x5a395a6e), CHC(0x6b0f724f)}, - {-11, -5, -1, 0}, - }, - { - /* numBands=15 */ - {CHC(0x6baa2a22), CHC(0x5222eb91), CHC(0x6bec1a86)}, - {-1, 0, 0}, - {CHC(0x5f57393b), CHC(0x49ec8934), CHC(0x423b5b58)}, - {3, 4, 2}, - {CHC(0x77fd2486), CHC(0x5cfbdf2c), CHC(0x46153bd1), CHC(0x65757ed9)}, - {-12, -8, -4, -1}, - {CHC(0x41888ee6), CHC(0x6a661db3), CHC(0x49abc8c8), CHC(0x52965848), - CHC(0x6d9301b7), CHC(0x4bb04721)}, - {0, -2, -4, -3, -7, -10}, - {CHC(0x77fd2486), CHC(0x45424c68), CHC(0x50f33cc6), CHC(0x68ff43f0)}, - {-12, -5, -1, 0}, - }, - { - /* numBands=16 */ - {CHC(0x6bbaa499), CHC(0x5257ed94), CHC(0x6bf456e4)}, - {-1, 0, 0}, - {CHC(0x5f412594), CHC(0x49d8a766), CHC(0x432d1dbd)}, - {3, 4, 2}, - {CHC(0x5ef5cfde), CHC(0x4eafcd2d), CHC(0x7ed36893), CHC(0x62274b45)}, - {-12, -8, -5, -1}, - {CHC(0x7ac438f5), CHC(0x637aab21), CHC(0x4067617a), CHC(0x4d3c6ec7), - CHC(0x5fd6e0dd), CHC(0x7bd5f024)}, - {-1, -2, -4, -3, -7, -11}, - {CHC(0x5ef5cfde), CHC(0x751d0d4f), CHC(0x492b3c41), CHC(0x67065409)}, - {-12, -6, -1, 0}, - }, - { - /* numBands=17 */ - {CHC(0x6bc836c9), CHC(0x5283997e), CHC(0x6bfb1f5e)}, - {-1, 0, 0}, - {CHC(0x5f2f02b6), CHC(0x49c868e9), CHC(0x44078151)}, - {3, 4, 2}, - {CHC(0x4c43b65a), CHC(0x4349dcf6), CHC(0x73799e2d), CHC(0x5f267274)}, - {-12, -8, -5, -1}, - {CHC(0x73726394), CHC(0x5d68511a), CHC(0x7191bbcc), CHC(0x48898c70), - CHC(0x548956e1), CHC(0x66981ce8)}, - {-1, -2, -5, -3, -7, -11}, - {CHC(0x4c43b65a), CHC(0x64131116), CHC(0x429028e2), CHC(0x65240211)}, - {-12, -6, -1, 0}, - }, - { - /* numBands=18 */ - {CHC(0x6bd3860d), CHC(0x52a80156), CHC(0x6c00c68d)}, - {-1, 0, 0}, - {CHC(0x5f1fed86), CHC(0x49baf636), CHC(0x44cdb9dc)}, - {3, 4, 2}, - {CHC(0x7c189389), CHC(0x742666d8), CHC(0x69b8c776), CHC(0x5c67e27d)}, - {-13, -9, -5, -1}, - {CHC(0x6cf1ea76), CHC(0x58095703), CHC(0x64e351a9), CHC(0x4460da90), - CHC(0x4b1f8083), CHC(0x55f2d3e1)}, - {-1, -2, -5, -3, -7, -11}, - {CHC(0x7c189389), CHC(0x5651792a), CHC(0x79cb9b3d), CHC(0x635769c0)}, - {-13, -6, -2, 0}, - }, - { - /* numBands=19 */ - {CHC(0x6bdd0c40), CHC(0x52c6abf6), CHC(0x6c058950)}, - {-1, 0, 0}, - {CHC(0x5f133f88), CHC(0x49afb305), CHC(0x45826d73)}, - {3, 4, 2}, - {CHC(0x6621a164), CHC(0x6512528e), CHC(0x61449fc8), CHC(0x59e2a0c0)}, - {-13, -9, -5, -1}, - {CHC(0x6721cadb), CHC(0x53404cd4), CHC(0x5a389e91), CHC(0x40abcbd2), - CHC(0x43332f01), CHC(0x48b82e46)}, - {-1, -2, -5, -3, -7, -11}, - {CHC(0x6621a164), CHC(0x4b12cc28), CHC(0x6ffd4df8), CHC(0x619f835e)}, - {-13, -6, -2, 0}, - }, - { - /* numBands=20 */ - {CHC(0x6be524c5), CHC(0x52e0beb3), CHC(0x6c099552)}, - {-1, 0, 0}, - {CHC(0x5f087c68), CHC(0x49a62bb5), CHC(0x4627d175)}, - {3, 4, 2}, - {CHC(0x54ec6afe), CHC(0x58991a42), CHC(0x59e23e8c), CHC(0x578f4ef4)}, - {-13, -9, -5, -1}, - {CHC(0x61e78f6f), CHC(0x4ef5e1e9), CHC(0x5129c3b8), CHC(0x7ab0f7b2), - CHC(0x78efb076), CHC(0x7c2567ea)}, - {-1, -2, -5, -4, -8, -12}, - {CHC(0x54ec6afe), CHC(0x41c7812c), CHC(0x676f6f8d), CHC(0x5ffb383f)}, - {-13, -6, -2, 0}, - }, - { - /* numBands=21 */ - {CHC(0x6bec1542), CHC(0x52f71929), CHC(0x6c0d0d5e)}, - {-1, 0, 0}, - {CHC(0x5eff45c5), CHC(0x499e092d), CHC(0x46bfc0c9)}, - {3, 4, 2}, - {CHC(0x47457a78), CHC(0x4e2d99b3), CHC(0x53637ea5), CHC(0x5567d0e9)}, - {-13, -9, -5, -1}, - {CHC(0x5d2dc61b), CHC(0x4b1760c8), CHC(0x4967cf39), CHC(0x74b113d8), - CHC(0x6d6676b6), CHC(0x6ad114e9)}, - {-1, -2, -5, -4, -8, -12}, - {CHC(0x47457a78), CHC(0x740accaa), CHC(0x5feb6609), CHC(0x5e696f95)}, - {-13, -7, -2, 0}, - }, - { - /* numBands=22 */ - {CHC(0x6bf21387), CHC(0x530a683c), CHC(0x6c100c59)}, - {-1, 0, 0}, - {CHC(0x5ef752ea), CHC(0x499708c6), CHC(0x474bcd1b)}, - {3, 4, 2}, - {CHC(0x78a21ab7), CHC(0x45658aec), CHC(0x4da3c4fe), CHC(0x5367094b)}, - {-14, -9, -5, -1}, - {CHC(0x58e2df6a), CHC(0x4795990e), CHC(0x42b5e0f7), CHC(0x6f408c64), - CHC(0x6370bebf), CHC(0x5c91ca85)}, - {-1, -2, -5, -4, -8, -12}, - {CHC(0x78a21ab7), CHC(0x66f951d6), CHC(0x594605bb), CHC(0x5ce91657)}, - {-14, -7, -2, 0}, - }, - { - /* numBands=23 */ - {CHC(0x6bf749b2), CHC(0x531b3348), CHC(0x6c12a750)}, - {-1, 0, 0}, - {CHC(0x5ef06b17), CHC(0x4990f6c9), CHC(0x47cd4c5b)}, - {3, 4, 2}, - {CHC(0x66dede36), CHC(0x7bdf90a9), CHC(0x4885b2b9), CHC(0x5188a6b7)}, - {-14, -10, -5, -1}, - {CHC(0x54f85812), CHC(0x446414ae), CHC(0x79c8d519), CHC(0x6a4c2f31), - CHC(0x5ac8325f), CHC(0x50bf9200)}, - {-1, -2, -6, -4, -8, -12}, - {CHC(0x66dede36), CHC(0x5be0d90e), CHC(0x535cc453), CHC(0x5b7923f0)}, - {-14, -7, -2, 0}, - }, - { - /* numBands=24 */ - {CHC(0x6bfbd91d), CHC(0x5329e580), CHC(0x6c14eeed)}, - {-1, 0, 0}, - {CHC(0x5eea6179), CHC(0x498baa90), CHC(0x4845635d)}, - {3, 4, 2}, - {CHC(0x58559b7e), CHC(0x6f1b231f), CHC(0x43f1789b), CHC(0x4fc8fcb8)}, - {-14, -10, -5, -1}, - {CHC(0x51621775), CHC(0x417881a3), CHC(0x6f9ba9b6), CHC(0x65c412b2), - CHC(0x53352c61), CHC(0x46db9caf)}, - {-1, -2, -6, -4, -8, -12}, - {CHC(0x58559b7e), CHC(0x52636003), CHC(0x4e13b316), CHC(0x5a189cdf)}, - {-14, -7, -2, 0}, - }, - { - /* numBands=25 */ - {CHC(0x6bffdc73), CHC(0x5336d4af), CHC(0x6c16f084)}, - {-1, 0, 0}, - {CHC(0x5ee51249), CHC(0x498703cc), CHC(0x48b50e4f)}, - {3, 4, 2}, - {CHC(0x4c5616cf), CHC(0x641b9fad), CHC(0x7fa735e0), CHC(0x4e24e57a)}, - {-14, -10, -6, -1}, - {CHC(0x4e15f47a), CHC(0x7d9481d6), CHC(0x66a82f8a), CHC(0x619ae971), - CHC(0x4c8b2f5f), CHC(0x7d09ec11)}, - {-1, -3, -6, -4, -8, -13}, - {CHC(0x4c5616cf), CHC(0x4a3770fb), CHC(0x495402de), CHC(0x58c693fa)}, - {-14, -7, -2, 0}, - }, - { - /* numBands=26 */ - {CHC(0x6c036943), CHC(0x53424625), CHC(0x6c18b6dc)}, - {-1, 0, 0}, - {CHC(0x5ee060aa), CHC(0x4982e88a), CHC(0x491d277f)}, - {3, 4, 2}, - {CHC(0x425ada5b), CHC(0x5a9368ac), CHC(0x78380a42), CHC(0x4c99aa05)}, - {-14, -10, -6, -1}, - {CHC(0x4b0b569c), CHC(0x78a420da), CHC(0x5ebdf203), CHC(0x5dc57e63), - CHC(0x46a650ff), CHC(0x6ee13fb8)}, - {-1, -3, -6, -4, -8, -13}, - {CHC(0x425ada5b), CHC(0x4323073c), CHC(0x450ae92b), CHC(0x57822ad5)}, - {-14, -7, -2, 0}, - }, - { - /* numBands=27 */ - {CHC(0x6c06911a), CHC(0x534c7261), CHC(0x6c1a4aba)}, - {-1, 0, 0}, - {CHC(0x5edc3524), CHC(0x497f43c0), CHC(0x497e6cd8)}, - {3, 4, 2}, - {CHC(0x73fb550e), CHC(0x5244894f), CHC(0x717aad78), CHC(0x4b24ef6c)}, - {-15, -10, -6, -1}, - {CHC(0x483aebe4), CHC(0x74139116), CHC(0x57b58037), CHC(0x5a3a4f3c), - CHC(0x416950fe), CHC(0x62c7f4f2)}, - {-1, -3, -6, -4, -8, -13}, - {CHC(0x73fb550e), CHC(0x79efb994), CHC(0x4128cab7), CHC(0x564a919a)}, - {-15, -8, -2, 0}, - }, - { - /* numBands=28 */ - {CHC(0x6c096264), CHC(0x535587cd), CHC(0x6c1bb355)}, - {-1, 0, 0}, - {CHC(0x5ed87c76), CHC(0x497c0439), CHC(0x49d98452)}, - {3, 4, 2}, - {CHC(0x65dec5bf), CHC(0x4afd1ba3), CHC(0x6b58b4b3), CHC(0x49c4a7b0)}, - {-15, -10, -6, -1}, - {CHC(0x459e6eb1), CHC(0x6fd850b7), CHC(0x516e7be9), CHC(0x56f13d05), - CHC(0x79785594), CHC(0x58617de7)}, - {-1, -3, -6, -4, -9, -13}, - {CHC(0x65dec5bf), CHC(0x6f2168aa), CHC(0x7b41310f), CHC(0x551f0692)}, - {-15, -8, -3, 0}, - }, - { - /* numBands=29 */ - {CHC(0x6c0be913), CHC(0x535dacd5), CHC(0x6c1cf6a3)}, - {-1, 0, 0}, - {CHC(0x5ed526b4), CHC(0x49791bc5), CHC(0x4a2eff99)}, - {3, 4, 2}, - {CHC(0x59e44afe), CHC(0x44949ada), CHC(0x65bf36f5), CHC(0x487705a0)}, - {-15, -10, -6, -1}, - {CHC(0x43307779), CHC(0x6be959c4), CHC(0x4bce2122), CHC(0x53e34d89), - CHC(0x7115ff82), CHC(0x4f6421a1)}, - {-1, -3, -6, -4, -9, -13}, - {CHC(0x59e44afe), CHC(0x659eab7d), CHC(0x74cea459), CHC(0x53fed574)}, - {-15, -8, -3, 0}, - }, - { - /* numBands=30 */ - {CHC(0x6c0e2f17), CHC(0x53650181), CHC(0x6c1e199d)}, - {-1, 0, 0}, - {CHC(0x5ed2269f), CHC(0x49767e9e), CHC(0x4a7f5f0b)}, - {3, 4, 2}, - {CHC(0x4faa4ae6), CHC(0x7dd3bf11), CHC(0x609e2732), CHC(0x473a72e9)}, - {-15, -11, -6, -1}, - {CHC(0x40ec57c6), CHC(0x683ee147), CHC(0x46be261d), CHC(0x510a7983), - CHC(0x698a84cb), CHC(0x4794a927)}, - {-1, -3, -6, -4, -9, -13}, - {CHC(0x4faa4ae6), CHC(0x5d3615ad), CHC(0x6ee74773), CHC(0x52e956a1)}, - {-15, -8, -3, 0}, - }, - { - /* numBands=31 */ - {CHC(0x6c103cc9), CHC(0x536ba0ac), CHC(0x6c1f2070)}, - {-1, 0, 0}, - {CHC(0x5ecf711e), CHC(0x497422ea), CHC(0x4acb1438)}, - {3, 4, 2}, - {CHC(0x46e322ad), CHC(0x73c32f3c), CHC(0x5be7d172), CHC(0x460d8800)}, - {-15, -11, -6, -1}, - {CHC(0x7d9bf8ad), CHC(0x64d22351), CHC(0x422bdc81), CHC(0x4e6184aa), - CHC(0x62ba2375), CHC(0x40c325de)}, - {-2, -3, -6, -4, -9, -13}, - {CHC(0x46e322ad), CHC(0x55bef2a3), CHC(0x697b3135), CHC(0x51ddee4d)}, - {-15, -8, -3, 0}, - }, - { - // numBands=32 - {CHC(0x6c121933), CHC(0x5371a104), CHC(0x6c200ea0)}, - {-1, 0, 0}, - {CHC(0x5eccfcd3), CHC(0x49720060), CHC(0x4b1283f0)}, - {3, 4, 2}, - {CHC(0x7ea12a52), CHC(0x6aca3303), CHC(0x579072bf), CHC(0x44ef056e)}, - {-16, -11, -6, -1}, - {CHC(0x79a3a9ab), CHC(0x619d38fc), CHC(0x7c0f0734), CHC(0x4be3dd5d), - CHC(0x5c8d7163), CHC(0x7591065f)}, - {-2, -3, -7, -4, -9, -14}, - {CHC(0x7ea12a52), CHC(0x4f1782a6), CHC(0x647cbcb2), CHC(0x50dc0bb1)}, - {-16, -8, -3, 0}, - }, -}; - -/** \def SUM_SAFETY - * - * SUM_SAFTEY defines the bits needed to right-shift every summand in - * order to be overflow-safe. In the two backsubst functions we sum up 4 - * values. Since one of which is definitely not MAXVAL_DBL (the L[x][y]), - * we spare just 2 safety bits instead of 3. - */ -#define SUM_SAFETY 2 - -/** - * \brief Solves L*x=b via backsubstitution according to the following - * structure: - * - * x[0] = b[0]; - * x[1] = (b[1] - x[0]) / L[1][1]; - * x[2] = (b[2] - x[1]*L[2][1] - x[0]) / L[2][2]; - * x[3] = (b[3] - x[2]*L[3][2] - x[1]*L[3][1] - x[0]) / L[3][3]; - * - * \param[in] numBands SBR crossover band index - * \param[in] b the b in L*x=b (one-dimensional) - * \param[out] x output polynomial coefficients (mantissa) - * \param[out] x_sf exponents of x[] - */ -static void backsubst_fw(const int numBands, const FIXP_DBL *const b, - FIXP_DBL *RESTRICT x, int *RESTRICT x_sf) { - int i, k; - int m; /* the trip counter that indexes incrementally through Lnorm1d[] */ - - const FIXP_CHB *RESTRICT pLnorm1d = bsd[numBands - BSD_IDX_OFFSET].Lnorm1d; - const SCHAR *RESTRICT pLnorm1d_sf = bsd[numBands - BSD_IDX_OFFSET].Lnorm1d_sf; - const FIXP_CHB *RESTRICT pLnormii = bsd[numBands - BSD_IDX_OFFSET].Lnormii; - const SCHAR *RESTRICT pLnormii_sf = bsd[numBands - BSD_IDX_OFFSET].Lnormii_sf; - - x[0] = b[0]; - - for (i = 1, m = 0; i <= POLY_ORDER; ++i) { - FIXP_DBL sum = b[i] >> SUM_SAFETY; - int sum_sf = x_sf[i]; - for (k = i - 1; k > 0; --k, ++m) { - int e; - FIXP_DBL mult = fMultNorm(FX_CHB2FX_DBL(pLnorm1d[m]), x[k], &e); - int mult_sf = pLnorm1d_sf[m] + x_sf[k] + e; - - /* check if the new summand mult has a different sf than the sum currently - * has */ - int diff = mult_sf - sum_sf; - - if (diff > 0) { - /* yes, and it requires the sum to be adjusted (scaled down) */ - sum >>= diff; - sum_sf = mult_sf; - } else if (diff < 0) { - /* yes, but here mult needs to be scaled down */ - mult >>= -diff; - } - sum -= (mult >> SUM_SAFETY); - } - - /* - x[0] */ - if (x_sf[0] > sum_sf) { - sum >>= (x_sf[0] - sum_sf); - sum_sf = x_sf[0]; - } - sum -= (x[0] >> (sum_sf - x_sf[0] + SUM_SAFETY)); - - /* instead of the division /L[i][i], we multiply by the inverse */ - int e; - x[i] = fMultNorm(sum, FX_CHB2FX_DBL(pLnormii[i - 1]), &e); - x_sf[i] = sum_sf + pLnormii_sf[i - 1] + e + SUM_SAFETY; - } -} - -/** - * \brief Solves L*x=b via backsubstitution according to the following - * structure: - * - * x[3] = b[3]; - * x[2] = b[2] - L[2][3]*x[3]; - * x[1] = b[1] - L[1][2]*x[2] - L[1][3]*x[3]; - * x[0] = b[0] - L[0][1]*x[1] - L[0][2]*x[2] - L[0][3]*x[3]; - * - * \param[in] numBands SBR crossover band index - * \param[in] b the b in L*x=b (one-dimensional) - * \param[out] x solution vector - * \param[out] x_sf exponents of x[] - */ -static void backsubst_bw(const int numBands, const FIXP_DBL *const b, - FIXP_DBL *RESTRICT x, int *RESTRICT x_sf) { - int i, k; - int m; /* the trip counter that indexes incrementally through LnormInv1d[] */ - - const FIXP_CHB *RESTRICT pLnormInv1d = - bsd[numBands - BSD_IDX_OFFSET].LnormInv1d; - const SCHAR *RESTRICT pLnormInv1d_sf = - bsd[numBands - BSD_IDX_OFFSET].LnormInv1d_sf; - - x[POLY_ORDER] = b[POLY_ORDER]; - - for (i = POLY_ORDER - 1, m = 0; i >= 0; i--) { - FIXP_DBL sum = b[i] >> SUM_SAFETY; - int sum_sf = x_sf[i]; /* sum's sf but disregarding SUM_SAFETY (added at the - iteration's end) */ - - for (k = i + 1; k <= POLY_ORDER; ++k, ++m) { - int e; - FIXP_DBL mult = fMultNorm(FX_CHB2FX_DBL(pLnormInv1d[m]), x[k], &e); - int mult_sf = pLnormInv1d_sf[m] + x_sf[k] + e; - - /* check if the new summand mult has a different sf than sum currently has - */ - int diff = mult_sf - sum_sf; - - if (diff > 0) { - /* yes, and it requires the sum v to be adjusted (scaled down) */ - sum >>= diff; - sum_sf = mult_sf; - } else if (diff < 0) { - /* yes, but here mult needs to be scaled down */ - mult >>= -diff; - } - - /* mult has now the same sf than what it is about to be added to. */ - /* scale mult down additionally so that building the sum is overflow-safe. - */ - sum -= (mult >> SUM_SAFETY); - } - - x_sf[i] = sum_sf + SUM_SAFETY; - x[i] = sum; - } -} - -/** - * \brief Solves a system of linear equations (L*x=b) with the Cholesky - * algorithm. - * - * \param[in] numBands SBR crossover band index - * \param[in,out] b input: vector b, output: solution vector p. - * \param[in,out] b_sf input: exponent of b; output: exponent of solution - * p. - */ -static void choleskySolve(const int numBands, FIXP_DBL *RESTRICT b, - int *RESTRICT b_sf) { - int i, e; - - const FIXP_CHB *RESTRICT pBmul0 = bsd[numBands - BSD_IDX_OFFSET].Bmul0; - const SCHAR *RESTRICT pBmul0_sf = bsd[numBands - BSD_IDX_OFFSET].Bmul0_sf; - const FIXP_CHB *RESTRICT pBmul1 = bsd[numBands - BSD_IDX_OFFSET].Bmul1; - const SCHAR *RESTRICT pBmul1_sf = bsd[numBands - BSD_IDX_OFFSET].Bmul1_sf; - - /* normalize b */ - FIXP_DBL bnormed[POLY_ORDER + 1]; - for (i = 0; i <= POLY_ORDER; ++i) { - bnormed[i] = fMultNorm(b[i], FX_CHB2FX_DBL(pBmul0[i]), &e); - b_sf[i] += pBmul0_sf[i] + e; - } - - backsubst_fw(numBands, bnormed, b, b_sf); - - /* normalize b again */ - for (i = 0; i <= POLY_ORDER; ++i) { - bnormed[i] = fMultNorm(b[i], FX_CHB2FX_DBL(pBmul1[i]), &e); - b_sf[i] += pBmul1_sf[i] + e; - } - - backsubst_bw(numBands, bnormed, b, b_sf); -} - -/** - * \brief Find polynomial approximation of vector y with implicit abscisas - * x=0,1,2,3..n-1 - * - * The problem (V^T * V * p = V^T * y) is solved with Cholesky. - * V is the Vandermode Matrix constructed with x = 0...n-1; - * A = V^T * V; b = V^T * y; - * - * \param[in] numBands SBR crossover band index (BSD_IDX_OFFSET <= numBands <= - * MAXLOWBANDS) - * \param[in] y input vector (mantissa) - * \param[in] y_sf exponents of y[] - * \param[out] p output polynomial coefficients (mantissa) - * \param[out] p_sf exponents of p[] - */ -static void polyfit(const int numBands, const FIXP_DBL *const y, const int y_sf, - FIXP_DBL *RESTRICT p, int *RESTRICT p_sf) { - int i, k; - LONG v[POLY_ORDER + 1]; - int sum_saftey = getLog2[numBands - 1]; - - FDK_ASSERT((numBands >= BSD_IDX_OFFSET) && (numBands <= MAXLOWBANDS)); - - /* construct vector b[] temporarily stored in array p[] */ - FDKmemclear(p, (POLY_ORDER + 1) * sizeof(FIXP_DBL)); - - /* p[] are the sums over n values and each p[i] has its own sf */ - for (i = 0; i <= POLY_ORDER; ++i) p_sf[i] = 1 - DFRACT_BITS; - - for (k = 0; k < numBands; k++) { - v[0] = (LONG)1; - for (i = 1; i <= POLY_ORDER; i++) { - v[i] = k * v[i - 1]; - } - - for (i = 0; i <= POLY_ORDER; i++) { - if (v[POLY_ORDER - i] != 0 && y[k] != FIXP_DBL(0)) { - int e; - FIXP_DBL mult = fMultNorm((FIXP_DBL)v[POLY_ORDER - i], y[k], &e); - int sf = DFRACT_BITS - 1 + y_sf + e; - - /* check if the new summand has a different sf than the sum p[i] - * currently has */ - int diff = sf - p_sf[i]; - - if (diff > 0) { - /* yes, and it requires the sum p[i] to be adjusted (scaled down) */ - p[i] >>= fMin(DFRACT_BITS - 1, diff); - p_sf[i] = sf; - } else if (diff < 0) { - /* yes, but here mult needs to be scaled down */ - mult >>= -diff; - } - - /* mult has now the same sf than what it is about to be added to. - scale mult down additionally so that building the sum is - overflow-safe. */ - p[i] += mult >> sum_saftey; - } - } - } - - p_sf[0] += sum_saftey; - p_sf[1] += sum_saftey; - p_sf[2] += sum_saftey; - p_sf[3] += sum_saftey; - - choleskySolve(numBands, p, p_sf); -} - -/** - * \brief Calculates the output of a POLY_ORDER-degree polynomial function - * with Horner scheme: - * - * y(x) = p3 + p2*x + p1*x^2 + p0*x^3 - * = p3 + x*(p2 + x*(p1 + x*p0)) - * - * The for loop iterates through the mult/add parts in y(x) as above, - * during which regular upscaling ensures a stable exponent of the - * result. - * - * \param[in] p coefficients as in y(x) - * \param[in] p_sf exponents of p[] - * \param[in] x_int non-fractional integer representation of x as in y(x) - * \param[out] out_sf exponent of return value - * - * \return result y(x) - */ -static FIXP_DBL polyval(const FIXP_DBL *const p, const int *const p_sf, - const int x_int, int *out_sf) { - FDK_ASSERT(x_int <= 31); /* otherwise getLog2[] needs more elements */ - - int k, x_sf; - int result_sf; /* working space to compute return value *out_sf */ - FIXP_DBL x; /* fractional value of x_int */ - FIXP_DBL result; /* return value */ - - /* if x == 0, then y(x) is just p3 */ - if (x_int != 0) { - x_sf = getLog2[x_int]; - x = (FIXP_DBL)x_int << (DFRACT_BITS - 1 - x_sf); - } else { - *out_sf = p_sf[3]; - return p[3]; - } - - result = p[0]; - result_sf = p_sf[0]; - - for (k = 1; k <= POLY_ORDER; ++k) { - FIXP_DBL mult = fMult(x, result); - int mult_sf = x_sf + result_sf; - - int room = CountLeadingBits(mult); - mult <<= room; - mult_sf -= room; - - FIXP_DBL pp = p[k]; - int pp_sf = p_sf[k]; - - /* equalize the shift factors of pp and mult so that we can sum them up */ - int diff = pp_sf - mult_sf; - - if (diff > 0) { - diff = fMin(diff, DFRACT_BITS - 1); - mult >>= diff; - } else if (diff < 0) { - diff = fMax(diff, 1 - DFRACT_BITS); - pp >>= -diff; - } - - /* downshift by 1 to ensure safe summation */ - mult >>= 1; - mult_sf++; - pp >>= 1; - pp_sf++; - - result_sf = fMax(pp_sf, mult_sf); - - result = mult + pp; - /* rarely, mult and pp happen to be almost equal except their sign, - and then upon summation, result becomes so small, that it is within - the inaccuracy range of a few bits, and then the relative error - produced by this function may become HUGE */ - } - - *out_sf = result_sf; - return result; -} - -void sbrDecoder_calculateGainVec(FIXP_DBL **sourceBufferReal, - FIXP_DBL **sourceBufferImag, - int sourceBuf_e_overlap, - int sourceBuf_e_current, int overlap, - FIXP_DBL *RESTRICT GainVec, int *GainVec_exp, - int numBands, const int startSample, - const int stopSample) { - FIXP_DBL p[POLY_ORDER + 1]; - FIXP_DBL meanNrg; - FIXP_DBL LowEnv[MAXLOWBANDS]; - FIXP_DBL invNumBands = GetInvInt(numBands); - FIXP_DBL invNumSlots = GetInvInt(stopSample - startSample); - int i, loBand, exp, scale_nrg, scale_nrg_ov; - int sum_scale = 5, sum_scale_ov = 3; - - if (overlap > 8) { - FDK_ASSERT(overlap <= 16); - sum_scale_ov += 1; - sum_scale += 1; - } - - /* exponents of energy values */ - sourceBuf_e_overlap = sourceBuf_e_overlap * 2 + sum_scale_ov; - sourceBuf_e_current = sourceBuf_e_current * 2 + sum_scale; - exp = fMax(sourceBuf_e_overlap, sourceBuf_e_current); - scale_nrg = sourceBuf_e_current - exp; - scale_nrg_ov = sourceBuf_e_overlap - exp; - - meanNrg = (FIXP_DBL)0; - /* Calculate the spectral envelope in dB over the current copy-up frame. */ - for (loBand = 0; loBand < numBands; loBand++) { - FIXP_DBL nrg_ov, nrg; - INT reserve = 0, exp_new; - FIXP_DBL maxVal = FL2FX_DBL(0.0f); - - for (i = startSample; i < stopSample; i++) { - maxVal |= - (FIXP_DBL)((LONG)(sourceBufferReal[i][loBand]) ^ - ((LONG)sourceBufferReal[i][loBand] >> (SAMPLE_BITS - 1))); - maxVal |= - (FIXP_DBL)((LONG)(sourceBufferImag[i][loBand]) ^ - ((LONG)sourceBufferImag[i][loBand] >> (SAMPLE_BITS - 1))); - } - - if (maxVal != FL2FX_DBL(0.0f)) { - reserve = fixMax(0, CntLeadingZeros(maxVal) - 2); - } - - nrg_ov = nrg = (FIXP_DBL)0; - if (scale_nrg_ov > -31) { - for (i = startSample; i < overlap; i++) { - nrg_ov += (fPow2Div2(sourceBufferReal[i][loBand] << reserve) + - fPow2Div2(sourceBufferImag[i][loBand] << reserve)) >> - sum_scale_ov; - } - } else { - scale_nrg_ov = 0; - } - if (scale_nrg > -31) { - for (i = overlap; i < stopSample; i++) { - nrg += (fPow2Div2(sourceBufferReal[i][loBand] << reserve) + - fPow2Div2(sourceBufferImag[i][loBand] << reserve)) >> - sum_scale; - } - } else { - scale_nrg = 0; - } - - nrg = (scaleValue(nrg_ov, scale_nrg_ov) >> 1) + - (scaleValue(nrg, scale_nrg) >> 1); - nrg = fMult(nrg, invNumSlots); - - exp_new = - exp - (2 * reserve) + - 2; /* +1 for addition directly above, +1 for fPow2Div2 in loops above */ - - /* LowEnv = 10*log10(nrg) = log2(nrg) * 10/log2(10) */ - /* exponent of logarithmic energy is 8 */ - if (nrg > (FIXP_DBL)0) { - int exp_log2; - nrg = CalcLog2(nrg, exp_new, &exp_log2); - nrg = scaleValue(nrg, exp_log2 - 6); - nrg = fMult(FL2FXCONST_SGL(LOG10FAC), nrg); - } else { - nrg = (FIXP_DBL)0; - } - LowEnv[loBand] = nrg; - meanNrg += fMult(nrg, invNumBands); - } - exp = 6 + 2; /* exponent of LowEnv: +2 is exponent of LOG10FAC */ - - /* subtract mean before polynomial approximation to reduce dynamic of p[] */ - for (loBand = 0; loBand < numBands; loBand++) { - LowEnv[loBand] = meanNrg - LowEnv[loBand]; - } - - /* For numBands < BSD_IDX_OFFSET (== POLY_ORDER+2) we dont get an - overdetermined equation system. The calculated polynomial will exactly fit - the input data and evaluating the polynomial will lead to the same vector - than the original input vector: lowEnvSlope[] == lowEnv[] - */ - if (numBands > POLY_ORDER + 1) { - /* Find polynomial approximation of LowEnv */ - int p_sf[POLY_ORDER + 1]; - - polyfit(numBands, LowEnv, exp, p, p_sf); - - for (i = 0; i < numBands; i++) { - int sf; - - /* lowBandEnvSlope[i] = tmp; */ - FIXP_DBL tmp = polyval(p, p_sf, i, &sf); - - /* GainVec = 10^((mean(y)-y)/20) = 2^( (mean(y)-y) * log2(10)/20 ) */ - tmp = fMult(tmp, FL2FXCONST_SGL(LOG10FAC_INV)); - GainVec[i] = f2Pow(tmp, sf - 2, - &GainVec_exp[i]); /* -2 is exponent of LOG10FAC_INV */ - } - } else { /* numBands <= POLY_ORDER+1 */ - for (i = 0; i < numBands; i++) { - int sf = exp; /* exponent of LowEnv[] */ - - /* lowBandEnvSlope[i] = LowEnv[i]; */ - FIXP_DBL tmp = LowEnv[i]; - - /* GainVec = 10^((mean(y)-y)/20) = 2^( (mean(y)-y) * log2(10)/20 ) */ - tmp = fMult(tmp, FL2FXCONST_SGL(LOG10FAC_INV)); - GainVec[i] = f2Pow(tmp, sf - 2, - &GainVec_exp[i]); /* -2 is exponent of LOG10FAC_INV */ - } - } -} --- a/libSBRdec/src/HFgen_preFlat.h +++ /dev/null @@ -1,132 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): Manuel Jander, Matthias Hildenbrand - - Description: QMF frequency pre whitening for SBR - -*******************************************************************************/ - -#include "common_fix.h" - -#ifndef HFGEN_PREFLAT_H -#define HFGEN_PREFLAT_H - -#define GAIN_VEC_EXP 6 /* exponent of GainVec[] */ - -/** - * \brief Find gain vector to flatten the QMF frequency bands whithout loosing - * the fine structure. - * \param[in] sourceBufferReal real part of QMF domain data. - * \param[in] sourceBufferImag imaginary part of QMF domain data. - * \param[in] sourceBuffer_e_overlap exponent of sourceBufferReal. - * \param[in] sourceBuffer_e_current exponent of sourceBufferImag. - * \param[in] overlap number of overlap samples. - * \param[out] GainVec array of gain values (one for each QMF band). - * \param[out] GainVec_exp exponents of GainVec (one for each QMF band). - * \param[in] numBands number of low bands (k_0). - * \param[in] startSample time slot start. - * \param[in] stopSample time slot stop. - */ -void sbrDecoder_calculateGainVec(FIXP_DBL **sourceBufferReal, - FIXP_DBL **sourceBufferImag, - int sourceBuffer_e_overlap, - int sourceBuffer_e_current, int overlap, - FIXP_DBL GainVec[], int GainVec_exp[], - const int numBands, const int startSample, - const int stopSample); - -#endif /* __HFGEN_PREFLAT_H */ --- a/libSBRdec/src/arm/lpp_tran_arm.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): Arthur Tritthart - - Description: (ARM optimised) LPP transposer subroutines - -*******************************************************************************/ - -#if defined(__arm__) - -#define FUNCTION_LPPTRANSPOSER_func1 - -#ifdef FUNCTION_LPPTRANSPOSER_func1 - -/* Note: This code requires only 43 cycles per iteration instead of 61 on - * ARM926EJ-S */ -static void lppTransposer_func1(FIXP_DBL *lowBandReal, FIXP_DBL *lowBandImag, - FIXP_DBL **qmfBufferReal, - FIXP_DBL **qmfBufferImag, int loops, int hiBand, - int dynamicScale, int descale, FIXP_SGL a0r, - FIXP_SGL a0i, FIXP_SGL a1r, FIXP_SGL a1i, - const int fPreWhitening, - FIXP_DBL preWhiteningGain, - int preWhiteningGains_sf) { - FIXP_DBL real1, real2, imag1, imag2, accu1, accu2; - - real2 = lowBandReal[-2]; - real1 = lowBandReal[-1]; - imag2 = lowBandImag[-2]; - imag1 = lowBandImag[-1]; - for (int i = 0; i < loops; i++) { - accu1 = fMultDiv2(a0r, real1); - accu2 = fMultDiv2(a0i, imag1); - accu1 = fMultAddDiv2(accu1, a1r, real2); - accu2 = fMultAddDiv2(accu2, a1i, imag2); - real2 = fMultDiv2(a1i, real2); - accu1 = accu1 - accu2; - accu1 = accu1 >> dynamicScale; - - accu2 = fMultAddDiv2(real2, a1r, imag2); - real2 = real1; - imag2 = imag1; - accu2 = fMultAddDiv2(accu2, a0i, real1); - real1 = lowBandReal[i]; - accu2 = fMultAddDiv2(accu2, a0r, imag1); - imag1 = lowBandImag[i]; - accu2 = accu2 >> dynamicScale; - - accu1 <<= 1; - accu2 <<= 1; - accu1 += (real1 >> descale); - accu2 += (imag1 >> descale); - if (fPreWhitening) { - accu1 = scaleValueSaturate(fMultDiv2(accu1, preWhiteningGain), - preWhiteningGains_sf); - accu2 = scaleValueSaturate(fMultDiv2(accu2, preWhiteningGain), - preWhiteningGains_sf); - } - qmfBufferReal[i][hiBand] = accu1; - qmfBufferImag[i][hiBand] = accu2; - } -} -#endif /* #ifdef FUNCTION_LPPTRANSPOSER_func1 */ - -#endif /* __arm__ */ --- a/libSBRdec/src/env_calc.cpp +++ /dev/null @@ -1,3158 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Envelope calculation - - The envelope adjustor compares the energies present in the transposed - highband to the reference energies conveyed with the bitstream. - The highband is amplified (sometimes) or attenuated (mostly) to the - desired level. - - The spectral shape of the reference energies can be changed several times per - frame if necessary. Each set of energy values corresponding to a certain range - in time will be called an envelope here. - The bitstream supports several frequency scales and two resolutions. Normally, - one or more QMF-subbands are grouped to one SBR-band. An envelope contains - reference energies for each SBR-band. - In addition to the energy envelopes, noise envelopes are transmitted that - define the ratio of energy which is generated by adding noise instead of - transposing the lowband. The noise envelopes are given in a coarser time - and frequency resolution. - If a signal contains strong tonal components, synthetic sines can be - generated in individual SBR bands. - - An overlap buffer of 6 QMF-timeslots is used to allow a more - flexible alignment of the envelopes in time that is not restricted to the - core codec's frame borders. - Therefore the envelope adjustor has access to the spectral data of the - current frame as well as the last 6 QMF-timeslots of the previous frame. - However, in average only the data of 1 frame is being processed as - the adjustor is called once per frame. - - Depending on the frequency range set in the bitstream, only QMF-subbands - between lowSubband and highSubband are adjusted. - - Scaling of spectral data to maximize SNR (see #QMF_SCALE_FACTOR) as well as a - special Mantissa-Exponent format ( see calculateSbrEnvelope() ) are being - used. The main entry point for this modules is calculateSbrEnvelope(). - - \sa sbr_scale.h, #QMF_SCALE_FACTOR, calculateSbrEnvelope(), \ref - documentationOverview -*/ - -#include "env_calc.h" - -#include "sbrdec_freq_sca.h" -#include "env_extr.h" -#include "transcendent.h" -#include "sbr_ram.h" -#include "sbr_rom.h" - -#include "genericStds.h" /* need FDKpow() for debug outputs */ - -typedef struct { - FIXP_DBL nrgRef[MAX_FREQ_COEFFS]; - FIXP_DBL nrgEst[MAX_FREQ_COEFFS]; - FIXP_DBL nrgGain[MAX_FREQ_COEFFS]; - FIXP_DBL noiseLevel[MAX_FREQ_COEFFS]; - FIXP_DBL nrgSine[MAX_FREQ_COEFFS]; - - SCHAR nrgRef_e[MAX_FREQ_COEFFS]; - SCHAR nrgEst_e[MAX_FREQ_COEFFS]; - SCHAR nrgGain_e[MAX_FREQ_COEFFS]; - SCHAR noiseLevel_e[MAX_FREQ_COEFFS]; - SCHAR nrgSine_e[MAX_FREQ_COEFFS]; - /* yet another exponent [0]: for ts < no_cols; [1]: for ts >= no_cols */ - SCHAR exponent[2]; -} ENV_CALC_NRGS; - -static void equalizeFiltBufferExp(FIXP_DBL *filtBuffer, SCHAR *filtBuffer_e, - FIXP_DBL *NrgGain, SCHAR *NrgGain_e, - int subbands); - -static void calcNrgPerSubband(FIXP_DBL **analysBufferReal, - FIXP_DBL **analysBufferImag, int lowSubband, - int highSubband, int start_pos, int next_pos, - SCHAR frameExp, FIXP_DBL *nrgEst, - SCHAR *nrgEst_e); - -static void calcNrgPerSfb(FIXP_DBL **analysBufferReal, - FIXP_DBL **analysBufferImag, int nSfb, - UCHAR *freqBandTable, int start_pos, int next_pos, - SCHAR input_e, FIXP_DBL *nrg_est, SCHAR *nrg_est_e); - -static void calcSubbandGain(FIXP_DBL nrgRef, SCHAR nrgRef_e, - ENV_CALC_NRGS *nrgs, int c, FIXP_DBL tmpNoise, - SCHAR tmpNoise_e, UCHAR sinePresentFlag, - UCHAR sineMapped, int noNoiseFlag); - -static void calcAvgGain(ENV_CALC_NRGS *nrgs, int lowSubband, int highSubband, - FIXP_DBL *sumRef_m, SCHAR *sumRef_e, - FIXP_DBL *ptrAvgGain_m, SCHAR *ptrAvgGain_e); - -static void adjustTimeSlot_EldGrid(FIXP_DBL *ptrReal, ENV_CALC_NRGS *nrgs, - UCHAR *ptrHarmIndex, int lowSubbands, - int noSubbands, int scale_change, - int noNoiseFlag, int *ptrPhaseIndex, - int scale_diff_low); - -static void adjustTimeSlotLC(FIXP_DBL *ptrReal, ENV_CALC_NRGS *nrgs, - UCHAR *ptrHarmIndex, int lowSubbands, - int noSubbands, int scale_change, int noNoiseFlag, - int *ptrPhaseIndex); - -/** - * \brief Variant of adjustTimeSlotHQ() which only regards gain and noise but no - * additional harmonics - */ -static void adjustTimeSlotHQ_GainAndNoise( - FIXP_DBL *ptrReal, FIXP_DBL *ptrImag, - HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs, - int lowSubbands, int noSubbands, int scale_change, FIXP_SGL smooth_ratio, - int noNoiseFlag, int filtBufferNoiseShift); -/** - * \brief Variant of adjustTimeSlotHQ() which only adds the additional harmonics - */ -static void adjustTimeSlotHQ_AddHarmonics( - FIXP_DBL *ptrReal, FIXP_DBL *ptrImag, - HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs, - int lowSubbands, int noSubbands, int scale_change); - -static void adjustTimeSlotHQ(FIXP_DBL *ptrReal, FIXP_DBL *ptrImag, - HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, - ENV_CALC_NRGS *nrgs, int lowSubbands, - int noSubbands, int scale_change, - FIXP_SGL smooth_ratio, int noNoiseFlag, - int filtBufferNoiseShift); - -/*! - \brief Map sine flags from bitstream to QMF bands - - The bitstream carries only 1 sine flag per band (Sfb) and frame. - This function maps every sine flag from the bitstream to a specific QMF - subband and to a specific envelope where the sine shall start. The result is - stored in the vector sineMapped which contains one entry per QMF subband. The - value of an entry specifies the envelope where a sine shall start. A value of - 32 indicates that no sine is present in the subband. The missing harmonics - flags from the previous frame (harmFlagsPrev) determine if a sine starts at - the beginning of the frame or at the transient position. Additionally, the - flags in harmFlagsPrev are being updated by this function for the next frame. -*/ -static void mapSineFlags( - UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per band) */ - int nSfb, /*!< Number of bands in the table */ - ULONG *addHarmonics, /*!< Packed addHarmonics of current frame (aligned to - the MSB) */ - ULONG *harmFlagsPrev, /*!< Packed addHarmonics of previous frame (aligned to - the LSB) */ - ULONG *harmFlagsPrevActive, /*!< Packed sineMapped of previous frame - (aligned to the LSB) */ - int tranEnv, /*!< Transient position */ - SCHAR *sineMapped) /*!< Resulting vector of sine start positions for each - QMF band */ - -{ - int i; - int bitcount = 31; - ULONG harmFlagsQmfBands[ADD_HARMONICS_FLAGS_SIZE] = {0}; - ULONG *curFlags = addHarmonics; - - /* - Format of addHarmonics (aligned to MSB): - - Up to MAX_FREQ_COEFFS sfb bands can be flagged for a sign. - first word = flags for lowest 32 sfb bands in use - second word = flags for higest 32 sfb bands (if present) - - Format of harmFlagsPrev (aligned to LSB): - - Index is absolute (not relative to lsb) so it is correct even if lsb - changes first word = flags for lowest 32 qmf bands (0...31) second word = - flags for next higher 32 qmf bands (32...63) - - */ - - /* Reset the output vector first */ - FDKmemset(sineMapped, 32, - MAX_FREQ_COEFFS * sizeof(SCHAR)); /* 32 means 'no sine' */ - FDKmemclear(harmFlagsPrevActive, ADD_HARMONICS_FLAGS_SIZE * sizeof(ULONG)); - for (i = 0; i < nSfb; i++) { - ULONG maskSfb = - 1 << bitcount; /* mask to extract addHarmonics flag of current Sfb */ - - if (*curFlags & maskSfb) { /* There is a sine in this band */ - const int lsb = freqBandTable[0]; /* start of sbr range */ - /* qmf band to which sine should be added */ - const int qmfBand = (freqBandTable[i] + freqBandTable[i + 1]) >> 1; - const int qmfBandDiv32 = qmfBand >> 5; - const int maskQmfBand = - 1 << (qmfBand & - 31); /* mask to extract harmonic flag from prevFlags */ - - /* mapping of sfb with sine to a certain qmf band -> for harmFlagsPrev */ - harmFlagsQmfBands[qmfBandDiv32] |= maskQmfBand; - - /* - If there was a sine in the last frame, let it continue from the first - envelope on else start at the transient position. Indexing of sineMapped - starts relative to lsb. - */ - sineMapped[qmfBand - lsb] = - (harmFlagsPrev[qmfBandDiv32] & maskQmfBand) ? 0 : tranEnv; - if (sineMapped[qmfBand - lsb] < PVC_NTIMESLOT) { - harmFlagsPrevActive[qmfBandDiv32] |= maskQmfBand; - } - } - - if (bitcount-- == 0) { - bitcount = 31; - curFlags++; - } - } - FDKmemcpy(harmFlagsPrev, harmFlagsQmfBands, - sizeof(ULONG) * ADD_HARMONICS_FLAGS_SIZE); -} - -/*! - \brief Restore sineMapped of previous frame - - For PVC it might happen that the PVC framing (always 0) is out of sync with - the SBR framing. The adding of additional harmonics is done based on the SBR - framing. If the SBR framing is trailing the PVC framing the sine mapping of - the previous SBR frame needs to be used for the overlapping time slots. -*/ -/*static*/ void mapSineFlagsPvc( - UCHAR *freqBandTable, /*!< Band borders (there's only 1 flag per - band) */ - int nSfb, /*!< Number of bands in the table */ - ULONG *harmFlagsPrev, /*!< Packed addHarmonics of previous frame - (aligned to the MSB) */ - ULONG *harmFlagsPrevActive, /*!< Packed sineMapped of previous - frame (aligned to the LSB) */ - SCHAR *sineMapped, /*!< Resulting vector of sine start positions - for each QMF band */ - int sinusoidalPos, /*!< sinusoidal position */ - SCHAR *sinusoidalPosPrev, /*!< sinusoidal position of previous - frame */ - int trailingSbrFrame) /*!< indication if the SBR framing is - trailing the PVC framing */ -{ - /* Reset the output vector first */ - FDKmemset(sineMapped, 32, MAX_FREQ_COEFFS); /* 32 means 'no sine' */ - - if (trailingSbrFrame) { - /* restore sineMapped[] of previous frame */ - int i; - const int lsb = freqBandTable[0]; - const int usb = freqBandTable[nSfb]; - for (i = lsb; i < usb; i++) { - const int qmfBandDiv32 = i >> 5; - const int maskQmfBand = - 1 << (i & 31); /* mask to extract harmonic flag from prevFlags */ - - /* Two cases need to be distinguished ... */ - if (harmFlagsPrevActive[qmfBandDiv32] & maskQmfBand) { - /* the sine mapping already started last PVC frame -> seamlessly - * continue */ - sineMapped[i - lsb] = 0; - } else if (harmFlagsPrev[qmfBandDiv32] & maskQmfBand) { - /* sinusoidalPos of prev PVC frame was >= PVC_NTIMESLOT -> sine starts - * in this frame */ - sineMapped[i - lsb] = - *sinusoidalPosPrev - PVC_NTIMESLOT; /* we are 16 sbr time slots - ahead of last frame now */ - } - } - } - *sinusoidalPosPrev = sinusoidalPos; -} - -/*! - \brief Reduce gain-adjustment induced aliasing for real valued filterbank. -*/ -/*static*/ void aliasingReduction( - FIXP_DBL *degreeAlias, /*!< estimated aliasing for each QMF - channel */ - ENV_CALC_NRGS *nrgs, - UCHAR *useAliasReduction, /*!< synthetic sine energy for each - subband, used as flag */ - int noSubbands) /*!< number of QMF channels to process */ -{ - FIXP_DBL *nrgGain = nrgs->nrgGain; /*!< subband gains to be modified */ - SCHAR *nrgGain_e = - nrgs->nrgGain_e; /*!< subband gains to be modified (exponents) */ - FIXP_DBL *nrgEst = nrgs->nrgEst; /*!< subband energy before amplification */ - SCHAR *nrgEst_e = - nrgs->nrgEst_e; /*!< subband energy before amplification (exponents) */ - int grouping = 0, index = 0, noGroups, k; - int groupVector[MAX_FREQ_COEFFS]; - - /* Calculate grouping*/ - for (k = 0; k < noSubbands - 1; k++) { - if ((degreeAlias[k + 1] != FL2FXCONST_DBL(0.0f)) && useAliasReduction[k]) { - if (grouping == 0) { - groupVector[index++] = k; - grouping = 1; - } else { - if (groupVector[index - 1] + 3 == k) { - groupVector[index++] = k + 1; - grouping = 0; - } - } - } else { - if (grouping) { - if (useAliasReduction[k]) - groupVector[index++] = k + 1; - else - groupVector[index++] = k; - grouping = 0; - } - } - } - - if (grouping) { - groupVector[index++] = noSubbands; - } - noGroups = index >> 1; - - /*Calculate new gain*/ - for (int group = 0; group < noGroups; group++) { - FIXP_DBL nrgOrig = FL2FXCONST_DBL( - 0.0f); /* Original signal energy in current group of bands */ - SCHAR nrgOrig_e = 0; - FIXP_DBL nrgAmp = FL2FXCONST_DBL( - 0.0f); /* Amplified signal energy in group (using current gains) */ - SCHAR nrgAmp_e = 0; - FIXP_DBL nrgMod = FL2FXCONST_DBL( - 0.0f); /* Signal energy in group when applying modified gains */ - SCHAR nrgMod_e = 0; - FIXP_DBL groupGain; /* Total energy gain in group */ - SCHAR groupGain_e; - FIXP_DBL compensation; /* Compensation factor for the energy change when - applying modified gains */ - SCHAR compensation_e; - - int startGroup = groupVector[2 * group]; - int stopGroup = groupVector[2 * group + 1]; - - /* Calculate total energy in group before and after amplification with - * current gains: */ - for (k = startGroup; k < stopGroup; k++) { - /* Get original band energy */ - FIXP_DBL tmp = nrgEst[k]; - SCHAR tmp_e = nrgEst_e[k]; - - FDK_add_MantExp(tmp, tmp_e, nrgOrig, nrgOrig_e, &nrgOrig, &nrgOrig_e); - - /* Multiply band energy with current gain */ - tmp = fMult(tmp, nrgGain[k]); - tmp_e = tmp_e + nrgGain_e[k]; - - FDK_add_MantExp(tmp, tmp_e, nrgAmp, nrgAmp_e, &nrgAmp, &nrgAmp_e); - } - - /* Calculate total energy gain in group */ - FDK_divide_MantExp(nrgAmp, nrgAmp_e, nrgOrig, nrgOrig_e, &groupGain, - &groupGain_e); - - for (k = startGroup; k < stopGroup; k++) { - FIXP_DBL tmp; - SCHAR tmp_e; - - FIXP_DBL alpha = degreeAlias[k]; - if (k < noSubbands - 1) { - if (degreeAlias[k + 1] > alpha) alpha = degreeAlias[k + 1]; - } - - /* Modify gain depending on the degree of aliasing */ - FDK_add_MantExp( - fMult(alpha, groupGain), groupGain_e, - fMult(/*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - alpha, - nrgGain[k]), - nrgGain_e[k], &nrgGain[k], &nrgGain_e[k]); - - /* Apply modified gain to original energy */ - tmp = fMult(nrgGain[k], nrgEst[k]); - tmp_e = nrgGain_e[k] + nrgEst_e[k]; - - /* Accumulate energy with modified gains applied */ - FDK_add_MantExp(tmp, tmp_e, nrgMod, nrgMod_e, &nrgMod, &nrgMod_e); - } - - /* Calculate compensation factor to retain the energy of the amplified - * signal */ - FDK_divide_MantExp(nrgAmp, nrgAmp_e, nrgMod, nrgMod_e, &compensation, - &compensation_e); - - /* Apply compensation factor to all gains of the group */ - for (k = startGroup; k < stopGroup; k++) { - nrgGain[k] = fMult(nrgGain[k], compensation); - nrgGain_e[k] = nrgGain_e[k] + compensation_e; - } - } -} - -#define INTER_TES_SF_CHANGE 3 - -typedef struct { - FIXP_DBL subsample_power_low[(((1024) / (32) * (4) / 2) + (3 * (4)))]; - FIXP_DBL subsample_power_high[(((1024) / (32) * (4) / 2) + (3 * (4)))]; - FIXP_DBL gain[(((1024) / (32) * (4) / 2) + (3 * (4)))]; - SCHAR subsample_power_low_sf[(((1024) / (32) * (4) / 2) + (3 * (4)))]; - SCHAR subsample_power_high_sf[(((1024) / (32) * (4) / 2) + (3 * (4)))]; -} ITES_TEMP; - -static void apply_inter_tes(FIXP_DBL **qmfReal, FIXP_DBL **qmfImag, - const QMF_SCALE_FACTOR *sbrScaleFactor, - const SCHAR exp[2], const int RATE, - const int startPos, const int stopPos, - const int lowSubband, const int nbSubband, - const UCHAR gamma_idx) { - int highSubband = lowSubband + nbSubband; - FIXP_DBL *subsample_power_high, *subsample_power_low; - SCHAR *subsample_power_high_sf, *subsample_power_low_sf; - FIXP_DBL total_power_high = (FIXP_DBL)0; - FIXP_DBL total_power_low = (FIXP_DBL)0; - FIXP_DBL *gain; - int gain_sf[(((1024) / (32) * (4) / 2) + (3 * (4)))]; - - /* gamma[gamma_idx] = {0.0f, 1.0f, 2.0f, 4.0f} */ - int gamma_sf = - (int)gamma_idx - 1; /* perhaps +1 to save one bit? (0.99999f vs 1.f) */ - - int nbSubsample = stopPos - startPos; - int i, j; - - C_ALLOC_SCRATCH_START(pTmp, ITES_TEMP, 1); - subsample_power_high = pTmp->subsample_power_high; - subsample_power_low = pTmp->subsample_power_low; - subsample_power_high_sf = pTmp->subsample_power_high_sf; - subsample_power_low_sf = pTmp->subsample_power_low_sf; - gain = pTmp->gain; - - if (gamma_idx > 0) { - int preShift2 = 32 - fNormz((FIXP_DBL)nbSubsample); - int total_power_low_sf = 1 - DFRACT_BITS; - int total_power_high_sf = 1 - DFRACT_BITS; - - for (i = 0; i < nbSubsample; ++i) { - FIXP_DBL bufferReal[(((1024) / (32) * (4) / 2) + (3 * (4)))]; - FIXP_DBL bufferImag[(((1024) / (32) * (4) / 2) + (3 * (4)))]; - FIXP_DBL maxVal = (FIXP_DBL)0; - - int ts = startPos + i; - - int low_sf = (ts < 3 * RATE) ? sbrScaleFactor->ov_lb_scale - : sbrScaleFactor->lb_scale; - low_sf = 15 - low_sf; - - for (j = 0; j < lowSubband; ++j) { - bufferImag[j] = qmfImag[startPos + i][j]; - maxVal |= (FIXP_DBL)((LONG)(bufferImag[j]) ^ - ((LONG)bufferImag[j] >> (DFRACT_BITS - 1))); - bufferReal[j] = qmfReal[startPos + i][j]; - maxVal |= (FIXP_DBL)((LONG)(bufferReal[j]) ^ - ((LONG)bufferReal[j] >> (DFRACT_BITS - 1))); - } - - subsample_power_low[i] = (FIXP_DBL)0; - subsample_power_low_sf[i] = 0; - - if (maxVal != FL2FXCONST_DBL(0.f)) { - /* multiply first, then shift for safe summation */ - int preShift = 1 - CntLeadingZeros(maxVal); - int postShift = 32 - fNormz((FIXP_DBL)lowSubband); - - /* reduce preShift because otherwise we risk to square -1.f */ - if (preShift != 0) preShift++; - - subsample_power_low_sf[i] += (low_sf + preShift) * 2 + postShift + 1; - - scaleValues(bufferReal, lowSubband, -preShift); - scaleValues(bufferImag, lowSubband, -preShift); - for (j = 0; j < lowSubband; ++j) { - FIXP_DBL addme; - addme = fPow2Div2(bufferReal[j]); - subsample_power_low[i] += addme >> postShift; - addme = fPow2Div2(bufferImag[j]); - subsample_power_low[i] += addme >> postShift; - } - } - - /* now get high */ - - maxVal = (FIXP_DBL)0; - - int high_sf = exp[(ts < 16 * RATE) ? 0 : 1]; - - for (j = lowSubband; j < highSubband; ++j) { - bufferImag[j] = qmfImag[startPos + i][j]; - maxVal |= (FIXP_DBL)((LONG)(bufferImag[j]) ^ - ((LONG)bufferImag[j] >> (DFRACT_BITS - 1))); - bufferReal[j] = qmfReal[startPos + i][j]; - maxVal |= (FIXP_DBL)((LONG)(bufferReal[j]) ^ - ((LONG)bufferReal[j] >> (DFRACT_BITS - 1))); - } - - subsample_power_high[i] = (FIXP_DBL)0; - subsample_power_high_sf[i] = 0; - - if (maxVal != FL2FXCONST_DBL(0.f)) { - int preShift = 1 - CntLeadingZeros(maxVal); - /* reduce preShift because otherwise we risk to square -1.f */ - if (preShift != 0) preShift++; - - int postShift = 32 - fNormz((FIXP_DBL)(highSubband - lowSubband)); - subsample_power_high_sf[i] += (high_sf + preShift) * 2 + postShift + 1; - - scaleValues(&bufferReal[lowSubband], highSubband - lowSubband, - -preShift); - scaleValues(&bufferImag[lowSubband], highSubband - lowSubband, - -preShift); - for (j = lowSubband; j < highSubband; j++) { - subsample_power_high[i] += fPow2Div2(bufferReal[j]) >> postShift; - subsample_power_high[i] += fPow2Div2(bufferImag[j]) >> postShift; - } - } - - /* sum all together */ - FIXP_DBL new_summand = subsample_power_low[i]; - int new_summand_sf = subsample_power_low_sf[i]; - - /* make sure the current sum, and the new summand have the same SF */ - if (new_summand_sf > total_power_low_sf) { - int diff = fMin(DFRACT_BITS - 1, new_summand_sf - total_power_low_sf); - total_power_low >>= diff; - total_power_low_sf = new_summand_sf; - } else if (new_summand_sf < total_power_low_sf) { - new_summand >>= - fMin(DFRACT_BITS - 1, total_power_low_sf - new_summand_sf); - } - - total_power_low += (new_summand >> preShift2); - - new_summand = subsample_power_high[i]; - new_summand_sf = subsample_power_high_sf[i]; - if (new_summand_sf > total_power_high_sf) { - total_power_high >>= - fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_sf); - total_power_high_sf = new_summand_sf; - } else if (new_summand_sf < total_power_high_sf) { - new_summand >>= - fMin(DFRACT_BITS - 1, total_power_high_sf - new_summand_sf); - } - - total_power_high += (new_summand >> preShift2); - } - - total_power_low_sf += preShift2; - total_power_high_sf += preShift2; - - /* gain[i] = e_LOW[i] */ - for (i = 0; i < nbSubsample; ++i) { - int sf2; - FIXP_DBL mult = - fMultNorm(subsample_power_low[i], (FIXP_DBL)nbSubsample, &sf2); - int mult_sf = subsample_power_low_sf[i] + DFRACT_BITS - 1 + sf2; - - if (total_power_low != FIXP_DBL(0)) { - gain[i] = fDivNorm(mult, total_power_low, &sf2); - gain_sf[i] = mult_sf - total_power_low_sf + sf2; - gain[i] = sqrtFixp_lookup(gain[i], &gain_sf[i]); - if (gain_sf[i] < 0) { - gain[i] >>= -gain_sf[i]; - gain_sf[i] = 0; - } - } else { - if (mult == FIXP_DBL(0)) { - gain[i] = FIXP_DBL(0); - gain_sf[i] = 0; - } else { - gain[i] = (FIXP_DBL)MAXVAL_DBL; - gain_sf[i] = 0; - } - } - } - - FIXP_DBL total_power_high_after = (FIXP_DBL)0; - int total_power_high_after_sf = 1 - DFRACT_BITS; - - /* gain[i] = g_inter[i] */ - for (i = 0; i < nbSubsample; ++i) { - if (gain_sf[i] < 0) { - gain[i] >>= -gain_sf[i]; - gain_sf[i] = 0; - } - - /* calculate: gain[i] = 1.0f + gamma * (gain[i] - 1.0f); */ - FIXP_DBL one = (FIXP_DBL)MAXVAL_DBL >> - gain_sf[i]; /* to substract this from gain[i] */ - - /* gamma is actually always 1 according to the table, so skip the - * fMultDiv2 */ - FIXP_DBL mult = (gain[i] - one) >> 1; - int mult_sf = gain_sf[i] + gamma_sf; - - one = FL2FXCONST_DBL(0.5f) >> mult_sf; - gain[i] = one + mult; - gain_sf[i] += gamma_sf + 1; /* +1 because of fMultDiv2() */ - - /* set gain to at least 0.2f */ - FIXP_DBL point_two = FL2FXCONST_DBL(0.8f); /* scaled up by 2 */ - int point_two_sf = -2; - - FIXP_DBL tmp = gain[i]; - if (point_two_sf < gain_sf[i]) { - point_two >>= gain_sf[i] - point_two_sf; - } else { - tmp >>= point_two_sf - gain_sf[i]; - } - - /* limit and calculate gain[i]^2 too */ - FIXP_DBL gain_pow2; - int gain_pow2_sf; - if (tmp < point_two) { - gain[i] = FL2FXCONST_DBL(0.8f); - gain_sf[i] = -2; - gain_pow2 = FL2FXCONST_DBL(0.64f); - gain_pow2_sf = -4; - } else { - /* this upscaling seems quite important */ - int r = CountLeadingBits(gain[i]); - gain[i] <<= r; - gain_sf[i] -= r; - - gain_pow2 = fPow2(gain[i]); - gain_pow2_sf = gain_sf[i] << 1; - } - - int room; - subsample_power_high[i] = - fMultNorm(subsample_power_high[i], gain_pow2, &room); - subsample_power_high_sf[i] = - subsample_power_high_sf[i] + gain_pow2_sf + room; - - int new_summand_sf = subsample_power_high_sf[i]; /* + gain_pow2_sf; */ - if (new_summand_sf > total_power_high_after_sf) { - total_power_high_after >>= - fMin(DFRACT_BITS - 1, new_summand_sf - total_power_high_after_sf); - total_power_high_after_sf = new_summand_sf; - } else if (new_summand_sf < total_power_high_after_sf) { - subsample_power_high[i] >>= total_power_high_after_sf - new_summand_sf; - } - total_power_high_after += subsample_power_high[i] >> preShift2; - } - - total_power_high_after_sf += preShift2; - - int sf2 = 0; - FIXP_DBL gain_adj_2 = FL2FX_DBL(0.5f); - int gain_adj_2_sf = 1; - - if ((total_power_high != (FIXP_DBL)0) && - (total_power_high_after != (FIXP_DBL)0)) { - gain_adj_2 = fDivNorm(total_power_high, total_power_high_after, &sf2); - gain_adj_2_sf = total_power_high_sf - total_power_high_after_sf + sf2; - } - - FIXP_DBL gain_adj = sqrtFixp_lookup(gain_adj_2, &gain_adj_2_sf); - int gain_adj_sf = gain_adj_2_sf; - - for (i = 0; i < nbSubsample; ++i) { - gain[i] = fMult(gain[i], gain_adj); - gain_sf[i] += gain_adj_sf; - - /* limit gain */ - if (gain_sf[i] > INTER_TES_SF_CHANGE) { - gain[i] = (FIXP_DBL)MAXVAL_DBL; - gain_sf[i] = INTER_TES_SF_CHANGE; - } - } - - for (i = 0; i < nbSubsample; ++i) { - /* equalize gain[]'s scale factors */ - gain[i] >>= INTER_TES_SF_CHANGE - gain_sf[i]; - - for (j = lowSubband; j < highSubband; j++) { - qmfReal[startPos + i][j] = fMult(qmfReal[startPos + i][j], gain[i]); - qmfImag[startPos + i][j] = fMult(qmfImag[startPos + i][j], gain[i]); - } - } - } else { /* gamma_idx == 0 */ - /* Inter-TES is not active. Still perform the scale change to have a - * consistent scaling for all envelopes of this frame. */ - for (i = 0; i < nbSubsample; ++i) { - for (j = lowSubband; j < highSubband; j++) { - qmfReal[startPos + i][j] >>= INTER_TES_SF_CHANGE; - qmfImag[startPos + i][j] >>= INTER_TES_SF_CHANGE; - } - } - } - C_ALLOC_SCRATCH_END(pTmp, ITES_TEMP, 1); -} - -/*! - \brief Apply spectral envelope to subband samples - - This function is called from sbr_dec.cpp in each frame. - - To enhance accuracy and due to the usage of tables for squareroots and - inverse, some calculations are performed with the operands being split - into mantissa and exponent. The variable names in the source code carry - the suffixes _m and _e respectively. The control data - in #hFrameData containts envelope data which is represented by this format but - stored in single words. (See requantizeEnvelopeData() for details). This data - is unpacked within calculateSbrEnvelope() to follow the described suffix - convention. - - The actual value (comparable to the corresponding float-variable in the - research-implementation) of a mantissa/exponent-pair can be calculated as - - \f$ value = value\_m * 2^{value\_e} \f$ - - All energies and noise levels decoded from the bitstream suit for an - original signal magnitude of \f$\pm 32768 \f$ rather than \f$ \pm 1\f$. - Therefore, the scale factor hb_scale passed into this function will - be converted to an 'input exponent' (#input_e), which fits the internal - representation. - - Before the actual processing, an exponent #adj_e for resulting adjusted - samples is derived from the maximum reference energy. - - Then, for each envelope, the following steps are performed: - - \li Calculate energy in the signal to be adjusted. Depending on the the value - of #interpolFreq (interpolation mode), this is either done seperately for each - QMF-subband or for each SBR-band. The resulting energies are stored in - #nrgEst_m[#MAX_FREQ_COEFFS] (mantissas) and #nrgEst_e[#MAX_FREQ_COEFFS] - (exponents). \li Calculate gain and noise level for each subband:
\f$ gain - = \sqrt{ \frac{nrgRef}{nrgEst} \cdot (1 - noiseRatio) } \hspace{2cm} noise = - \sqrt{ nrgRef \cdot noiseRatio } \f$
where noiseRatio and - nrgRef are extracted from the bitstream and nrgEst is the - subband energy before adjustment. The resulting gains are stored in - #nrgGain_m[#MAX_FREQ_COEFFS] (mantissas) and #nrgGain_e[#MAX_FREQ_COEFFS] - (exponents), the noise levels are stored in #noiseLevel_m[#MAX_FREQ_COEFFS] - and #noiseLevel_e[#MAX_FREQ_COEFFS] (exponents). The sine levels are stored in - #nrgSine_m[#MAX_FREQ_COEFFS] and #nrgSine_e[#MAX_FREQ_COEFFS]. \li Noise - limiting: The gain for each subband is limited both absolutely and relatively - compared to the total gain over all subbands. \li Boost gain: Calculate and - apply boost factor for each limiter band in order to compensate for the energy - loss imposed by the limiting. \li Apply gains and add noise: The gains and - noise levels are applied to all timeslots of the current envelope. A short - FIR-filter (length 4 QMF-timeslots) can be used to smooth the sudden change at - the envelope borders. Each complex subband sample of the current timeslot is - multiplied by the smoothed gain, then random noise with the calculated level - is added. - - \note - To reduce the stack size, some of the local arrays could be located within - the time output buffer. Of the 512 samples temporarily available there, - about half the size is already used by #SBR_FRAME_DATA. A pointer to the - remaining free memory could be supplied by an additional argument to - calculateSbrEnvelope() in sbr_dec: - - \par - \code - calculateSbrEnvelope (&hSbrDec->sbrScaleFactor, - &hSbrDec->SbrCalculateEnvelope, - hHeaderData, - hFrameData, - QmfBufferReal, - QmfBufferImag, - timeOutPtr + sizeof(SBR_FRAME_DATA)/sizeof(Float) + - 1); \endcode - - \par - Within calculateSbrEnvelope(), some pointers could be defined instead of the - arrays #nrgRef_m, #nrgRef_e, #nrgEst_m, #nrgEst_e, #noiseLevel_m: - - \par - \code - fract* nrgRef_m = timeOutPtr; - SCHAR* nrgRef_e = nrgRef_m + MAX_FREQ_COEFFS; - fract* nrgEst_m = nrgRef_e + MAX_FREQ_COEFFS; - SCHAR* nrgEst_e = nrgEst_m + MAX_FREQ_COEFFS; - fract* noiseLevel_m = nrgEst_e + MAX_FREQ_COEFFS; - \endcode - -
-*/ -void calculateSbrEnvelope( - QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */ - HANDLE_SBR_CALCULATE_ENVELOPE - h_sbr_cal_env, /*!< Handle to struct filled by the create-function */ - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */ - PVC_DYNAMIC_DATA *pPvcDynamicData, - FIXP_DBL * - *analysBufferReal, /*!< Real part of subband samples to be processed */ - FIXP_DBL * - *analysBufferImag, /*!< Imag part of subband samples to be processed */ - const int useLP, - FIXP_DBL *degreeAlias, /*!< Estimated aliasing for each QMF channel */ - const UINT flags, const int frameErrorFlag) { - int c, i, i_stop, j, envNoise = 0; - UCHAR *borders = hFrameData->frameInfo.borders; - UCHAR *bordersPvc = hFrameData->frameInfo.pvcBorders; - int pvc_mode = pPvcDynamicData->pvc_mode; - int first_start = - ((pvc_mode > 0) ? bordersPvc[0] : borders[0]) * hHeaderData->timeStep; - FIXP_SGL *noiseLevels = hFrameData->sbrNoiseFloorLevel; - HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData; - UCHAR **pFreqBandTable = hFreq->freqBandTable; - UCHAR *pFreqBandTableNoise = hFreq->freqBandTableNoise; - - int lowSubband = hFreq->lowSubband; - int highSubband = hFreq->highSubband; - int noSubbands = highSubband - lowSubband; - - /* old high subband before headerchange - we asume no headerchange here */ - int ov_highSubband = hFreq->highSubband; - - int noNoiseBands = hFreq->nNfb; - UCHAR *noSubFrameBands = hFreq->nSfb; - int no_cols = hHeaderData->numberTimeSlots * hHeaderData->timeStep; - - SCHAR sineMapped[MAX_FREQ_COEFFS]; - SCHAR ov_adj_e = SCALE2EXP(sbrScaleFactor->ov_hb_scale); - SCHAR adj_e = 0; - SCHAR output_e; - SCHAR final_e = 0; - /* inter-TES is active in one or more envelopes of the current SBR frame */ - const int iTES_enable = hFrameData->iTESactive; - const int iTES_scale_change = (iTES_enable) ? INTER_TES_SF_CHANGE : 0; - SCHAR maxGainLimit_e = (frameErrorFlag) ? MAX_GAIN_CONCEAL_EXP : MAX_GAIN_EXP; - - UCHAR smooth_length = 0; - - FIXP_SGL *pIenv = hFrameData->iEnvelope; - - C_ALLOC_SCRATCH_START(useAliasReduction, UCHAR, 64) - - /* if values differ we had a headerchange; if old highband is bigger then new - one we need to patch overlap-highband-scaling for this frame (see use of - ov_highSubband) as overlap contains higher frequency components which would - get lost */ - if (hFreq->highSubband < hFreq->ov_highSubband) { - ov_highSubband = hFreq->ov_highSubband; - } - - if (pvc_mode > 0) { - if (hFrameData->frameInfo.bordersNoise[0] > bordersPvc[0]) { - /* noise envelope of previous frame is trailing into current PVC frame */ - envNoise = -1; - noiseLevels = h_sbr_cal_env->prevSbrNoiseFloorLevel; - noNoiseBands = h_sbr_cal_env->prevNNfb; - noSubFrameBands = h_sbr_cal_env->prevNSfb; - lowSubband = h_sbr_cal_env->prevLoSubband; - highSubband = h_sbr_cal_env->prevHiSubband; - - noSubbands = highSubband - lowSubband; - ov_highSubband = highSubband; - if (highSubband < h_sbr_cal_env->prev_ov_highSubband) { - ov_highSubband = h_sbr_cal_env->prev_ov_highSubband; - } - - pFreqBandTable[0] = h_sbr_cal_env->prevFreqBandTableLo; - pFreqBandTable[1] = h_sbr_cal_env->prevFreqBandTableHi; - pFreqBandTableNoise = h_sbr_cal_env->prevFreqBandTableNoise; - } - - mapSineFlagsPvc(pFreqBandTable[1], noSubFrameBands[1], - h_sbr_cal_env->harmFlagsPrev, - h_sbr_cal_env->harmFlagsPrevActive, sineMapped, - hFrameData->sinusoidal_position, - &h_sbr_cal_env->sinusoidal_positionPrev, - (borders[0] > bordersPvc[0]) ? 1 : 0); - } else { - /* - Extract sine flags for all QMF bands - */ - mapSineFlags(pFreqBandTable[1], noSubFrameBands[1], - hFrameData->addHarmonics, h_sbr_cal_env->harmFlagsPrev, - h_sbr_cal_env->harmFlagsPrevActive, - hFrameData->frameInfo.tranEnv, sineMapped); - } - - /* - Scan for maximum in bufferd noise levels. - This is needed in case that we had strong noise in the previous frame - which is smoothed into the current frame. - The resulting exponent is used as start value for the maximum search - in reference energies - */ - if (!useLP) - adj_e = h_sbr_cal_env->filtBufferNoise_e - - getScalefactor(h_sbr_cal_env->filtBufferNoise, noSubbands); - - /* - Scan for maximum reference energy to be able - to select appropriate values for adj_e and final_e. - */ - if (pvc_mode > 0) { - INT maxSfbNrg_e = pPvcDynamicData->predEsg_expMax; - - /* Energy -> magnitude (sqrt halfens exponent) */ - maxSfbNrg_e = - (maxSfbNrg_e + 1) >> 1; /* +1 to go safe (round to next higher int) */ - - /* Some safety margin is needed for 2 reasons: - - The signal energy is not equally spread over all subband samples in - a specific sfb of an envelope (Nrg could be too high by a factor of - envWidth * sfbWidth) - - Smoothing can smear high gains of the previous envelope into the - current - */ - maxSfbNrg_e += 6; - - adj_e = maxSfbNrg_e; - // final_e should not exist for PVC fixfix framing - } else { - for (i = 0; i < hFrameData->frameInfo.nEnvelopes; i++) { - INT maxSfbNrg_e = - -FRACT_BITS + NRG_EXP_OFFSET; /* start value for maximum search */ - - /* Fetch frequency resolution for current envelope: */ - for (j = noSubFrameBands[hFrameData->frameInfo.freqRes[i]]; j != 0; j--) { - maxSfbNrg_e = fixMax(maxSfbNrg_e, (INT)((LONG)(*pIenv++) & MASK_E)); - } - maxSfbNrg_e -= NRG_EXP_OFFSET; - - /* Energy -> magnitude (sqrt halfens exponent) */ - maxSfbNrg_e = - (maxSfbNrg_e + 1) >> 1; /* +1 to go safe (round to next higher int) */ - - /* Some safety margin is needed for 2 reasons: - - The signal energy is not equally spread over all subband samples in - a specific sfb of an envelope (Nrg could be too high by a factor of - envWidth * sfbWidth) - - Smoothing can smear high gains of the previous envelope into the - current - */ - maxSfbNrg_e += 6; - - if (borders[i] < hHeaderData->numberTimeSlots) - /* This envelope affects timeslots that belong to the output frame */ - adj_e = fMax(maxSfbNrg_e, adj_e); - - if (borders[i + 1] > hHeaderData->numberTimeSlots) - /* This envelope affects timeslots after the output frame */ - final_e = fMax(maxSfbNrg_e, final_e); - } - } - /* - Calculate adjustment factors and apply them for every envelope. - */ - pIenv = hFrameData->iEnvelope; - - if (pvc_mode > 0) { - /* iterate over SBR time slots starting with bordersPvc[i] */ - i = bordersPvc[0]; /* usually 0; can be >0 if switching from legacy SBR to - PVC */ - i_stop = PVC_NTIMESLOT; - FDK_ASSERT(bordersPvc[hFrameData->frameInfo.nEnvelopes] == PVC_NTIMESLOT); - } else { - /* iterate over SBR envelopes starting with 0 */ - i = 0; - i_stop = hFrameData->frameInfo.nEnvelopes; - } - for (; i < i_stop; i++) { - int k, noNoiseFlag; - SCHAR noise_e, input_e = SCALE2EXP(sbrScaleFactor->hb_scale); - C_ALLOC_SCRATCH_START(pNrgs, ENV_CALC_NRGS, 1); - - /* - Helper variables. - */ - int start_pos, stop_pos, freq_res; - if (pvc_mode > 0) { - start_pos = - hHeaderData->timeStep * - i; /* Start-position in time (subband sample) for current envelope. */ - stop_pos = hHeaderData->timeStep * (i + 1); /* Stop-position in time - (subband sample) for - current envelope. */ - freq_res = - hFrameData->frameInfo - .freqRes[0]; /* Frequency resolution for current envelope. */ - FDK_ASSERT( - freq_res == - hFrameData->frameInfo.freqRes[hFrameData->frameInfo.nEnvelopes - 1]); - } else { - start_pos = hHeaderData->timeStep * - borders[i]; /* Start-position in time (subband sample) for - current envelope. */ - stop_pos = hHeaderData->timeStep * - borders[i + 1]; /* Stop-position in time (subband sample) for - current envelope. */ - freq_res = - hFrameData->frameInfo - .freqRes[i]; /* Frequency resolution for current envelope. */ - } - - /* Always fully initialize the temporary energy table. This prevents - negative energies and extreme gain factors in cases where the number of - limiter bands exceeds the number of subbands. The latter can be caused by - undetected bit errors and is tested by some streams from the - certification set. */ - FDKmemclear(pNrgs, sizeof(ENV_CALC_NRGS)); - - if (pvc_mode > 0) { - /* get predicted energy values from PVC module */ - expandPredEsg(pPvcDynamicData, i, (int)MAX_FREQ_COEFFS, pNrgs->nrgRef, - pNrgs->nrgRef_e); - - if (i == borders[0]) { - mapSineFlags(pFreqBandTable[1], noSubFrameBands[1], - hFrameData->addHarmonics, h_sbr_cal_env->harmFlagsPrev, - h_sbr_cal_env->harmFlagsPrevActive, - hFrameData->sinusoidal_position, sineMapped); - } - - if (i >= hFrameData->frameInfo.bordersNoise[envNoise + 1]) { - if (envNoise >= 0) { - noiseLevels += noNoiseBands; /* The noise floor data is stored in a - row [noiseFloor1 noiseFloor2...].*/ - } else { - /* leave trailing noise envelope of past frame */ - noNoiseBands = hFreq->nNfb; - noSubFrameBands = hFreq->nSfb; - noiseLevels = hFrameData->sbrNoiseFloorLevel; - - lowSubband = hFreq->lowSubband; - highSubband = hFreq->highSubband; - - noSubbands = highSubband - lowSubband; - ov_highSubband = highSubband; - if (highSubband < hFreq->ov_highSubband) { - ov_highSubband = hFreq->ov_highSubband; - } - - pFreqBandTable[0] = hFreq->freqBandTableLo; - pFreqBandTable[1] = hFreq->freqBandTableHi; - pFreqBandTableNoise = hFreq->freqBandTableNoise; - } - envNoise++; - } - } else { - /* If the start-pos of the current envelope equals the stop pos of the - current noise envelope, increase the pointer (i.e. choose the next - noise-floor).*/ - if (borders[i] == hFrameData->frameInfo.bordersNoise[envNoise + 1]) { - noiseLevels += noNoiseBands; /* The noise floor data is stored in a row - [noiseFloor1 noiseFloor2...].*/ - envNoise++; - } - } - if (i == hFrameData->frameInfo.tranEnv || - i == h_sbr_cal_env->prevTranEnv) /* attack */ - { - noNoiseFlag = 1; - if (!useLP) smooth_length = 0; /* No smoothing on attacks! */ - } else { - noNoiseFlag = 0; - if (!useLP) - smooth_length = (1 - hHeaderData->bs_data.smoothingLength) - << 2; /* can become either 0 or 4 */ - } - - /* - Energy estimation in transposed highband. - */ - if (hHeaderData->bs_data.interpolFreq) - calcNrgPerSubband(analysBufferReal, (useLP) ? NULL : analysBufferImag, - lowSubband, highSubband, start_pos, stop_pos, input_e, - pNrgs->nrgEst, pNrgs->nrgEst_e); - else - calcNrgPerSfb(analysBufferReal, (useLP) ? NULL : analysBufferImag, - noSubFrameBands[freq_res], pFreqBandTable[freq_res], - start_pos, stop_pos, input_e, pNrgs->nrgEst, - pNrgs->nrgEst_e); - - /* - Calculate subband gains - */ - { - UCHAR *table = pFreqBandTable[freq_res]; - UCHAR *pUiNoise = - &pFreqBandTableNoise[1]; /*! Upper limit of the current noise floor - band. */ - - FIXP_SGL *pNoiseLevels = noiseLevels; - - FIXP_DBL tmpNoise = - FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M)); - SCHAR tmpNoise_e = - (UCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET; - - int cc = 0; - c = 0; - if (pvc_mode > 0) { - for (j = 0; j < noSubFrameBands[freq_res]; j++) { - UCHAR sinePresentFlag = 0; - int li = table[j]; - int ui = table[j + 1]; - - for (k = li; k < ui; k++) { - sinePresentFlag |= (i >= sineMapped[cc]); - cc++; - } - - for (k = li; k < ui; k++) { - FIXP_DBL refNrg = pNrgs->nrgRef[k - lowSubband]; - SCHAR refNrg_e = pNrgs->nrgRef_e[k - lowSubband]; - - if (k >= *pUiNoise) { - tmpNoise = - FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M)); - tmpNoise_e = - (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET; - - pUiNoise++; - } - - FDK_ASSERT(k >= lowSubband); - - if (useLP) useAliasReduction[k - lowSubband] = !sinePresentFlag; - - pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f); - pNrgs->nrgSine_e[c] = 0; - - calcSubbandGain(refNrg, refNrg_e, pNrgs, c, tmpNoise, tmpNoise_e, - sinePresentFlag, i >= sineMapped[c], noNoiseFlag); - - c++; - } - } - } else { - for (j = 0; j < noSubFrameBands[freq_res]; j++) { - FIXP_DBL refNrg = FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pIenv) & MASK_M)); - SCHAR refNrg_e = (SCHAR)((LONG)(*pIenv) & MASK_E) - NRG_EXP_OFFSET; - - UCHAR sinePresentFlag = 0; - int li = table[j]; - int ui = table[j + 1]; - - for (k = li; k < ui; k++) { - sinePresentFlag |= (i >= sineMapped[cc]); - cc++; - } - - for (k = li; k < ui; k++) { - if (k >= *pUiNoise) { - tmpNoise = - FX_SGL2FX_DBL((FIXP_SGL)((LONG)(*pNoiseLevels) & MASK_M)); - tmpNoise_e = - (SCHAR)((LONG)(*pNoiseLevels++) & MASK_E) - NOISE_EXP_OFFSET; - - pUiNoise++; - } - - FDK_ASSERT(k >= lowSubband); - - if (useLP) useAliasReduction[k - lowSubband] = !sinePresentFlag; - - pNrgs->nrgSine[c] = FL2FXCONST_DBL(0.0f); - pNrgs->nrgSine_e[c] = 0; - - calcSubbandGain(refNrg, refNrg_e, pNrgs, c, tmpNoise, tmpNoise_e, - sinePresentFlag, i >= sineMapped[c], noNoiseFlag); - - pNrgs->nrgRef[c] = refNrg; - pNrgs->nrgRef_e[c] = refNrg_e; - - c++; - } - pIenv++; - } - } - } - - /* - Noise limiting - */ - - for (c = 0; c < hFreq->noLimiterBands; c++) { - FIXP_DBL sumRef, boostGain, maxGain; - FIXP_DBL accu = FL2FXCONST_DBL(0.0f); - SCHAR sumRef_e, boostGain_e, maxGain_e, accu_e = 0; - int maxGainLimGainSum_e = 0; - - calcAvgGain(pNrgs, hFreq->limiterBandTable[c], - hFreq->limiterBandTable[c + 1], &sumRef, &sumRef_e, &maxGain, - &maxGain_e); - - /* Multiply maxGain with limiterGain: */ - maxGain = fMult( - maxGain, - FDK_sbrDecoder_sbr_limGains_m[hHeaderData->bs_data.limiterGains]); - /* maxGain_e += - * FDK_sbrDecoder_sbr_limGains_e[hHeaderData->bs_data.limiterGains]; */ - /* The addition of maxGain_e and FDK_sbrDecoder_sbr_limGains_e[3] might - yield values greater than 127 which doesn't fit into an SCHAR! In these - rare situations limit maxGain_e to 127. - */ - maxGainLimGainSum_e = - maxGain_e + - FDK_sbrDecoder_sbr_limGains_e[hHeaderData->bs_data.limiterGains]; - maxGain_e = - (maxGainLimGainSum_e > 127) ? (SCHAR)127 : (SCHAR)maxGainLimGainSum_e; - - /* Scale mantissa of MaxGain into range between 0.5 and 1: */ - if (maxGain == FL2FXCONST_DBL(0.0f)) - maxGain_e = -FRACT_BITS; - else { - SCHAR charTemp = CountLeadingBits(maxGain); - maxGain_e -= charTemp; - maxGain <<= (int)charTemp; - } - - if (maxGain_e >= maxGainLimit_e) { /* upper limit (e.g. 96 dB) */ - maxGain = FL2FXCONST_DBL(0.5f); - maxGain_e = maxGainLimit_e; - } - - /* Every subband gain is compared to the scaled "average gain" - and limited if necessary: */ - for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1]; - k++) { - if ((pNrgs->nrgGain_e[k] > maxGain_e) || - (pNrgs->nrgGain_e[k] == maxGain_e && pNrgs->nrgGain[k] > maxGain)) { - FIXP_DBL noiseAmp; - SCHAR noiseAmp_e; - - FDK_divide_MantExp(maxGain, maxGain_e, pNrgs->nrgGain[k], - pNrgs->nrgGain_e[k], &noiseAmp, &noiseAmp_e); - pNrgs->noiseLevel[k] = fMult(pNrgs->noiseLevel[k], noiseAmp); - pNrgs->noiseLevel_e[k] += noiseAmp_e; - pNrgs->nrgGain[k] = maxGain; - pNrgs->nrgGain_e[k] = maxGain_e; - } - } - - /* -- Boost gain - Calculate and apply boost factor for each limiter band: - 1. Check how much energy would be present when using the limited gain - 2. Calculate boost factor by comparison with reference energy - 3. Apply boost factor to compensate for the energy loss due to limiting - */ - for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1]; - k++) { - /* 1.a Add energy of adjusted signal (using preliminary gain) */ - FIXP_DBL tmp = fMult(pNrgs->nrgGain[k], pNrgs->nrgEst[k]); - SCHAR tmp_e = pNrgs->nrgGain_e[k] + pNrgs->nrgEst_e[k]; - FDK_add_MantExp(tmp, tmp_e, accu, accu_e, &accu, &accu_e); - - /* 1.b Add sine energy (if present) */ - if (pNrgs->nrgSine[k] != FL2FXCONST_DBL(0.0f)) { - FDK_add_MantExp(pNrgs->nrgSine[k], pNrgs->nrgSine_e[k], accu, accu_e, - &accu, &accu_e); - } else { - /* 1.c Add noise energy (if present) */ - if (noNoiseFlag == 0) { - FDK_add_MantExp(pNrgs->noiseLevel[k], pNrgs->noiseLevel_e[k], accu, - accu_e, &accu, &accu_e); - } - } - } - - /* 2.a Calculate ratio of wanted energy and accumulated energy */ - if (accu == (FIXP_DBL)0) { /* If divisor is 0, limit quotient to +4 dB */ - boostGain = FL2FXCONST_DBL(0.6279716f); - boostGain_e = 2; - } else { - INT div_e; - boostGain = fDivNorm(sumRef, accu, &div_e); - boostGain_e = sumRef_e - accu_e + div_e; - } - - /* 2.b Result too high? --> Limit the boost factor to +4 dB */ - if ((boostGain_e > 3) || - (boostGain_e == 2 && boostGain > FL2FXCONST_DBL(0.6279716f)) || - (boostGain_e == 3 && boostGain > FL2FXCONST_DBL(0.3139858f))) { - boostGain = FL2FXCONST_DBL(0.6279716f); - boostGain_e = 2; - } - /* 3. Multiply all signal components with the boost factor */ - for (k = hFreq->limiterBandTable[c]; k < hFreq->limiterBandTable[c + 1]; - k++) { - pNrgs->nrgGain[k] = fMultDiv2(pNrgs->nrgGain[k], boostGain); - pNrgs->nrgGain_e[k] = pNrgs->nrgGain_e[k] + boostGain_e + 1; - - pNrgs->nrgSine[k] = fMultDiv2(pNrgs->nrgSine[k], boostGain); - pNrgs->nrgSine_e[k] = pNrgs->nrgSine_e[k] + boostGain_e + 1; - - pNrgs->noiseLevel[k] = fMultDiv2(pNrgs->noiseLevel[k], boostGain); - pNrgs->noiseLevel_e[k] = pNrgs->noiseLevel_e[k] + boostGain_e + 1; - } - } - /* End of noise limiting */ - - if (useLP) - aliasingReduction(degreeAlias + lowSubband, pNrgs, useAliasReduction, - noSubbands); - - /* For the timeslots within the range for the output frame, - use the same scale for the noise levels. - Drawback: If the envelope exceeds the frame border, the noise levels - will have to be rescaled later to fit final_e of - the gain-values. - */ - noise_e = (start_pos < no_cols) ? adj_e : final_e; - - /* - Convert energies to amplitude levels - */ - for (k = 0; k < noSubbands; k++) { - FDK_sqrt_MantExp(&pNrgs->nrgSine[k], &pNrgs->nrgSine_e[k], &noise_e); - FDK_sqrt_MantExp(&pNrgs->nrgGain[k], &pNrgs->nrgGain_e[k], - &pNrgs->nrgGain_e[k]); - FDK_sqrt_MantExp(&pNrgs->noiseLevel[k], &pNrgs->noiseLevel_e[k], - &noise_e); - } - - /* - Apply calculated gains and adaptive noise - */ - - /* assembleHfSignals() */ - { - int scale_change, sc_change; - FIXP_SGL smooth_ratio; - int filtBufferNoiseShift = 0; - - /* Initialize smoothing buffers with the first valid values */ - if (h_sbr_cal_env->startUp) { - if (!useLP) { - h_sbr_cal_env->filtBufferNoise_e = noise_e; - - FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e, - noSubbands * sizeof(SCHAR)); - FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel, - noSubbands * sizeof(FIXP_DBL)); - FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain, - noSubbands * sizeof(FIXP_DBL)); - } - h_sbr_cal_env->startUp = 0; - } - - if (!useLP) { - equalizeFiltBufferExp(h_sbr_cal_env->filtBuffer, /* buffered */ - h_sbr_cal_env->filtBuffer_e, /* buffered */ - pNrgs->nrgGain, /* current */ - pNrgs->nrgGain_e, /* current */ - noSubbands); - - /* Adapt exponent of buffered noise levels to the current exponent - so they can easily be smoothed */ - if ((h_sbr_cal_env->filtBufferNoise_e - noise_e) >= 0) { - int shift = fixMin(DFRACT_BITS - 1, - (int)(h_sbr_cal_env->filtBufferNoise_e - noise_e)); - for (k = 0; k < noSubbands; k++) - h_sbr_cal_env->filtBufferNoise[k] <<= shift; - } else { - int shift = - fixMin(DFRACT_BITS - 1, - -(int)(h_sbr_cal_env->filtBufferNoise_e - noise_e)); - for (k = 0; k < noSubbands; k++) - h_sbr_cal_env->filtBufferNoise[k] >>= shift; - } - - h_sbr_cal_env->filtBufferNoise_e = noise_e; - } - - /* find best scaling! */ - scale_change = -(DFRACT_BITS - 1); - for (k = 0; k < noSubbands; k++) { - scale_change = fixMax(scale_change, (int)pNrgs->nrgGain_e[k]); - } - sc_change = (start_pos < no_cols) ? adj_e - input_e : final_e - input_e; - - if ((scale_change - sc_change + 1) < 0) - scale_change -= (scale_change - sc_change + 1); - - scale_change = (scale_change - sc_change) + 1; - - for (k = 0; k < noSubbands; k++) { - int sc = scale_change - pNrgs->nrgGain_e[k] + (sc_change - 1); - pNrgs->nrgGain[k] >>= sc; - pNrgs->nrgGain_e[k] += sc; - } - - if (!useLP) { - for (k = 0; k < noSubbands; k++) { - int sc = - scale_change - h_sbr_cal_env->filtBuffer_e[k] + (sc_change - 1); - h_sbr_cal_env->filtBuffer[k] >>= sc; - } - } - - for (j = start_pos; j < stop_pos; j++) { - /* This timeslot is located within the first part of the processing - buffer and will be fed into the QMF-synthesis for the current frame. - adj_e - input_e - This timeslot will not yet be fed into the QMF so we do not care - about the adj_e. - sc_change = final_e - input_e - */ - if ((j == no_cols) && (start_pos < no_cols)) { - int shift = (int)(noise_e - final_e); - if (!useLP) - filtBufferNoiseShift = shift; /* shifting of - h_sbr_cal_env->filtBufferNoise[k] - will be applied in function - adjustTimeSlotHQ() */ - if (shift >= 0) { - shift = fixMin(DFRACT_BITS - 1, shift); - for (k = 0; k < noSubbands; k++) { - pNrgs->nrgSine[k] <<= shift; - pNrgs->noiseLevel[k] <<= shift; - /* - if (!useLP) - h_sbr_cal_env->filtBufferNoise[k] <<= shift; - */ - } - } else { - shift = fixMin(DFRACT_BITS - 1, -shift); - for (k = 0; k < noSubbands; k++) { - pNrgs->nrgSine[k] >>= shift; - pNrgs->noiseLevel[k] >>= shift; - /* - if (!useLP) - h_sbr_cal_env->filtBufferNoise[k] >>= shift; - */ - } - } - - /* update noise scaling */ - noise_e = final_e; - if (!useLP) - h_sbr_cal_env->filtBufferNoise_e = - noise_e; /* scaling value unused! */ - - /* update gain buffer*/ - sc_change -= (final_e - input_e); - - if (sc_change < 0) { - for (k = 0; k < noSubbands; k++) { - pNrgs->nrgGain[k] >>= -sc_change; - pNrgs->nrgGain_e[k] += -sc_change; - } - if (!useLP) { - for (k = 0; k < noSubbands; k++) { - h_sbr_cal_env->filtBuffer[k] >>= -sc_change; - } - } - } else { - scale_change += sc_change; - } - - } /* if */ - - if (!useLP) { - /* Prevent the smoothing filter from running on constant levels */ - if (j - start_pos < smooth_length) - smooth_ratio = FDK_sbrDecoder_sbr_smoothFilter[j - start_pos]; - else - smooth_ratio = FL2FXCONST_SGL(0.0f); - - if (iTES_enable) { - /* adjustTimeSlotHQ() without adding of additional harmonics */ - adjustTimeSlotHQ_GainAndNoise( - &analysBufferReal[j][lowSubband], - &analysBufferImag[j][lowSubband], h_sbr_cal_env, pNrgs, - lowSubband, noSubbands, fMin(scale_change, DFRACT_BITS - 1), - smooth_ratio, noNoiseFlag, filtBufferNoiseShift); - } else { - adjustTimeSlotHQ(&analysBufferReal[j][lowSubband], - &analysBufferImag[j][lowSubband], h_sbr_cal_env, - pNrgs, lowSubband, noSubbands, - fMin(scale_change, DFRACT_BITS - 1), smooth_ratio, - noNoiseFlag, filtBufferNoiseShift); - } - } else { - FDK_ASSERT(!iTES_enable); /* not supported */ - if (flags & SBRDEC_ELD_GRID) { - /* FDKmemset(analysBufferReal[j], 0, 64 * sizeof(FIXP_DBL)); */ - adjustTimeSlot_EldGrid(&analysBufferReal[j][lowSubband], pNrgs, - &h_sbr_cal_env->harmIndex, lowSubband, - noSubbands, - fMin(scale_change, DFRACT_BITS - 1), - noNoiseFlag, &h_sbr_cal_env->phaseIndex, - EXP2SCALE(adj_e) - sbrScaleFactor->lb_scale); - } else { - adjustTimeSlotLC(&analysBufferReal[j][lowSubband], pNrgs, - &h_sbr_cal_env->harmIndex, lowSubband, noSubbands, - fMin(scale_change, DFRACT_BITS - 1), noNoiseFlag, - &h_sbr_cal_env->phaseIndex); - } - } - /* In case the envelope spans accross the no_cols border both exponents - * are needed. */ - /* nrgGain_e[0...(noSubbands-1)] are equalized by - * equalizeFiltBufferExp() */ - pNrgs->exponent[(j < no_cols) ? 0 : 1] = - (SCHAR)((15 - sbrScaleFactor->hb_scale) + pNrgs->nrgGain_e[0] + 1 - - scale_change); - } /* for */ - - if (iTES_enable) { - apply_inter_tes( - analysBufferReal, /* pABufR, */ - analysBufferImag, /* pABufI, */ - sbrScaleFactor, pNrgs->exponent, hHeaderData->timeStep, start_pos, - stop_pos, lowSubband, noSubbands, - hFrameData - ->interTempShapeMode[i] /* frameData->interTempShapeMode[env] */ - ); - - /* add additional harmonics */ - for (j = start_pos; j < stop_pos; j++) { - /* match exponent of additional harmonics to scale change of QMF data - * caused by apply_inter_tes() */ - scale_change = 0; - - if ((start_pos <= no_cols) && (stop_pos > no_cols)) { - /* Scaling of analysBuffers was potentially changed within this - envelope. The pNrgs->nrgSine_e match the second part of the - envelope. For (j<=no_cols) the exponent of the sine energies has - to be adapted. */ - scale_change = pNrgs->exponent[1] - pNrgs->exponent[0]; - } - - adjustTimeSlotHQ_AddHarmonics( - &analysBufferReal[j][lowSubband], - &analysBufferImag[j][lowSubband], h_sbr_cal_env, pNrgs, - lowSubband, noSubbands, - -iTES_scale_change + ((j < no_cols) ? scale_change : 0)); - } - } - - if (!useLP) { - /* Update time-smoothing-buffers for gains and noise levels - The gains and the noise values of the current envelope are copied - into the buffer. This has to be done at the end of each envelope as - the values are required for a smooth transition to the next envelope. - */ - FDKmemcpy(h_sbr_cal_env->filtBuffer, pNrgs->nrgGain, - noSubbands * sizeof(FIXP_DBL)); - FDKmemcpy(h_sbr_cal_env->filtBuffer_e, pNrgs->nrgGain_e, - noSubbands * sizeof(SCHAR)); - FDKmemcpy(h_sbr_cal_env->filtBufferNoise, pNrgs->noiseLevel, - noSubbands * sizeof(FIXP_DBL)); - } - } - C_ALLOC_SCRATCH_END(pNrgs, ENV_CALC_NRGS, 1); - } - - /* adapt adj_e to the scale change caused by apply_inter_tes() */ - adj_e += iTES_scale_change; - - /* Rescale output samples */ - { - FIXP_DBL maxVal; - int ov_reserve, reserve; - - /* Determine headroom in old adjusted samples */ - maxVal = - maxSubbandSample(analysBufferReal, (useLP) ? NULL : analysBufferImag, - lowSubband, ov_highSubband, 0, first_start); - - ov_reserve = fNorm(maxVal); - - /* Determine headroom in new adjusted samples */ - maxVal = - maxSubbandSample(analysBufferReal, (useLP) ? NULL : analysBufferImag, - lowSubband, highSubband, first_start, no_cols); - - reserve = fNorm(maxVal); - - /* Determine common output exponent */ - output_e = fMax(ov_adj_e - ov_reserve, adj_e - reserve); - - /* Rescale old samples */ - rescaleSubbandSamples(analysBufferReal, (useLP) ? NULL : analysBufferImag, - lowSubband, ov_highSubband, 0, first_start, - ov_adj_e - output_e); - - /* Rescale new samples */ - rescaleSubbandSamples(analysBufferReal, (useLP) ? NULL : analysBufferImag, - lowSubband, highSubband, first_start, no_cols, - adj_e - output_e); - } - - /* Update hb_scale */ - sbrScaleFactor->hb_scale = EXP2SCALE(output_e); - - /* Save the current final exponent for the next frame: */ - /* adapt final_e to the scale change caused by apply_inter_tes() */ - sbrScaleFactor->ov_hb_scale = EXP2SCALE(final_e + iTES_scale_change); - - /* We need to remember to the next frame that the transient - will occur in the first envelope (if tranEnv == nEnvelopes). */ - if (hFrameData->frameInfo.tranEnv == hFrameData->frameInfo.nEnvelopes) - h_sbr_cal_env->prevTranEnv = 0; - else - h_sbr_cal_env->prevTranEnv = -1; - - if (pvc_mode > 0) { - /* Not more than just the last noise envelope reaches into the next PVC - frame! This should be true because bs_noise_position is <= 15 */ - FDK_ASSERT(hFrameData->frameInfo - .bordersNoise[hFrameData->frameInfo.nNoiseEnvelopes - 1] < - PVC_NTIMESLOT); - if (hFrameData->frameInfo - .bordersNoise[hFrameData->frameInfo.nNoiseEnvelopes] > - PVC_NTIMESLOT) { - FDK_ASSERT(noiseLevels == - (hFrameData->sbrNoiseFloorLevel + - (hFrameData->frameInfo.nNoiseEnvelopes - 1) * noNoiseBands)); - h_sbr_cal_env->prevNNfb = noNoiseBands; - - h_sbr_cal_env->prevNSfb[0] = noSubFrameBands[0]; - h_sbr_cal_env->prevNSfb[1] = noSubFrameBands[1]; - - h_sbr_cal_env->prevLoSubband = lowSubband; - h_sbr_cal_env->prevHiSubband = highSubband; - h_sbr_cal_env->prev_ov_highSubband = ov_highSubband; - - FDKmemcpy(h_sbr_cal_env->prevFreqBandTableLo, pFreqBandTable[0], - noSubFrameBands[0] + 1); - FDKmemcpy(h_sbr_cal_env->prevFreqBandTableHi, pFreqBandTable[1], - noSubFrameBands[1] + 1); - FDKmemcpy(h_sbr_cal_env->prevFreqBandTableNoise, - hFreq->freqBandTableNoise, sizeof(hFreq->freqBandTableNoise)); - - FDKmemcpy(h_sbr_cal_env->prevSbrNoiseFloorLevel, noiseLevels, - MAX_NOISE_COEFFS * sizeof(FIXP_SGL)); - } - } - - C_ALLOC_SCRATCH_END(useAliasReduction, UCHAR, 64) -} - -/*! - \brief Create envelope instance - - Must be called once for each channel before calculateSbrEnvelope() can be - used. - - \return errorCode, 0 if successful -*/ -SBR_ERROR -createSbrEnvelopeCalc( - HANDLE_SBR_CALCULATE_ENVELOPE hs, /*!< pointer to envelope instance */ - HANDLE_SBR_HEADER_DATA - hHeaderData, /*!< static SBR control data, initialized with defaults */ - const int chan, /*!< Channel for which to assign buffers */ - const UINT flags) { - SBR_ERROR err = SBRDEC_OK; - int i; - - /* Clear previous missing harmonics flags */ - for (i = 0; i < ADD_HARMONICS_FLAGS_SIZE; i++) { - hs->harmFlagsPrev[i] = 0; - hs->harmFlagsPrevActive[i] = 0; - } - hs->harmIndex = 0; - - FDKmemclear(hs->prevSbrNoiseFloorLevel, sizeof(hs->prevSbrNoiseFloorLevel)); - hs->prevNNfb = 0; - FDKmemclear(hs->prevFreqBandTableNoise, sizeof(hs->prevFreqBandTableNoise)); - hs->sinusoidal_positionPrev = 0; - - /* - Setup pointers for time smoothing. - The buffer itself will be initialized later triggered by the startUp-flag. - */ - hs->prevTranEnv = -1; - - /* initialization */ - resetSbrEnvelopeCalc(hs); - - if (chan == 0) { /* do this only once */ - err = resetFreqBandTables(hHeaderData, flags); - } - - return err; -} - -/*! - \brief Create envelope instance - - Must be called once for each channel before calculateSbrEnvelope() can be - used. - - \return errorCode, 0 if successful -*/ -int deleteSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hs) { return 0; } - -/*! - \brief Reset envelope instance - - This function must be called for each channel on a change of configuration. - Note that resetFreqBandTables should also be called in this case. - - \return errorCode, 0 if successful -*/ -void resetSbrEnvelopeCalc( - HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv) /*!< pointer to envelope instance */ -{ - hCalEnv->phaseIndex = 0; - - /* Noise exponent needs to be reset because the output exponent for the next - * frame depends on it */ - hCalEnv->filtBufferNoise_e = 0; - - hCalEnv->startUp = 1; -} - -/*! - \brief Equalize exponents of the buffered gain values and the new ones - - After equalization of exponents, the FIR-filter addition for smoothing - can be performed. - This function is called once for each envelope before adjusting. -*/ -static void equalizeFiltBufferExp( - FIXP_DBL *filtBuffer, /*!< bufferd gains */ - SCHAR *filtBuffer_e, /*!< exponents of bufferd gains */ - FIXP_DBL *nrgGain, /*!< gains for current envelope */ - SCHAR *nrgGain_e, /*!< exponents of gains for current envelope */ - int subbands) /*!< Number of QMF subbands */ -{ - int band; - int diff; - - for (band = 0; band < subbands; band++) { - diff = (int)(nrgGain_e[band] - filtBuffer_e[band]); - if (diff > 0) { - filtBuffer[band] >>= - diff; /* Compensate for the scale change by shifting the mantissa. */ - filtBuffer_e[band] += diff; /* New gain is bigger, use its exponent */ - } else if (diff < 0) { - /* The buffered gains seem to be larger, but maybe there - are some unused bits left in the mantissa */ - - int reserve = CntLeadingZeros(fixp_abs(filtBuffer[band])) - 1; - - if ((-diff) <= reserve) { - /* There is enough space in the buffered mantissa so - that we can take the new exponent as common. - */ - filtBuffer[band] <<= (-diff); - filtBuffer_e[band] += diff; /* becomes equal to *ptrNewExp */ - } else { - filtBuffer[band] <<= - reserve; /* Shift the mantissa as far as possible: */ - filtBuffer_e[band] -= reserve; /* Compensate in the exponent: */ - - /* For the remaining difference, change the new gain value */ - diff = fixMin(-(reserve + diff), DFRACT_BITS - 1); - nrgGain[band] >>= diff; - nrgGain_e[band] += diff; - } - } - } -} - -/*! - \brief Shift left the mantissas of all subband samples - in the giventime and frequency range by the specified number of bits. - - This function is used to rescale the audio data in the overlap buffer - which has already been envelope adjusted with the last frame. -*/ -void rescaleSubbandSamples( - FIXP_DBL **re, /*!< Real part of input and output subband samples */ - FIXP_DBL **im, /*!< Imaginary part of input and output subband samples */ - int lowSubband, /*!< Begin of frequency range to process */ - int highSubband, /*!< End of frequency range to process */ - int start_pos, /*!< Begin of time rage (QMF-timeslot) */ - int next_pos, /*!< End of time rage (QMF-timeslot) */ - int shift) /*!< number of bits to shift */ -{ - int width = highSubband - lowSubband; - - if ((width > 0) && (shift != 0)) { - if (im != NULL) { - for (int l = start_pos; l < next_pos; l++) { - scaleValues(&re[l][lowSubband], width, shift); - scaleValues(&im[l][lowSubband], width, shift); - } - } else { - for (int l = start_pos; l < next_pos; l++) { - scaleValues(&re[l][lowSubband], width, shift); - } - } - } -} - -static inline FIXP_DBL FDK_get_maxval_real(FIXP_DBL maxVal, FIXP_DBL *reTmp, - INT width) { - maxVal = (FIXP_DBL)0; - while (width-- != 0) { - FIXP_DBL tmp = *(reTmp++); - maxVal |= (FIXP_DBL)((LONG)(tmp) ^ ((LONG)tmp >> (DFRACT_BITS - 1))); - } - - return maxVal; -} - -/*! - \brief Determine headroom for shifting - - Determine by how much the spectrum can be shifted left - for better accuracy in later processing. - - \return Number of free bits in the biggest spectral value -*/ - -FIXP_DBL maxSubbandSample( - FIXP_DBL **re, /*!< Real part of input and output subband samples */ - FIXP_DBL **im, /*!< Real part of input and output subband samples */ - int lowSubband, /*!< Begin of frequency range to process */ - int highSubband, /*!< Number of QMF bands to process */ - int start_pos, /*!< Begin of time rage (QMF-timeslot) */ - int next_pos /*!< End of time rage (QMF-timeslot) */ -) { - FIXP_DBL maxVal = FL2FX_DBL(0.0f); - unsigned int width = highSubband - lowSubband; - - FDK_ASSERT(width <= (64)); - - if (width > 0) { - if (im != NULL) { - for (int l = start_pos; l < next_pos; l++) { - int k = width; - FIXP_DBL *reTmp = &re[l][lowSubband]; - FIXP_DBL *imTmp = &im[l][lowSubband]; - do { - FIXP_DBL tmp1 = *(reTmp++); - FIXP_DBL tmp2 = *(imTmp++); - maxVal |= - (FIXP_DBL)((LONG)(tmp1) ^ ((LONG)tmp1 >> (DFRACT_BITS - 1))); - maxVal |= - (FIXP_DBL)((LONG)(tmp2) ^ ((LONG)tmp2 >> (DFRACT_BITS - 1))); - } while (--k != 0); - } - } else { - for (int l = start_pos; l < next_pos; l++) { - maxVal |= FDK_get_maxval_real(maxVal, &re[l][lowSubband], width); - } - } - } - - if (maxVal > (FIXP_DBL)0) { - /* For negative input values, maxVal is too small by 1. Add 1 only when - * necessary: if maxVal is a power of 2 */ - FIXP_DBL lowerPow2 = - (FIXP_DBL)(1 << (DFRACT_BITS - 1 - CntLeadingZeros(maxVal))); - if (maxVal == lowerPow2) maxVal += (FIXP_DBL)1; - } - - return (maxVal); -} - -/* #define SHIFT_BEFORE_SQUARE (3) */ /* (7/2) */ -/* Avoid assertion failures triggerd by overflows which occured in robustness - tests. Setting the SHIFT_BEFORE_SQUARE to 4 has negligible effect on (USAC) - conformance results. */ -#define SHIFT_BEFORE_SQUARE (4) /* ((8 - 0) / 2) */ - -/*!< - If the accumulator does not provide enough overflow bits or - does not provide a high dynamic range, the below energy calculation - requires an additional shift operation for each sample. - On the other hand, doing the shift allows using a single-precision - multiplication for the square (at least 16bit x 16bit). - For even values of OVRFLW_BITS (0, 2, 4, 6), saturated arithmetic - is required for the energy accumulation. - Theoretically, the sample-squares can sum up to a value of 76, - requiring 7 overflow bits. However since such situations are *very* - rare, accu can be limited to 64. - In case native saturated arithmetic is not available, overflows - can be prevented by replacing the above #define by - #define SHIFT_BEFORE_SQUARE ((8 - OVRFLW_BITS) / 2) - which will result in slightly reduced accuracy. -*/ - -/*! - \brief Estimates the mean energy of each filter-bank channel for the - duration of the current envelope - - This function is used when interpolFreq is true. -*/ -static void calcNrgPerSubband( - FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */ - FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */ - int lowSubband, /*!< Begin of the SBR frequency range */ - int highSubband, /*!< High end of the SBR frequency range */ - int start_pos, /*!< First QMF-slot of current envelope */ - int next_pos, /*!< Last QMF-slot of current envelope + 1 */ - SCHAR frameExp, /*!< Common exponent for all input samples */ - FIXP_DBL *nrgEst, /*!< resulting Energy (0..1) */ - SCHAR *nrgEst_e) /*!< Exponent of resulting Energy */ -{ - FIXP_SGL invWidth; - SCHAR preShift; - SCHAR shift; - FIXP_DBL sum; - int k; - - /* Divide by width of envelope later: */ - invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos)); - /* The common exponent needs to be doubled because all mantissas are squared: - */ - frameExp = frameExp << 1; - - for (k = lowSubband; k < highSubband; k++) { - FIXP_DBL bufferReal[(((1024) / (32) * (4) / 2) + (3 * (4)))]; - FIXP_DBL bufferImag[(((1024) / (32) * (4) / 2) + (3 * (4)))]; - FIXP_DBL maxVal; - - if (analysBufferImag != NULL) { - int l; - maxVal = FL2FX_DBL(0.0f); - for (l = start_pos; l < next_pos; l++) { - bufferImag[l] = analysBufferImag[l][k]; - maxVal |= (FIXP_DBL)((LONG)(bufferImag[l]) ^ - ((LONG)bufferImag[l] >> (DFRACT_BITS - 1))); - bufferReal[l] = analysBufferReal[l][k]; - maxVal |= (FIXP_DBL)((LONG)(bufferReal[l]) ^ - ((LONG)bufferReal[l] >> (DFRACT_BITS - 1))); - } - } else { - int l; - maxVal = FL2FX_DBL(0.0f); - for (l = start_pos; l < next_pos; l++) { - bufferReal[l] = analysBufferReal[l][k]; - maxVal |= (FIXP_DBL)((LONG)(bufferReal[l]) ^ - ((LONG)bufferReal[l] >> (DFRACT_BITS - 1))); - } - } - - if (maxVal != FL2FXCONST_DBL(0.f)) { - /* If the accu does not provide enough overflow bits, we cannot - shift the samples up to the limit. - Instead, keep up to 3 free bits in each sample, i.e. up to - 6 bits after calculation of square. - Please note the comment on saturated arithmetic above! - */ - FIXP_DBL accu; - preShift = CntLeadingZeros(maxVal) - 1; - preShift -= SHIFT_BEFORE_SQUARE; - - /* Limit preShift to a maximum value to prevent accumulator overflow in - exceptional situations where the signal in the analysis-buffer is very - small (small maxVal). - */ - preShift = fMin(preShift, (SCHAR)25); - - accu = FL2FXCONST_DBL(0.0f); - if (preShift >= 0) { - int l; - if (analysBufferImag != NULL) { - for (l = start_pos; l < next_pos; l++) { - FIXP_DBL temp1 = bufferReal[l] << (int)preShift; - FIXP_DBL temp2 = bufferImag[l] << (int)preShift; - accu = fPow2AddDiv2(accu, temp1); - accu = fPow2AddDiv2(accu, temp2); - } - } else { - for (l = start_pos; l < next_pos; l++) { - FIXP_DBL temp = bufferReal[l] << (int)preShift; - accu = fPow2AddDiv2(accu, temp); - } - } - } else { /* if negative shift value */ - int l; - int negpreShift = -preShift; - if (analysBufferImag != NULL) { - for (l = start_pos; l < next_pos; l++) { - FIXP_DBL temp1 = bufferReal[l] >> (int)negpreShift; - FIXP_DBL temp2 = bufferImag[l] >> (int)negpreShift; - accu = fPow2AddDiv2(accu, temp1); - accu = fPow2AddDiv2(accu, temp2); - } - } else { - for (l = start_pos; l < next_pos; l++) { - FIXP_DBL temp = bufferReal[l] >> (int)negpreShift; - accu = fPow2AddDiv2(accu, temp); - } - } - } - accu <<= 1; - - /* Convert double precision to Mantissa/Exponent: */ - shift = fNorm(accu); - sum = accu << (int)shift; - - /* Divide by width of envelope and apply frame scale: */ - *nrgEst++ = fMult(sum, invWidth); - shift += 2 * preShift; - if (analysBufferImag != NULL) - *nrgEst_e++ = frameExp - shift; - else - *nrgEst_e++ = frameExp - shift + 1; /* +1 due to missing imag. part */ - } /* maxVal!=0 */ - else { - /* Prevent a zero-mantissa-number from being misinterpreted - due to its exponent. */ - *nrgEst++ = FL2FXCONST_DBL(0.0f); - *nrgEst_e++ = 0; - } - } -} - -/*! - \brief Estimates the mean energy of each Scale factor band for the - duration of the current envelope. - - This function is used when interpolFreq is false. -*/ -static void calcNrgPerSfb( - FIXP_DBL **analysBufferReal, /*!< Real part of subband samples */ - FIXP_DBL **analysBufferImag, /*!< Imaginary part of subband samples */ - int nSfb, /*!< Number of scale factor bands */ - UCHAR *freqBandTable, /*!< First Subband for each Sfb */ - int start_pos, /*!< First QMF-slot of current envelope */ - int next_pos, /*!< Last QMF-slot of current envelope + 1 */ - SCHAR input_e, /*!< Common exponent for all input samples */ - FIXP_DBL *nrgEst, /*!< resulting Energy (0..1) */ - SCHAR *nrgEst_e) /*!< Exponent of resulting Energy */ -{ - FIXP_SGL invWidth; - FIXP_DBL temp; - SCHAR preShift; - SCHAR shift, sum_e; - FIXP_DBL sum; - - int j, k, l, li, ui; - FIXP_DBL sumAll, sumLine; /* Single precision would be sufficient, - but overflow bits are required for accumulation */ - - /* Divide by width of envelope later: */ - invWidth = FX_DBL2FX_SGL(GetInvInt(next_pos - start_pos)); - /* The common exponent needs to be doubled because all mantissas are squared: - */ - input_e = input_e << 1; - - for (j = 0; j < nSfb; j++) { - li = freqBandTable[j]; - ui = freqBandTable[j + 1]; - - FIXP_DBL maxVal = maxSubbandSample(analysBufferReal, analysBufferImag, li, - ui, start_pos, next_pos); - - if (maxVal != FL2FXCONST_DBL(0.f)) { - preShift = CntLeadingZeros(maxVal) - 1; - - /* If the accu does not provide enough overflow bits, we cannot - shift the samples up to the limit. - Instead, keep up to 3 free bits in each sample, i.e. up to - 6 bits after calculation of square. - Please note the comment on saturated arithmetic above! - */ - preShift -= SHIFT_BEFORE_SQUARE; - - sumAll = FL2FXCONST_DBL(0.0f); - - for (k = li; k < ui; k++) { - sumLine = FL2FXCONST_DBL(0.0f); - - if (analysBufferImag != NULL) { - if (preShift >= 0) { - for (l = start_pos; l < next_pos; l++) { - temp = analysBufferReal[l][k] << (int)preShift; - sumLine += fPow2Div2(temp); - temp = analysBufferImag[l][k] << (int)preShift; - sumLine += fPow2Div2(temp); - } - } else { - for (l = start_pos; l < next_pos; l++) { - temp = analysBufferReal[l][k] >> -(int)preShift; - sumLine += fPow2Div2(temp); - temp = analysBufferImag[l][k] >> -(int)preShift; - sumLine += fPow2Div2(temp); - } - } - } else { - if (preShift >= 0) { - for (l = start_pos; l < next_pos; l++) { - temp = analysBufferReal[l][k] << (int)preShift; - sumLine += fPow2Div2(temp); - } - } else { - for (l = start_pos; l < next_pos; l++) { - temp = analysBufferReal[l][k] >> -(int)preShift; - sumLine += fPow2Div2(temp); - } - } - } - - /* The number of QMF-channels per SBR bands may be up to 15. - Shift right to avoid overflows in sum over all channels. */ - sumLine = sumLine >> (4 - 1); - sumAll += sumLine; - } - - /* Convert double precision to Mantissa/Exponent: */ - shift = fNorm(sumAll); - sum = sumAll << (int)shift; - - /* Divide by width of envelope: */ - sum = fMult(sum, invWidth); - - /* Divide by width of Sfb: */ - sum = fMult(sum, FX_DBL2FX_SGL(GetInvInt(ui - li))); - - /* Set all Subband energies in the Sfb to the average energy: */ - if (analysBufferImag != NULL) - sum_e = input_e + 4 - shift; /* -4 to compensate right-shift */ - else - sum_e = input_e + 4 + 1 - - shift; /* -4 to compensate right-shift; +1 due to missing - imag. part */ - - sum_e -= 2 * preShift; - } /* maxVal!=0 */ - else { - /* Prevent a zero-mantissa-number from being misinterpreted - due to its exponent. */ - sum = FL2FXCONST_DBL(0.0f); - sum_e = 0; - } - - for (k = li; k < ui; k++) { - *nrgEst++ = sum; - *nrgEst_e++ = sum_e; - } - } -} - -/*! - \brief Calculate gain, noise, and additional sine level for one subband. - - The resulting energy gain is given by mantissa and exponent. -*/ -static void calcSubbandGain( - FIXP_DBL nrgRef, /*!< Reference Energy according to envelope data */ - SCHAR - nrgRef_e, /*!< Reference Energy according to envelope data (exponent) */ - ENV_CALC_NRGS *nrgs, int i, FIXP_DBL tmpNoise, /*!< Relative noise level */ - SCHAR tmpNoise_e, /*!< Relative noise level (exponent) */ - UCHAR sinePresentFlag, /*!< Indicates if sine is present on band */ - UCHAR sineMapped, /*!< Indicates if sine must be added */ - int noNoiseFlag) /*!< Flag to suppress noise addition */ -{ - FIXP_DBL nrgEst = nrgs->nrgEst[i]; /*!< Energy in transposed signal */ - SCHAR nrgEst_e = - nrgs->nrgEst_e[i]; /*!< Energy in transposed signal (exponent) */ - FIXP_DBL *ptrNrgGain = &nrgs->nrgGain[i]; /*!< Resulting energy gain */ - SCHAR *ptrNrgGain_e = - &nrgs->nrgGain_e[i]; /*!< Resulting energy gain (exponent) */ - FIXP_DBL *ptrNoiseLevel = - &nrgs->noiseLevel[i]; /*!< Resulting absolute noise energy */ - SCHAR *ptrNoiseLevel_e = - &nrgs->noiseLevel_e[i]; /*!< Resulting absolute noise energy (exponent) */ - FIXP_DBL *ptrNrgSine = &nrgs->nrgSine[i]; /*!< Additional sine energy */ - SCHAR *ptrNrgSine_e = - &nrgs->nrgSine_e[i]; /*!< Additional sine energy (exponent) */ - - FIXP_DBL a, b, c; - SCHAR a_e, b_e, c_e; - - /* - This addition of 1 prevents divisions by zero in the reference code. - For very small energies in nrgEst, it prevents the gains from becoming - very high which could cause some trouble due to the smoothing. - */ - b_e = (int)(nrgEst_e - 1); - if (b_e >= 0) { - nrgEst = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e + 1, DFRACT_BITS - 1)) + - (nrgEst >> 1); - nrgEst_e += 1; /* shift by 1 bit to avoid overflow */ - - } else { - nrgEst = (nrgEst >> (INT)(fixMin(-b_e + 1, DFRACT_BITS - 1))) + - (FL2FXCONST_DBL(0.5f) >> 1); - nrgEst_e = 2; /* shift by 1 bit to avoid overflow */ - } - - /* A = NrgRef * TmpNoise */ - a = fMult(nrgRef, tmpNoise); - a_e = nrgRef_e + tmpNoise_e; - - /* B = 1 + TmpNoise */ - b_e = (int)(tmpNoise_e - 1); - if (b_e >= 0) { - b = (FL2FXCONST_DBL(0.5f) >> (INT)fixMin(b_e + 1, DFRACT_BITS - 1)) + - (tmpNoise >> 1); - b_e = tmpNoise_e + 1; /* shift by 1 bit to avoid overflow */ - } else { - b = (tmpNoise >> (INT)(fixMin(-b_e + 1, DFRACT_BITS - 1))) + - (FL2FXCONST_DBL(0.5f) >> 1); - b_e = 2; /* shift by 1 bit to avoid overflow */ - } - - /* noiseLevel = A / B = (NrgRef * TmpNoise) / (1 + TmpNoise) */ - FDK_divide_MantExp(a, a_e, b, b_e, ptrNoiseLevel, ptrNoiseLevel_e); - - if (sinePresentFlag) { - /* C = (1 + TmpNoise) * NrgEst */ - c = fMult(b, nrgEst); - c_e = b_e + nrgEst_e; - - /* gain = A / C = (NrgRef * TmpNoise) / (1 + TmpNoise) * NrgEst */ - FDK_divide_MantExp(a, a_e, c, c_e, ptrNrgGain, ptrNrgGain_e); - - if (sineMapped) { - /* sineLevel = nrgRef/ (1 + TmpNoise) */ - FDK_divide_MantExp(nrgRef, nrgRef_e, b, b_e, ptrNrgSine, ptrNrgSine_e); - } - } else { - if (noNoiseFlag) { - /* B = NrgEst */ - b = nrgEst; - b_e = nrgEst_e; - } else { - /* B = NrgEst * (1 + TmpNoise) */ - b = fMult(b, nrgEst); - b_e = b_e + nrgEst_e; - } - - /* gain = nrgRef / B */ - FDK_divide_MantExp(nrgRef, nrgRef_e, b, b_e, ptrNrgGain, ptrNrgGain_e); - } -} - -/*! - \brief Calculate "average gain" for the specified subband range. - - This is rather a gain of the average magnitude than the average - of gains! - The result is used as a relative limit for all gains within the - current "limiter band" (a certain frequency range). -*/ -static void calcAvgGain( - ENV_CALC_NRGS *nrgs, int lowSubband, /*!< Begin of the limiter band */ - int highSubband, /*!< High end of the limiter band */ - FIXP_DBL *ptrSumRef, SCHAR *ptrSumRef_e, - FIXP_DBL *ptrAvgGain, /*!< Resulting overall gain (mantissa) */ - SCHAR *ptrAvgGain_e) /*!< Resulting overall gain (exponent) */ -{ - FIXP_DBL *nrgRef = - nrgs->nrgRef; /*!< Reference Energy according to envelope data */ - SCHAR *nrgRef_e = - nrgs->nrgRef_e; /*!< Reference Energy according to envelope data - (exponent) */ - FIXP_DBL *nrgEst = nrgs->nrgEst; /*!< Energy in transposed signal */ - SCHAR *nrgEst_e = - nrgs->nrgEst_e; /*!< Energy in transposed signal (exponent) */ - - FIXP_DBL sumRef = 1; - FIXP_DBL sumEst = 1; - SCHAR sumRef_e = -FRACT_BITS; - SCHAR sumEst_e = -FRACT_BITS; - int k; - - for (k = lowSubband; k < highSubband; k++) { - /* Add nrgRef[k] to sumRef: */ - FDK_add_MantExp(sumRef, sumRef_e, nrgRef[k], nrgRef_e[k], &sumRef, - &sumRef_e); - - /* Add nrgEst[k] to sumEst: */ - FDK_add_MantExp(sumEst, sumEst_e, nrgEst[k], nrgEst_e[k], &sumEst, - &sumEst_e); - } - - FDK_divide_MantExp(sumRef, sumRef_e, sumEst, sumEst_e, ptrAvgGain, - ptrAvgGain_e); - - *ptrSumRef = sumRef; - *ptrSumRef_e = sumRef_e; -} - -static void adjustTimeSlot_EldGrid( - FIXP_DBL *RESTRICT - ptrReal, /*!< Subband samples to be adjusted, real part */ - ENV_CALC_NRGS *nrgs, UCHAR *ptrHarmIndex, /*!< Harmonic index */ - int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */ - int noSubbands, /*!< Number of QMF subbands */ - int scale_change, /*!< Number of bits to shift adjusted samples */ - int noNoiseFlag, /*!< Flag to suppress noise addition */ - int *ptrPhaseIndex, /*!< Start index to random number array */ - int scale_diff_low) /*!< */ - -{ - int k; - FIXP_DBL signalReal, sbNoise; - int tone_count = 0; - - FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */ - FIXP_DBL *RESTRICT pNoiseLevel = - nrgs->noiseLevel; /*!< Noise levels of current envelope */ - FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */ - - int phaseIndex = *ptrPhaseIndex; - UCHAR harmIndex = *ptrHarmIndex; - - static const INT harmonicPhase[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; - - static const FIXP_DBL harmonicPhaseX[4][2] = { - {FL2FXCONST_DBL(2.0 * 1.245183154539139e-001), - FL2FXCONST_DBL(2.0 * 1.245183154539139e-001)}, - {FL2FXCONST_DBL(2.0 * -1.123767859325028e-001), - FL2FXCONST_DBL(2.0 * 1.123767859325028e-001)}, - {FL2FXCONST_DBL(2.0 * -1.245183154539139e-001), - FL2FXCONST_DBL(2.0 * -1.245183154539139e-001)}, - {FL2FXCONST_DBL(2.0 * 1.123767859325028e-001), - FL2FXCONST_DBL(2.0 * -1.123767859325028e-001)}}; - - const FIXP_DBL *p_harmonicPhaseX = &harmonicPhaseX[harmIndex][0]; - const INT *p_harmonicPhase = &harmonicPhase[harmIndex][0]; - - *(ptrReal - 1) = fAddSaturate( - *(ptrReal - 1), - SATURATE_SHIFT(fMultDiv2(p_harmonicPhaseX[lowSubband & 1], pSineLevel[0]), - scale_diff_low, DFRACT_BITS)); - FIXP_DBL pSineLevel_prev = (FIXP_DBL)0; - - int idx_k = lowSubband & 1; - - for (k = 0; k < noSubbands; k++) { - FIXP_DBL sineLevel_curr = *pSineLevel++; - phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1); - - signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change); - sbNoise = *pNoiseLevel++; - if (((INT)sineLevel_curr | noNoiseFlag) == 0) { - signalReal += - (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise) - << 4); - } - signalReal += sineLevel_curr * p_harmonicPhase[0]; - signalReal = - fMultAddDiv2(signalReal, pSineLevel_prev, p_harmonicPhaseX[idx_k]); - pSineLevel_prev = sineLevel_curr; - idx_k = !idx_k; - if (k < noSubbands - 1) { - signalReal = - fMultAddDiv2(signalReal, pSineLevel[0], p_harmonicPhaseX[idx_k]); - } else /* (k == noSubbands - 1) */ - { - if (k + lowSubband + 1 < 63) { - *(ptrReal + 1) += fMultDiv2(pSineLevel_prev, p_harmonicPhaseX[idx_k]); - } - } - *ptrReal++ = signalReal; - - if (pSineLevel_prev != FL2FXCONST_DBL(0.0f)) { - if (++tone_count == 16) { - k++; - break; - } - } - } - /* Run again, if previous loop got breaked with tone_count = 16 */ - for (; k < noSubbands; k++) { - FIXP_DBL sineLevel_curr = *pSineLevel++; - phaseIndex = (phaseIndex + 1) & (SBR_NF_NO_RANDOM_VAL - 1); - - signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change); - sbNoise = *pNoiseLevel++; - if (((INT)sineLevel_curr | noNoiseFlag) == 0) { - signalReal += - (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[phaseIndex][0], sbNoise) - << 4); - } - signalReal += sineLevel_curr * p_harmonicPhase[0]; - *ptrReal++ = signalReal; - } - - *ptrHarmIndex = (harmIndex + 1) & 3; - *ptrPhaseIndex = phaseIndex & (SBR_NF_NO_RANDOM_VAL - 1); -} - -/*! - \brief Amplify one timeslot of the signal with the calculated gains - and add the noisefloor. -*/ - -static void adjustTimeSlotLC( - FIXP_DBL *ptrReal, /*!< Subband samples to be adjusted, real part */ - ENV_CALC_NRGS *nrgs, UCHAR *ptrHarmIndex, /*!< Harmonic index */ - int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */ - int noSubbands, /*!< Number of QMF subbands */ - int scale_change, /*!< Number of bits to shift adjusted samples */ - int noNoiseFlag, /*!< Flag to suppress noise addition */ - int *ptrPhaseIndex) /*!< Start index to random number array */ -{ - FIXP_DBL *pGain = nrgs->nrgGain; /*!< Gains of current envelope */ - FIXP_DBL *pNoiseLevel = - nrgs->noiseLevel; /*!< Noise levels of current envelope */ - FIXP_DBL *pSineLevel = nrgs->nrgSine; /*!< Sine levels */ - - int k; - int index = *ptrPhaseIndex; - UCHAR harmIndex = *ptrHarmIndex; - UCHAR freqInvFlag = (lowSubband & 1); - FIXP_DBL signalReal, sineLevel, sineLevelNext, sineLevelPrev; - int tone_count = 0; - int sineSign = 1; - -#define C1 ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.00815f)) -#define C1_CLDFB ((FIXP_SGL)FL2FXCONST_SGL(2.f * 0.16773f)) - - /* - First pass for k=0 pulled out of the loop: - */ - - index = (index + 1) & (SBR_NF_NO_RANDOM_VAL - 1); - - /* - The next multiplication constitutes the actual envelope adjustment - of the signal and should be carried out with full accuracy - (supplying #FRACT_BITS valid bits). - */ - signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change); - sineLevel = *pSineLevel++; - sineLevelNext = (noSubbands > 1) ? pSineLevel[0] : FL2FXCONST_DBL(0.0f); - - if (sineLevel != FL2FXCONST_DBL(0.0f)) - tone_count++; - else if (!noNoiseFlag) - /* Add noisefloor to the amplified signal */ - signalReal += - (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0]) - << 4); - - { - if (!(harmIndex & 0x1)) { - /* harmIndex 0,2 */ - signalReal += (harmIndex & 0x2) ? -sineLevel : sineLevel; - *ptrReal++ = signalReal; - } else { - /* harmIndex 1,3 in combination with freqInvFlag */ - int shift = (int)(scale_change + 1); - shift = (shift >= 0) ? fixMin(DFRACT_BITS - 1, shift) - : fixMax(-(DFRACT_BITS - 1), shift); - - FIXP_DBL tmp1 = (shift >= 0) ? (fMultDiv2(C1, sineLevel) >> shift) - : (fMultDiv2(C1, sineLevel) << (-shift)); - FIXP_DBL tmp2 = fMultDiv2(C1, sineLevelNext); - - /* save switch and compare operations and reduce to XOR statement */ - if (((harmIndex >> 1) & 0x1) ^ freqInvFlag) { - *(ptrReal - 1) += tmp1; - signalReal -= tmp2; - } else { - *(ptrReal - 1) -= tmp1; - signalReal += tmp2; - } - *ptrReal++ = signalReal; - freqInvFlag = !freqInvFlag; - } - } - - pNoiseLevel++; - - if (noSubbands > 2) { - if (!(harmIndex & 0x1)) { - /* harmIndex 0,2 */ - if (!harmIndex) { - sineSign = 0; - } - - for (k = noSubbands - 2; k != 0; k--) { - FIXP_DBL sinelevel = *pSineLevel++; - index++; - if (((signalReal = (sineSign ? -sinelevel : sinelevel)) == - FL2FXCONST_DBL(0.0f)) && - !noNoiseFlag) { - /* Add noisefloor to the amplified signal */ - index &= (SBR_NF_NO_RANDOM_VAL - 1); - signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], - pNoiseLevel[0]) - << 4); - } - - /* The next multiplication constitutes the actual envelope adjustment of - * the signal. */ - signalReal += fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change); - - pNoiseLevel++; - *ptrReal++ = signalReal; - } /* for ... */ - } else { - /* harmIndex 1,3 in combination with freqInvFlag */ - if (harmIndex == 1) freqInvFlag = !freqInvFlag; - - for (k = noSubbands - 2; k != 0; k--) { - index++; - /* The next multiplication constitutes the actual envelope adjustment of - * the signal. */ - signalReal = fMultDiv2(*ptrReal, *pGain++) << ((int)scale_change); - - if (*pSineLevel++ != FL2FXCONST_DBL(0.0f)) - tone_count++; - else if (!noNoiseFlag) { - /* Add noisefloor to the amplified signal */ - index &= (SBR_NF_NO_RANDOM_VAL - 1); - signalReal += (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], - pNoiseLevel[0]) - << 4); - } - - pNoiseLevel++; - - if (tone_count <= 16) { - FIXP_DBL addSine = fMultDiv2((pSineLevel[-2] - pSineLevel[0]), C1); - signalReal += (freqInvFlag) ? (-addSine) : (addSine); - } - - *ptrReal++ = signalReal; - freqInvFlag = !freqInvFlag; - } /* for ... */ - } - } - - if (noSubbands > -1) { - index++; - /* The next multiplication constitutes the actual envelope adjustment of the - * signal. */ - signalReal = fMultDiv2(*ptrReal, *pGain) << ((int)scale_change); - sineLevelPrev = fMultDiv2(pSineLevel[-1], FL2FX_SGL(0.0163f)); - sineLevel = pSineLevel[0]; - - if (pSineLevel[0] != FL2FXCONST_DBL(0.0f)) - tone_count++; - else if (!noNoiseFlag) { - /* Add noisefloor to the amplified signal */ - index &= (SBR_NF_NO_RANDOM_VAL - 1); - signalReal = - signalReal + - (fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], pNoiseLevel[0]) - << 4); - } - - if (!(harmIndex & 0x1)) { - /* harmIndex 0,2 */ - *ptrReal = signalReal + ((sineSign) ? -sineLevel : sineLevel); - } else { - /* harmIndex 1,3 in combination with freqInvFlag */ - if (tone_count <= 16) { - if (freqInvFlag) { - *ptrReal++ = signalReal - sineLevelPrev; - if (noSubbands + lowSubband < 63) - *ptrReal = *ptrReal + fMultDiv2(C1, sineLevel); - } else { - *ptrReal++ = signalReal + sineLevelPrev; - if (noSubbands + lowSubband < 63) - *ptrReal = *ptrReal - fMultDiv2(C1, sineLevel); - } - } else - *ptrReal = signalReal; - } - } - *ptrHarmIndex = (harmIndex + 1) & 3; - *ptrPhaseIndex = index & (SBR_NF_NO_RANDOM_VAL - 1); -} - -static void adjustTimeSlotHQ_GainAndNoise( - FIXP_DBL *RESTRICT - ptrReal, /*!< Subband samples to be adjusted, real part */ - FIXP_DBL *RESTRICT - ptrImag, /*!< Subband samples to be adjusted, imag part */ - HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs, - int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */ - int noSubbands, /*!< Number of QMF subbands */ - int scale_change, /*!< Number of bits to shift adjusted samples */ - FIXP_SGL smooth_ratio, /*!< Impact of last envelope */ - int noNoiseFlag, /*!< Start index to random number array */ - int filtBufferNoiseShift) /*!< Shift factor of filtBufferNoise */ -{ - FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */ - FIXP_DBL *RESTRICT noiseLevel = - nrgs->noiseLevel; /*!< Noise levels of current envelope */ - FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */ - - FIXP_DBL *RESTRICT filtBuffer = - h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */ - FIXP_DBL *RESTRICT filtBufferNoise = - h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */ - int *RESTRICT ptrPhaseIndex = - &h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */ - - int k; - FIXP_DBL signalReal, signalImag; - FIXP_DBL noiseReal, noiseImag; - FIXP_DBL smoothedGain, smoothedNoise; - FIXP_SGL direct_ratio = - /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio; - int index = *ptrPhaseIndex; - int shift; - - *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1); - - filtBufferNoiseShift += - 1; /* due to later use of fMultDiv2 instead of fMult */ - if (filtBufferNoiseShift < 0) { - shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift); - } else { - shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift); - } - - if (smooth_ratio > FL2FXCONST_SGL(0.0f)) { - for (k = 0; k < noSubbands; k++) { - /* - Smoothing: The old envelope has been bufferd and a certain ratio - of the old gains and noise levels is used. - */ - smoothedGain = - fMult(smooth_ratio, filtBuffer[k]) + fMult(direct_ratio, gain[k]); - - if (filtBufferNoiseShift < 0) { - smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) + - fMult(direct_ratio, noiseLevel[k]); - } else { - smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) << shift) + - fMult(direct_ratio, noiseLevel[k]); - } - - /* - The next 2 multiplications constitute the actual envelope adjustment - of the signal and should be carried out with full accuracy - (supplying #DFRACT_BITS valid bits). - */ - signalReal = fMultDiv2(*ptrReal, smoothedGain) << ((int)scale_change); - signalImag = fMultDiv2(*ptrImag, smoothedGain) << ((int)scale_change); - - index++; - - if ((pSineLevel[k] != FL2FXCONST_DBL(0.0f)) || noNoiseFlag) { - /* Just the amplified signal is saved */ - *ptrReal++ = signalReal; - *ptrImag++ = signalImag; - } else { - /* Add noisefloor to the amplified signal */ - index &= (SBR_NF_NO_RANDOM_VAL - 1); - noiseReal = - fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise) - << 4; - noiseImag = - fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise) - << 4; - *ptrReal++ = (signalReal + noiseReal); - *ptrImag++ = (signalImag + noiseImag); - } - } - } else { - for (k = 0; k < noSubbands; k++) { - smoothedGain = gain[k]; - signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change; - signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change; - - index++; - - if ((pSineLevel[k] == FL2FXCONST_DBL(0.0f)) && (noNoiseFlag == 0)) { - /* Add noisefloor to the amplified signal */ - smoothedNoise = noiseLevel[k]; - index &= (SBR_NF_NO_RANDOM_VAL - 1); - noiseReal = - fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise); - noiseImag = - fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise); - - /* FDK_sbrDecoder_sbr_randomPhase is downscaled by 2^3 */ - signalReal += noiseReal << 4; - signalImag += noiseImag << 4; - } - *ptrReal++ = signalReal; - *ptrImag++ = signalImag; - } - } -} - -static void adjustTimeSlotHQ_AddHarmonics( - FIXP_DBL *RESTRICT - ptrReal, /*!< Subband samples to be adjusted, real part */ - FIXP_DBL *RESTRICT - ptrImag, /*!< Subband samples to be adjusted, imag part */ - HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs, - int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */ - int noSubbands, /*!< Number of QMF subbands */ - int scale_change /*!< Scale mismatch between QMF input and sineLevel - exponent. */ -) { - FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */ - UCHAR *RESTRICT ptrHarmIndex = - &h_sbr_cal_env->harmIndex; /*!< Harmonic index */ - - int k; - FIXP_DBL signalReal, signalImag; - UCHAR harmIndex = *ptrHarmIndex; - int freqInvFlag = (lowSubband & 1); - FIXP_DBL sineLevel; - - *ptrHarmIndex = (harmIndex + 1) & 3; - - for (k = 0; k < noSubbands; k++) { - sineLevel = pSineLevel[k]; - freqInvFlag ^= 1; - if (sineLevel != FL2FXCONST_DBL(0.f)) { - signalReal = ptrReal[k]; - signalImag = ptrImag[k]; - sineLevel = scaleValue(sineLevel, scale_change); - if (harmIndex & 2) { - /* case 2,3 */ - sineLevel = -sineLevel; - } - if (!(harmIndex & 1)) { - /* case 0,2: */ - ptrReal[k] = signalReal + sineLevel; - } else { - /* case 1,3 */ - if (!freqInvFlag) sineLevel = -sineLevel; - ptrImag[k] = signalImag + sineLevel; - } - } - } -} - -static void adjustTimeSlotHQ( - FIXP_DBL *RESTRICT - ptrReal, /*!< Subband samples to be adjusted, real part */ - FIXP_DBL *RESTRICT - ptrImag, /*!< Subband samples to be adjusted, imag part */ - HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, ENV_CALC_NRGS *nrgs, - int lowSubband, /*!< Lowest QMF-channel in the currently used SBR range. */ - int noSubbands, /*!< Number of QMF subbands */ - int scale_change, /*!< Number of bits to shift adjusted samples */ - FIXP_SGL smooth_ratio, /*!< Impact of last envelope */ - int noNoiseFlag, /*!< Start index to random number array */ - int filtBufferNoiseShift) /*!< Shift factor of filtBufferNoise */ -{ - FIXP_DBL *RESTRICT gain = nrgs->nrgGain; /*!< Gains of current envelope */ - FIXP_DBL *RESTRICT noiseLevel = - nrgs->noiseLevel; /*!< Noise levels of current envelope */ - FIXP_DBL *RESTRICT pSineLevel = nrgs->nrgSine; /*!< Sine levels */ - - FIXP_DBL *RESTRICT filtBuffer = - h_sbr_cal_env->filtBuffer; /*!< Gains of last envelope */ - FIXP_DBL *RESTRICT filtBufferNoise = - h_sbr_cal_env->filtBufferNoise; /*!< Noise levels of last envelope */ - UCHAR *RESTRICT ptrHarmIndex = - &h_sbr_cal_env->harmIndex; /*!< Harmonic index */ - int *RESTRICT ptrPhaseIndex = - &h_sbr_cal_env->phaseIndex; /*!< Start index to random number array */ - - int k; - FIXP_DBL signalReal, signalImag; - FIXP_DBL noiseReal, noiseImag; - FIXP_DBL smoothedGain, smoothedNoise; - FIXP_SGL direct_ratio = - /*FL2FXCONST_SGL(1.0f) */ (FIXP_SGL)MAXVAL_SGL - smooth_ratio; - int index = *ptrPhaseIndex; - UCHAR harmIndex = *ptrHarmIndex; - int freqInvFlag = (lowSubband & 1); - FIXP_DBL sineLevel; - int shift; - - *ptrPhaseIndex = (index + noSubbands) & (SBR_NF_NO_RANDOM_VAL - 1); - *ptrHarmIndex = (harmIndex + 1) & 3; - - /* - Possible optimization: - smooth_ratio and harmIndex stay constant during the loop. - It might be faster to include a separate loop in each path. - - the check for smooth_ratio is now outside the loop and the workload - of the whole function decreased by about 20 % - */ - - filtBufferNoiseShift += - 1; /* due to later use of fMultDiv2 instead of fMult */ - if (filtBufferNoiseShift < 0) - shift = fixMin(DFRACT_BITS - 1, -filtBufferNoiseShift); - else - shift = fixMin(DFRACT_BITS - 1, filtBufferNoiseShift); - - if (smooth_ratio > FL2FXCONST_SGL(0.0f)) { - for (k = 0; k < noSubbands; k++) { - /* - Smoothing: The old envelope has been bufferd and a certain ratio - of the old gains and noise levels is used. - */ - - smoothedGain = - fMult(smooth_ratio, filtBuffer[k]) + fMult(direct_ratio, gain[k]); - - if (filtBufferNoiseShift < 0) { - smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) >> shift) + - fMult(direct_ratio, noiseLevel[k]); - } else { - smoothedNoise = (fMultDiv2(smooth_ratio, filtBufferNoise[k]) << shift) + - fMult(direct_ratio, noiseLevel[k]); - } - - /* - The next 2 multiplications constitute the actual envelope adjustment - of the signal and should be carried out with full accuracy - (supplying #DFRACT_BITS valid bits). - */ - signalReal = fMultDiv2(*ptrReal, smoothedGain) << ((int)scale_change); - signalImag = fMultDiv2(*ptrImag, smoothedGain) << ((int)scale_change); - - index++; - - if (pSineLevel[k] != FL2FXCONST_DBL(0.0f)) { - sineLevel = pSineLevel[k]; - - switch (harmIndex) { - case 0: - *ptrReal++ = (signalReal + sineLevel); - *ptrImag++ = (signalImag); - break; - case 2: - *ptrReal++ = (signalReal - sineLevel); - *ptrImag++ = (signalImag); - break; - case 1: - *ptrReal++ = (signalReal); - if (freqInvFlag) - *ptrImag++ = (signalImag - sineLevel); - else - *ptrImag++ = (signalImag + sineLevel); - break; - case 3: - *ptrReal++ = signalReal; - if (freqInvFlag) - *ptrImag++ = (signalImag + sineLevel); - else - *ptrImag++ = (signalImag - sineLevel); - break; - } - } else { - if (noNoiseFlag) { - /* Just the amplified signal is saved */ - *ptrReal++ = (signalReal); - *ptrImag++ = (signalImag); - } else { - /* Add noisefloor to the amplified signal */ - index &= (SBR_NF_NO_RANDOM_VAL - 1); - /* FDK_sbrDecoder_sbr_randomPhase is downscaled by 2^3 */ - noiseReal = - fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], smoothedNoise) - << 4; - noiseImag = - fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], smoothedNoise) - << 4; - *ptrReal++ = (signalReal + noiseReal); - *ptrImag++ = (signalImag + noiseImag); - } - } - freqInvFlag ^= 1; - } - - } else { - for (k = 0; k < noSubbands; k++) { - smoothedGain = gain[k]; - signalReal = fMultDiv2(*ptrReal, smoothedGain) << scale_change; - signalImag = fMultDiv2(*ptrImag, smoothedGain) << scale_change; - - index++; - - if ((sineLevel = pSineLevel[k]) != FL2FXCONST_DBL(0.0f)) { - switch (harmIndex) { - case 0: - signalReal += sineLevel; - break; - case 1: - if (freqInvFlag) - signalImag -= sineLevel; - else - signalImag += sineLevel; - break; - case 2: - signalReal -= sineLevel; - break; - case 3: - if (freqInvFlag) - signalImag += sineLevel; - else - signalImag -= sineLevel; - break; - } - } else { - if (noNoiseFlag == 0) { - /* Add noisefloor to the amplified signal */ - smoothedNoise = noiseLevel[k]; - index &= (SBR_NF_NO_RANDOM_VAL - 1); - noiseReal = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][0], - smoothedNoise); - noiseImag = fMultDiv2(FDK_sbrDecoder_sbr_randomPhase[index][1], - smoothedNoise); - - /* FDK_sbrDecoder_sbr_randomPhase is downscaled by 2^3 */ - signalReal += noiseReal << 4; - signalImag += noiseImag << 4; - } - } - *ptrReal++ = signalReal; - *ptrImag++ = signalImag; - - freqInvFlag ^= 1; - } - } -} - -/*! - \brief Reset limiter bands. - - Build frequency band table for the gain limiter dependent on - the previously generated transposer patch areas. - - \return SBRDEC_OK if ok, SBRDEC_UNSUPPORTED_CONFIG on error -*/ -SBR_ERROR -ResetLimiterBands( - UCHAR *limiterBandTable, /*!< Resulting band borders in QMF channels */ - UCHAR *noLimiterBands, /*!< Resulting number of limiter band */ - UCHAR *freqBandTable, /*!< Table with possible band borders */ - int noFreqBands, /*!< Number of bands in freqBandTable */ - const PATCH_PARAM *patchParam, /*!< Transposer patch parameters */ - int noPatches, /*!< Number of transposer patches */ - int limiterBands, /*!< Selected 'band density' from bitstream */ - UCHAR sbrPatchingMode, int xOverQmf[MAX_NUM_PATCHES], int b41Sbr) { - int i, k, isPatchBorder[2], loLimIndex, hiLimIndex, tempNoLim, nBands; - UCHAR workLimiterBandTable[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1]; - int patchBorders[MAX_NUM_PATCHES + 1]; - int kx, k2; - - int lowSubband = freqBandTable[0]; - int highSubband = freqBandTable[noFreqBands]; - - /* 1 limiter band. */ - if (limiterBands == 0) { - limiterBandTable[0] = 0; - limiterBandTable[1] = highSubband - lowSubband; - nBands = 1; - } else { - if (!sbrPatchingMode && xOverQmf != NULL) { - noPatches = 0; - - if (b41Sbr == 1) { - for (i = 1; i < MAX_NUM_PATCHES_HBE; i++) - if (xOverQmf[i] != 0) noPatches++; - } else { - for (i = 1; i < MAX_STRETCH_HBE; i++) - if (xOverQmf[i] != 0) noPatches++; - } - for (i = 0; i < noPatches; i++) { - patchBorders[i] = xOverQmf[i] - lowSubband; - } - } else { - for (i = 0; i < noPatches; i++) { - patchBorders[i] = patchParam[i].guardStartBand - lowSubband; - } - } - patchBorders[i] = highSubband - lowSubband; - - /* 1.2, 2, or 3 limiter bands/octave plus bandborders at patchborders. */ - for (k = 0; k <= noFreqBands; k++) { - workLimiterBandTable[k] = freqBandTable[k] - lowSubband; - } - for (k = 1; k < noPatches; k++) { - workLimiterBandTable[noFreqBands + k] = patchBorders[k]; - } - - tempNoLim = nBands = noFreqBands + noPatches - 1; - shellsort(workLimiterBandTable, tempNoLim + 1); - - loLimIndex = 0; - hiLimIndex = 1; - - while (hiLimIndex <= tempNoLim) { - FIXP_DBL div_m, oct_m, temp; - INT div_e = 0, oct_e = 0, temp_e = 0; - - k2 = workLimiterBandTable[hiLimIndex] + lowSubband; - kx = workLimiterBandTable[loLimIndex] + lowSubband; - - div_m = fDivNorm(k2, kx, &div_e); - - /* calculate number of octaves */ - oct_m = fLog2(div_m, div_e, &oct_e); - - /* multiply with limiterbands per octave */ - /* values 1, 1.2, 2, 3 -> scale factor of 2 */ - temp = fMultNorm( - oct_m, FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[limiterBands], - &temp_e); - - /* overall scale factor of temp ist addition of scalefactors from log2 - calculation, limiter bands scalefactor (2) and limiter bands - multiplication */ - temp_e += oct_e + 2; - - /* div can be a maximum of 64 (k2 = 64 and kx = 1) - -> oct can be a maximum of 6 - -> temp can be a maximum of 18 (as limiterBandsPerOctoave is a maximum - factor of 3) - -> we need a scale factor of 5 for comparisson - */ - if (temp >> (5 - temp_e) < FL2FXCONST_DBL(0.49f) >> 5) { - if (workLimiterBandTable[hiLimIndex] == - workLimiterBandTable[loLimIndex]) { - workLimiterBandTable[hiLimIndex] = highSubband; - nBands--; - hiLimIndex++; - continue; - } - isPatchBorder[0] = isPatchBorder[1] = 0; - for (k = 0; k <= noPatches; k++) { - if (workLimiterBandTable[hiLimIndex] == patchBorders[k]) { - isPatchBorder[1] = 1; - break; - } - } - if (!isPatchBorder[1]) { - workLimiterBandTable[hiLimIndex] = highSubband; - nBands--; - hiLimIndex++; - continue; - } - for (k = 0; k <= noPatches; k++) { - if (workLimiterBandTable[loLimIndex] == patchBorders[k]) { - isPatchBorder[0] = 1; - break; - } - } - if (!isPatchBorder[0]) { - workLimiterBandTable[loLimIndex] = highSubband; - nBands--; - } - } - loLimIndex = hiLimIndex; - hiLimIndex++; - } - shellsort(workLimiterBandTable, tempNoLim + 1); - - /* Test if algorithm exceeded maximum allowed limiterbands */ - if (nBands > MAX_NUM_LIMITERS || nBands <= 0) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - - /* Copy limiterbands from working buffer into final destination */ - for (k = 0; k <= nBands; k++) { - limiterBandTable[k] = workLimiterBandTable[k]; - } - } - *noLimiterBands = nBands; - - return SBRDEC_OK; -} --- a/libSBRdec/src/env_calc.h +++ /dev/null @@ -1,182 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Envelope calculation prototypes -*/ -#ifndef ENV_CALC_H -#define ENV_CALC_H - -#include "sbrdecoder.h" -#include "env_extr.h" /* for HANDLE_SBR_HEADER_DATA */ - -typedef struct { - FIXP_DBL filtBuffer[MAX_FREQ_COEFFS]; /*!< previous gains (required for - smoothing) */ - FIXP_DBL filtBufferNoise[MAX_FREQ_COEFFS]; /*!< previous noise levels - (required for smoothing) */ - SCHAR filtBuffer_e[MAX_FREQ_COEFFS]; /*!< Exponents of previous gains */ - SCHAR filtBufferNoise_e; /*!< Common exponent of previous noise levels */ - - int startUp; /*!< flag to signal initial conditions in buffers */ - int phaseIndex; /*!< Index for randomPase array */ - int prevTranEnv; /*!< The transient envelope of the previous frame. */ - - ULONG harmFlagsPrev[ADD_HARMONICS_FLAGS_SIZE]; - /*!< Words with 16 flags each indicating where a sine was added in the - * previous frame.*/ - UCHAR harmIndex; /*!< Current phase of synthetic sine */ - int sbrPatchingMode; /*!< Current patching mode */ - - FIXP_SGL prevSbrNoiseFloorLevel[MAX_NOISE_COEFFS]; - UCHAR prevNNfb; - UCHAR prevNSfb[2]; - UCHAR prevLoSubband; - UCHAR prevHiSubband; - UCHAR prev_ov_highSubband; - UCHAR *prevFreqBandTable[2]; - UCHAR prevFreqBandTableLo[MAX_FREQ_COEFFS / 2 + 1]; - UCHAR prevFreqBandTableHi[MAX_FREQ_COEFFS + 1]; - UCHAR prevFreqBandTableNoise[MAX_NOISE_COEFFS + 1]; - SCHAR sinusoidal_positionPrev; - ULONG harmFlagsPrevActive[ADD_HARMONICS_FLAGS_SIZE]; -} SBR_CALCULATE_ENVELOPE; - -typedef SBR_CALCULATE_ENVELOPE *HANDLE_SBR_CALCULATE_ENVELOPE; - -void calculateSbrEnvelope( - QMF_SCALE_FACTOR *sbrScaleFactor, - HANDLE_SBR_CALCULATE_ENVELOPE h_sbr_cal_env, - HANDLE_SBR_HEADER_DATA hHeaderData, HANDLE_SBR_FRAME_DATA hFrameData, - PVC_DYNAMIC_DATA *pPvcDynamicData, FIXP_DBL **analysBufferReal, - FIXP_DBL * - *analysBufferImag, /*!< Imag part of subband samples to be processed */ - const int useLP, - FIXP_DBL *degreeAlias, /*!< Estimated aliasing for each QMF channel */ - const UINT flags, const int frameErrorFlag); - -SBR_ERROR -createSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hSbrCalculateEnvelope, - HANDLE_SBR_HEADER_DATA hHeaderData, const int chan, - const UINT flags); - -int deleteSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hSbrCalculateEnvelope); - -void resetSbrEnvelopeCalc(HANDLE_SBR_CALCULATE_ENVELOPE hCalEnv); - -SBR_ERROR -ResetLimiterBands(UCHAR *limiterBandTable, UCHAR *noLimiterBands, - UCHAR *freqBandTable, int noFreqBands, - const PATCH_PARAM *patchParam, int noPatches, - int limiterBands, UCHAR sbrPatchingMode, - int xOverQmf[MAX_NUM_PATCHES], int sbrRatio); - -void rescaleSubbandSamples(FIXP_DBL **re, FIXP_DBL **im, int lowSubband, - int noSubbands, int start_pos, int next_pos, - int shift); - -FIXP_DBL maxSubbandSample(FIXP_DBL **analysBufferReal_m, - FIXP_DBL **analysBufferImag_m, int lowSubband, - int highSubband, int start_pos, int stop_pos); - -#endif // ENV_CALC_H --- a/libSBRdec/src/env_dec.cpp +++ /dev/null @@ -1,873 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief envelope decoding - This module provides envelope decoding and error concealment algorithms. The - main entry point is decodeSbrData(). - - \sa decodeSbrData(),\ref documentationOverview -*/ - -#include "env_dec.h" - -#include "env_extr.h" -#include "transcendent.h" - -#include "genericStds.h" - -static void decodeEnvelope(HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_FRAME_DATA h_sbr_data, - HANDLE_SBR_PREV_FRAME_DATA h_prev_data, - HANDLE_SBR_PREV_FRAME_DATA h_prev_data_otherChannel); -static void sbr_envelope_unmapping(HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_FRAME_DATA h_data_left, - HANDLE_SBR_FRAME_DATA h_data_right); -static void requantizeEnvelopeData(HANDLE_SBR_FRAME_DATA h_sbr_data, - int ampResolution); -static void deltaToLinearPcmEnvelopeDecoding( - HANDLE_SBR_HEADER_DATA hHeaderData, HANDLE_SBR_FRAME_DATA h_sbr_data, - HANDLE_SBR_PREV_FRAME_DATA h_prev_data); -static void decodeNoiseFloorlevels(HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_FRAME_DATA h_sbr_data, - HANDLE_SBR_PREV_FRAME_DATA h_prev_data); -static void timeCompensateFirstEnvelope(HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_FRAME_DATA h_sbr_data, - HANDLE_SBR_PREV_FRAME_DATA h_prev_data); -static int checkEnvelopeData(HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_FRAME_DATA h_sbr_data, - HANDLE_SBR_PREV_FRAME_DATA h_prev_data); - -#define SBR_ENERGY_PAN_OFFSET (12 << ENV_EXP_FRACT) -#define SBR_MAX_ENERGY (35 << ENV_EXP_FRACT) - -#define DECAY (1 << ENV_EXP_FRACT) - -#if ENV_EXP_FRACT -#define DECAY_COUPLING \ - (1 << (ENV_EXP_FRACT - 1)) /*!< corresponds to a value of 0.5 */ -#else -#define DECAY_COUPLING \ - 1 /*!< If the energy data is not shifted, use 1 instead of 0.5 */ -#endif - -/*! - \brief Convert table index -*/ -static int indexLow2High(int offset, /*!< mapping factor */ - int index, /*!< index to scalefactor band */ - int res) /*!< frequency resolution */ -{ - if (res == 0) { - if (offset >= 0) { - if (index < offset) - return (index); - else - return (2 * index - offset); - } else { - offset = -offset; - if (index < offset) - return (2 * index + index); - else - return (2 * index + offset); - } - } else - return (index); -} - -/*! - \brief Update previous envelope value for delta-coding - - The current envelope values needs to be stored for delta-coding - in the next frame. The stored envelope is always represented with - the high frequency resolution. If the current envelope uses the - low frequency resolution, the energy value will be mapped to the - corresponding high-res bands. -*/ -static void mapLowResEnergyVal( - FIXP_SGL currVal, /*!< current energy value */ - FIXP_SGL *prevData, /*!< pointer to previous data vector */ - int offset, /*!< mapping factor */ - int index, /*!< index to scalefactor band */ - int res) /*!< frequeny resolution */ -{ - if (res == 0) { - if (offset >= 0) { - if (index < offset) - prevData[index] = currVal; - else { - prevData[2 * index - offset] = currVal; - prevData[2 * index + 1 - offset] = currVal; - } - } else { - offset = -offset; - if (index < offset) { - prevData[3 * index] = currVal; - prevData[3 * index + 1] = currVal; - prevData[3 * index + 2] = currVal; - } else { - prevData[2 * index + offset] = currVal; - prevData[2 * index + 1 + offset] = currVal; - } - } - } else - prevData[index] = currVal; -} - -/*! - \brief Convert raw envelope and noisefloor data to energy levels - - This function is being called by sbrDecoder_ParseElement() and provides two - important algorithms: - - First the function decodes envelopes and noise floor levels as described in - requantizeEnvelopeData() and sbr_envelope_unmapping(). The function also - implements concealment algorithms in case there are errors within the sbr - data. For both operations fractional arithmetic is used. Therefore you might - encounter different output values on your target system compared to the - reference implementation. -*/ -void decodeSbrData( - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA - h_data_left, /*!< pointer to left channel frame data */ - HANDLE_SBR_PREV_FRAME_DATA - h_prev_data_left, /*!< pointer to left channel previous frame data */ - HANDLE_SBR_FRAME_DATA - h_data_right, /*!< pointer to right channel frame data */ - HANDLE_SBR_PREV_FRAME_DATA - h_prev_data_right) /*!< pointer to right channel previous frame data */ -{ - FIXP_SGL tempSfbNrgPrev[MAX_FREQ_COEFFS]; - int errLeft; - - /* Save previous energy values to be able to reuse them later for concealment. - */ - FDKmemcpy(tempSfbNrgPrev, h_prev_data_left->sfb_nrg_prev, - MAX_FREQ_COEFFS * sizeof(FIXP_SGL)); - - if (hHeaderData->frameErrorFlag || hHeaderData->bs_info.pvc_mode == 0) { - decodeEnvelope(hHeaderData, h_data_left, h_prev_data_left, - h_prev_data_right); - } else { - FDK_ASSERT(h_data_right == NULL); - } - decodeNoiseFloorlevels(hHeaderData, h_data_left, h_prev_data_left); - - if (h_data_right != NULL) { - errLeft = hHeaderData->frameErrorFlag; - decodeEnvelope(hHeaderData, h_data_right, h_prev_data_right, - h_prev_data_left); - decodeNoiseFloorlevels(hHeaderData, h_data_right, h_prev_data_right); - - if (!errLeft && hHeaderData->frameErrorFlag) { - /* If an error occurs in the right channel where the left channel seemed - ok, we apply concealment also on the left channel. This ensures that - the coupling modes of both channels match and that we have the same - number of envelopes in coupling mode. However, as the left channel has - already been processed before, the resulting energy levels are not the - same as if the left channel had been concealed during the first call of - decodeEnvelope(). - */ - /* Restore previous energy values for concealment, because the values have - been overwritten by the first call of decodeEnvelope(). */ - FDKmemcpy(h_prev_data_left->sfb_nrg_prev, tempSfbNrgPrev, - MAX_FREQ_COEFFS * sizeof(FIXP_SGL)); - /* Do concealment */ - decodeEnvelope(hHeaderData, h_data_left, h_prev_data_left, - h_prev_data_right); - } - - if (h_data_left->coupling) { - sbr_envelope_unmapping(hHeaderData, h_data_left, h_data_right); - } - } - - /* Display the data for debugging: */ -} - -/*! - \brief Convert from coupled channels to independent L/R data -*/ -static void sbr_envelope_unmapping( - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA h_data_left, /*!< pointer to left channel */ - HANDLE_SBR_FRAME_DATA h_data_right) /*!< pointer to right channel */ -{ - int i; - FIXP_SGL tempL_m, tempR_m, tempRplus1_m, newL_m, newR_m; - SCHAR tempL_e, tempR_e, tempRplus1_e, newL_e, newR_e; - - /* 1. Unmap (already dequantized) coupled envelope energies */ - - for (i = 0; i < h_data_left->nScaleFactors; i++) { - tempR_m = (FIXP_SGL)((LONG)h_data_right->iEnvelope[i] & MASK_M); - tempR_e = (SCHAR)((LONG)h_data_right->iEnvelope[i] & MASK_E); - - tempR_e -= (18 + NRG_EXP_OFFSET); /* -18 = ld(UNMAPPING_SCALE / - h_data_right->nChannels) */ - tempL_m = (FIXP_SGL)((LONG)h_data_left->iEnvelope[i] & MASK_M); - tempL_e = (SCHAR)((LONG)h_data_left->iEnvelope[i] & MASK_E); - - tempL_e -= NRG_EXP_OFFSET; - - /* Calculate tempRight+1 */ - FDK_add_MantExp(tempR_m, tempR_e, FL2FXCONST_SGL(0.5f), 1, /* 1.0 */ - &tempRplus1_m, &tempRplus1_e); - - FDK_divide_MantExp(tempL_m, tempL_e + 1, /* 2 * tempLeft */ - tempRplus1_m, tempRplus1_e, &newR_m, &newR_e); - - if (newR_m >= ((FIXP_SGL)MAXVAL_SGL - ROUNDING)) { - newR_m >>= 1; - newR_e += 1; - } - - newL_m = FX_DBL2FX_SGL(fMult(tempR_m, newR_m)); - newL_e = tempR_e + newR_e; - - h_data_right->iEnvelope[i] = - ((FIXP_SGL)((SHORT)(FIXP_SGL)(newR_m + ROUNDING) & MASK_M)) + - (FIXP_SGL)((SHORT)(FIXP_SGL)(newR_e + NRG_EXP_OFFSET) & MASK_E); - h_data_left->iEnvelope[i] = - ((FIXP_SGL)((SHORT)(FIXP_SGL)(newL_m + ROUNDING) & MASK_M)) + - (FIXP_SGL)((SHORT)(FIXP_SGL)(newL_e + NRG_EXP_OFFSET) & MASK_E); - } - - /* 2. Dequantize and unmap coupled noise floor levels */ - - for (i = 0; i < hHeaderData->freqBandData.nNfb * - h_data_left->frameInfo.nNoiseEnvelopes; - i++) { - tempL_e = (SCHAR)(6 - (LONG)h_data_left->sbrNoiseFloorLevel[i]); - tempR_e = (SCHAR)((LONG)h_data_right->sbrNoiseFloorLevel[i] - - 12) /*SBR_ENERGY_PAN_OFFSET*/; - - /* Calculate tempR+1 */ - FDK_add_MantExp(FL2FXCONST_SGL(0.5f), 1 + tempR_e, /* tempR */ - FL2FXCONST_SGL(0.5f), 1, /* 1.0 */ - &tempRplus1_m, &tempRplus1_e); - - /* Calculate 2*tempLeft/(tempR+1) */ - FDK_divide_MantExp(FL2FXCONST_SGL(0.5f), tempL_e + 2, /* 2 * tempLeft */ - tempRplus1_m, tempRplus1_e, &newR_m, &newR_e); - - /* if (newR_m >= ((FIXP_SGL)MAXVAL_SGL - ROUNDING)) { - newR_m >>= 1; - newR_e += 1; - } */ - - /* L = tempR * R */ - newL_m = newR_m; - newL_e = newR_e + tempR_e; - h_data_right->sbrNoiseFloorLevel[i] = - ((FIXP_SGL)((SHORT)(FIXP_SGL)(newR_m + ROUNDING) & MASK_M)) + - (FIXP_SGL)((SHORT)(FIXP_SGL)(newR_e + NOISE_EXP_OFFSET) & MASK_E); - h_data_left->sbrNoiseFloorLevel[i] = - ((FIXP_SGL)((SHORT)(FIXP_SGL)(newL_m + ROUNDING) & MASK_M)) + - (FIXP_SGL)((SHORT)(FIXP_SGL)(newL_e + NOISE_EXP_OFFSET) & MASK_E); - } -} - -/*! - \brief Simple alternative to the real SBR concealment - - If the real frameInfo is not available due to a frame loss, a replacement will - be constructed with 1 envelope spanning the whole frame (FIX-FIX). - The delta-coded energies are set to negative values, resulting in a fade-down. - In case of coupling, the balance-channel will move towards the center. -*/ -static void leanSbrConcealment( - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA h_sbr_data, /*!< pointer to current data */ - HANDLE_SBR_PREV_FRAME_DATA h_prev_data /*!< pointer to data of last frame */ -) { - FIXP_SGL target; /* targeted level for sfb_nrg_prev during fade-down */ - FIXP_SGL step; /* speed of fade */ - int i; - - int currentStartPos = - fMax(0, h_prev_data->stopPos - hHeaderData->numberTimeSlots); - int currentStopPos = hHeaderData->numberTimeSlots; - - /* Use some settings of the previous frame */ - h_sbr_data->ampResolutionCurrentFrame = h_prev_data->ampRes; - h_sbr_data->coupling = h_prev_data->coupling; - for (i = 0; i < MAX_INVF_BANDS; i++) - h_sbr_data->sbr_invf_mode[i] = h_prev_data->sbr_invf_mode[i]; - - /* Generate concealing control data */ - - h_sbr_data->frameInfo.nEnvelopes = 1; - h_sbr_data->frameInfo.borders[0] = currentStartPos; - h_sbr_data->frameInfo.borders[1] = currentStopPos; - h_sbr_data->frameInfo.freqRes[0] = 1; - h_sbr_data->frameInfo.tranEnv = -1; /* no transient */ - h_sbr_data->frameInfo.nNoiseEnvelopes = 1; - h_sbr_data->frameInfo.bordersNoise[0] = currentStartPos; - h_sbr_data->frameInfo.bordersNoise[1] = currentStopPos; - - h_sbr_data->nScaleFactors = hHeaderData->freqBandData.nSfb[1]; - - /* Generate fake envelope data */ - - h_sbr_data->domain_vec[0] = 1; - - if (h_sbr_data->coupling == COUPLING_BAL) { - target = (FIXP_SGL)SBR_ENERGY_PAN_OFFSET; - step = (FIXP_SGL)DECAY_COUPLING; - } else { - target = FL2FXCONST_SGL(0.0f); - step = (FIXP_SGL)DECAY; - } - if (hHeaderData->bs_info.ampResolution == 0) { - target <<= 1; - step <<= 1; - } - - for (i = 0; i < h_sbr_data->nScaleFactors; i++) { - if (h_prev_data->sfb_nrg_prev[i] > target) - h_sbr_data->iEnvelope[i] = -step; - else - h_sbr_data->iEnvelope[i] = step; - } - - /* Noisefloor levels are always cleared ... */ - - h_sbr_data->domain_vec_noise[0] = 1; - FDKmemclear(h_sbr_data->sbrNoiseFloorLevel, - sizeof(h_sbr_data->sbrNoiseFloorLevel)); - - /* ... and so are the sines */ - FDKmemclear(h_sbr_data->addHarmonics, - sizeof(ULONG) * ADD_HARMONICS_FLAGS_SIZE); -} - -/*! - \brief Build reference energies and noise levels from bitstream elements -*/ -static void decodeEnvelope( - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA h_sbr_data, /*!< pointer to current data */ - HANDLE_SBR_PREV_FRAME_DATA - h_prev_data, /*!< pointer to data of last frame */ - HANDLE_SBR_PREV_FRAME_DATA - otherChannel /*!< other channel's last frame data */ -) { - int i; - int fFrameError = hHeaderData->frameErrorFlag; - FIXP_SGL tempSfbNrgPrev[MAX_FREQ_COEFFS]; - - if (!fFrameError) { - /* - To avoid distortions after bad frames, set the error flag if delta coding - in time occurs. However, SBR can take a little longer to come up again. - */ - if (h_prev_data->frameErrorFlag) { - if (h_sbr_data->domain_vec[0] != 0) { - fFrameError = 1; - } - } else { - /* Check that the previous stop position and the current start position - match. (Could be done in checkFrameInfo(), but the previous frame data - is not available there) */ - if (h_sbr_data->frameInfo.borders[0] != - h_prev_data->stopPos - hHeaderData->numberTimeSlots) { - /* Both the previous as well as the current frame are flagged to be ok, - * but they do not match! */ - if (h_sbr_data->domain_vec[0] == 1) { - /* Prefer concealment over delta-time coding between the mismatching - * frames */ - fFrameError = 1; - } else { - /* Close the gap in time by triggering timeCompensateFirstEnvelope() - */ - fFrameError = 1; - } - } - } - } - - if (fFrameError) /* Error is detected */ - { - leanSbrConcealment(hHeaderData, h_sbr_data, h_prev_data); - - /* decode the envelope data to linear PCM */ - deltaToLinearPcmEnvelopeDecoding(hHeaderData, h_sbr_data, h_prev_data); - } else /*Do a temporary dummy decoding and check that the envelope values are - within limits */ - { - if (h_prev_data->frameErrorFlag) { - timeCompensateFirstEnvelope(hHeaderData, h_sbr_data, h_prev_data); - if (h_sbr_data->coupling != h_prev_data->coupling) { - /* - Coupling mode has changed during concealment. - The stored energy levels need to be converted. - */ - for (i = 0; i < hHeaderData->freqBandData.nSfb[1]; i++) { - /* Former Level-Channel will be used for both channels */ - if (h_prev_data->coupling == COUPLING_BAL) { - h_prev_data->sfb_nrg_prev[i] = - (otherChannel != NULL) ? otherChannel->sfb_nrg_prev[i] - : (FIXP_SGL)SBR_ENERGY_PAN_OFFSET; - } - /* Former L/R will be combined as the new Level-Channel */ - else if (h_sbr_data->coupling == COUPLING_LEVEL && - otherChannel != NULL) { - h_prev_data->sfb_nrg_prev[i] = (h_prev_data->sfb_nrg_prev[i] + - otherChannel->sfb_nrg_prev[i]) >> - 1; - } else if (h_sbr_data->coupling == COUPLING_BAL) { - h_prev_data->sfb_nrg_prev[i] = (FIXP_SGL)SBR_ENERGY_PAN_OFFSET; - } - } - } - } - FDKmemcpy(tempSfbNrgPrev, h_prev_data->sfb_nrg_prev, - MAX_FREQ_COEFFS * sizeof(FIXP_SGL)); - - deltaToLinearPcmEnvelopeDecoding(hHeaderData, h_sbr_data, h_prev_data); - - fFrameError = checkEnvelopeData(hHeaderData, h_sbr_data, h_prev_data); - - if (fFrameError) { - hHeaderData->frameErrorFlag = 1; - FDKmemcpy(h_prev_data->sfb_nrg_prev, tempSfbNrgPrev, - MAX_FREQ_COEFFS * sizeof(FIXP_SGL)); - decodeEnvelope(hHeaderData, h_sbr_data, h_prev_data, otherChannel); - return; - } - } - - requantizeEnvelopeData(h_sbr_data, h_sbr_data->ampResolutionCurrentFrame); - - hHeaderData->frameErrorFlag = fFrameError; -} - -/*! - \brief Verify that envelope energies are within the allowed range - \return 0 if all is fine, 1 if an envelope value was too high -*/ -static int checkEnvelopeData( - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA h_sbr_data, /*!< pointer to current data */ - HANDLE_SBR_PREV_FRAME_DATA h_prev_data /*!< pointer to data of last frame */ -) { - FIXP_SGL *iEnvelope = h_sbr_data->iEnvelope; - FIXP_SGL *sfb_nrg_prev = h_prev_data->sfb_nrg_prev; - int i = 0, errorFlag = 0; - FIXP_SGL sbr_max_energy = (h_sbr_data->ampResolutionCurrentFrame == 1) - ? SBR_MAX_ENERGY - : (SBR_MAX_ENERGY << 1); - - /* - Range check for current energies - */ - for (i = 0; i < h_sbr_data->nScaleFactors; i++) { - if (iEnvelope[i] > sbr_max_energy) { - errorFlag = 1; - } - if (iEnvelope[i] < FL2FXCONST_SGL(0.0f)) { - errorFlag = 1; - /* iEnvelope[i] = FL2FXCONST_SGL(0.0f); */ - } - } - - /* - Range check for previous energies - */ - for (i = 0; i < hHeaderData->freqBandData.nSfb[1]; i++) { - sfb_nrg_prev[i] = fixMax(sfb_nrg_prev[i], FL2FXCONST_SGL(0.0f)); - sfb_nrg_prev[i] = fixMin(sfb_nrg_prev[i], sbr_max_energy); - } - - return (errorFlag); -} - -/*! - \brief Verify that the noise levels are within the allowed range - - The function is equivalent to checkEnvelopeData(). - When the noise-levels are being decoded, it is already too late for - concealment. Therefore the noise levels are simply limited here. -*/ -static void limitNoiseLevels( - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA h_sbr_data) /*!< pointer to current data */ -{ - int i; - int nNfb = hHeaderData->freqBandData.nNfb; - -/* - Set range limits. The exact values depend on the coupling mode. - However this limitation is primarily intended to avoid unlimited - accumulation of the delta-coded noise levels. -*/ -#define lowerLimit \ - ((FIXP_SGL)0) /* lowerLimit actually refers to the _highest_ noise energy */ -#define upperLimit \ - ((FIXP_SGL)35) /* upperLimit actually refers to the _lowest_ noise energy */ - - /* - Range check for current noise levels - */ - for (i = 0; i < h_sbr_data->frameInfo.nNoiseEnvelopes * nNfb; i++) { - h_sbr_data->sbrNoiseFloorLevel[i] = - fixMin(h_sbr_data->sbrNoiseFloorLevel[i], upperLimit); - h_sbr_data->sbrNoiseFloorLevel[i] = - fixMax(h_sbr_data->sbrNoiseFloorLevel[i], lowerLimit); - } -} - -/*! - \brief Compensate for the wrong timing that might occur after a frame error. -*/ -static void timeCompensateFirstEnvelope( - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA h_sbr_data, /*!< pointer to actual data */ - HANDLE_SBR_PREV_FRAME_DATA - h_prev_data) /*!< pointer to data of last frame */ -{ - int i, nScalefactors; - FRAME_INFO *pFrameInfo = &h_sbr_data->frameInfo; - UCHAR *nSfb = hHeaderData->freqBandData.nSfb; - int estimatedStartPos = - fMax(0, h_prev_data->stopPos - hHeaderData->numberTimeSlots); - int refLen, newLen, shift; - FIXP_SGL deltaExp; - - /* Original length of first envelope according to bitstream */ - refLen = pFrameInfo->borders[1] - pFrameInfo->borders[0]; - /* Corrected length of first envelope (concealing can make the first envelope - * longer) */ - newLen = pFrameInfo->borders[1] - estimatedStartPos; - - if (newLen <= 0) { - /* An envelope length of <= 0 would not work, so we don't use it. - May occur if the previous frame was flagged bad due to a mismatch - of the old and new frame infos. */ - newLen = refLen; - estimatedStartPos = pFrameInfo->borders[0]; - } - - deltaExp = FDK_getNumOctavesDiv8(newLen, refLen); - - /* Shift by -3 to rescale ld-table, ampRes-1 to enable coarser steps */ - shift = (FRACT_BITS - 1 - ENV_EXP_FRACT - 1 + - h_sbr_data->ampResolutionCurrentFrame - 3); - deltaExp = deltaExp >> shift; - pFrameInfo->borders[0] = estimatedStartPos; - pFrameInfo->bordersNoise[0] = estimatedStartPos; - - if (h_sbr_data->coupling != COUPLING_BAL) { - nScalefactors = (pFrameInfo->freqRes[0]) ? nSfb[1] : nSfb[0]; - - for (i = 0; i < nScalefactors; i++) - h_sbr_data->iEnvelope[i] = h_sbr_data->iEnvelope[i] + deltaExp; - } -} - -/*! - \brief Convert each envelope value from logarithmic to linear domain - - Energy levels are transmitted in powers of 2, i.e. only the exponent - is extracted from the bitstream. - Therefore, normally only integer exponents can occur. However during - fading (in case of a corrupt bitstream), a fractional part can also - occur. The data in the array iEnvelope is shifted left by ENV_EXP_FRACT - compared to an integer representation so that numbers smaller than 1 - can be represented. - - This function calculates a mantissa corresponding to the fractional - part of the exponent for each reference energy. The array iEnvelope - is converted in place to save memory. Input and output data must - be interpreted differently, as shown in the below figure: - - \image html EnvelopeData.png - - The data is then used in calculateSbrEnvelope(). -*/ -static void requantizeEnvelopeData(HANDLE_SBR_FRAME_DATA h_sbr_data, - int ampResolution) { - int i; - FIXP_SGL mantissa; - int ampShift = 1 - ampResolution; - int exponent; - - /* In case that ENV_EXP_FRACT is changed to something else but 0 or 8, - the initialization of this array has to be adapted! - */ -#if ENV_EXP_FRACT - static const FIXP_SGL pow2[ENV_EXP_FRACT] = { - FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 1))), /* 0.7071 */ - FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 2))), /* 0.5946 */ - FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 3))), - FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 4))), - FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 5))), - FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 6))), - FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 7))), - FL2FXCONST_SGL(0.5f * pow(2.0f, pow(0.5f, 8))) /* 0.5013 */ - }; - - int bit, mask; -#endif - - for (i = 0; i < h_sbr_data->nScaleFactors; i++) { - exponent = (LONG)h_sbr_data->iEnvelope[i]; - -#if ENV_EXP_FRACT - - exponent = exponent >> ampShift; - mantissa = 0.5f; - - /* Amplify mantissa according to the fractional part of the - exponent (result will be between 0.500000 and 0.999999) - */ - mask = 1; /* begin with lowest bit of exponent */ - - for (bit = ENV_EXP_FRACT - 1; bit >= 0; bit--) { - if (exponent & mask) { - /* The current bit of the exponent is set, - multiply mantissa with the corresponding factor: */ - mantissa = (FIXP_SGL)((mantissa * pow2[bit]) << 1); - } - /* Advance to next bit */ - mask = mask << 1; - } - - /* Make integer part of exponent right aligned */ - exponent = exponent >> ENV_EXP_FRACT; - -#else - /* In case of the high amplitude resolution, 1 bit of the exponent gets lost - by the shift. This will be compensated by a mantissa of 0.5*sqrt(2) - instead of 0.5 if that bit is 1. */ - mantissa = (exponent & ampShift) ? FL2FXCONST_SGL(0.707106781186548f) - : FL2FXCONST_SGL(0.5f); - exponent = exponent >> ampShift; -#endif - - /* - Mantissa was set to 0.5 (instead of 1.0, therefore increase exponent by - 1). Multiply by L=nChannels=64 by increasing exponent by another 6. - => Increase exponent by 7 - */ - exponent += 7 + NRG_EXP_OFFSET; - - /* Combine mantissa and exponent and write back the result */ - h_sbr_data->iEnvelope[i] = - ((FIXP_SGL)((SHORT)(FIXP_SGL)mantissa & MASK_M)) + - (FIXP_SGL)((SHORT)(FIXP_SGL)exponent & MASK_E); - } -} - -/*! - \brief Build new reference energies from old ones and delta coded data -*/ -static void deltaToLinearPcmEnvelopeDecoding( - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA h_sbr_data, /*!< pointer to current data */ - HANDLE_SBR_PREV_FRAME_DATA h_prev_data) /*!< pointer to previous data */ -{ - int i, domain, no_of_bands, band, freqRes; - - FIXP_SGL *sfb_nrg_prev = h_prev_data->sfb_nrg_prev; - FIXP_SGL *ptr_nrg = h_sbr_data->iEnvelope; - - int offset = - 2 * hHeaderData->freqBandData.nSfb[0] - hHeaderData->freqBandData.nSfb[1]; - - for (i = 0; i < h_sbr_data->frameInfo.nEnvelopes; i++) { - domain = h_sbr_data->domain_vec[i]; - freqRes = h_sbr_data->frameInfo.freqRes[i]; - - FDK_ASSERT(freqRes >= 0 && freqRes <= 1); - - no_of_bands = hHeaderData->freqBandData.nSfb[freqRes]; - - FDK_ASSERT(no_of_bands < (64)); - - if (domain == 0) { - mapLowResEnergyVal(*ptr_nrg, sfb_nrg_prev, offset, 0, freqRes); - ptr_nrg++; - for (band = 1; band < no_of_bands; band++) { - *ptr_nrg = *ptr_nrg + *(ptr_nrg - 1); - mapLowResEnergyVal(*ptr_nrg, sfb_nrg_prev, offset, band, freqRes); - ptr_nrg++; - } - } else { - for (band = 0; band < no_of_bands; band++) { - *ptr_nrg = - *ptr_nrg + sfb_nrg_prev[indexLow2High(offset, band, freqRes)]; - mapLowResEnergyVal(*ptr_nrg, sfb_nrg_prev, offset, band, freqRes); - ptr_nrg++; - } - } - } -} - -/*! - \brief Build new noise levels from old ones and delta coded data -*/ -static void decodeNoiseFloorlevels( - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA h_sbr_data, /*!< pointer to current data */ - HANDLE_SBR_PREV_FRAME_DATA h_prev_data) /*!< pointer to previous data */ -{ - int i; - int nNfb = hHeaderData->freqBandData.nNfb; - int nNoiseFloorEnvelopes = h_sbr_data->frameInfo.nNoiseEnvelopes; - - /* Decode first noise envelope */ - - if (h_sbr_data->domain_vec_noise[0] == 0) { - FIXP_SGL noiseLevel = h_sbr_data->sbrNoiseFloorLevel[0]; - for (i = 1; i < nNfb; i++) { - noiseLevel += h_sbr_data->sbrNoiseFloorLevel[i]; - h_sbr_data->sbrNoiseFloorLevel[i] = noiseLevel; - } - } else { - for (i = 0; i < nNfb; i++) { - h_sbr_data->sbrNoiseFloorLevel[i] += h_prev_data->prevNoiseLevel[i]; - } - } - - /* If present, decode the second noise envelope - Note: nNoiseFloorEnvelopes can only be 1 or 2 */ - - if (nNoiseFloorEnvelopes > 1) { - if (h_sbr_data->domain_vec_noise[1] == 0) { - FIXP_SGL noiseLevel = h_sbr_data->sbrNoiseFloorLevel[nNfb]; - for (i = nNfb + 1; i < 2 * nNfb; i++) { - noiseLevel += h_sbr_data->sbrNoiseFloorLevel[i]; - h_sbr_data->sbrNoiseFloorLevel[i] = noiseLevel; - } - } else { - for (i = 0; i < nNfb; i++) { - h_sbr_data->sbrNoiseFloorLevel[i + nNfb] += - h_sbr_data->sbrNoiseFloorLevel[i]; - } - } - } - - limitNoiseLevels(hHeaderData, h_sbr_data); - - /* Update prevNoiseLevel with the last noise envelope */ - for (i = 0; i < nNfb; i++) - h_prev_data->prevNoiseLevel[i] = - h_sbr_data->sbrNoiseFloorLevel[i + nNfb * (nNoiseFloorEnvelopes - 1)]; - - /* Requantize the noise floor levels in COUPLING_OFF-mode */ - if (!h_sbr_data->coupling) { - int nf_e; - - for (i = 0; i < nNoiseFloorEnvelopes * nNfb; i++) { - nf_e = 6 - (LONG)h_sbr_data->sbrNoiseFloorLevel[i] + 1 + NOISE_EXP_OFFSET; - /* +1 to compensate for a mantissa of 0.5 instead of 1.0 */ - - h_sbr_data->sbrNoiseFloorLevel[i] = - (FIXP_SGL)(((LONG)FL2FXCONST_SGL(0.5f)) + /* mantissa */ - (nf_e & MASK_E)); /* exponent */ - } - } -} --- a/libSBRdec/src/env_dec.h +++ /dev/null @@ -1,119 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Envelope decoding -*/ -#ifndef ENV_DEC_H -#define ENV_DEC_H - -#include "sbrdecoder.h" -#include "env_extr.h" - -void decodeSbrData(HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_FRAME_DATA h_data_left, - HANDLE_SBR_PREV_FRAME_DATA h_prev_data_left, - HANDLE_SBR_FRAME_DATA h_data_right, - HANDLE_SBR_PREV_FRAME_DATA h_prev_data_right); - -#endif --- a/libSBRdec/src/env_extr.cpp +++ /dev/null @@ -1,1728 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Envelope extraction - The functions provided by this module are mostly called by applySBR(). After - it is determined that there is valid SBR data, sbrGetHeaderData() might be - called if the current SBR data contains an \ref SBR_HEADER_ELEMENT as opposed - to a \ref SBR_STANDARD_ELEMENT. This function may return various error codes - as defined in #SBR_HEADER_STATUS . Most importantly it returns HEADER_RESET - when decoder settings need to be recalculated according to the SBR - specifications. In that case applySBR() will initiatite the required - re-configuration. - - The header data is stored in a #SBR_HEADER_DATA structure. - - The actual SBR data for the current frame is decoded into SBR_FRAME_DATA - stuctures by sbrGetChannelPairElement() [for stereo streams] and - sbrGetSingleChannelElement() [for mono streams]. There is no fractional - arithmetic involved. - - Once the information is extracted, the data needs to be further prepared - before the actual decoding process. This is done in decodeSbrData(). - - \sa Description of buffer management in applySBR(). \ref documentationOverview - -

About the SBR data format:

- - Each frame includes SBR data (side chain information), and can be either the - \ref SBR_HEADER_ELEMENT or the \ref SBR_STANDARD_ELEMENT. Parts of the data - can be protected by a CRC checksum. - - \anchor SBR_HEADER_ELEMENT

The SBR_HEADER_ELEMENT

- - The SBR_HEADER_ELEMENT can be transmitted with every frame, however, it - typically is send every second or so. It contains fundamental information such - as SBR sampling frequency and frequency range as well as control signals that - do not require frequent changes. It also includes the \ref - SBR_STANDARD_ELEMENT. - - Depending on the changes between the information in a current - SBR_HEADER_ELEMENT and the previous SBR_HEADER_ELEMENT, the SBR decoder might - need to be reset and reconfigured (e.g. new tables need to be calculated). - - \anchor SBR_STANDARD_ELEMENT

The SBR_STANDARD_ELEMENT

- - This data can be subdivided into "side info" and "raw data", where side info - is defined as signals needed to decode the raw data and some decoder tuning - signals. Raw data is referred to as PCM and Huffman coded envelope and noise - floor estimates. The side info also includes information about the - time-frequency grid for the current frame. - - \sa \ref documentationOverview -*/ - -#include "env_extr.h" - -#include "sbr_ram.h" -#include "sbr_rom.h" -#include "huff_dec.h" - -#include "psbitdec.h" - -#define DRM_PARAMETRIC_STEREO 0 -#define EXTENSION_ID_PS_CODING 2 - -static int extractPvcFrameInfo( - HANDLE_FDK_BITSTREAM hBs, /*!< bitbuffer handle */ - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA h_frame_data, /*!< pointer to memory where the - frame-info will be stored */ - HANDLE_SBR_PREV_FRAME_DATA h_prev_frame_data, /*!< pointer to memory where - the previous frame-info - will be stored */ - UCHAR pvc_mode_last, /**< PVC mode of last frame */ - const UINT flags); -static int extractFrameInfo(HANDLE_FDK_BITSTREAM hBs, - HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_FRAME_DATA h_frame_data, - const UINT nrOfChannels, const UINT flags); - -static int sbrGetPvcEnvelope(HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_FRAME_DATA h_frame_data, - HANDLE_FDK_BITSTREAM hBs, const UINT flags, - const UINT pvcMode); -static int sbrGetEnvelope(HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_FRAME_DATA h_frame_data, - HANDLE_FDK_BITSTREAM hBs, const UINT flags); - -static void sbrGetDirectionControlData(HANDLE_SBR_FRAME_DATA hFrameData, - HANDLE_FDK_BITSTREAM hBs, - const UINT flags, const int bs_pvc_mode); - -static void sbrGetNoiseFloorData(HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_FRAME_DATA h_frame_data, - HANDLE_FDK_BITSTREAM hBs); - -static int checkFrameInfo(FRAME_INFO *pFrameInfo, int numberOfTimeSlots, - int overlap, int timeStep); - -/* Mapping to std samplerate table according to 14496-3 (4.6.18.2.6) */ -typedef struct SR_MAPPING { - UINT fsRangeLo; /* If fsRangeLo(n+1)>fs>=fsRangeLo(n), it will be mapped to... - */ - UINT fsMapped; /* fsMapped. */ -} SR_MAPPING; - -static const SR_MAPPING stdSampleRatesMapping[] = { - {0, 8000}, {9391, 11025}, {11502, 12000}, {13856, 16000}, - {18783, 22050}, {23004, 24000}, {27713, 32000}, {37566, 44100}, - {46009, 48000}, {55426, 64000}, {75132, 88200}, {92017, 96000}}; -static const SR_MAPPING stdSampleRatesMappingUsac[] = { - {0, 16000}, {18783, 22050}, {23004, 24000}, {27713, 32000}, - {35777, 40000}, {42000, 44100}, {46009, 48000}, {55426, 64000}, - {75132, 88200}, {92017, 96000}}; - -UINT sbrdec_mapToStdSampleRate(UINT fs, - UINT isUsac) /*!< Output sampling frequency */ -{ - UINT fsMapped = fs, tableSize = 0; - const SR_MAPPING *mappingTable; - int i; - - if (!isUsac) { - mappingTable = stdSampleRatesMapping; - tableSize = sizeof(stdSampleRatesMapping) / sizeof(SR_MAPPING); - } else { - mappingTable = stdSampleRatesMappingUsac; - tableSize = sizeof(stdSampleRatesMappingUsac) / sizeof(SR_MAPPING); - } - - for (i = tableSize - 1; i >= 0; i--) { - if (fs >= mappingTable[i].fsRangeLo) { - fsMapped = mappingTable[i].fsMapped; - break; - } - } - - return (fsMapped); -} - -SBR_ERROR -initHeaderData(HANDLE_SBR_HEADER_DATA hHeaderData, const int sampleRateIn, - const int sampleRateOut, const INT downscaleFactor, - const int samplesPerFrame, const UINT flags, - const int setDefaultHdr) { - HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData; - SBR_ERROR sbrError = SBRDEC_OK; - int numAnalysisBands; - int sampleRateProc; - - if (!(flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50))) { - sampleRateProc = - sbrdec_mapToStdSampleRate(sampleRateOut * downscaleFactor, 0); - } else { - sampleRateProc = sampleRateOut * downscaleFactor; - } - - if (sampleRateIn == sampleRateOut) { - hHeaderData->sbrProcSmplRate = sampleRateProc << 1; - numAnalysisBands = 32; - } else { - hHeaderData->sbrProcSmplRate = sampleRateProc; - if ((sampleRateOut >> 1) == sampleRateIn) { - /* 1:2 */ - numAnalysisBands = 32; - } else if ((sampleRateOut >> 2) == sampleRateIn) { - /* 1:4 */ - numAnalysisBands = 16; - } else if ((sampleRateOut * 3) >> 3 == (sampleRateIn * 8) >> 3) { - /* 3:8, 3/4 core frame length */ - numAnalysisBands = 24; - } else { - sbrError = SBRDEC_UNSUPPORTED_CONFIG; - goto bail; - } - } - numAnalysisBands /= downscaleFactor; - - if (setDefaultHdr) { - /* Fill in default values first */ - hHeaderData->syncState = SBR_NOT_INITIALIZED; - hHeaderData->status = 0; - hHeaderData->frameErrorFlag = 0; - - hHeaderData->bs_info.ampResolution = 1; - hHeaderData->bs_info.xover_band = 0; - hHeaderData->bs_info.sbr_preprocessing = 0; - hHeaderData->bs_info.pvc_mode = 0; - - hHeaderData->bs_data.startFreq = 5; - hHeaderData->bs_data.stopFreq = 0; - hHeaderData->bs_data.freqScale = - 0; /* previously 2; for ELD reduced delay bitstreams - /samplerates initializing of the sbr decoder instance fails if - freqScale is set to 2 because no master table can be generated; in - ELD reduced delay bitstreams this value is always 0; gets overwritten - when header is read */ - hHeaderData->bs_data.alterScale = 1; - hHeaderData->bs_data.noise_bands = 2; - hHeaderData->bs_data.limiterBands = 2; - hHeaderData->bs_data.limiterGains = 2; - hHeaderData->bs_data.interpolFreq = 1; - hHeaderData->bs_data.smoothingLength = 1; - - /* Patch some entries */ - if (sampleRateOut * downscaleFactor >= 96000) { - hHeaderData->bs_data.startFreq = - 4; /* having read these frequency values from bit stream before. */ - hHeaderData->bs_data.stopFreq = 3; - } else if (sampleRateOut * downscaleFactor > - 24000) { /* Trigger an error if SBR is going to be processed - without */ - hHeaderData->bs_data.startFreq = - 7; /* having read these frequency values from bit stream before. */ - hHeaderData->bs_data.stopFreq = 3; - } - } - - if ((sampleRateOut >> 2) == sampleRateIn) { - hHeaderData->timeStep = 4; - } else { - hHeaderData->timeStep = (flags & SBRDEC_ELD_GRID) ? 1 : 2; - } - - /* Setup pointers to frequency band tables */ - hFreq->freqBandTable[0] = hFreq->freqBandTableLo; - hFreq->freqBandTable[1] = hFreq->freqBandTableHi; - - /* One SBR timeslot corresponds to the amount of samples equal to the amount - * of analysis bands, divided by the timestep. */ - hHeaderData->numberTimeSlots = - (samplesPerFrame / numAnalysisBands) >> (hHeaderData->timeStep - 1); - if (hHeaderData->numberTimeSlots > (16)) { - sbrError = SBRDEC_UNSUPPORTED_CONFIG; - } - - hHeaderData->numberOfAnalysisBands = numAnalysisBands; - if ((sampleRateOut >> 2) == sampleRateIn) { - hHeaderData->numberTimeSlots <<= 1; - } - -bail: - return sbrError; -} - -/*! - \brief Initialize the SBR_PREV_FRAME_DATA struct -*/ -void initSbrPrevFrameData( - HANDLE_SBR_PREV_FRAME_DATA - h_prev_data, /*!< handle to struct SBR_PREV_FRAME_DATA */ - int timeSlots) /*!< Framelength in SBR-timeslots */ -{ - int i; - - /* Set previous energy and noise levels to 0 for the case - that decoding starts in the middle of a bitstream */ - for (i = 0; i < MAX_FREQ_COEFFS; i++) - h_prev_data->sfb_nrg_prev[i] = (FIXP_DBL)0; - for (i = 0; i < MAX_NOISE_COEFFS; i++) - h_prev_data->prevNoiseLevel[i] = (FIXP_DBL)0; - for (i = 0; i < MAX_INVF_BANDS; i++) h_prev_data->sbr_invf_mode[i] = INVF_OFF; - - h_prev_data->stopPos = timeSlots; - h_prev_data->coupling = COUPLING_OFF; - h_prev_data->ampRes = 0; - - FDKmemclear(&h_prev_data->prevFrameInfo, sizeof(h_prev_data->prevFrameInfo)); -} - -/*! - \brief Read header data from bitstream - - \return error status - 0 if ok -*/ -SBR_HEADER_STATUS -sbrGetHeaderData(HANDLE_SBR_HEADER_DATA hHeaderData, HANDLE_FDK_BITSTREAM hBs, - const UINT flags, const int fIsSbrData, - const UCHAR configMode) { - SBR_HEADER_DATA_BS *pBsData; - SBR_HEADER_DATA_BS lastHeader; - SBR_HEADER_DATA_BS_INFO lastInfo; - int headerExtra1 = 0, headerExtra2 = 0; - - /* Read and discard new header in config change detection mode */ - if (configMode & AC_CM_DET_CFG_CHANGE) { - if (!(flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC))) { - /* ampResolution */ - FDKreadBits(hBs, 1); - } - /* startFreq, stopFreq */ - FDKpushFor(hBs, 8); - if (!(flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC))) { - /* xover_band */ - FDKreadBits(hBs, 3); - /* reserved bits */ - FDKreadBits(hBs, 2); - } - headerExtra1 = FDKreadBit(hBs); - headerExtra2 = FDKreadBit(hBs); - FDKpushFor(hBs, 5 * headerExtra1 + 6 * headerExtra2); - - return HEADER_OK; - } - - /* Copy SBR bit stream header to temporary header */ - lastHeader = hHeaderData->bs_data; - lastInfo = hHeaderData->bs_info; - - /* Read new header from bitstream */ - if ((flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC)) && !fIsSbrData) { - pBsData = &hHeaderData->bs_dflt; - } else { - pBsData = &hHeaderData->bs_data; - } - - if (!(flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC))) { - hHeaderData->bs_info.ampResolution = FDKreadBits(hBs, 1); - } - - pBsData->startFreq = FDKreadBits(hBs, 4); - pBsData->stopFreq = FDKreadBits(hBs, 4); - - if (!(flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC))) { - hHeaderData->bs_info.xover_band = FDKreadBits(hBs, 3); - FDKreadBits(hBs, 2); - } - - headerExtra1 = FDKreadBits(hBs, 1); - headerExtra2 = FDKreadBits(hBs, 1); - - /* Handle extra header information */ - if (headerExtra1) { - pBsData->freqScale = FDKreadBits(hBs, 2); - pBsData->alterScale = FDKreadBits(hBs, 1); - pBsData->noise_bands = FDKreadBits(hBs, 2); - } else { - pBsData->freqScale = 2; - pBsData->alterScale = 1; - pBsData->noise_bands = 2; - } - - if (headerExtra2) { - pBsData->limiterBands = FDKreadBits(hBs, 2); - pBsData->limiterGains = FDKreadBits(hBs, 2); - pBsData->interpolFreq = FDKreadBits(hBs, 1); - pBsData->smoothingLength = FDKreadBits(hBs, 1); - } else { - pBsData->limiterBands = 2; - pBsData->limiterGains = 2; - pBsData->interpolFreq = 1; - pBsData->smoothingLength = 1; - } - - /* Look for new settings. IEC 14496-3, 4.6.18.3.1 */ - if (hHeaderData->syncState < SBR_HEADER || - lastHeader.startFreq != pBsData->startFreq || - lastHeader.stopFreq != pBsData->stopFreq || - lastHeader.freqScale != pBsData->freqScale || - lastHeader.alterScale != pBsData->alterScale || - lastHeader.noise_bands != pBsData->noise_bands || - lastInfo.xover_band != hHeaderData->bs_info.xover_band) { - return HEADER_RESET; /* New settings */ - } - - return HEADER_OK; -} - -/*! - \brief Get missing harmonics parameters (only used for AAC+SBR) - - \return error status - 0 if ok -*/ -int sbrGetSyntheticCodedData(HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_FRAME_DATA hFrameData, - HANDLE_FDK_BITSTREAM hBs, const UINT flags) { - int i, bitsRead = 0; - - int add_harmonic_flag = FDKreadBits(hBs, 1); - bitsRead++; - - if (add_harmonic_flag) { - int nSfb = hHeaderData->freqBandData.nSfb[1]; - for (i = 0; i < ADD_HARMONICS_FLAGS_SIZE; i++) { - /* read maximum 32 bits and align them to the MSB */ - int readBits = fMin(32, nSfb); - nSfb -= readBits; - if (readBits > 0) { - hFrameData->addHarmonics[i] = FDKreadBits(hBs, readBits) - << (32 - readBits); - } else { - hFrameData->addHarmonics[i] = 0; - } - - bitsRead += readBits; - } - /* bs_pvc_mode = 0 for Rsvd50 */ - if (flags & SBRDEC_SYNTAX_USAC) { - if (hHeaderData->bs_info.pvc_mode) { - int bs_sinusoidal_position = 31; - if (FDKreadBit(hBs) /* bs_sinusoidal_position_flag */) { - bs_sinusoidal_position = FDKreadBits(hBs, 5); - } - hFrameData->sinusoidal_position = bs_sinusoidal_position; - } - } - } else { - for (i = 0; i < ADD_HARMONICS_FLAGS_SIZE; i++) - hFrameData->addHarmonics[i] = 0; - } - - return (bitsRead); -} - -/*! - \brief Reads extension data from the bitstream - - The bitstream format allows up to 4 kinds of extended data element. - Extended data may contain several elements, each identified by a 2-bit-ID. - So far, no extended data elements are defined hence the first 2 parameters - are unused. The data should be skipped in order to update the number - of read bits for the consistency check in applySBR(). -*/ -static int extractExtendedData( - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< handle to SBR header */ - HANDLE_FDK_BITSTREAM hBs /*!< Handle to the bit buffer */ - , - HANDLE_PS_DEC hParametricStereoDec /*!< Parametric Stereo Decoder */ -) { - INT nBitsLeft; - int extended_data; - int i, frameOk = 1; - - extended_data = FDKreadBits(hBs, 1); - - if (extended_data) { - int cnt; - int bPsRead = 0; - - cnt = FDKreadBits(hBs, 4); - if (cnt == (1 << 4) - 1) cnt += FDKreadBits(hBs, 8); - - nBitsLeft = 8 * cnt; - - /* sanity check for cnt */ - if (nBitsLeft > (INT)FDKgetValidBits(hBs)) { - /* limit nBitsLeft */ - nBitsLeft = (INT)FDKgetValidBits(hBs); - /* set frame error */ - frameOk = 0; - } - - while (nBitsLeft > 7) { - int extension_id = FDKreadBits(hBs, 2); - nBitsLeft -= 2; - - switch (extension_id) { - case EXTENSION_ID_PS_CODING: - - /* Read PS data from bitstream */ - - if (hParametricStereoDec != NULL) { - if (bPsRead && - !hParametricStereoDec->bsData[hParametricStereoDec->bsReadSlot] - .mpeg.bPsHeaderValid) { - cnt = nBitsLeft >> 3; /* number of remaining bytes */ - for (i = 0; i < cnt; i++) FDKreadBits(hBs, 8); - nBitsLeft -= cnt * 8; - } else { - nBitsLeft -= - (INT)ReadPsData(hParametricStereoDec, hBs, nBitsLeft); - bPsRead = 1; - } - } - - /* parametric stereo detected, could set channelMode accordingly here - */ - /* */ - /* "The usage of this parametric stereo extension to HE-AAC is */ - /* signalled implicitly in the bitstream. Hence, if an sbr_extension() - */ - /* with bs_extension_id==EXTENSION_ID_PS is found in the SBR part of - */ - /* the bitstream, a decoder supporting the combination of SBR and PS - */ - /* shall operate the PS tool to generate a stereo output signal." */ - /* source: ISO/IEC 14496-3:2001/FDAM 2:2004(E) */ - - break; - - default: - cnt = nBitsLeft >> 3; /* number of remaining bytes */ - for (i = 0; i < cnt; i++) FDKreadBits(hBs, 8); - nBitsLeft -= cnt * 8; - break; - } - } - - if (nBitsLeft < 0) { - frameOk = 0; - goto bail; - } else { - /* Read fill bits for byte alignment */ - FDKreadBits(hBs, nBitsLeft); - } - } - -bail: - return (frameOk); -} - -/*! - \brief Read bitstream elements of a SBR channel element - \return SbrFrameOK -*/ -int sbrGetChannelElement(HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_FRAME_DATA hFrameDataLeft, - HANDLE_SBR_FRAME_DATA hFrameDataRight, - HANDLE_SBR_PREV_FRAME_DATA hFrameDataLeftPrev, - UCHAR pvc_mode_last, HANDLE_FDK_BITSTREAM hBs, - HANDLE_PS_DEC hParametricStereoDec, const UINT flags, - const int overlap) { - int i, bs_coupling = COUPLING_OFF; - const int nCh = (hFrameDataRight == NULL) ? 1 : 2; - - if (!(flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50))) { - /* Reserved bits */ - if (FDKreadBits(hBs, 1)) { /* bs_data_extra */ - FDKreadBits(hBs, 4); - if ((flags & SBRDEC_SYNTAX_SCAL) || (nCh == 2)) { - FDKreadBits(hBs, 4); - } - } - } - - if (nCh == 2) { - /* Read coupling flag */ - bs_coupling = FDKreadBits(hBs, 1); - if (bs_coupling) { - hFrameDataLeft->coupling = COUPLING_LEVEL; - hFrameDataRight->coupling = COUPLING_BAL; - } else { - hFrameDataLeft->coupling = COUPLING_OFF; - hFrameDataRight->coupling = COUPLING_OFF; - } - } else { - if (flags & SBRDEC_SYNTAX_SCAL) { - FDKreadBits(hBs, 1); /* bs_coupling */ - } - hFrameDataLeft->coupling = COUPLING_OFF; - } - - if (flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) { - if (flags & SBRDEC_USAC_HARMONICSBR) { - hFrameDataLeft->sbrPatchingMode = FDKreadBit(hBs); - if (hFrameDataLeft->sbrPatchingMode == 0) { - hFrameDataLeft->sbrOversamplingFlag = FDKreadBit(hBs); - if (FDKreadBit(hBs)) { /* sbrPitchInBinsFlag */ - hFrameDataLeft->sbrPitchInBins = FDKreadBits(hBs, 7); - } else { - hFrameDataLeft->sbrPitchInBins = 0; - } - } else { - hFrameDataLeft->sbrOversamplingFlag = 0; - hFrameDataLeft->sbrPitchInBins = 0; - } - - if (nCh == 2) { - if (bs_coupling) { - hFrameDataRight->sbrPatchingMode = hFrameDataLeft->sbrPatchingMode; - hFrameDataRight->sbrOversamplingFlag = - hFrameDataLeft->sbrOversamplingFlag; - hFrameDataRight->sbrPitchInBins = hFrameDataLeft->sbrPitchInBins; - } else { - hFrameDataRight->sbrPatchingMode = FDKreadBit(hBs); - if (hFrameDataRight->sbrPatchingMode == 0) { - hFrameDataRight->sbrOversamplingFlag = FDKreadBit(hBs); - if (FDKreadBit(hBs)) { /* sbrPitchInBinsFlag */ - hFrameDataRight->sbrPitchInBins = FDKreadBits(hBs, 7); - } else { - hFrameDataRight->sbrPitchInBins = 0; - } - } else { - hFrameDataRight->sbrOversamplingFlag = 0; - hFrameDataRight->sbrPitchInBins = 0; - } - } - } - } else { - if (nCh == 2) { - hFrameDataRight->sbrPatchingMode = 1; - hFrameDataRight->sbrOversamplingFlag = 0; - hFrameDataRight->sbrPitchInBins = 0; - } - - hFrameDataLeft->sbrPatchingMode = 1; - hFrameDataLeft->sbrOversamplingFlag = 0; - hFrameDataLeft->sbrPitchInBins = 0; - } - } else { - if (nCh == 2) { - hFrameDataRight->sbrPatchingMode = 1; - hFrameDataRight->sbrOversamplingFlag = 0; - hFrameDataRight->sbrPitchInBins = 0; - } - - hFrameDataLeft->sbrPatchingMode = 1; - hFrameDataLeft->sbrOversamplingFlag = 0; - hFrameDataLeft->sbrPitchInBins = 0; - } - - /* - sbr_grid(): Grid control - */ - if (hHeaderData->bs_info.pvc_mode) { - FDK_ASSERT(nCh == 1); /* PVC not possible for CPE */ - if (!extractPvcFrameInfo(hBs, hHeaderData, hFrameDataLeft, - hFrameDataLeftPrev, pvc_mode_last, flags)) - return 0; - - if (!checkFrameInfo(&hFrameDataLeft->frameInfo, - hHeaderData->numberTimeSlots, overlap, - hHeaderData->timeStep)) - return 0; - } else { - if (!extractFrameInfo(hBs, hHeaderData, hFrameDataLeft, 1, flags)) return 0; - - if (!checkFrameInfo(&hFrameDataLeft->frameInfo, - hHeaderData->numberTimeSlots, overlap, - hHeaderData->timeStep)) - return 0; - } - if (nCh == 2) { - if (hFrameDataLeft->coupling) { - FDKmemcpy(&hFrameDataRight->frameInfo, &hFrameDataLeft->frameInfo, - sizeof(FRAME_INFO)); - hFrameDataRight->ampResolutionCurrentFrame = - hFrameDataLeft->ampResolutionCurrentFrame; - } else { - if (!extractFrameInfo(hBs, hHeaderData, hFrameDataRight, 2, flags)) - return 0; - - if (!checkFrameInfo(&hFrameDataRight->frameInfo, - hHeaderData->numberTimeSlots, overlap, - hHeaderData->timeStep)) - return 0; - } - } - - /* - sbr_dtdf(): Fetch domain vectors (time or frequency direction for - delta-coding) - */ - sbrGetDirectionControlData(hFrameDataLeft, hBs, flags, - hHeaderData->bs_info.pvc_mode); - if (nCh == 2) { - sbrGetDirectionControlData(hFrameDataRight, hBs, flags, 0); - } - - /* sbr_invf() */ - for (i = 0; i < hHeaderData->freqBandData.nInvfBands; i++) { - hFrameDataLeft->sbr_invf_mode[i] = (INVF_MODE)FDKreadBits(hBs, 2); - } - if (nCh == 2) { - if (hFrameDataLeft->coupling) { - for (i = 0; i < hHeaderData->freqBandData.nInvfBands; i++) { - hFrameDataRight->sbr_invf_mode[i] = hFrameDataLeft->sbr_invf_mode[i]; - } - } else { - for (i = 0; i < hHeaderData->freqBandData.nInvfBands; i++) { - hFrameDataRight->sbr_invf_mode[i] = (INVF_MODE)FDKreadBits(hBs, 2); - } - } - } - - if (nCh == 1) { - if (hHeaderData->bs_info.pvc_mode) { - if (!sbrGetPvcEnvelope(hHeaderData, hFrameDataLeft, hBs, flags, - hHeaderData->bs_info.pvc_mode)) - return 0; - } else if (!sbrGetEnvelope(hHeaderData, hFrameDataLeft, hBs, flags)) - return 0; - - sbrGetNoiseFloorData(hHeaderData, hFrameDataLeft, hBs); - } else if (hFrameDataLeft->coupling) { - if (!sbrGetEnvelope(hHeaderData, hFrameDataLeft, hBs, flags)) { - return 0; - } - - sbrGetNoiseFloorData(hHeaderData, hFrameDataLeft, hBs); - - if (!sbrGetEnvelope(hHeaderData, hFrameDataRight, hBs, flags)) { - return 0; - } - sbrGetNoiseFloorData(hHeaderData, hFrameDataRight, hBs); - } else { /* nCh == 2 && no coupling */ - - if (!sbrGetEnvelope(hHeaderData, hFrameDataLeft, hBs, flags)) return 0; - - if (!sbrGetEnvelope(hHeaderData, hFrameDataRight, hBs, flags)) return 0; - - sbrGetNoiseFloorData(hHeaderData, hFrameDataLeft, hBs); - - sbrGetNoiseFloorData(hHeaderData, hFrameDataRight, hBs); - } - - sbrGetSyntheticCodedData(hHeaderData, hFrameDataLeft, hBs, flags); - if (nCh == 2) { - sbrGetSyntheticCodedData(hHeaderData, hFrameDataRight, hBs, flags); - } - - if (!(flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50))) { - if (!extractExtendedData(hHeaderData, hBs, hParametricStereoDec)) { - return 0; - } - } - - return 1; -} - -/*! - \brief Read direction control data from bitstream -*/ -void sbrGetDirectionControlData( - HANDLE_SBR_FRAME_DATA h_frame_data, /*!< handle to struct SBR_FRAME_DATA */ - HANDLE_FDK_BITSTREAM hBs, /*!< handle to struct BIT_BUF */ - const UINT flags, const int bs_pvc_mode) - -{ - int i; - int indepFlag = 0; - - if (flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) { - indepFlag = flags & SBRDEC_USAC_INDEP; - } - - if (bs_pvc_mode == 0) { - i = 0; - if (indepFlag) { - h_frame_data->domain_vec[i++] = 0; - } - for (; i < h_frame_data->frameInfo.nEnvelopes; i++) { - h_frame_data->domain_vec[i] = FDKreadBits(hBs, 1); - } - } - - i = 0; - if (indepFlag) { - h_frame_data->domain_vec_noise[i++] = 0; - } - for (; i < h_frame_data->frameInfo.nNoiseEnvelopes; i++) { - h_frame_data->domain_vec_noise[i] = FDKreadBits(hBs, 1); - } -} - -/*! - \brief Read noise-floor-level data from bitstream -*/ -void sbrGetNoiseFloorData( - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA h_frame_data, /*!< handle to struct SBR_FRAME_DATA */ - HANDLE_FDK_BITSTREAM hBs) /*!< handle to struct BIT_BUF */ -{ - int i, j; - int delta; - COUPLING_MODE coupling; - int noNoiseBands = hHeaderData->freqBandData.nNfb; - - Huffman hcb_noiseF; - Huffman hcb_noise; - int envDataTableCompFactor; - - coupling = h_frame_data->coupling; - - /* - Select huffman codebook depending on coupling mode - */ - if (coupling == COUPLING_BAL) { - hcb_noise = (Huffman)&FDK_sbrDecoder_sbr_huffBook_NoiseBalance11T; - hcb_noiseF = - (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance11F; /* "sbr_huffBook_NoiseBalance11F" - */ - envDataTableCompFactor = 1; - } else { - hcb_noise = (Huffman)&FDK_sbrDecoder_sbr_huffBook_NoiseLevel11T; - hcb_noiseF = - (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel11F; /* "sbr_huffBook_NoiseLevel11F" - */ - envDataTableCompFactor = 0; - } - - /* - Read raw noise-envelope data - */ - for (i = 0; i < h_frame_data->frameInfo.nNoiseEnvelopes; i++) { - if (h_frame_data->domain_vec_noise[i] == 0) { - if (coupling == COUPLING_BAL) { - h_frame_data->sbrNoiseFloorLevel[i * noNoiseBands] = - (FIXP_SGL)(((int)FDKreadBits(hBs, 5)) << envDataTableCompFactor); - } else { - h_frame_data->sbrNoiseFloorLevel[i * noNoiseBands] = - (FIXP_SGL)(int)FDKreadBits(hBs, 5); - } - - for (j = 1; j < noNoiseBands; j++) { - delta = DecodeHuffmanCW(hcb_noiseF, hBs); - h_frame_data->sbrNoiseFloorLevel[i * noNoiseBands + j] = - (FIXP_SGL)(delta << envDataTableCompFactor); - } - } else { - for (j = 0; j < noNoiseBands; j++) { - delta = DecodeHuffmanCW(hcb_noise, hBs); - h_frame_data->sbrNoiseFloorLevel[i * noNoiseBands + j] = - (FIXP_SGL)(delta << envDataTableCompFactor); - } - } - } -} - -/* ns = mapNsMode2ns[pvcMode-1][nsMode] */ -static const UCHAR mapNsMode2ns[2][2] = { - {16, 4}, /* pvcMode = 1 */ - {12, 3} /* pvcMode = 2 */ -}; - -static int sbrGetPvcEnvelope( - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA h_frame_data, /*!< handle to struct SBR_FRAME_DATA */ - HANDLE_FDK_BITSTREAM hBs, /*!< handle to struct BIT_BUF */ - const UINT flags, const UINT pvcMode) { - int divMode, nsMode; - int indepFlag = flags & SBRDEC_USAC_INDEP; - UCHAR *pvcID = h_frame_data->pvcID; - - divMode = FDKreadBits(hBs, PVC_DIVMODE_BITS); - nsMode = FDKreadBit(hBs); - FDK_ASSERT((pvcMode == 1) || (pvcMode == 2)); - h_frame_data->ns = mapNsMode2ns[pvcMode - 1][nsMode]; - - if (divMode <= 3) { - int i, k = 1, sum_length = 0, reuse_pcvID; - - /* special treatment for first time slot k=0 */ - indepFlag ? (reuse_pcvID = 0) : (reuse_pcvID = FDKreadBit(hBs)); - if (reuse_pcvID) { - pvcID[0] = hHeaderData->pvcIDprev; - } else { - pvcID[0] = FDKreadBits(hBs, PVC_PVCID_BITS); - } - - /* other time slots k>0 */ - for (i = 0; i < divMode; i++) { - int length, numBits = 4; - - if (sum_length >= 13) { - numBits = 1; - } else if (sum_length >= 11) { - numBits = 2; - } else if (sum_length >= 7) { - numBits = 3; - } - - length = FDKreadBits(hBs, numBits); - sum_length += length + 1; - if (sum_length >= PVC_NTIMESLOT) { - return 0; /* parse error */ - } - for (; length--; k++) { - pvcID[k] = pvcID[k - 1]; - } - pvcID[k++] = FDKreadBits(hBs, PVC_PVCID_BITS); - } - for (; k < 16; k++) { - pvcID[k] = pvcID[k - 1]; - } - } else { /* divMode >= 4 */ - int num_grid_info, fixed_length, grid_info, j, k = 0; - - divMode -= 4; - num_grid_info = 2 << divMode; - fixed_length = 8 >> divMode; - FDK_ASSERT(num_grid_info * fixed_length == PVC_NTIMESLOT); - - /* special treatment for first time slot k=0 */ - indepFlag ? (grid_info = 1) : (grid_info = FDKreadBit(hBs)); - if (grid_info) { - pvcID[k++] = FDKreadBits(hBs, PVC_PVCID_BITS); - } else { - pvcID[k++] = hHeaderData->pvcIDprev; - } - j = fixed_length - 1; - for (; j--; k++) { - pvcID[k] = pvcID[k - 1]; - } - num_grid_info--; - - /* other time slots k>0 */ - for (; num_grid_info--;) { - j = fixed_length; - grid_info = FDKreadBit(hBs); - if (grid_info) { - pvcID[k++] = FDKreadBits(hBs, PVC_PVCID_BITS); - j--; - } - for (; j--; k++) { - pvcID[k] = pvcID[k - 1]; - } - } - } - - hHeaderData->pvcIDprev = pvcID[PVC_NTIMESLOT - 1]; - - /* usage of PVC excludes inter-TES tool */ - h_frame_data->iTESactive = (UCHAR)0; - - return 1; -} -/*! - \brief Read envelope data from bitstream -*/ -static int sbrGetEnvelope( - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA h_frame_data, /*!< handle to struct SBR_FRAME_DATA */ - HANDLE_FDK_BITSTREAM hBs, /*!< handle to struct BIT_BUF */ - const UINT flags) { - int i, j; - UCHAR no_band[MAX_ENVELOPES]; - int delta = 0; - int offset = 0; - COUPLING_MODE coupling = h_frame_data->coupling; - int ampRes = hHeaderData->bs_info.ampResolution; - int nEnvelopes = h_frame_data->frameInfo.nEnvelopes; - int envDataTableCompFactor; - int start_bits, start_bits_balance; - Huffman hcb_t, hcb_f; - - h_frame_data->nScaleFactors = 0; - - if ((h_frame_data->frameInfo.frameClass == 0) && (nEnvelopes == 1)) { - if (flags & SBRDEC_ELD_GRID) - ampRes = h_frame_data->ampResolutionCurrentFrame; - else - ampRes = 0; - } - h_frame_data->ampResolutionCurrentFrame = ampRes; - - /* - Set number of bits for first value depending on amplitude resolution - */ - if (ampRes == 1) { - start_bits = 6; - start_bits_balance = 5; - } else { - start_bits = 7; - start_bits_balance = 6; - } - - /* - Calculate number of values for each envelope and alltogether - */ - for (i = 0; i < nEnvelopes; i++) { - no_band[i] = - hHeaderData->freqBandData.nSfb[h_frame_data->frameInfo.freqRes[i]]; - h_frame_data->nScaleFactors += no_band[i]; - } - if (h_frame_data->nScaleFactors > MAX_NUM_ENVELOPE_VALUES) return 0; - - /* - Select Huffman codebook depending on coupling mode and amplitude resolution - */ - if (coupling == COUPLING_BAL) { - envDataTableCompFactor = 1; - if (ampRes == 0) { - hcb_t = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance10T; - hcb_f = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance10F; - } else { - hcb_t = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance11T; - hcb_f = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvBalance11F; - } - } else { - envDataTableCompFactor = 0; - if (ampRes == 0) { - hcb_t = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel10T; - hcb_f = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel10F; - } else { - hcb_t = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel11T; - hcb_f = (Huffman)&FDK_sbrDecoder_sbr_huffBook_EnvLevel11F; - } - } - - h_frame_data->iTESactive = (UCHAR)0; /* disable inter-TES by default */ - /* - Now read raw envelope data - */ - for (j = 0, offset = 0; j < nEnvelopes; j++) { - if (h_frame_data->domain_vec[j] == 0) { - if (coupling == COUPLING_BAL) { - h_frame_data->iEnvelope[offset] = - (FIXP_SGL)(((int)FDKreadBits(hBs, start_bits_balance)) - << envDataTableCompFactor); - } else { - h_frame_data->iEnvelope[offset] = - (FIXP_SGL)(int)FDKreadBits(hBs, start_bits); - } - } - - for (i = (1 - h_frame_data->domain_vec[j]); i < no_band[j]; i++) { - if (h_frame_data->domain_vec[j] == 0) { - delta = DecodeHuffmanCW(hcb_f, hBs); - } else { - delta = DecodeHuffmanCW(hcb_t, hBs); - } - - h_frame_data->iEnvelope[offset + i] = - (FIXP_SGL)(delta << envDataTableCompFactor); - } - if ((flags & SBRDEC_SYNTAX_USAC) && (flags & SBRDEC_USAC_ITES)) { - int bs_temp_shape = FDKreadBit(hBs); - FDK_ASSERT(j < 8); - h_frame_data->iTESactive |= (UCHAR)(bs_temp_shape << j); - if (bs_temp_shape) { - h_frame_data->interTempShapeMode[j] = - FDKread2Bits(hBs); /* bs_inter_temp_shape_mode */ - } else { - h_frame_data->interTempShapeMode[j] = 0; - } - } - offset += no_band[j]; - } - -#if ENV_EXP_FRACT - /* Convert from int to scaled fract (ENV_EXP_FRACT bits for the fractional - * part) */ - for (i = 0; i < h_frame_data->nScaleFactors; i++) { - h_frame_data->iEnvelope[i] <<= ENV_EXP_FRACT; - } -#endif - - return 1; -} - -/***************************************************************************/ -/*! - \brief Generates frame info for FIXFIXonly frame class used for low delay - version - - \return zero for error, one for correct. - ****************************************************************************/ -static int generateFixFixOnly(FRAME_INFO *hSbrFrameInfo, int tranPosInternal, - int numberTimeSlots, const UINT flags) { - int nEnv, i, tranIdx; - const int *pTable; - - switch (numberTimeSlots) { - case 8: - pTable = FDK_sbrDecoder_envelopeTable_8[tranPosInternal]; - break; - case 15: - pTable = FDK_sbrDecoder_envelopeTable_15[tranPosInternal]; - break; - case 16: - pTable = FDK_sbrDecoder_envelopeTable_16[tranPosInternal]; - break; - default: - return 0; - } - - /* look number of envelopes in table */ - nEnv = pTable[0]; - /* look up envelope distribution in table */ - for (i = 1; i < nEnv; i++) hSbrFrameInfo->borders[i] = pTable[i + 2]; - /* open and close frame border */ - hSbrFrameInfo->borders[0] = 0; - hSbrFrameInfo->borders[nEnv] = numberTimeSlots; - hSbrFrameInfo->nEnvelopes = nEnv; - - /* transient idx */ - tranIdx = hSbrFrameInfo->tranEnv = pTable[1]; - - /* add noise floors */ - hSbrFrameInfo->bordersNoise[0] = 0; - hSbrFrameInfo->bordersNoise[1] = - hSbrFrameInfo->borders[tranIdx ? tranIdx : 1]; - hSbrFrameInfo->bordersNoise[2] = numberTimeSlots; - /* nEnv is always > 1, so nNoiseEnvelopes is always 2 (IEC 14496-3 4.6.19.3.2) - */ - hSbrFrameInfo->nNoiseEnvelopes = 2; - - return 1; -} - -/*! - \brief Extracts LowDelaySBR control data from the bitstream. - - \return zero for bitstream error, one for correct. -*/ -static int extractLowDelayGrid( - HANDLE_FDK_BITSTREAM hBitBuf, /*!< bitbuffer handle */ - HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_FRAME_DATA - h_frame_data, /*!< contains the FRAME_INFO struct to be filled */ - int timeSlots, const UINT flags) { - FRAME_INFO *pFrameInfo = &h_frame_data->frameInfo; - INT numberTimeSlots = hHeaderData->numberTimeSlots; - INT temp = 0, k; - - /* FIXFIXonly framing case */ - h_frame_data->frameInfo.frameClass = 0; - - /* get the transient position from the bitstream */ - switch (timeSlots) { - case 8: - /* 3bit transient position (temp={0;..;7}) */ - temp = FDKreadBits(hBitBuf, 3); - break; - - case 16: - case 15: - /* 4bit transient position (temp={0;..;15}) */ - temp = FDKreadBits(hBitBuf, 4); - break; - - default: - return 0; - } - - /* For "case 15" only*/ - if (temp >= timeSlots) { - return 0; - } - - /* calculate borders according to the transient position */ - if (!generateFixFixOnly(pFrameInfo, temp, numberTimeSlots, flags)) { - return 0; - } - - /* decode freq res: */ - for (k = 0; k < pFrameInfo->nEnvelopes; k++) { - pFrameInfo->freqRes[k] = - (UCHAR)FDKreadBits(hBitBuf, 1); /* f = F [1 bits] */ - } - - return 1; -} - -/*! - \brief Extract the PVC frame information (structure FRAME_INFO) from the - bitstream \return Zero for bitstream error, one for correct. -*/ -int extractPvcFrameInfo( - HANDLE_FDK_BITSTREAM hBs, /*!< bitbuffer handle */ - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA h_frame_data, /*!< pointer to memory where the - frame-info will be stored */ - HANDLE_SBR_PREV_FRAME_DATA h_prev_frame_data, /*!< pointer to memory where - the previous frame-info - will be stored */ - UCHAR pvc_mode_last, /**< PVC mode of last frame */ - const UINT flags) { - FRAME_INFO *pFrameInfo = &h_frame_data->frameInfo; - FRAME_INFO *pPrevFrameInfo = &h_prev_frame_data->prevFrameInfo; - int bs_var_len_hf, bs_noise_position; - bs_noise_position = FDKreadBits(hBs, 4); /* SBR_PVC_NOISEPOSITION_BITS 4 */ - bs_var_len_hf = FDKreadBit(hBs); - pFrameInfo->noisePosition = bs_noise_position; - pFrameInfo->tranEnv = -1; - - /* Init for bs_noise_position == 0 in case a parse error is found below. */ - pFrameInfo->nEnvelopes = 1; - pFrameInfo->nNoiseEnvelopes = 1; - pFrameInfo->freqRes[0] = 0; - - if (bs_var_len_hf) { /* 1 or 3 Bits */ - pFrameInfo->varLength = FDKreadBits(hBs, 2) + 1; - if (pFrameInfo->varLength > 3) { - pFrameInfo->varLength = - 0; /* assume bs_var_len_hf == 0 in case of error */ - return 0; /* reserved value -> parse error */ - } - } else { - pFrameInfo->varLength = 0; - } - - if (bs_noise_position) { - pFrameInfo->nEnvelopes = 2; - pFrameInfo->nNoiseEnvelopes = 2; - FDKmemclear(pFrameInfo->freqRes, sizeof(pFrameInfo->freqRes)); - } - - /* frame border calculation */ - if (hHeaderData->bs_info.pvc_mode > 0) { - /* See "7.5.1.4 HF adjustment of SBR envelope scalefactors" for reference. - */ - - FDK_ASSERT((pFrameInfo->nEnvelopes == 1) || (pFrameInfo->nEnvelopes == 2)); - - /* left timeborder-offset: use the timeborder of prev SBR frame */ - if (pPrevFrameInfo->nEnvelopes > 0) { - pFrameInfo->borders[0] = - pPrevFrameInfo->borders[pPrevFrameInfo->nEnvelopes] - PVC_NTIMESLOT; - FDK_ASSERT(pFrameInfo->borders[0] <= 3); - } else { - pFrameInfo->borders[0] = 0; - } - - /* right timeborder-offset: */ - pFrameInfo->borders[pFrameInfo->nEnvelopes] = 16 + pFrameInfo->varLength; - - if (pFrameInfo->nEnvelopes == 2) { - pFrameInfo->borders[1] = pFrameInfo->noisePosition; - } - - /* Calculation of PVC time borders t_EPVC */ - if (pvc_mode_last == 0) { - /* there was a legacy SBR frame before this frame => use bs_var_len' for - * first PVC timeslot */ - pFrameInfo->pvcBorders[0] = pFrameInfo->borders[0]; - } else { - pFrameInfo->pvcBorders[0] = 0; - } - if (pFrameInfo->nEnvelopes == 2) { - pFrameInfo->pvcBorders[1] = pFrameInfo->borders[1]; - } - pFrameInfo->pvcBorders[pFrameInfo->nEnvelopes] = 16; - - /* calculation of SBR noise-floor time-border vector: */ - for (INT i = 0; i <= pFrameInfo->nNoiseEnvelopes; i++) { - pFrameInfo->bordersNoise[i] = pFrameInfo->borders[i]; - } - - pFrameInfo->tranEnv = -1; /* tranEnv not used */ - } - return 1; -} - -/*! - \brief Extract the frame information (structure FRAME_INFO) from the - bitstream \return Zero for bitstream error, one for correct. -*/ -int extractFrameInfo( - HANDLE_FDK_BITSTREAM hBs, /*!< bitbuffer handle */ - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA h_frame_data, /*!< pointer to memory where the - frame-info will be stored */ - const UINT nrOfChannels, const UINT flags) { - FRAME_INFO *pFrameInfo = &h_frame_data->frameInfo; - int numberTimeSlots = hHeaderData->numberTimeSlots; - int pointer_bits = 0, nEnv = 0, b = 0, border, i, n = 0, k, p, aL, aR, nL, nR, - temp = 0, staticFreqRes; - UCHAR frameClass; - - if (flags & SBRDEC_ELD_GRID) { - /* CODEC_AACLD (LD+SBR) only uses the normal 0 Grid for non-transient Frames - * and the LowDelayGrid for transient Frames */ - frameClass = FDKreadBits(hBs, 1); /* frameClass = [1 bit] */ - if (frameClass == 1) { - /* if frameClass == 1, extract LowDelaySbrGrid, otherwise extract normal - * SBR-Grid for FIXIFX */ - /* extract the AACLD-Sbr-Grid */ - pFrameInfo->frameClass = frameClass; - int err = 1; - err = extractLowDelayGrid(hBs, hHeaderData, h_frame_data, numberTimeSlots, - flags); - return err; - } - } else { - frameClass = FDKreadBits(hBs, 2); /* frameClass = C [2 bits] */ - } - - switch (frameClass) { - case 0: - temp = FDKreadBits(hBs, 2); /* E [2 bits ] */ - nEnv = (int)(1 << temp); /* E -> e */ - - if ((flags & SBRDEC_ELD_GRID) && (nEnv == 1)) - h_frame_data->ampResolutionCurrentFrame = - FDKreadBits(hBs, 1); /* new ELD Syntax 07-11-09 */ - - staticFreqRes = FDKreadBits(hBs, 1); - - if (flags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) { - if (nEnv > MAX_ENVELOPES_USAC) return 0; - } else - - b = nEnv + 1; - switch (nEnv) { - case 1: - switch (numberTimeSlots) { - case 15: - FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info1_15, - sizeof(FRAME_INFO)); - break; - case 16: - FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info1_16, - sizeof(FRAME_INFO)); - break; - default: - FDK_ASSERT(0); - } - break; - case 2: - switch (numberTimeSlots) { - case 15: - FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info2_15, - sizeof(FRAME_INFO)); - break; - case 16: - FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info2_16, - sizeof(FRAME_INFO)); - break; - default: - FDK_ASSERT(0); - } - break; - case 4: - switch (numberTimeSlots) { - case 15: - FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info4_15, - sizeof(FRAME_INFO)); - break; - case 16: - FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info4_16, - sizeof(FRAME_INFO)); - break; - default: - FDK_ASSERT(0); - } - break; - case 8: -#if (MAX_ENVELOPES >= 8) - switch (numberTimeSlots) { - case 15: - FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info8_15, - sizeof(FRAME_INFO)); - break; - case 16: - FDKmemcpy(pFrameInfo, &FDK_sbrDecoder_sbr_frame_info8_16, - sizeof(FRAME_INFO)); - break; - default: - FDK_ASSERT(0); - } - break; -#else - return 0; -#endif - } - /* Apply correct freqRes (High is default) */ - if (!staticFreqRes) { - for (i = 0; i < nEnv; i++) pFrameInfo->freqRes[i] = 0; - } - - break; - case 1: - case 2: - temp = FDKreadBits(hBs, 2); /* A [2 bits] */ - - n = FDKreadBits(hBs, 2); /* n = N [2 bits] */ - - nEnv = n + 1; /* # envelopes */ - b = nEnv + 1; /* # borders */ - - break; - } - - switch (frameClass) { - case 1: - /* Decode borders: */ - pFrameInfo->borders[0] = 0; /* first border */ - border = temp + numberTimeSlots; /* A -> aR */ - i = b - 1; /* frame info index for last border */ - pFrameInfo->borders[i] = border; /* last border */ - - for (k = 0; k < n; k++) { - temp = FDKreadBits(hBs, 2); /* R [2 bits] */ - border -= (2 * temp + 2); /* R -> r */ - pFrameInfo->borders[--i] = border; - } - - /* Decode pointer: */ - pointer_bits = DFRACT_BITS - 1 - CountLeadingBits((FIXP_DBL)(n + 1)); - p = FDKreadBits(hBs, pointer_bits); /* p = P [pointer_bits bits] */ - - if (p > n + 1) return 0; - - pFrameInfo->tranEnv = p ? n + 2 - p : -1; - - /* Decode freq res: */ - for (k = n; k >= 0; k--) { - pFrameInfo->freqRes[k] = FDKreadBits(hBs, 1); /* f = F [1 bits] */ - } - - /* Calculate noise floor middle border: */ - if (p == 0 || p == 1) - pFrameInfo->bordersNoise[1] = pFrameInfo->borders[n]; - else - pFrameInfo->bordersNoise[1] = pFrameInfo->borders[pFrameInfo->tranEnv]; - - break; - - case 2: - /* Decode borders: */ - border = temp; /* A -> aL */ - pFrameInfo->borders[0] = border; /* first border */ - - for (k = 1; k <= n; k++) { - temp = FDKreadBits(hBs, 2); /* R [2 bits] */ - border += (2 * temp + 2); /* R -> r */ - pFrameInfo->borders[k] = border; - } - pFrameInfo->borders[k] = numberTimeSlots; /* last border */ - - /* Decode pointer: */ - pointer_bits = DFRACT_BITS - 1 - CountLeadingBits((FIXP_DBL)(n + 1)); - p = FDKreadBits(hBs, pointer_bits); /* p = P [pointer_bits bits] */ - if (p > n + 1) return 0; - - if (p == 0 || p == 1) - pFrameInfo->tranEnv = -1; - else - pFrameInfo->tranEnv = p - 1; - - /* Decode freq res: */ - for (k = 0; k <= n; k++) { - pFrameInfo->freqRes[k] = FDKreadBits(hBs, 1); /* f = F [1 bits] */ - } - - /* Calculate noise floor middle border: */ - switch (p) { - case 0: - pFrameInfo->bordersNoise[1] = pFrameInfo->borders[1]; - break; - case 1: - pFrameInfo->bordersNoise[1] = pFrameInfo->borders[n]; - break; - default: - pFrameInfo->bordersNoise[1] = - pFrameInfo->borders[pFrameInfo->tranEnv]; - break; - } - - break; - - case 3: - /* v_ctrlSignal = [frameClass,aL,aR,nL,nR,v_rL,v_rR,p,v_fLR]; */ - - aL = FDKreadBits(hBs, 2); /* AL [2 bits], AL -> aL */ - - aR = FDKreadBits(hBs, 2) + numberTimeSlots; /* AR [2 bits], AR -> aR */ - - nL = FDKreadBits(hBs, 2); /* nL = NL [2 bits] */ - - nR = FDKreadBits(hBs, 2); /* nR = NR [2 bits] */ - - /*------------------------------------------------------------------------- - Calculate help variables - --------------------------------------------------------------------------*/ - - /* general: */ - nEnv = nL + nR + 1; /* # envelopes */ - if (nEnv > MAX_ENVELOPES) return 0; - b = nEnv + 1; /* # borders */ - - /*------------------------------------------------------------------------- - Decode envelopes - --------------------------------------------------------------------------*/ - - /* L-borders: */ - border = aL; /* first border */ - pFrameInfo->borders[0] = border; - - for (k = 1; k <= nL; k++) { - temp = FDKreadBits(hBs, 2); /* R [2 bits] */ - border += (2 * temp + 2); /* R -> r */ - pFrameInfo->borders[k] = border; - } - - /* R-borders: */ - border = aR; /* last border */ - i = nEnv; - - pFrameInfo->borders[i] = border; - - for (k = 0; k < nR; k++) { - temp = FDKreadBits(hBs, 2); /* R [2 bits] */ - border -= (2 * temp + 2); /* R -> r */ - pFrameInfo->borders[--i] = border; - } - - /* decode pointer: */ - pointer_bits = - DFRACT_BITS - 1 - CountLeadingBits((FIXP_DBL)(nL + nR + 1)); - p = FDKreadBits(hBs, pointer_bits); /* p = P [pointer_bits bits] */ - - if (p > nL + nR + 1) return 0; - - pFrameInfo->tranEnv = p ? b - p : -1; - - /* decode freq res: */ - for (k = 0; k < nEnv; k++) { - pFrameInfo->freqRes[k] = FDKreadBits(hBs, 1); /* f = F [1 bits] */ - } - - /*------------------------------------------------------------------------- - Decode noise floors - --------------------------------------------------------------------------*/ - pFrameInfo->bordersNoise[0] = aL; - - if (nEnv == 1) { - /* 1 noise floor envelope: */ - pFrameInfo->bordersNoise[1] = aR; - } else { - /* 2 noise floor envelopes */ - if (p == 0 || p == 1) - pFrameInfo->bordersNoise[1] = pFrameInfo->borders[nEnv - 1]; - else - pFrameInfo->bordersNoise[1] = - pFrameInfo->borders[pFrameInfo->tranEnv]; - pFrameInfo->bordersNoise[2] = aR; - } - break; - } - - /* - Store number of envelopes, noise floor envelopes and frame class - */ - pFrameInfo->nEnvelopes = nEnv; - - if (nEnv == 1) - pFrameInfo->nNoiseEnvelopes = 1; - else - pFrameInfo->nNoiseEnvelopes = 2; - - pFrameInfo->frameClass = frameClass; - - if (pFrameInfo->frameClass == 2 || pFrameInfo->frameClass == 1) { - /* calculate noise floor first and last borders: */ - pFrameInfo->bordersNoise[0] = pFrameInfo->borders[0]; - pFrameInfo->bordersNoise[pFrameInfo->nNoiseEnvelopes] = - pFrameInfo->borders[nEnv]; - } - - return 1; -} - -/*! - \brief Check if the frameInfo vector has reasonable values. - \return Zero for error, one for correct -*/ -static int checkFrameInfo( - FRAME_INFO *pFrameInfo, /*!< pointer to frameInfo */ - int numberOfTimeSlots, /*!< QMF time slots per frame */ - int overlap, /*!< Amount of overlap QMF time slots */ - int timeStep) /*!< QMF slots to SBR slots step factor */ -{ - int maxPos, i, j; - int startPos; - int stopPos; - int tranEnv; - int startPosNoise; - int stopPosNoise; - int nEnvelopes = pFrameInfo->nEnvelopes; - int nNoiseEnvelopes = pFrameInfo->nNoiseEnvelopes; - - if (nEnvelopes < 1 || nEnvelopes > MAX_ENVELOPES) return 0; - - if (nNoiseEnvelopes > MAX_NOISE_ENVELOPES) return 0; - - startPos = pFrameInfo->borders[0]; - stopPos = pFrameInfo->borders[nEnvelopes]; - tranEnv = pFrameInfo->tranEnv; - startPosNoise = pFrameInfo->bordersNoise[0]; - stopPosNoise = pFrameInfo->bordersNoise[nNoiseEnvelopes]; - - if (overlap < 0 || overlap > (3 * (4))) { - return 0; - } - if (timeStep < 1 || timeStep > (4)) { - return 0; - } - maxPos = numberOfTimeSlots + (overlap / timeStep); - - /* Check that the start and stop positions of the frame are reasonable values. - */ - if ((startPos < 0) || (startPos >= stopPos)) return 0; - if (startPos > maxPos - numberOfTimeSlots) /* First env. must start in or - directly after the overlap - buffer */ - return 0; - if (stopPos < numberOfTimeSlots) /* One complete frame must be ready for - output after processing */ - return 0; - if (stopPos > maxPos) return 0; - - /* Check that the start border for every envelope is strictly later in time - */ - for (i = 0; i < nEnvelopes; i++) { - if (pFrameInfo->borders[i] >= pFrameInfo->borders[i + 1]) return 0; - } - - /* Check that the envelope to be shortened is actually among the envelopes */ - if (tranEnv > nEnvelopes) return 0; - - /* Check the noise borders */ - if (nEnvelopes == 1 && nNoiseEnvelopes > 1) return 0; - - if (startPos != startPosNoise || stopPos != stopPosNoise) return 0; - - /* Check that the start border for every noise-envelope is strictly later in - * time*/ - for (i = 0; i < nNoiseEnvelopes; i++) { - if (pFrameInfo->bordersNoise[i] >= pFrameInfo->bordersNoise[i + 1]) - return 0; - } - - /* Check that every noise border is the same as an envelope border*/ - for (i = 0; i < nNoiseEnvelopes; i++) { - startPosNoise = pFrameInfo->bordersNoise[i]; - - for (j = 0; j < nEnvelopes; j++) { - if (pFrameInfo->borders[j] == startPosNoise) break; - } - if (j == nEnvelopes) return 0; - } - - return 1; -} --- a/libSBRdec/src/env_extr.h +++ /dev/null @@ -1,415 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Envelope extraction prototypes -*/ - -#ifndef ENV_EXTR_H -#define ENV_EXTR_H - -#include "sbrdecoder.h" - -#include "FDK_bitstream.h" -#include "lpp_tran.h" - -#include "psdec.h" -#include "pvc_dec.h" - -#define ENV_EXP_FRACT 0 -/*!< Shift raw envelope data to support fractional numbers. - Can be set to 8 instead of 0 to enhance accuracy during concealment. - This is not required for conformance and #requantizeEnvelopeData() will - become more expensive. -*/ - -#define EXP_BITS 6 -/*!< Size of exponent-part of a pseudo float envelope value (should be at least - 6). The remaining bits in each word are used for the mantissa (should be at - least 10). This format is used in the arrays iEnvelope[] and - sbrNoiseFloorLevel[] in the FRAME_DATA struct which must fit in a certain part - of the output buffer (See buffer management in sbr_dec.cpp). Exponents and - mantissas could also be stored in separate arrays. Accessing the exponent or - the mantissa would be simplified and the masks #MASK_E resp. #MASK_M would - no longer be required. -*/ - -#define MASK_M \ - (((1 << (FRACT_BITS - EXP_BITS)) - 1) \ - << EXP_BITS) /*!< Mask for extracting the mantissa of a pseudo float \ - envelope value */ -#define MASK_E \ - ((1 << EXP_BITS) - 1) /*!< Mask for extracting the exponent of a pseudo \ - float envelope value */ - -#define SIGN_EXT \ - (((SCHAR)-1) ^ \ - MASK_E) /*!< a CHAR-constant with all bits above our sign-bit set */ -#define ROUNDING \ - ((FIXP_SGL)( \ - 1 << (EXP_BITS - 1))) /*!< 0.5-offset for rounding the mantissa of a \ - pseudo-float envelope value */ -#define NRG_EXP_OFFSET \ - 16 /*!< Will be added to the reference energy's exponent to prevent negative \ - numbers */ -#define NOISE_EXP_OFFSET \ - 38 /*!< Will be added to the noise level exponent to prevent negative \ - numbers */ - -#define ADD_HARMONICS_FLAGS_SIZE 2 /* ceil(MAX_FREQ_COEFFS/32) */ - -typedef enum { - HEADER_NOT_PRESENT, - HEADER_ERROR, - HEADER_OK, - HEADER_RESET -} SBR_HEADER_STATUS; - -typedef enum { - SBR_NOT_INITIALIZED = 0, - UPSAMPLING = 1, - SBR_HEADER = 2, - SBR_ACTIVE = 3 -} SBR_SYNC_STATE; - -typedef enum { COUPLING_OFF = 0, COUPLING_LEVEL, COUPLING_BAL } COUPLING_MODE; - -typedef struct { - UCHAR nSfb[2]; /*!< Number of SBR-bands for low and high freq-resolution */ - UCHAR nNfb; /*!< Actual number of noise bands to read from the bitstream*/ - UCHAR numMaster; /*!< Number of SBR-bands in v_k_master */ - UCHAR lowSubband; /*!< QMF-band where SBR frequency range starts */ - UCHAR highSubband; /*!< QMF-band where SBR frequency range ends */ - UCHAR ov_highSubband; /*!< if headerchange applies this value holds the old - highband value -> highband value of overlap area; - required for overlap in usac when headerchange - occurs between XVAR and VARX frame */ - UCHAR limiterBandTable[MAX_NUM_LIMITERS + 1]; /*!< Limiter band table. */ - UCHAR noLimiterBands; /*!< Number of limiter bands. */ - UCHAR nInvfBands; /*!< Number of bands for inverse filtering */ - UCHAR - *freqBandTable[2]; /*!< Pointers to freqBandTableLo and freqBandTableHi */ - UCHAR freqBandTableLo[MAX_FREQ_COEFFS / 2 + 1]; - /*!< Mapping of SBR bands to QMF bands for low frequency resolution */ - UCHAR freqBandTableHi[MAX_FREQ_COEFFS + 1]; - /*!< Mapping of SBR bands to QMF bands for high frequency resolution */ - UCHAR freqBandTableNoise[MAX_NOISE_COEFFS + 1]; - /*!< Mapping of SBR noise bands to QMF bands */ - UCHAR v_k_master[MAX_FREQ_COEFFS + 1]; - /*!< Master BandTable which freqBandTable is derived from */ -} FREQ_BAND_DATA; - -typedef FREQ_BAND_DATA *HANDLE_FREQ_BAND_DATA; - -#define SBRDEC_ELD_GRID 1 -#define SBRDEC_SYNTAX_SCAL 2 -#define SBRDEC_SYNTAX_USAC 4 -#define SBRDEC_SYNTAX_RSVD50 8 -#define SBRDEC_USAC_INDEP \ - 16 /* Flag indicating that USAC global independency flag is active. */ -#define SBRDEC_LOW_POWER \ - 32 /* Flag indicating that Low Power QMF mode shall be used. */ -#define SBRDEC_PS_DECODED \ - 64 /* Flag indicating that PS was decoded and rendered. */ -#define SBRDEC_QUAD_RATE \ - 128 /* Flag indicating that USAC SBR 4:1 is active. \ - */ -#define SBRDEC_USAC_HARMONICSBR \ - 256 /* Flag indicating that USAC HBE tool is active. */ -#define SBRDEC_LD_MPS_QMF \ - 512 /* Flag indicating that the LD-MPS QMF shall be used. */ -#define SBRDEC_USAC_ITES \ - 1024 /* Flag indicating that USAC inter TES tool is active. */ -#define SBRDEC_SYNTAX_DRM \ - 2048 /* Flag indicating that DRM30/DRM+ reverse syntax is being used. */ -#define SBRDEC_ELD_DOWNSCALE \ - 4096 /* Flag indicating that ELD downscaled mode decoding is used */ -#define SBRDEC_DOWNSAMPLE \ - 8192 /* Flag indicating that the downsampling mode is used. */ -#define SBRDEC_FLUSH 16384 /* Flag is used to flush all elements in use. */ -#define SBRDEC_FORCE_RESET \ - 32768 /* Flag is used to force a reset of all elements in use. */ -#define SBRDEC_SKIP_QMF_ANA \ - (1 << 21) /* Flag indicating that the input data is provided in the QMF \ - domain. */ -#define SBRDEC_SKIP_QMF_SYN \ - (1 << 22) /* Flag indicating that the output data is exported in the QMF \ - domain. */ - -#define SBRDEC_HDR_STAT_RESET 1 -#define SBRDEC_HDR_STAT_UPDATE 2 - -typedef struct { - UCHAR ampResolution; /*!< Amplitude resolution of envelope values (0: 1.5dB, - 1: 3dB) */ - UCHAR - xover_band; /*!< Start index in #v_k_master[] used for dynamic crossover - frequency */ - UCHAR sbr_preprocessing; /*!< SBR prewhitening flag. */ - UCHAR pvc_mode; /*!< Predictive vector coding mode */ -} SBR_HEADER_DATA_BS_INFO; - -typedef struct { - /* Changes in these variables causes a reset of the decoder */ - UCHAR startFreq; /*!< Index for SBR start frequency */ - UCHAR stopFreq; /*!< Index for SBR highest frequency */ - UCHAR freqScale; /*!< 0: linear scale, 1-3 logarithmic scales */ - UCHAR alterScale; /*!< Flag for coarser frequency resolution */ - UCHAR noise_bands; /*!< Noise bands per octave, read from bitstream*/ - - /* don't require reset */ - UCHAR limiterBands; /*!< Index for number of limiter bands per octave */ - UCHAR limiterGains; /*!< Index to select gain limit */ - UCHAR interpolFreq; /*!< Select gain calculation method (1: per QMF channel, - 0: per SBR band) */ - UCHAR smoothingLength; /*!< Smoothing of gains over time (0: on 1: off) */ - -} SBR_HEADER_DATA_BS; - -typedef struct { - SBR_SYNC_STATE - syncState; /*!< The current initialization status of the header */ - - UCHAR status; /*!< Flags field used for signaling a reset right before the - processing starts and an update from config (e.g. ASC). */ - UCHAR - frameErrorFlag; /*!< Frame data valid flag. CAUTION: This variable will be - overwritten by the flag stored in the element - structure. This is necessary because of the frame - delay. There it might happen that different slots use - the same header. */ - UCHAR numberTimeSlots; /*!< AAC: 16,15 */ - UCHAR numberOfAnalysisBands; /*!< Number of QMF analysis bands */ - UCHAR timeStep; /*!< Time resolution of SBR in QMF-slots */ - UINT - sbrProcSmplRate; /*!< SBR processing sampling frequency (!= - OutputSamplingRate) (always: CoreSamplingRate * - UpSamplingFactor; even in single rate mode) */ - - SBR_HEADER_DATA_BS bs_data; /*!< current SBR header. */ - SBR_HEADER_DATA_BS bs_dflt; /*!< Default sbr header. */ - SBR_HEADER_DATA_BS_INFO bs_info; /*!< SBR info. */ - - FREQ_BAND_DATA freqBandData; /*!< Pointer to struct #FREQ_BAND_DATA */ - UCHAR pvcIDprev; -} SBR_HEADER_DATA; - -typedef SBR_HEADER_DATA *HANDLE_SBR_HEADER_DATA; - -typedef struct { - UCHAR frameClass; /*!< Select grid type */ - UCHAR nEnvelopes; /*!< Number of envelopes */ - UCHAR borders[MAX_ENVELOPES + 1]; /*!< Envelope borders (in SBR-timeslots, - e.g. mp3PRO: 0..11) */ - UCHAR freqRes[MAX_ENVELOPES]; /*!< Frequency resolution for each envelope - (0=low, 1=high) */ - SCHAR tranEnv; /*!< Transient envelope, -1 if none */ - UCHAR nNoiseEnvelopes; /*!< Number of noise envelopes */ - UCHAR - bordersNoise[MAX_NOISE_ENVELOPES + 1]; /*!< borders of noise envelopes */ - UCHAR pvcBorders[MAX_PVC_ENVELOPES + 1]; - UCHAR noisePosition; - UCHAR varLength; -} FRAME_INFO; - -typedef struct { - FIXP_SGL sfb_nrg_prev[MAX_FREQ_COEFFS]; /*!< Previous envelope (required for - differential-coded values) */ - FIXP_SGL - prevNoiseLevel[MAX_NOISE_COEFFS]; /*!< Previous noise envelope (required - for differential-coded values) */ - COUPLING_MODE coupling; /*!< Stereo-mode of previous frame */ - INVF_MODE sbr_invf_mode[MAX_INVF_BANDS]; /*!< Previous strength of filtering - in transposer */ - UCHAR ampRes; /*!< Previous amplitude resolution (0: 1.5dB, 1: 3dB) */ - UCHAR stopPos; /*!< Position in time where last envelope ended */ - UCHAR frameErrorFlag; /*!< Previous frame status */ - UCHAR prevSbrPitchInBins; /*!< Previous frame pitchInBins */ - FRAME_INFO prevFrameInfo; -} SBR_PREV_FRAME_DATA; - -typedef SBR_PREV_FRAME_DATA *HANDLE_SBR_PREV_FRAME_DATA; - -typedef struct { - int nScaleFactors; /*!< total number of scalefactors in frame */ - - FRAME_INFO frameInfo; /*!< time grid for current frame */ - UCHAR domain_vec[MAX_ENVELOPES]; /*!< Bitfield containing direction of - delta-coding for each envelope - (0:frequency, 1:time) */ - UCHAR domain_vec_noise - [MAX_NOISE_ENVELOPES]; /*!< Same as above, but for noise envelopes */ - - INVF_MODE - sbr_invf_mode[MAX_INVF_BANDS]; /*!< Strength of filtering in transposer */ - COUPLING_MODE coupling; /*!< Stereo-mode */ - int ampResolutionCurrentFrame; /*!< Amplitude resolution of envelope values - (0: 1.5dB, 1: 3dB) */ - - ULONG addHarmonics[ADD_HARMONICS_FLAGS_SIZE]; /*!< Flags for synthetic sine - addition (aligned to MSB) */ - - FIXP_SGL iEnvelope[MAX_NUM_ENVELOPE_VALUES]; /*!< Envelope data */ - FIXP_SGL sbrNoiseFloorLevel[MAX_NUM_NOISE_VALUES]; /*!< Noise envelope data */ - UCHAR iTESactive; /*!< One flag for each envelope to enable USAC inter-TES */ - UCHAR - interTempShapeMode[MAX_ENVELOPES]; /*!< USAC inter-TES: - bs_inter_temp_shape_mode[ch][env] - value */ - UCHAR pvcID[PVC_NTIMESLOT]; /*!< One PVC ID value for each time slot */ - UCHAR ns; - UCHAR sinusoidal_position; - - UCHAR sbrPatchingMode; - UCHAR sbrOversamplingFlag; - UCHAR sbrPitchInBins; -} SBR_FRAME_DATA; - -typedef SBR_FRAME_DATA *HANDLE_SBR_FRAME_DATA; - -/*! -\brief Maps sampling frequencies to frequencies for which setup tables are -available - -Maps arbitary sampling frequency to nearest neighbors for which setup tables -are available (e.g. 25600 -> 24000). -Used for startFreq calculation. -The mapping is defined in 14496-3 (4.6.18.2.6), fs(SBR), and table 4.82 - -\return mapped sampling frequency -*/ -UINT sbrdec_mapToStdSampleRate(UINT fs, - UINT isUsac); /*!< Output sampling frequency */ - -void initSbrPrevFrameData(HANDLE_SBR_PREV_FRAME_DATA h_prev_data, - int timeSlots); - -int sbrGetChannelElement(HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_FRAME_DATA hFrameDataLeft, - HANDLE_SBR_FRAME_DATA hFrameDataRight, - HANDLE_SBR_PREV_FRAME_DATA hFrameDataLeftPrev, - UCHAR pvc_mode_last, HANDLE_FDK_BITSTREAM hBitBuf, - HANDLE_PS_DEC hParametricStereoDec, const UINT flags, - const int overlap); - -SBR_HEADER_STATUS -sbrGetHeaderData(HANDLE_SBR_HEADER_DATA headerData, - HANDLE_FDK_BITSTREAM hBitBuf, const UINT flags, - const int fIsSbrData, const UCHAR configMode); - -/*! - \brief Initialize SBR header data - - Copy default values to the header data struct and patch some entries - depending on the core codec. -*/ -SBR_ERROR -initHeaderData(HANDLE_SBR_HEADER_DATA hHeaderData, const int sampleRateIn, - const int sampleRateOut, const INT downscaleFactor, - const int samplesPerFrame, const UINT flags, - const int setDefaultHdr); -#endif - -/* Convert headroom bits to exponent */ -#define SCALE2EXP(s) (15 - (s)) -#define EXP2SCALE(e) (15 - (e)) --- a/libSBRdec/src/hbe.cpp +++ /dev/null @@ -1,2202 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Fast FFT routines prototypes - \author Fabian Haussel -*/ - -#include "hbe.h" -#include "qmf.h" -#include "env_extr.h" - -#define HBE_MAX_QMF_BANDS (40) - -#define HBE_MAX_OUT_SLOTS (11) - -#define QMF_WIN_LEN \ - (12 + 6 - 4 - 1) /* 6 subband slots extra delay to align with HQ - 4 slots \ - to compensate for critical sampling delay - 1 slot to \ - align critical sampling exactly (w additional time \ - domain delay)*/ - -#ifndef PI -#define PI 3.14159265358979323846 -#endif - -static const int xProducts[MAX_STRETCH_HBE - 1] = { - 1, 1, 1}; /* Cross products on(1)/off(0) for T=2,3,4. */ -static const int startSubband2kL[33] = { - 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, - 6, 8, 8, 8, 8, 8, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12}; - -static const int pmin = 12; - -static const FIXP_DBL hintReal_F[4][3] = { - {FL2FXCONST_DBL(0.39840335f), FL2FXCONST_DBL(0.39840335f), - FL2FXCONST_DBL(-0.39840335f)}, - {FL2FXCONST_DBL(0.39840335f), FL2FXCONST_DBL(-0.39840335f), - FL2FXCONST_DBL(-0.39840335f)}, - {FL2FXCONST_DBL(-0.39840335f), FL2FXCONST_DBL(-0.39840335f), - FL2FXCONST_DBL(0.39840335f)}, - {FL2FXCONST_DBL(-0.39840335f), FL2FXCONST_DBL(0.39840335f), - FL2FXCONST_DBL(0.39840335f)}}; - -static const FIXP_DBL factors[4] = { - FL2FXCONST_DBL(0.39840335f), FL2FXCONST_DBL(-0.39840335f), - FL2FXCONST_DBL(-0.39840335f), FL2FXCONST_DBL(0.39840335f)}; - -#define PSCALE 32 - -static const FIXP_DBL p_F[128] = {FL2FXCONST_DBL(0.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(1.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(2.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(3.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(4.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(5.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(6.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(7.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(8.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(9.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(10.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(11.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(12.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(13.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(14.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(15.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(16.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(17.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(18.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(19.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(20.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(21.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(22.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(23.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(24.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(25.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(26.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(27.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(28.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(29.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(30.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(31.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(32.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(33.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(34.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(35.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(36.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(37.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(38.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(39.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(40.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(41.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(42.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(43.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(44.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(45.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(46.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(47.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(48.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(49.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(50.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(51.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(52.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(53.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(54.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(55.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(56.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(57.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(58.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(59.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(60.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(61.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(62.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(63.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(64.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(65.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(66.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(67.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(68.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(69.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(70.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(71.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(72.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(73.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(74.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(75.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(76.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(77.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(78.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(79.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(80.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(81.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(82.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(83.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(84.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(85.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(86.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(87.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(88.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(89.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(90.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(91.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(92.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(93.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(94.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(95.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(96.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(97.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(98.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(99.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(100.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(101.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(102.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(103.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(104.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(105.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(106.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(107.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(108.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(109.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(110.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(111.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(112.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(113.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(114.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(115.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(116.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(117.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(118.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(119.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(120.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(121.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(122.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(123.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(124.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(125.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(126.f / (PSCALE * 12.f)), - FL2FXCONST_DBL(127.f / (PSCALE * 12.f))}; - -static const FIXP_DBL band_F[64] = { - FL2FXCONST_DBL((0.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((1.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((2.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((3.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((4.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((5.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((6.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((7.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((8.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((9.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((10.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((11.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((12.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((13.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((14.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((15.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((16.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((17.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((18.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((19.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((20.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((21.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((22.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((23.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((24.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((25.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((26.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((27.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((28.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((29.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((30.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((31.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((32.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((33.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((34.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((35.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((36.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((37.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((38.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((39.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((40.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((41.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((42.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((43.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((44.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((45.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((46.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((47.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((48.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((49.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((50.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((51.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((52.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((53.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((54.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((55.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((56.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((57.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((58.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((59.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((60.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((61.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((62.f * 2.f + 1) / (PSCALE << 2)), - FL2FXCONST_DBL((63.f * 2.f + 1) / (PSCALE << 2))}; - -static const FIXP_DBL tr_str[3] = {FL2FXCONST_DBL(1.f / 4.f), - FL2FXCONST_DBL(2.f / 4.f), - FL2FXCONST_DBL(3.f / 4.f)}; - -static const FIXP_DBL stretchfac[3] = {FL2FXCONST_DBL(1.f / 2.f), - FL2FXCONST_DBL(1.f / 3.f), - FL2FXCONST_DBL(1.f / 4.f)}; - -static const FIXP_DBL cos_F[64] = { - 26353028, -79043208, 131685776, -184244944, 236697216, -289006912, - 341142496, -393072608, 444773984, -496191392, 547325824, -598114752, - 648559104, -698597248, 748230016, -797411904, 846083200, -894275136, - 941928192, -989013760, 1035474624, -1081340672, 1126555136, -1171063296, - 1214893696, -1257992192, 1300332544, -1341889408, 1382612736, -1422503808, - 1461586944, -1499741440, 1537039104, -1573364864, 1608743808, -1643196672, - 1676617344, -1709028992, 1740450560, -1770784896, 1800089472, -1828273536, - 1855357440, -1881356288, 1906190080, -1929876608, 1952428928, -1973777664, - 1993962880, -2012922240, 2030670208, -2047216000, 2062508288, -2076559488, - 2089376128, -2100932224, 2111196800, -2120214784, 2127953792, -2134394368, - 2139565056, -2143444864, 2146026624, -2147321856}; - -static const FIXP_DBL twiddle[121] = {1073741824, - 1071442860, - 1064555814, - 1053110176, - 1037154959, - 1016758484, - 992008094, - 963009773, - 929887697, - 892783698, - 851856663, - 807281846, - 759250125, - 707967178, - 653652607, - 596538995, - 536870912, - 474903865, - 410903207, - 345142998, - 277904834, - 209476638, - 140151432, - 70226075, - 0, - -70226075, - -140151432, - -209476638, - -277904834, - -345142998, - -410903207, - -474903865, - -536870912, - -596538995, - -653652607, - -707967178, - -759250125, - -807281846, - -851856663, - -892783698, - -929887697, - -963009773, - -992008094, - -1016758484, - -1037154959, - -1053110176, - -1064555814, - -1071442860, - -1073741824, - -1071442860, - -1064555814, - -1053110176, - -1037154959, - -1016758484, - -992008094, - -963009773, - -929887697, - -892783698, - -851856663, - -807281846, - -759250125, - -707967178, - -653652607, - -596538995, - -536870912, - -474903865, - -410903207, - -345142998, - -277904834, - -209476638, - -140151432, - -70226075, - 0, - 70226075, - 140151432, - 209476638, - 277904834, - 345142998, - 410903207, - 474903865, - 536870912, - 596538995, - 653652607, - 707967178, - 759250125, - 807281846, - 851856663, - 892783698, - 929887697, - 963009773, - 992008094, - 1016758484, - 1037154959, - 1053110176, - 1064555814, - 1071442860, - 1073741824, - 1071442860, - 1064555814, - 1053110176, - 1037154959, - 1016758484, - 992008094, - 963009773, - 929887697, - 892783698, - 851856663, - 807281846, - 759250125, - 707967178, - 653652607, - 596538995, - 536870912, - 474903865, - 410903207, - 345142998, - 277904834, - 209476638, - 140151432, - 70226075, - 0}; - -#if FIXP_QTW == FIXP_SGL -#define HTW(x) (x) -#else -#define HTW(x) FX_DBL2FX_QTW(FX_SGL2FX_DBL((const FIXP_SGL)x)) -#endif - -static const FIXP_QTW post_twiddle_cos_8[8] = { - HTW(-1606), HTW(4756), HTW(-7723), HTW(10394), - HTW(-12665), HTW(14449), HTW(-15679), HTW(16305)}; - -static const FIXP_QTW post_twiddle_cos_16[16] = { - HTW(-804), HTW(2404), HTW(-3981), HTW(5520), HTW(-7005), HTW(8423), - HTW(-9760), HTW(11003), HTW(-12140), HTW(13160), HTW(-14053), HTW(14811), - HTW(-15426), HTW(15893), HTW(-16207), HTW(16364)}; - -static const FIXP_QTW post_twiddle_cos_24[24] = { - HTW(-536), HTW(1606), HTW(-2669), HTW(3720), HTW(-4756), HTW(5771), - HTW(-6762), HTW(7723), HTW(-8652), HTW(9543), HTW(-10394), HTW(11200), - HTW(-11958), HTW(12665), HTW(-13318), HTW(13913), HTW(-14449), HTW(14924), - HTW(-15334), HTW(15679), HTW(-15956), HTW(16165), HTW(-16305), HTW(16375)}; - -static const FIXP_QTW post_twiddle_cos_32[32] = { - HTW(-402), HTW(1205), HTW(-2006), HTW(2801), HTW(-3590), HTW(4370), - HTW(-5139), HTW(5897), HTW(-6639), HTW(7366), HTW(-8076), HTW(8765), - HTW(-9434), HTW(10080), HTW(-10702), HTW(11297), HTW(-11866), HTW(12406), - HTW(-12916), HTW(13395), HTW(-13842), HTW(14256), HTW(-14635), HTW(14978), - HTW(-15286), HTW(15557), HTW(-15791), HTW(15986), HTW(-16143), HTW(16261), - HTW(-16340), HTW(16379)}; - -static const FIXP_QTW post_twiddle_cos_40[40] = { - HTW(-322), HTW(965), HTW(-1606), HTW(2245), HTW(-2880), HTW(3511), - HTW(-4137), HTW(4756), HTW(-5368), HTW(5971), HTW(-6566), HTW(7150), - HTW(-7723), HTW(8285), HTW(-8833), HTW(9368), HTW(-9889), HTW(10394), - HTW(-10883), HTW(11356), HTW(-11810), HTW(12247), HTW(-12665), HTW(13063), - HTW(-13441), HTW(13799), HTW(-14135), HTW(14449), HTW(-14741), HTW(15011), - HTW(-15257), HTW(15480), HTW(-15679), HTW(15853), HTW(-16003), HTW(16129), - HTW(-16229), HTW(16305), HTW(-16356), HTW(16381)}; - -static const FIXP_QTW post_twiddle_sin_8[8] = { - HTW(16305), HTW(-15679), HTW(14449), HTW(-12665), - HTW(10394), HTW(-7723), HTW(4756), HTW(-1606)}; - -static const FIXP_QTW post_twiddle_sin_16[16] = { - HTW(16364), HTW(-16207), HTW(15893), HTW(-15426), HTW(14811), HTW(-14053), - HTW(13160), HTW(-12140), HTW(11003), HTW(-9760), HTW(8423), HTW(-7005), - HTW(5520), HTW(-3981), HTW(2404), HTW(-804)}; - -static const FIXP_QTW post_twiddle_sin_24[24] = { - HTW(16375), HTW(-16305), HTW(16165), HTW(-15956), HTW(15679), HTW(-15334), - HTW(14924), HTW(-14449), HTW(13913), HTW(-13318), HTW(12665), HTW(-11958), - HTW(11200), HTW(-10394), HTW(9543), HTW(-8652), HTW(7723), HTW(-6762), - HTW(5771), HTW(-4756), HTW(3720), HTW(-2669), HTW(1606), HTW(-536)}; - -static const FIXP_QTW post_twiddle_sin_32[32] = { - HTW(16379), HTW(-16340), HTW(16261), HTW(-16143), HTW(15986), HTW(-15791), - HTW(15557), HTW(-15286), HTW(14978), HTW(-14635), HTW(14256), HTW(-13842), - HTW(13395), HTW(-12916), HTW(12406), HTW(-11866), HTW(11297), HTW(-10702), - HTW(10080), HTW(-9434), HTW(8765), HTW(-8076), HTW(7366), HTW(-6639), - HTW(5897), HTW(-5139), HTW(4370), HTW(-3590), HTW(2801), HTW(-2006), - HTW(1205), HTW(-402)}; - -static const FIXP_QTW post_twiddle_sin_40[40] = { - HTW(16381), HTW(-16356), HTW(16305), HTW(-16229), HTW(16129), HTW(-16003), - HTW(15853), HTW(-15679), HTW(15480), HTW(-15257), HTW(15011), HTW(-14741), - HTW(14449), HTW(-14135), HTW(13799), HTW(-13441), HTW(13063), HTW(-12665), - HTW(12247), HTW(-11810), HTW(11356), HTW(-10883), HTW(10394), HTW(-9889), - HTW(9368), HTW(-8833), HTW(8285), HTW(-7723), HTW(7150), HTW(-6566), - HTW(5971), HTW(-5368), HTW(4756), HTW(-4137), HTW(3511), HTW(-2880), - HTW(2245), HTW(-1606), HTW(965), HTW(-322)}; - -static const FIXP_DBL preModCos[32] = { - -749875776, 786681536, 711263552, -821592064, -670937792, 854523392, - 628995648, -885396032, -585538240, 914135680, 540670208, -940673088, - -494499680, 964944384, 447137824, -986891008, -398698816, 1006460096, - 349299264, -1023604544, -299058240, 1038283072, 248096752, -1050460288, - -196537584, 1060106816, 144504928, -1067199488, -92124160, 1071721152, - 39521456, -1073660992}; - -static const FIXP_DBL preModSin[32] = { - 768510144, 730789760, -804379072, -691308864, 838310208, 650162560, - -870221760, -607449920, 900036928, 563273856, -927683776, -517740896, - 953095808, 470960608, -976211712, -423045728, 996975808, 374111712, - -1015338112, -324276416, 1031254400, 273659904, -1044686336, -222384144, - 1055601472, 170572640, -1063973632, -118350192, 1069782528, 65842640, - -1073014208, -13176464}; - -/* The cube root function */ -/***************************************************************************** - - functionname: invCubeRootNorm2 - description: delivers 1/cuberoot(op) in Q1.31 format and modified exponent - -*****************************************************************************/ -#define CUBE_ROOT_BITS 7 -#define CUBE_ROOT_VALUES (128 + 2) -#define CUBE_ROOT_BITS_MASK 0x7f -#define CUBE_ROOT_FRACT_BITS_MASK 0x007FFFFF -/* Inverse cube root table for operands running from 0.5 to 1.0 */ -/* (INT) (1.0/cuberoot((op))); */ -/* Implicit exponent is 1. */ - -LNK_SECTION_CONSTDATA -static const FIXP_DBL invCubeRootTab[CUBE_ROOT_VALUES] = { - (0x50a28be6), (0x506d1172), (0x503823c4), (0x5003c05a), (0x4fcfe4c0), - (0x4f9c8e92), (0x4f69bb7d), (0x4f37693b), (0x4f059594), (0x4ed43e5f), - (0x4ea36181), (0x4e72fcea), (0x4e430e98), (0x4e139495), (0x4de48cf5), - (0x4db5f5db), (0x4d87cd73), (0x4d5a11f2), (0x4d2cc19c), (0x4cffdabb), - (0x4cd35ba4), (0x4ca742b7), (0x4c7b8e5c), (0x4c503d05), (0x4c254d2a), - (0x4bfabd50), (0x4bd08c00), (0x4ba6b7cd), (0x4b7d3f53), (0x4b542134), - (0x4b2b5c18), (0x4b02eeb1), (0x4adad7b8), (0x4ab315ea), (0x4a8ba80d), - (0x4a648cec), (0x4a3dc35b), (0x4a174a30), (0x49f1204a), (0x49cb448d), - (0x49a5b5e2), (0x49807339), (0x495b7b86), (0x4936cdc2), (0x491268ec), - (0x48ee4c08), (0x48ca761f), (0x48a6e63e), (0x48839b76), (0x486094de), - (0x483dd190), (0x481b50ad), (0x47f91156), (0x47d712b3), (0x47b553f0), - (0x4793d43c), (0x477292c9), (0x47518ece), (0x4730c785), (0x47103c2d), - (0x46efec06), (0x46cfd655), (0x46affa61), (0x46905777), (0x4670ece4), - (0x4651b9f9), (0x4632be0b), (0x4613f871), (0x45f56885), (0x45d70da5), - (0x45b8e72f), (0x459af487), (0x457d3511), (0x455fa835), (0x45424d5d), - (0x452523f6), (0x45082b6e), (0x44eb6337), (0x44cecac5), (0x44b2618d), - (0x44962708), (0x447a1ab1), (0x445e3c02), (0x44428a7c), (0x4427059e), - (0x440bacec), (0x43f07fe9), (0x43d57e1c), (0x43baa70e), (0x439ffa48), - (0x43857757), (0x436b1dc8), (0x4350ed2b), (0x4336e511), (0x431d050c), - (0x43034cb2), (0x42e9bb98), (0x42d05156), (0x42b70d85), (0x429defc0), - (0x4284f7a2), (0x426c24cb), (0x425376d8), (0x423aed6a), (0x42228823), - (0x420a46a6), (0x41f22898), (0x41da2d9f), (0x41c25561), (0x41aa9f86), - (0x41930bba), (0x417b99a5), (0x416448f5), (0x414d1956), (0x41360a76), - (0x411f1c06), (0x41084db5), (0x40f19f35), (0x40db1039), (0x40c4a074), - (0x40ae4f9b), (0x40981d64), (0x40820985), (0x406c13b6), (0x40563bb1), - (0x4040812e), (0x402ae3e7), (0x40156399), (0x40000000), (0x3FEAB8D9)}; -/* n.a. */ -static const FIXP_DBL invCubeRootCorrection[3] = {0x40000000, 0x50A28BE6, - 0x6597FA95}; - -/***************************************************************************** - * \brief calculate 1.0/cube_root(op), op contains mantissa and exponent - * \param op_m: (i) mantissa of operand, must not be zero (0x0000.0000) or - * negative - * \param op_e: (i) pointer to the exponent of the operand (must be initialized) - * and .. (o) pointer to the exponent of the result - * \return: (o) mantissa of the result - * \description: - * This routine calculates the cube root of the input operand, that is - * given with its mantissa in Q31 format (FIXP_DBL) and its exponent (INT). - * The resulting mantissa is returned in format Q31. The exponent (*op_e) - * is modified accordingly. It is not assured, that the result is fully - * left-aligned but assumed to have not more than 2 bits headroom. There is one - * macro to activate the use of this algorithm: FUNCTION_invCubeRootNorm2 By - * means of activating the macro INVCUBEROOTNORM2_LINEAR_INTERPOLATE_HQ, a - * slightly higher precision is reachable (by default, not active). For DEBUG - * purpose only: a FDK_ASSERT macro validates, if the input mantissa is greater - * zero. - * - */ -static -#ifdef __arm__ - FIXP_DBL FDK_FORCEINLINE - invCubeRootNorm2(FIXP_DBL op_m, INT* op_e) -#else - FIXP_DBL - invCubeRootNorm2(FIXP_DBL op_m, INT* op_e) -#endif -{ - FDK_ASSERT(op_m > FIXP_DBL(0)); - - /* normalize input, calculate shift value */ - INT exponent = (INT)fNormz(op_m) - 1; - op_m <<= exponent; - - INT index = (INT)(op_m >> (DFRACT_BITS - 1 - (CUBE_ROOT_BITS + 1))) & - CUBE_ROOT_BITS_MASK; - FIXP_DBL fract = (FIXP_DBL)(((INT)op_m & CUBE_ROOT_FRACT_BITS_MASK) - << (CUBE_ROOT_BITS + 1)); - FIXP_DBL diff = invCubeRootTab[index + 1] - invCubeRootTab[index]; - op_m = fMultAddDiv2(invCubeRootTab[index], diff << 1, fract); -#if defined(INVCUBEROOTNORM2_LINEAR_INTERPOLATE_HQ) - /* reg1 = t[i] + (t[i+1]-t[i])*fract ... already computed ... + - * (1-fract)fract*(t[i+2]-t[i+1])/2 */ - if (fract != (FIXP_DBL)0) { - /* fract = fract * (1 - fract) */ - fract = fMultDiv2(fract, (FIXP_DBL)((LONG)0x80000000 - (LONG)fract)) << 1; - diff = diff - (invCubeRootTab[index + 2] - invCubeRootTab[index + 1]); - op_m = fMultAddDiv2(op_m, fract, diff); - } -#endif /* INVCUBEROOTNORM2_LINEAR_INTERPOLATE_HQ */ - - /* calculate the output exponent = input * exp/3 = cubicroot(m)*2^(exp/3) - * where 2^(exp/3) = 2^k'*2 or 2^k'*2^(1/3) or 2^k'*2^(2/3) */ - exponent = exponent - *op_e + 3; - INT shift_tmp = - ((INT)fMultDiv2((FIXP_SGL)fAbs(exponent), (FIXP_SGL)0x5556)) >> 16; - if (exponent < 0) { - shift_tmp = -shift_tmp; - } - INT rem = exponent - 3 * shift_tmp; - if (rem < 0) { - rem += 3; - shift_tmp--; - } - - *op_e = shift_tmp; - op_m = fMultDiv2(op_m, invCubeRootCorrection[rem]) << 2; - - return (op_m); -} - - /***************************************************************************** - - functionname: invFourthRootNorm2 - description: delivers 1/FourthRoot(op) in Q1.31 format and modified - exponent - - *****************************************************************************/ - -#define FOURTHROOT_BITS 7 -#define FOURTHROOT_VALUES (128 + 2) -#define FOURTHROOT_BITS_MASK 0x7f -#define FOURTHROOT_FRACT_BITS_MASK 0x007FFFFF - -LNK_SECTION_CONSTDATA -static const FIXP_DBL invFourthRootTab[FOURTHROOT_VALUES] = { - (0x4c1bf829), (0x4bf61977), (0x4bd09843), (0x4bab72ef), (0x4b86a7eb), - (0x4b6235ac), (0x4b3e1ab6), (0x4b1a5592), (0x4af6e4d4), (0x4ad3c718), - (0x4ab0fb03), (0x4a8e7f42), (0x4a6c5288), (0x4a4a7393), (0x4a28e126), - (0x4a079a0c), (0x49e69d16), (0x49c5e91f), (0x49a57d04), (0x498557ac), - (0x49657802), (0x4945dcf9), (0x49268588), (0x490770ac), (0x48e89d6a), - (0x48ca0ac9), (0x48abb7d6), (0x488da3a6), (0x486fcd4f), (0x485233ed), - (0x4834d6a3), (0x4817b496), (0x47faccf0), (0x47de1ee0), (0x47c1a999), - (0x47a56c51), (0x47896643), (0x476d96af), (0x4751fcd6), (0x473697ff), - (0x471b6773), (0x47006a81), (0x46e5a079), (0x46cb08ae), (0x46b0a279), - (0x46966d34), (0x467c683d), (0x466292f4), (0x4648ecbc), (0x462f74fe), - (0x46162b20), (0x45fd0e91), (0x45e41ebe), (0x45cb5b19), (0x45b2c315), - (0x459a562a), (0x458213cf), (0x4569fb81), (0x45520cbc), (0x453a4701), - (0x4522a9d1), (0x450b34b0), (0x44f3e726), (0x44dcc0ba), (0x44c5c0f7), - (0x44aee768), (0x4498339e), (0x4481a527), (0x446b3b96), (0x4454f67e), - (0x443ed576), (0x4428d815), (0x4412fdf3), (0x43fd46ad), (0x43e7b1de), - (0x43d23f23), (0x43bcee1e), (0x43a7be6f), (0x4392afb8), (0x437dc19d), - (0x4368f3c5), (0x435445d6), (0x433fb779), (0x432b4856), (0x4316f81a), - (0x4302c66f), (0x42eeb305), (0x42dabd8a), (0x42c6e5ad), (0x42b32b21), - (0x429f8d96), (0x428c0cc2), (0x4278a859), (0x42656010), (0x4252339e), - (0x423f22bc), (0x422c2d23), (0x4219528b), (0x420692b2), (0x41f3ed51), - (0x41e16228), (0x41cef0f2), (0x41bc9971), (0x41aa5b62), (0x41983687), - (0x41862aa2), (0x41743775), (0x41625cc3), (0x41509a50), (0x413eefe2), - (0x412d5d3e), (0x411be22b), (0x410a7e70), (0x40f931d5), (0x40e7fc23), - (0x40d6dd24), (0x40c5d4a2), (0x40b4e268), (0x40a40642), (0x40933ffc), - (0x40828f64), (0x4071f447), (0x40616e73), (0x4050fdb9), (0x4040a1e6), - (0x40305acc), (0x4020283c), (0x40100a08), (0x40000000), (0x3ff009f9), -}; - -static const FIXP_DBL invFourthRootCorrection[4] = {0x40000000, 0x4C1BF829, - 0x5A82799A, 0x6BA27E65}; - -/* The fourth root function */ -/***************************************************************************** - * \brief calculate 1.0/fourth_root(op), op contains mantissa and exponent - * \param op_m: (i) mantissa of operand, must not be zero (0x0000.0000) or - * negative - * \param op_e: (i) pointer to the exponent of the operand (must be initialized) - * and .. (o) pointer to the exponent of the result - * \return: (o) mantissa of the result - * \description: - * This routine calculates the cube root of the input operand, that is - * given with its mantissa in Q31 format (FIXP_DBL) and its exponent (INT). - * The resulting mantissa is returned in format Q31. The exponent (*op_e) - * is modified accordingly. It is not assured, that the result is fully - * left-aligned but assumed to have not more than 2 bits headroom. There is one - * macro to activate the use of this algorithm: FUNCTION_invFourthRootNorm2 By - * means of activating the macro INVFOURTHROOTNORM2_LINEAR_INTERPOLATE_HQ, a - * slightly higher precision is reachable (by default, not active). For DEBUG - * purpose only: a FDK_ASSERT macro validates, if the input mantissa is greater - * zero. - * - */ - -/* #define INVFOURTHROOTNORM2_LINEAR_INTERPOLATE_HQ */ - -static -#ifdef __arm__ - FIXP_DBL FDK_FORCEINLINE - invFourthRootNorm2(FIXP_DBL op_m, INT* op_e) -#else - FIXP_DBL - invFourthRootNorm2(FIXP_DBL op_m, INT* op_e) -#endif -{ - FDK_ASSERT(op_m > FL2FXCONST_DBL(0.0)); - - /* normalize input, calculate shift value */ - INT exponent = (INT)fNormz(op_m) - 1; - op_m <<= exponent; - - INT index = (INT)(op_m >> (DFRACT_BITS - 1 - (FOURTHROOT_BITS + 1))) & - FOURTHROOT_BITS_MASK; - FIXP_DBL fract = (FIXP_DBL)(((INT)op_m & FOURTHROOT_FRACT_BITS_MASK) - << (FOURTHROOT_BITS + 1)); - FIXP_DBL diff = invFourthRootTab[index + 1] - invFourthRootTab[index]; - op_m = invFourthRootTab[index] + (fMultDiv2(diff, fract) << 1); - -#if defined(INVFOURTHROOTNORM2_LINEAR_INTERPOLATE_HQ) - /* reg1 = t[i] + (t[i+1]-t[i])*fract ... already computed ... + - * (1-fract)fract*(t[i+2]-t[i+1])/2 */ - if (fract != (FIXP_DBL)0) { - /* fract = fract * (1 - fract) */ - fract = fMultDiv2(fract, (FIXP_DBL)((LONG)0x80000000 - (LONG)fract)) << 1; - diff = diff - (invFourthRootTab[index + 2] - invFourthRootTab[index + 1]); - op_m = fMultAddDiv2(op_m, fract, diff); - } -#endif /* INVFOURTHROOTNORM2_LINEAR_INTERPOLATE_HQ */ - - exponent = exponent - *op_e + 4; - INT rem = exponent & 0x00000003; - INT shift_tmp = (exponent >> 2); - - *op_e = shift_tmp; - op_m = fMultDiv2(op_m, invFourthRootCorrection[rem]) << 2; - - return (op_m); -} - -/***************************************************************************** - - functionname: inv3EigthRootNorm2 - description: delivers 1/cubert(op) normalized to .5...1 and the shift value -of the OUTPUT - -*****************************************************************************/ -#define THREEIGTHROOT_BITS 7 -#define THREEIGTHROOT_VALUES (128 + 2) -#define THREEIGTHROOT_BITS_MASK 0x7f -#define THREEIGTHROOT_FRACT_BITS_MASK 0x007FFFFF - -LNK_SECTION_CONSTDATA -static const FIXP_DBL inv3EigthRootTab[THREEIGTHROOT_VALUES] = { - (0x45cae0f2), (0x45b981bf), (0x45a8492a), (0x45973691), (0x45864959), - (0x457580e6), (0x4564dca4), (0x45545c00), (0x4543fe6b), (0x4533c35a), - (0x4523aa44), (0x4513b2a4), (0x4503dbf7), (0x44f425be), (0x44e48f7b), - (0x44d518b6), (0x44c5c0f7), (0x44b687c8), (0x44a76cb8), (0x44986f58), - (0x44898f38), (0x447acbef), (0x446c2514), (0x445d9a3f), (0x444f2b0d), - (0x4440d71a), (0x44329e07), (0x44247f73), (0x44167b04), (0x4408905e), - (0x43fabf28), (0x43ed070b), (0x43df67b0), (0x43d1e0c5), (0x43c471f7), - (0x43b71af6), (0x43a9db71), (0x439cb31c), (0x438fa1ab), (0x4382a6d2), - (0x4375c248), (0x4368f3c5), (0x435c3b03), (0x434f97bc), (0x434309ac), - (0x43369091), (0x432a2c28), (0x431ddc30), (0x4311a06c), (0x4305789c), - (0x42f96483), (0x42ed63e5), (0x42e17688), (0x42d59c30), (0x42c9d4a6), - (0x42be1fb1), (0x42b27d1a), (0x42a6ecac), (0x429b6e2f), (0x42900172), - (0x4284a63f), (0x42795c64), (0x426e23b0), (0x4262fbf2), (0x4257e4f9), - (0x424cde96), (0x4241e89a), (0x423702d8), (0x422c2d23), (0x4221674d), - (0x4216b12c), (0x420c0a94), (0x4201735b), (0x41f6eb57), (0x41ec725f), - (0x41e2084b), (0x41d7acf3), (0x41cd6030), (0x41c321db), (0x41b8f1ce), - (0x41aecfe5), (0x41a4bbf8), (0x419ab5e6), (0x4190bd89), (0x4186d2bf), - (0x417cf565), (0x41732558), (0x41696277), (0x415faca1), (0x415603b4), - (0x414c6792), (0x4142d818), (0x4139552a), (0x412fdea6), (0x41267470), - (0x411d1668), (0x4113c472), (0x410a7e70), (0x41014445), (0x40f815d4), - (0x40eef302), (0x40e5dbb4), (0x40dccfcd), (0x40d3cf33), (0x40cad9cb), - (0x40c1ef7b), (0x40b9102a), (0x40b03bbd), (0x40a7721c), (0x409eb32e), - (0x4095feda), (0x408d5508), (0x4084b5a0), (0x407c208b), (0x407395b2), - (0x406b14fd), (0x40629e56), (0x405a31a6), (0x4051ced8), (0x404975d5), - (0x40412689), (0x4038e0dd), (0x4030a4bd), (0x40287215), (0x402048cf), - (0x401828d7), (0x4010121a), (0x40080483), (0x40000000), (0x3ff8047d), -}; - -/* The last value is rounded in order to avoid any overflow due to the values - * range of the root table */ -static const FIXP_DBL inv3EigthRootCorrection[8] = { - 0x40000000, 0x45CAE0F2, 0x4C1BF829, 0x52FF6B55, - 0x5A82799A, 0x62B39509, 0x6BA27E65, 0x75606373}; - -/* The 3/8 root function */ -/***************************************************************************** - * \brief calculate 1.0/3Eigth_root(op) = 1.0/(x)^(3/8), op contains mantissa - * and exponent - * \param op_m: (i) mantissa of operand, must not be zero (0x0000.0000) or - * negative - * \param op_e: (i) pointer to the exponent of the operand (must be initialized) - * and .. (o) pointer to the exponent of the result - * \return: (o) mantissa of the result - * \description: - * This routine calculates the cube root of the input operand, that is - * given with its mantissa in Q31 format (FIXP_DBL) and its exponent (INT). - * The resulting mantissa is returned in format Q31. The exponent (*op_e) - * is modified accordingly. It is not assured, that the result is fully - * left-aligned but assumed to have not more than 2 bits headroom. There is one - * macro to activate the use of this algorithm: FUNCTION_inv3EigthRootNorm2 By - * means of activating the macro INVTHREEIGTHROOTNORM2_LINEAR_INTERPOLATE_HQ, a - * slightly higher precision is reachable (by default, not active). For DEBUG - * purpose only: a FDK_ASSERT macro validates, if the input mantissa is greater - * zero. - * - */ - -/* #define INVTHREEIGTHROOTNORM2_LINEAR_INTERPOLATE_HQ */ - -static -#ifdef __arm__ - FIXP_DBL FDK_FORCEINLINE - inv3EigthRootNorm2(FIXP_DBL op_m, INT* op_e) -#else - FIXP_DBL - inv3EigthRootNorm2(FIXP_DBL op_m, INT* op_e) -#endif -{ - FDK_ASSERT(op_m > FL2FXCONST_DBL(0.0)); - - /* normalize input, calculate shift op_mue */ - INT exponent = (INT)fNormz(op_m) - 1; - op_m <<= exponent; - - INT index = (INT)(op_m >> (DFRACT_BITS - 1 - (THREEIGTHROOT_BITS + 1))) & - THREEIGTHROOT_BITS_MASK; - FIXP_DBL fract = (FIXP_DBL)(((INT)op_m & THREEIGTHROOT_FRACT_BITS_MASK) - << (THREEIGTHROOT_BITS + 1)); - FIXP_DBL diff = inv3EigthRootTab[index + 1] - inv3EigthRootTab[index]; - op_m = inv3EigthRootTab[index] + (fMultDiv2(diff, fract) << 1); - -#if defined(INVTHREEIGTHROOTNORM2_LINEAR_INTERPOLATE_HQ) - /* op_m = t[i] + (t[i+1]-t[i])*fract ... already computed ... + - * (1-fract)fract*(t[i+2]-t[i+1])/2 */ - if (fract != (FIXP_DBL)0) { - /* fract = fract * (1 - fract) */ - fract = fMultDiv2(fract, (FIXP_DBL)((LONG)0x80000000 - (LONG)fract)) << 1; - diff = diff - (inv3EigthRootTab[index + 2] - inv3EigthRootTab[index + 1]); - op_m = fMultAddDiv2(op_m, fract, diff); - } -#endif /* INVTHREEIGTHROOTNORM2_LINEAR_INTERPOLATE_HQ */ - - exponent = exponent - *op_e + 8; - INT rem = exponent & 0x00000007; - INT shift_tmp = (exponent >> 3); - - *op_e = shift_tmp * 3; - op_m = fMultDiv2(op_m, inv3EigthRootCorrection[rem]) << 2; - - return (fMult(op_m, fMult(op_m, op_m))); -} - -SBR_ERROR -QmfTransposerCreate(HANDLE_HBE_TRANSPOSER* hQmfTransposer, const int frameSize, - int bDisableCrossProducts, int bSbr41) { - HANDLE_HBE_TRANSPOSER hQmfTran = NULL; - - int i; - - if (hQmfTransposer != NULL) { - /* Memory allocation */ - /*--------------------------------------------------------------------------------------------*/ - hQmfTran = - (HANDLE_HBE_TRANSPOSER)FDKcalloc(1, sizeof(struct hbeTransposer)); - if (hQmfTran == NULL) { - return SBRDEC_MEM_ALLOC_FAILED; - } - - for (i = 0; i < MAX_STRETCH_HBE - 1; i++) { - hQmfTran->bXProducts[i] = (bDisableCrossProducts ? 0 : xProducts[i]); - } - - hQmfTran->timeDomainWinLen = frameSize; - if (frameSize == 768) { - hQmfTran->noCols = - (8 * frameSize / 3) / QMF_SYNTH_CHANNELS; /* 32 for 24:64 */ - } else { - hQmfTran->noCols = - (bSbr41 + 1) * 2 * frameSize / - QMF_SYNTH_CHANNELS; /* 32 for 32:64 and 64 for 16:64 -> identical to - sbrdec->no_cols */ - } - - hQmfTran->noChannels = frameSize / hQmfTran->noCols; - - hQmfTran->qmfInBufSize = QMF_WIN_LEN; - hQmfTran->qmfOutBufSize = 2 * (hQmfTran->noCols / 2 + QMF_WIN_LEN - 1); - - hQmfTran->inBuf_F = - (INT_PCM*)FDKcalloc(QMF_SYNTH_CHANNELS + 20 + 1, sizeof(INT_PCM)); - /* buffered time signal needs to be delayed by synthesis_size; max - * synthesis_size = 20; */ - if (hQmfTran->inBuf_F == NULL) { - QmfTransposerClose(hQmfTran); - return SBRDEC_MEM_ALLOC_FAILED; - } - - hQmfTran->qmfInBufReal_F = - (FIXP_DBL**)FDKcalloc(hQmfTran->qmfInBufSize, sizeof(FIXP_DBL*)); - hQmfTran->qmfInBufImag_F = - (FIXP_DBL**)FDKcalloc(hQmfTran->qmfInBufSize, sizeof(FIXP_DBL*)); - - if (hQmfTran->qmfInBufReal_F == NULL) { - QmfTransposerClose(hQmfTran); - return SBRDEC_MEM_ALLOC_FAILED; - } - if (hQmfTran->qmfInBufImag_F == NULL) { - QmfTransposerClose(hQmfTran); - return SBRDEC_MEM_ALLOC_FAILED; - } - - for (i = 0; i < hQmfTran->qmfInBufSize; i++) { - hQmfTran->qmfInBufReal_F[i] = (FIXP_DBL*)FDKaalloc( - QMF_SYNTH_CHANNELS * sizeof(FIXP_DBL), ALIGNMENT_DEFAULT); - hQmfTran->qmfInBufImag_F[i] = (FIXP_DBL*)FDKaalloc( - QMF_SYNTH_CHANNELS * sizeof(FIXP_DBL), ALIGNMENT_DEFAULT); - if (hQmfTran->qmfInBufReal_F[i] == NULL) { - QmfTransposerClose(hQmfTran); - return SBRDEC_MEM_ALLOC_FAILED; - } - if (hQmfTran->qmfInBufImag_F[i] == NULL) { - QmfTransposerClose(hQmfTran); - return SBRDEC_MEM_ALLOC_FAILED; - } - } - - hQmfTran->qmfHBEBufReal_F = - (FIXP_DBL**)FDKcalloc(HBE_MAX_OUT_SLOTS, sizeof(FIXP_DBL*)); - hQmfTran->qmfHBEBufImag_F = - (FIXP_DBL**)FDKcalloc(HBE_MAX_OUT_SLOTS, sizeof(FIXP_DBL*)); - - if (hQmfTran->qmfHBEBufReal_F == NULL) { - QmfTransposerClose(hQmfTran); - return SBRDEC_MEM_ALLOC_FAILED; - } - if (hQmfTran->qmfHBEBufImag_F == NULL) { - QmfTransposerClose(hQmfTran); - return SBRDEC_MEM_ALLOC_FAILED; - } - - for (i = 0; i < HBE_MAX_OUT_SLOTS; i++) { - hQmfTran->qmfHBEBufReal_F[i] = - (FIXP_DBL*)FDKcalloc(QMF_SYNTH_CHANNELS, sizeof(FIXP_DBL)); - hQmfTran->qmfHBEBufImag_F[i] = - (FIXP_DBL*)FDKcalloc(QMF_SYNTH_CHANNELS, sizeof(FIXP_DBL)); - if (hQmfTran->qmfHBEBufReal_F[i] == NULL) { - QmfTransposerClose(hQmfTran); - return SBRDEC_MEM_ALLOC_FAILED; - } - if (hQmfTran->qmfHBEBufImag_F[i] == NULL) { - QmfTransposerClose(hQmfTran); - return SBRDEC_MEM_ALLOC_FAILED; - } - } - - hQmfTran->qmfBufferCodecTempSlot_F = - (FIXP_DBL*)FDKcalloc(QMF_SYNTH_CHANNELS / 2, sizeof(FIXP_DBL)); - if (hQmfTran->qmfBufferCodecTempSlot_F == NULL) { - QmfTransposerClose(hQmfTran); - return SBRDEC_MEM_ALLOC_FAILED; - } - - hQmfTran->bSbr41 = bSbr41; - - hQmfTran->highband_exp[0] = 0; - hQmfTran->highband_exp[1] = 0; - hQmfTran->target_exp[0] = 0; - hQmfTran->target_exp[1] = 0; - - *hQmfTransposer = hQmfTran; - } - - return SBRDEC_OK; -} - -SBR_ERROR QmfTransposerReInit(HANDLE_HBE_TRANSPOSER hQmfTransposer, - UCHAR* FreqBandTable[2], UCHAR NSfb[2]) -/* removed bSbr41 from parameterlist: - don't know where to get this value from - at call-side */ -{ - int L, sfb, patch, stopPatch, qmfErr; - - if (hQmfTransposer != NULL) { - const FIXP_QTW* tmp_t_cos; - const FIXP_QTW* tmp_t_sin; - - hQmfTransposer->startBand = FreqBandTable[0][0]; - FDK_ASSERT((!hQmfTransposer->bSbr41 && hQmfTransposer->startBand <= 32) || - (hQmfTransposer->bSbr41 && - hQmfTransposer->startBand <= - 16)); /* is checked by resetFreqBandTables() */ - hQmfTransposer->stopBand = FreqBandTable[0][NSfb[0]]; - - hQmfTransposer->synthSize = - 4 * ((hQmfTransposer->startBand + 4) / 8 + 1); /* 8, 12, 16, 20 */ - hQmfTransposer->kstart = startSubband2kL[hQmfTransposer->startBand]; - - /* don't know where to take this information from */ - /* hQmfTransposer->bSbr41 = bSbr41; */ - - if (hQmfTransposer->bSbr41) { - if (hQmfTransposer->kstart + hQmfTransposer->synthSize > 16) - hQmfTransposer->kstart = 16 - hQmfTransposer->synthSize; - } else if (hQmfTransposer->timeDomainWinLen == 768) { - if (hQmfTransposer->kstart + hQmfTransposer->synthSize > 24) - hQmfTransposer->kstart = 24 - hQmfTransposer->synthSize; - } - - hQmfTransposer->synthesisQmfPreModCos_F = - &preModCos[hQmfTransposer->kstart]; - hQmfTransposer->synthesisQmfPreModSin_F = - &preModSin[hQmfTransposer->kstart]; - - L = 2 * hQmfTransposer->synthSize; /* 8, 16, 24, 32, 40 */ - /* Change analysis post twiddles */ - - switch (L) { - case 8: - tmp_t_cos = post_twiddle_cos_8; - tmp_t_sin = post_twiddle_sin_8; - break; - case 16: - tmp_t_cos = post_twiddle_cos_16; - tmp_t_sin = post_twiddle_sin_16; - break; - case 24: - tmp_t_cos = post_twiddle_cos_24; - tmp_t_sin = post_twiddle_sin_24; - break; - case 32: - tmp_t_cos = post_twiddle_cos_32; - tmp_t_sin = post_twiddle_sin_32; - break; - case 40: - tmp_t_cos = post_twiddle_cos_40; - tmp_t_sin = post_twiddle_sin_40; - break; - default: - return SBRDEC_UNSUPPORTED_CONFIG; - } - - qmfErr = qmfInitSynthesisFilterBank( - &hQmfTransposer->HBESynthesisQMF, hQmfTransposer->synQmfStates, - hQmfTransposer->noCols, 0, hQmfTransposer->synthSize, - hQmfTransposer->synthSize, 1); - if (qmfErr != 0) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - - qmfErr = qmfInitAnalysisFilterBank( - &hQmfTransposer->HBEAnalysiscQMF, hQmfTransposer->anaQmfStates, - hQmfTransposer->noCols / 2, 0, 2 * hQmfTransposer->synthSize, - 2 * hQmfTransposer->synthSize, 0); - - if (qmfErr != 0) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - - hQmfTransposer->HBEAnalysiscQMF.t_cos = tmp_t_cos; - hQmfTransposer->HBEAnalysiscQMF.t_sin = tmp_t_sin; - - FDKmemset(hQmfTransposer->xOverQmf, 0, - MAX_NUM_PATCHES * sizeof(int)); /* global */ - sfb = 0; - if (hQmfTransposer->bSbr41) { - stopPatch = MAX_NUM_PATCHES; - hQmfTransposer->maxStretch = MAX_STRETCH_HBE; - } else { - stopPatch = MAX_STRETCH_HBE; - } - - for (patch = 1; patch <= stopPatch; patch++) { - while (sfb <= NSfb[0] && - FreqBandTable[0][sfb] <= patch * hQmfTransposer->startBand) - sfb++; - if (sfb <= NSfb[0]) { - /* If the distance is larger than three QMF bands - try aligning to high - * resolution frequency bands instead. */ - if ((patch * hQmfTransposer->startBand - FreqBandTable[0][sfb - 1]) <= - 3) { - hQmfTransposer->xOverQmf[patch - 1] = FreqBandTable[0][sfb - 1]; - } else { - int sfb_tmp = 0; - while (sfb_tmp <= NSfb[1] && - FreqBandTable[1][sfb_tmp] <= patch * hQmfTransposer->startBand) - sfb_tmp++; - hQmfTransposer->xOverQmf[patch - 1] = FreqBandTable[1][sfb_tmp - 1]; - } - } else { - hQmfTransposer->xOverQmf[patch - 1] = hQmfTransposer->stopBand; - hQmfTransposer->maxStretch = fMin(patch, MAX_STRETCH_HBE); - break; - } - } - - hQmfTransposer->highband_exp[0] = 0; - hQmfTransposer->highband_exp[1] = 0; - hQmfTransposer->target_exp[0] = 0; - hQmfTransposer->target_exp[1] = 0; - } - - return SBRDEC_OK; -} - -void QmfTransposerClose(HANDLE_HBE_TRANSPOSER hQmfTransposer) { - int i; - - if (hQmfTransposer != NULL) { - if (hQmfTransposer->inBuf_F) FDKfree(hQmfTransposer->inBuf_F); - - if (hQmfTransposer->qmfInBufReal_F) { - for (i = 0; i < hQmfTransposer->qmfInBufSize; i++) { - FDKafree(hQmfTransposer->qmfInBufReal_F[i]); - } - FDKfree(hQmfTransposer->qmfInBufReal_F); - } - - if (hQmfTransposer->qmfInBufImag_F) { - for (i = 0; i < hQmfTransposer->qmfInBufSize; i++) { - FDKafree(hQmfTransposer->qmfInBufImag_F[i]); - } - FDKfree(hQmfTransposer->qmfInBufImag_F); - } - - if (hQmfTransposer->qmfHBEBufReal_F) { - for (i = 0; i < HBE_MAX_OUT_SLOTS; i++) { - FDKfree(hQmfTransposer->qmfHBEBufReal_F[i]); - } - FDKfree(hQmfTransposer->qmfHBEBufReal_F); - } - - if (hQmfTransposer->qmfHBEBufImag_F) { - for (i = 0; i < HBE_MAX_OUT_SLOTS; i++) { - FDKfree(hQmfTransposer->qmfHBEBufImag_F[i]); - } - FDKfree(hQmfTransposer->qmfHBEBufImag_F); - } - - FDKfree(hQmfTransposer->qmfBufferCodecTempSlot_F); - - FDKfree(hQmfTransposer); - } -} - -inline void scaleUp(FIXP_DBL* real_m, FIXP_DBL* imag_m, INT* _e) { - INT reserve; - /* shift gc_r and gc_i up if possible */ - reserve = CntLeadingZeros((INT(*real_m) ^ INT((*real_m >> 31))) | - (INT(*imag_m) ^ INT((*imag_m >> 31)))) - - 1; - reserve = fMax(reserve - 1, - 0); /* Leave one bit headroom such that (real_m^2 + imag_m^2) - does not overflow later if both are 0x80000000. */ - reserve = fMin(reserve, *_e); - FDK_ASSERT(reserve >= 0); - *real_m <<= reserve; - *imag_m <<= reserve; - *_e -= reserve; -} - -static void calculateCenterFIXP(FIXP_DBL gammaVecReal, FIXP_DBL gammaVecImag, - FIXP_DBL* centerReal, FIXP_DBL* centerImag, - INT* exponent, int stretch, int mult) { - scaleUp(&gammaVecReal, &gammaVecImag, exponent); - FIXP_DBL energy = fPow2Div2(gammaVecReal) + fPow2Div2(gammaVecImag); - - if (energy != FL2FXCONST_DBL(0.f)) { - FIXP_DBL gc_r_m, gc_i_m, factor_m = (FIXP_DBL)0; - INT factor_e, gc_e; - factor_e = 2 * (*exponent) + 1; - - switch (stretch) { - case 2: - factor_m = invFourthRootNorm2(energy, &factor_e); - break; - case 3: - factor_m = invCubeRootNorm2(energy, &factor_e); - break; - case 4: - factor_m = inv3EigthRootNorm2(energy, &factor_e); - break; - } - - gc_r_m = fMultDiv2(gammaVecReal, - factor_m); /* exponent = HBE_SCALE + factor_e + 1 */ - gc_i_m = fMultDiv2(gammaVecImag, - factor_m); /* exponent = HBE_SCALE + factor_e + 1*/ - gc_e = *exponent + factor_e + 1; - - scaleUp(&gc_r_m, &gc_i_m, &gc_e); - - switch (mult) { - case 0: - *centerReal = gc_r_m; - *centerImag = gc_i_m; - break; - case 1: - *centerReal = fPow2Div2(gc_r_m) - fPow2Div2(gc_i_m); - *centerImag = fMult(gc_r_m, gc_i_m); - gc_e = 2 * gc_e + 1; - break; - case 2: - FIXP_DBL tmp_r = gc_r_m; - FIXP_DBL tmp_i = gc_i_m; - gc_r_m = fPow2Div2(gc_r_m) - fPow2Div2(gc_i_m); - gc_i_m = fMult(tmp_r, gc_i_m); - gc_e = 3 * gc_e + 1 + 1; - cplxMultDiv2(¢erReal[0], ¢erImag[0], gc_r_m, gc_i_m, tmp_r, - tmp_i); - break; - } - - scaleUp(centerReal, centerImag, &gc_e); - - FDK_ASSERT(gc_e >= 0); - *exponent = gc_e; - } else { - *centerReal = energy; /* energy = 0 */ - *centerImag = energy; /* energy = 0 */ - *exponent = (INT)energy; - } -} - -static int getHBEScaleFactorFrame(const int bSbr41, const int maxStretch, - const int pitchInBins) { - if (pitchInBins >= pmin * (1 + bSbr41)) { - /* crossproducts enabled */ - return 26; - } else { - return (maxStretch == 2) ? 24 : 25; - } -} - -static void addHighBandPart(FIXP_DBL g_r_m, FIXP_DBL g_i_m, INT g_e, - FIXP_DBL mult, FIXP_DBL gammaCenterReal_m, - FIXP_DBL gammaCenterImag_m, INT gammaCenter_e, - INT stretch, INT scale_factor_hbe, - FIXP_DBL* qmfHBEBufReal_F, - FIXP_DBL* qmfHBEBufImag_F) { - if ((g_r_m | g_i_m) != FL2FXCONST_DBL(0.f)) { - FIXP_DBL factor_m = (FIXP_DBL)0; - INT factor_e; - INT add = (stretch == 4) ? 1 : 0; - INT shift = (stretch == 4) ? 1 : 2; - - scaleUp(&g_r_m, &g_i_m, &g_e); - FIXP_DBL energy = fPow2AddDiv2(fPow2Div2(g_r_m), g_i_m); - factor_e = 2 * g_e + 1; - - switch (stretch) { - case 2: - factor_m = invFourthRootNorm2(energy, &factor_e); - break; - case 3: - factor_m = invCubeRootNorm2(energy, &factor_e); - break; - case 4: - factor_m = inv3EigthRootNorm2(energy, &factor_e); - break; - } - - factor_m = fMult(factor_m, mult); - - FIXP_DBL tmp_r, tmp_i; - cplxMultDiv2(&tmp_r, &tmp_i, g_r_m, g_i_m, gammaCenterReal_m, - gammaCenterImag_m); - - g_r_m = fMultDiv2(tmp_r, factor_m) << shift; - g_i_m = fMultDiv2(tmp_i, factor_m) << shift; - g_e = scale_factor_hbe - (g_e + factor_e + gammaCenter_e + add); - fMax((INT)0, g_e); - *qmfHBEBufReal_F += g_r_m >> g_e; - *qmfHBEBufImag_F += g_i_m >> g_e; - } -} - -void QmfTransposerApply(HANDLE_HBE_TRANSPOSER hQmfTransposer, - FIXP_DBL** qmfBufferCodecReal, - FIXP_DBL** qmfBufferCodecImag, int nColsIn, - FIXP_DBL** ppQmfBufferOutReal_F, - FIXP_DBL** ppQmfBufferOutImag_F, - FIXP_DBL lpcFilterStatesReal[2 + (3 * (4))][(64)], - FIXP_DBL lpcFilterStatesImag[2 + (3 * (4))][(64)], - int pitchInBins, int scale_lb, int scale_hbe, - int* scale_hb, int timeStep, int firstSlotOffsset, - int ov_len, - KEEP_STATES_SYNCED_MODE keepStatesSyncedMode) { - int i, j, stretch, band, sourceband, r, s; - int qmfVocoderColsIn = hQmfTransposer->noCols / 2; - int bSbr41 = hQmfTransposer->bSbr41; - - const int winLength[3] = {10, 8, 6}; - const int slotOffset = 6; /* hQmfTransposer->winLen-6; */ - - int qmfOffset = 2 * hQmfTransposer->kstart; - int scale_border = (nColsIn == 64) ? 32 : nColsIn; - - INT slot_stretch4[9] = {0, 0, 0, 0, 2, 4, 6, 8, 10}; - INT slot_stretch2[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - INT slot_stretch3[10] = {0, 0, 0, 1, 3, 4, 6, 7, 9, 10}; - INT filt_stretch3[10] = {0, 0, 0, 1, 0, 1, 0, 1, 0, 1}; - INT filt_dummy[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - INT* pSlotStretch; - INT* pFilt; - - int offset = 0; /* where to take QmfTransposer data */ - - int signPreMod = - (hQmfTransposer->synthesisQmfPreModCos_F[0] < FL2FXCONST_DBL(0.f)) ? 1 - : -1; - - int scale_factor_hbe = - getHBEScaleFactorFrame(bSbr41, hQmfTransposer->maxStretch, pitchInBins); - - if (keepStatesSyncedMode != KEEP_STATES_SYNCED_OFF) { - offset = hQmfTransposer->noCols - ov_len - LPC_ORDER; - } - - hQmfTransposer->highband_exp[0] = hQmfTransposer->highband_exp[1]; - hQmfTransposer->target_exp[0] = hQmfTransposer->target_exp[1]; - - hQmfTransposer->highband_exp[1] = scale_factor_hbe; - hQmfTransposer->target_exp[1] = - fixMax(hQmfTransposer->highband_exp[1], hQmfTransposer->highband_exp[0]); - - scale_factor_hbe = hQmfTransposer->target_exp[1]; - - int shift_ov = hQmfTransposer->target_exp[0] - hQmfTransposer->target_exp[1]; - - if (shift_ov != 0) { - for (i = 0; i < HBE_MAX_OUT_SLOTS; i++) { - for (band = 0; band < QMF_SYNTH_CHANNELS; band++) { - if (shift_ov >= 0) { - hQmfTransposer->qmfHBEBufReal_F[i][band] <<= shift_ov; - hQmfTransposer->qmfHBEBufImag_F[i][band] <<= shift_ov; - } else { - hQmfTransposer->qmfHBEBufReal_F[i][band] >>= (-shift_ov); - hQmfTransposer->qmfHBEBufImag_F[i][band] >>= (-shift_ov); - } - } - } - } - - if ((keepStatesSyncedMode == KEEP_STATES_SYNCED_OFF) && shift_ov != 0) { - for (i = timeStep * firstSlotOffsset; i < ov_len; i++) { - for (band = hQmfTransposer->startBand; band < hQmfTransposer->stopBand; - band++) { - if (shift_ov >= 0) { - ppQmfBufferOutReal_F[i][band] <<= shift_ov; - ppQmfBufferOutImag_F[i][band] <<= shift_ov; - } else { - ppQmfBufferOutReal_F[i][band] >>= (-shift_ov); - ppQmfBufferOutImag_F[i][band] >>= (-shift_ov); - } - } - } - - /* shift lpc filterstates */ - for (i = 0; i < timeStep * firstSlotOffsset + LPC_ORDER; i++) { - for (band = 0; band < (64); band++) { - if (shift_ov >= 0) { - lpcFilterStatesReal[i][band] <<= shift_ov; - lpcFilterStatesImag[i][band] <<= shift_ov; - } else { - lpcFilterStatesReal[i][band] >>= (-shift_ov); - lpcFilterStatesImag[i][band] >>= (-shift_ov); - } - } - } - } - - FIXP_DBL twid_m_new[3][2]; /* [stretch][cos/sin] */ - INT stepsize = 1 + !bSbr41, sine_offset = 24, mod = 96; - INT mult[3] = {1, 2, 3}; - - for (s = 0; s <= MAX_STRETCH_HBE - 2; s++) { - twid_m_new[s][0] = twiddle[(mult[s] * (stepsize * pitchInBins)) % mod]; - twid_m_new[s][1] = - twiddle[((mult[s] * (stepsize * pitchInBins)) + sine_offset) % mod]; - } - - /* Time-stretch */ - for (j = 0; j < qmfVocoderColsIn; j++) { - int sign = -1, k, z, addrshift, codecTemp_e; - /* update inbuf */ - for (i = 0; i < hQmfTransposer->synthSize; i++) { - hQmfTransposer->inBuf_F[i] = - hQmfTransposer->inBuf_F[i + 2 * hQmfTransposer->synthSize]; - } - - /* run synthesis for two sbr slots as transposer uses - half slots double bands representation */ - for (z = 0; z < 2; z++) { - int scale_factor = ((nColsIn == 64) && ((2 * j + z) < scale_border)) - ? scale_lb - : scale_hbe; - codecTemp_e = scale_factor - 1; /* -2 for Div2 and cos/sin scale of 1 */ - - for (k = 0; k < hQmfTransposer->synthSize; k++) { - int ki = hQmfTransposer->kstart + k; - hQmfTransposer->qmfBufferCodecTempSlot_F[k] = - fMultDiv2(signPreMod * hQmfTransposer->synthesisQmfPreModCos_F[k], - qmfBufferCodecReal[2 * j + z][ki]); - hQmfTransposer->qmfBufferCodecTempSlot_F[k] += - fMultDiv2(signPreMod * hQmfTransposer->synthesisQmfPreModSin_F[k], - qmfBufferCodecImag[2 * j + z][ki]); - } - - C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, (HBE_MAX_QMF_BANDS << 1)); - - qmfSynthesisFilteringSlot( - &hQmfTransposer->HBESynthesisQMF, - hQmfTransposer->qmfBufferCodecTempSlot_F, NULL, 0, - -7 - hQmfTransposer->HBESynthesisQMF.filterScale - codecTemp_e + 1, - hQmfTransposer->inBuf_F + hQmfTransposer->synthSize * (z + 1), 1, - pWorkBuffer); - - C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, (HBE_MAX_QMF_BANDS << 1)); - } - - C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, (HBE_MAX_QMF_BANDS << 1)); - - qmfAnalysisFilteringSlot(&hQmfTransposer->HBEAnalysiscQMF, - hQmfTransposer->qmfInBufReal_F[QMF_WIN_LEN - 1], - hQmfTransposer->qmfInBufImag_F[QMF_WIN_LEN - 1], - hQmfTransposer->inBuf_F + 1, 1, pWorkBuffer); - - C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, (HBE_MAX_QMF_BANDS << 1)); - - if ((keepStatesSyncedMode == KEEP_STATES_SYNCED_NORMAL) && - j <= qmfVocoderColsIn - ((LPC_ORDER + ov_len + QMF_WIN_LEN - 1) >> 1)) { - /* update in buffer */ - for (i = 0; i < QMF_WIN_LEN - 1; i++) { - FDKmemcpy( - hQmfTransposer->qmfInBufReal_F[i], - hQmfTransposer->qmfInBufReal_F[i + 1], - sizeof(FIXP_DBL) * hQmfTransposer->HBEAnalysiscQMF.no_channels); - FDKmemcpy( - hQmfTransposer->qmfInBufImag_F[i], - hQmfTransposer->qmfInBufImag_F[i + 1], - sizeof(FIXP_DBL) * hQmfTransposer->HBEAnalysiscQMF.no_channels); - } - continue; - } - - for (stretch = 2; stretch <= hQmfTransposer->maxStretch; stretch++) { - int start = slotOffset - winLength[stretch - 2] / 2; - int stop = slotOffset + winLength[stretch - 2] / 2; - - FIXP_DBL factor = FL2FXCONST_DBL(1.f / 3.f); - - for (band = hQmfTransposer->xOverQmf[stretch - 2]; - band < hQmfTransposer->xOverQmf[stretch - 1]; band++) { - FIXP_DBL gammaCenterReal_m[2] = {(FIXP_DBL)0, (FIXP_DBL)0}, - gammaCenterImag_m[2] = {(FIXP_DBL)0, (FIXP_DBL)0}; - INT gammaCenter_e[2] = {0, 0}; - - FIXP_DBL gammaVecReal_m[2] = {(FIXP_DBL)0, (FIXP_DBL)0}, - gammaVecImag_m[2] = {(FIXP_DBL)0, (FIXP_DBL)0}; - INT gammaVec_e[2] = {0, 0}; - - FIXP_DBL wingain = (FIXP_DBL)0; - - gammaCenter_e[0] = - SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor); - gammaCenter_e[1] = - SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor); - - /* interpolation filters for 3rd order */ - sourceband = 2 * band / stretch - qmfOffset; - FDK_ASSERT(sourceband >= 0); - - /* maximum gammaCenter_e == 20 */ - calculateCenterFIXP( - hQmfTransposer->qmfInBufReal_F[slotOffset][sourceband], - hQmfTransposer->qmfInBufImag_F[slotOffset][sourceband], - &gammaCenterReal_m[0], &gammaCenterImag_m[0], &gammaCenter_e[0], - stretch, stretch - 2); - - if (stretch == 4) { - r = band - 2 * (band / 2); - sourceband += (r == 0) ? -1 : 1; - pSlotStretch = slot_stretch4; - factor = FL2FXCONST_DBL(2.f / 3.f); - pFilt = filt_dummy; - } else if (stretch == 2) { - r = 0; - sourceband = 2 * band / stretch - qmfOffset; - pSlotStretch = slot_stretch2; - factor = FL2FXCONST_DBL(1.f / 3.f); - pFilt = filt_dummy; - } else { - r = 2 * band - 3 * (2 * band / 3); - sourceband = 2 * band / stretch - qmfOffset; - pSlotStretch = slot_stretch3; - factor = FL2FXCONST_DBL(1.4142f / 3.0f); - pFilt = filt_stretch3; - } - - if (r == 2) { - calculateCenterFIXP( - hQmfTransposer->qmfInBufReal_F[slotOffset][sourceband + 1], - hQmfTransposer->qmfInBufImag_F[slotOffset][sourceband + 1], - &gammaCenterReal_m[1], &gammaCenterImag_m[1], &gammaCenter_e[1], - stretch, stretch - 2); - - factor = FL2FXCONST_DBL(1.4142f / 6.0f); - } - - if (r == 2) { - for (k = start; k < stop; k++) { - gammaVecReal_m[0] = - hQmfTransposer->qmfInBufReal_F[pSlotStretch[k]][sourceband]; - gammaVecReal_m[1] = - hQmfTransposer->qmfInBufReal_F[pSlotStretch[k]][sourceband + 1]; - gammaVecImag_m[0] = - hQmfTransposer->qmfInBufImag_F[pSlotStretch[k]][sourceband]; - gammaVecImag_m[1] = - hQmfTransposer->qmfInBufImag_F[pSlotStretch[k]][sourceband + 1]; - gammaVec_e[0] = gammaVec_e[1] = - SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor); - - if (pFilt[k] == 1) { - FIXP_DBL tmpRealF = gammaVecReal_m[0], tmpImagF; - gammaVecReal_m[0] = - (fMult(gammaVecReal_m[0], hintReal_F[sourceband % 4][1]) - - fMult(gammaVecImag_m[0], - hintReal_F[(sourceband + 3) % 4][1])) >> - 1; /* sum should be <= 1 because of sin/cos multiplication */ - gammaVecImag_m[0] = - (fMult(tmpRealF, hintReal_F[(sourceband + 3) % 4][1]) + - fMult(gammaVecImag_m[0], hintReal_F[sourceband % 4][1])) >> - 1; /* sum should be <= 1 because of sin/cos multiplication */ - - tmpRealF = hQmfTransposer - ->qmfInBufReal_F[pSlotStretch[k] + 1][sourceband]; - tmpImagF = hQmfTransposer - ->qmfInBufImag_F[pSlotStretch[k] + 1][sourceband]; - - gammaVecReal_m[0] += - (fMult(tmpRealF, hintReal_F[sourceband % 4][1]) - - fMult(tmpImagF, hintReal_F[(sourceband + 1) % 4][1])) >> - 1; /* sum should be <= 1 because of sin/cos multiplication */ - gammaVecImag_m[0] += - (fMult(tmpRealF, hintReal_F[(sourceband + 1) % 4][1]) + - fMult(tmpImagF, hintReal_F[sourceband % 4][1])) >> - 1; /* sum should be <= 1 because of sin/cos multiplication */ - gammaVec_e[0]++; - - tmpRealF = gammaVecReal_m[1]; - - gammaVecReal_m[1] = - (fMult(gammaVecReal_m[1], hintReal_F[sourceband % 4][2]) - - fMult(gammaVecImag_m[1], - hintReal_F[(sourceband + 3) % 4][2])) >> - 1; - gammaVecImag_m[1] = - (fMult(tmpRealF, hintReal_F[(sourceband + 3) % 4][2]) + - fMult(gammaVecImag_m[1], hintReal_F[sourceband % 4][2])) >> - 1; - - tmpRealF = - hQmfTransposer - ->qmfInBufReal_F[pSlotStretch[k] + 1][sourceband + 1]; - tmpImagF = - hQmfTransposer - ->qmfInBufImag_F[pSlotStretch[k] + 1][sourceband + 1]; - - gammaVecReal_m[1] += - (fMult(tmpRealF, hintReal_F[sourceband % 4][2]) - - fMult(tmpImagF, hintReal_F[(sourceband + 1) % 4][2])) >> - 1; - gammaVecImag_m[1] += - (fMult(tmpRealF, hintReal_F[(sourceband + 1) % 4][2]) + - fMult(tmpImagF, hintReal_F[sourceband % 4][2])) >> - 1; - gammaVec_e[1]++; - } - - addHighBandPart(gammaVecReal_m[1], gammaVecImag_m[1], gammaVec_e[1], - factor, gammaCenterReal_m[0], gammaCenterImag_m[0], - gammaCenter_e[0], stretch, scale_factor_hbe, - &hQmfTransposer->qmfHBEBufReal_F[k][band], - &hQmfTransposer->qmfHBEBufImag_F[k][band]); - - addHighBandPart(gammaVecReal_m[0], gammaVecImag_m[0], gammaVec_e[0], - factor, gammaCenterReal_m[1], gammaCenterImag_m[1], - gammaCenter_e[1], stretch, scale_factor_hbe, - &hQmfTransposer->qmfHBEBufReal_F[k][band], - &hQmfTransposer->qmfHBEBufImag_F[k][band]); - } - } else { - for (k = start; k < stop; k++) { - gammaVecReal_m[0] = - hQmfTransposer->qmfInBufReal_F[pSlotStretch[k]][sourceband]; - gammaVecImag_m[0] = - hQmfTransposer->qmfInBufImag_F[pSlotStretch[k]][sourceband]; - gammaVec_e[0] = - SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor); - - if (pFilt[k] == 1) { - FIXP_DBL tmpRealF = gammaVecReal_m[0], tmpImagF; - gammaVecReal_m[0] = - (fMult(gammaVecReal_m[0], hintReal_F[sourceband % 4][1]) - - fMult(gammaVecImag_m[0], - hintReal_F[(sourceband + 3) % 4][1])) >> - 1; /* sum should be <= 1 because of sin/cos multiplication */ - gammaVecImag_m[0] = - (fMult(tmpRealF, hintReal_F[(sourceband + 3) % 4][1]) + - fMult(gammaVecImag_m[0], hintReal_F[sourceband % 4][1])) >> - 1; /* sum should be <= 1 because of sin/cos multiplication */ - - tmpRealF = hQmfTransposer - ->qmfInBufReal_F[pSlotStretch[k] + 1][sourceband]; - tmpImagF = hQmfTransposer - ->qmfInBufImag_F[pSlotStretch[k] + 1][sourceband]; - - gammaVecReal_m[0] += - (fMult(tmpRealF, hintReal_F[sourceband % 4][1]) - - fMult(tmpImagF, hintReal_F[(sourceband + 1) % 4][1])) >> - 1; /* sum should be <= 1 because of sin/cos multiplication */ - gammaVecImag_m[0] += - (fMult(tmpRealF, hintReal_F[(sourceband + 1) % 4][1]) + - fMult(tmpImagF, hintReal_F[sourceband % 4][1])) >> - 1; /* sum should be <= 1 because of sin/cos multiplication */ - gammaVec_e[0]++; - } - - addHighBandPart(gammaVecReal_m[0], gammaVecImag_m[0], gammaVec_e[0], - factor, gammaCenterReal_m[0], gammaCenterImag_m[0], - gammaCenter_e[0], stretch, scale_factor_hbe, - &hQmfTransposer->qmfHBEBufReal_F[k][band], - &hQmfTransposer->qmfHBEBufImag_F[k][band]); - } - } - - /* pitchInBins is given with the resolution of a 768 bins FFT and we - * need 64 QMF units so factor 768/64 = 12 */ - if (pitchInBins >= pmin * (1 + bSbr41)) { - int tr, ti1, ti2, mTr = 0, ts1 = 0, ts2 = 0, mVal_e = 0, temp_e = 0; - int sqmag0_e = - SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor); - - FIXP_DBL mVal_F = FL2FXCONST_DBL(0.f), sqmag0_F, sqmag1_F, sqmag2_F, - temp_F, f1_F; /* all equal exponent */ - sign = -1; - - sourceband = 2 * band / stretch - qmfOffset; /* consistent with the - already computed for - stretch = 3,4. */ - FDK_ASSERT(sourceband >= 0); - - FIXP_DBL sqmag0R_F = - hQmfTransposer->qmfInBufReal_F[slotOffset][sourceband]; - FIXP_DBL sqmag0I_F = - hQmfTransposer->qmfInBufImag_F[slotOffset][sourceband]; - scaleUp(&sqmag0R_F, &sqmag0I_F, &sqmag0_e); - - sqmag0_F = fPow2Div2(sqmag0R_F); - sqmag0_F += fPow2Div2(sqmag0I_F); - sqmag0_e = 2 * sqmag0_e + 1; - - for (tr = 1; tr < stretch; tr++) { - int sqmag1_e = - SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor); - int sqmag2_e = - SCALE2EXP(-hQmfTransposer->HBEAnalysiscQMF.outScalefactor); - - FIXP_DBL tmp_band = band_F[band]; - FIXP_DBL tr_p = - fMult(p_F[pitchInBins] >> bSbr41, tr_str[tr - 1]); /* scale 7 */ - f1_F = - fMult(tmp_band - tr_p, stretchfac[stretch - 2]); /* scale 7 */ - ti1 = (INT)(f1_F >> (DFRACT_BITS - 1 - 7)) - qmfOffset; - ti2 = (INT)(((f1_F) + ((p_F[pitchInBins] >> bSbr41) >> 2)) >> - (DFRACT_BITS - 1 - 7)) - - qmfOffset; - - if (ti1 >= 0 && ti2 < 2 * hQmfTransposer->synthSize) { - FIXP_DBL sqmag1R_F = - hQmfTransposer->qmfInBufReal_F[slotOffset][ti1]; - FIXP_DBL sqmag1I_F = - hQmfTransposer->qmfInBufImag_F[slotOffset][ti1]; - scaleUp(&sqmag1R_F, &sqmag1I_F, &sqmag1_e); - sqmag1_F = fPow2Div2(sqmag1R_F); - sqmag1_F += fPow2Div2(sqmag1I_F); - sqmag1_e = 2 * sqmag1_e + 1; - - FIXP_DBL sqmag2R_F = - hQmfTransposer->qmfInBufReal_F[slotOffset][ti2]; - FIXP_DBL sqmag2I_F = - hQmfTransposer->qmfInBufImag_F[slotOffset][ti2]; - scaleUp(&sqmag2R_F, &sqmag2I_F, &sqmag2_e); - sqmag2_F = fPow2Div2(sqmag2R_F); - sqmag2_F += fPow2Div2(sqmag2I_F); - sqmag2_e = 2 * sqmag2_e + 1; - - int shift1 = fMin(fMax(sqmag1_e, sqmag2_e) - sqmag1_e, 31); - int shift2 = fMin(fMax(sqmag1_e, sqmag2_e) - sqmag2_e, 31); - - temp_F = fMin((sqmag1_F >> shift1), (sqmag2_F >> shift2)); - temp_e = fMax(sqmag1_e, sqmag2_e); - - int shift3 = fMin(fMax(temp_e, mVal_e) - temp_e, 31); - int shift4 = fMin(fMax(temp_e, mVal_e) - mVal_e, 31); - - if ((temp_F >> shift3) > (mVal_F >> shift4)) { - mVal_F = temp_F; - mVal_e = temp_e; /* equals sqmag2_e + shift2 */ - mTr = tr; - ts1 = ti1; - ts2 = ti2; - } - } - } - - int shift1 = fMin(fMax(sqmag0_e, mVal_e) - sqmag0_e, 31); - int shift2 = fMin(fMax(sqmag0_e, mVal_e) - mVal_e, 31); - - if ((mVal_F >> shift2) > (sqmag0_F >> shift1) && ts1 >= 0 && - ts2 < 2 * hQmfTransposer->synthSize) { - INT gammaOut_e[2]; - FIXP_DBL gammaOutReal_m[2], gammaOutImag_m[2]; - FIXP_DBL tmpReal_m = (FIXP_DBL)0, tmpImag_m = (FIXP_DBL)0; - - int Tcenter, Tvec; - - Tcenter = stretch - mTr; /* default phase power parameters */ - Tvec = mTr; - switch (stretch) /* 2 tap block creation design depends on stretch - order */ - { - case 2: - wingain = - FL2FXCONST_DBL(5.f / 12.f); /* sum of taps divided by two */ - - if (hQmfTransposer->bXProducts[0]) { - gammaCenterReal_m[0] = - hQmfTransposer->qmfInBufReal_F[slotOffset][ts1]; - gammaCenterImag_m[0] = - hQmfTransposer->qmfInBufImag_F[slotOffset][ts1]; - - for (k = 0; k < 2; k++) { - gammaVecReal_m[k] = - hQmfTransposer->qmfInBufReal_F[slotOffset - 1 + k][ts2]; - gammaVecImag_m[k] = - hQmfTransposer->qmfInBufImag_F[slotOffset - 1 + k][ts2]; - } - - gammaCenter_e[0] = SCALE2EXP( - -hQmfTransposer->HBEAnalysiscQMF.outScalefactor); - gammaVec_e[0] = gammaVec_e[1] = SCALE2EXP( - -hQmfTransposer->HBEAnalysiscQMF.outScalefactor); - } - break; - - case 4: - wingain = - FL2FXCONST_DBL(6.f / 12.f); /* sum of taps divided by two */ - if (hQmfTransposer->bXProducts[2]) { - if (mTr == 1) { - gammaCenterReal_m[0] = - hQmfTransposer->qmfInBufReal_F[slotOffset][ts1]; - gammaCenterImag_m[0] = - hQmfTransposer->qmfInBufImag_F[slotOffset][ts1]; - - for (k = 0; k < 2; k++) { - gammaVecReal_m[k] = - hQmfTransposer - ->qmfInBufReal_F[slotOffset + 2 * (k - 1)][ts2]; - gammaVecImag_m[k] = - hQmfTransposer - ->qmfInBufImag_F[slotOffset + 2 * (k - 1)][ts2]; - } - } else if (mTr == 2) { - gammaCenterReal_m[0] = - hQmfTransposer->qmfInBufReal_F[slotOffset][ts1]; - gammaCenterImag_m[0] = - hQmfTransposer->qmfInBufImag_F[slotOffset][ts1]; - - for (k = 0; k < 2; k++) { - gammaVecReal_m[k] = - hQmfTransposer - ->qmfInBufReal_F[slotOffset + (k - 1)][ts2]; - gammaVecImag_m[k] = - hQmfTransposer - ->qmfInBufImag_F[slotOffset + (k - 1)][ts2]; - } - } else /* (mTr == 3) */ - { - sign = 1; - Tcenter = mTr; /* opposite phase power parameters as ts2 is - center */ - Tvec = stretch - mTr; - - gammaCenterReal_m[0] = - hQmfTransposer->qmfInBufReal_F[slotOffset][ts2]; - gammaCenterImag_m[0] = - hQmfTransposer->qmfInBufImag_F[slotOffset][ts2]; - - for (k = 0; k < 2; k++) { - gammaVecReal_m[k] = - hQmfTransposer - ->qmfInBufReal_F[slotOffset + 2 * (k - 1)][ts1]; - gammaVecImag_m[k] = - hQmfTransposer - ->qmfInBufImag_F[slotOffset + 2 * (k - 1)][ts1]; - } - } - - gammaCenter_e[0] = SCALE2EXP( - -hQmfTransposer->HBEAnalysiscQMF.outScalefactor); - gammaVec_e[0] = gammaVec_e[1] = SCALE2EXP( - -hQmfTransposer->HBEAnalysiscQMF.outScalefactor); - } - break; - - case 3: - wingain = FL2FXCONST_DBL(5.6568f / - 12.f); /* sum of taps divided by two */ - - if (hQmfTransposer->bXProducts[1]) { - FIXP_DBL tmpReal_F, tmpImag_F; - if (mTr == 1) { - gammaCenterReal_m[0] = - hQmfTransposer->qmfInBufReal_F[slotOffset][ts1]; - gammaCenterImag_m[0] = - hQmfTransposer->qmfInBufImag_F[slotOffset][ts1]; - gammaVecReal_m[1] = - hQmfTransposer->qmfInBufReal_F[slotOffset][ts2]; - gammaVecImag_m[1] = - hQmfTransposer->qmfInBufImag_F[slotOffset][ts2]; - - addrshift = -2; - tmpReal_F = - hQmfTransposer - ->qmfInBufReal_F[addrshift + slotOffset][ts2]; - tmpImag_F = - hQmfTransposer - ->qmfInBufImag_F[addrshift + slotOffset][ts2]; - - gammaVecReal_m[0] = - (fMult(factors[ts2 % 4], tmpReal_F) - - fMult(factors[(ts2 + 3) % 4], tmpImag_F)) >> - 1; - gammaVecImag_m[0] = - (fMult(factors[(ts2 + 3) % 4], tmpReal_F) + - fMult(factors[ts2 % 4], tmpImag_F)) >> - 1; - - tmpReal_F = - hQmfTransposer - ->qmfInBufReal_F[addrshift + 1 + slotOffset][ts2]; - tmpImag_F = - hQmfTransposer - ->qmfInBufImag_F[addrshift + 1 + slotOffset][ts2]; - - gammaVecReal_m[0] += - (fMult(factors[ts2 % 4], tmpReal_F) - - fMult(factors[(ts2 + 1) % 4], tmpImag_F)) >> - 1; - gammaVecImag_m[0] += - (fMult(factors[(ts2 + 1) % 4], tmpReal_F) + - fMult(factors[ts2 % 4], tmpImag_F)) >> - 1; - - } else /* (mTr == 2) */ - { - sign = 1; - Tcenter = mTr; /* opposite phase power parameters as ts2 is - center */ - Tvec = stretch - mTr; - - gammaCenterReal_m[0] = - hQmfTransposer->qmfInBufReal_F[slotOffset][ts2]; - gammaCenterImag_m[0] = - hQmfTransposer->qmfInBufImag_F[slotOffset][ts2]; - gammaVecReal_m[1] = - hQmfTransposer->qmfInBufReal_F[slotOffset][ts1]; - gammaVecImag_m[1] = - hQmfTransposer->qmfInBufImag_F[slotOffset][ts1]; - - addrshift = -2; - tmpReal_F = - hQmfTransposer - ->qmfInBufReal_F[addrshift + slotOffset][ts1]; - tmpImag_F = - hQmfTransposer - ->qmfInBufImag_F[addrshift + slotOffset][ts1]; - - gammaVecReal_m[0] = - (fMult(factors[ts1 % 4], tmpReal_F) - - fMult(factors[(ts1 + 3) % 4], tmpImag_F)) >> - 1; - gammaVecImag_m[0] = - (fMult(factors[(ts1 + 3) % 4], tmpReal_F) + - fMult(factors[ts1 % 4], tmpImag_F)) >> - 1; - - tmpReal_F = - hQmfTransposer - ->qmfInBufReal_F[addrshift + 1 + slotOffset][ts1]; - tmpImag_F = - hQmfTransposer - ->qmfInBufImag_F[addrshift + 1 + slotOffset][ts1]; - - gammaVecReal_m[0] += - (fMult(factors[ts1 % 4], tmpReal_F) - - fMult(factors[(ts1 + 1) % 4], tmpImag_F)) >> - 1; - gammaVecImag_m[0] += - (fMult(factors[(ts1 + 1) % 4], tmpReal_F) + - fMult(factors[ts1 % 4], tmpImag_F)) >> - 1; - } - - gammaCenter_e[0] = gammaVec_e[1] = SCALE2EXP( - -hQmfTransposer->HBEAnalysiscQMF.outScalefactor); - gammaVec_e[0] = - SCALE2EXP( - -hQmfTransposer->HBEAnalysiscQMF.outScalefactor) + - 1; - } - break; - default: - FDK_ASSERT(0); - break; - } /* stretch cases */ - - /* parameter controlled phase modification parts */ - /* maximum *_e == 20 */ - calculateCenterFIXP(gammaCenterReal_m[0], gammaCenterImag_m[0], - &gammaCenterReal_m[0], &gammaCenterImag_m[0], - &gammaCenter_e[0], stretch, Tcenter - 1); - calculateCenterFIXP(gammaVecReal_m[0], gammaVecImag_m[0], - &gammaVecReal_m[0], &gammaVecImag_m[0], - &gammaVec_e[0], stretch, Tvec - 1); - calculateCenterFIXP(gammaVecReal_m[1], gammaVecImag_m[1], - &gammaVecReal_m[1], &gammaVecImag_m[1], - &gammaVec_e[1], stretch, Tvec - 1); - - /* Final multiplication of prepared parts */ - for (k = 0; k < 2; k++) { - gammaOutReal_m[k] = - fMultDiv2(gammaVecReal_m[k], gammaCenterReal_m[0]) - - fMultDiv2(gammaVecImag_m[k], gammaCenterImag_m[0]); - gammaOutImag_m[k] = - fMultDiv2(gammaVecReal_m[k], gammaCenterImag_m[0]) + - fMultDiv2(gammaVecImag_m[k], gammaCenterReal_m[0]); - gammaOut_e[k] = gammaCenter_e[0] + gammaVec_e[k] + 1; - } - - scaleUp(&gammaOutReal_m[0], &gammaOutImag_m[0], &gammaOut_e[0]); - scaleUp(&gammaOutReal_m[1], &gammaOutImag_m[1], &gammaOut_e[1]); - FDK_ASSERT(gammaOut_e[0] >= 0); - FDK_ASSERT(gammaOut_e[0] < 32); - - tmpReal_m = gammaOutReal_m[0]; - tmpImag_m = gammaOutImag_m[0]; - - INT modstretch4 = ((stretch == 4) && (mTr == 2)); - - FIXP_DBL cos_twid = twid_m_new[stretch - 2 - modstretch4][0]; - FIXP_DBL sin_twid = sign * twid_m_new[stretch - 2 - modstretch4][1]; - - gammaOutReal_m[0] = - fMult(tmpReal_m, cos_twid) - - fMult(tmpImag_m, sin_twid); /* sum should be <= 1 because of - sin/cos multiplication */ - gammaOutImag_m[0] = - fMult(tmpImag_m, cos_twid) + - fMult(tmpReal_m, sin_twid); /* sum should be <= 1 because of - sin/cos multiplication */ - - /* wingain */ - for (k = 0; k < 2; k++) { - gammaOutReal_m[k] = (fMult(gammaOutReal_m[k], wingain) << 1); - gammaOutImag_m[k] = (fMult(gammaOutImag_m[k], wingain) << 1); - } - - gammaOutReal_m[1] >>= 1; - gammaOutImag_m[1] >>= 1; - gammaOut_e[0] += 2; - gammaOut_e[1] += 2; - - /* OLA including window scaling by wingain/3 */ - for (k = 0; k < 2; k++) /* need k=1 to correspond to - grainModImag[slotOffset] -> out to - j*2+(slotOffset-offset) */ - { - hQmfTransposer->qmfHBEBufReal_F[(k + slotOffset - 1)][band] += - gammaOutReal_m[k] >> (scale_factor_hbe - gammaOut_e[k]); - hQmfTransposer->qmfHBEBufImag_F[(k + slotOffset - 1)][band] += - gammaOutImag_m[k] >> (scale_factor_hbe - gammaOut_e[k]); - } - } /* mVal > qThrQMF * qThrQMF * sqmag0 && ts1 > 0 && ts2 < 64 */ - } /* p >= pmin */ - } /* for band */ - } /* for stretch */ - - for (i = 0; i < QMF_WIN_LEN - 1; i++) { - FDKmemcpy(hQmfTransposer->qmfInBufReal_F[i], - hQmfTransposer->qmfInBufReal_F[i + 1], - sizeof(FIXP_DBL) * hQmfTransposer->HBEAnalysiscQMF.no_channels); - FDKmemcpy(hQmfTransposer->qmfInBufImag_F[i], - hQmfTransposer->qmfInBufImag_F[i + 1], - sizeof(FIXP_DBL) * hQmfTransposer->HBEAnalysiscQMF.no_channels); - } - - if (keepStatesSyncedMode != KEEP_STATES_SYNCED_NOOUT) { - if (2 * j >= offset) { - /* copy first two slots of internal buffer to output */ - if (keepStatesSyncedMode == KEEP_STATES_SYNCED_OUTDIFF) { - for (i = 0; i < 2; i++) { - FDKmemcpy(&ppQmfBufferOutReal_F[2 * j - offset + i] - [hQmfTransposer->xOverQmf[0]], - &hQmfTransposer - ->qmfHBEBufReal_F[i][hQmfTransposer->xOverQmf[0]], - (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) * - sizeof(FIXP_DBL)); - FDKmemcpy(&ppQmfBufferOutImag_F[2 * j - offset + i] - [hQmfTransposer->xOverQmf[0]], - &hQmfTransposer - ->qmfHBEBufImag_F[i][hQmfTransposer->xOverQmf[0]], - (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) * - sizeof(FIXP_DBL)); - } - } else { - for (i = 0; i < 2; i++) { - FDKmemcpy(&ppQmfBufferOutReal_F[2 * j + i + ov_len] - [hQmfTransposer->xOverQmf[0]], - &hQmfTransposer - ->qmfHBEBufReal_F[i][hQmfTransposer->xOverQmf[0]], - (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) * - sizeof(FIXP_DBL)); - FDKmemcpy(&ppQmfBufferOutImag_F[2 * j + i + ov_len] - [hQmfTransposer->xOverQmf[0]], - &hQmfTransposer - ->qmfHBEBufImag_F[i][hQmfTransposer->xOverQmf[0]], - (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) * - sizeof(FIXP_DBL)); - } - } - } - } - - /* move slots up */ - for (i = 0; i < HBE_MAX_OUT_SLOTS - 2; i++) { - FDKmemcpy( - &hQmfTransposer->qmfHBEBufReal_F[i][hQmfTransposer->xOverQmf[0]], - &hQmfTransposer->qmfHBEBufReal_F[i + 2][hQmfTransposer->xOverQmf[0]], - (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) * - sizeof(FIXP_DBL)); - FDKmemcpy( - &hQmfTransposer->qmfHBEBufImag_F[i][hQmfTransposer->xOverQmf[0]], - &hQmfTransposer->qmfHBEBufImag_F[i + 2][hQmfTransposer->xOverQmf[0]], - (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) * - sizeof(FIXP_DBL)); - } - - /* finally set last two slot to zero */ - for (i = 0; i < 2; i++) { - FDKmemset(&hQmfTransposer->qmfHBEBufReal_F[HBE_MAX_OUT_SLOTS - 1 - i] - [hQmfTransposer->xOverQmf[0]], - 0, - (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) * - sizeof(FIXP_DBL)); - FDKmemset(&hQmfTransposer->qmfHBEBufImag_F[HBE_MAX_OUT_SLOTS - 1 - i] - [hQmfTransposer->xOverQmf[0]], - 0, - (QMF_SYNTH_CHANNELS - hQmfTransposer->xOverQmf[0]) * - sizeof(FIXP_DBL)); - } - } /* qmfVocoderColsIn */ - - if (keepStatesSyncedMode != KEEP_STATES_SYNCED_NOOUT) { - if (keepStatesSyncedMode == KEEP_STATES_SYNCED_OUTDIFF) { - for (i = 0; i < ov_len + LPC_ORDER; i++) { - for (band = hQmfTransposer->startBand; band < hQmfTransposer->stopBand; - band++) { - FIXP_DBL tmpR = ppQmfBufferOutReal_F[i][band]; - FIXP_DBL tmpI = ppQmfBufferOutImag_F[i][band]; - - ppQmfBufferOutReal_F[i][band] = - fMult(tmpR, cos_F[band]) - - fMult(tmpI, (-cos_F[64 - band - 1])); /* sum should be <= 1 - because of sin/cos - multiplication */ - ppQmfBufferOutImag_F[i][band] = - fMult(tmpR, (-cos_F[64 - band - 1])) + - fMult(tmpI, cos_F[band]); /* sum should by <= 1 because of sin/cos - multiplication */ - } - } - } else { - for (i = offset; i < hQmfTransposer->noCols; i++) { - for (band = hQmfTransposer->startBand; band < hQmfTransposer->stopBand; - band++) { - FIXP_DBL tmpR = ppQmfBufferOutReal_F[i + ov_len][band]; - FIXP_DBL tmpI = ppQmfBufferOutImag_F[i + ov_len][band]; - - ppQmfBufferOutReal_F[i + ov_len][band] = - fMult(tmpR, cos_F[band]) - - fMult(tmpI, (-cos_F[64 - band - 1])); /* sum should be <= 1 - because of sin/cos - multiplication */ - ppQmfBufferOutImag_F[i + ov_len][band] = - fMult(tmpR, (-cos_F[64 - band - 1])) + - fMult(tmpI, cos_F[band]); /* sum should by <= 1 because of sin/cos - multiplication */ - } - } - } - } - - *scale_hb = EXP2SCALE(scale_factor_hbe); -} - -int* GetxOverBandQmfTransposer(HANDLE_HBE_TRANSPOSER hQmfTransposer) { - if (hQmfTransposer) - return hQmfTransposer->xOverQmf; - else - return NULL; -} - -int Get41SbrQmfTransposer(HANDLE_HBE_TRANSPOSER hQmfTransposer) { - if (hQmfTransposer != NULL) - return hQmfTransposer->bSbr41; - else - return 0; -} --- a/libSBRdec/src/hbe.h +++ /dev/null @@ -1,200 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -#ifndef HBE_H -#define HBE_H - -#include "sbrdecoder.h" - -#ifndef QMF_SYNTH_CHANNELS -#define QMF_SYNTH_CHANNELS (64) -#endif - -#define HBE_QMF_FILTER_STATE_ANA_SIZE (400) -#define HBE_QMF_FILTER_STATE_SYN_SIZE (200) - -#ifndef MAX_NUM_PATCHES_HBE -#define MAX_NUM_PATCHES_HBE (6) -#endif -#define MAX_STRETCH_HBE (4) - -typedef enum { - KEEP_STATES_SYNCED_OFF = 0, /*!< normal QMF transposer behaviour */ - KEEP_STATES_SYNCED_NORMAL = 1, /*!< QMF transposer called for syncing of - states the last 8/14 slots are calculated in - case next frame is HBE */ - KEEP_STATES_SYNCED_OUTDIFF = - 2, /*!< QMF transposer behaviour as in normal case, but the calculated - slots are directly written to overlap area of buffer; only used in - resetSbrDec function */ - KEEP_STATES_SYNCED_NOOUT = - 3 /*!< QMF transposer is called for syncing of states only, not output - is generated at all; only used in resetSbrDec function */ -} KEEP_STATES_SYNCED_MODE; - -struct hbeTransposer { - int xOverQmf[MAX_NUM_PATCHES_HBE]; - - int maxStretch; - int timeDomainWinLen; - int qmfInBufSize; - int qmfOutBufSize; - int noCols; - int noChannels; - int startBand; - int stopBand; - int bSbr41; - - INT_PCM *inBuf_F; - FIXP_DBL **qmfInBufReal_F; - FIXP_DBL **qmfInBufImag_F; - - FIXP_DBL *qmfBufferCodecTempSlot_F; - - QMF_FILTER_BANK HBEAnalysiscQMF; - QMF_FILTER_BANK HBESynthesisQMF; - - FIXP_DBL const *synthesisQmfPreModCos_F; - FIXP_DBL const *synthesisQmfPreModSin_F; - - FIXP_QAS anaQmfStates[HBE_QMF_FILTER_STATE_ANA_SIZE]; - FIXP_QSS synQmfStates[HBE_QMF_FILTER_STATE_SYN_SIZE]; - - FIXP_DBL **qmfHBEBufReal_F; - FIXP_DBL **qmfHBEBufImag_F; - - int bXProducts[MAX_STRETCH_HBE]; - - int kstart; - int synthSize; - - int highband_exp[2]; - int target_exp[2]; -}; - -typedef struct hbeTransposer *HANDLE_HBE_TRANSPOSER; - -SBR_ERROR QmfTransposerCreate(HANDLE_HBE_TRANSPOSER *hQmfTransposer, - const int frameSize, int bDisableCrossProducts, - int bSbr41); - -SBR_ERROR QmfTransposerReInit(HANDLE_HBE_TRANSPOSER hQmfTransposer, - UCHAR *FreqBandTable[2], UCHAR NSfb[2]); - -void QmfTransposerClose(HANDLE_HBE_TRANSPOSER hQmfTransposer); - -void QmfTransposerApply(HANDLE_HBE_TRANSPOSER hQmfTransposer, - FIXP_DBL **qmfBufferCodecReal, - FIXP_DBL **qmfBufferCodecImag, int nColsIn, - FIXP_DBL **ppQmfBufferOutReal_F, - FIXP_DBL **ppQmfBufferOutImag_F, - FIXP_DBL lpcFilterStatesReal[2 + (3 * (4))][(64)], - FIXP_DBL lpcFilterStatesImag[2 + (3 * (4))][(64)], - int pitchInBins, int scale_lb, int scale_hbe, - int *scale_hb, int timeStep, int firstSlotOffsset, - int ov_len, - KEEP_STATES_SYNCED_MODE keepStatesSyncedMode); - -int *GetxOverBandQmfTransposer(HANDLE_HBE_TRANSPOSER hQmfTransposer); - -int Get41SbrQmfTransposer(HANDLE_HBE_TRANSPOSER hQmfTransposer); -#endif /* HBE_H */ --- a/libSBRdec/src/huff_dec.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Huffman Decoder -*/ - -#include "huff_dec.h" - -/***************************************************************************/ -/*! - \brief Decodes one huffman code word - - Reads bits from the bitstream until a valid codeword is found. - The table entries are interpreted either as index to the next entry - or - if negative - as the codeword. - - \return decoded value - - \author - -****************************************************************************/ -int DecodeHuffmanCW(Huffman h, /*!< pointer to huffman codebook table */ - HANDLE_FDK_BITSTREAM hBs) /*!< Handle to Bitbuffer */ -{ - SCHAR index = 0; - int value, bit; - - while (index >= 0) { - bit = FDKreadBits(hBs, 1); - index = h[index][bit]; - } - - value = index + 64; /* Add offset */ - - return value; -} --- a/libSBRdec/src/huff_dec.h +++ /dev/null @@ -1,117 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Huffman Decoder -*/ -#ifndef HUFF_DEC_H -#define HUFF_DEC_H - -#include "sbrdecoder.h" -#include "FDK_bitstream.h" - -typedef const SCHAR (*Huffman)[2]; - -int DecodeHuffmanCW(Huffman h, HANDLE_FDK_BITSTREAM hBitBuf); - -#endif --- a/libSBRdec/src/lpp_tran.cpp +++ /dev/null @@ -1,1471 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Low Power Profile Transposer - This module provides the transposer. The main entry point is lppTransposer(). - The function generates high frequency content by copying data from the low - band (provided by core codec) into the high band. This process is also - referred to as "patching". The function also implements spectral whitening by - means of inverse filtering based on LPC coefficients. - - Together with the QMF filterbank the transposer can be tested using a supplied - test program. See main_audio.cpp for details. This module does use fractional - arithmetic and the accuracy of the computations has an impact on the overall - sound quality. The module also needs to take into account the different - scaling of spectral data. - - \sa lppTransposer(), main_audio.cpp, sbr_scale.h, \ref documentationOverview -*/ - -#ifdef __ANDROID__ -#include "log/log.h" -#endif - -#include "lpp_tran.h" - -#include "sbr_ram.h" -#include "sbr_rom.h" - -#include "genericStds.h" -#include "autocorr2nd.h" - -#include "HFgen_preFlat.h" - -#if defined(__arm__) -#include "arm/lpp_tran_arm.cpp" -#endif - -#define LPC_SCALE_FACTOR 2 - -/*! - * - * \brief Get bandwidth expansion factor from filtering level - * - * Returns a filter parameter (bandwidth expansion factor) depending on - * the desired filtering level signalled in the bitstream. - * When switching the filtering level from LOW to OFF, an additional - * level is being inserted to achieve a smooth transition. - */ - -static FIXP_DBL mapInvfMode(INVF_MODE mode, INVF_MODE prevMode, - WHITENING_FACTORS whFactors) { - switch (mode) { - case INVF_LOW_LEVEL: - if (prevMode == INVF_OFF) - return whFactors.transitionLevel; - else - return whFactors.lowLevel; - - case INVF_MID_LEVEL: - return whFactors.midLevel; - - case INVF_HIGH_LEVEL: - return whFactors.highLevel; - - default: - if (prevMode == INVF_LOW_LEVEL) - return whFactors.transitionLevel; - else - return whFactors.off; - } -} - -/*! - * - * \brief Perform inverse filtering level emphasis - * - * Retrieve bandwidth expansion factor and apply smoothing for each filter band - * - */ - -static void inverseFilteringLevelEmphasis( - HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer */ - UCHAR nInvfBands, /*!< Number of bands for inverse filtering */ - INVF_MODE *sbr_invf_mode, /*!< Current inverse filtering modes */ - INVF_MODE *sbr_invf_mode_prev, /*!< Previous inverse filtering modes */ - FIXP_DBL *bwVector /*!< Resulting filtering levels */ -) { - for (int i = 0; i < nInvfBands; i++) { - FIXP_DBL accu; - FIXP_DBL bwTmp = mapInvfMode(sbr_invf_mode[i], sbr_invf_mode_prev[i], - hLppTrans->pSettings->whFactors); - - if (bwTmp < hLppTrans->bwVectorOld[i]) { - accu = fMultDiv2(FL2FXCONST_DBL(0.75f), bwTmp) + - fMultDiv2(FL2FXCONST_DBL(0.25f), hLppTrans->bwVectorOld[i]); - } else { - accu = fMultDiv2(FL2FXCONST_DBL(0.90625f), bwTmp) + - fMultDiv2(FL2FXCONST_DBL(0.09375f), hLppTrans->bwVectorOld[i]); - } - - if (accu> 1) { - bwVector[i] = FL2FXCONST_DBL(0.0f); - } else { - bwVector[i] = fixMin(accu << 1, FL2FXCONST_DBL(0.99609375f)); - } - } -} - -/* Resulting autocorrelation determinant exponent */ -#define ACDET_EXP \ - (2 * (DFRACT_BITS + sbrScaleFactor->lb_scale + 10 - ac.det_scale)) -#define AC_EXP (-sbrScaleFactor->lb_scale + LPC_SCALE_FACTOR) -#define ALPHA_EXP (-sbrScaleFactor->lb_scale + LPC_SCALE_FACTOR + 1) -/* Resulting transposed QMF values exponent 16 bit normalized samplebits - * assumed. */ -#define QMFOUT_EXP ((SAMPLE_BITS - 15) - sbrScaleFactor->lb_scale) - -static inline void calc_qmfBufferReal(FIXP_DBL **qmfBufferReal, - const FIXP_DBL *const lowBandReal, - const int startSample, - const int stopSample, const UCHAR hiBand, - const int dynamicScale, const int descale, - const FIXP_SGL a0r, const FIXP_SGL a1r) { - FIXP_DBL accu1, accu2; - int i; - - for (i = 0; i < stopSample - startSample; i++) { - accu1 = fMultDiv2(a1r, lowBandReal[i]); - accu1 = (fMultDiv2(a0r, lowBandReal[i + 1]) + accu1); - accu1 = accu1 >> dynamicScale; - - accu1 <<= 1; - accu2 = (lowBandReal[i + 2] >> descale); - qmfBufferReal[i + startSample][hiBand] = accu1 + accu2; - } -} - -/*! - * - * \brief Perform transposition by patching of subband samples. - * This function serves as the main entry point into the module. The function - * determines the areas for the patching process (these are the source range as - * well as the target range) and implements spectral whitening by means of - * inverse filtering. The function autoCorrelation2nd() is an auxiliary function - * for calculating the LPC coefficients for the filtering. The actual - * calculation of the LPC coefficients and the implementation of the filtering - * are done as part of lppTransposer(). - * - * Note that the filtering is done on all available QMF subsamples, whereas the - * patching is only done on those QMF subsamples that will be used in the next - * QMF synthesis. The filtering is also implemented before the patching includes - * further dependencies on parameters from the SBR data. - * - */ - -void lppTransposer( - HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer */ - QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */ - FIXP_DBL **qmfBufferReal, /*!< Pointer to pointer to real part of subband - samples (source) */ - - FIXP_DBL *degreeAlias, /*!< Vector for results of aliasing estimation */ - FIXP_DBL **qmfBufferImag, /*!< Pointer to pointer to imaginary part of - subband samples (source) */ - const int useLP, const int fPreWhitening, const int v_k_master0, - const int timeStep, /*!< Time step of envelope */ - const int firstSlotOffs, /*!< Start position in time */ - const int lastSlotOffs, /*!< Number of overlap-slots into next frame */ - const int nInvfBands, /*!< Number of bands for inverse filtering */ - INVF_MODE *sbr_invf_mode, /*!< Current inverse filtering modes */ - INVF_MODE *sbr_invf_mode_prev /*!< Previous inverse filtering modes */ -) { - INT bwIndex[MAX_NUM_PATCHES]; - FIXP_DBL bwVector[MAX_NUM_PATCHES]; /*!< pole moving factors */ - FIXP_DBL preWhiteningGains[(64) / 2]; - int preWhiteningGains_exp[(64) / 2]; - - int i; - int loBand, start, stop; - TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings; - PATCH_PARAM *patchParam = pSettings->patchParam; - int patch; - - FIXP_SGL alphar[LPC_ORDER], a0r, a1r; - FIXP_SGL alphai[LPC_ORDER], a0i = 0, a1i = 0; - FIXP_SGL bw = FL2FXCONST_SGL(0.0f); - - int autoCorrLength; - - FIXP_DBL k1, k1_below = 0, k1_below2 = 0; - - ACORR_COEFS ac; - int startSample; - int stopSample; - int stopSampleClear; - - int comLowBandScale; - int ovLowBandShift; - int lowBandShift; - /* int ovHighBandShift;*/ - - alphai[0] = FL2FXCONST_SGL(0.0f); - alphai[1] = FL2FXCONST_SGL(0.0f); - - startSample = firstSlotOffs * timeStep; - stopSample = pSettings->nCols + lastSlotOffs * timeStep; - FDK_ASSERT((lastSlotOffs * timeStep) <= pSettings->overlap); - - inverseFilteringLevelEmphasis(hLppTrans, nInvfBands, sbr_invf_mode, - sbr_invf_mode_prev, bwVector); - - stopSampleClear = stopSample; - - autoCorrLength = pSettings->nCols + pSettings->overlap; - - if (pSettings->noOfPatches > 0) { - /* Set upper subbands to zero: - This is required in case that the patches do not cover the complete - highband (because the last patch would be too short). Possible - optimization: Clearing bands up to usb would be sufficient here. */ - int targetStopBand = - patchParam[pSettings->noOfPatches - 1].targetStartBand + - patchParam[pSettings->noOfPatches - 1].numBandsInPatch; - - int memSize = ((64) - targetStopBand) * sizeof(FIXP_DBL); - - if (!useLP) { - for (i = startSample; i < stopSampleClear; i++) { - FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize); - FDKmemclear(&qmfBufferImag[i][targetStopBand], memSize); - } - } else { - for (i = startSample; i < stopSampleClear; i++) { - FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize); - } - } - } -#ifdef __ANDROID__ - else { - // Safetynet logging - android_errorWriteLog(0x534e4554, "112160868"); - } -#endif - - /* init bwIndex for each patch */ - FDKmemclear(bwIndex, sizeof(bwIndex)); - - /* - Calc common low band scale factor - */ - comLowBandScale = - fixMin(sbrScaleFactor->ov_lb_scale, sbrScaleFactor->lb_scale); - - ovLowBandShift = sbrScaleFactor->ov_lb_scale - comLowBandScale; - lowBandShift = sbrScaleFactor->lb_scale - comLowBandScale; - /* ovHighBandShift = firstSlotOffs == 0 ? ovLowBandShift:0;*/ - - if (fPreWhitening) { - sbrDecoder_calculateGainVec( - qmfBufferReal, qmfBufferImag, - DFRACT_BITS - 1 - 16 - - sbrScaleFactor->ov_lb_scale, /* convert scale to exponent */ - DFRACT_BITS - 1 - 16 - - sbrScaleFactor->lb_scale, /* convert scale to exponent */ - pSettings->overlap, preWhiteningGains, preWhiteningGains_exp, - v_k_master0, startSample, stopSample); - } - - /* outer loop over bands to do analysis only once for each band */ - - if (!useLP) { - start = pSettings->lbStartPatching; - stop = pSettings->lbStopPatching; - } else { - start = fixMax(1, pSettings->lbStartPatching - 2); - stop = patchParam[0].targetStartBand; - } - - for (loBand = start; loBand < stop; loBand++) { - FIXP_DBL lowBandReal[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER]; - FIXP_DBL *plowBandReal = lowBandReal; - FIXP_DBL **pqmfBufferReal = - qmfBufferReal + firstSlotOffs * timeStep /* + pSettings->overlap */; - FIXP_DBL lowBandImag[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER]; - FIXP_DBL *plowBandImag = lowBandImag; - FIXP_DBL **pqmfBufferImag = - qmfBufferImag + firstSlotOffs * timeStep /* + pSettings->overlap */; - int resetLPCCoeffs = 0; - int dynamicScale = DFRACT_BITS - 1 - LPC_SCALE_FACTOR; - int acDetScale = 0; /* scaling of autocorrelation determinant */ - - for (i = 0; - i < LPC_ORDER + firstSlotOffs * timeStep /*+pSettings->overlap*/; - i++) { - *plowBandReal++ = hLppTrans->lpcFilterStatesRealLegSBR[i][loBand]; - if (!useLP) - *plowBandImag++ = hLppTrans->lpcFilterStatesImagLegSBR[i][loBand]; - } - - /* - Take old slope length qmf slot source values out of (overlap)qmf buffer - */ - if (!useLP) { - for (i = 0; - i < pSettings->nCols + pSettings->overlap - firstSlotOffs * timeStep; - i++) { - *plowBandReal++ = (*pqmfBufferReal++)[loBand]; - *plowBandImag++ = (*pqmfBufferImag++)[loBand]; - } - } else { - /* pSettings->overlap is always even */ - FDK_ASSERT((pSettings->overlap & 1) == 0); - for (i = 0; i < ((pSettings->nCols + pSettings->overlap - - firstSlotOffs * timeStep) >> - 1); - i++) { - *plowBandReal++ = (*pqmfBufferReal++)[loBand]; - *plowBandReal++ = (*pqmfBufferReal++)[loBand]; - } - if (pSettings->nCols & 1) { - *plowBandReal++ = (*pqmfBufferReal++)[loBand]; - } - } - - /* - Determine dynamic scaling value. - */ - dynamicScale = - fixMin(dynamicScale, - getScalefactor(lowBandReal, LPC_ORDER + pSettings->overlap) + - ovLowBandShift); - dynamicScale = - fixMin(dynamicScale, - getScalefactor(&lowBandReal[LPC_ORDER + pSettings->overlap], - pSettings->nCols) + - lowBandShift); - if (!useLP) { - dynamicScale = - fixMin(dynamicScale, - getScalefactor(lowBandImag, LPC_ORDER + pSettings->overlap) + - ovLowBandShift); - dynamicScale = - fixMin(dynamicScale, - getScalefactor(&lowBandImag[LPC_ORDER + pSettings->overlap], - pSettings->nCols) + - lowBandShift); - } - dynamicScale = fixMax( - 0, dynamicScale - 1); /* one additional bit headroom to prevent -1.0 */ - - /* - Scale temporal QMF buffer. - */ - scaleValues(&lowBandReal[0], LPC_ORDER + pSettings->overlap, - dynamicScale - ovLowBandShift); - scaleValues(&lowBandReal[LPC_ORDER + pSettings->overlap], pSettings->nCols, - dynamicScale - lowBandShift); - - if (!useLP) { - scaleValues(&lowBandImag[0], LPC_ORDER + pSettings->overlap, - dynamicScale - ovLowBandShift); - scaleValues(&lowBandImag[LPC_ORDER + pSettings->overlap], - pSettings->nCols, dynamicScale - lowBandShift); - } - - if (!useLP) { - acDetScale += autoCorr2nd_cplx(&ac, lowBandReal + LPC_ORDER, - lowBandImag + LPC_ORDER, autoCorrLength); - } else { - acDetScale += - autoCorr2nd_real(&ac, lowBandReal + LPC_ORDER, autoCorrLength); - } - - /* Examine dynamic of determinant in autocorrelation. */ - acDetScale += 2 * (comLowBandScale + dynamicScale); - acDetScale *= 2; /* two times reflection coefficent scaling */ - acDetScale += ac.det_scale; /* ac scaling of determinant */ - - /* In case of determinant < 10^-38, resetLPCCoeffs=1 has to be enforced. */ - if (acDetScale > 126) { - resetLPCCoeffs = 1; - } - - alphar[1] = FL2FXCONST_SGL(0.0f); - if (!useLP) alphai[1] = FL2FXCONST_SGL(0.0f); - - if (ac.det != FL2FXCONST_DBL(0.0f)) { - FIXP_DBL tmp, absTmp, absDet; - - absDet = fixp_abs(ac.det); - - if (!useLP) { - tmp = (fMultDiv2(ac.r01r, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) - - ((fMultDiv2(ac.r01i, ac.r12i) + fMultDiv2(ac.r02r, ac.r11r)) >> - (LPC_SCALE_FACTOR - 1)); - } else { - tmp = (fMultDiv2(ac.r01r, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) - - (fMultDiv2(ac.r02r, ac.r11r) >> (LPC_SCALE_FACTOR - 1)); - } - absTmp = fixp_abs(tmp); - - /* - Quick check: is first filter coeff >= 1(4) - */ - { - INT scale; - FIXP_DBL result = fDivNorm(absTmp, absDet, &scale); - scale = scale + ac.det_scale; - - if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) { - resetLPCCoeffs = 1; - } else { - alphar[1] = FX_DBL2FX_SGL(scaleValue(result, scale)); - if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) { - alphar[1] = -alphar[1]; - } - } - } - - if (!useLP) { - tmp = (fMultDiv2(ac.r01i, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) + - ((fMultDiv2(ac.r01r, ac.r12i) - - (FIXP_DBL)fMultDiv2(ac.r02i, ac.r11r)) >> - (LPC_SCALE_FACTOR - 1)); - - absTmp = fixp_abs(tmp); - - /* - Quick check: is second filter coeff >= 1(4) - */ - { - INT scale; - FIXP_DBL result = fDivNorm(absTmp, absDet, &scale); - scale = scale + ac.det_scale; - - if ((scale > 0) && - (result >= /*FL2FXCONST_DBL(1.f)*/ (FIXP_DBL)MAXVAL_DBL >> - scale)) { - resetLPCCoeffs = 1; - } else { - alphai[1] = FX_DBL2FX_SGL(scaleValue(result, scale)); - if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) { - alphai[1] = -alphai[1]; - } - } - } - } - } - - alphar[0] = FL2FXCONST_SGL(0.0f); - if (!useLP) alphai[0] = FL2FXCONST_SGL(0.0f); - - if (ac.r11r != FL2FXCONST_DBL(0.0f)) { - /* ac.r11r is always >=0 */ - FIXP_DBL tmp, absTmp; - - if (!useLP) { - tmp = (ac.r01r >> (LPC_SCALE_FACTOR + 1)) + - (fMultDiv2(alphar[1], ac.r12r) + fMultDiv2(alphai[1], ac.r12i)); - } else { - if (ac.r01r >= FL2FXCONST_DBL(0.0f)) - tmp = (ac.r01r >> (LPC_SCALE_FACTOR + 1)) + - fMultDiv2(alphar[1], ac.r12r); - else - tmp = -((-ac.r01r) >> (LPC_SCALE_FACTOR + 1)) + - fMultDiv2(alphar[1], ac.r12r); - } - - absTmp = fixp_abs(tmp); - - /* - Quick check: is first filter coeff >= 1(4) - */ - - if (absTmp >= (ac.r11r >> 1)) { - resetLPCCoeffs = 1; - } else { - INT scale; - FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale); - alphar[0] = FX_DBL2FX_SGL(scaleValue(result, scale + 1)); - - if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) - alphar[0] = -alphar[0]; - } - - if (!useLP) { - tmp = (ac.r01i >> (LPC_SCALE_FACTOR + 1)) + - (fMultDiv2(alphai[1], ac.r12r) - fMultDiv2(alphar[1], ac.r12i)); - - absTmp = fixp_abs(tmp); - - /* - Quick check: is second filter coeff >= 1(4) - */ - if (absTmp >= (ac.r11r >> 1)) { - resetLPCCoeffs = 1; - } else { - INT scale; - FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale); - alphai[0] = FX_DBL2FX_SGL(scaleValue(result, scale + 1)); - if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) - alphai[0] = -alphai[0]; - } - } - } - - if (!useLP) { - /* Now check the quadratic criteria */ - if ((fMultDiv2(alphar[0], alphar[0]) + fMultDiv2(alphai[0], alphai[0])) >= - FL2FXCONST_DBL(0.5f)) - resetLPCCoeffs = 1; - if ((fMultDiv2(alphar[1], alphar[1]) + fMultDiv2(alphai[1], alphai[1])) >= - FL2FXCONST_DBL(0.5f)) - resetLPCCoeffs = 1; - } - - if (resetLPCCoeffs) { - alphar[0] = FL2FXCONST_SGL(0.0f); - alphar[1] = FL2FXCONST_SGL(0.0f); - if (!useLP) { - alphai[0] = FL2FXCONST_SGL(0.0f); - alphai[1] = FL2FXCONST_SGL(0.0f); - } - } - - if (useLP) { - /* Aliasing detection */ - if (ac.r11r == FL2FXCONST_DBL(0.0f)) { - k1 = FL2FXCONST_DBL(0.0f); - } else { - if (fixp_abs(ac.r01r) >= fixp_abs(ac.r11r)) { - if (fMultDiv2(ac.r01r, ac.r11r) < FL2FX_DBL(0.0f)) { - k1 = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_SGL(1.0f)*/; - } else { - /* Since this value is squared later, it must not ever become -1.0f. - */ - k1 = (FIXP_DBL)(MINVAL_DBL + 1) /*FL2FXCONST_SGL(-1.0f)*/; - } - } else { - INT scale; - FIXP_DBL result = - fDivNorm(fixp_abs(ac.r01r), fixp_abs(ac.r11r), &scale); - k1 = scaleValue(result, scale); - - if (!((ac.r01r < FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f)))) { - k1 = -k1; - } - } - } - if ((loBand > 1) && (loBand < v_k_master0)) { - /* Check if the gain should be locked */ - FIXP_DBL deg = - /*FL2FXCONST_DBL(1.0f)*/ (FIXP_DBL)MAXVAL_DBL - fPow2(k1_below); - degreeAlias[loBand] = FL2FXCONST_DBL(0.0f); - if (((loBand & 1) == 0) && (k1 < FL2FXCONST_DBL(0.0f))) { - if (k1_below < FL2FXCONST_DBL(0.0f)) { /* 2-Ch Aliasing Detection */ - degreeAlias[loBand] = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_DBL(1.0f)*/; - if (k1_below2 > - FL2FXCONST_DBL(0.0f)) { /* 3-Ch Aliasing Detection */ - degreeAlias[loBand - 1] = deg; - } - } else if (k1_below2 > - FL2FXCONST_DBL(0.0f)) { /* 3-Ch Aliasing Detection */ - degreeAlias[loBand] = deg; - } - } - if (((loBand & 1) == 1) && (k1 > FL2FXCONST_DBL(0.0f))) { - if (k1_below > FL2FXCONST_DBL(0.0f)) { /* 2-CH Aliasing Detection */ - degreeAlias[loBand] = (FIXP_DBL)MAXVAL_DBL /*FL2FXCONST_DBL(1.0f)*/; - if (k1_below2 < - FL2FXCONST_DBL(0.0f)) { /* 3-CH Aliasing Detection */ - degreeAlias[loBand - 1] = deg; - } - } else if (k1_below2 < - FL2FXCONST_DBL(0.0f)) { /* 3-CH Aliasing Detection */ - degreeAlias[loBand] = deg; - } - } - } - /* remember k1 values of the 2 QMF channels below the current channel */ - k1_below2 = k1_below; - k1_below = k1; - } - - patch = 0; - - while (patch < pSettings->noOfPatches) { /* inner loop over every patch */ - - int hiBand = loBand + patchParam[patch].targetBandOffs; - - if (loBand < patchParam[patch].sourceStartBand || - loBand >= patchParam[patch].sourceStopBand - //|| hiBand >= hLppTrans->pSettings->noChannels - ) { - /* Lowband not in current patch - proceed */ - patch++; - continue; - } - - FDK_ASSERT(hiBand < (64)); - - /* bwIndex[patch] is already initialized with value from previous band - * inside this patch */ - while (hiBand >= pSettings->bwBorders[bwIndex[patch]] && - bwIndex[patch] < MAX_NUM_PATCHES - 1) { - bwIndex[patch]++; - } - - /* - Filter Step 2: add the left slope with the current filter to the buffer - pure source values are already in there - */ - bw = FX_DBL2FX_SGL(bwVector[bwIndex[patch]]); - - a0r = FX_DBL2FX_SGL( - fMult(bw, alphar[0])); /* Apply current bandwidth expansion factor */ - - if (!useLP) a0i = FX_DBL2FX_SGL(fMult(bw, alphai[0])); - bw = FX_DBL2FX_SGL(fPow2(bw)); - a1r = FX_DBL2FX_SGL(fMult(bw, alphar[1])); - if (!useLP) a1i = FX_DBL2FX_SGL(fMult(bw, alphai[1])); - - /* - Filter Step 3: insert the middle part which won't be windowed - */ - if (bw <= FL2FXCONST_SGL(0.0f)) { - if (!useLP) { - int descale = - fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale)); - for (i = startSample; i < stopSample; i++) { - FIXP_DBL accu1, accu2; - accu1 = lowBandReal[LPC_ORDER + i] >> descale; - accu2 = lowBandImag[LPC_ORDER + i] >> descale; - if (fPreWhitening) { - accu1 = scaleValueSaturate( - fMultDiv2(accu1, preWhiteningGains[loBand]), - preWhiteningGains_exp[loBand] + 1); - accu2 = scaleValueSaturate( - fMultDiv2(accu2, preWhiteningGains[loBand]), - preWhiteningGains_exp[loBand] + 1); - } - qmfBufferReal[i][hiBand] = accu1; - qmfBufferImag[i][hiBand] = accu2; - } - } else { - int descale = - fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale)); - for (i = startSample; i < stopSample; i++) { - qmfBufferReal[i][hiBand] = lowBandReal[LPC_ORDER + i] >> descale; - } - } - } else { /* bw <= 0 */ - - if (!useLP) { - int descale = - fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale)); -#ifdef FUNCTION_LPPTRANSPOSER_func1 - lppTransposer_func1( - lowBandReal + LPC_ORDER + startSample, - lowBandImag + LPC_ORDER + startSample, - qmfBufferReal + startSample, qmfBufferImag + startSample, - stopSample - startSample, (int)hiBand, dynamicScale, descale, a0r, - a0i, a1r, a1i, fPreWhitening, preWhiteningGains[loBand], - preWhiteningGains_exp[loBand] + 1); -#else - for (i = startSample; i < stopSample; i++) { - FIXP_DBL accu1, accu2; - - accu1 = (fMultDiv2(a0r, lowBandReal[LPC_ORDER + i - 1]) - - fMultDiv2(a0i, lowBandImag[LPC_ORDER + i - 1]) + - fMultDiv2(a1r, lowBandReal[LPC_ORDER + i - 2]) - - fMultDiv2(a1i, lowBandImag[LPC_ORDER + i - 2])) >> - dynamicScale; - accu2 = (fMultDiv2(a0i, lowBandReal[LPC_ORDER + i - 1]) + - fMultDiv2(a0r, lowBandImag[LPC_ORDER + i - 1]) + - fMultDiv2(a1i, lowBandReal[LPC_ORDER + i - 2]) + - fMultDiv2(a1r, lowBandImag[LPC_ORDER + i - 2])) >> - dynamicScale; - - accu1 = (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << 1); - accu2 = (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << 1); - if (fPreWhitening) { - accu1 = scaleValueSaturate( - fMultDiv2(accu1, preWhiteningGains[loBand]), - preWhiteningGains_exp[loBand] + 1); - accu2 = scaleValueSaturate( - fMultDiv2(accu2, preWhiteningGains[loBand]), - preWhiteningGains_exp[loBand] + 1); - } - qmfBufferReal[i][hiBand] = accu1; - qmfBufferImag[i][hiBand] = accu2; - } -#endif - } else { - FDK_ASSERT(dynamicScale >= 0); - calc_qmfBufferReal( - qmfBufferReal, &(lowBandReal[LPC_ORDER + startSample - 2]), - startSample, stopSample, hiBand, dynamicScale, - fMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale)), a0r, - a1r); - } - } /* bw <= 0 */ - - patch++; - - } /* inner loop over patches */ - - /* - * store the unmodified filter coefficients if there is - * an overlapping envelope - *****************************************************************/ - - } /* outer loop over bands (loBand) */ - - if (useLP) { - for (loBand = pSettings->lbStartPatching; - loBand < pSettings->lbStopPatching; loBand++) { - patch = 0; - while (patch < pSettings->noOfPatches) { - UCHAR hiBand = loBand + patchParam[patch].targetBandOffs; - - if (loBand < patchParam[patch].sourceStartBand || - loBand >= patchParam[patch].sourceStopBand || - hiBand >= (64) /* Highband out of range (biterror) */ - ) { - /* Lowband not in current patch or highband out of range (might be - * caused by biterrors)- proceed */ - patch++; - continue; - } - - if (hiBand != patchParam[patch].targetStartBand) - degreeAlias[hiBand] = degreeAlias[loBand]; - - patch++; - } - } /* end for loop */ - } - - for (i = 0; i < nInvfBands; i++) { - hLppTrans->bwVectorOld[i] = bwVector[i]; - } - - /* - set high band scale factor - */ - sbrScaleFactor->hb_scale = comLowBandScale - (LPC_SCALE_FACTOR); -} - -void lppTransposerHBE( - HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer */ - HANDLE_HBE_TRANSPOSER hQmfTransposer, - QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */ - FIXP_DBL **qmfBufferReal, /*!< Pointer to pointer to real part of subband - samples (source) */ - FIXP_DBL **qmfBufferImag, /*!< Pointer to pointer to imaginary part of - subband samples (source) */ - const int timeStep, /*!< Time step of envelope */ - const int firstSlotOffs, /*!< Start position in time */ - const int lastSlotOffs, /*!< Number of overlap-slots into next frame */ - const int nInvfBands, /*!< Number of bands for inverse filtering */ - INVF_MODE *sbr_invf_mode, /*!< Current inverse filtering modes */ - INVF_MODE *sbr_invf_mode_prev /*!< Previous inverse filtering modes */ -) { - INT bwIndex; - FIXP_DBL bwVector[MAX_NUM_PATCHES_HBE]; /*!< pole moving factors */ - - int i; - int loBand, start, stop; - TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings; - PATCH_PARAM *patchParam = pSettings->patchParam; - - FIXP_SGL alphar[LPC_ORDER], a0r, a1r; - FIXP_SGL alphai[LPC_ORDER], a0i = 0, a1i = 0; - FIXP_SGL bw = FL2FXCONST_SGL(0.0f); - - int autoCorrLength; - - ACORR_COEFS ac; - int startSample; - int stopSample; - int stopSampleClear; - - int comBandScale; - int ovLowBandShift; - int lowBandShift; - /* int ovHighBandShift;*/ - - alphai[0] = FL2FXCONST_SGL(0.0f); - alphai[1] = FL2FXCONST_SGL(0.0f); - - startSample = firstSlotOffs * timeStep; - stopSample = pSettings->nCols + lastSlotOffs * timeStep; - - inverseFilteringLevelEmphasis(hLppTrans, nInvfBands, sbr_invf_mode, - sbr_invf_mode_prev, bwVector); - - stopSampleClear = stopSample; - - autoCorrLength = pSettings->nCols + pSettings->overlap; - - if (pSettings->noOfPatches > 0) { - /* Set upper subbands to zero: - This is required in case that the patches do not cover the complete - highband (because the last patch would be too short). Possible - optimization: Clearing bands up to usb would be sufficient here. */ - int targetStopBand = - patchParam[pSettings->noOfPatches - 1].targetStartBand + - patchParam[pSettings->noOfPatches - 1].numBandsInPatch; - - int memSize = ((64) - targetStopBand) * sizeof(FIXP_DBL); - - for (i = startSample; i < stopSampleClear; i++) { - FDKmemclear(&qmfBufferReal[i][targetStopBand], memSize); - FDKmemclear(&qmfBufferImag[i][targetStopBand], memSize); - } - } -#ifdef __ANDROID__ - else { - // Safetynet logging - android_errorWriteLog(0x534e4554, "112160868"); - } -#endif - - /* - Calc common low band scale factor - */ - comBandScale = sbrScaleFactor->hb_scale; - - ovLowBandShift = sbrScaleFactor->hb_scale - comBandScale; - lowBandShift = sbrScaleFactor->hb_scale - comBandScale; - /* ovHighBandShift = firstSlotOffs == 0 ? ovLowBandShift:0;*/ - - /* outer loop over bands to do analysis only once for each band */ - - start = hQmfTransposer->startBand; - stop = hQmfTransposer->stopBand; - - for (loBand = start; loBand < stop; loBand++) { - bwIndex = 0; - - FIXP_DBL lowBandReal[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER]; - FIXP_DBL lowBandImag[(((1024) / (32) * (4) / 2) + (3 * (4))) + LPC_ORDER]; - - int resetLPCCoeffs = 0; - int dynamicScale = DFRACT_BITS - 1 - LPC_SCALE_FACTOR; - int acDetScale = 0; /* scaling of autocorrelation determinant */ - - for (i = 0; i < LPC_ORDER; i++) { - lowBandReal[i] = hLppTrans->lpcFilterStatesRealHBE[i][loBand]; - lowBandImag[i] = hLppTrans->lpcFilterStatesImagHBE[i][loBand]; - } - - for (; i < LPC_ORDER + firstSlotOffs * timeStep; i++) { - lowBandReal[i] = hLppTrans->lpcFilterStatesRealHBE[i][loBand]; - lowBandImag[i] = hLppTrans->lpcFilterStatesImagHBE[i][loBand]; - } - - /* - Take old slope length qmf slot source values out of (overlap)qmf buffer - */ - for (i = firstSlotOffs * timeStep; - i < pSettings->nCols + pSettings->overlap; i++) { - lowBandReal[i + LPC_ORDER] = qmfBufferReal[i][loBand]; - lowBandImag[i + LPC_ORDER] = qmfBufferImag[i][loBand]; - } - - /* store unmodified values to buffer */ - for (i = 0; i < LPC_ORDER + pSettings->overlap; i++) { - hLppTrans->lpcFilterStatesRealHBE[i][loBand] = - qmfBufferReal[pSettings->nCols - LPC_ORDER + i][loBand]; - hLppTrans->lpcFilterStatesImagHBE[i][loBand] = - qmfBufferImag[pSettings->nCols - LPC_ORDER + i][loBand]; - } - - /* - Determine dynamic scaling value. - */ - dynamicScale = - fixMin(dynamicScale, - getScalefactor(lowBandReal, LPC_ORDER + pSettings->overlap) + - ovLowBandShift); - dynamicScale = - fixMin(dynamicScale, - getScalefactor(&lowBandReal[LPC_ORDER + pSettings->overlap], - pSettings->nCols) + - lowBandShift); - dynamicScale = - fixMin(dynamicScale, - getScalefactor(lowBandImag, LPC_ORDER + pSettings->overlap) + - ovLowBandShift); - dynamicScale = - fixMin(dynamicScale, - getScalefactor(&lowBandImag[LPC_ORDER + pSettings->overlap], - pSettings->nCols) + - lowBandShift); - - dynamicScale = fixMax( - 0, dynamicScale - 1); /* one additional bit headroom to prevent -1.0 */ - - /* - Scale temporal QMF buffer. - */ - scaleValues(&lowBandReal[0], LPC_ORDER + pSettings->overlap, - dynamicScale - ovLowBandShift); - scaleValues(&lowBandReal[LPC_ORDER + pSettings->overlap], pSettings->nCols, - dynamicScale - lowBandShift); - scaleValues(&lowBandImag[0], LPC_ORDER + pSettings->overlap, - dynamicScale - ovLowBandShift); - scaleValues(&lowBandImag[LPC_ORDER + pSettings->overlap], pSettings->nCols, - dynamicScale - lowBandShift); - - acDetScale += autoCorr2nd_cplx(&ac, lowBandReal + LPC_ORDER, - lowBandImag + LPC_ORDER, autoCorrLength); - - /* Examine dynamic of determinant in autocorrelation. */ - acDetScale += 2 * (comBandScale + dynamicScale); - acDetScale *= 2; /* two times reflection coefficent scaling */ - acDetScale += ac.det_scale; /* ac scaling of determinant */ - - /* In case of determinant < 10^-38, resetLPCCoeffs=1 has to be enforced. */ - if (acDetScale > 126) { - resetLPCCoeffs = 1; - } - - alphar[1] = FL2FXCONST_SGL(0.0f); - alphai[1] = FL2FXCONST_SGL(0.0f); - - if (ac.det != FL2FXCONST_DBL(0.0f)) { - FIXP_DBL tmp, absTmp, absDet; - - absDet = fixp_abs(ac.det); - - tmp = (fMultDiv2(ac.r01r, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) - - ((fMultDiv2(ac.r01i, ac.r12i) + fMultDiv2(ac.r02r, ac.r11r)) >> - (LPC_SCALE_FACTOR - 1)); - absTmp = fixp_abs(tmp); - - /* - Quick check: is first filter coeff >= 1(4) - */ - { - INT scale; - FIXP_DBL result = fDivNorm(absTmp, absDet, &scale); - scale = scale + ac.det_scale; - - if ((scale > 0) && (result >= (FIXP_DBL)MAXVAL_DBL >> scale)) { - resetLPCCoeffs = 1; - } else { - alphar[1] = FX_DBL2FX_SGL(scaleValue(result, scale)); - if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) { - alphar[1] = -alphar[1]; - } - } - } - - tmp = (fMultDiv2(ac.r01i, ac.r12r) >> (LPC_SCALE_FACTOR - 1)) + - ((fMultDiv2(ac.r01r, ac.r12i) - - (FIXP_DBL)fMultDiv2(ac.r02i, ac.r11r)) >> - (LPC_SCALE_FACTOR - 1)); - - absTmp = fixp_abs(tmp); - - /* - Quick check: is second filter coeff >= 1(4) - */ - { - INT scale; - FIXP_DBL result = fDivNorm(absTmp, absDet, &scale); - scale = scale + ac.det_scale; - - if ((scale > 0) && - (result >= /*FL2FXCONST_DBL(1.f)*/ (FIXP_DBL)MAXVAL_DBL >> scale)) { - resetLPCCoeffs = 1; - } else { - alphai[1] = FX_DBL2FX_SGL(scaleValue(result, scale)); - if ((tmp < FL2FX_DBL(0.0f)) ^ (ac.det < FL2FX_DBL(0.0f))) { - alphai[1] = -alphai[1]; - } - } - } - } - - alphar[0] = FL2FXCONST_SGL(0.0f); - alphai[0] = FL2FXCONST_SGL(0.0f); - - if (ac.r11r != FL2FXCONST_DBL(0.0f)) { - /* ac.r11r is always >=0 */ - FIXP_DBL tmp, absTmp; - - tmp = (ac.r01r >> (LPC_SCALE_FACTOR + 1)) + - (fMultDiv2(alphar[1], ac.r12r) + fMultDiv2(alphai[1], ac.r12i)); - - absTmp = fixp_abs(tmp); - - /* - Quick check: is first filter coeff >= 1(4) - */ - - if (absTmp >= (ac.r11r >> 1)) { - resetLPCCoeffs = 1; - } else { - INT scale; - FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale); - alphar[0] = FX_DBL2FX_SGL(scaleValue(result, scale + 1)); - - if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) - alphar[0] = -alphar[0]; - } - - tmp = (ac.r01i >> (LPC_SCALE_FACTOR + 1)) + - (fMultDiv2(alphai[1], ac.r12r) - fMultDiv2(alphar[1], ac.r12i)); - - absTmp = fixp_abs(tmp); - - /* - Quick check: is second filter coeff >= 1(4) - */ - if (absTmp >= (ac.r11r >> 1)) { - resetLPCCoeffs = 1; - } else { - INT scale; - FIXP_DBL result = fDivNorm(absTmp, fixp_abs(ac.r11r), &scale); - alphai[0] = FX_DBL2FX_SGL(scaleValue(result, scale + 1)); - if ((tmp > FL2FX_DBL(0.0f)) ^ (ac.r11r < FL2FX_DBL(0.0f))) { - alphai[0] = -alphai[0]; - } - } - } - - /* Now check the quadratic criteria */ - if ((fMultDiv2(alphar[0], alphar[0]) + fMultDiv2(alphai[0], alphai[0])) >= - FL2FXCONST_DBL(0.5f)) { - resetLPCCoeffs = 1; - } - if ((fMultDiv2(alphar[1], alphar[1]) + fMultDiv2(alphai[1], alphai[1])) >= - FL2FXCONST_DBL(0.5f)) { - resetLPCCoeffs = 1; - } - - if (resetLPCCoeffs) { - alphar[0] = FL2FXCONST_SGL(0.0f); - alphar[1] = FL2FXCONST_SGL(0.0f); - alphai[0] = FL2FXCONST_SGL(0.0f); - alphai[1] = FL2FXCONST_SGL(0.0f); - } - - while (bwIndex < MAX_NUM_PATCHES - 1 && - loBand >= pSettings->bwBorders[bwIndex]) { - bwIndex++; - } - - /* - Filter Step 2: add the left slope with the current filter to the buffer - pure source values are already in there - */ - bw = FX_DBL2FX_SGL(bwVector[bwIndex]); - - a0r = FX_DBL2FX_SGL( - fMult(bw, alphar[0])); /* Apply current bandwidth expansion factor */ - a0i = FX_DBL2FX_SGL(fMult(bw, alphai[0])); - bw = FX_DBL2FX_SGL(fPow2(bw)); - a1r = FX_DBL2FX_SGL(fMult(bw, alphar[1])); - a1i = FX_DBL2FX_SGL(fMult(bw, alphai[1])); - - /* - Filter Step 3: insert the middle part which won't be windowed - */ - if (bw <= FL2FXCONST_SGL(0.0f)) { - int descale = fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale)); - for (i = startSample; i < stopSample; i++) { - qmfBufferReal[i][loBand] = lowBandReal[LPC_ORDER + i] >> descale; - qmfBufferImag[i][loBand] = lowBandImag[LPC_ORDER + i] >> descale; - } - } else { /* bw <= 0 */ - - int descale = fixMin(DFRACT_BITS - 1, (LPC_SCALE_FACTOR + dynamicScale)); - - for (i = startSample; i < stopSample; i++) { - FIXP_DBL accu1, accu2; - - accu1 = (fMultDiv2(a0r, lowBandReal[LPC_ORDER + i - 1]) - - fMultDiv2(a0i, lowBandImag[LPC_ORDER + i - 1]) + - fMultDiv2(a1r, lowBandReal[LPC_ORDER + i - 2]) - - fMultDiv2(a1i, lowBandImag[LPC_ORDER + i - 2])) >> - dynamicScale; - accu2 = (fMultDiv2(a0i, lowBandReal[LPC_ORDER + i - 1]) + - fMultDiv2(a0r, lowBandImag[LPC_ORDER + i - 1]) + - fMultDiv2(a1i, lowBandReal[LPC_ORDER + i - 2]) + - fMultDiv2(a1r, lowBandImag[LPC_ORDER + i - 2])) >> - dynamicScale; - - qmfBufferReal[i][loBand] = - (lowBandReal[LPC_ORDER + i] >> descale) + (accu1 << 1); - qmfBufferImag[i][loBand] = - (lowBandImag[LPC_ORDER + i] >> descale) + (accu2 << 1); - } - } /* bw <= 0 */ - - /* - * store the unmodified filter coefficients if there is - * an overlapping envelope - *****************************************************************/ - - } /* outer loop over bands (loBand) */ - - for (i = 0; i < nInvfBands; i++) { - hLppTrans->bwVectorOld[i] = bwVector[i]; - } - - /* - set high band scale factor - */ - sbrScaleFactor->hb_scale = comBandScale - (LPC_SCALE_FACTOR); -} - -/*! - * - * \brief Initialize one low power transposer instance - * - * - */ -SBR_ERROR -createLppTransposer( - HANDLE_SBR_LPP_TRANS hs, /*!< Handle of low power transposer */ - TRANSPOSER_SETTINGS *pSettings, /*!< Pointer to settings */ - const int highBandStartSb, /*!< ? */ - UCHAR *v_k_master, /*!< Master table */ - const int numMaster, /*!< Valid entries in master table */ - const int usb, /*!< Highband area stop subband */ - const int timeSlots, /*!< Number of time slots */ - const int nCols, /*!< Number of colums (codec qmf bank) */ - UCHAR *noiseBandTable, /*!< Mapping of SBR noise bands to QMF bands */ - const int noNoiseBands, /*!< Number of noise bands */ - UINT fs, /*!< Sample Frequency */ - const int chan, /*!< Channel number */ - const int overlap) { - /* FB inverse filtering settings */ - hs->pSettings = pSettings; - - pSettings->nCols = nCols; - pSettings->overlap = overlap; - - switch (timeSlots) { - case 15: - case 16: - break; - - default: - return SBRDEC_UNSUPPORTED_CONFIG; /* Unimplemented */ - } - - if (chan == 0) { - /* Init common data only once */ - hs->pSettings->nCols = nCols; - - return resetLppTransposer(hs, highBandStartSb, v_k_master, numMaster, - noiseBandTable, noNoiseBands, usb, fs); - } - return SBRDEC_OK; -} - -static int findClosestEntry(UCHAR goalSb, UCHAR *v_k_master, UCHAR numMaster, - UCHAR direction) { - int index; - - if (goalSb <= v_k_master[0]) return v_k_master[0]; - - if (goalSb >= v_k_master[numMaster]) return v_k_master[numMaster]; - - if (direction) { - index = 0; - while (v_k_master[index] < goalSb) { - index++; - } - } else { - index = numMaster; - while (v_k_master[index] > goalSb) { - index--; - } - } - - return v_k_master[index]; -} - -/*! - * - * \brief Reset memory for one lpp transposer instance - * - * \return SBRDEC_OK on success, SBRDEC_UNSUPPORTED_CONFIG on error - */ -SBR_ERROR -resetLppTransposer( - HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer */ - UCHAR highBandStartSb, /*!< High band area: start subband */ - UCHAR *v_k_master, /*!< Master table */ - UCHAR numMaster, /*!< Valid entries in master table */ - UCHAR *noiseBandTable, /*!< Mapping of SBR noise bands to QMF bands */ - UCHAR noNoiseBands, /*!< Number of noise bands */ - UCHAR usb, /*!< High band area: stop subband */ - UINT fs /*!< SBR output sampling frequency */ -) { - TRANSPOSER_SETTINGS *pSettings = hLppTrans->pSettings; - PATCH_PARAM *patchParam = pSettings->patchParam; - - int i, patch; - int targetStopBand; - int sourceStartBand; - int patchDistance; - int numBandsInPatch; - - int lsb = v_k_master[0]; /* Start subband expressed in "non-critical" sampling - terms*/ - int xoverOffset = highBandStartSb - - lsb; /* Calculate distance in QMF bands between k0 and kx */ - int startFreqHz; - - int desiredBorder; - - usb = fixMin(usb, v_k_master[numMaster]); /* Avoid endless loops (compare with - float code). */ - - /* - * Plausibility check - */ - - if (pSettings->nCols == 64) { - if (lsb < 4) { - /* 4:1 SBR Requirement k0 >= 4 missed! */ - return SBRDEC_UNSUPPORTED_CONFIG; - } - } else if (lsb - SHIFT_START_SB < 4) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - - /* - * Initialize the patching parameter - */ - /* ISO/IEC 14496-3 (Figure 4.48): goalSb = round( 2.048e6 / fs ) */ - desiredBorder = (((2048000 * 2) / fs) + 1) >> 1; - - desiredBorder = findClosestEntry(desiredBorder, v_k_master, numMaster, - 1); /* Adapt region to master-table */ - - /* First patch */ - sourceStartBand = SHIFT_START_SB + xoverOffset; - targetStopBand = lsb + xoverOffset; /* upperBand */ - - /* Even (odd) numbered channel must be patched to even (odd) numbered channel - */ - patch = 0; - while (targetStopBand < usb) { - /* Too many patches? - Allow MAX_NUM_PATCHES+1 patches here. - we need to check later again, since patch might be the highest patch - AND contain less than 3 bands => actual number of patches will be reduced - by 1. - */ - if (patch > MAX_NUM_PATCHES) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - - patchParam[patch].guardStartBand = targetStopBand; - patchParam[patch].targetStartBand = targetStopBand; - - numBandsInPatch = - desiredBorder - targetStopBand; /* Get the desired range of the patch */ - - if (numBandsInPatch >= lsb - sourceStartBand) { - /* Desired number bands are not available -> patch whole source range */ - patchDistance = - targetStopBand - sourceStartBand; /* Get the targetOffset */ - patchDistance = - patchDistance & ~1; /* Rounding off odd numbers and make all even */ - numBandsInPatch = - lsb - (targetStopBand - - patchDistance); /* Update number of bands to be patched */ - numBandsInPatch = findClosestEntry(targetStopBand + numBandsInPatch, - v_k_master, numMaster, 0) - - targetStopBand; /* Adapt region to master-table */ - } - - if (pSettings->nCols == 64) { - if (numBandsInPatch == 0 && sourceStartBand == SHIFT_START_SB) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - } - - /* Desired number bands are available -> get the minimal even patching - * distance */ - patchDistance = - numBandsInPatch + targetStopBand - lsb; /* Get minimal distance */ - patchDistance = (patchDistance + 1) & - ~1; /* Rounding up odd numbers and make all even */ - - if (numBandsInPatch > 0) { - patchParam[patch].sourceStartBand = targetStopBand - patchDistance; - patchParam[patch].targetBandOffs = patchDistance; - patchParam[patch].numBandsInPatch = numBandsInPatch; - patchParam[patch].sourceStopBand = - patchParam[patch].sourceStartBand + numBandsInPatch; - - targetStopBand += patchParam[patch].numBandsInPatch; - patch++; - } - - /* All patches but first */ - sourceStartBand = SHIFT_START_SB; - - /* Check if we are close to desiredBorder */ - if (desiredBorder - targetStopBand < 3) /* MPEG doc */ - { - desiredBorder = usb; - } - } - - patch--; - - /* If highest patch contains less than three subband: skip it */ - if ((patch > 0) && (patchParam[patch].numBandsInPatch < 3)) { - patch--; - targetStopBand = - patchParam[patch].targetStartBand + patchParam[patch].numBandsInPatch; - } - - /* now check if we don't have one too many */ - if (patch >= MAX_NUM_PATCHES) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - - pSettings->noOfPatches = patch + 1; - - /* Check lowest and highest source subband */ - pSettings->lbStartPatching = targetStopBand; - pSettings->lbStopPatching = 0; - for (patch = 0; patch < pSettings->noOfPatches; patch++) { - pSettings->lbStartPatching = - fixMin(pSettings->lbStartPatching, patchParam[patch].sourceStartBand); - pSettings->lbStopPatching = - fixMax(pSettings->lbStopPatching, patchParam[patch].sourceStopBand); - } - - for (i = 0; i < noNoiseBands; i++) { - pSettings->bwBorders[i] = noiseBandTable[i + 1]; - } - for (; i < MAX_NUM_NOISE_VALUES; i++) { - pSettings->bwBorders[i] = 255; - } - - /* - * Choose whitening factors - */ - - startFreqHz = - ((lsb + xoverOffset) * fs) >> 7; /* Shift does a division by 2*(64) */ - - for (i = 1; i < NUM_WHFACTOR_TABLE_ENTRIES; i++) { - if (startFreqHz < FDK_sbrDecoder_sbr_whFactorsIndex[i]) break; - } - i--; - - pSettings->whFactors.off = FDK_sbrDecoder_sbr_whFactorsTable[i][0]; - pSettings->whFactors.transitionLevel = - FDK_sbrDecoder_sbr_whFactorsTable[i][1]; - pSettings->whFactors.lowLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][2]; - pSettings->whFactors.midLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][3]; - pSettings->whFactors.highLevel = FDK_sbrDecoder_sbr_whFactorsTable[i][4]; - - return SBRDEC_OK; -} --- a/libSBRdec/src/lpp_tran.h +++ /dev/null @@ -1,275 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Low Power Profile Transposer -*/ - -#ifndef LPP_TRAN_H -#define LPP_TRAN_H - -#include "sbrdecoder.h" -#include "hbe.h" -#include "qmf.h" - -/* - Common -*/ -#define QMF_OUT_SCALE 8 - -/* - Frequency scales -*/ - -/* - Env-Adjust -*/ -#define MAX_NOISE_ENVELOPES 2 -#define MAX_NOISE_COEFFS 5 -#define MAX_NUM_NOISE_VALUES (MAX_NOISE_ENVELOPES * MAX_NOISE_COEFFS) -#define MAX_NUM_LIMITERS 12 - -/* Set MAX_ENVELOPES to the largest value of all supported BSFORMATs - by overriding MAX_ENVELOPES in the correct order: */ -#define MAX_ENVELOPES_LEGACY 5 -#define MAX_ENVELOPES_USAC 8 -#define MAX_ENVELOPES MAX_ENVELOPES_USAC - -#define MAX_FREQ_COEFFS_DUAL_RATE 48 -#define MAX_FREQ_COEFFS_QUAD_RATE 56 -#define MAX_FREQ_COEFFS MAX_FREQ_COEFFS_QUAD_RATE - -#define MAX_FREQ_COEFFS_FS44100 35 -#define MAX_FREQ_COEFFS_FS48000 32 - -#define MAX_NUM_ENVELOPE_VALUES (MAX_ENVELOPES * MAX_FREQ_COEFFS) - -#define MAX_GAIN_EXP 34 -/* Maximum gain will be sqrt(0.5 * 2^MAX_GAIN_EXP) - example: 34=99dB */ -#define MAX_GAIN_CONCEAL_EXP 1 -/* Maximum gain will be sqrt(0.5 * 2^MAX_GAIN_CONCEAL_EXP) in concealment case - * (0dB) */ - -/* - LPP Transposer -*/ -#define LPC_ORDER 2 - -#define MAX_INVF_BANDS MAX_NOISE_COEFFS - -#define MAX_NUM_PATCHES 6 -#define SHIFT_START_SB 1 /*!< lowest subband of source range */ - -typedef enum { - INVF_OFF = 0, - INVF_LOW_LEVEL, - INVF_MID_LEVEL, - INVF_HIGH_LEVEL, - INVF_SWITCHED /* not a real choice but used here to control behaviour */ -} INVF_MODE; - -/** parameter set for one single patch */ -typedef struct { - UCHAR sourceStartBand; /*!< first band in lowbands where to take the samples - from */ - UCHAR - sourceStopBand; /*!< first band in lowbands which is not included in the - patch anymore */ - UCHAR guardStartBand; /*!< first band in highbands to be filled with zeros in - order to reduce interferences between patches */ - UCHAR - targetStartBand; /*!< first band in highbands to be filled with whitened - lowband signal */ - UCHAR targetBandOffs; /*!< difference between 'startTargetBand' and - 'startSourceBand' */ - UCHAR numBandsInPatch; /*!< number of consecutive bands in this one patch */ -} PATCH_PARAM; - -/** whitening factors for different levels of whitening - need to be initialized corresponding to crossover frequency */ -typedef struct { - FIXP_DBL off; /*!< bw factor for signal OFF */ - FIXP_DBL transitionLevel; - FIXP_DBL lowLevel; /*!< bw factor for signal LOW_LEVEL */ - FIXP_DBL midLevel; /*!< bw factor for signal MID_LEVEL */ - FIXP_DBL highLevel; /*!< bw factor for signal HIGH_LEVEL */ -} WHITENING_FACTORS; - -/*! The transposer settings are calculated on a header reset and are shared by - * both channels. */ -typedef struct { - UCHAR nCols; /*!< number subsamples of a codec frame */ - UCHAR noOfPatches; /*!< number of patches */ - UCHAR lbStartPatching; /*!< first band of lowbands that will be patched */ - UCHAR lbStopPatching; /*!< first band that won't be patched anymore*/ - UCHAR bwBorders[MAX_NUM_NOISE_VALUES]; /*!< spectral bands with different - inverse filtering levels */ - - PATCH_PARAM - patchParam[MAX_NUM_PATCHES]; /*!< new parameter set for patching */ - WHITENING_FACTORS - whFactors; /*!< the pole moving factors for certain - whitening levels as indicated in the bitstream - depending on the crossover frequency */ - UCHAR overlap; /*!< Overlap size */ -} TRANSPOSER_SETTINGS; - -typedef struct { - TRANSPOSER_SETTINGS *pSettings; /*!< Common settings for both channels */ - FIXP_DBL - bwVectorOld[MAX_NUM_PATCHES]; /*!< pole moving factors of past frame */ - FIXP_DBL lpcFilterStatesRealLegSBR[LPC_ORDER + (3 * (4))][( - 32)]; /*!< pointer array to save filter states */ - - FIXP_DBL lpcFilterStatesImagLegSBR[LPC_ORDER + (3 * (4))][( - 32)]; /*!< pointer array to save filter states */ - - FIXP_DBL lpcFilterStatesRealHBE[LPC_ORDER + (3 * (4))][( - 64)]; /*!< pointer array to save filter states */ - FIXP_DBL lpcFilterStatesImagHBE[LPC_ORDER + (3 * (4))][( - 64)]; /*!< pointer array to save filter states */ -} SBR_LPP_TRANS; - -typedef SBR_LPP_TRANS *HANDLE_SBR_LPP_TRANS; - -void lppTransposer(HANDLE_SBR_LPP_TRANS hLppTrans, - QMF_SCALE_FACTOR *sbrScaleFactor, FIXP_DBL **qmfBufferReal, - - FIXP_DBL *degreeAlias, FIXP_DBL **qmfBufferImag, - const int useLP, const int fPreWhitening, - const int v_k_master0, const int timeStep, - const int firstSlotOffset, const int lastSlotOffset, - const int nInvfBands, INVF_MODE *sbr_invf_mode, - INVF_MODE *sbr_invf_mode_prev); - -void lppTransposerHBE( - HANDLE_SBR_LPP_TRANS hLppTrans, /*!< Handle of lpp transposer */ - HANDLE_HBE_TRANSPOSER hQmfTransposer, - QMF_SCALE_FACTOR *sbrScaleFactor, /*!< Scaling factors */ - FIXP_DBL **qmfBufferReal, /*!< Pointer to pointer to real part of subband - samples (source) */ - FIXP_DBL **qmfBufferImag, /*!< Pointer to pointer to imaginary part of - subband samples (source) */ - const int timeStep, /*!< Time step of envelope */ - const int firstSlotOffs, /*!< Start position in time */ - const int lastSlotOffs, /*!< Number of overlap-slots into next frame */ - const int nInvfBands, /*!< Number of bands for inverse filtering */ - INVF_MODE *sbr_invf_mode, /*!< Current inverse filtering modes */ - INVF_MODE *sbr_invf_mode_prev /*!< Previous inverse filtering modes */ -); - -SBR_ERROR -createLppTransposer(HANDLE_SBR_LPP_TRANS hLppTrans, - TRANSPOSER_SETTINGS *pSettings, const int highBandStartSb, - UCHAR *v_k_master, const int numMaster, const int usb, - const int timeSlots, const int nCols, UCHAR *noiseBandTable, - const int noNoiseBands, UINT fs, const int chan, - const int overlap); - -SBR_ERROR -resetLppTransposer(HANDLE_SBR_LPP_TRANS hLppTrans, UCHAR highBandStartSb, - UCHAR *v_k_master, UCHAR numMaster, UCHAR *noiseBandTable, - UCHAR noNoiseBands, UCHAR usb, UINT fs); - -#endif /* LPP_TRAN_H */ --- a/libSBRdec/src/psbitdec.cpp +++ /dev/null @@ -1,594 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -#include "psbitdec.h" - -#include "sbr_rom.h" -#include "huff_dec.h" - -/* PS dec privat functions */ -SBR_ERROR ResetPsDec(HANDLE_PS_DEC h_ps_d); - -/***************************************************************************/ -/*! - \brief huffman decoding by codebook table - - \return index of huffman codebook table - -****************************************************************************/ -static SCHAR decode_huff_cw( - Huffman h, /*!< pointer to huffman codebook table */ - HANDLE_FDK_BITSTREAM hBitBuf, /*!< Handle to Bitbuffer */ - int *length) /*!< length of huffman codeword (or NULL) */ -{ - UCHAR bit = 0; - SCHAR index = 0; - UCHAR bitCount = 0; - - while (index >= 0) { - bit = FDKreadBits(hBitBuf, 1); - bitCount++; - index = h[index][bit]; - } - if (length) { - *length = bitCount; - } - return (index + 64); /* Add offset */ -} - -/***************************************************************************/ -/*! - \brief helper function - limiting of value to min/max values - - \return limited value - -****************************************************************************/ - -static SCHAR limitMinMax(SCHAR i, SCHAR min, SCHAR max) { - if (i < min) - return min; - else if (i > max) - return max; - else - return i; -} - -/***************************************************************************/ -/*! - \brief Decodes delta values in-place and updates - data buffers according to quantization classes. - - When delta coded in frequency the first element is deltacode from zero. - aIndex buffer is decoded from delta values to actual values. - - \return none - -****************************************************************************/ -static void deltaDecodeArray( - SCHAR enable, SCHAR *aIndex, /*!< ICC/IID parameters */ - SCHAR *aPrevFrameIndex, /*!< ICC/IID parameters of previous frame */ - SCHAR DtDf, UCHAR nrElements, /*!< as conveyed in bitstream */ - /*!< output array size: nrElements*stride */ - UCHAR stride, /*!< 1=dflt, 2=half freq. resolution */ - SCHAR minIdx, SCHAR maxIdx) { - int i; - - /* Delta decode */ - if (enable == 1) { - if (DtDf == 0) { /* Delta coded in freq */ - aIndex[0] = 0 + aIndex[0]; - aIndex[0] = limitMinMax(aIndex[0], minIdx, maxIdx); - for (i = 1; i < nrElements; i++) { - aIndex[i] = aIndex[i - 1] + aIndex[i]; - aIndex[i] = limitMinMax(aIndex[i], minIdx, maxIdx); - } - } else { /* Delta time */ - for (i = 0; i < nrElements; i++) { - aIndex[i] = aPrevFrameIndex[i * stride] + aIndex[i]; - aIndex[i] = limitMinMax(aIndex[i], minIdx, maxIdx); - } - } - } else { /* No data is sent, set index to zero */ - for (i = 0; i < nrElements; i++) { - aIndex[i] = 0; - } - } - if (stride == 2) { - for (i = nrElements * stride - 1; i > 0; i--) { - aIndex[i] = aIndex[i >> 1]; - } - } -} - -/***************************************************************************/ -/*! - \brief Mapping of ICC/IID parameters to 20 stereo bands - - \return none - -****************************************************************************/ -static void map34IndexTo20(SCHAR *aIndex, /*!< decoded ICC/IID parameters */ - UCHAR noBins) /*!< number of stereo bands */ -{ - aIndex[0] = (2 * aIndex[0] + aIndex[1]) / 3; - aIndex[1] = (aIndex[1] + 2 * aIndex[2]) / 3; - aIndex[2] = (2 * aIndex[3] + aIndex[4]) / 3; - aIndex[3] = (aIndex[4] + 2 * aIndex[5]) / 3; - aIndex[4] = (aIndex[6] + aIndex[7]) / 2; - aIndex[5] = (aIndex[8] + aIndex[9]) / 2; - aIndex[6] = aIndex[10]; - aIndex[7] = aIndex[11]; - aIndex[8] = (aIndex[12] + aIndex[13]) / 2; - aIndex[9] = (aIndex[14] + aIndex[15]) / 2; - aIndex[10] = aIndex[16]; - /* For IPD/OPD it stops here */ - - if (noBins == NO_HI_RES_BINS) { - aIndex[11] = aIndex[17]; - aIndex[12] = aIndex[18]; - aIndex[13] = aIndex[19]; - aIndex[14] = (aIndex[20] + aIndex[21]) / 2; - aIndex[15] = (aIndex[22] + aIndex[23]) / 2; - aIndex[16] = (aIndex[24] + aIndex[25]) / 2; - aIndex[17] = (aIndex[26] + aIndex[27]) / 2; - aIndex[18] = (aIndex[28] + aIndex[29] + aIndex[30] + aIndex[31]) / 4; - aIndex[19] = (aIndex[32] + aIndex[33]) / 2; - } -} - -/***************************************************************************/ -/*! - \brief Decodes delta coded IID, ICC, IPD and OPD indices - - \return PS processing flag. If set to 1 - -****************************************************************************/ -int DecodePs(struct PS_DEC *h_ps_d, /*!< PS handle */ - const UCHAR frameError, /*!< Flag telling that frame had errors */ - PS_DEC_COEFFICIENTS *pScratch) { - MPEG_PS_BS_DATA *pBsData; - UCHAR gr, env; - int bPsHeaderValid, bPsDataAvail; - - /* Assign Scratch */ - h_ps_d->specificTo.mpeg.pCoef = pScratch; - - /* Shortcuts to avoid deferencing and keep the code readable */ - pBsData = &h_ps_d->bsData[h_ps_d->processSlot].mpeg; - bPsHeaderValid = pBsData->bPsHeaderValid; - bPsDataAvail = - (h_ps_d->bPsDataAvail[h_ps_d->processSlot] == ppt_mpeg) ? 1 : 0; - - /*************************************************************************************** - * Decide whether to process or to conceal PS data or not. */ - - if ((h_ps_d->psDecodedPrv && !frameError && !bPsDataAvail) || - (!h_ps_d->psDecodedPrv && - (frameError || !bPsDataAvail || !bPsHeaderValid))) { - /* Don't apply PS processing. - * Declare current PS header and bitstream data invalid. */ - pBsData->bPsHeaderValid = 0; - h_ps_d->bPsDataAvail[h_ps_d->processSlot] = ppt_none; - return (0); - } - - if (frameError || - !bPsHeaderValid) { /* no new PS data available (e.g. frame loss) */ - /* => keep latest data constant (i.e. FIX with noEnv=0) */ - pBsData->noEnv = 0; - } - - /*************************************************************************************** - * Decode bitstream payload or prepare parameter for concealment: - */ - for (env = 0; env < pBsData->noEnv; env++) { - SCHAR *aPrevIidIndex; - SCHAR *aPrevIccIndex; - - UCHAR noIidSteps = pBsData->bFineIidQ ? NO_IID_STEPS_FINE : NO_IID_STEPS; - - if (env == 0) { - aPrevIidIndex = h_ps_d->specificTo.mpeg.aIidPrevFrameIndex; - aPrevIccIndex = h_ps_d->specificTo.mpeg.aIccPrevFrameIndex; - } else { - aPrevIidIndex = pBsData->aaIidIndex[env - 1]; - aPrevIccIndex = pBsData->aaIccIndex[env - 1]; - } - - deltaDecodeArray(pBsData->bEnableIid, pBsData->aaIidIndex[env], - aPrevIidIndex, pBsData->abIidDtFlag[env], - FDK_sbrDecoder_aNoIidBins[pBsData->freqResIid], - (pBsData->freqResIid) ? 1 : 2, -noIidSteps, noIidSteps); - - deltaDecodeArray(pBsData->bEnableIcc, pBsData->aaIccIndex[env], - aPrevIccIndex, pBsData->abIccDtFlag[env], - FDK_sbrDecoder_aNoIccBins[pBsData->freqResIcc], - (pBsData->freqResIcc) ? 1 : 2, 0, NO_ICC_STEPS - 1); - } /* for (env=0; envnoEnv; env++) */ - - /* handling of FIX noEnv=0 */ - if (pBsData->noEnv == 0) { - /* set noEnv=1, keep last parameters or force 0 if not enabled */ - pBsData->noEnv = 1; - - if (pBsData->bEnableIid) { - pBsData->bFineIidQ = h_ps_d->specificTo.mpeg.bPrevFrameFineIidQ; - pBsData->freqResIid = h_ps_d->specificTo.mpeg.prevFreqResIid; - for (gr = 0; gr < NO_HI_RES_IID_BINS; gr++) { - pBsData->aaIidIndex[pBsData->noEnv - 1][gr] = - h_ps_d->specificTo.mpeg.aIidPrevFrameIndex[gr]; - } - } else { - for (gr = 0; gr < NO_HI_RES_IID_BINS; gr++) { - pBsData->aaIidIndex[pBsData->noEnv - 1][gr] = 0; - } - } - - if (pBsData->bEnableIcc) { - pBsData->freqResIcc = h_ps_d->specificTo.mpeg.prevFreqResIcc; - for (gr = 0; gr < NO_HI_RES_ICC_BINS; gr++) { - pBsData->aaIccIndex[pBsData->noEnv - 1][gr] = - h_ps_d->specificTo.mpeg.aIccPrevFrameIndex[gr]; - } - } else { - for (gr = 0; gr < NO_HI_RES_ICC_BINS; gr++) { - pBsData->aaIccIndex[pBsData->noEnv - 1][gr] = 0; - } - } - } - - /* Update previous frame Iid quantization */ - h_ps_d->specificTo.mpeg.bPrevFrameFineIidQ = pBsData->bFineIidQ; - - /* Update previous frequency resolution for IID */ - h_ps_d->specificTo.mpeg.prevFreqResIid = pBsData->freqResIid; - - /* Update previous frequency resolution for ICC */ - h_ps_d->specificTo.mpeg.prevFreqResIcc = pBsData->freqResIcc; - - /* Update previous frame index buffers */ - for (gr = 0; gr < NO_HI_RES_IID_BINS; gr++) { - h_ps_d->specificTo.mpeg.aIidPrevFrameIndex[gr] = - pBsData->aaIidIndex[pBsData->noEnv - 1][gr]; - } - for (gr = 0; gr < NO_HI_RES_ICC_BINS; gr++) { - h_ps_d->specificTo.mpeg.aIccPrevFrameIndex[gr] = - pBsData->aaIccIndex[pBsData->noEnv - 1][gr]; - } - - /* PS data from bitstream (if avail) was decoded now */ - h_ps_d->bPsDataAvail[h_ps_d->processSlot] = ppt_none; - - /* handling of env borders for FIX & VAR */ - if (pBsData->bFrameClass == 0) { - /* FIX_BORDERS NoEnv=0,1,2,4 */ - pBsData->aEnvStartStop[0] = 0; - for (env = 1; env < pBsData->noEnv; env++) { - pBsData->aEnvStartStop[env] = - (env * h_ps_d->noSubSamples) / pBsData->noEnv; - } - pBsData->aEnvStartStop[pBsData->noEnv] = h_ps_d->noSubSamples; - /* 1024 (32 slots) env borders: 0, 8, 16, 24, 32 */ - /* 960 (30 slots) env borders: 0, 7, 15, 22, 30 */ - } else { /* if (h_ps_d->bFrameClass == 0) */ - /* VAR_BORDERS NoEnv=1,2,3,4 */ - pBsData->aEnvStartStop[0] = 0; - - /* handle case aEnvStartStop[noEnv]aEnvStartStop[pBsData->noEnv] < h_ps_d->noSubSamples) { - for (gr = 0; gr < NO_HI_RES_IID_BINS; gr++) { - pBsData->aaIidIndex[pBsData->noEnv][gr] = - pBsData->aaIidIndex[pBsData->noEnv - 1][gr]; - } - for (gr = 0; gr < NO_HI_RES_ICC_BINS; gr++) { - pBsData->aaIccIndex[pBsData->noEnv][gr] = - pBsData->aaIccIndex[pBsData->noEnv - 1][gr]; - } - pBsData->noEnv++; - pBsData->aEnvStartStop[pBsData->noEnv] = h_ps_d->noSubSamples; - } - - /* enforce strictly monotonic increasing borders */ - for (env = 1; env < pBsData->noEnv; env++) { - UCHAR thr; - thr = (UCHAR)h_ps_d->noSubSamples - (pBsData->noEnv - env); - if (pBsData->aEnvStartStop[env] > thr) { - pBsData->aEnvStartStop[env] = thr; - } else { - thr = pBsData->aEnvStartStop[env - 1] + 1; - if (pBsData->aEnvStartStop[env] < thr) { - pBsData->aEnvStartStop[env] = thr; - } - } - } - } /* if (h_ps_d->bFrameClass == 0) ... else */ - - /* copy data prior to possible 20<->34 in-place mapping */ - for (env = 0; env < pBsData->noEnv; env++) { - UCHAR i; - for (i = 0; i < NO_HI_RES_IID_BINS; i++) { - h_ps_d->specificTo.mpeg.pCoef->aaIidIndexMapped[env][i] = - pBsData->aaIidIndex[env][i]; - } - for (i = 0; i < NO_HI_RES_ICC_BINS; i++) { - h_ps_d->specificTo.mpeg.pCoef->aaIccIndexMapped[env][i] = - pBsData->aaIccIndex[env][i]; - } - } - - /* MPEG baseline PS */ - /* Baseline version of PS always uses the hybrid filter structure with 20 - * stereo bands. */ - /* If ICC/IID parameters for 34 stereo bands are decoded they have to be - * mapped to 20 */ - /* stereo bands. */ - /* Additionaly the IPD/OPD parameters won't be used. */ - - for (env = 0; env < pBsData->noEnv; env++) { - if (pBsData->freqResIid == 2) - map34IndexTo20(h_ps_d->specificTo.mpeg.pCoef->aaIidIndexMapped[env], - NO_HI_RES_IID_BINS); - if (pBsData->freqResIcc == 2) - map34IndexTo20(h_ps_d->specificTo.mpeg.pCoef->aaIccIndexMapped[env], - NO_HI_RES_ICC_BINS); - - /* IPD/OPD is disabled in baseline version and thus was removed here */ - } - - return (1); -} - -/***************************************************************************/ -/*! - - \brief Reads parametric stereo data from bitstream - - \return - -****************************************************************************/ -unsigned int ReadPsData( - HANDLE_PS_DEC h_ps_d, /*!< handle to struct PS_DEC */ - HANDLE_FDK_BITSTREAM hBitBuf, /*!< handle to struct BIT_BUF */ - int nBitsLeft /*!< max number of bits available */ -) { - MPEG_PS_BS_DATA *pBsData; - - UCHAR gr, env; - SCHAR dtFlag; - INT startbits; - Huffman CurrentTable; - SCHAR bEnableHeader; - - if (!h_ps_d) return 0; - - pBsData = &h_ps_d->bsData[h_ps_d->bsReadSlot].mpeg; - - if (h_ps_d->bsReadSlot != h_ps_d->bsLastSlot) { - /* Copy last header data */ - FDKmemcpy(pBsData, &h_ps_d->bsData[h_ps_d->bsLastSlot].mpeg, - sizeof(MPEG_PS_BS_DATA)); - } - - startbits = (INT)FDKgetValidBits(hBitBuf); - - bEnableHeader = (SCHAR)FDKreadBits(hBitBuf, 1); - - /* Read header */ - if (bEnableHeader) { - pBsData->bPsHeaderValid = 1; - pBsData->bEnableIid = (UCHAR)FDKreadBits(hBitBuf, 1); - if (pBsData->bEnableIid) { - pBsData->modeIid = (UCHAR)FDKreadBits(hBitBuf, 3); - } - - pBsData->bEnableIcc = (UCHAR)FDKreadBits(hBitBuf, 1); - if (pBsData->bEnableIcc) { - pBsData->modeIcc = (UCHAR)FDKreadBits(hBitBuf, 3); - } - - pBsData->bEnableExt = (UCHAR)FDKreadBits(hBitBuf, 1); - } - - pBsData->bFrameClass = (UCHAR)FDKreadBits(hBitBuf, 1); - if (pBsData->bFrameClass == 0) { - /* FIX_BORDERS NoEnv=0,1,2,4 */ - pBsData->noEnv = - FDK_sbrDecoder_aFixNoEnvDecode[(UCHAR)FDKreadBits(hBitBuf, 2)]; - /* all additional handling of env borders is now in DecodePs() */ - } else { - /* VAR_BORDERS NoEnv=1,2,3,4 */ - pBsData->noEnv = 1 + (UCHAR)FDKreadBits(hBitBuf, 2); - for (env = 1; env < pBsData->noEnv + 1; env++) - pBsData->aEnvStartStop[env] = ((UCHAR)FDKreadBits(hBitBuf, 5)) + 1; - /* all additional handling of env borders is now in DecodePs() */ - } - - /* verify that IID & ICC modes (quant grid, freq res) are supported */ - if ((pBsData->modeIid > 5) || (pBsData->modeIcc > 5)) { - /* no useful PS data could be read from bitstream */ - h_ps_d->bPsDataAvail[h_ps_d->bsReadSlot] = ppt_none; - /* discard all remaining bits */ - nBitsLeft -= startbits - (INT)FDKgetValidBits(hBitBuf); - while (nBitsLeft > 0) { - int i = nBitsLeft; - if (i > 8) { - i = 8; - } - FDKreadBits(hBitBuf, i); - nBitsLeft -= i; - } - return (UINT)(startbits - (INT)FDKgetValidBits(hBitBuf)); - } - - if (pBsData->modeIid > 2) { - pBsData->freqResIid = pBsData->modeIid - 3; - pBsData->bFineIidQ = 1; - } else { - pBsData->freqResIid = pBsData->modeIid; - pBsData->bFineIidQ = 0; - } - - if (pBsData->modeIcc > 2) { - pBsData->freqResIcc = pBsData->modeIcc - 3; - } else { - pBsData->freqResIcc = pBsData->modeIcc; - } - - /* Extract IID data */ - if (pBsData->bEnableIid) { - for (env = 0; env < pBsData->noEnv; env++) { - dtFlag = (SCHAR)FDKreadBits(hBitBuf, 1); - if (!dtFlag) { - if (pBsData->bFineIidQ) - CurrentTable = (Huffman)&aBookPsIidFineFreqDecode; - else - CurrentTable = (Huffman)&aBookPsIidFreqDecode; - } else { - if (pBsData->bFineIidQ) - CurrentTable = (Huffman)&aBookPsIidFineTimeDecode; - else - CurrentTable = (Huffman)&aBookPsIidTimeDecode; - } - - for (gr = 0; gr < FDK_sbrDecoder_aNoIidBins[pBsData->freqResIid]; gr++) - pBsData->aaIidIndex[env][gr] = - decode_huff_cw(CurrentTable, hBitBuf, NULL); - pBsData->abIidDtFlag[env] = dtFlag; - } - } - - /* Extract ICC data */ - if (pBsData->bEnableIcc) { - for (env = 0; env < pBsData->noEnv; env++) { - dtFlag = (SCHAR)FDKreadBits(hBitBuf, 1); - if (!dtFlag) - CurrentTable = (Huffman)&aBookPsIccFreqDecode; - else - CurrentTable = (Huffman)&aBookPsIccTimeDecode; - - for (gr = 0; gr < FDK_sbrDecoder_aNoIccBins[pBsData->freqResIcc]; gr++) - pBsData->aaIccIndex[env][gr] = - decode_huff_cw(CurrentTable, hBitBuf, NULL); - pBsData->abIccDtFlag[env] = dtFlag; - } - } - - if (pBsData->bEnableExt) { - /*! - Decoders that support only the baseline version of the PS tool are allowed - to ignore the IPD/OPD data, but according header data has to be parsed. - ISO/IEC 14496-3 Subpart 8 Annex 4 - */ - - int cnt = FDKreadBits(hBitBuf, PS_EXTENSION_SIZE_BITS); - if (cnt == (1 << PS_EXTENSION_SIZE_BITS) - 1) { - cnt += FDKreadBits(hBitBuf, PS_EXTENSION_ESC_COUNT_BITS); - } - while (cnt--) FDKreadBits(hBitBuf, 8); - } - - /* new PS data was read from bitstream */ - h_ps_d->bPsDataAvail[h_ps_d->bsReadSlot] = ppt_mpeg; - - return (startbits - (INT)FDKgetValidBits(hBitBuf)); -} --- a/libSBRdec/src/psbitdec.h +++ /dev/null @@ -1,116 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -#ifndef PSBITDEC_H -#define PSBITDEC_H - -#include "sbrdecoder.h" - -#include "psdec.h" - -unsigned int ReadPsData(struct PS_DEC *h_ps_d, HANDLE_FDK_BITSTREAM hBs, - int nBitsLeft); - -int DecodePs(struct PS_DEC *h_ps_d, const UCHAR frameError, - PS_DEC_COEFFICIENTS *pCoef); - -#endif /* PSBITDEC_H */ --- a/libSBRdec/src/psdec.cpp +++ /dev/null @@ -1,722 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief parametric stereo decoder -*/ - -#include "psdec.h" - -#include "FDK_bitbuffer.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); - -/***** HELPERS *****/ - -/***************************************************************************/ -/*! - \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) { - goto bail; - } - } else { - /* Reset an open instance */ - h_ps_d = *h_PS_DEC; - } - - /* - * Create Analysis Hybrid filterbank. - */ - FDKhybridAnalysisOpen(&h_ps_d->specificTo.mpeg.hybridAnalysis, - h_ps_d->specificTo.mpeg.pHybridAnaStatesLFdmx, - sizeof(h_ps_d->specificTo.mpeg.pHybridAnaStatesLFdmx), - NULL, 0); - - /* 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; - } - { - int error; - error = FDKdecorrelateOpen(&(h_ps_d->specificTo.mpeg.apDecor), - h_ps_d->specificTo.mpeg.decorrBufferCplx, - (2 * ((825) + (373)))); - if (error) goto bail; - } - - 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; - - *h_PS_DEC = h_ps_d; - - return 0; - -bail: - if (h_ps_d != NULL) { - 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; - } - - { - HANDLE_PS_DEC h_ps_d = *h_PS_DEC; - FDKdecorrelateClose(&(h_ps_d->specificTo.mpeg.apDecor)); - } - - 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; - - /* explicitly init state variables to safe values (until first ps header - * arrives) */ - - h_ps_d->specificTo.mpeg.lastUsb = 0; - - /* - * Initialize Analysis Hybrid filterbank. - */ - FDKhybridAnalysisInit(&h_ps_d->specificTo.mpeg.hybridAnalysis, THREE_TO_TEN, - NO_QMF_BANDS_HYBRID20, NO_QMF_BANDS_HYBRID20, 1); - - /* - * Initialize Synthesis Hybrid filterbank. - */ - for (i = 0; i < 2; i++) { - FDKhybridSynthesisInit(&h_ps_d->specificTo.mpeg.hybridSynthesis[i], - THREE_TO_TEN, NO_QMF_CHANNELS, NO_QMF_CHANNELS); - } - { - INT error; - error = FDKdecorrelateInit(&h_ps_d->specificTo.mpeg.apDecor, 71, DECORR_PS, - DUCKER_AUTOMATIC, 0, 0, 0, 0, 1, /* isLegacyPS */ - 1); - if (error) return SBRDEC_NOT_INITIALIZED; - } - - 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 Feed delaylines when parametric stereo is switched on. - \return -****************************************************************************/ -void PreparePsProcessing(HANDLE_PS_DEC h_ps_d, - const FIXP_DBL *const *const rIntBufferLeft, - const FIXP_DBL *const *const iIntBufferLeft, - const int scaleFactorLowBand) { - if (h_ps_d->procFrameBased == - 1) /* If we have switched from frame to slot based processing */ - { /* fill hybrid delay buffer. */ - int i, j; - - for (i = 0; i < HYBRID_FILTER_DELAY; i++) { - FIXP_DBL qmfInputData[2][NO_QMF_BANDS_HYBRID20]; - FIXP_DBL hybridOutputData[2][NO_SUB_QMF_CHANNELS]; - - for (j = 0; j < NO_QMF_BANDS_HYBRID20; j++) { - qmfInputData[0][j] = - scaleValue(rIntBufferLeft[i][j], scaleFactorLowBand); - qmfInputData[1][j] = - scaleValue(iIntBufferLeft[i][j], scaleFactorLowBand); - } - - FDKhybridAnalysisApply(&h_ps_d->specificTo.mpeg.hybridAnalysis, - qmfInputData[0], qmfInputData[1], - hybridOutputData[0], hybridOutputData[1]); - } - h_ps_d->procFrameBased = 0; /* switch to slot based processing. */ - - } /* procFrameBased==1 */ -} - -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, noFactors; - - FIXP_SGL invL; - FIXP_DBL ScaleL, ScaleR; - FIXP_DBL Alpha, Beta, AlphasValue; - FIXP_DBL h11r, h12r, h21r, h22r; - - const FIXP_DBL *PScaleFactors; - - if (h_ps_d->bsData[h_ps_d->processSlot].mpeg.bFineIidQ) { - PScaleFactors = ScaleFactorsFine; /* values are shiftet right by one */ - noIidSteps = NO_IID_STEPS_FINE; - noFactors = NO_IID_LEVELS_FINE; - } else { - PScaleFactors = ScaleFactors; /* values are shiftet right by one */ - noIidSteps = NO_IID_STEPS; - noFactors = NO_IID_LEVELS; - } - - /* dequantize and decode */ - for (group = 0; group < NO_IID_GROUPS; group++) { - bin = bins2groupMap20[group]; - - /*! -

type 'A' rotation

- mixing procedure R_a, used in baseline version
- - 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 */ - - ScaleL = ScaleR = 0; - if (noIidSteps + h_ps_d->specificTo.mpeg.pCoef->aaIidIndexMapped[env][bin] >= 0 && noIidSteps + h_ps_d->specificTo.mpeg.pCoef->aaIidIndexMapped[env][bin] < noFactors) - ScaleR = PScaleFactors[noIidSteps + h_ps_d->specificTo.mpeg.pCoef - ->aaIidIndexMapped[env][bin]]; - if (noIidSteps - h_ps_d->specificTo.mpeg.pCoef->aaIidIndexMapped[env][bin] >= 0 && noIidSteps - h_ps_d->specificTo.mpeg.pCoef->aaIidIndexMapped[env][bin] < noFactors) - ScaleL = PScaleFactors[noIidSteps - h_ps_d->specificTo.mpeg.pCoef - ->aaIidIndexMapped[env][bin]]; - - AlphasValue = 0; - if (h_ps_d->specificTo.mpeg.pCoef->aaIccIndexMapped[env][bin] >= 0) - AlphasValue = Alphas[h_ps_d->specificTo.mpeg.pCoef->aaIccIndexMapped[env][bin]]; - Beta = fMult( - fMult(AlphasValue, - (ScaleR - ScaleL)), - FIXP_SQRT05); - Alpha = - AlphasValue >> 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.pCoef->H11r[group] = - h_ps_d->specificTo.mpeg.h11rPrev[group]; - h_ps_d->specificTo.mpeg.pCoef->H12r[group] = - h_ps_d->specificTo.mpeg.h12rPrev[group]; - h_ps_d->specificTo.mpeg.pCoef->H21r[group] = - h_ps_d->specificTo.mpeg.h21rPrev[group]; - h_ps_d->specificTo.mpeg.pCoef->H22r[group] = - h_ps_d->specificTo.mpeg.h22rPrev[group]; - - h_ps_d->specificTo.mpeg.pCoef->DeltaH11r[group] = - fMult(h11r - h_ps_d->specificTo.mpeg.pCoef->H11r[group], invL); - h_ps_d->specificTo.mpeg.pCoef->DeltaH12r[group] = - fMult(h12r - h_ps_d->specificTo.mpeg.pCoef->H12r[group], invL); - h_ps_d->specificTo.mpeg.pCoef->DeltaH21r[group] = - fMult(h21r - h_ps_d->specificTo.mpeg.pCoef->H21r[group], invL); - h_ps_d->specificTo.mpeg.pCoef->DeltaH22r[group] = - fMult(h22r - h_ps_d->specificTo.mpeg.pCoef->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 const UCHAR groupTable[NO_IID_GROUPS + 1] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 18, 21, 25, 30, 42, 71}; - -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 *mHybridRealRight, /*!< hybrid values real right */ - FIXP_DBL *mHybridImagRight /*!< hybrid values imag right */ -) { - INT group; - INT subband; - - /**********************************************************************************************/ - /*! -

Mapping

- - The number of stereo bands that is actually used depends on the number of - availble parameters for IID and ICC:
 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
-  
- 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. - **********************************************************************************************/ - - /************************************************************************************************/ - /*! -

Mixing

- - 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: -
-  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)
-  
- 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. - ************************************************************************************************/ - - /************************************************************************************************/ - /*! -

Phase parameters

- With disabled phase parameters (which is the case in baseline version), the - H-matrices are just calculated by: - -
-  H11(k,n[e+1] = h11(b(k))
-  (...)
-  b(k): parameter index according to mapping table
-  
- -

Processing of the samples in the sub subbands

- this loop includes the interpolation of the coefficients Hxx - ************************************************************************************************/ - - /******************************************************/ - /* 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) */ - /******************************************************/ - PS_DEC_COEFFICIENTS *pCoef = h_ps_d->specificTo.mpeg.pCoef; - - for (group = 0; group < NO_IID_GROUPS; group++) { - pCoef->H11r[group] += pCoef->DeltaH11r[group]; - pCoef->H12r[group] += pCoef->DeltaH12r[group]; - pCoef->H21r[group] += pCoef->DeltaH21r[group]; - pCoef->H22r[group] += pCoef->DeltaH22r[group]; - - const int start = groupTable[group]; - const int stop = groupTable[group + 1]; - for (subband = start; subband < stop; subband++) { - FIXP_DBL tmpLeft = - fMultAdd(fMultDiv2(pCoef->H11r[group], mHybridRealLeft[subband]), - pCoef->H21r[group], mHybridRealRight[subband]); - FIXP_DBL tmpRight = - fMultAdd(fMultDiv2(pCoef->H12r[group], mHybridRealLeft[subband]), - pCoef->H22r[group], mHybridRealRight[subband]); - mHybridRealLeft[subband] = tmpLeft; - mHybridRealRight[subband] = tmpRight; - - tmpLeft = - fMultAdd(fMultDiv2(pCoef->H11r[group], mHybridImagLeft[subband]), - pCoef->H21r[group], mHybridImagRight[subband]); - tmpRight = - fMultAdd(fMultDiv2(pCoef->H12r[group], mHybridImagLeft[subband]), - pCoef->H22r[group], mHybridImagRight[subband]); - mHybridImagLeft[subband] = tmpLeft; - mHybridImagRight[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) */ - const int scaleFactorLowBand_no_ov, const int scaleFactorLowBand, - const int scaleFactorHighBand, const int lsb, const int usb) { -/*! -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. - -
-
-           -------------            ----------            -------------
-          | Hybrid      | M_n[k,m] |          | L_n[k,m] | Hybrid      | l[n]
- m[n] --->| analysis    |--------->|          |--------->| synthesis   |----->
-           -------------           | 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
-
-
-*/ -#define NO_HYBRID_DATA_BANDS (71) - - int i; - FIXP_DBL qmfInputData[2][NO_QMF_BANDS_HYBRID20]; - FIXP_DBL *hybridData[2][2]; - C_ALLOC_SCRATCH_START(pHybridData, FIXP_DBL, 4 * NO_HYBRID_DATA_BANDS); - - hybridData[0][0] = - pHybridData + 0 * NO_HYBRID_DATA_BANDS; /* left real hybrid data */ - hybridData[0][1] = - pHybridData + 1 * NO_HYBRID_DATA_BANDS; /* left imag hybrid data */ - hybridData[1][0] = - pHybridData + 2 * NO_HYBRID_DATA_BANDS; /* right real hybrid data */ - hybridData[1][1] = - pHybridData + 3 * NO_HYBRID_DATA_BANDS; /* right imag hybrid data */ - - /*! - 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) ) - */ - - /* - * Hybrid analysis. - */ - - /* Get qmf input data and apply descaling */ - for (i = 0; i < NO_QMF_BANDS_HYBRID20; i++) { - qmfInputData[0][i] = scaleValue(rIntBufferLeft[HYBRID_FILTER_DELAY][i], - scaleFactorLowBand_no_ov); - qmfInputData[1][i] = scaleValue(iIntBufferLeft[HYBRID_FILTER_DELAY][i], - scaleFactorLowBand_no_ov); - } - - /* LF - part */ - FDKhybridAnalysisApply(&h_ps_d->specificTo.mpeg.hybridAnalysis, - qmfInputData[0], qmfInputData[1], hybridData[0][0], - hybridData[0][1]); - - /* HF - part */ - /* bands up to lsb */ - scaleValues(&hybridData[0][0][NO_SUB_QMF_CHANNELS - 2], - &rIntBufferLeft[0][NO_QMF_BANDS_HYBRID20], - lsb - NO_QMF_BANDS_HYBRID20, scaleFactorLowBand); - scaleValues(&hybridData[0][1][NO_SUB_QMF_CHANNELS - 2], - &iIntBufferLeft[0][NO_QMF_BANDS_HYBRID20], - lsb - NO_QMF_BANDS_HYBRID20, scaleFactorLowBand); - - /* bands from lsb to usb */ - scaleValues(&hybridData[0][0][lsb + (NO_SUB_QMF_CHANNELS - 2 - - NO_QMF_BANDS_HYBRID20)], - &rIntBufferLeft[0][lsb], usb - lsb, scaleFactorHighBand); - scaleValues(&hybridData[0][1][lsb + (NO_SUB_QMF_CHANNELS - 2 - - NO_QMF_BANDS_HYBRID20)], - &iIntBufferLeft[0][lsb], usb - lsb, scaleFactorHighBand); - - /* bands from usb to NO_SUB_QMF_CHANNELS which should be zero for non-overlap - slots but can be non-zero for overlap slots */ - FDKmemcpy( - &hybridData[0][0] - [usb + (NO_SUB_QMF_CHANNELS - 2 - NO_QMF_BANDS_HYBRID20)], - &rIntBufferLeft[0][usb], sizeof(FIXP_DBL) * (NO_QMF_CHANNELS - usb)); - FDKmemcpy( - &hybridData[0][1] - [usb + (NO_SUB_QMF_CHANNELS - 2 - NO_QMF_BANDS_HYBRID20)], - &iIntBufferLeft[0][usb], sizeof(FIXP_DBL) * (NO_QMF_CHANNELS - usb)); - - /*! - 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 - */ - - FDKdecorrelateApply(&h_ps_d->specificTo.mpeg.apDecor, - &hybridData[0][0][0], /* left real hybrid data */ - &hybridData[0][1][0], /* left imag hybrid data */ - &hybridData[1][0][0], /* right real hybrid data */ - &hybridData[1][1][0], /* right imag hybrid data */ - 0 /* startHybBand */ - ); - - /*! - 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, - &hybridData[0][0][0], /* left real hybrid data */ - &hybridData[0][1][0], /* left imag hybrid data */ - &hybridData[1][0][0], /* right real hybrid data */ - &hybridData[1][1][0] /* right imag hybrid data */ - ); - - /*! - 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. - */ - - /* - * Hybrid synthesis. - */ - for (i = 0; i < 2; i++) { - FDKhybridSynthesisApply( - &h_ps_d->specificTo.mpeg.hybridSynthesis[i], - hybridData[i][0], /* real hybrid data */ - hybridData[i][1], /* imag hybrid data */ - (i == 0) ? rIntBufferLeft[0] - : rIntBufferRight, /* output real qmf buffer */ - (i == 0) ? iIntBufferLeft[0] - : iIntBufferRight /* output imag qmf buffer */ - ); - } - - /* free temporary hybrid qmf values of one timeslot */ - C_ALLOC_SCRATCH_END(pHybridData, FIXP_DBL, 4 * NO_HYBRID_DATA_BANDS); - -} /* END ApplyPsSlot */ --- a/libSBRdec/src/psdec.h +++ /dev/null @@ -1,333 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Sbr decoder -*/ -#ifndef PSDEC_H -#define PSDEC_H - -#include "sbrdecoder.h" -#include "FDK_hybrid.h" - -#include "FDK_decorrelate.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" - -#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 HYBRID_FILTER_DELAY (6) - -#define MAX_NO_PS_ENV (4 + 1) /* +1 needed for VAR_BORDER */ - -#define NO_HI_RES_BINS (34) -#define NO_MID_RES_BINS (20) -#define NO_LOW_RES_BINS (10) - -#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). */ - - 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 - bPrevFrameFineIidQ; /*!< The IID quantization of the previous frame */ - UCHAR prevFreqResIid; /*!< Frequency resolution for IID of the previous - frame */ - UCHAR prevFreqResIcc; /*!< Frequency resolution for ICC of the previous - frame */ - UCHAR lastUsb; /*!< uppermost WMF delay band of last frame */ - - FIXP_DBL pHybridAnaStatesLFdmx - [2 * 13 * NO_QMF_BANDS_HYBRID20]; /*!< Memory used in hybrid analysis - for filter states. */ - FDK_ANA_HYB_FILTER hybridAnalysis; - FDK_SYN_HYB_FILTER hybridSynthesis[2]; - - DECORR_DEC apDecor; /*!< Decorrelator instance. */ - FIXP_DBL decorrBufferCplx[(2 * ((825) + (373)))]; - - 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 - *pCoef; /*!< temporal coefficients are on 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 PreparePsProcessing(HANDLE_PS_DEC h_ps_d, - const FIXP_DBL *const *const rIntBufferLeft, - const FIXP_DBL *const *const iIntBufferLeft, - const int scaleFactorLowBand); - -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 */ - const int scaleFactorLowBand_no_ov, const int scaleFactorLowBand, - const int scaleFactorHighBand, const int lsb, const int usb); - -#endif /* PSDEC_H */ --- a/libSBRdec/src/psdec_drm.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief parametric stereo decoder for Digital radio mondial -*/ - -#include "psdec_drm.h" --- a/libSBRdec/src/psdec_drm.h +++ /dev/null @@ -1,113 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief parametric stereo decoder for digital radio mondial -*/ - -#ifndef PSDEC_DRM_H -#define PSDEC_DRM_H - -#include "sbrdecoder.h" - -#endif /* PSDEC_DRM_H */ --- a/libSBRdec/src/psdecrom_drm.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief rom tables for Drm parametric stereo decoder -*/ - -#include "psdec_drm.h" --- a/libSBRdec/src/pvc_dec.cpp +++ /dev/null @@ -1,683 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): Matthias Hildenbrand - - Description: Decode Predictive Vector Coding Data - -*******************************************************************************/ - -#include "pvc_dec.h" - -/* PVC interal definitions */ -#define PVC_DIVMODE_BITS 3 -#define PVC_NSMODE_BITS 1 -#define PVC_REUSEPVCID_BITS 1 -#define PVC_PVCID_BITS 7 -#define PVC_GRIDINFO_BITS 1 -#define PVC_NQMFBAND 64 -#define PVC_NBLOW 3 /* max. number of grouped QMF subbands below SBR range */ - -#define PVC_NTAB1 3 -#define PVC_NTAB2 128 -#define PVC_ID_NBIT 7 - -/* Exponent of pPvcStaticData->Esg and predictedEsg in dB domain. - max(Esg) = 10*log10(2^15*2^15) = 90.30; - min(Esg) = 10*log10(0.1) = -10 - max of predicted Esg seems to be higher than 90dB but 7 Bit should be enough. -*/ -#define PVC_ESG_EXP 7 - -#define LOG10FAC 0.752574989159953f /* == 10/log2(10) * 2^-2 */ -#define LOG10FAC_INV 0.664385618977472f /* == log2(10)/10 * 2^1 */ - -RAM_ALIGN -LNK_SECTION_CONSTDATA -static const FIXP_SGL pvc_SC_16[] = { - FX_DBL2FXCONST_SGL(0x14413695), FX_DBL2FXCONST_SGL(0x1434b6cb), - FX_DBL2FXCONST_SGL(0x140f27c7), FX_DBL2FXCONST_SGL(0x13d0591d), - FX_DBL2FXCONST_SGL(0x1377f502), FX_DBL2FXCONST_SGL(0x130577d6), - FX_DBL2FXCONST_SGL(0x12782266), FX_DBL2FXCONST_SGL(0x11cee459), - FX_DBL2FXCONST_SGL(0x11083a2a), FX_DBL2FXCONST_SGL(0x1021f5e9), - FX_DBL2FXCONST_SGL(0x0f18e17c), FX_DBL2FXCONST_SGL(0x0de814ca), - FX_DBL2FXCONST_SGL(0x0c87a568), FX_DBL2FXCONST_SGL(0x0ae9b167), - FX_DBL2FXCONST_SGL(0x08f24226), FX_DBL2FXCONST_SGL(0x06575ed5), -}; - -RAM_ALIGN -LNK_SECTION_CONSTDATA -static const FIXP_SGL pvc_SC_12[] = { - FX_DBL2FXCONST_SGL(0x1aba6b3e), FX_DBL2FXCONST_SGL(0x1a9d164e), - FX_DBL2FXCONST_SGL(0x1a44d56d), FX_DBL2FXCONST_SGL(0x19b0d742), - FX_DBL2FXCONST_SGL(0x18df969a), FX_DBL2FXCONST_SGL(0x17ce91a0), - FX_DBL2FXCONST_SGL(0x1679c3fa), FX_DBL2FXCONST_SGL(0x14daabfc), - FX_DBL2FXCONST_SGL(0x12e65221), FX_DBL2FXCONST_SGL(0x1088d125), - FX_DBL2FXCONST_SGL(0x0d9907b3), FX_DBL2FXCONST_SGL(0x09a80e9d), -}; - -RAM_ALIGN -LNK_SECTION_CONSTDATA -static const FIXP_SGL pvc_SC_4[] = { - FX_DBL2FXCONST_SGL(0x4ad6ab0f), - FX_DBL2FXCONST_SGL(0x47ef0dbe), - FX_DBL2FXCONST_SGL(0x3eee7496), - FX_DBL2FXCONST_SGL(0x2e4bd29d), -}; - -RAM_ALIGN -LNK_SECTION_CONSTDATA -static const FIXP_SGL pvc_SC_3[] = { - FX_DBL2FXCONST_SGL(0x610dc761), - FX_DBL2FXCONST_SGL(0x5a519a3d), - FX_DBL2FXCONST_SGL(0x44a09e62), -}; - -static const UCHAR g_3a_pvcTab1_mode1[PVC_NTAB1][PVC_NBLOW][PVC_NBHIGH_MODE1] = - {{{0x4F, 0x5B, 0x57, 0x52, 0x4D, 0x65, 0x45, 0x57}, - {0xF3, 0x0F, 0x18, 0x20, 0x19, 0x4F, 0x3D, 0x23}, - {0x78, 0x57, 0x55, 0x50, 0x50, 0x20, 0x36, 0x37}}, - {{0x4C, 0x5F, 0x53, 0x37, 0x1E, 0xFD, 0x15, 0x0A}, - {0x05, 0x0E, 0x28, 0x41, 0x48, 0x6E, 0x54, 0x5B}, - {0x59, 0x47, 0x40, 0x40, 0x3D, 0x33, 0x3F, 0x39}}, - {{0x47, 0x5F, 0x57, 0x34, 0x3C, 0x2E, 0x2E, 0x31}, - {0xFA, 0x13, 0x23, 0x4E, 0x44, 0x7C, 0x34, 0x38}, - {0x63, 0x43, 0x41, 0x3D, 0x35, 0x19, 0x3D, 0x33}}}; - -static const UCHAR g_2a_pvcTab2_mode1[PVC_NTAB2][PVC_NBHIGH_MODE1] = { - {0xCB, 0xD1, 0xCC, 0xD2, 0xE2, 0xEB, 0xE7, 0xE8}, - {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}, - {0x84, 0x8C, 0x88, 0x83, 0x90, 0x93, 0x86, 0x80}, - {0xD7, 0xD8, 0xC0, 0xC7, 0xCF, 0xE5, 0xF1, 0xF6}, - {0xA5, 0xA6, 0xAA, 0xA8, 0xB0, 0xB1, 0xB8, 0xB8}, - {0xD7, 0xCB, 0xC1, 0xC3, 0xC5, 0xC9, 0xC9, 0xCE}, - {0xCA, 0xB5, 0xB8, 0xB3, 0xAC, 0xB6, 0xBB, 0xB8}, - {0xC1, 0xC4, 0xC3, 0xC5, 0xC6, 0xCA, 0xCA, 0xCB}, - {0xE0, 0xE1, 0xD8, 0xCD, 0xCB, 0xCB, 0xCE, 0xCC}, - {0xDB, 0xE1, 0xDF, 0xDB, 0xDC, 0xD9, 0xD9, 0xD6}, - {0xE0, 0xDE, 0xDD, 0xDD, 0xE0, 0xE3, 0xE5, 0xE6}, - {0xCA, 0xD2, 0xCD, 0xCE, 0xD5, 0xDB, 0xD9, 0xDB}, - {0xD2, 0xE0, 0xDB, 0xD5, 0xDB, 0xDE, 0xE3, 0xE1}, - {0xE5, 0xDB, 0xD0, 0xD2, 0xD8, 0xDD, 0xDB, 0xDD}, - {0xC0, 0xB5, 0xBF, 0xDD, 0xE3, 0xDC, 0xDC, 0xE4}, - {0xDB, 0xCE, 0xC6, 0xCF, 0xCF, 0xD1, 0xD3, 0xD4}, - {0xC9, 0xD7, 0xDA, 0xE2, 0xE9, 0xE7, 0xDF, 0xDC}, - {0x0A, 0x07, 0x0A, 0x08, 0x19, 0x24, 0x1F, 0x22}, - {0x1E, 0x1F, 0x11, 0x0E, 0x22, 0x2D, 0x33, 0x32}, - {0xF0, 0xDA, 0xDC, 0x18, 0x1F, 0x19, 0x0A, 0x1E}, - {0x09, 0xF8, 0xE6, 0x05, 0x19, 0x11, 0x0E, 0x0B}, - {0x09, 0x10, 0x0E, 0xE6, 0xF4, 0x20, 0x22, 0xFA}, - {0xF2, 0xE5, 0xF8, 0x0E, 0x18, 0x15, 0x0D, 0x10}, - {0x15, 0x13, 0x16, 0x0A, 0x0D, 0x1F, 0x1D, 0x1B}, - {0xFA, 0xFF, 0xFE, 0xFF, 0x09, 0x11, 0x03, 0x0B}, - {0xFE, 0xFA, 0xF2, 0xF8, 0x0C, 0x1E, 0x11, 0x12}, - {0xFA, 0xF8, 0x0B, 0x17, 0x1D, 0x17, 0x0E, 0x16}, - {0x00, 0xF3, 0xFD, 0x0A, 0x1C, 0x17, 0xFD, 0x08}, - {0xEA, 0xEA, 0x03, 0x12, 0x1E, 0x14, 0x09, 0x04}, - {0x02, 0xFE, 0x04, 0xFB, 0x0C, 0x0E, 0x07, 0x02}, - {0xF6, 0x02, 0x07, 0x0B, 0x17, 0x17, 0x01, 0xFF}, - {0xF5, 0xFB, 0xFE, 0x04, 0x12, 0x14, 0x0C, 0x0D}, - {0x10, 0x10, 0x0E, 0x04, 0x07, 0x11, 0x0F, 0x13}, - {0x0C, 0x0F, 0xFB, 0xF2, 0x0A, 0x12, 0x09, 0x0D}, - {0x0D, 0x1D, 0xF1, 0xF4, 0x2A, 0x06, 0x3B, 0x32}, - {0xFC, 0x08, 0x06, 0x02, 0x0E, 0x17, 0x08, 0x0E}, - {0x07, 0x02, 0xEE, 0xEE, 0x2B, 0xF6, 0x23, 0x13}, - {0x04, 0x02, 0x05, 0x08, 0x0B, 0x0E, 0xFB, 0xFB}, - {0x00, 0x04, 0x10, 0x18, 0x22, 0x25, 0x1D, 0x1F}, - {0xFB, 0x0D, 0x07, 0x00, 0x0C, 0x0F, 0xFC, 0x02}, - {0x00, 0x00, 0x00, 0x01, 0x05, 0x07, 0x03, 0x05}, - {0x04, 0x05, 0x08, 0x13, 0xFF, 0xEB, 0x0C, 0x06}, - {0x05, 0x13, 0x0E, 0x0B, 0x12, 0x15, 0x09, 0x0A}, - {0x09, 0x03, 0x09, 0x05, 0x12, 0x16, 0x11, 0x12}, - {0x14, 0x1A, 0x06, 0x01, 0x10, 0x11, 0xFE, 0x02}, - {0x01, 0x0B, 0x0B, 0x0C, 0x18, 0x21, 0x10, 0x13}, - {0x12, 0x0D, 0x0A, 0x10, 0x1C, 0x1D, 0x0D, 0x10}, - {0x03, 0x09, 0x14, 0x15, 0x1B, 0x1A, 0x01, 0xFF}, - {0x08, 0x12, 0x13, 0x0E, 0x16, 0x1D, 0x14, 0x1B}, - {0x07, 0x15, 0x1C, 0x1B, 0x20, 0x21, 0x11, 0x0E}, - {0x12, 0x18, 0x19, 0x17, 0x20, 0x25, 0x1A, 0x1E}, - {0x0C, 0x1A, 0x1D, 0x22, 0x2F, 0x33, 0x27, 0x28}, - {0x0E, 0x1A, 0x17, 0x10, 0x0A, 0x0E, 0xFF, 0x06}, - {0x1A, 0x1C, 0x18, 0x14, 0x1A, 0x16, 0x0A, 0x0E}, - {0x1E, 0x27, 0x25, 0x26, 0x27, 0x2A, 0x21, 0x21}, - {0xF1, 0x0A, 0x16, 0x1C, 0x28, 0x25, 0x15, 0x19}, - {0x08, 0x12, 0x09, 0x08, 0x16, 0x17, 0xEF, 0xF6}, - {0x0C, 0x0B, 0x00, 0xFC, 0x04, 0x09, 0xFC, 0x03}, - {0xFB, 0xF1, 0xF8, 0x26, 0x24, 0x18, 0x1D, 0x20}, - {0xF9, 0x01, 0x0C, 0x0F, 0x07, 0x08, 0x06, 0x07}, - {0x07, 0x06, 0x08, 0x04, 0x07, 0x0D, 0x07, 0x09}, - {0xFE, 0x01, 0x06, 0x05, 0x13, 0x1B, 0x14, 0x19}, - {0x09, 0x0C, 0x0E, 0x01, 0x08, 0x05, 0xFB, 0xFD}, - {0x07, 0x06, 0x03, 0x0A, 0x16, 0x12, 0x04, 0x07}, - {0x04, 0x01, 0x00, 0x04, 0x1F, 0x20, 0x0E, 0x0A}, - {0x03, 0xFF, 0xF6, 0xFB, 0x15, 0x1A, 0x00, 0x03}, - {0xFC, 0x18, 0x0B, 0x2D, 0x35, 0x23, 0x12, 0x09}, - {0x02, 0xFE, 0x01, 0xFF, 0x0C, 0x11, 0x0D, 0x0F}, - {0xFA, 0xE9, 0xD9, 0xFF, 0x0D, 0x05, 0x0D, 0x10}, - {0xF1, 0xE0, 0xF0, 0x01, 0x06, 0x06, 0x06, 0x10}, - {0xE9, 0xD4, 0xD7, 0x0F, 0x14, 0x0B, 0x0D, 0x16}, - {0x00, 0xFF, 0xEE, 0xE5, 0xFF, 0x08, 0x02, 0xF9}, - {0xE0, 0xDA, 0xE5, 0xFE, 0x09, 0x02, 0xF9, 0x04}, - {0xE0, 0xE2, 0xF4, 0x09, 0x13, 0x0C, 0x0D, 0x09}, - {0xFC, 0x02, 0x04, 0xFF, 0x00, 0xFF, 0xF8, 0xF7}, - {0xFE, 0xFB, 0xED, 0xF2, 0xFE, 0xFE, 0x08, 0x0C}, - {0xF3, 0xEF, 0xD0, 0xE3, 0x05, 0x11, 0xFD, 0xFF}, - {0xFA, 0xEF, 0xEA, 0xFE, 0x0D, 0x0E, 0xFE, 0x02}, - {0xF7, 0xFB, 0xDB, 0xDF, 0x14, 0xDD, 0x07, 0xFE}, - {0xFE, 0x08, 0x00, 0xDB, 0xE5, 0x1A, 0x13, 0xED}, - {0xF9, 0xFE, 0xFF, 0xF4, 0xF3, 0x00, 0x05, 0x02}, - {0xEF, 0xDE, 0xD8, 0xEB, 0xEA, 0xF5, 0x0E, 0x19}, - {0xFB, 0xFC, 0xFA, 0xEC, 0xEB, 0xED, 0xEE, 0xE8}, - {0xEE, 0xFC, 0xFD, 0x00, 0x04, 0xFC, 0xF0, 0xF5}, - {0x00, 0xFA, 0xF4, 0xF1, 0xF5, 0xFA, 0xFB, 0xF9}, - {0xEB, 0xF0, 0xDF, 0xE3, 0xEF, 0x07, 0x02, 0x05}, - {0xF7, 0xF0, 0xE6, 0xE7, 0x06, 0x15, 0x06, 0x0C}, - {0xF1, 0xE4, 0xD8, 0xEA, 0x06, 0xF2, 0x07, 0x09}, - {0xFF, 0xFE, 0xFE, 0xF9, 0xFF, 0xFF, 0x02, 0xF9}, - {0xDD, 0xF4, 0xF0, 0xF1, 0xFF, 0xFF, 0xEA, 0xF1}, - {0xF0, 0xF1, 0xFD, 0x03, 0x03, 0xFE, 0x00, 0x05}, - {0xF1, 0xF6, 0xE0, 0xDF, 0xF5, 0x01, 0xF4, 0xF8}, - {0x02, 0x03, 0xE5, 0xDC, 0xE7, 0xFD, 0x02, 0x08}, - {0xEC, 0xF1, 0xF5, 0xEC, 0xF2, 0xF8, 0xF6, 0xEE}, - {0xF3, 0xF4, 0xF6, 0xF4, 0xF5, 0xF1, 0xE7, 0xEA}, - {0xF7, 0xF3, 0xEC, 0xEA, 0xEF, 0xF0, 0xEE, 0xF1}, - {0xEB, 0xF6, 0xFB, 0xFA, 0xEF, 0xF3, 0xF3, 0xF7}, - {0x01, 0x03, 0xF1, 0xF6, 0x05, 0xF8, 0xE1, 0xEB}, - {0xF5, 0xF6, 0xF6, 0xF4, 0xFB, 0xFB, 0xFF, 0x00}, - {0xF8, 0x01, 0xFB, 0xFA, 0xFF, 0x03, 0xFE, 0x04}, - {0x04, 0xFB, 0x03, 0xFD, 0xF5, 0xF7, 0xF6, 0xFB}, - {0x06, 0x09, 0xFB, 0xF4, 0xF9, 0xFA, 0xFC, 0xFF}, - {0xF5, 0xF6, 0xF1, 0xEE, 0xF5, 0xF8, 0xF5, 0xF9}, - {0xF5, 0xF9, 0xFA, 0xFC, 0x07, 0x09, 0x01, 0xFB}, - {0xD7, 0xE9, 0xE8, 0xEC, 0x00, 0x0C, 0xFE, 0xF1}, - {0xEC, 0x04, 0xE9, 0xDF, 0x03, 0xE8, 0x00, 0xFA}, - {0xE6, 0xE2, 0xFF, 0x0A, 0x13, 0x01, 0x00, 0xF7}, - {0xF1, 0xFA, 0xF7, 0xF5, 0x01, 0x06, 0x05, 0x0A}, - {0xF6, 0xF6, 0xFC, 0xF6, 0xE8, 0x11, 0xF2, 0xFE}, - {0xFE, 0x08, 0x05, 0x12, 0xFD, 0xD0, 0x0E, 0x07}, - {0xF1, 0xFE, 0xF7, 0xF2, 0xFB, 0x02, 0xFA, 0xF8}, - {0xF4, 0xEA, 0xEC, 0xF3, 0xFE, 0x01, 0xF7, 0xF6}, - {0xFF, 0xFA, 0xFB, 0xF9, 0xFF, 0x01, 0x04, 0x03}, - {0x00, 0xF9, 0xF4, 0xFC, 0x05, 0xFC, 0xF7, 0xFB}, - {0xF8, 0xFF, 0xEF, 0xEC, 0xFB, 0x04, 0xF8, 0x03}, - {0xEB, 0xF1, 0xED, 0xF4, 0x02, 0x0E, 0x0B, 0x04}, - {0xF7, 0x01, 0xF8, 0xF4, 0xF8, 0xEF, 0xF8, 0x04}, - {0xEB, 0xF0, 0xF7, 0xFC, 0x10, 0x0D, 0xF8, 0xF8}, - {0xE8, 0xFE, 0xEE, 0xE8, 0xED, 0xF7, 0xF5, 0xF8}, - {0xED, 0xEB, 0xE9, 0xEA, 0xF2, 0xF5, 0xF4, 0xF9}, - {0xEA, 0xF2, 0xEF, 0xEE, 0xF9, 0xFE, 0xFD, 0x02}, - {0xFA, 0xFD, 0x02, 0x0D, 0xFA, 0xE4, 0x0F, 0x01}, - {0xFF, 0x08, 0x05, 0xF6, 0xF7, 0xFB, 0xF1, 0xF1}, - {0xF4, 0xEC, 0xEE, 0xF6, 0xEE, 0xEE, 0xF8, 0x06}, - {0xE8, 0xFA, 0xF8, 0xE8, 0xF8, 0xE9, 0xEE, 0xF9}, - {0xE5, 0xE9, 0xF0, 0x00, 0x00, 0xEF, 0xF3, 0xF8}, - {0xF7, 0xFB, 0xFB, 0xF7, 0xF9, 0xF9, 0xF5, 0xF0}, - {0xFD, 0xFF, 0xF2, 0xEE, 0xF2, 0xF5, 0xF1, 0xF3}}; - -static const UCHAR g_3a_pvcTab1_mode2[PVC_NTAB1][PVC_NBLOW][PVC_NBHIGH_MODE2] = - {{{0x11, 0x27, 0x0F, 0xFD, 0x04, 0xFC}, - {0x00, 0xBE, 0xE3, 0xF4, 0xDB, 0xF0}, - {0x09, 0x1E, 0x18, 0x1A, 0x21, 0x1B}}, - {{0x16, 0x28, 0x2B, 0x29, 0x25, 0x32}, - {0xF2, 0xE9, 0xE4, 0xE5, 0xE2, 0xD4}, - {0x0E, 0x0B, 0x0C, 0x0D, 0x0D, 0x0E}}, - {{0x2E, 0x3C, 0x20, 0x16, 0x1B, 0x1A}, - {0xE4, 0xC6, 0xE5, 0xF4, 0xDC, 0xDC}, - {0x0F, 0x1B, 0x18, 0x14, 0x1E, 0x1A}}}; - -static const UCHAR g_2a_pvcTab2_mode2[PVC_NTAB2][PVC_NBHIGH_MODE2] = { - {0x26, 0x25, 0x11, 0x0C, 0xFA, 0x15}, {0x1B, 0x18, 0x11, 0x0E, 0x0E, 0x0E}, - {0x12, 0x10, 0x10, 0x10, 0x11, 0x10}, {0x1E, 0x24, 0x19, 0x15, 0x14, 0x12}, - {0x24, 0x16, 0x12, 0x13, 0x15, 0x1C}, {0xEA, 0xED, 0xEB, 0xEA, 0xEC, 0xEB}, - {0xFC, 0xFD, 0xFD, 0xFC, 0xFE, 0xFE}, {0x0F, 0x0C, 0x0B, 0x0A, 0x0B, 0x0B}, - {0x22, 0x0B, 0x16, 0x18, 0x13, 0x19}, {0x1C, 0x14, 0x1D, 0x20, 0x19, 0x1A}, - {0x10, 0x08, 0x00, 0xFF, 0x02, 0x05}, {0x06, 0x07, 0x05, 0x03, 0x05, 0x04}, - {0x2A, 0x1F, 0x12, 0x12, 0x11, 0x18}, {0x19, 0x19, 0x02, 0x04, 0x00, 0x04}, - {0x18, 0x17, 0x17, 0x15, 0x16, 0x15}, {0x21, 0x1E, 0x1B, 0x19, 0x1C, 0x1B}, - {0x3C, 0x35, 0x20, 0x1D, 0x30, 0x34}, {0x3A, 0x1F, 0x37, 0x38, 0x33, 0x31}, - {0x37, 0x34, 0x25, 0x27, 0x35, 0x34}, {0x34, 0x2E, 0x32, 0x31, 0x34, 0x31}, - {0x36, 0x33, 0x2F, 0x2F, 0x32, 0x2F}, {0x35, 0x20, 0x2F, 0x32, 0x2F, 0x2C}, - {0x2E, 0x2B, 0x2F, 0x34, 0x36, 0x30}, {0x3F, 0x39, 0x30, 0x28, 0x29, 0x29}, - {0x3C, 0x30, 0x32, 0x37, 0x39, 0x36}, {0x37, 0x36, 0x30, 0x2B, 0x26, 0x24}, - {0x44, 0x38, 0x2F, 0x2D, 0x2D, 0x2D}, {0x38, 0x2B, 0x2C, 0x2C, 0x30, 0x2D}, - {0x37, 0x36, 0x2F, 0x23, 0x2D, 0x32}, {0x3C, 0x39, 0x29, 0x2E, 0x38, 0x37}, - {0x3B, 0x3A, 0x35, 0x32, 0x31, 0x2D}, {0x32, 0x31, 0x2F, 0x2C, 0x2D, 0x28}, - {0x2C, 0x31, 0x32, 0x30, 0x32, 0x2D}, {0x35, 0x34, 0x34, 0x34, 0x35, 0x33}, - {0x34, 0x38, 0x3B, 0x3C, 0x3E, 0x3A}, {0x3E, 0x3C, 0x3B, 0x3A, 0x3C, 0x39}, - {0x3D, 0x41, 0x46, 0x41, 0x3D, 0x38}, {0x44, 0x41, 0x40, 0x3E, 0x3F, 0x3A}, - {0x47, 0x47, 0x47, 0x42, 0x44, 0x40}, {0x4C, 0x4A, 0x4A, 0x46, 0x49, 0x45}, - {0x53, 0x52, 0x52, 0x4C, 0x4E, 0x49}, {0x41, 0x3D, 0x39, 0x2C, 0x2E, 0x2E}, - {0x2D, 0x37, 0x36, 0x30, 0x28, 0x36}, {0x3B, 0x32, 0x2E, 0x2D, 0x2D, 0x29}, - {0x40, 0x39, 0x36, 0x35, 0x36, 0x32}, {0x30, 0x2D, 0x2D, 0x2E, 0x31, 0x30}, - {0x38, 0x3D, 0x3B, 0x37, 0x35, 0x34}, {0x44, 0x3D, 0x3C, 0x38, 0x37, 0x33}, - {0x3A, 0x36, 0x37, 0x37, 0x39, 0x36}, {0x32, 0x36, 0x37, 0x30, 0x2E, 0x2A}, - {0x3C, 0x33, 0x33, 0x31, 0x33, 0x30}, {0x30, 0x31, 0x36, 0x37, 0x38, 0x34}, - {0x26, 0x27, 0x2E, 0x29, 0x1C, 0x16}, {0x14, 0x15, 0x1F, 0x17, 0x15, 0x1C}, - {0x38, 0x2D, 0x18, 0x13, 0x1E, 0x2B}, {0x30, 0x22, 0x17, 0x1A, 0x26, 0x2B}, - {0x24, 0x20, 0x1F, 0x10, 0x0C, 0x11}, {0x27, 0x1F, 0x13, 0x17, 0x24, 0x2A}, - {0x2F, 0x13, 0x18, 0x13, 0x2A, 0x32}, {0x31, 0x1E, 0x1E, 0x1E, 0x21, 0x28}, - {0x2A, 0x12, 0x19, 0x17, 0x16, 0x24}, {0x27, 0x0F, 0x16, 0x1D, 0x17, 0x1C}, - {0x2F, 0x26, 0x25, 0x22, 0x20, 0x22}, {0x1E, 0x1B, 0x1E, 0x18, 0x1E, 0x24}, - {0x31, 0x26, 0x0E, 0x15, 0x15, 0x25}, {0x2D, 0x22, 0x1E, 0x14, 0x10, 0x22}, - {0x25, 0x1B, 0x18, 0x11, 0x13, 0x1F}, {0x2F, 0x1B, 0x13, 0x1B, 0x18, 0x22}, - {0x21, 0x24, 0x1D, 0x1C, 0x1D, 0x1B}, {0x23, 0x1E, 0x28, 0x29, 0x27, 0x25}, - {0x2E, 0x2A, 0x1D, 0x17, 0x26, 0x2D}, {0x31, 0x2C, 0x1A, 0x0E, 0x1A, 0x24}, - {0x26, 0x16, 0x20, 0x1D, 0x14, 0x1E}, {0x29, 0x20, 0x1B, 0x1B, 0x17, 0x17}, - {0x1D, 0x06, 0x1A, 0x1E, 0x1B, 0x1D}, {0x2B, 0x23, 0x1F, 0x1F, 0x1D, 0x1C}, - {0x27, 0x1A, 0x0C, 0x0E, 0x0F, 0x1A}, {0x29, 0x1D, 0x1E, 0x22, 0x22, 0x24}, - {0x20, 0x21, 0x1B, 0x18, 0x13, 0x21}, {0x27, 0x0E, 0x10, 0x14, 0x10, 0x1A}, - {0x26, 0x24, 0x25, 0x25, 0x26, 0x28}, {0x1A, 0x24, 0x25, 0x29, 0x26, 0x24}, - {0x1D, 0x1D, 0x15, 0x12, 0x0F, 0x18}, {0x1E, 0x14, 0x13, 0x12, 0x14, 0x18}, - {0x16, 0x13, 0x13, 0x1A, 0x1B, 0x1D}, {0x20, 0x27, 0x22, 0x24, 0x1A, 0x19}, - {0x1F, 0x17, 0x19, 0x18, 0x17, 0x18}, {0x20, 0x1B, 0x1C, 0x1C, 0x1B, 0x1A}, - {0x23, 0x19, 0x1D, 0x1F, 0x1E, 0x21}, {0x26, 0x1F, 0x1D, 0x1B, 0x19, 0x1A}, - {0x23, 0x1E, 0x1F, 0x20, 0x1F, 0x1E}, {0x29, 0x20, 0x22, 0x20, 0x20, 0x1F}, - {0x26, 0x23, 0x21, 0x22, 0x23, 0x23}, {0x29, 0x1F, 0x24, 0x25, 0x26, 0x29}, - {0x2B, 0x22, 0x25, 0x27, 0x23, 0x21}, {0x29, 0x21, 0x19, 0x0E, 0x22, 0x2D}, - {0x32, 0x29, 0x1F, 0x1C, 0x1B, 0x21}, {0x1E, 0x1A, 0x1E, 0x24, 0x25, 0x25}, - {0x24, 0x1D, 0x21, 0x22, 0x22, 0x25}, {0x2C, 0x25, 0x21, 0x22, 0x23, 0x25}, - {0x24, 0x1E, 0x21, 0x26, 0x2B, 0x2C}, {0x28, 0x24, 0x1B, 0x1F, 0x28, 0x2D}, - {0x23, 0x13, 0x16, 0x22, 0x22, 0x29}, {0x1B, 0x23, 0x1C, 0x20, 0x14, 0x0D}, - {0x1E, 0x16, 0x1A, 0x1E, 0x1C, 0x1D}, {0x2B, 0x1C, 0x1D, 0x20, 0x1B, 0x1C}, - {0x1C, 0x1B, 0x23, 0x1F, 0x19, 0x1E}, {0x21, 0x23, 0x26, 0x20, 0x20, 0x22}, - {0x1D, 0x0B, 0x19, 0x1E, 0x11, 0x19}, {0x18, 0x17, 0x16, 0x17, 0x14, 0x16}, - {0x16, 0x19, 0x1C, 0x20, 0x21, 0x22}, {0x30, 0x1E, 0x22, 0x24, 0x25, 0x26}, - {0x1B, 0x1F, 0x17, 0x1D, 0x1E, 0x21}, {0x32, 0x2B, 0x27, 0x1F, 0x1B, 0x1A}, - {0x28, 0x20, 0x1A, 0x1B, 0x1F, 0x23}, {0x32, 0x21, 0x20, 0x21, 0x1D, 0x1F}, - {0x22, 0x18, 0x12, 0x15, 0x1B, 0x20}, {0x27, 0x27, 0x2A, 0x24, 0x21, 0x21}, - {0x1E, 0x0F, 0x0D, 0x1A, 0x1D, 0x23}, {0x28, 0x25, 0x27, 0x21, 0x17, 0x25}, - {0x2B, 0x27, 0x23, 0x19, 0x13, 0x14}, {0x25, 0x2B, 0x22, 0x22, 0x20, 0x21}, - {0x27, 0x1B, 0x16, 0x17, 0x0F, 0x15}, {0x29, 0x26, 0x23, 0x15, 0x1E, 0x28}, - {0x24, 0x1C, 0x19, 0x1A, 0x18, 0x19}, {0x2D, 0x15, 0x27, 0x2B, 0x24, 0x23}, - {0x2C, 0x12, 0x1F, 0x23, 0x1F, 0x20}, {0x25, 0x0F, 0x22, 0x27, 0x1F, 0x21}}; - -static const UCHAR g_a_pvcTab1_dp_mode1[PVC_NTAB1 - 1] = {17, 68}; -static const UCHAR g_a_pvcTab1_dp_mode2[PVC_NTAB1 - 1] = {16, 52}; -/* fractional exponent which corresponds to Q representation value */ -static const SCHAR g_a_scalingCoef_mode1[PVC_NBLOW + 1] = { - -1, -1, 0, 6}; /* { 8, 8, 7, 1 }; Q scaling */ -static const SCHAR g_a_scalingCoef_mode2[PVC_NBLOW + 1] = { - 0, 0, 1, 7}; /* { 7, 7, 6, 0 }; Q scaling */ - -int pvcInitFrame(PVC_STATIC_DATA *pPvcStaticData, - PVC_DYNAMIC_DATA *pPvcDynamicData, const UCHAR pvcMode, - const UCHAR ns, const int RATE, const int kx, - const int pvcBorder0, const UCHAR *pPvcID) { - int lbw, hbw, i, temp; - pPvcDynamicData->pvc_mode = pvcMode; - pPvcDynamicData->kx = kx; - pPvcDynamicData->RATE = RATE; - - switch (pvcMode) { - case 0: - /* legacy SBR, nothing to do */ - return 0; - case 1: - pPvcDynamicData->nbHigh = 8; - pPvcDynamicData->pPVCTab1 = (const UCHAR *)g_3a_pvcTab1_mode1; - pPvcDynamicData->pPVCTab2 = (const UCHAR *)g_2a_pvcTab2_mode1; - pPvcDynamicData->pPVCTab1_dp = g_a_pvcTab1_dp_mode1; - pPvcDynamicData->pScalingCoef = g_a_scalingCoef_mode1; - hbw = 8 / RATE; - break; - case 2: - pPvcDynamicData->nbHigh = 6; - pPvcDynamicData->pPVCTab1 = (const UCHAR *)g_3a_pvcTab1_mode2; - pPvcDynamicData->pPVCTab2 = (const UCHAR *)g_2a_pvcTab2_mode2; - pPvcDynamicData->pPVCTab1_dp = g_a_pvcTab1_dp_mode2; - pPvcDynamicData->pScalingCoef = g_a_scalingCoef_mode2; - hbw = 12 / RATE; - break; - default: - /* invalid pvcMode */ - return 1; - } - - pPvcDynamicData->pvcBorder0 = pvcBorder0; - UCHAR pvcBorder0_last = pPvcStaticData->pvcBorder0; - pPvcStaticData->pvcBorder0 = pvcBorder0; - pPvcDynamicData->pPvcID = pPvcID; - - pPvcDynamicData->ns = ns; - switch (ns) { - case 16: - pPvcDynamicData->pSCcoeffs = pvc_SC_16; - break; - case 12: - pPvcDynamicData->pSCcoeffs = pvc_SC_12; - break; - case 4: - pPvcDynamicData->pSCcoeffs = pvc_SC_4; - break; - case 3: - pPvcDynamicData->pSCcoeffs = pvc_SC_3; - break; - default: - return 1; - } - - /* in the lower part of Esg-array there are previous values of Esg (from last - call to this function In case of an previous legay-SBR frame, or if there - was a change in cross-over FQ the value of first PVC SBR timeslot is - propagated to prev-values in order to have reasonable values for - smooth-filtering - */ - if ((pPvcStaticData->pvc_mode_last == 0) || (pPvcStaticData->kx_last != kx)) { - pPvcDynamicData->pastEsgSlotsAvail = 0; - } else { - pPvcDynamicData->pastEsgSlotsAvail = PVC_NS_MAX - pvcBorder0_last; - } - - lbw = 8 / RATE; - - temp = kx; - for (i = PVC_NBLOW; i >= 0; i--) { - pPvcDynamicData->sg_offset_low[i] = temp; - temp -= lbw; - } - - temp = 0; - for (i = 0; i <= pPvcDynamicData->nbHigh; i++) { - pPvcDynamicData->sg_offset_high_kx[i] = temp; - temp += hbw; - } - - return 0; -} - -/* call if pvcMode = 1,2 */ -void pvcDecodeFrame(PVC_STATIC_DATA *pPvcStaticData, - PVC_DYNAMIC_DATA *pPvcDynamicData, FIXP_DBL **qmfBufferReal, - FIXP_DBL **qmfBufferImag, const int overlap, - const int qmfExponentOverlap, - const int qmfExponentCurrent) { - int t; - FIXP_DBL *predictedEsgSlot; - int RATE = pPvcDynamicData->RATE; - int pvcBorder0 = pPvcDynamicData->pvcBorder0; - - for (t = pvcBorder0; t < PVC_NTIMESLOT; t++) { - int *pPredEsg_exp = &pPvcDynamicData->predEsg_exp[t]; - predictedEsgSlot = pPvcDynamicData->predEsg[t]; - - pvcDecodeTimeSlot( - pPvcStaticData, pPvcDynamicData, &qmfBufferReal[t * RATE], - &qmfBufferImag[t * RATE], - (t * RATE < overlap) ? qmfExponentOverlap : qmfExponentCurrent, - pvcBorder0, t, predictedEsgSlot, pPredEsg_exp); - } - - return; -} - -void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData, - PVC_DYNAMIC_DATA *pPvcDynamicData, - FIXP_DBL **qmfSlotReal, FIXP_DBL **qmfSlotImag, - const int qmfExponent, const int pvcBorder0, - const int timeSlotNumber, FIXP_DBL predictedEsgSlot[], - int *predictedEsg_exp) { - int i, band, ksg, ksg_start = 0; - int RATE = pPvcDynamicData->RATE; - int Esg_index = pPvcStaticData->Esg_slot_index; - const SCHAR *sg_borders = pPvcDynamicData->sg_offset_low; - FIXP_DBL *pEsg = pPvcStaticData->Esg[Esg_index]; - FIXP_DBL E[PVC_NBLOW] = {0}; - - /* Subband grouping in QMF subbands below SBR range */ - /* Within one timeslot ( i = [0...(RATE-1)] QMF subsamples) calculate energy - E(ib,t) and group them to Esg(ksg,t). Then transfer values to logarithmical - domain and store them for time domain smoothing. (7.5.6.3 Subband grouping - in QMF subbands below SBR range) - */ - for (ksg = 0; sg_borders[ksg] < 0; ksg++) { - pEsg[ksg] = FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP)); /* 10*log10(0.1) */ - ksg_start++; - } - - for (i = 0; i < RATE; i++) { - FIXP_DBL *qmfR, *qmfI; - qmfR = qmfSlotReal[i]; - qmfI = qmfSlotImag[i]; - for (ksg = ksg_start; ksg < PVC_NBLOW; ksg++) { - for (band = sg_borders[ksg]; band < sg_borders[ksg + 1]; band++) { - /* The division by 8 == (RATE*lbw) is required algorithmically */ - E[ksg] += (fPow2Div2(qmfR[band]) + fPow2Div2(qmfI[band])) >> 2; - } - } - } - for (ksg = ksg_start; ksg < PVC_NBLOW; ksg++) { - if (E[ksg] > (FIXP_DBL)0) { - /* 10/log2(10) = 0.752574989159953 * 2^2 */ - int exp_log; - FIXP_DBL nrg = CalcLog2(E[ksg], 2 * qmfExponent, &exp_log); - nrg = fMult(nrg, FL2FXCONST_SGL(LOG10FAC)); - nrg = scaleValue(nrg, exp_log - PVC_ESG_EXP + 2); - pEsg[ksg] = fMax(nrg, FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP))); - } else { - pEsg[ksg] = - FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP)); /* 10*log10(0.1) */ - } - } - - /* Time domain smoothing of subband-grouped energy */ - { - int idx = pPvcStaticData->Esg_slot_index; - FIXP_DBL *pEsg_filt; - FIXP_SGL SCcoeff; - - E[0] = E[1] = E[2] = (FIXP_DBL)0; - for (i = 0; i < pPvcDynamicData->ns; i++) { - SCcoeff = pPvcDynamicData->pSCcoeffs[i]; - pEsg_filt = pPvcStaticData->Esg[idx]; - /* Div2 is compensated by scaling of coeff table */ - E[0] = fMultAddDiv2(E[0], pEsg_filt[0], SCcoeff); - E[1] = fMultAddDiv2(E[1], pEsg_filt[1], SCcoeff); - E[2] = fMultAddDiv2(E[2], pEsg_filt[2], SCcoeff); - if (i >= pPvcDynamicData->pastEsgSlotsAvail) { - /* if past Esg values are not available use the ones from the last valid - * slot */ - continue; - } - if (idx > 0) { - idx--; - } else { - idx += PVC_NS_MAX - 1; - } - } - } - - /* SBR envelope scalefactor prediction */ - { - int E_high_exp[PVC_NBHIGH_MAX]; - int E_high_exp_max = 0; - int pvcTab1ID; - int pvcTab2ID = (int)pPvcDynamicData->pPvcID[timeSlotNumber]; - const UCHAR *pTab1, *pTab2; - if (pvcTab2ID < pPvcDynamicData->pPVCTab1_dp[0]) { - pvcTab1ID = 0; - } else if (pvcTab2ID < pPvcDynamicData->pPVCTab1_dp[1]) { - pvcTab1ID = 1; - } else { - pvcTab1ID = 2; - } - pTab1 = &(pPvcDynamicData - ->pPVCTab1[pvcTab1ID * PVC_NBLOW * pPvcDynamicData->nbHigh]); - pTab2 = &(pPvcDynamicData->pPVCTab2[pvcTab2ID * pPvcDynamicData->nbHigh]); - for (ksg = 0; ksg < pPvcDynamicData->nbHigh; ksg++) { - FIXP_SGL predCoeff; - FIXP_DBL accu; - int predCoeff_exp, kb; - E_high_exp[ksg] = 0; - - /* residual part */ - accu = ((LONG)(SCHAR)*pTab2++) << (DFRACT_BITS - 8 - PVC_ESG_EXP + - pPvcDynamicData->pScalingCoef[3]); - - /* linear combination of lower grouped energies part */ - for (kb = 0; kb < PVC_NBLOW; kb++) { - predCoeff = (FIXP_SGL)( - (SHORT)(SCHAR)pTab1[kb * pPvcDynamicData->nbHigh + ksg] << 8); - predCoeff_exp = pPvcDynamicData->pScalingCoef[kb] + - 1; /* +1 to compensate for Div2 */ - accu += fMultDiv2(E[kb], predCoeff) << predCoeff_exp; - } - /* convert back to linear domain */ - accu = fMult(accu, FL2FXCONST_SGL(LOG10FAC_INV)); - accu = f2Pow( - accu, PVC_ESG_EXP - 1, - &predCoeff_exp); /* -1 compensates for exponent of LOG10FAC_INV */ - predictedEsgSlot[ksg] = accu; - E_high_exp[ksg] = predCoeff_exp; - if (predCoeff_exp > E_high_exp_max) { - E_high_exp_max = predCoeff_exp; - } - } - - /* rescale output vector according to largest exponent */ - for (ksg = 0; ksg < pPvcDynamicData->nbHigh; ksg++) { - int scale = E_high_exp[ksg] - E_high_exp_max; - predictedEsgSlot[ksg] = scaleValue(predictedEsgSlot[ksg], scale); - } - *predictedEsg_exp = E_high_exp_max; - } - - pPvcStaticData->Esg_slot_index = - (pPvcStaticData->Esg_slot_index + 1) & (PVC_NS_MAX - 1); - pPvcDynamicData->pastEsgSlotsAvail = - fMin(pPvcDynamicData->pastEsgSlotsAvail + 1, PVC_NS_MAX - 1); - return; -} - -/* call if pvcMode = 0,1,2 */ -void pvcEndFrame(PVC_STATIC_DATA *pPvcStaticData, - PVC_DYNAMIC_DATA *pPvcDynamicData) { - pPvcStaticData->pvc_mode_last = pPvcDynamicData->pvc_mode; - pPvcStaticData->kx_last = pPvcDynamicData->kx; - - if (pPvcDynamicData->pvc_mode == 0) return; - - { - int t, max = -100; - for (t = pPvcDynamicData->pvcBorder0; t < PVC_NTIMESLOT; t++) { - if (pPvcDynamicData->predEsg_exp[t] > max) { - max = pPvcDynamicData->predEsg_exp[t]; - } - } - pPvcDynamicData->predEsg_expMax = max; - } - return; -} - -void expandPredEsg(const PVC_DYNAMIC_DATA *pPvcDynamicData, const int timeSlot, - const int lengthOutputVector, FIXP_DBL *pOutput, - SCHAR *pOutput_exp) { - int k = 0, ksg; - const FIXP_DBL *predEsg = pPvcDynamicData->predEsg[timeSlot]; - - for (ksg = 0; ksg < pPvcDynamicData->nbHigh; ksg++) { - for (; k < pPvcDynamicData->sg_offset_high_kx[ksg + 1]; k++) { - pOutput[k] = predEsg[ksg]; - pOutput_exp[k] = (SCHAR)pPvcDynamicData->predEsg_exp[timeSlot]; - } - } - ksg--; - for (; k < lengthOutputVector; k++) { - pOutput[k] = predEsg[ksg]; - pOutput_exp[k] = (SCHAR)pPvcDynamicData->predEsg_exp[timeSlot]; - } - - return; -} --- a/libSBRdec/src/pvc_dec.h +++ /dev/null @@ -1,238 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): Matthias Hildenbrand - - Description: Decode Predictive Vector Coding Data - -*******************************************************************************/ - -#ifndef PVC_DEC_H -#define PVC_DEC_H - -#include "common_fix.h" - -#define PVC_DIVMODE_BITS 3 -#define PVC_REUSEPVCID_BITS 1 -#define PVC_PVCID_BITS 7 -#define PVC_GRIDINFO_BITS 1 - -#define MAX_PVC_ENVELOPES 2 -#define PVC_NTIMESLOT 16 -#define PVC_NBLOW 3 /* max. number of grouped QMF subbands below SBR range */ - -#define PVC_NBHIGH_MODE1 8 -#define PVC_NBHIGH_MODE2 6 -#define PVC_NBHIGH_MAX (PVC_NBHIGH_MODE1) -#define PVC_NS_MAX 16 - -/** Data for each PVC instance which needs to be persistent accross SBR frames - */ -typedef struct { - UCHAR kx_last; /**< Xover frequency of last frame */ - UCHAR pvc_mode_last; /**< PVC mode of last frame */ - UCHAR Esg_slot_index; /**< Ring buffer index to current Esg time slot */ - UCHAR pvcBorder0; /**< Start SBR time slot of PVC frame */ - FIXP_DBL Esg[PVC_NS_MAX][PVC_NBLOW]; /**< Esg(ksg,t) of current and 15 - previous time slots (ring buffer) in - logarithmical domain */ -} PVC_STATIC_DATA; - -/** Data for each PVC instance which is valid during one SBR frame */ -typedef struct { - UCHAR pvc_mode; /**< PVC mode 1 or 2, 0 means legacy SBR */ - UCHAR pvcBorder0; /**< Start SBR time slot of PVC frame */ - UCHAR kx; /**< Index of the first QMF subband in the SBR range */ - UCHAR RATE; /**< Number of QMF subband samples per time slot (2 or 4) */ - UCHAR ns; /**< Number of time slots for time-domain smoothing of Esg(ksg,t) */ - const UCHAR - *pPvcID; /**< Pointer to prediction coefficient matrix index table */ - UCHAR pastEsgSlotsAvail; /**< Number of past Esg(ksg,t) which are available - for smoothing filter */ - const FIXP_SGL *pSCcoeffs; /**< Pointer to smoothing window table */ - SCHAR - sg_offset_low[PVC_NBLOW + 1]; /**< Offset table for PVC grouping of SBR - subbands below SBR range */ - SCHAR sg_offset_high_kx[PVC_NBHIGH_MAX + 1]; /**< Offset table for PVC - grouping of SBR subbands in - SBR range (relativ to kx) */ - UCHAR nbHigh; /**< Number of grouped QMF subbands in the SBR range */ - const SCHAR *pScalingCoef; /**< Pointer to scaling coeff table */ - const UCHAR *pPVCTab1; /**< PVC mode 1 table */ - const UCHAR *pPVCTab2; /**< PVC mode 2 table */ - const UCHAR *pPVCTab1_dp; /**< Mapping of pvcID to PVC mode 1 table */ - FIXP_DBL predEsg[PVC_NTIMESLOT] - [PVC_NBHIGH_MAX]; /**< Predicted Energy in linear domain */ - int predEsg_exp[PVC_NTIMESLOT]; /**< Exponent of predicted Energy in linear - domain */ - int predEsg_expMax; /**< Maximum of predEsg_exp[] */ -} PVC_DYNAMIC_DATA; - -/** - * \brief Initialize PVC data structures for current frame (call if pvcMode = - * 0,1,2) - * \param[in] pPvcStaticData Pointer to PVC persistent data - * \param[out] pPvcDynamicData Pointer to PVC dynamic data - * \param[in] pvcMode PVC mode 1 or 2, 0 means legacy SBR - * \param[in] ns Number of time slots for time-domain smoothing of Esg(ksg,t) - * \param[in] RATE Number of QMF subband samples per time slot (2 or 4) - * \param[in] kx Index of the first QMF subband in the SBR range - * \param[in] pvcBorder0 Start SBR time slot of PVC frame - * \param[in] pPvcID Pointer to array of PvcIDs read from bitstream - */ -int pvcInitFrame(PVC_STATIC_DATA *pPvcStaticData, - PVC_DYNAMIC_DATA *pPvcDynamicData, const UCHAR pvcMode, - const UCHAR ns, const int RATE, const int kx, - const int pvcBorder0, const UCHAR *pPvcID); - -/** - * \brief Wrapper function for pvcDecodeTimeSlot() to decode PVC data of one - * frame (call if pvcMode = 1,2) - * \param[in,out] pPvcStaticData Pointer to PVC persistent data - * \param[in,out] pPvcDynamicData Pointer to PVC dynamic data - * \param[in] qmfBufferReal Pointer to array with real QMF subbands - * \param[in] qmfBufferImag Pointer to array with imag QMF subbands - * \param[in] overlap Number of QMF overlap slots - * \param[in] qmfExponentOverlap Exponent of qmfBuffer (low part) of overlap - * slots - * \param[in] qmfExponentCurrent Exponent of qmfBuffer (low part) - */ -void pvcDecodeFrame(PVC_STATIC_DATA *pPvcStaticData, - PVC_DYNAMIC_DATA *pPvcDynamicData, FIXP_DBL **qmfBufferReal, - FIXP_DBL **qmfBufferImag, const int overlap, - const int qmfExponentOverlap, const int qmfExponentCurrent); - -/** - * \brief Decode PVC data for one SBR time slot (call if pvcMode = 1,2) - * \param[in,out] pPvcStaticData Pointer to PVC persistent data - * \param[in,out] pPvcDynamicData Pointer to PVC dynamic data - * \param[in] qmfBufferReal Pointer to array with real QMF subbands - * \param[in] qmfBufferImag Pointer to array with imag QMF subbands - * \param[in] qmfExponent Exponent of qmfBuffer of current time slot - * \param[in] pvcBorder0 Start SBR time slot of PVC frame - * \param[in] timeSlotNumber Number of current SBR time slot (0..15) - * \param[out] predictedEsgSlot Predicted Energy of current time slot - * \param[out] predictedEsg_exp Exponent of predicted Energy of current time - * slot - */ -void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData, - PVC_DYNAMIC_DATA *pPvcDynamicData, - FIXP_DBL **qmfSlotReal, FIXP_DBL **qmfSlotImag, - const int qmfExponent, const int pvcBorder0, - const int timeSlotNumber, FIXP_DBL predictedEsgSlot[], - int *predictedEsg_exp); - -/** - * \brief Finish the current PVC frame (call if pvcMode = 0,1,2) - * \param[in,out] pPvcStaticData Pointer to PVC persistent data - * \param[in,out] pPvcDynamicData Pointer to PVC dynamic data - */ -void pvcEndFrame(PVC_STATIC_DATA *pPvcStaticData, - PVC_DYNAMIC_DATA *pPvcDynamicData); - -/** - * \brief Expand predicted PVC grouped energies to full QMF subband resolution - * \param[in] pPvcDynamicData Pointer to PVC dynamic data - * \param[in] timeSlot Number of current SBR time slot (0..15) - * \param[in] lengthOutputVector Lenght of output vector - * \param[out] pOutput Output array for predicted energies - * \param[out] pOutput_exp Exponent of predicted energies - */ -void expandPredEsg(const PVC_DYNAMIC_DATA *pPvcDynamicData, const int timeSlot, - const int lengthOutputVector, FIXP_DBL *pOutput, - SCHAR *pOutput_exp); - -#endif /* PVC_DEC_H*/ --- a/libSBRdec/src/sbr_crc.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief CRC check coutines -*/ - -#include "sbr_crc.h" - -#include "FDK_bitstream.h" -#include "transcendent.h" - -#define MAXCRCSTEP 16 -#define MAXCRCSTEP_LD 4 - -/*! - \brief crc calculation -*/ -static ULONG calcCRC(HANDLE_CRC hCrcBuf, ULONG bValue, int nBits) { - int i; - ULONG bMask = (1UL << (nBits - 1)); - - for (i = 0; i < nBits; i++, bMask >>= 1) { - USHORT flag = (hCrcBuf->crcState & hCrcBuf->crcMask) ? 1 : 0; - USHORT flag1 = (bMask & bValue) ? 1 : 0; - - flag ^= flag1; - hCrcBuf->crcState <<= 1; - if (flag) hCrcBuf->crcState ^= hCrcBuf->crcPoly; - } - - return (hCrcBuf->crcState); -} - -/*! - \brief crc -*/ -static int getCrc(HANDLE_FDK_BITSTREAM hBs, ULONG NrBits) { - int i; - CRC_BUFFER CrcBuf; - - CrcBuf.crcState = SBR_CRC_START; - CrcBuf.crcPoly = SBR_CRC_POLY; - CrcBuf.crcMask = SBR_CRC_MASK; - - int CrcStep = NrBits >> MAXCRCSTEP_LD; - - int CrcNrBitsRest = (NrBits - CrcStep * MAXCRCSTEP); - ULONG bValue; - - for (i = 0; i < CrcStep; i++) { - bValue = FDKreadBits(hBs, MAXCRCSTEP); - calcCRC(&CrcBuf, bValue, MAXCRCSTEP); - } - - bValue = FDKreadBits(hBs, CrcNrBitsRest); - calcCRC(&CrcBuf, bValue, CrcNrBitsRest); - - return (CrcBuf.crcState & SBR_CRC_RANGE); -} - -/*! - \brief crc interface - \return 1: CRC OK, 0: CRC check failure -*/ -int SbrCrcCheck(HANDLE_FDK_BITSTREAM hBs, /*!< handle to bit-buffer */ - LONG NrBits) /*!< max. CRC length */ -{ - int crcResult = 1; - ULONG NrCrcBits; - ULONG crcCheckResult; - LONG NrBitsAvailable; - ULONG crcCheckSum; - - crcCheckSum = FDKreadBits(hBs, 10); - - NrBitsAvailable = FDKgetValidBits(hBs); - if (NrBitsAvailable <= 0) { - return 0; - } - - NrCrcBits = fixMin((INT)NrBits, (INT)NrBitsAvailable); - - crcCheckResult = getCrc(hBs, NrCrcBits); - FDKpushBack(hBs, (NrBitsAvailable - FDKgetValidBits(hBs))); - - if (crcCheckResult != crcCheckSum) { - crcResult = 0; - } - - return (crcResult); -} --- a/libSBRdec/src/sbr_crc.h +++ /dev/null @@ -1,138 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief CRC checking routines -*/ -#ifndef SBR_CRC_H -#define SBR_CRC_H - -#include "sbrdecoder.h" - -#include "FDK_bitstream.h" - -/* some useful crc polynoms: - -crc5: x^5+x^4+x^2+x^1+1 -crc6: x^6+x^5+x^3+x^2+x+1 -crc7: x^7+x^6+x^2+1 -crc8: x^8+x^2+x+x+1 -*/ - -/* default SBR CRC */ /* G(x) = x^10 + x^9 + x^5 + x^4 + x + 1 */ -#define SBR_CRC_POLY 0x0233 -#define SBR_CRC_MASK 0x0200 -#define SBR_CRC_START 0x0000 -#define SBR_CRC_RANGE 0x03FF - -typedef struct { - USHORT crcState; - USHORT crcMask; - USHORT crcPoly; -} CRC_BUFFER; - -typedef CRC_BUFFER *HANDLE_CRC; - -int SbrCrcCheck(HANDLE_FDK_BITSTREAM hBitBuf, LONG NrCrcBits); - -#endif --- a/libSBRdec/src/sbr_deb.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Print selected debug messages -*/ - -#include "sbr_deb.h" --- a/libSBRdec/src/sbr_deb.h +++ /dev/null @@ -1,113 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Debugging aids -*/ - -#ifndef SBR_DEB_H -#define SBR_DEB_H - -#include "sbrdecoder.h" - -#endif --- a/libSBRdec/src/sbr_dec.cpp +++ /dev/null @@ -1,1480 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Sbr decoder - This module provides the actual decoder implementation. The SBR data (side - information) is already decoded. Only three functions are provided: - - \li 1.) createSbrDec(): One time initialization - \li 2.) resetSbrDec(): Called by sbr_Apply() when the information contained in - an SBR_HEADER_ELEMENT requires a reset and recalculation of important SBR - structures. \li 3.) sbr_dec(): The actual decoder. Calls the different tools - such as filterbanks, lppTransposer(), and calculateSbrEnvelope() [the envelope - adjuster]. - - \sa sbr_dec(), \ref documentationOverview -*/ - -#include "sbr_dec.h" - -#include "sbr_ram.h" -#include "env_extr.h" -#include "env_calc.h" -#include "scale.h" -#include "FDK_matrixCalloc.h" -#include "hbe.h" - -#include "genericStds.h" - -#include "sbrdec_drc.h" - -static void copyHarmonicSpectrum(int *xOverQmf, FIXP_DBL **qmfReal, - FIXP_DBL **qmfImag, int noCols, int overlap, - KEEP_STATES_SYNCED_MODE keepStatesSynced) { - int patchBands; - int patch, band, col, target, sourceBands, i; - int numPatches = 0; - int slotOffset = 0; - - FIXP_DBL **ppqmfReal = qmfReal + overlap; - FIXP_DBL **ppqmfImag = qmfImag + overlap; - - if (keepStatesSynced == KEEP_STATES_SYNCED_NORMAL) { - slotOffset = noCols - overlap - LPC_ORDER; - } - - if (keepStatesSynced == KEEP_STATES_SYNCED_OUTDIFF) { - ppqmfReal = qmfReal; - ppqmfImag = qmfImag; - } - - for (i = 1; i < MAX_NUM_PATCHES; i++) { - if (xOverQmf[i] != 0) { - numPatches++; - } - } - - for (patch = (MAX_STRETCH_HBE - 1); patch < numPatches; patch++) { - patchBands = xOverQmf[patch + 1] - xOverQmf[patch]; - target = xOverQmf[patch]; - sourceBands = xOverQmf[MAX_STRETCH_HBE - 1] - xOverQmf[MAX_STRETCH_HBE - 2]; - - while (patchBands > 0) { - int numBands = sourceBands; - int startBand = xOverQmf[MAX_STRETCH_HBE - 1] - 1; - if (target + numBands >= xOverQmf[patch + 1]) { - numBands = xOverQmf[patch + 1] - target; - } - if ((((target + numBands - 1) % 2) + - ((xOverQmf[MAX_STRETCH_HBE - 1] - 1) % 2)) % - 2) { - if (numBands == sourceBands) { - numBands--; - } else { - startBand--; - } - } - if (keepStatesSynced == KEEP_STATES_SYNCED_OUTDIFF) { - for (col = slotOffset; col < overlap + LPC_ORDER; col++) { - i = 0; - for (band = numBands; band > 0; band--) { - if ((target + band - 1 < 64) && - (target + band - 1 < xOverQmf[patch + 1])) { - ppqmfReal[col][target + band - 1] = ppqmfReal[col][startBand - i]; - ppqmfImag[col][target + band - 1] = ppqmfImag[col][startBand - i]; - i++; - } - } - } - } else { - for (col = slotOffset; col < noCols; col++) { - i = 0; - for (band = numBands; band > 0; band--) { - if ((target + band - 1 < 64) && - (target + band - 1 < xOverQmf[patch + 1])) { - ppqmfReal[col][target + band - 1] = ppqmfReal[col][startBand - i]; - ppqmfImag[col][target + band - 1] = ppqmfImag[col][startBand - i]; - i++; - } - } - } - } - target += numBands; - patchBands -= numBands; - } - } -} - -/*! - \brief SBR decoder core function for one channel - - \image html BufferMgmtDetailed-1632.png - - Besides the filter states of the QMF filter bank and the LPC-states of - the LPP-Transposer, processing is mainly based on four buffers: - #timeIn, #timeOut, #WorkBuffer2 and #OverlapBuffer. The #WorkBuffer2 - is reused for all channels and might be used by the core decoder, a - static overlap buffer is required for each channel. Due to in-place - processing, #timeIn and #timeOut point to identical locations. - - The spectral data is organized in so-called slots. Each slot - contains 64 bands of complex data. The number of slots per frame - depends on the frame size. For mp3PRO, there are 18 slots per frame - and 6 slots per #OverlapBuffer. It is not necessary to have the slots - in located consecutive address ranges. - - To optimize memory usage and to minimize the number of memory - accesses, the memory management is organized as follows (slot numbers - based on mp3PRO): - - 1.) Input time domain signal is located in #timeIn. The last slots - (0..5) of the spectral data of the previous frame are located in the - #OverlapBuffer. In addition, #frameData of the current frame resides - in the upper part of #timeIn. - - 2.) During the cplxAnalysisQmfFiltering(), 32 samples from #timeIn are - transformed into a slot of up to 32 complex spectral low band values at a - time. The first spectral slot -- nr. 6 -- is written at slot number - zero of #WorkBuffer2. #WorkBuffer2 will be completely filled with - spectral data. - - 3.) LPP-Transposition in lppTransposer() is processed on 24 slots. During the - transposition, the high band part of the spectral data is replicated - based on the low band data. - - Envelope Adjustment is processed on the high band part of the spectral - data only by calculateSbrEnvelope(). - - 4.) The cplxSynthesisQmfFiltering() creates 64 time domain samples out - of a slot of 64 complex spectral values at a time. The first 6 slots - in #timeOut are filled from the results of spectral slots 0..5 in the - #OverlapBuffer. The consecutive slots in timeOut are now filled with - the results of spectral slots 6..17. - - 5.) The preprocessed slots 18..23 have to be stored in the - #OverlapBuffer. - -*/ - -void sbr_dec( - HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */ - INT_PCM *timeIn, /*!< pointer to input time signal */ - INT_PCM *timeOut, /*!< pointer to output time signal */ - HANDLE_SBR_DEC hSbrDecRight, /*!< handle to Decoder channel right */ - INT_PCM *timeOutRight, /*!< pointer to output time signal */ - const int strideOut, /*!< Time data traversal strideOut */ - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */ - 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 int codecFrameSize) { - int i, slot, reserve; - int saveLbScale; - int lastSlotOffs; - FIXP_DBL maxVal; - - /* temporary pointer / variable for QMF; - required as we want to use temporary buffer - creating one frame delay for HBE in LP mode */ - INT_PCM *pTimeInQmf = timeIn; - - /* Number of QMF timeslots in the overlap buffer: */ - int ov_len = hSbrDec->LppTrans.pSettings->overlap; - - /* Number of QMF slots per frame */ - int noCols = hHeaderData->numberTimeSlots * hHeaderData->timeStep; - - /* create pointer array for data to use for HBE and legacy sbr */ - FIXP_DBL *pLowBandReal[(3 * 4) + 2 * ((1024) / (32) * (4) / 2)]; - FIXP_DBL *pLowBandImag[(3 * 4) + 2 * ((1024) / (32) * (4) / 2)]; - - /* set pReal to where QMF analysis writes in case of legacy SBR */ - FIXP_DBL **pReal = pLowBandReal + ov_len; - FIXP_DBL **pImag = pLowBandImag + ov_len; - - /* map QMF buffer to pointer array (Overlap + Frame)*/ - for (i = 0; i < noCols + ov_len; i++) { - pLowBandReal[i] = hSbrDec->qmfDomainInCh->hQmfSlotsReal[i]; - pLowBandImag[i] = hSbrDec->qmfDomainInCh->hQmfSlotsImag[i]; - } - - if ((flags & SBRDEC_USAC_HARMONICSBR)) { - /* in case of harmonic SBR and no HBE_LP map additional buffer for - one more frame to pointer arry */ - for (i = 0; i < noCols; i++) { - pLowBandReal[i + noCols + ov_len] = hSbrDec->hQmfHBESlotsReal[i]; - pLowBandImag[i + noCols + ov_len] = hSbrDec->hQmfHBESlotsImag[i]; - } - - /* shift scale values according to buffer */ - hSbrDec->scale_ov = hSbrDec->scale_lb; - hSbrDec->scale_lb = hSbrDec->scale_hbe; - - /* set pReal to where QMF analysis writes in case of HBE */ - pReal += noCols; - pImag += noCols; - if (flags & SBRDEC_SKIP_QMF_ANA) { - /* stereoCfgIndex3 with HBE */ - FDK_QmfDomain_QmfData2HBE(hSbrDec->qmfDomainInCh, - hSbrDec->hQmfHBESlotsReal, - hSbrDec->hQmfHBESlotsImag); - } else { - /* We have to move old hbe frame data to lb area of buffer */ - for (i = 0; i < noCols; i++) { - FDKmemcpy(pLowBandReal[ov_len + i], hSbrDec->hQmfHBESlotsReal[i], - hHeaderData->numberOfAnalysisBands * sizeof(FIXP_DBL)); - FDKmemcpy(pLowBandImag[ov_len + i], hSbrDec->hQmfHBESlotsImag[i], - hHeaderData->numberOfAnalysisBands * sizeof(FIXP_DBL)); - } - } - } - - /* - low band codec signal subband filtering - */ - - if (flags & SBRDEC_SKIP_QMF_ANA) { - if (!(flags & SBRDEC_USAC_HARMONICSBR)) /* stereoCfgIndex3 w/o HBE */ - FDK_QmfDomain_WorkBuffer2ProcChannel(hSbrDec->qmfDomainInCh); - } else { - C_AALLOC_SCRATCH_START(qmfTemp, FIXP_DBL, 2 * (64)); - qmfAnalysisFiltering(&hSbrDec->qmfDomainInCh->fb, pReal, pImag, - &hSbrDec->qmfDomainInCh->scaling, pTimeInQmf, 0, 1, - qmfTemp); - - C_AALLOC_SCRATCH_END(qmfTemp, FIXP_DBL, 2 * (64)); - } - - /* - Clear upper half of spectrum - */ - if (!((flags & SBRDEC_USAC_HARMONICSBR) && - (hFrameData->sbrPatchingMode == 0))) { - int nAnalysisBands = hHeaderData->numberOfAnalysisBands; - - if (!(flags & SBRDEC_LOW_POWER)) { - for (slot = ov_len; slot < noCols + ov_len; slot++) { - FDKmemclear(&pLowBandReal[slot][nAnalysisBands], - ((64) - nAnalysisBands) * sizeof(FIXP_DBL)); - FDKmemclear(&pLowBandImag[slot][nAnalysisBands], - ((64) - nAnalysisBands) * sizeof(FIXP_DBL)); - } - } else { - for (slot = ov_len; slot < noCols + ov_len; slot++) { - FDKmemclear(&pLowBandReal[slot][nAnalysisBands], - ((64) - nAnalysisBands) * sizeof(FIXP_DBL)); - } - } - } - - /* - Shift spectral data left to gain accuracy in transposer and adjustor - */ - /* Range was increased from lsb to no_channels because in some cases (e.g. - USAC conf eSbr_4_Pvc.mp4 and some HBE cases) it could be observed that the - signal between lsb and no_channels is used for the patching process. - */ - maxVal = maxSubbandSample(pReal, (flags & SBRDEC_LOW_POWER) ? NULL : pImag, 0, - hSbrDec->qmfDomainInCh->fb.no_channels, 0, noCols); - - reserve = fixMax(0, CntLeadingZeros(maxVal) - 1); - reserve = fixMin(reserve, - DFRACT_BITS - 1 - hSbrDec->qmfDomainInCh->scaling.lb_scale); - - /* If all data is zero, lb_scale could become too large */ - rescaleSubbandSamples(pReal, (flags & SBRDEC_LOW_POWER) ? NULL : pImag, 0, - hSbrDec->qmfDomainInCh->fb.no_channels, 0, noCols, - reserve); - - hSbrDec->qmfDomainInCh->scaling.lb_scale += reserve; - - if ((flags & SBRDEC_USAC_HARMONICSBR)) { - /* actually this is our hbe_scale */ - hSbrDec->scale_hbe = hSbrDec->qmfDomainInCh->scaling.lb_scale; - /* the real lb_scale is stored in scale_lb from sbr */ - hSbrDec->qmfDomainInCh->scaling.lb_scale = hSbrDec->scale_lb; - } - /* - save low band scale, wavecoding or parametric stereo may modify it - */ - saveLbScale = hSbrDec->qmfDomainInCh->scaling.lb_scale; - - if (applyProcessing) { - UCHAR *borders = hFrameData->frameInfo.borders; - lastSlotOffs = borders[hFrameData->frameInfo.nEnvelopes] - - hHeaderData->numberTimeSlots; - - FIXP_DBL degreeAlias[(64)]; - PVC_DYNAMIC_DATA pvcDynamicData; - pvcInitFrame( - &hSbrDec->PvcStaticData, &pvcDynamicData, - (hHeaderData->frameErrorFlag ? 0 : hHeaderData->bs_info.pvc_mode), - hFrameData->ns, hHeaderData->timeStep, - hHeaderData->freqBandData.lowSubband, - hFrameData->frameInfo.pvcBorders[0], hFrameData->pvcID); - - if (!hHeaderData->frameErrorFlag && (hHeaderData->bs_info.pvc_mode > 0)) { - pvcDecodeFrame(&hSbrDec->PvcStaticData, &pvcDynamicData, pLowBandReal, - pLowBandImag, ov_len, - SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale), - SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.lb_scale)); - } - pvcEndFrame(&hSbrDec->PvcStaticData, &pvcDynamicData); - - /* The transposer will override most values in degreeAlias[]. - The array needs to be cleared at least from lowSubband to highSubband - before. */ - if (flags & SBRDEC_LOW_POWER) - FDKmemclear(°reeAlias[hHeaderData->freqBandData.lowSubband], - (hHeaderData->freqBandData.highSubband - - hHeaderData->freqBandData.lowSubband) * - sizeof(FIXP_DBL)); - - /* - Inverse filtering of lowband and transposition into the SBR-frequency - range - */ - - { - KEEP_STATES_SYNCED_MODE keepStatesSyncedMode = - ((flags & SBRDEC_USAC_HARMONICSBR) && - (hFrameData->sbrPatchingMode != 0)) - ? KEEP_STATES_SYNCED_NORMAL - : KEEP_STATES_SYNCED_OFF; - - if (flags & SBRDEC_USAC_HARMONICSBR) { - if (flags & SBRDEC_QUAD_RATE) { - pReal -= 32; - pImag -= 32; - } - - if ((hSbrDec->savedStates == 0) && (hFrameData->sbrPatchingMode == 1)) { - /* copy saved states from previous frame to legacy SBR lpc filterstate - * buffer */ - for (i = 0; i < LPC_ORDER + ov_len; i++) { - FDKmemcpy( - hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i], - hSbrDec->codecQMFBufferReal[noCols - LPC_ORDER - ov_len + i], - hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL)); - FDKmemcpy( - hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[i], - hSbrDec->codecQMFBufferImag[noCols - LPC_ORDER - ov_len + i], - hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL)); - } - } - - /* saving unmodified QMF states in case we are switching from legacy SBR - * to HBE */ - for (i = 0; i < hSbrDec->hHBE->noCols; i++) { - FDKmemcpy(hSbrDec->codecQMFBufferReal[i], pLowBandReal[ov_len + i], - hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL)); - FDKmemcpy(hSbrDec->codecQMFBufferImag[i], pLowBandImag[ov_len + i], - hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL)); - } - - QmfTransposerApply( - hSbrDec->hHBE, pReal, pImag, noCols, pLowBandReal, pLowBandImag, - hSbrDec->LppTrans.lpcFilterStatesRealHBE, - hSbrDec->LppTrans.lpcFilterStatesImagHBE, - hFrameData->sbrPitchInBins, hSbrDec->scale_lb, hSbrDec->scale_hbe, - &hSbrDec->qmfDomainInCh->scaling.hb_scale, hHeaderData->timeStep, - borders[0], ov_len, keepStatesSyncedMode); - - if (flags & SBRDEC_QUAD_RATE) { - int *xOverQmf = GetxOverBandQmfTransposer(hSbrDec->hHBE); - - copyHarmonicSpectrum(xOverQmf, pLowBandReal, pLowBandImag, noCols, - ov_len, keepStatesSyncedMode); - } - } - } - - if ((flags & SBRDEC_USAC_HARMONICSBR) && - (hFrameData->sbrPatchingMode == 0)) { - hSbrDec->prev_frame_lSbr = 0; - hSbrDec->prev_frame_hbeSbr = 1; - - lppTransposerHBE( - &hSbrDec->LppTrans, hSbrDec->hHBE, &hSbrDec->qmfDomainInCh->scaling, - pLowBandReal, pLowBandImag, hHeaderData->timeStep, borders[0], - lastSlotOffs, hHeaderData->freqBandData.nInvfBands, - hFrameData->sbr_invf_mode, hPrevFrameData->sbr_invf_mode); - - } else { - if (flags & SBRDEC_USAC_HARMONICSBR) { - for (i = 0; i < LPC_ORDER + hSbrDec->LppTrans.pSettings->overlap; i++) { - /* - Store the unmodified qmf Slots values for upper part of spectrum - (required for LPC filtering) required if next frame is a HBE frame - */ - FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesRealHBE[i], - hSbrDec->qmfDomainInCh - ->hQmfSlotsReal[hSbrDec->hHBE->noCols - LPC_ORDER + i], - (64) * sizeof(FIXP_DBL)); - FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesImagHBE[i], - hSbrDec->qmfDomainInCh - ->hQmfSlotsImag[hSbrDec->hHBE->noCols - LPC_ORDER + i], - (64) * sizeof(FIXP_DBL)); - } - } - { - hSbrDec->prev_frame_lSbr = 1; - hSbrDec->prev_frame_hbeSbr = 0; - } - - lppTransposer( - &hSbrDec->LppTrans, &hSbrDec->qmfDomainInCh->scaling, pLowBandReal, - degreeAlias, // only used if useLP = 1 - pLowBandImag, flags & SBRDEC_LOW_POWER, - hHeaderData->bs_info.sbr_preprocessing, - hHeaderData->freqBandData.v_k_master[0], hHeaderData->timeStep, - borders[0], lastSlotOffs, hHeaderData->freqBandData.nInvfBands, - hFrameData->sbr_invf_mode, hPrevFrameData->sbr_invf_mode); - } - - /* - Adjust envelope of current frame. - */ - - if ((hFrameData->sbrPatchingMode != - hSbrDec->SbrCalculateEnvelope.sbrPatchingMode)) { - ResetLimiterBands(hHeaderData->freqBandData.limiterBandTable, - &hHeaderData->freqBandData.noLimiterBands, - hHeaderData->freqBandData.freqBandTable[0], - hHeaderData->freqBandData.nSfb[0], - hSbrDec->LppTrans.pSettings->patchParam, - hSbrDec->LppTrans.pSettings->noOfPatches, - hHeaderData->bs_data.limiterBands, - hFrameData->sbrPatchingMode, - (flags & SBRDEC_USAC_HARMONICSBR) && - (hFrameData->sbrPatchingMode == 0) - ? GetxOverBandQmfTransposer(hSbrDec->hHBE) - : NULL, - Get41SbrQmfTransposer(hSbrDec->hHBE)); - - hSbrDec->SbrCalculateEnvelope.sbrPatchingMode = - hFrameData->sbrPatchingMode; - } - - calculateSbrEnvelope( - &hSbrDec->qmfDomainInCh->scaling, &hSbrDec->SbrCalculateEnvelope, - hHeaderData, hFrameData, &pvcDynamicData, pLowBandReal, pLowBandImag, - flags & SBRDEC_LOW_POWER, - - degreeAlias, flags, - (hHeaderData->frameErrorFlag || hPrevFrameData->frameErrorFlag)); - -#if (SBRDEC_MAX_HB_FADE_FRAMES > 0) - /* Avoid hard onsets of high band */ - if (hHeaderData->frameErrorFlag) { - if (hSbrDec->highBandFadeCnt < SBRDEC_MAX_HB_FADE_FRAMES) { - hSbrDec->highBandFadeCnt += 1; - } - } else { - if (hSbrDec->highBandFadeCnt > - 0) { /* Manipulate high band scale factor to get a smooth fade-in */ - hSbrDec->qmfDomainInCh->scaling.hb_scale += hSbrDec->highBandFadeCnt; - hSbrDec->qmfDomainInCh->scaling.hb_scale = - fMin(hSbrDec->qmfDomainInCh->scaling.hb_scale, DFRACT_BITS - 1); - hSbrDec->highBandFadeCnt -= 1; - } - } - -#endif - /* - Update hPrevFrameData (to be used in the next frame) - */ - for (i = 0; i < hHeaderData->freqBandData.nInvfBands; i++) { - hPrevFrameData->sbr_invf_mode[i] = hFrameData->sbr_invf_mode[i]; - } - hPrevFrameData->coupling = hFrameData->coupling; - hPrevFrameData->stopPos = borders[hFrameData->frameInfo.nEnvelopes]; - hPrevFrameData->ampRes = hFrameData->ampResolutionCurrentFrame; - hPrevFrameData->prevSbrPitchInBins = hFrameData->sbrPitchInBins; - /* could be done in extractFrameInfo_pvc() but hPrevFrameData is not - * available there */ - FDKmemcpy(&hPrevFrameData->prevFrameInfo, &hFrameData->frameInfo, - sizeof(FRAME_INFO)); - } else { - /* rescale from lsb to nAnalysisBands in order to compensate scaling with - * hb_scale in this area, done by synthesisFiltering*/ - int rescale; - int lsb; - int length; - - /* Reset hb_scale if no highband is present, because hb_scale is considered - * in the QMF-synthesis */ - hSbrDec->qmfDomainInCh->scaling.hb_scale = saveLbScale; - - rescale = hSbrDec->qmfDomainInCh->scaling.hb_scale - - hSbrDec->qmfDomainInCh->scaling.ov_lb_scale; - lsb = hSbrDec->qmfDomainOutCh->fb.lsb; - length = (hSbrDec->qmfDomainInCh->fb.no_channels - lsb); - - if ((rescale < 0) && (length > 0)) { - if (!(flags & SBRDEC_LOW_POWER)) { - for (i = 0; i < ov_len; i++) { - scaleValues(&pLowBandReal[i][lsb], length, rescale); - scaleValues(&pLowBandImag[i][lsb], length, rescale); - } - } else { - for (i = 0; i < ov_len; i++) { - scaleValues(&pLowBandReal[i][lsb], length, rescale); - } - } - } - } - - if (!(flags & SBRDEC_USAC_HARMONICSBR)) { - int length = hSbrDec->qmfDomainInCh->fb.lsb; - if (flags & SBRDEC_SYNTAX_USAC) { - length = hSbrDec->qmfDomainInCh->fb.no_channels; - } - - /* in case of legacy sbr saving of filter states here */ - for (i = 0; i < LPC_ORDER + ov_len; i++) { - /* - Store the unmodified qmf Slots values (required for LPC filtering) - */ - if (!(flags & SBRDEC_LOW_POWER)) { - FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i], - pLowBandReal[noCols - LPC_ORDER + i], - length * sizeof(FIXP_DBL)); - FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[i], - pLowBandImag[noCols - LPC_ORDER + i], - length * sizeof(FIXP_DBL)); - } else - FDKmemcpy(hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i], - pLowBandReal[noCols - LPC_ORDER + i], - length * sizeof(FIXP_DBL)); - } - } - - /* - Synthesis subband filtering. - */ - - if (!(flags & SBRDEC_PS_DECODED)) { - if (!(flags & SBRDEC_SKIP_QMF_SYN)) { - int outScalefactor = 0; - - if (h_ps_d != NULL) { - h_ps_d->procFrameBased = 1; /* we here do frame based processing */ - } - - sbrDecoder_drcApply(&hSbrDec->sbrDrcChannel, pLowBandReal, - (flags & SBRDEC_LOW_POWER) ? NULL : pLowBandImag, - hSbrDec->qmfDomainOutCh->fb.no_col, &outScalefactor); - - qmfChangeOutScalefactor(&hSbrDec->qmfDomainOutCh->fb, outScalefactor); - - { - HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData; - int save_usb = hSbrDec->qmfDomainOutCh->fb.usb; - -#if (QMF_MAX_SYNTHESIS_BANDS <= 64) - C_AALLOC_SCRATCH_START(qmfTemp, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS); -#else - C_AALLOC_STACK_START(qmfTemp, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS); -#endif - if (hSbrDec->qmfDomainOutCh->fb.usb < hFreq->ov_highSubband) { - /* we need to patch usb for this frame as overlap may contain higher - frequency range if headerchange occured; fb. usb is always limited - to maximum fb.no_channels; In case of wrongly decoded headers it - might be that ov_highSubband is higher than the number of synthesis - channels (fb.no_channels), which is forbidden, therefore we need to - limit ov_highSubband with fMin function to avoid not allowed usb in - synthesis filterbank. */ - hSbrDec->qmfDomainOutCh->fb.usb = - fMin((UINT)hFreq->ov_highSubband, - (UINT)hSbrDec->qmfDomainOutCh->fb.no_channels); - } - { - qmfSynthesisFiltering( - &hSbrDec->qmfDomainOutCh->fb, pLowBandReal, - (flags & SBRDEC_LOW_POWER) ? NULL : pLowBandImag, - &hSbrDec->qmfDomainInCh->scaling, - hSbrDec->LppTrans.pSettings->overlap, timeOut, strideOut, - qmfTemp); - } - /* restore saved value */ - hSbrDec->qmfDomainOutCh->fb.usb = save_usb; - hFreq->ov_highSubband = save_usb; -#if (QMF_MAX_SYNTHESIS_BANDS <= 64) - C_AALLOC_SCRATCH_END(qmfTemp, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS); -#else - C_AALLOC_STACK_END(qmfTemp, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS); -#endif - } - } - - } else { /* (flags & SBRDEC_PS_DECODED) */ - INT sdiff; - INT scaleFactorHighBand, scaleFactorLowBand_ov, scaleFactorLowBand_no_ov; - - HANDLE_QMF_FILTER_BANK synQmf = &hSbrDec->qmfDomainOutCh->fb; - HANDLE_QMF_FILTER_BANK synQmfRight = &hSbrDecRight->qmfDomainOutCh->fb; - - /* adapt scaling */ - sdiff = hSbrDec->qmfDomainInCh->scaling.lb_scale - - reserve; /* Scaling difference */ - scaleFactorHighBand = sdiff - hSbrDec->qmfDomainInCh->scaling.hb_scale; - scaleFactorLowBand_ov = sdiff - hSbrDec->qmfDomainInCh->scaling.ov_lb_scale; - scaleFactorLowBand_no_ov = sdiff - hSbrDec->qmfDomainInCh->scaling.lb_scale; - - /* Scale of low band overlapping QMF data */ - scaleFactorLowBand_ov = - fMin(DFRACT_BITS - 1, fMax(-(DFRACT_BITS - 1), scaleFactorLowBand_ov)); - /* Scale of low band current QMF data */ - scaleFactorLowBand_no_ov = fMin( - DFRACT_BITS - 1, fMax(-(DFRACT_BITS - 1), scaleFactorLowBand_no_ov)); - /* Scale of current high band */ - scaleFactorHighBand = - fMin(DFRACT_BITS - 1, fMax(-(DFRACT_BITS - 1), scaleFactorHighBand)); - - if (h_ps_d->procFrameBased == 1) /* If we have switched from frame to slot - based processing copy filter states */ - { /* procFrameBased will be unset later */ - /* copy filter states from left to right */ - /* was ((640)-(64))*sizeof(FIXP_QSS) - flexible amount of synthesis bands needed for QMF based resampling - */ - FDK_ASSERT(hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis <= - QMF_MAX_SYNTHESIS_BANDS); - FDKmemcpy(synQmfRight->FilterStates, synQmf->FilterStates, - 9 * hSbrDec->qmfDomainInCh->pGlobalConf->nBandsSynthesis * - sizeof(FIXP_QSS)); - } - - /* Feed delaylines when parametric stereo is switched on. */ - PreparePsProcessing(h_ps_d, pLowBandReal, pLowBandImag, - scaleFactorLowBand_ov); - - /* use the same synthese qmf values for left and right channel */ - synQmfRight->no_col = synQmf->no_col; - synQmfRight->lsb = synQmf->lsb; - synQmfRight->usb = synQmf->usb; - - int env = 0; - - { -#if (QMF_MAX_SYNTHESIS_BANDS <= 64) - C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, - 2 * QMF_MAX_SYNTHESIS_BANDS); -#else - C_AALLOC_STACK_START(pWorkBuffer, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS); -#endif - - int maxShift = 0; - - if (hSbrDec->sbrDrcChannel.enable != 0) { - if (hSbrDec->sbrDrcChannel.prevFact_exp > maxShift) { - maxShift = hSbrDec->sbrDrcChannel.prevFact_exp; - } - if (hSbrDec->sbrDrcChannel.currFact_exp > maxShift) { - maxShift = hSbrDec->sbrDrcChannel.currFact_exp; - } - if (hSbrDec->sbrDrcChannel.nextFact_exp > maxShift) { - maxShift = hSbrDec->sbrDrcChannel.nextFact_exp; - } - } - - /* copy DRC data to right channel (with PS both channels use the same DRC - * gains) */ - FDKmemcpy(&hSbrDecRight->sbrDrcChannel, &hSbrDec->sbrDrcChannel, - sizeof(SBRDEC_DRC_CHANNEL)); - - for (i = 0; i < synQmf->no_col; i++) { /* ----- no_col loop ----- */ - - INT outScalefactorR, outScalefactorL; - - /* qmf timeslot of right channel */ - FIXP_DBL *rQmfReal = pWorkBuffer; - FIXP_DBL *rQmfImag = pWorkBuffer + synQmf->no_channels; - - { - if (i == - h_ps_d->bsData[h_ps_d->processSlot].mpeg.aEnvStartStop[env]) { - initSlotBasedRotation(h_ps_d, env, - hHeaderData->freqBandData.highSubband); - env++; - } - - ApplyPsSlot( - h_ps_d, /* parametric stereo decoder handle */ - (pLowBandReal + i), /* one timeslot of left/mono channel */ - (pLowBandImag + i), /* one timeslot of left/mono channel */ - rQmfReal, /* one timeslot or right channel */ - rQmfImag, /* one timeslot or right channel */ - scaleFactorLowBand_no_ov, - (i < hSbrDec->LppTrans.pSettings->overlap) - ? scaleFactorLowBand_ov - : scaleFactorLowBand_no_ov, - scaleFactorHighBand, synQmf->lsb, synQmf->usb); - - outScalefactorL = outScalefactorR = 1; /* psDiffScale! (MPEG-PS) */ - } - - sbrDecoder_drcApplySlot(/* right channel */ - &hSbrDecRight->sbrDrcChannel, rQmfReal, - rQmfImag, i, synQmfRight->no_col, maxShift); - - outScalefactorR += maxShift; - - sbrDecoder_drcApplySlot(/* left channel */ - &hSbrDec->sbrDrcChannel, *(pLowBandReal + i), - *(pLowBandImag + i), i, synQmf->no_col, - maxShift); - - outScalefactorL += maxShift; - - if (!(flags & SBRDEC_SKIP_QMF_SYN)) { - qmfSynthesisFilteringSlot( - synQmfRight, rQmfReal, /* QMF real buffer */ - rQmfImag, /* QMF imag buffer */ - outScalefactorL, outScalefactorL, - timeOutRight + (i * synQmf->no_channels * strideOut), strideOut, - pWorkBuffer); - - qmfSynthesisFilteringSlot( - synQmf, *(pLowBandReal + i), /* QMF real buffer */ - *(pLowBandImag + i), /* QMF imag buffer */ - outScalefactorR, outScalefactorR, - timeOut + (i * synQmf->no_channels * strideOut), strideOut, - pWorkBuffer); - } - } /* no_col loop i */ -#if (QMF_MAX_SYNTHESIS_BANDS <= 64) - C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS); -#else - C_AALLOC_STACK_END(pWorkBuffer, FIXP_DBL, 2 * QMF_MAX_SYNTHESIS_BANDS); -#endif - } - } - - sbrDecoder_drcUpdateChannel(&hSbrDec->sbrDrcChannel); - - /* - Update overlap buffer - Even bands above usb are copied to avoid outdated spectral data in case - the stop frequency raises. - */ - - if (!(flags & SBRDEC_SKIP_QMF_SYN)) { - { - FDK_QmfDomain_SaveOverlap(hSbrDec->qmfDomainInCh, 0); - FDK_ASSERT(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale == saveLbScale); - } - } - - hSbrDec->savedStates = 0; - - /* Save current frame status */ - hPrevFrameData->frameErrorFlag = hHeaderData->frameErrorFlag; - hSbrDec->applySbrProc_old = applyProcessing; - -} /* sbr_dec() */ - -/*! - \brief Creates sbr decoder structure - \return errorCode, 0 if successful -*/ -SBR_ERROR -createSbrDec(SBR_CHANNEL *hSbrChannel, - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - TRANSPOSER_SETTINGS *pSettings, - const int downsampleFac, /*!< Downsampling factor */ - const UINT qmfFlags, /*!< flags -> 1: HQ/LP selector, 2: CLDFB */ - const UINT flags, const int overlap, - int chan, /*!< Channel for which to assign buffers etc. */ - int codecFrameSize) - -{ - SBR_ERROR err = SBRDEC_OK; - int timeSlots = - hHeaderData->numberTimeSlots; /* Number of SBR slots per frame */ - int noCols = - timeSlots * hHeaderData->timeStep; /* Number of QMF slots per frame */ - HANDLE_SBR_DEC hs = &(hSbrChannel->SbrDec); - -#if (SBRDEC_MAX_HB_FADE_FRAMES > 0) - hs->highBandFadeCnt = SBRDEC_MAX_HB_FADE_FRAMES; - -#endif - hs->scale_hbe = 15; - hs->scale_lb = 15; - hs->scale_ov = 15; - - hs->prev_frame_lSbr = 0; - hs->prev_frame_hbeSbr = 0; - - hs->codecFrameSize = codecFrameSize; - - /* - create envelope calculator - */ - err = createSbrEnvelopeCalc(&hs->SbrCalculateEnvelope, hHeaderData, chan, - flags); - if (err != SBRDEC_OK) { - return err; - } - - initSbrPrevFrameData(&hSbrChannel->prevFrameData, timeSlots); - - /* - create transposer - */ - err = createLppTransposer( - &hs->LppTrans, pSettings, hHeaderData->freqBandData.lowSubband, - hHeaderData->freqBandData.v_k_master, hHeaderData->freqBandData.numMaster, - hHeaderData->freqBandData.highSubband, timeSlots, noCols, - hHeaderData->freqBandData.freqBandTableNoise, - hHeaderData->freqBandData.nNfb, hHeaderData->sbrProcSmplRate, chan, - overlap); - if (err != SBRDEC_OK) { - return err; - } - - if (flags & SBRDEC_USAC_HARMONICSBR) { - int noChannels, bSbr41 = flags & SBRDEC_QUAD_RATE ? 1 : 0; - - noChannels = - QMF_SYNTH_CHANNELS / - ((bSbr41 + 1) * 2); /* 32 for (32:64 and 24:64) and 16 for 16:64 */ - - /* shared memory between hbeLightTimeDelayBuffer and hQmfHBESlotsReal if - * SBRDEC_HBE_ENABLE */ - hSbrChannel->SbrDec.tmp_memory = (FIXP_DBL **)fdkCallocMatrix2D_aligned( - noCols, noChannels, sizeof(FIXP_DBL)); - if (hSbrChannel->SbrDec.tmp_memory == NULL) { - return SBRDEC_MEM_ALLOC_FAILED; - } - - hSbrChannel->SbrDec.hQmfHBESlotsReal = hSbrChannel->SbrDec.tmp_memory; - hSbrChannel->SbrDec.hQmfHBESlotsImag = - (FIXP_DBL **)fdkCallocMatrix2D_aligned(noCols, noChannels, - sizeof(FIXP_DBL)); - if (hSbrChannel->SbrDec.hQmfHBESlotsImag == NULL) { - return SBRDEC_MEM_ALLOC_FAILED; - } - - /* buffers containing unmodified qmf data; required when switching from - * legacy SBR to HBE */ - /* buffer can be used as LPCFilterstates buffer because legacy SBR needs - * exactly these values for LPC filtering */ - hSbrChannel->SbrDec.codecQMFBufferReal = - (FIXP_DBL **)fdkCallocMatrix2D_aligned(noCols, noChannels, - sizeof(FIXP_DBL)); - if (hSbrChannel->SbrDec.codecQMFBufferReal == NULL) { - return SBRDEC_MEM_ALLOC_FAILED; - } - - hSbrChannel->SbrDec.codecQMFBufferImag = - (FIXP_DBL **)fdkCallocMatrix2D_aligned(noCols, noChannels, - sizeof(FIXP_DBL)); - if (hSbrChannel->SbrDec.codecQMFBufferImag == NULL) { - return SBRDEC_MEM_ALLOC_FAILED; - } - - err = QmfTransposerCreate(&hs->hHBE, codecFrameSize, 0, bSbr41); - if (err != SBRDEC_OK) { - return err; - } - } - - return err; -} - -/*! - \brief Delete sbr decoder structure - \return errorCode, 0 if successful -*/ -int deleteSbrDec(SBR_CHANNEL *hSbrChannel) { - HANDLE_SBR_DEC hs = &hSbrChannel->SbrDec; - - deleteSbrEnvelopeCalc(&hs->SbrCalculateEnvelope); - - if (hs->tmp_memory != NULL) { - FDK_FREE_MEMORY_2D_ALIGNED(hs->tmp_memory); - } - - /* modify here */ - FDK_FREE_MEMORY_2D_ALIGNED(hs->hQmfHBESlotsImag); - - if (hs->hHBE != NULL) QmfTransposerClose(hs->hHBE); - - if (hs->codecQMFBufferReal != NULL) { - FDK_FREE_MEMORY_2D_ALIGNED(hs->codecQMFBufferReal); - } - - if (hs->codecQMFBufferImag != NULL) { - FDK_FREE_MEMORY_2D_ALIGNED(hs->codecQMFBufferImag); - } - - return 0; -} - -/*! - \brief resets sbr decoder structure - \return errorCode, 0 if successful -*/ -SBR_ERROR -resetSbrDec(HANDLE_SBR_DEC hSbrDec, HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, const int downsampleFac, - const UINT flags, HANDLE_SBR_FRAME_DATA hFrameData) { - SBR_ERROR sbrError = SBRDEC_OK; - int i; - FIXP_DBL *pLowBandReal[128]; - FIXP_DBL *pLowBandImag[128]; - int useLP = flags & SBRDEC_LOW_POWER; - - int old_lsb = hSbrDec->qmfDomainInCh->fb.lsb; - int old_usb = hSbrDec->qmfDomainInCh->fb.usb; - int new_lsb = hHeaderData->freqBandData.lowSubband; - /* int new_usb = hHeaderData->freqBandData.highSubband; */ - int l, startBand, stopBand, startSlot, size; - - FIXP_DBL **OverlapBufferReal = hSbrDec->qmfDomainInCh->hQmfSlotsReal; - FIXP_DBL **OverlapBufferImag = hSbrDec->qmfDomainInCh->hQmfSlotsImag; - - /* in case the previous frame was not active in terms of SBR processing, the - full band from 0 to no_channels was rescaled and not overwritten. Thats why - the scaling factor lb_scale can be seen as assigned to all bands from 0 to - no_channels in the previous frame. The same states for the current frame if - the current frame is not active in terms of SBR processing - */ - int applySbrProc = (hHeaderData->syncState == SBR_ACTIVE || - (hHeaderData->frameErrorFlag == 0 && - hHeaderData->syncState == SBR_HEADER)); - int applySbrProc_old = hSbrDec->applySbrProc_old; - - if (!applySbrProc) { - new_lsb = (hSbrDec->qmfDomainInCh->fb).no_channels; - } - if (!applySbrProc_old) { - old_lsb = (hSbrDec->qmfDomainInCh->fb).no_channels; - old_usb = old_lsb; - } - - resetSbrEnvelopeCalc(&hSbrDec->SbrCalculateEnvelope); - - /* Change lsb and usb */ - /* Synthesis */ - FDK_ASSERT(hSbrDec->qmfDomainOutCh != NULL); - hSbrDec->qmfDomainOutCh->fb.lsb = - fixMin((INT)hSbrDec->qmfDomainOutCh->fb.no_channels, - (INT)hHeaderData->freqBandData.lowSubband); - hSbrDec->qmfDomainOutCh->fb.usb = - fixMin((INT)hSbrDec->qmfDomainOutCh->fb.no_channels, - (INT)hHeaderData->freqBandData.highSubband); - /* Analysis */ - FDK_ASSERT(hSbrDec->qmfDomainInCh != NULL); - hSbrDec->qmfDomainInCh->fb.lsb = hSbrDec->qmfDomainOutCh->fb.lsb; - hSbrDec->qmfDomainInCh->fb.usb = hSbrDec->qmfDomainOutCh->fb.usb; - - /* - The following initialization of spectral data in the overlap buffer - is required for dynamic x-over or a change of the start-freq for 2 reasons: - - 1. If the lowband gets _wider_, unadjusted data would remain - - 2. If the lowband becomes _smaller_, the highest bands of the old lowband - must be cleared because the whitening would be affected - */ - startBand = old_lsb; - stopBand = new_lsb; - startSlot = fMax(0, hHeaderData->timeStep * (hPrevFrameData->stopPos - - hHeaderData->numberTimeSlots)); - size = fMax(0, stopBand - startBand); - - /* in case of USAC we don't want to zero out the memory, as this can lead to - holes in the spectrum; fix shall only be applied for USAC not for MPEG-4 - SBR, in this case setting zero remains */ - if (!(flags & SBRDEC_SYNTAX_USAC)) { - /* keep already adjusted data in the x-over-area */ - if (!useLP) { - for (l = startSlot; l < hSbrDec->LppTrans.pSettings->overlap; l++) { - FDKmemclear(&OverlapBufferReal[l][startBand], size * sizeof(FIXP_DBL)); - FDKmemclear(&OverlapBufferImag[l][startBand], size * sizeof(FIXP_DBL)); - } - } else { - for (l = startSlot; l < hSbrDec->LppTrans.pSettings->overlap; l++) { - FDKmemclear(&OverlapBufferReal[l][startBand], size * sizeof(FIXP_DBL)); - } - } - - /* - reset LPC filter states - */ - startBand = fixMin(old_lsb, new_lsb); - stopBand = fixMax(old_lsb, new_lsb); - size = fixMax(0, stopBand - startBand); - - FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[0][startBand], - size * sizeof(FIXP_DBL)); - FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[1][startBand], - size * sizeof(FIXP_DBL)); - if (!useLP) { - FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[0][startBand], - size * sizeof(FIXP_DBL)); - FDKmemclear(&hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[1][startBand], - size * sizeof(FIXP_DBL)); - } - } - - if (startSlot != 0) { - int source_exp, target_exp, delta_exp, target_lsb, target_usb, reserve; - FIXP_DBL maxVal; - - /* - Rescale already processed spectral data between old and new x-over - frequency. This must be done because of the separate scalefactors for - lowband and highband. - */ - - /* We have four relevant transitions to cover: - 1. old_usb is lower than new_lsb; old SBR area is completely below new SBR - area. - -> entire old area was highband and belongs to lowband now - and has to be rescaled. - 2. old_lsb is higher than new_usb; new SBR area is completely below old SBR - area. - -> old area between new_lsb and old_lsb was lowband and belongs to - highband now and has to be rescaled to match new highband scale. - 3. old_lsb is lower and old_usb is higher than new_lsb; old and new SBR - areas overlap. - -> old area between old_lsb and new_lsb was highband and belongs to - lowband now and has to be rescaled to match new lowband scale. - 4. new_lsb is lower and new_usb_is higher than old_lsb; old and new SBR - areas overlap. - -> old area between new_lsb and old_usb was lowband and belongs to - highband now and has to be rescaled to match new highband scale. - */ - - if (new_lsb > old_lsb) { - /* case 1 and 3 */ - source_exp = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_hb_scale); - target_exp = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale); - - startBand = old_lsb; - - if (new_lsb >= old_usb) { - /* case 1 */ - stopBand = old_usb; - } else { - /* case 3 */ - stopBand = new_lsb; - } - - target_lsb = 0; - target_usb = old_lsb; - } else { - /* case 2 and 4 */ - source_exp = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale); - target_exp = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_hb_scale); - - startBand = new_lsb; - stopBand = old_lsb; - - target_lsb = old_lsb; - target_usb = old_usb; - } - - maxVal = - maxSubbandSample(OverlapBufferReal, (useLP) ? NULL : OverlapBufferImag, - startBand, stopBand, 0, startSlot); - - reserve = ((LONG)maxVal != 0 ? CntLeadingZeros(maxVal) - 1 : 0); - reserve = fixMin( - reserve, - DFRACT_BITS - 1 - - EXP2SCALE( - source_exp)); /* what is this line for, why do we need it? */ - - /* process only if x-over-area is not dominant after rescale; - otherwise I'm not sure if all buffers are scaled correctly; - */ - if (target_exp - (source_exp - reserve) >= 0) { - rescaleSubbandSamples(OverlapBufferReal, - (useLP) ? NULL : OverlapBufferImag, startBand, - stopBand, 0, startSlot, reserve); - source_exp -= reserve; - } - - delta_exp = target_exp - source_exp; - - if (delta_exp < 0) { /* x-over-area is dominant */ - startBand = target_lsb; - stopBand = target_usb; - delta_exp = -delta_exp; - - if (new_lsb > old_lsb) { - /* The lowband has to be rescaled */ - hSbrDec->qmfDomainInCh->scaling.ov_lb_scale = EXP2SCALE(source_exp); - } else { - /* The highband has to be rescaled */ - hSbrDec->qmfDomainInCh->scaling.ov_hb_scale = EXP2SCALE(source_exp); - } - } - - FDK_ASSERT(startBand <= stopBand); - - if (!useLP) { - for (l = 0; l < startSlot; l++) { - scaleValues(OverlapBufferReal[l] + startBand, stopBand - startBand, - -delta_exp); - scaleValues(OverlapBufferImag[l] + startBand, stopBand - startBand, - -delta_exp); - } - } else - for (l = 0; l < startSlot; l++) { - scaleValues(OverlapBufferReal[l] + startBand, stopBand - startBand, - -delta_exp); - } - } /* startSlot != 0 */ - - /* - Initialize transposer and limiter - */ - sbrError = resetLppTransposer( - &hSbrDec->LppTrans, hHeaderData->freqBandData.lowSubband, - hHeaderData->freqBandData.v_k_master, hHeaderData->freqBandData.numMaster, - hHeaderData->freqBandData.freqBandTableNoise, - hHeaderData->freqBandData.nNfb, hHeaderData->freqBandData.highSubband, - hHeaderData->sbrProcSmplRate); - if (sbrError != SBRDEC_OK) return sbrError; - - hSbrDec->savedStates = 0; - - if ((flags & SBRDEC_USAC_HARMONICSBR) && applySbrProc) { - sbrError = QmfTransposerReInit(hSbrDec->hHBE, - hHeaderData->freqBandData.freqBandTable, - hHeaderData->freqBandData.nSfb); - if (sbrError != SBRDEC_OK) return sbrError; - - /* copy saved states from previous frame to legacy SBR lpc filterstate - * buffer */ - for (i = 0; i < LPC_ORDER + hSbrDec->LppTrans.pSettings->overlap; i++) { - FDKmemcpy( - hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i], - hSbrDec->codecQMFBufferReal[hSbrDec->hHBE->noCols - LPC_ORDER - - hSbrDec->LppTrans.pSettings->overlap + i], - hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL)); - FDKmemcpy( - hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[i], - hSbrDec->codecQMFBufferImag[hSbrDec->hHBE->noCols - LPC_ORDER - - hSbrDec->LppTrans.pSettings->overlap + i], - hSbrDec->hHBE->noChannels * sizeof(FIXP_DBL)); - } - hSbrDec->savedStates = 1; - - { - /* map QMF buffer to pointer array (Overlap + Frame)*/ - for (i = 0; i < hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER; i++) { - pLowBandReal[i] = hSbrDec->LppTrans.lpcFilterStatesRealHBE[i]; - pLowBandImag[i] = hSbrDec->LppTrans.lpcFilterStatesImagHBE[i]; - } - - /* map QMF buffer to pointer array (Overlap + Frame)*/ - for (i = 0; i < hSbrDec->hHBE->noCols; i++) { - pLowBandReal[i + hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] = - hSbrDec->codecQMFBufferReal[i]; - pLowBandImag[i + hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] = - hSbrDec->codecQMFBufferImag[i]; - } - - if (flags & SBRDEC_QUAD_RATE) { - if (hFrameData->sbrPatchingMode == 0) { - int *xOverQmf = GetxOverBandQmfTransposer(hSbrDec->hHBE); - - /* in case of harmonic SBR and no HBE_LP map additional buffer for - one more frame to pointer arry */ - for (i = 0; i < hSbrDec->hHBE->noCols / 2; i++) { - pLowBandReal[i + hSbrDec->hHBE->noCols + - hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] = - hSbrDec->hQmfHBESlotsReal[i]; - pLowBandImag[i + hSbrDec->hHBE->noCols + - hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] = - hSbrDec->hQmfHBESlotsImag[i]; - } - - QmfTransposerApply( - hSbrDec->hHBE, - pLowBandReal + hSbrDec->LppTrans.pSettings->overlap + - hSbrDec->hHBE->noCols / 2 + LPC_ORDER, - pLowBandImag + hSbrDec->LppTrans.pSettings->overlap + - hSbrDec->hHBE->noCols / 2 + LPC_ORDER, - hSbrDec->hHBE->noCols, pLowBandReal, pLowBandImag, - hSbrDec->LppTrans.lpcFilterStatesRealHBE, - hSbrDec->LppTrans.lpcFilterStatesImagHBE, - hPrevFrameData->prevSbrPitchInBins, hSbrDec->scale_lb, - hSbrDec->scale_hbe, &hSbrDec->qmfDomainInCh->scaling.hb_scale, - hHeaderData->timeStep, hFrameData->frameInfo.borders[0], - hSbrDec->LppTrans.pSettings->overlap, KEEP_STATES_SYNCED_OUTDIFF); - - copyHarmonicSpectrum( - xOverQmf, pLowBandReal, pLowBandImag, hSbrDec->hHBE->noCols, - hSbrDec->LppTrans.pSettings->overlap, KEEP_STATES_SYNCED_OUTDIFF); - } - } else { - /* in case of harmonic SBR and no HBE_LP map additional buffer for - one more frame to pointer arry */ - for (i = 0; i < hSbrDec->hHBE->noCols; i++) { - pLowBandReal[i + hSbrDec->hHBE->noCols + - hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] = - hSbrDec->hQmfHBESlotsReal[i]; - pLowBandImag[i + hSbrDec->hHBE->noCols + - hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER] = - hSbrDec->hQmfHBESlotsImag[i]; - } - - if (hFrameData->sbrPatchingMode == 0) { - QmfTransposerApply( - hSbrDec->hHBE, - pLowBandReal + hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER, - pLowBandImag + hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER, - hSbrDec->hHBE->noCols, pLowBandReal, pLowBandImag, - hSbrDec->LppTrans.lpcFilterStatesRealHBE, - hSbrDec->LppTrans.lpcFilterStatesImagHBE, - 0 /* not required for keeping states updated in this frame*/, - hSbrDec->scale_lb, hSbrDec->scale_lb, - &hSbrDec->qmfDomainInCh->scaling.hb_scale, hHeaderData->timeStep, - hFrameData->frameInfo.borders[0], - hSbrDec->LppTrans.pSettings->overlap, KEEP_STATES_SYNCED_NOOUT); - } - - QmfTransposerApply( - hSbrDec->hHBE, - pLowBandReal + hSbrDec->LppTrans.pSettings->overlap + - hSbrDec->hHBE->noCols + LPC_ORDER, - pLowBandImag + hSbrDec->LppTrans.pSettings->overlap + - hSbrDec->hHBE->noCols + LPC_ORDER, - hSbrDec->hHBE->noCols, pLowBandReal, pLowBandImag, - hSbrDec->LppTrans.lpcFilterStatesRealHBE, - hSbrDec->LppTrans.lpcFilterStatesImagHBE, - hPrevFrameData->prevSbrPitchInBins, hSbrDec->scale_lb, - hSbrDec->scale_hbe, &hSbrDec->qmfDomainInCh->scaling.hb_scale, - hHeaderData->timeStep, hFrameData->frameInfo.borders[0], - hSbrDec->LppTrans.pSettings->overlap, KEEP_STATES_SYNCED_OUTDIFF); - } - - if (hFrameData->sbrPatchingMode == 0) { - for (i = startSlot; i < hSbrDec->LppTrans.pSettings->overlap; i++) { - /* - Store the unmodified qmf Slots values for upper part of spectrum - (required for LPC filtering) required if next frame is a HBE frame - */ - FDKmemcpy(hSbrDec->qmfDomainInCh->hQmfSlotsReal[i], - hSbrDec->LppTrans.lpcFilterStatesRealHBE[i + LPC_ORDER], - (64) * sizeof(FIXP_DBL)); - FDKmemcpy(hSbrDec->qmfDomainInCh->hQmfSlotsImag[i], - hSbrDec->LppTrans.lpcFilterStatesImagHBE[i + LPC_ORDER], - (64) * sizeof(FIXP_DBL)); - } - - for (i = startSlot; i < hSbrDec->LppTrans.pSettings->overlap; i++) { - /* - Store the unmodified qmf Slots values for upper part of spectrum - (required for LPC filtering) required if next frame is a HBE frame - */ - FDKmemcpy( - hSbrDec->qmfDomainInCh->hQmfSlotsReal[i], - hSbrDec->codecQMFBufferReal[hSbrDec->hHBE->noCols - - hSbrDec->LppTrans.pSettings->overlap + - i], - new_lsb * sizeof(FIXP_DBL)); - FDKmemcpy( - hSbrDec->qmfDomainInCh->hQmfSlotsImag[i], - hSbrDec->codecQMFBufferImag[hSbrDec->hHBE->noCols - - hSbrDec->LppTrans.pSettings->overlap + - i], - new_lsb * sizeof(FIXP_DBL)); - } - } - } - } - - { - int adapt_lb = 0, diff = 0, - new_scale = hSbrDec->qmfDomainInCh->scaling.ov_lb_scale; - - if ((hSbrDec->qmfDomainInCh->scaling.ov_lb_scale != - hSbrDec->qmfDomainInCh->scaling.lb_scale) && - startSlot != 0) { - /* we need to adapt spectrum to have equal scale factor, always larger - * than zero */ - diff = SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.ov_lb_scale) - - SCALE2EXP(hSbrDec->qmfDomainInCh->scaling.lb_scale); - - if (diff > 0) { - adapt_lb = 1; - diff = -diff; - new_scale = hSbrDec->qmfDomainInCh->scaling.ov_lb_scale; - } - - stopBand = new_lsb; - } - - if (hFrameData->sbrPatchingMode == 1) { - /* scale states from LegSBR filterstates buffer */ - for (i = 0; i < hSbrDec->LppTrans.pSettings->overlap + LPC_ORDER; i++) { - scaleValues(hSbrDec->LppTrans.lpcFilterStatesRealLegSBR[i], new_lsb, - diff); - if (!useLP) { - scaleValues(hSbrDec->LppTrans.lpcFilterStatesImagLegSBR[i], new_lsb, - diff); - } - } - - if (flags & SBRDEC_SYNTAX_USAC) { - /* get missing states between old and new x_over from LegSBR - * filterstates buffer */ - /* in case of legacy SBR we leave these values zeroed out */ - for (i = startSlot; i < hSbrDec->LppTrans.pSettings->overlap; i++) { - FDKmemcpy(&OverlapBufferReal[i][old_lsb], - &hSbrDec->LppTrans - .lpcFilterStatesRealLegSBR[LPC_ORDER + i][old_lsb], - fMax(new_lsb - old_lsb, 0) * sizeof(FIXP_DBL)); - if (!useLP) { - FDKmemcpy(&OverlapBufferImag[i][old_lsb], - &hSbrDec->LppTrans - .lpcFilterStatesImagLegSBR[LPC_ORDER + i][old_lsb], - fMax(new_lsb - old_lsb, 0) * sizeof(FIXP_DBL)); - } - } - } - - if (new_lsb > old_lsb) { - stopBand = old_lsb; - } - } - if ((adapt_lb == 1) && (stopBand > startBand)) { - for (l = startSlot; l < hSbrDec->LppTrans.pSettings->overlap; l++) { - scaleValues(OverlapBufferReal[l] + startBand, stopBand - startBand, - diff); - if (!useLP) { - scaleValues(OverlapBufferImag[l] + startBand, stopBand - startBand, - diff); - } - } - } - hSbrDec->qmfDomainInCh->scaling.ov_lb_scale = new_scale; - } - - sbrError = ResetLimiterBands(hHeaderData->freqBandData.limiterBandTable, - &hHeaderData->freqBandData.noLimiterBands, - hHeaderData->freqBandData.freqBandTable[0], - hHeaderData->freqBandData.nSfb[0], - hSbrDec->LppTrans.pSettings->patchParam, - hSbrDec->LppTrans.pSettings->noOfPatches, - hHeaderData->bs_data.limiterBands, - hFrameData->sbrPatchingMode, - GetxOverBandQmfTransposer(hSbrDec->hHBE), - Get41SbrQmfTransposer(hSbrDec->hHBE)); - - hSbrDec->SbrCalculateEnvelope.sbrPatchingMode = hFrameData->sbrPatchingMode; - - return sbrError; -} --- a/libSBRdec/src/sbr_dec.h +++ /dev/null @@ -1,204 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Sbr decoder -*/ -#ifndef SBR_DEC_H -#define SBR_DEC_H - -#include "sbrdecoder.h" - -#include "lpp_tran.h" -#include "qmf.h" -#include "env_calc.h" -#include "FDK_audio.h" - -#include "sbrdec_drc.h" - -#include "pvc_dec.h" - -#include "hbe.h" - -enum SBRDEC_QMF_SKIP { - qmfSkipNothing = 0, - qmfSkipAnalysis = 1 << 0, - qmfSkipSynthesis = 1 << 1 -}; - -typedef struct { - SBR_CALCULATE_ENVELOPE SbrCalculateEnvelope; - SBR_LPP_TRANS LppTrans; - PVC_STATIC_DATA PvcStaticData; - - /* do scale handling in sbr an not in qmf */ - SHORT scale_ov; - SHORT scale_lb; - SHORT scale_hbe; - - SHORT prev_frame_lSbr; - SHORT prev_frame_hbeSbr; - - int codecFrameSize; - - HANDLE_HBE_TRANSPOSER hHBE; - - HANDLE_FDK_QMF_DOMAIN_IN qmfDomainInCh; - HANDLE_FDK_QMF_DOMAIN_OUT qmfDomainOutCh; - - SBRDEC_DRC_CHANNEL sbrDrcChannel; - -#if (SBRDEC_MAX_HB_FADE_FRAMES > 0) - INT highBandFadeCnt; /* counter for fading in high-band signal smoothly */ - -#endif - FIXP_DBL **tmp_memory; /* shared memory between hbeLightTimeDelayBuffer and - hQmfHBESlotsReal */ - - FIXP_DBL **hQmfHBESlotsReal; - FIXP_DBL **hQmfHBESlotsImag; - - FIXP_DBL **codecQMFBufferReal; - FIXP_DBL **codecQMFBufferImag; - UCHAR savedStates; - int applySbrProc_old; -} SBR_DEC; - -typedef SBR_DEC *HANDLE_SBR_DEC; - -typedef struct { - SBR_FRAME_DATA frameData[(1) + 1]; - SBR_PREV_FRAME_DATA prevFrameData; - SBR_DEC SbrDec; -} SBR_CHANNEL; - -typedef SBR_CHANNEL *HANDLE_SBR_CHANNEL; - -void sbr_dec( - HANDLE_SBR_DEC hSbrDec, /*!< handle to Decoder channel */ - INT_PCM *timeIn, /*!< pointer to input time signal */ - INT_PCM *timeOut, /*!< pointer to output time signal */ - HANDLE_SBR_DEC hSbrDecRight, /*!< handle to Decoder channel right */ - INT_PCM *timeOutRight, /*!< pointer to output time signal */ - INT strideOut, /*!< Time data traversal strideOut */ - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Static control data */ - HANDLE_SBR_FRAME_DATA hFrameData, /*!< Control data of current frame */ - 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 int codecFrameSize); - -SBR_ERROR -createSbrDec(SBR_CHANNEL *hSbrChannel, HANDLE_SBR_HEADER_DATA hHeaderData, - TRANSPOSER_SETTINGS *pSettings, const int downsampleFac, - const UINT qmfFlags, const UINT flags, const int overlap, int chan, - int codecFrameSize); - -int deleteSbrDec(SBR_CHANNEL *hSbrChannel); - -SBR_ERROR -resetSbrDec(HANDLE_SBR_DEC hSbrDec, HANDLE_SBR_HEADER_DATA hHeaderData, - HANDLE_SBR_PREV_FRAME_DATA hPrevFrameData, const int downsampleFac, - const UINT flags, HANDLE_SBR_FRAME_DATA hFrameData); - -#endif --- a/libSBRdec/src/sbr_ram.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Memory layout - - This module declares all static and dynamic memory spaces -*/ - -#include "sbr_ram.h" - -#define WORKBUFFER1_TAG 2 -#define WORKBUFFER2_TAG 3 - -/*! - \name StaticSbrData - - Static memory areas, must not be overwritten in other sections of the decoder -*/ -/* @{ */ - -/*! SBR Decoder main structure */ -C_ALLOC_MEM(Ram_SbrDecoder, struct SBR_DECODER_INSTANCE, 1) -/*! SBR Decoder element data
- Dimension: (8) */ -C_ALLOC_MEM2(Ram_SbrDecElement, SBR_DECODER_ELEMENT, 1, (8)) -/*! SBR Decoder individual channel data
- Dimension: (8) */ -C_ALLOC_MEM2(Ram_SbrDecChannel, SBR_CHANNEL, 1, (8) + 1) - -/*! Static Data of PS */ - -C_ALLOC_MEM(Ram_ps_dec, struct PS_DEC, 1) - -/* @} */ - -/*! - \name DynamicSbrData - - Dynamic memory areas, might be reused in other algorithm sections, - e.g. the core decoder -
- Depending on the mode set by DONT_USE_CORE_WORKBUFFER, workbuffers are - defined additionally to the CoreWorkbuffer. -
- The size of WorkBuffers is ((1024) / (32) * (4) / 2)*(64) = 2048. -
- WorkBuffer2 is a pointer to the CoreWorkBuffer wich is reused here in the SBR - part. In case of DONT_USE_CORE_WORKBUFFER, the CoreWorkbuffer is not used and - the according Workbuffer2 is defined locally in this file.
WorkBuffer1 is - reused in the AAC core (-> aacdecoder.cpp, aac_ram.cpp)
- - Use of WorkBuffers: -
-
-    -------------------------------------------------------------
-    AAC core:
-
-      CoreWorkbuffer: spectral coefficients
-      WorkBuffer1:    CAacDecoderChannelInfo, CAacDecoderDynamicData
-
-    -------------------------------------------------------------
-    SBR part:
-      ----------------------------------------------
-      Low Power Mode (useLP=1 or LOW_POWER_SBR_ONLY), see assignLcTimeSlots()
-
-        SLOT_BASED_PROTOTYPE_SYN_FILTER
-
-        WorkBuffer1                                WorkBuffer2(=CoreWorkbuffer)
-         ________________                           ________________
-        | RealLeft       |                         | RealRight      |
-        |________________|                         |________________|
-
-      ----------------------------------------------
-      High Quality Mode (!LOW_POWER_SBR_ONLY and useLP=0), see
-  assignHqTimeSlots()
-
-         SLOTBASED_PS
-
-         WorkBuffer1                                WorkBuffer2(=CoreWorkbuffer)
-         ________________                           ________________
-        | Real/Imag      |  interleaved            | Real/Imag      |
-  interleaved
-        |________________|  first half actual ch   |________________|  second
-  half actual ch
-
-    -------------------------------------------------------------
-
-  
- -*/ --- a/libSBRdec/src/sbr_ram.h +++ /dev/null @@ -1,186 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! -\file -\brief Memory layout -*/ -#ifndef SBR_RAM_H -#define SBR_RAM_H - -#include "sbrdecoder.h" - -#include "env_extr.h" -#include "sbr_dec.h" - -#define SBRDEC_MAX_CH_PER_ELEMENT (2) - -#define FRAME_OK (0) -#define FRAME_ERROR (1) -#define FRAME_ERROR_ALLSLOTS (2) - -typedef struct { - SBR_CHANNEL *pSbrChannel[SBRDEC_MAX_CH_PER_ELEMENT]; - TRANSPOSER_SETTINGS - transposerSettings; /* Common transport settings for each individual - channel of an element */ - HANDLE_FDK_BITSTREAM hBs; - - MP4_ELEMENT_ID - elementID; /* Element ID set during initialization. Can be used for - concealment */ - int nChannels; /* Number of elements output channels (=2 in case of PS) */ - - UCHAR frameErrorFlag[(1) + 1]; /* Frame error status (for every slot in the - delay line). Will be copied into header at - the very beginning of decodeElement() - routine. */ - - UCHAR useFrameSlot; /* Index which defines which slot will be decoded/filled - next (used with additional delay) */ - UCHAR useHeaderSlot[(1) + 1]; /* Index array that provides the link between - header and frame data (important when - processing with additional delay). */ -} SBR_DECODER_ELEMENT; - -struct SBR_DECODER_INSTANCE { - SBR_DECODER_ELEMENT *pSbrElement[(8)]; - SBR_HEADER_DATA sbrHeader[( - 8)][(1) + 1]; /* Sbr header for each individual channel of an element */ - - HANDLE_FDK_QMF_DOMAIN pQmfDomain; - - HANDLE_PS_DEC hParametricStereoDec; - - /* Global parameters */ - AUDIO_OBJECT_TYPE coreCodec; /* AOT of core codec */ - int numSbrElements; - int numSbrChannels; - INT sampleRateIn; /* SBR decoder input sampling rate; might be different than - the transposer input sampling rate. */ - INT sampleRateOut; /* Sampling rate of the SBR decoder output audio samples. - */ - USHORT codecFrameSize; - UCHAR synDownsampleFac; - INT downscaleFactor; - UCHAR numDelayFrames; /* The current number of additional delay frames used - for processing. */ - UCHAR harmonicSBR; - UCHAR - numFlushedFrames; /* The variable counts the number of frames which are - flushed consecutively. */ - - UINT flags; -}; - -H_ALLOC_MEM(Ram_SbrDecElement, SBR_DECODER_ELEMENT) -H_ALLOC_MEM(Ram_SbrDecChannel, SBR_CHANNEL) -H_ALLOC_MEM(Ram_SbrDecoder, struct SBR_DECODER_INSTANCE) - -H_ALLOC_MEM(Ram_sbr_QmfStatesSynthesis, FIXP_QSS) -H_ALLOC_MEM(Ram_sbr_OverlapBuffer, FIXP_DBL) - -H_ALLOC_MEM(Ram_sbr_HBEOverlapBuffer, FIXP_DBL) - -H_ALLOC_MEM(Ram_ps_dec, PS_DEC) - -#endif /* SBR_RAM_H */ --- a/libSBRdec/src/sbr_rom.cpp +++ /dev/null @@ -1,1705 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Definition of constant tables - - This module contains most of the constant data that can be stored in ROM. -*/ - -#include "sbr_rom.h" - -/*! - \name StartStopBands - \brief Start and stop subbands of the highband. - - k_o = startMin + offset[bs_start_freq]; - startMin = {3000,4000,5000} * (128/FS_sbr) / FS_sbr < 32Khz, 32Khz <= FS_sbr < - 64KHz, 64KHz <= FS_sbr The stop subband can also be calculated to save memory - by defining #CALC_STOP_BAND. -*/ -//@{ -/* tables were created with ../addon/octave/sbr_start_freq_table.m */ -const UCHAR FDK_sbrDecoder_sbr_start_freq_16[][16] = { - {16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, - {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}}; -const UCHAR FDK_sbrDecoder_sbr_start_freq_22[][16] = { - {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 28, 30}, - {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22}}; -const UCHAR FDK_sbrDecoder_sbr_start_freq_24[][16] = { - {11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25, 27, 29, 32}, - {3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 19, 21, 24}}; -const UCHAR FDK_sbrDecoder_sbr_start_freq_32[][16] = { - {10, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 25, 27, 29, 32}, - {2, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 19, 21, 24}}; -const UCHAR FDK_sbrDecoder_sbr_start_freq_40[][16] = { - {12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 26, 28, 30, 32}, - {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 19, 21, 23, 25}}; -const UCHAR FDK_sbrDecoder_sbr_start_freq_44[][16] = { - {8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 23, 25, 28, 32}, - {2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 17, 19, 22, 26}}; -const UCHAR FDK_sbrDecoder_sbr_start_freq_48[][16] = { - {7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 27, 31}, - {1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 21, 25}}; -const UCHAR FDK_sbrDecoder_sbr_start_freq_64[][16] = { - {6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 21, 23, 26, 30}, - {1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 21, 25}}; -const UCHAR FDK_sbrDecoder_sbr_start_freq_88[][16] = { - {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 23, 27, 31}, - {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 20, 24, 28}}; -const UCHAR FDK_sbrDecoder_sbr_start_freq_192[16] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 19, 23, 27}; -const UCHAR FDK_sbrDecoder_sbr_start_freq_176[16] = { - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 20, 24, 28}; -const UCHAR FDK_sbrDecoder_sbr_start_freq_128[16] = { - 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 21, 25}; - -//@} - -/*! - \name Whitening - \brief Coefficients for spectral whitening in the transposer -*/ -//@{ -/*! Assignment of whitening tuning depending on the crossover frequency */ -const USHORT FDK_sbrDecoder_sbr_whFactorsIndex[NUM_WHFACTOR_TABLE_ENTRIES] = { - 0, 5000, 6000, 6500, 7000, 7500, 8000, 9000, 10000}; - -/*! - \brief Whithening levels tuning table - - With the current tuning, there are some redundant entries: - - \li NUM_WHFACTOR_TABLE_ENTRIES can be reduced by 3, - \li the first coloumn can be eliminated. - -*/ -const FIXP_DBL - FDK_sbrDecoder_sbr_whFactorsTable[NUM_WHFACTOR_TABLE_ENTRIES][6] = { - /* OFF_LEVEL, TRANSITION_LEVEL, LOW_LEVEL, MID_LEVEL, HIGH_LEVEL */ - {FL2FXCONST_DBL(0.00f), FL2FXCONST_DBL(0.6f), FL2FXCONST_DBL(0.75f), - FL2FXCONST_DBL(0.90f), FL2FXCONST_DBL(0.98f)}, /* < 5000 */ - {FL2FXCONST_DBL(0.00f), FL2FXCONST_DBL(0.6f), FL2FXCONST_DBL(0.75f), - FL2FXCONST_DBL(0.90f), FL2FXCONST_DBL(0.98f)}, /* 5000 < 6000 */ - {FL2FXCONST_DBL(0.00f), FL2FXCONST_DBL(0.6f), FL2FXCONST_DBL(0.75f), - FL2FXCONST_DBL(0.90f), FL2FXCONST_DBL(0.98f)}, /* 6000 < 6500 */ - {FL2FXCONST_DBL(0.00f), FL2FXCONST_DBL(0.6f), FL2FXCONST_DBL(0.75f), - FL2FXCONST_DBL(0.90f), FL2FXCONST_DBL(0.98f)}, /* 6500 < 7000 */ - {FL2FXCONST_DBL(0.00f), FL2FXCONST_DBL(0.6f), FL2FXCONST_DBL(0.75f), - FL2FXCONST_DBL(0.90f), FL2FXCONST_DBL(0.98f)}, /* 7000 < 7500 */ - {FL2FXCONST_DBL(0.00f), FL2FXCONST_DBL(0.6f), FL2FXCONST_DBL(0.75f), - FL2FXCONST_DBL(0.90f), FL2FXCONST_DBL(0.98f)}, /* 7500 < 8000 */ - {FL2FXCONST_DBL(0.00f), FL2FXCONST_DBL(0.6f), FL2FXCONST_DBL(0.75f), - FL2FXCONST_DBL(0.90f), FL2FXCONST_DBL(0.98f)}, /* 8000 < 9000 */ - {FL2FXCONST_DBL(0.00f), FL2FXCONST_DBL(0.6f), FL2FXCONST_DBL(0.75f), - FL2FXCONST_DBL(0.90f), FL2FXCONST_DBL(0.98f)}, /* 9000 < 10000 */ - {FL2FXCONST_DBL(0.00f), FL2FXCONST_DBL(0.6f), FL2FXCONST_DBL(0.75f), - FL2FXCONST_DBL(0.90f), FL2FXCONST_DBL(0.98f)}, /* > 10000 */ -}; - -//@} - -/*! - \name EnvAdj - \brief Constants and tables used for envelope adjustment -*/ -//@{ - -/*! Mantissas of gain limits */ -const FIXP_SGL FDK_sbrDecoder_sbr_limGains_m[4] = { - FL2FXCONST_SGL(0.5011932025f), /*!< -3 dB. Gain limit when limiterGains in - frameData is 0 */ - FL2FXCONST_SGL( - 0.5f), /*!< 0 dB. Gain limit when limiterGains in frameData is 1 */ - FL2FXCONST_SGL(0.9976346258f), /*!< +3 dB. Gain limit when limiterGains in - frameData is 2 */ - FL2FXCONST_SGL(0.6776263578f) /*!< Inf. Gain limit when limiterGains in - frameData is 3 */ -}; - -/*! Exponents of gain limits */ -const UCHAR FDK_sbrDecoder_sbr_limGains_e[4] = {0, 1, 1, 67}; - -/*! Constants for calculating the number of limiter bands */ -const FIXP_SGL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[4] = { - FL2FXCONST_SGL(1.0f / 4.0f), FL2FXCONST_SGL(1.2f / 4.0f), - FL2FXCONST_SGL(2.0f / 4.0f), FL2FXCONST_SGL(3.0f / 4.0f)}; - -/*! Constants for calculating the number of limiter bands */ -const FIXP_DBL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[4] = { - FL2FXCONST_DBL(1.0f / 4.0f), FL2FXCONST_DBL(1.2f / 4.0f), - FL2FXCONST_DBL(2.0f / 4.0f), FL2FXCONST_DBL(3.0f / 4.0f)}; - -/*! Ratio of old gains and noise levels for the first 4 timeslots of an envelope - */ -const FIXP_SGL FDK_sbrDecoder_sbr_smoothFilter[4] = { - FL2FXCONST_SGL(0.66666666666666f), FL2FXCONST_SGL(0.36516383427084f), - FL2FXCONST_SGL(0.14699433520835f), FL2FXCONST_SGL(0.03183050093751f)}; - -/*! Real and imaginary part of random noise which will be modulated - to the desired level. An accuracy of 13 bits is sufficient for these - random numbers. -*/ -const FIXP_SGL FDK_sbrDecoder_sbr_randomPhase[SBR_NF_NO_RANDOM_VAL][2] = { - {FL2FXCONST_SGL(-0.99948153278296f / 8.0), - FL2FXCONST_SGL(-0.59483417516607f / 8.0)}, - {FL2FXCONST_SGL(0.97113454393991f / 8.0), - FL2FXCONST_SGL(-0.67528515225647f / 8.0)}, - {FL2FXCONST_SGL(0.14130051758487f / 8.0), - FL2FXCONST_SGL(-0.95090983575689f / 8.0)}, - {FL2FXCONST_SGL(-0.47005496701697f / 8.0), - FL2FXCONST_SGL(-0.37340549728647f / 8.0)}, - {FL2FXCONST_SGL(0.80705063769351f / 8.0), - FL2FXCONST_SGL(0.29653668284408f / 8.0)}, - {FL2FXCONST_SGL(-0.38981478896926f / 8.0), - FL2FXCONST_SGL(0.89572605717087f / 8.0)}, - {FL2FXCONST_SGL(-0.01053049862020f / 8.0), - FL2FXCONST_SGL(-0.66959058036166f / 8.0)}, - {FL2FXCONST_SGL(-0.91266367957293f / 8.0), - FL2FXCONST_SGL(-0.11522938140034f / 8.0)}, - {FL2FXCONST_SGL(0.54840422910309f / 8.0), - FL2FXCONST_SGL(0.75221367176302f / 8.0)}, - {FL2FXCONST_SGL(0.40009252867955f / 8.0), - FL2FXCONST_SGL(-0.98929400334421f / 8.0)}, - {FL2FXCONST_SGL(-0.99867974711855f / 8.0), - FL2FXCONST_SGL(-0.88147068645358f / 8.0)}, - {FL2FXCONST_SGL(-0.95531076805040f / 8.0), - FL2FXCONST_SGL(0.90908757154593f / 8.0)}, - {FL2FXCONST_SGL(-0.45725933317144f / 8.0), - FL2FXCONST_SGL(-0.56716323646760f / 8.0)}, - {FL2FXCONST_SGL(-0.72929675029275f / 8.0), - FL2FXCONST_SGL(-0.98008272727324f / 8.0)}, - {FL2FXCONST_SGL(0.75622801399036f / 8.0), - FL2FXCONST_SGL(0.20950329995549f / 8.0)}, - {FL2FXCONST_SGL(0.07069442601050f / 8.0), - FL2FXCONST_SGL(-0.78247898470706f / 8.0)}, - {FL2FXCONST_SGL(0.74496252926055f / 8.0), - FL2FXCONST_SGL(-0.91169004445807f / 8.0)}, - {FL2FXCONST_SGL(-0.96440182703856f / 8.0), - FL2FXCONST_SGL(-0.94739918296622f / 8.0)}, - {FL2FXCONST_SGL(0.30424629369539f / 8.0), - FL2FXCONST_SGL(-0.49438267012479f / 8.0)}, - {FL2FXCONST_SGL(0.66565033746925f / 8.0), - FL2FXCONST_SGL(0.64652935542491f / 8.0)}, - {FL2FXCONST_SGL(0.91697008020594f / 8.0), - FL2FXCONST_SGL(0.17514097332009f / 8.0)}, - {FL2FXCONST_SGL(-0.70774918760427f / 8.0), - FL2FXCONST_SGL(0.52548653416543f / 8.0)}, - {FL2FXCONST_SGL(-0.70051415345560f / 8.0), - FL2FXCONST_SGL(-0.45340028808763f / 8.0)}, - {FL2FXCONST_SGL(-0.99496513054797f / 8.0), - FL2FXCONST_SGL(-0.90071908066973f / 8.0)}, - {FL2FXCONST_SGL(0.98164490790123f / 8.0), - FL2FXCONST_SGL(-0.77463155528697f / 8.0)}, - {FL2FXCONST_SGL(-0.54671580548181f / 8.0), - FL2FXCONST_SGL(-0.02570928536004f / 8.0)}, - {FL2FXCONST_SGL(-0.01689629065389f / 8.0), - FL2FXCONST_SGL(0.00287506445732f / 8.0)}, - {FL2FXCONST_SGL(-0.86110349531986f / 8.0), - FL2FXCONST_SGL(0.42548583726477f / 8.0)}, - {FL2FXCONST_SGL(-0.98892980586032f / 8.0), - FL2FXCONST_SGL(-0.87881132267556f / 8.0)}, - {FL2FXCONST_SGL(0.51756627678691f / 8.0), - FL2FXCONST_SGL(0.66926784710139f / 8.0)}, - {FL2FXCONST_SGL(-0.99635026409640f / 8.0), - FL2FXCONST_SGL(-0.58107730574765f / 8.0)}, - {FL2FXCONST_SGL(-0.99969370862163f / 8.0), - FL2FXCONST_SGL(0.98369989360250f / 8.0)}, - {FL2FXCONST_SGL(0.55266258627194f / 8.0), - FL2FXCONST_SGL(0.59449057465591f / 8.0)}, - {FL2FXCONST_SGL(0.34581177741673f / 8.0), - FL2FXCONST_SGL(0.94879421061866f / 8.0)}, - {FL2FXCONST_SGL(0.62664209577999f / 8.0), - FL2FXCONST_SGL(-0.74402970906471f / 8.0)}, - {FL2FXCONST_SGL(-0.77149701404973f / 8.0), - FL2FXCONST_SGL(-0.33883658042801f / 8.0)}, - {FL2FXCONST_SGL(-0.91592244254432f / 8.0), - FL2FXCONST_SGL(0.03687901376713f / 8.0)}, - {FL2FXCONST_SGL(-0.76285492357887f / 8.0), - FL2FXCONST_SGL(-0.91371867919124f / 8.0)}, - {FL2FXCONST_SGL(0.79788337195331f / 8.0), - FL2FXCONST_SGL(-0.93180971199849f / 8.0)}, - {FL2FXCONST_SGL(0.54473080610200f / 8.0), - FL2FXCONST_SGL(-0.11919206037186f / 8.0)}, - {FL2FXCONST_SGL(-0.85639281671058f / 8.0), - FL2FXCONST_SGL(0.42429854760451f / 8.0)}, - {FL2FXCONST_SGL(-0.92882402971423f / 8.0), - FL2FXCONST_SGL(0.27871809078609f / 8.0)}, - {FL2FXCONST_SGL(-0.11708371046774f / 8.0), - FL2FXCONST_SGL(-0.99800843444966f / 8.0)}, - {FL2FXCONST_SGL(0.21356749817493f / 8.0), - FL2FXCONST_SGL(-0.90716295627033f / 8.0)}, - {FL2FXCONST_SGL(-0.76191692573909f / 8.0), - FL2FXCONST_SGL(0.99768118356265f / 8.0)}, - {FL2FXCONST_SGL(0.98111043100884f / 8.0), - FL2FXCONST_SGL(-0.95854459734407f / 8.0)}, - {FL2FXCONST_SGL(-0.85913269895572f / 8.0), - FL2FXCONST_SGL(0.95766566168880f / 8.0)}, - {FL2FXCONST_SGL(-0.93307242253692f / 8.0), - FL2FXCONST_SGL(0.49431757696466f / 8.0)}, - {FL2FXCONST_SGL(0.30485754879632f / 8.0), - FL2FXCONST_SGL(-0.70540034357529f / 8.0)}, - {FL2FXCONST_SGL(0.85289650925190f / 8.0), - FL2FXCONST_SGL(0.46766131791044f / 8.0)}, - {FL2FXCONST_SGL(0.91328082618125f / 8.0), - FL2FXCONST_SGL(-0.99839597361769f / 8.0)}, - {FL2FXCONST_SGL(-0.05890199924154f / 8.0), - FL2FXCONST_SGL(0.70741827819497f / 8.0)}, - {FL2FXCONST_SGL(0.28398686150148f / 8.0), - FL2FXCONST_SGL(0.34633555702188f / 8.0)}, - {FL2FXCONST_SGL(0.95258164539612f / 8.0), - FL2FXCONST_SGL(-0.54893416026939f / 8.0)}, - {FL2FXCONST_SGL(-0.78566324168507f / 8.0), - FL2FXCONST_SGL(-0.75568541079691f / 8.0)}, - {FL2FXCONST_SGL(-0.95789495447877f / 8.0), - FL2FXCONST_SGL(-0.20423194696966f / 8.0)}, - {FL2FXCONST_SGL(0.82411158711197f / 8.0), - FL2FXCONST_SGL(0.96654618432562f / 8.0)}, - {FL2FXCONST_SGL(-0.65185446735885f / 8.0), - FL2FXCONST_SGL(-0.88734990773289f / 8.0)}, - {FL2FXCONST_SGL(-0.93643603134666f / 8.0), - FL2FXCONST_SGL(0.99870790442385f / 8.0)}, - {FL2FXCONST_SGL(0.91427159529618f / 8.0), - FL2FXCONST_SGL(-0.98290505544444f / 8.0)}, - {FL2FXCONST_SGL(-0.70395684036886f / 8.0), - FL2FXCONST_SGL(0.58796798221039f / 8.0)}, - {FL2FXCONST_SGL(0.00563771969365f / 8.0), - FL2FXCONST_SGL(0.61768196727244f / 8.0)}, - {FL2FXCONST_SGL(0.89065051931895f / 8.0), - FL2FXCONST_SGL(0.52783352697585f / 8.0)}, - {FL2FXCONST_SGL(-0.68683707712762f / 8.0), - FL2FXCONST_SGL(0.80806944710339f / 8.0)}, - {FL2FXCONST_SGL(0.72165342518718f / 8.0), - FL2FXCONST_SGL(-0.69259857349564f / 8.0)}, - {FL2FXCONST_SGL(-0.62928247730667f / 8.0), - FL2FXCONST_SGL(0.13627037407335f / 8.0)}, - {FL2FXCONST_SGL(0.29938434065514f / 8.0), - FL2FXCONST_SGL(-0.46051329682246f / 8.0)}, - {FL2FXCONST_SGL(-0.91781958879280f / 8.0), - FL2FXCONST_SGL(-0.74012716684186f / 8.0)}, - {FL2FXCONST_SGL(0.99298717043688f / 8.0), - FL2FXCONST_SGL(0.40816610075661f / 8.0)}, - {FL2FXCONST_SGL(0.82368298622748f / 8.0), - FL2FXCONST_SGL(-0.74036047190173f / 8.0)}, - {FL2FXCONST_SGL(-0.98512833386833f / 8.0), - FL2FXCONST_SGL(-0.99972330709594f / 8.0)}, - {FL2FXCONST_SGL(-0.95915368242257f / 8.0), - FL2FXCONST_SGL(-0.99237800466040f / 8.0)}, - {FL2FXCONST_SGL(-0.21411126572790f / 8.0), - FL2FXCONST_SGL(-0.93424819052545f / 8.0)}, - {FL2FXCONST_SGL(-0.68821476106884f / 8.0), - FL2FXCONST_SGL(-0.26892306315457f / 8.0)}, - {FL2FXCONST_SGL(0.91851997982317f / 8.0), - FL2FXCONST_SGL(0.09358228901785f / 8.0)}, - {FL2FXCONST_SGL(-0.96062769559127f / 8.0), - FL2FXCONST_SGL(0.36099095133739f / 8.0)}, - {FL2FXCONST_SGL(0.51646184922287f / 8.0), - FL2FXCONST_SGL(-0.71373332873917f / 8.0)}, - {FL2FXCONST_SGL(0.61130721139669f / 8.0), - FL2FXCONST_SGL(0.46950141175917f / 8.0)}, - {FL2FXCONST_SGL(0.47336129371299f / 8.0), - FL2FXCONST_SGL(-0.27333178296162f / 8.0)}, - {FL2FXCONST_SGL(0.90998308703519f / 8.0), - FL2FXCONST_SGL(0.96715662938132f / 8.0)}, - {FL2FXCONST_SGL(0.44844799194357f / 8.0), - FL2FXCONST_SGL(0.99211574628306f / 8.0)}, - {FL2FXCONST_SGL(0.66614891079092f / 8.0), - FL2FXCONST_SGL(0.96590176169121f / 8.0)}, - {FL2FXCONST_SGL(0.74922239129237f / 8.0), - FL2FXCONST_SGL(-0.89879858826087f / 8.0)}, - {FL2FXCONST_SGL(-0.99571588506485f / 8.0), - FL2FXCONST_SGL(0.52785521494349f / 8.0)}, - {FL2FXCONST_SGL(0.97401082477563f / 8.0), - FL2FXCONST_SGL(-0.16855870075190f / 8.0)}, - {FL2FXCONST_SGL(0.72683747733879f / 8.0), - FL2FXCONST_SGL(-0.48060774432251f / 8.0)}, - {FL2FXCONST_SGL(0.95432193457128f / 8.0), - FL2FXCONST_SGL(0.68849603408441f / 8.0)}, - {FL2FXCONST_SGL(-0.72962208425191f / 8.0), - FL2FXCONST_SGL(-0.76608443420917f / 8.0)}, - {FL2FXCONST_SGL(-0.85359479233537f / 8.0), - FL2FXCONST_SGL(0.88738125901579f / 8.0)}, - {FL2FXCONST_SGL(-0.81412430338535f / 8.0), - FL2FXCONST_SGL(-0.97480768049637f / 8.0)}, - {FL2FXCONST_SGL(-0.87930772356786f / 8.0), - FL2FXCONST_SGL(0.74748307690436f / 8.0)}, - {FL2FXCONST_SGL(-0.71573331064977f / 8.0), - FL2FXCONST_SGL(-0.98570608178923f / 8.0)}, - {FL2FXCONST_SGL(0.83524300028228f / 8.0), - FL2FXCONST_SGL(0.83702537075163f / 8.0)}, - {FL2FXCONST_SGL(-0.48086065601423f / 8.0), - FL2FXCONST_SGL(-0.98848504923531f / 8.0)}, - {FL2FXCONST_SGL(0.97139128574778f / 8.0), - FL2FXCONST_SGL(0.80093621198236f / 8.0)}, - {FL2FXCONST_SGL(0.51992825347895f / 8.0), - FL2FXCONST_SGL(0.80247631400510f / 8.0)}, - {FL2FXCONST_SGL(-0.00848591195325f / 8.0), - FL2FXCONST_SGL(-0.76670128000486f / 8.0)}, - {FL2FXCONST_SGL(-0.70294374303036f / 8.0), - FL2FXCONST_SGL(0.55359910445577f / 8.0)}, - {FL2FXCONST_SGL(-0.95894428168140f / 8.0), - FL2FXCONST_SGL(-0.43265504344783f / 8.0)}, - {FL2FXCONST_SGL(0.97079252950321f / 8.0), - FL2FXCONST_SGL(0.09325857238682f / 8.0)}, - {FL2FXCONST_SGL(-0.92404293670797f / 8.0), - FL2FXCONST_SGL(0.85507704027855f / 8.0)}, - {FL2FXCONST_SGL(-0.69506469500450f / 8.0), - FL2FXCONST_SGL(0.98633412625459f / 8.0)}, - {FL2FXCONST_SGL(0.26559203620024f / 8.0), - FL2FXCONST_SGL(0.73314307966524f / 8.0)}, - {FL2FXCONST_SGL(0.28038443336943f / 8.0), - FL2FXCONST_SGL(0.14537913654427f / 8.0)}, - {FL2FXCONST_SGL(-0.74138124825523f / 8.0), - FL2FXCONST_SGL(0.99310339807762f / 8.0)}, - {FL2FXCONST_SGL(-0.01752795995444f / 8.0), - FL2FXCONST_SGL(-0.82616635284178f / 8.0)}, - {FL2FXCONST_SGL(-0.55126773094930f / 8.0), - FL2FXCONST_SGL(-0.98898543862153f / 8.0)}, - {FL2FXCONST_SGL(0.97960898850996f / 8.0), - FL2FXCONST_SGL(-0.94021446752851f / 8.0)}, - {FL2FXCONST_SGL(-0.99196309146936f / 8.0), - FL2FXCONST_SGL(0.67019017358456f / 8.0)}, - {FL2FXCONST_SGL(-0.67684928085260f / 8.0), - FL2FXCONST_SGL(0.12631491649378f / 8.0)}, - {FL2FXCONST_SGL(0.09140039465500f / 8.0), - FL2FXCONST_SGL(-0.20537731453108f / 8.0)}, - {FL2FXCONST_SGL(-0.71658965751996f / 8.0), - FL2FXCONST_SGL(-0.97788200391224f / 8.0)}, - {FL2FXCONST_SGL(0.81014640078925f / 8.0), - FL2FXCONST_SGL(0.53722648362443f / 8.0)}, - {FL2FXCONST_SGL(0.40616991671205f / 8.0), - FL2FXCONST_SGL(-0.26469008598449f / 8.0)}, - {FL2FXCONST_SGL(-0.67680188682972f / 8.0), - FL2FXCONST_SGL(0.94502052337695f / 8.0)}, - {FL2FXCONST_SGL(0.86849774348749f / 8.0), - FL2FXCONST_SGL(-0.18333598647899f / 8.0)}, - {FL2FXCONST_SGL(-0.99500381284851f / 8.0), - FL2FXCONST_SGL(-0.02634122068550f / 8.0)}, - {FL2FXCONST_SGL(0.84329189340667f / 8.0), - FL2FXCONST_SGL(0.10406957462213f / 8.0)}, - {FL2FXCONST_SGL(-0.09215968531446f / 8.0), - FL2FXCONST_SGL(0.69540012101253f / 8.0)}, - {FL2FXCONST_SGL(0.99956173327206f / 8.0), - FL2FXCONST_SGL(-0.12358542001404f / 8.0)}, - {FL2FXCONST_SGL(-0.79732779473535f / 8.0), - FL2FXCONST_SGL(-0.91582524736159f / 8.0)}, - {FL2FXCONST_SGL(0.96349973642406f / 8.0), - FL2FXCONST_SGL(0.96640458041000f / 8.0)}, - {FL2FXCONST_SGL(-0.79942778496547f / 8.0), - FL2FXCONST_SGL(0.64323902822857f / 8.0)}, - {FL2FXCONST_SGL(-0.11566039853896f / 8.0), - FL2FXCONST_SGL(0.28587846253726f / 8.0)}, - {FL2FXCONST_SGL(-0.39922954514662f / 8.0), - FL2FXCONST_SGL(0.94129601616966f / 8.0)}, - {FL2FXCONST_SGL(0.99089197565987f / 8.0), - FL2FXCONST_SGL(-0.92062625581587f / 8.0)}, - {FL2FXCONST_SGL(0.28631285179909f / 8.0), - FL2FXCONST_SGL(-0.91035047143603f / 8.0)}, - {FL2FXCONST_SGL(-0.83302725605608f / 8.0), - FL2FXCONST_SGL(-0.67330410892084f / 8.0)}, - {FL2FXCONST_SGL(0.95404443402072f / 8.0), - FL2FXCONST_SGL(0.49162765398743f / 8.0)}, - {FL2FXCONST_SGL(-0.06449863579434f / 8.0), - FL2FXCONST_SGL(0.03250560813135f / 8.0)}, - {FL2FXCONST_SGL(-0.99575054486311f / 8.0), - FL2FXCONST_SGL(0.42389784469507f / 8.0)}, - {FL2FXCONST_SGL(-0.65501142790847f / 8.0), - FL2FXCONST_SGL(0.82546114655624f / 8.0)}, - {FL2FXCONST_SGL(-0.81254441908887f / 8.0), - FL2FXCONST_SGL(-0.51627234660629f / 8.0)}, - {FL2FXCONST_SGL(-0.99646369485481f / 8.0), - FL2FXCONST_SGL(0.84490533520752f / 8.0)}, - {FL2FXCONST_SGL(0.00287840603348f / 8.0), - FL2FXCONST_SGL(0.64768261158166f / 8.0)}, - {FL2FXCONST_SGL(0.70176989408455f / 8.0), - FL2FXCONST_SGL(-0.20453028573322f / 8.0)}, - {FL2FXCONST_SGL(0.96361882270190f / 8.0), - FL2FXCONST_SGL(0.40706967140989f / 8.0)}, - {FL2FXCONST_SGL(-0.68883758192426f / 8.0), - FL2FXCONST_SGL(0.91338958840772f / 8.0)}, - {FL2FXCONST_SGL(-0.34875585502238f / 8.0), - FL2FXCONST_SGL(0.71472290693300f / 8.0)}, - {FL2FXCONST_SGL(0.91980081243087f / 8.0), - FL2FXCONST_SGL(0.66507455644919f / 8.0)}, - {FL2FXCONST_SGL(-0.99009048343881f / 8.0), - FL2FXCONST_SGL(0.85868021604848f / 8.0)}, - {FL2FXCONST_SGL(0.68865791458395f / 8.0), - FL2FXCONST_SGL(0.55660316809678f / 8.0)}, - {FL2FXCONST_SGL(-0.99484402129368f / 8.0), - FL2FXCONST_SGL(-0.20052559254934f / 8.0)}, - {FL2FXCONST_SGL(0.94214511408023f / 8.0), - FL2FXCONST_SGL(-0.99696425367461f / 8.0)}, - {FL2FXCONST_SGL(-0.67414626793544f / 8.0), - FL2FXCONST_SGL(0.49548221180078f / 8.0)}, - {FL2FXCONST_SGL(-0.47339353684664f / 8.0), - FL2FXCONST_SGL(-0.85904328834047f / 8.0)}, - {FL2FXCONST_SGL(0.14323651387360f / 8.0), - FL2FXCONST_SGL(-0.94145598222488f / 8.0)}, - {FL2FXCONST_SGL(-0.29268293575672f / 8.0), - FL2FXCONST_SGL(0.05759224927952f / 8.0)}, - {FL2FXCONST_SGL(0.43793861458754f / 8.0), - FL2FXCONST_SGL(-0.78904969892724f / 8.0)}, - {FL2FXCONST_SGL(-0.36345126374441f / 8.0), - FL2FXCONST_SGL(0.64874435357162f / 8.0)}, - {FL2FXCONST_SGL(-0.08750604656825f / 8.0), - FL2FXCONST_SGL(0.97686944362527f / 8.0)}, - {FL2FXCONST_SGL(-0.96495267812511f / 8.0), - FL2FXCONST_SGL(-0.53960305946511f / 8.0)}, - {FL2FXCONST_SGL(0.55526940659947f / 8.0), - FL2FXCONST_SGL(0.78891523734774f / 8.0)}, - {FL2FXCONST_SGL(0.73538215752630f / 8.0), - FL2FXCONST_SGL(0.96452072373404f / 8.0)}, - {FL2FXCONST_SGL(-0.30889773919437f / 8.0), - FL2FXCONST_SGL(-0.80664389776860f / 8.0)}, - {FL2FXCONST_SGL(0.03574995626194f / 8.0), - FL2FXCONST_SGL(-0.97325616900959f / 8.0)}, - {FL2FXCONST_SGL(0.98720684660488f / 8.0), - FL2FXCONST_SGL(0.48409133691962f / 8.0)}, - {FL2FXCONST_SGL(-0.81689296271203f / 8.0), - FL2FXCONST_SGL(-0.90827703628298f / 8.0)}, - {FL2FXCONST_SGL(0.67866860118215f / 8.0), - FL2FXCONST_SGL(0.81284503870856f / 8.0)}, - {FL2FXCONST_SGL(-0.15808569732583f / 8.0), - FL2FXCONST_SGL(0.85279555024382f / 8.0)}, - {FL2FXCONST_SGL(0.80723395114371f / 8.0), - FL2FXCONST_SGL(-0.24717418514605f / 8.0)}, - {FL2FXCONST_SGL(0.47788757329038f / 8.0), - FL2FXCONST_SGL(-0.46333147839295f / 8.0)}, - {FL2FXCONST_SGL(0.96367554763201f / 8.0), - FL2FXCONST_SGL(0.38486749303242f / 8.0)}, - {FL2FXCONST_SGL(-0.99143875716818f / 8.0), - FL2FXCONST_SGL(-0.24945277239809f / 8.0)}, - {FL2FXCONST_SGL(0.83081876925833f / 8.0), - FL2FXCONST_SGL(-0.94780851414763f / 8.0)}, - {FL2FXCONST_SGL(-0.58753191905341f / 8.0), - FL2FXCONST_SGL(0.01290772389163f / 8.0)}, - {FL2FXCONST_SGL(0.95538108220960f / 8.0), - FL2FXCONST_SGL(-0.85557052096538f / 8.0)}, - {FL2FXCONST_SGL(-0.96490920476211f / 8.0), - FL2FXCONST_SGL(-0.64020970923102f / 8.0)}, - {FL2FXCONST_SGL(-0.97327101028521f / 8.0), - FL2FXCONST_SGL(0.12378128133110f / 8.0)}, - {FL2FXCONST_SGL(0.91400366022124f / 8.0), - FL2FXCONST_SGL(0.57972471346930f / 8.0)}, - {FL2FXCONST_SGL(-0.99925837363824f / 8.0), - FL2FXCONST_SGL(0.71084847864067f / 8.0)}, - {FL2FXCONST_SGL(-0.86875903507313f / 8.0), - FL2FXCONST_SGL(-0.20291699203564f / 8.0)}, - {FL2FXCONST_SGL(-0.26240034795124f / 8.0), - FL2FXCONST_SGL(-0.68264554369108f / 8.0)}, - {FL2FXCONST_SGL(-0.24664412953388f / 8.0), - FL2FXCONST_SGL(-0.87642273115183f / 8.0)}, - {FL2FXCONST_SGL(0.02416275806869f / 8.0), - FL2FXCONST_SGL(0.27192914288905f / 8.0)}, - {FL2FXCONST_SGL(0.82068619590515f / 8.0), - FL2FXCONST_SGL(-0.85087787994476f / 8.0)}, - {FL2FXCONST_SGL(0.88547373760759f / 8.0), - FL2FXCONST_SGL(-0.89636802901469f / 8.0)}, - {FL2FXCONST_SGL(-0.18173078152226f / 8.0), - FL2FXCONST_SGL(-0.26152145156800f / 8.0)}, - {FL2FXCONST_SGL(0.09355476558534f / 8.0), - FL2FXCONST_SGL(0.54845123045604f / 8.0)}, - {FL2FXCONST_SGL(-0.54668414224090f / 8.0), - FL2FXCONST_SGL(0.95980774020221f / 8.0)}, - {FL2FXCONST_SGL(0.37050990604091f / 8.0), - FL2FXCONST_SGL(-0.59910140383171f / 8.0)}, - {FL2FXCONST_SGL(-0.70373594262891f / 8.0), - FL2FXCONST_SGL(0.91227665827081f / 8.0)}, - {FL2FXCONST_SGL(-0.34600785879594f / 8.0), - FL2FXCONST_SGL(-0.99441426144200f / 8.0)}, - {FL2FXCONST_SGL(-0.68774481731008f / 8.0), - FL2FXCONST_SGL(-0.30238837956299f / 8.0)}, - {FL2FXCONST_SGL(-0.26843291251234f / 8.0), - FL2FXCONST_SGL(0.83115668004362f / 8.0)}, - {FL2FXCONST_SGL(0.49072334613242f / 8.0), - FL2FXCONST_SGL(-0.45359708737775f / 8.0)}, - {FL2FXCONST_SGL(0.38975993093975f / 8.0), - FL2FXCONST_SGL(0.95515358099121f / 8.0)}, - {FL2FXCONST_SGL(-0.97757125224150f / 8.0), - FL2FXCONST_SGL(0.05305894580606f / 8.0)}, - {FL2FXCONST_SGL(-0.17325552859616f / 8.0), - FL2FXCONST_SGL(-0.92770672250494f / 8.0)}, - {FL2FXCONST_SGL(0.99948035025744f / 8.0), - FL2FXCONST_SGL(0.58285545563426f / 8.0)}, - {FL2FXCONST_SGL(-0.64946246527458f / 8.0), - FL2FXCONST_SGL(0.68645507104960f / 8.0)}, - {FL2FXCONST_SGL(-0.12016920576437f / 8.0), - FL2FXCONST_SGL(-0.57147322153312f / 8.0)}, - {FL2FXCONST_SGL(-0.58947456517751f / 8.0), - FL2FXCONST_SGL(-0.34847132454388f / 8.0)}, - {FL2FXCONST_SGL(-0.41815140454465f / 8.0), - FL2FXCONST_SGL(0.16276422358861f / 8.0)}, - {FL2FXCONST_SGL(0.99885650204884f / 8.0), - FL2FXCONST_SGL(0.11136095490444f / 8.0)}, - {FL2FXCONST_SGL(-0.56649614128386f / 8.0), - FL2FXCONST_SGL(-0.90494866361587f / 8.0)}, - {FL2FXCONST_SGL(0.94138021032330f / 8.0), - FL2FXCONST_SGL(0.35281916733018f / 8.0)}, - {FL2FXCONST_SGL(-0.75725076534641f / 8.0), - FL2FXCONST_SGL(0.53650549640587f / 8.0)}, - {FL2FXCONST_SGL(0.20541973692630f / 8.0), - FL2FXCONST_SGL(-0.94435144369918f / 8.0)}, - {FL2FXCONST_SGL(0.99980371023351f / 8.0), - FL2FXCONST_SGL(0.79835913565599f / 8.0)}, - {FL2FXCONST_SGL(0.29078277605775f / 8.0), - FL2FXCONST_SGL(0.35393777921520f / 8.0)}, - {FL2FXCONST_SGL(-0.62858772103030f / 8.0), - FL2FXCONST_SGL(0.38765693387102f / 8.0)}, - {FL2FXCONST_SGL(0.43440904467688f / 8.0), - FL2FXCONST_SGL(-0.98546330463232f / 8.0)}, - {FL2FXCONST_SGL(-0.98298583762390f / 8.0), - FL2FXCONST_SGL(0.21021524625209f / 8.0)}, - {FL2FXCONST_SGL(0.19513029146934f / 8.0), - FL2FXCONST_SGL(-0.94239832251867f / 8.0)}, - {FL2FXCONST_SGL(-0.95476662400101f / 8.0), - FL2FXCONST_SGL(0.98364554179143f / 8.0)}, - {FL2FXCONST_SGL(0.93379635304810f / 8.0), - FL2FXCONST_SGL(-0.70881994583682f / 8.0)}, - {FL2FXCONST_SGL(-0.85235410573336f / 8.0), - FL2FXCONST_SGL(-0.08342347966410f / 8.0)}, - {FL2FXCONST_SGL(-0.86425093011245f / 8.0), - FL2FXCONST_SGL(-0.45795025029466f / 8.0)}, - {FL2FXCONST_SGL(0.38879779059045f / 8.0), - FL2FXCONST_SGL(0.97274429344593f / 8.0)}, - {FL2FXCONST_SGL(0.92045124735495f / 8.0), - FL2FXCONST_SGL(-0.62433652524220f / 8.0)}, - {FL2FXCONST_SGL(0.89162532251878f / 8.0), - FL2FXCONST_SGL(0.54950955570563f / 8.0)}, - {FL2FXCONST_SGL(-0.36834336949252f / 8.0), - FL2FXCONST_SGL(0.96458298020975f / 8.0)}, - {FL2FXCONST_SGL(0.93891760988045f / 8.0), - FL2FXCONST_SGL(-0.89968353740388f / 8.0)}, - {FL2FXCONST_SGL(0.99267657565094f / 8.0), - FL2FXCONST_SGL(-0.03757034316958f / 8.0)}, - {FL2FXCONST_SGL(-0.94063471614176f / 8.0), - FL2FXCONST_SGL(0.41332338538963f / 8.0)}, - {FL2FXCONST_SGL(0.99740224117019f / 8.0), - FL2FXCONST_SGL(-0.16830494996370f / 8.0)}, - {FL2FXCONST_SGL(-0.35899413170555f / 8.0), - FL2FXCONST_SGL(-0.46633226649613f / 8.0)}, - {FL2FXCONST_SGL(0.05237237274947f / 8.0), - FL2FXCONST_SGL(-0.25640361602661f / 8.0)}, - {FL2FXCONST_SGL(0.36703583957424f / 8.0), - FL2FXCONST_SGL(-0.38653265641875f / 8.0)}, - {FL2FXCONST_SGL(0.91653180367913f / 8.0), - FL2FXCONST_SGL(-0.30587628726597f / 8.0)}, - {FL2FXCONST_SGL(0.69000803499316f / 8.0), - FL2FXCONST_SGL(0.90952171386132f / 8.0)}, - {FL2FXCONST_SGL(-0.38658751133527f / 8.0), - FL2FXCONST_SGL(0.99501571208985f / 8.0)}, - {FL2FXCONST_SGL(-0.29250814029851f / 8.0), - FL2FXCONST_SGL(0.37444994344615f / 8.0)}, - {FL2FXCONST_SGL(-0.60182204677608f / 8.0), - FL2FXCONST_SGL(0.86779651036123f / 8.0)}, - {FL2FXCONST_SGL(-0.97418588163217f / 8.0), - FL2FXCONST_SGL(0.96468523666475f / 8.0)}, - {FL2FXCONST_SGL(0.88461574003963f / 8.0), - FL2FXCONST_SGL(0.57508405276414f / 8.0)}, - {FL2FXCONST_SGL(0.05198933055162f / 8.0), - FL2FXCONST_SGL(0.21269661669964f / 8.0)}, - {FL2FXCONST_SGL(-0.53499621979720f / 8.0), - FL2FXCONST_SGL(0.97241553731237f / 8.0)}, - {FL2FXCONST_SGL(-0.49429560226497f / 8.0), - FL2FXCONST_SGL(0.98183865291903f / 8.0)}, - {FL2FXCONST_SGL(-0.98935142339139f / 8.0), - FL2FXCONST_SGL(-0.40249159006933f / 8.0)}, - {FL2FXCONST_SGL(-0.98081380091130f / 8.0), - FL2FXCONST_SGL(-0.72856895534041f / 8.0)}, - {FL2FXCONST_SGL(-0.27338148835532f / 8.0), - FL2FXCONST_SGL(0.99950922447209f / 8.0)}, - {FL2FXCONST_SGL(0.06310802338302f / 8.0), - FL2FXCONST_SGL(-0.54539587529618f / 8.0)}, - {FL2FXCONST_SGL(-0.20461677199539f / 8.0), - FL2FXCONST_SGL(-0.14209977628489f / 8.0)}, - {FL2FXCONST_SGL(0.66223843141647f / 8.0), - FL2FXCONST_SGL(0.72528579940326f / 8.0)}, - {FL2FXCONST_SGL(-0.84764345483665f / 8.0), - FL2FXCONST_SGL(0.02372316801261f / 8.0)}, - {FL2FXCONST_SGL(-0.89039863483811f / 8.0), - FL2FXCONST_SGL(0.88866581484602f / 8.0)}, - {FL2FXCONST_SGL(0.95903308477986f / 8.0), - FL2FXCONST_SGL(0.76744927173873f / 8.0)}, - {FL2FXCONST_SGL(0.73504123909879f / 8.0), - FL2FXCONST_SGL(-0.03747203173192f / 8.0)}, - {FL2FXCONST_SGL(-0.31744434966056f / 8.0), - FL2FXCONST_SGL(-0.36834111883652f / 8.0)}, - {FL2FXCONST_SGL(-0.34110827591623f / 8.0), - FL2FXCONST_SGL(0.40211222807691f / 8.0)}, - {FL2FXCONST_SGL(0.47803883714199f / 8.0), - FL2FXCONST_SGL(-0.39423219786288f / 8.0)}, - {FL2FXCONST_SGL(0.98299195879514f / 8.0), - FL2FXCONST_SGL(0.01989791390047f / 8.0)}, - {FL2FXCONST_SGL(-0.30963073129751f / 8.0), - FL2FXCONST_SGL(-0.18076720599336f / 8.0)}, - {FL2FXCONST_SGL(0.99992588229018f / 8.0), - FL2FXCONST_SGL(-0.26281872094289f / 8.0)}, - {FL2FXCONST_SGL(-0.93149731080767f / 8.0), - FL2FXCONST_SGL(-0.98313162570490f / 8.0)}, - {FL2FXCONST_SGL(0.99923472302773f / 8.0), - FL2FXCONST_SGL(-0.80142993767554f / 8.0)}, - {FL2FXCONST_SGL(-0.26024169633417f / 8.0), - FL2FXCONST_SGL(-0.75999759855752f / 8.0)}, - {FL2FXCONST_SGL(-0.35712514743563f / 8.0), - FL2FXCONST_SGL(0.19298963768574f / 8.0)}, - {FL2FXCONST_SGL(-0.99899084509530f / 8.0), - FL2FXCONST_SGL(0.74645156992493f / 8.0)}, - {FL2FXCONST_SGL(0.86557171579452f / 8.0), - FL2FXCONST_SGL(0.55593866696299f / 8.0)}, - {FL2FXCONST_SGL(0.33408042438752f / 8.0), - FL2FXCONST_SGL(0.86185953874709f / 8.0)}, - {FL2FXCONST_SGL(0.99010736374716f / 8.0), - FL2FXCONST_SGL(0.04602397576623f / 8.0)}, - {FL2FXCONST_SGL(-0.66694269691195f / 8.0), - FL2FXCONST_SGL(-0.91643611810148f / 8.0)}, - {FL2FXCONST_SGL(0.64016792079480f / 8.0), - FL2FXCONST_SGL(0.15649530836856f / 8.0)}, - {FL2FXCONST_SGL(0.99570534804836f / 8.0), - FL2FXCONST_SGL(0.45844586038111f / 8.0)}, - {FL2FXCONST_SGL(-0.63431466947340f / 8.0), - FL2FXCONST_SGL(0.21079116459234f / 8.0)}, - {FL2FXCONST_SGL(-0.07706847005931f / 8.0), - FL2FXCONST_SGL(-0.89581437101329f / 8.0)}, - {FL2FXCONST_SGL(0.98590090577724f / 8.0), - FL2FXCONST_SGL(0.88241721133981f / 8.0)}, - {FL2FXCONST_SGL(0.80099335254678f / 8.0), - FL2FXCONST_SGL(-0.36851896710853f / 8.0)}, - {FL2FXCONST_SGL(0.78368131392666f / 8.0), - FL2FXCONST_SGL(0.45506999802597f / 8.0)}, - {FL2FXCONST_SGL(0.08707806671691f / 8.0), - FL2FXCONST_SGL(0.80938994918745f / 8.0)}, - {FL2FXCONST_SGL(-0.86811883080712f / 8.0), - FL2FXCONST_SGL(0.39347308654705f / 8.0)}, - {FL2FXCONST_SGL(-0.39466529740375f / 8.0), - FL2FXCONST_SGL(-0.66809432114456f / 8.0)}, - {FL2FXCONST_SGL(0.97875325649683f / 8.0), - FL2FXCONST_SGL(-0.72467840967746f / 8.0)}, - {FL2FXCONST_SGL(-0.95038560288864f / 8.0), - FL2FXCONST_SGL(0.89563219587625f / 8.0)}, - {FL2FXCONST_SGL(0.17005239424212f / 8.0), - FL2FXCONST_SGL(0.54683053962658f / 8.0)}, - {FL2FXCONST_SGL(-0.76910792026848f / 8.0), - FL2FXCONST_SGL(-0.96226617549298f / 8.0)}, - {FL2FXCONST_SGL(0.99743281016846f / 8.0), - FL2FXCONST_SGL(0.42697157037567f / 8.0)}, - {FL2FXCONST_SGL(0.95437383549973f / 8.0), - FL2FXCONST_SGL(0.97002324109952f / 8.0)}, - {FL2FXCONST_SGL(0.99578905365569f / 8.0), - FL2FXCONST_SGL(-0.54106826257356f / 8.0)}, - {FL2FXCONST_SGL(0.28058259829990f / 8.0), - FL2FXCONST_SGL(-0.85361420634036f / 8.0)}, - {FL2FXCONST_SGL(0.85256524470573f / 8.0), - FL2FXCONST_SGL(-0.64567607735589f / 8.0)}, - {FL2FXCONST_SGL(-0.50608540105128f / 8.0), - FL2FXCONST_SGL(-0.65846015480300f / 8.0)}, - {FL2FXCONST_SGL(-0.97210735183243f / 8.0), - FL2FXCONST_SGL(-0.23095213067791f / 8.0)}, - {FL2FXCONST_SGL(0.95424048234441f / 8.0), - FL2FXCONST_SGL(-0.99240147091219f / 8.0)}, - {FL2FXCONST_SGL(-0.96926570524023f / 8.0), - FL2FXCONST_SGL(0.73775654896574f / 8.0)}, - {FL2FXCONST_SGL(0.30872163214726f / 8.0), - FL2FXCONST_SGL(0.41514960556126f / 8.0)}, - {FL2FXCONST_SGL(-0.24523839572639f / 8.0), - FL2FXCONST_SGL(0.63206633394807f / 8.0)}, - {FL2FXCONST_SGL(-0.33813265086024f / 8.0), - FL2FXCONST_SGL(-0.38661779441897f / 8.0)}, - {FL2FXCONST_SGL(-0.05826828420146f / 8.0), - FL2FXCONST_SGL(-0.06940774188029f / 8.0)}, - {FL2FXCONST_SGL(-0.22898461455054f / 8.0), - FL2FXCONST_SGL(0.97054853316316f / 8.0)}, - {FL2FXCONST_SGL(-0.18509915019881f / 8.0), - FL2FXCONST_SGL(0.47565762892084f / 8.0)}, - {FL2FXCONST_SGL(-0.10488238045009f / 8.0), - FL2FXCONST_SGL(-0.87769947402394f / 8.0)}, - {FL2FXCONST_SGL(-0.71886586182037f / 8.0), - FL2FXCONST_SGL(0.78030982480538f / 8.0)}, - {FL2FXCONST_SGL(0.99793873738654f / 8.0), - FL2FXCONST_SGL(0.90041310491497f / 8.0)}, - {FL2FXCONST_SGL(0.57563307626120f / 8.0), - FL2FXCONST_SGL(-0.91034337352097f / 8.0)}, - {FL2FXCONST_SGL(0.28909646383717f / 8.0), - FL2FXCONST_SGL(0.96307783970534f / 8.0)}, - {FL2FXCONST_SGL(0.42188998312520f / 8.0), - FL2FXCONST_SGL(0.48148651230437f / 8.0)}, - {FL2FXCONST_SGL(0.93335049681047f / 8.0), - FL2FXCONST_SGL(-0.43537023883588f / 8.0)}, - {FL2FXCONST_SGL(-0.97087374418267f / 8.0), - FL2FXCONST_SGL(0.86636445711364f / 8.0)}, - {FL2FXCONST_SGL(0.36722871286923f / 8.0), - FL2FXCONST_SGL(0.65291654172961f / 8.0)}, - {FL2FXCONST_SGL(-0.81093025665696f / 8.0), - FL2FXCONST_SGL(0.08778370229363f / 8.0)}, - {FL2FXCONST_SGL(-0.26240603062237f / 8.0), - FL2FXCONST_SGL(-0.92774095379098f / 8.0)}, - {FL2FXCONST_SGL(0.83996497984604f / 8.0), - FL2FXCONST_SGL(0.55839849139647f / 8.0)}, - {FL2FXCONST_SGL(-0.99909615720225f / 8.0), - FL2FXCONST_SGL(-0.96024605713970f / 8.0)}, - {FL2FXCONST_SGL(0.74649464155061f / 8.0), - FL2FXCONST_SGL(0.12144893606462f / 8.0)}, - {FL2FXCONST_SGL(-0.74774595569805f / 8.0), - FL2FXCONST_SGL(-0.26898062008959f / 8.0)}, - {FL2FXCONST_SGL(0.95781667469567f / 8.0), - FL2FXCONST_SGL(-0.79047927052628f / 8.0)}, - {FL2FXCONST_SGL(0.95472308713099f / 8.0), - FL2FXCONST_SGL(-0.08588776019550f / 8.0)}, - {FL2FXCONST_SGL(0.48708332746299f / 8.0), - FL2FXCONST_SGL(0.99999041579432f / 8.0)}, - {FL2FXCONST_SGL(0.46332038247497f / 8.0), - FL2FXCONST_SGL(0.10964126185063f / 8.0)}, - {FL2FXCONST_SGL(-0.76497004940162f / 8.0), - FL2FXCONST_SGL(0.89210929242238f / 8.0)}, - {FL2FXCONST_SGL(0.57397389364339f / 8.0), - FL2FXCONST_SGL(0.35289703373760f / 8.0)}, - {FL2FXCONST_SGL(0.75374316974495f / 8.0), - FL2FXCONST_SGL(0.96705214651335f / 8.0)}, - {FL2FXCONST_SGL(-0.59174397685714f / 8.0), - FL2FXCONST_SGL(-0.89405370422752f / 8.0)}, - {FL2FXCONST_SGL(0.75087906691890f / 8.0), - FL2FXCONST_SGL(-0.29612672982396f / 8.0)}, - {FL2FXCONST_SGL(-0.98607857336230f / 8.0), - FL2FXCONST_SGL(0.25034911730023f / 8.0)}, - {FL2FXCONST_SGL(-0.40761056640505f / 8.0), - FL2FXCONST_SGL(-0.90045573444695f / 8.0)}, - {FL2FXCONST_SGL(0.66929266740477f / 8.0), - FL2FXCONST_SGL(0.98629493401748f / 8.0)}, - {FL2FXCONST_SGL(-0.97463695257310f / 8.0), - FL2FXCONST_SGL(-0.00190223301301f / 8.0)}, - {FL2FXCONST_SGL(0.90145509409859f / 8.0), - FL2FXCONST_SGL(0.99781390365446f / 8.0)}, - {FL2FXCONST_SGL(-0.87259289048043f / 8.0), - FL2FXCONST_SGL(0.99233587353666f / 8.0)}, - {FL2FXCONST_SGL(-0.91529461447692f / 8.0), - FL2FXCONST_SGL(-0.15698707534206f / 8.0)}, - {FL2FXCONST_SGL(-0.03305738840705f / 8.0), - FL2FXCONST_SGL(-0.37205262859764f / 8.0)}, - {FL2FXCONST_SGL(0.07223051368337f / 8.0), - FL2FXCONST_SGL(-0.88805001733626f / 8.0)}, - {FL2FXCONST_SGL(0.99498012188353f / 8.0), - FL2FXCONST_SGL(0.97094358113387f / 8.0)}, - {FL2FXCONST_SGL(-0.74904939500519f / 8.0), - FL2FXCONST_SGL(0.99985483641521f / 8.0)}, - {FL2FXCONST_SGL(0.04585228574211f / 8.0), - FL2FXCONST_SGL(0.99812337444082f / 8.0)}, - {FL2FXCONST_SGL(-0.89054954257993f / 8.0), - FL2FXCONST_SGL(-0.31791913188064f / 8.0)}, - {FL2FXCONST_SGL(-0.83782144651251f / 8.0), - FL2FXCONST_SGL(0.97637632547466f / 8.0)}, - {FL2FXCONST_SGL(0.33454804933804f / 8.0), - FL2FXCONST_SGL(-0.86231516800408f / 8.0)}, - {FL2FXCONST_SGL(-0.99707579362824f / 8.0), - FL2FXCONST_SGL(0.93237990079441f / 8.0)}, - {FL2FXCONST_SGL(-0.22827527843994f / 8.0), - FL2FXCONST_SGL(0.18874759397997f / 8.0)}, - {FL2FXCONST_SGL(0.67248046289143f / 8.0), - FL2FXCONST_SGL(-0.03646211390569f / 8.0)}, - {FL2FXCONST_SGL(-0.05146538187944f / 8.0), - FL2FXCONST_SGL(-0.92599700120679f / 8.0)}, - {FL2FXCONST_SGL(0.99947295749905f / 8.0), - FL2FXCONST_SGL(0.93625229707912f / 8.0)}, - {FL2FXCONST_SGL(0.66951124390363f / 8.0), - FL2FXCONST_SGL(0.98905825623893f / 8.0)}, - {FL2FXCONST_SGL(-0.99602956559179f / 8.0), - FL2FXCONST_SGL(-0.44654715757688f / 8.0)}, - {FL2FXCONST_SGL(0.82104905483590f / 8.0), - FL2FXCONST_SGL(0.99540741724928f / 8.0)}, - {FL2FXCONST_SGL(0.99186510988782f / 8.0), - FL2FXCONST_SGL(0.72023001312947f / 8.0)}, - {FL2FXCONST_SGL(-0.65284592392918f / 8.0), - FL2FXCONST_SGL(0.52186723253637f / 8.0)}, - {FL2FXCONST_SGL(0.93885443798188f / 8.0), - FL2FXCONST_SGL(-0.74895312615259f / 8.0)}, - {FL2FXCONST_SGL(0.96735248738388f / 8.0), - FL2FXCONST_SGL(0.90891816978629f / 8.0)}, - {FL2FXCONST_SGL(-0.22225968841114f / 8.0), - FL2FXCONST_SGL(0.57124029781228f / 8.0)}, - {FL2FXCONST_SGL(-0.44132783753414f / 8.0), - FL2FXCONST_SGL(-0.92688840659280f / 8.0)}, - {FL2FXCONST_SGL(-0.85694974219574f / 8.0), - FL2FXCONST_SGL(0.88844532719844f / 8.0)}, - {FL2FXCONST_SGL(0.91783042091762f / 8.0), - FL2FXCONST_SGL(-0.46356892383970f / 8.0)}, - {FL2FXCONST_SGL(0.72556974415690f / 8.0), - FL2FXCONST_SGL(-0.99899555770747f / 8.0)}, - {FL2FXCONST_SGL(-0.99711581834508f / 8.0), - FL2FXCONST_SGL(0.58211560180426f / 8.0)}, - {FL2FXCONST_SGL(0.77638976371966f / 8.0), - FL2FXCONST_SGL(0.94321834873819f / 8.0)}, - {FL2FXCONST_SGL(0.07717324253925f / 8.0), - FL2FXCONST_SGL(0.58638399856595f / 8.0)}, - {FL2FXCONST_SGL(-0.56049829194163f / 8.0), - FL2FXCONST_SGL(0.82522301569036f / 8.0)}, - {FL2FXCONST_SGL(0.98398893639988f / 8.0), - FL2FXCONST_SGL(0.39467440420569f / 8.0)}, - {FL2FXCONST_SGL(0.47546946844938f / 8.0), - FL2FXCONST_SGL(0.68613044836811f / 8.0)}, - {FL2FXCONST_SGL(0.65675089314631f / 8.0), - FL2FXCONST_SGL(0.18331637134880f / 8.0)}, - {FL2FXCONST_SGL(0.03273375457980f / 8.0), - FL2FXCONST_SGL(-0.74933109564108f / 8.0)}, - {FL2FXCONST_SGL(-0.38684144784738f / 8.0), - FL2FXCONST_SGL(0.51337349030406f / 8.0)}, - {FL2FXCONST_SGL(-0.97346267944545f / 8.0), - FL2FXCONST_SGL(-0.96549364384098f / 8.0)}, - {FL2FXCONST_SGL(-0.53282156061942f / 8.0), - FL2FXCONST_SGL(-0.91423265091354f / 8.0)}, - {FL2FXCONST_SGL(0.99817310731176f / 8.0), - FL2FXCONST_SGL(0.61133572482148f / 8.0)}, - {FL2FXCONST_SGL(-0.50254500772635f / 8.0), - FL2FXCONST_SGL(-0.88829338134294f / 8.0)}, - {FL2FXCONST_SGL(0.01995873238855f / 8.0), - FL2FXCONST_SGL(0.85223515096765f / 8.0)}, - {FL2FXCONST_SGL(0.99930381973804f / 8.0), - FL2FXCONST_SGL(0.94578896296649f / 8.0)}, - {FL2FXCONST_SGL(0.82907767600783f / 8.0), - FL2FXCONST_SGL(-0.06323442598128f / 8.0)}, - {FL2FXCONST_SGL(-0.58660709669728f / 8.0), - FL2FXCONST_SGL(0.96840773806582f / 8.0)}, - {FL2FXCONST_SGL(-0.17573736667267f / 8.0), - FL2FXCONST_SGL(-0.48166920859485f / 8.0)}, - {FL2FXCONST_SGL(0.83434292401346f / 8.0), - FL2FXCONST_SGL(-0.13023450646997f / 8.0)}, - {FL2FXCONST_SGL(0.05946491307025f / 8.0), - FL2FXCONST_SGL(0.20511047074866f / 8.0)}, - {FL2FXCONST_SGL(0.81505484574602f / 8.0), - FL2FXCONST_SGL(-0.94685947861369f / 8.0)}, - {FL2FXCONST_SGL(-0.44976380954860f / 8.0), - FL2FXCONST_SGL(0.40894572671545f / 8.0)}, - {FL2FXCONST_SGL(-0.89746474625671f / 8.0), - FL2FXCONST_SGL(0.99846578838537f / 8.0)}, - {FL2FXCONST_SGL(0.39677256130792f / 8.0), - FL2FXCONST_SGL(-0.74854668609359f / 8.0)}, - {FL2FXCONST_SGL(-0.07588948563079f / 8.0), - FL2FXCONST_SGL(0.74096214084170f / 8.0)}, - {FL2FXCONST_SGL(0.76343198951445f / 8.0), - FL2FXCONST_SGL(0.41746629422634f / 8.0)}, - {FL2FXCONST_SGL(-0.74490104699626f / 8.0), - FL2FXCONST_SGL(0.94725911744610f / 8.0)}, - {FL2FXCONST_SGL(0.64880119792759f / 8.0), - FL2FXCONST_SGL(0.41336660830571f / 8.0)}, - {FL2FXCONST_SGL(0.62319537462542f / 8.0), - FL2FXCONST_SGL(-0.93098313552599f / 8.0)}, - {FL2FXCONST_SGL(0.42215817594807f / 8.0), - FL2FXCONST_SGL(-0.07712787385208f / 8.0)}, - {FL2FXCONST_SGL(0.02704554141885f / 8.0), - FL2FXCONST_SGL(-0.05417518053666f / 8.0)}, - {FL2FXCONST_SGL(0.80001773566818f / 8.0), - FL2FXCONST_SGL(0.91542195141039f / 8.0)}, - {FL2FXCONST_SGL(-0.79351832348816f / 8.0), - FL2FXCONST_SGL(-0.36208897989136f / 8.0)}, - {FL2FXCONST_SGL(0.63872359151636f / 8.0), - FL2FXCONST_SGL(0.08128252493444f / 8.0)}, - {FL2FXCONST_SGL(0.52890520960295f / 8.0), - FL2FXCONST_SGL(0.60048872455592f / 8.0)}, - {FL2FXCONST_SGL(0.74238552914587f / 8.0), - FL2FXCONST_SGL(0.04491915291044f / 8.0)}, - {FL2FXCONST_SGL(0.99096131449250f / 8.0), - FL2FXCONST_SGL(-0.19451182854402f / 8.0)}, - {FL2FXCONST_SGL(-0.80412329643109f / 8.0), - FL2FXCONST_SGL(-0.88513818199457f / 8.0)}, - {FL2FXCONST_SGL(-0.64612616129736f / 8.0), - FL2FXCONST_SGL(0.72198674804544f / 8.0)}, - {FL2FXCONST_SGL(0.11657770663191f / 8.0), - FL2FXCONST_SGL(-0.83662833815041f / 8.0)}, - {FL2FXCONST_SGL(-0.95053182488101f / 8.0), - FL2FXCONST_SGL(-0.96939905138082f / 8.0)}, - {FL2FXCONST_SGL(-0.62228872928622f / 8.0), - FL2FXCONST_SGL(0.82767262846661f / 8.0)}, - {FL2FXCONST_SGL(0.03004475787316f / 8.0), - FL2FXCONST_SGL(-0.99738896333384f / 8.0)}, - {FL2FXCONST_SGL(-0.97987214341034f / 8.0), - FL2FXCONST_SGL(0.36526129686425f / 8.0)}, - {FL2FXCONST_SGL(-0.99986980746200f / 8.0), - FL2FXCONST_SGL(-0.36021610299715f / 8.0)}, - {FL2FXCONST_SGL(0.89110648599879f / 8.0), - FL2FXCONST_SGL(-0.97894250343044f / 8.0)}, - {FL2FXCONST_SGL(0.10407960510582f / 8.0), - FL2FXCONST_SGL(0.77357793811619f / 8.0)}, - {FL2FXCONST_SGL(0.95964737821728f / 8.0), - FL2FXCONST_SGL(-0.35435818285502f / 8.0)}, - {FL2FXCONST_SGL(0.50843233159162f / 8.0), - FL2FXCONST_SGL(0.96107691266205f / 8.0)}, - {FL2FXCONST_SGL(0.17006334670615f / 8.0), - FL2FXCONST_SGL(-0.76854025314829f / 8.0)}, - {FL2FXCONST_SGL(0.25872675063360f / 8.0), - FL2FXCONST_SGL(0.99893303933816f / 8.0)}, - {FL2FXCONST_SGL(-0.01115998681937f / 8.0), - FL2FXCONST_SGL(0.98496019742444f / 8.0)}, - {FL2FXCONST_SGL(-0.79598702973261f / 8.0), - FL2FXCONST_SGL(0.97138411318894f / 8.0)}, - {FL2FXCONST_SGL(-0.99264708948101f / 8.0), - FL2FXCONST_SGL(-0.99542822402536f / 8.0)}, - {FL2FXCONST_SGL(-0.99829663752818f / 8.0), - FL2FXCONST_SGL(0.01877138824311f / 8.0)}, - {FL2FXCONST_SGL(-0.70801016548184f / 8.0), - FL2FXCONST_SGL(0.33680685948117f / 8.0)}, - {FL2FXCONST_SGL(-0.70467057786826f / 8.0), - FL2FXCONST_SGL(0.93272777501857f / 8.0)}, - {FL2FXCONST_SGL(0.99846021905254f / 8.0), - FL2FXCONST_SGL(-0.98725746254433f / 8.0)}, - {FL2FXCONST_SGL(-0.63364968534650f / 8.0), - FL2FXCONST_SGL(-0.16473594423746f / 8.0)}, - {FL2FXCONST_SGL(-0.16258217500792f / 8.0), - FL2FXCONST_SGL(-0.95939125400802f / 8.0)}, - {FL2FXCONST_SGL(-0.43645594360633f / 8.0), - FL2FXCONST_SGL(-0.94805030113284f / 8.0)}, - {FL2FXCONST_SGL(-0.99848471702976f / 8.0), - FL2FXCONST_SGL(0.96245166923809f / 8.0)}, - {FL2FXCONST_SGL(-0.16796458968998f / 8.0), - FL2FXCONST_SGL(-0.98987511890470f / 8.0)}, - {FL2FXCONST_SGL(-0.87979225745213f / 8.0), - FL2FXCONST_SGL(-0.71725725041680f / 8.0)}, - {FL2FXCONST_SGL(0.44183099021786f / 8.0), - FL2FXCONST_SGL(-0.93568974498761f / 8.0)}, - {FL2FXCONST_SGL(0.93310180125532f / 8.0), - FL2FXCONST_SGL(-0.99913308068246f / 8.0)}, - {FL2FXCONST_SGL(-0.93941931782002f / 8.0), - FL2FXCONST_SGL(-0.56409379640356f / 8.0)}, - {FL2FXCONST_SGL(-0.88590003188677f / 8.0), - FL2FXCONST_SGL(0.47624600491382f / 8.0)}, - {FL2FXCONST_SGL(0.99971463703691f / 8.0), - FL2FXCONST_SGL(-0.83889954253462f / 8.0)}, - {FL2FXCONST_SGL(-0.75376385639978f / 8.0), - FL2FXCONST_SGL(0.00814643438625f / 8.0)}, - {FL2FXCONST_SGL(0.93887685615875f / 8.0), - FL2FXCONST_SGL(-0.11284528204636f / 8.0)}, - {FL2FXCONST_SGL(0.85126435782309f / 8.0), - FL2FXCONST_SGL(0.52349251543547f / 8.0)}, - {FL2FXCONST_SGL(0.39701421446381f / 8.0), - FL2FXCONST_SGL(0.81779634174316f / 8.0)}, - {FL2FXCONST_SGL(-0.37024464187437f / 8.0), - FL2FXCONST_SGL(-0.87071656222959f / 8.0)}, - {FL2FXCONST_SGL(-0.36024828242896f / 8.0), - FL2FXCONST_SGL(0.34655735648287f / 8.0)}, - {FL2FXCONST_SGL(-0.93388812549209f / 8.0), - FL2FXCONST_SGL(-0.84476541096429f / 8.0)}, - {FL2FXCONST_SGL(-0.65298804552119f / 8.0), - FL2FXCONST_SGL(-0.18439575450921f / 8.0)}, - {FL2FXCONST_SGL(0.11960319006843f / 8.0), - FL2FXCONST_SGL(0.99899346780168f / 8.0)}, - {FL2FXCONST_SGL(0.94292565553160f / 8.0), - FL2FXCONST_SGL(0.83163906518293f / 8.0)}, - {FL2FXCONST_SGL(0.75081145286948f / 8.0), - FL2FXCONST_SGL(-0.35533223142265f / 8.0)}, - {FL2FXCONST_SGL(0.56721979748394f / 8.0), - FL2FXCONST_SGL(-0.24076836414499f / 8.0)}, - {FL2FXCONST_SGL(0.46857766746029f / 8.0), - FL2FXCONST_SGL(-0.30140233457198f / 8.0)}, - {FL2FXCONST_SGL(0.97312313923635f / 8.0), - FL2FXCONST_SGL(-0.99548191630031f / 8.0)}, - {FL2FXCONST_SGL(-0.38299976567017f / 8.0), - FL2FXCONST_SGL(0.98516909715427f / 8.0)}, - {FL2FXCONST_SGL(0.41025800019463f / 8.0), - FL2FXCONST_SGL(0.02116736935734f / 8.0)}, - {FL2FXCONST_SGL(0.09638062008048f / 8.0), - FL2FXCONST_SGL(0.04411984381457f / 8.0)}, - {FL2FXCONST_SGL(-0.85283249275397f / 8.0), - FL2FXCONST_SGL(0.91475563922421f / 8.0)}, - {FL2FXCONST_SGL(0.88866808958124f / 8.0), - FL2FXCONST_SGL(-0.99735267083226f / 8.0)}, - {FL2FXCONST_SGL(-0.48202429536989f / 8.0), - FL2FXCONST_SGL(-0.96805608884164f / 8.0)}, - {FL2FXCONST_SGL(0.27572582416567f / 8.0), - FL2FXCONST_SGL(0.58634753335832f / 8.0)}, - {FL2FXCONST_SGL(-0.65889129659168f / 8.0), - FL2FXCONST_SGL(0.58835634138583f / 8.0)}, - {FL2FXCONST_SGL(0.98838086953732f / 8.0), - FL2FXCONST_SGL(0.99994349600236f / 8.0)}, - {FL2FXCONST_SGL(-0.20651349620689f / 8.0), - FL2FXCONST_SGL(0.54593044066355f / 8.0)}, - {FL2FXCONST_SGL(-0.62126416356920f / 8.0), - FL2FXCONST_SGL(-0.59893681700392f / 8.0)}, - {FL2FXCONST_SGL(0.20320105410437f / 8.0), - FL2FXCONST_SGL(-0.86879180355289f / 8.0)}, - {FL2FXCONST_SGL(-0.97790548600584f / 8.0), - FL2FXCONST_SGL(0.96290806999242f / 8.0)}, - {FL2FXCONST_SGL(0.11112534735126f / 8.0), - FL2FXCONST_SGL(0.21484763313301f / 8.0)}, - {FL2FXCONST_SGL(-0.41368337314182f / 8.0), - FL2FXCONST_SGL(0.28216837680365f / 8.0)}, - {FL2FXCONST_SGL(0.24133038992960f / 8.0), - FL2FXCONST_SGL(0.51294362630238f / 8.0)}, - {FL2FXCONST_SGL(-0.66393410674885f / 8.0), - FL2FXCONST_SGL(-0.08249679629081f / 8.0)}, - {FL2FXCONST_SGL(-0.53697829178752f / 8.0), - FL2FXCONST_SGL(-0.97649903936228f / 8.0)}, - {FL2FXCONST_SGL(-0.97224737889348f / 8.0), - FL2FXCONST_SGL(0.22081333579837f / 8.0)}, - {FL2FXCONST_SGL(0.87392477144549f / 8.0), - FL2FXCONST_SGL(-0.12796173740361f / 8.0)}, - {FL2FXCONST_SGL(0.19050361015753f / 8.0), - FL2FXCONST_SGL(0.01602615387195f / 8.0)}, - {FL2FXCONST_SGL(-0.46353441212724f / 8.0), - FL2FXCONST_SGL(-0.95249041539006f / 8.0)}, - {FL2FXCONST_SGL(-0.07064096339021f / 8.0), - FL2FXCONST_SGL(-0.94479803205886f / 8.0)}, - {FL2FXCONST_SGL(-0.92444085484466f / 8.0), - FL2FXCONST_SGL(-0.10457590187436f / 8.0)}, - {FL2FXCONST_SGL(-0.83822593578728f / 8.0), - FL2FXCONST_SGL(-0.01695043208885f / 8.0)}, - {FL2FXCONST_SGL(0.75214681811150f / 8.0), - FL2FXCONST_SGL(-0.99955681042665f / 8.0)}, - {FL2FXCONST_SGL(-0.42102998829339f / 8.0), - FL2FXCONST_SGL(0.99720941999394f / 8.0)}, - {FL2FXCONST_SGL(-0.72094786237696f / 8.0), - FL2FXCONST_SGL(-0.35008961934255f / 8.0)}, - {FL2FXCONST_SGL(0.78843311019251f / 8.0), - FL2FXCONST_SGL(0.52851398958271f / 8.0)}, - {FL2FXCONST_SGL(0.97394027897442f / 8.0), - FL2FXCONST_SGL(-0.26695944086561f / 8.0)}, - {FL2FXCONST_SGL(0.99206463477946f / 8.0), - FL2FXCONST_SGL(-0.57010120849429f / 8.0)}, - {FL2FXCONST_SGL(0.76789609461795f / 8.0), - FL2FXCONST_SGL(-0.76519356730966f / 8.0)}, - {FL2FXCONST_SGL(-0.82002421836409f / 8.0), - FL2FXCONST_SGL(-0.73530179553767f / 8.0)}, - {FL2FXCONST_SGL(0.81924990025724f / 8.0), - FL2FXCONST_SGL(0.99698425250579f / 8.0)}, - {FL2FXCONST_SGL(-0.26719850873357f / 8.0), - FL2FXCONST_SGL(0.68903369776193f / 8.0)}, - {FL2FXCONST_SGL(-0.43311260380975f / 8.0), - FL2FXCONST_SGL(0.85321815947490f / 8.0)}, - {FL2FXCONST_SGL(0.99194979673836f / 8.0), - FL2FXCONST_SGL(0.91876249766422f / 8.0)}, - {FL2FXCONST_SGL(-0.80692001248487f / 8.0), - FL2FXCONST_SGL(-0.32627540663214f / 8.0)}, - {FL2FXCONST_SGL(0.43080003649976f / 8.0), - FL2FXCONST_SGL(-0.21919095636638f / 8.0)}, - {FL2FXCONST_SGL(0.67709491937357f / 8.0), - FL2FXCONST_SGL(-0.95478075822906f / 8.0)}, - {FL2FXCONST_SGL(0.56151770568316f / 8.0), - FL2FXCONST_SGL(-0.70693811747778f / 8.0)}, - {FL2FXCONST_SGL(0.10831862810749f / 8.0), - FL2FXCONST_SGL(-0.08628837174592f / 8.0)}, - {FL2FXCONST_SGL(0.91229417540436f / 8.0), - FL2FXCONST_SGL(-0.65987351408410f / 8.0)}, - {FL2FXCONST_SGL(-0.48972893932274f / 8.0), - FL2FXCONST_SGL(0.56289246362686f / 8.0)}, - {FL2FXCONST_SGL(-0.89033658689697f / 8.0), - FL2FXCONST_SGL(-0.71656563987082f / 8.0)}, - {FL2FXCONST_SGL(0.65269447475094f / 8.0), - FL2FXCONST_SGL(0.65916004833932f / 8.0)}, - {FL2FXCONST_SGL(0.67439478141121f / 8.0), - FL2FXCONST_SGL(-0.81684380846796f / 8.0)}, - {FL2FXCONST_SGL(-0.47770832416973f / 8.0), - FL2FXCONST_SGL(-0.16789556203025f / 8.0)}, - {FL2FXCONST_SGL(-0.99715979260878f / 8.0), - FL2FXCONST_SGL(-0.93565784007648f / 8.0)}, - {FL2FXCONST_SGL(-0.90889593602546f / 8.0), - FL2FXCONST_SGL(0.62034397054380f / 8.0)}, - {FL2FXCONST_SGL(-0.06618622548177f / 8.0), - FL2FXCONST_SGL(-0.23812217221359f / 8.0)}, - {FL2FXCONST_SGL(0.99430266919728f / 8.0), - FL2FXCONST_SGL(0.18812555317553f / 8.0)}, - {FL2FXCONST_SGL(0.97686402381843f / 8.0), - FL2FXCONST_SGL(-0.28664534366620f / 8.0)}, - {FL2FXCONST_SGL(0.94813650221268f / 8.0), - FL2FXCONST_SGL(-0.97506640027128f / 8.0)}, - {FL2FXCONST_SGL(-0.95434497492853f / 8.0), - FL2FXCONST_SGL(-0.79607978501983f / 8.0)}, - {FL2FXCONST_SGL(-0.49104783137150f / 8.0), - FL2FXCONST_SGL(0.32895214359663f / 8.0)}, - {FL2FXCONST_SGL(0.99881175120751f / 8.0), - FL2FXCONST_SGL(0.88993983831354f / 8.0)}, - {FL2FXCONST_SGL(0.50449166760303f / 8.0), - FL2FXCONST_SGL(-0.85995072408434f / 8.0)}, - {FL2FXCONST_SGL(0.47162891065108f / 8.0), - FL2FXCONST_SGL(-0.18680204049569f / 8.0)}, - {FL2FXCONST_SGL(-0.62081581361840f / 8.0), - FL2FXCONST_SGL(0.75000676218956f / 8.0)}, - {FL2FXCONST_SGL(-0.43867015250812f / 8.0), - FL2FXCONST_SGL(0.99998069244322f / 8.0)}, - {FL2FXCONST_SGL(0.98630563232075f / 8.0), - FL2FXCONST_SGL(-0.53578899600662f / 8.0)}, - {FL2FXCONST_SGL(-0.61510362277374f / 8.0), - FL2FXCONST_SGL(-0.89515019899997f / 8.0)}, - {FL2FXCONST_SGL(-0.03841517601843f / 8.0), - FL2FXCONST_SGL(-0.69888815681179f / 8.0)}, - {FL2FXCONST_SGL(-0.30102157304644f / 8.0), - FL2FXCONST_SGL(-0.07667808922205f / 8.0)}, - {FL2FXCONST_SGL(0.41881284182683f / 8.0), - FL2FXCONST_SGL(0.02188098922282f / 8.0)}, - {FL2FXCONST_SGL(-0.86135454941237f / 8.0), - FL2FXCONST_SGL(0.98947480909359f / 8.0)}, - {FL2FXCONST_SGL(0.67226861393788f / 8.0), - FL2FXCONST_SGL(-0.13494389011014f / 8.0)}, - {FL2FXCONST_SGL(-0.70737398842068f / 8.0), - FL2FXCONST_SGL(-0.76547349325992f / 8.0)}, - {FL2FXCONST_SGL(0.94044946687963f / 8.0), - FL2FXCONST_SGL(0.09026201157416f / 8.0)}, - {FL2FXCONST_SGL(-0.82386352534327f / 8.0), - FL2FXCONST_SGL(0.08924768823676f / 8.0)}, - {FL2FXCONST_SGL(-0.32070666698656f / 8.0), - FL2FXCONST_SGL(0.50143421908753f / 8.0)}, - {FL2FXCONST_SGL(0.57593163224487f / 8.0), - FL2FXCONST_SGL(-0.98966422921509f / 8.0)}, - {FL2FXCONST_SGL(-0.36326018419965f / 8.0), - FL2FXCONST_SGL(0.07440243123228f / 8.0)}, - {FL2FXCONST_SGL(0.99979044674350f / 8.0), - FL2FXCONST_SGL(-0.14130287347405f / 8.0)}, - {FL2FXCONST_SGL(-0.92366023326932f / 8.0), - FL2FXCONST_SGL(-0.97979298068180f / 8.0)}, - {FL2FXCONST_SGL(-0.44607178518598f / 8.0), - FL2FXCONST_SGL(-0.54233252016394f / 8.0)}, - {FL2FXCONST_SGL(0.44226800932956f / 8.0), - FL2FXCONST_SGL(0.71326756742752f / 8.0)}, - {FL2FXCONST_SGL(0.03671907158312f / 8.0), - FL2FXCONST_SGL(0.63606389366675f / 8.0)}, - {FL2FXCONST_SGL(0.52175424682195f / 8.0), - FL2FXCONST_SGL(-0.85396826735705f / 8.0)}, - {FL2FXCONST_SGL(-0.94701139690956f / 8.0), - FL2FXCONST_SGL(-0.01826348194255f / 8.0)}, - {FL2FXCONST_SGL(-0.98759606946049f / 8.0), - FL2FXCONST_SGL(0.82288714303073f / 8.0)}, - {FL2FXCONST_SGL(0.87434794743625f / 8.0), - FL2FXCONST_SGL(0.89399495655433f / 8.0)}, - {FL2FXCONST_SGL(-0.93412041758744f / 8.0), - FL2FXCONST_SGL(0.41374052024363f / 8.0)}, - {FL2FXCONST_SGL(0.96063943315511f / 8.0), - FL2FXCONST_SGL(0.93116709541280f / 8.0)}, - {FL2FXCONST_SGL(0.97534253457837f / 8.0), - FL2FXCONST_SGL(0.86150930812689f / 8.0)}, - {FL2FXCONST_SGL(0.99642466504163f / 8.0), - FL2FXCONST_SGL(0.70190043427512f / 8.0)}, - {FL2FXCONST_SGL(-0.94705089665984f / 8.0), - FL2FXCONST_SGL(-0.29580042814306f / 8.0)}, - {FL2FXCONST_SGL(0.91599807087376f / 8.0), - FL2FXCONST_SGL(-0.98147830385781f / 8.0)}}; -//@} - -/* -static const FIXP_SGL harmonicPhase [2][4] = { - { 1.0, 0.0, -1.0, 0.0}, - { 0.0, 1.0, 0.0, -1.0} -}; -*/ - -/* tables for SBR and AAC LD */ -/* table for 8 time slot index */ -const int FDK_sbrDecoder_envelopeTable_8[8][5] = { - /* transientIndex nEnv, tranIdx, shortEnv, border1, border2, ... */ - /* borders from left to right side; -1 = not in use */ - /*[|T-|------]*/ {2, 0, 0, 1, -1}, - /*[|-T-|-----]*/ {2, 0, 0, 2, -1}, - /*[--|T-|----]*/ {3, 1, 1, 2, 4}, - /*[---|T-|---]*/ {3, 1, 1, 3, 5}, - /*[----|T-|--]*/ {3, 1, 1, 4, 6}, - /*[-----|T--|]*/ {2, 1, 1, 5, -1}, - /*[------|T-|]*/ {2, 1, 1, 6, -1}, - /*[-------|T|]*/ {2, 1, 1, 7, -1}, -}; - -/* table for 15 time slot index */ -const int FDK_sbrDecoder_envelopeTable_15[15][6] = { - /* transientIndex nEnv, tranIdx, shortEnv, border1, border2, ... */ - /* length from left to right side; -1 = not in use */ - /*[|T---|------------]*/ {2, 0, 0, 4, -1, -1}, - /*[|-T---|-----------]*/ {2, 0, 0, 5, -1, -1}, - /*[|--|T---|---------]*/ {3, 1, 1, 2, 6, -1}, - /*[|---|T---|--------]*/ {3, 1, 1, 3, 7, -1}, - /*[|----|T---|-------]*/ {3, 1, 1, 4, 8, -1}, - /*[|-----|T---|------]*/ {3, 1, 1, 5, 9, -1}, - /*[|------|T---|-----]*/ {3, 1, 1, 6, 10, -1}, - /*[|-------|T---|----]*/ {3, 1, 1, 7, 11, -1}, - /*[|--------|T---|---]*/ {3, 1, 1, 8, 12, -1}, - /*[|---------|T---|--]*/ {3, 1, 1, 9, 13, -1}, - /*[|----------|T----|]*/ {2, 1, 1, 10, -1, -1}, - /*[|-----------|T---|]*/ {2, 1, 1, 11, -1, -1}, - /*[|------------|T--|]*/ {2, 1, 1, 12, -1, -1}, - /*[|-------------|T-|]*/ {2, 1, 1, 13, -1, -1}, - /*[|--------------|T|]*/ {2, 1, 1, 14, -1, -1}, -}; - -/* table for 16 time slot index */ -const int FDK_sbrDecoder_envelopeTable_16[16][6] = { - /* transientIndex nEnv, tranIdx, shortEnv, border1, border2, ... */ - /* length from left to right side; -1 = not in use */ - /*[|T---|------------|]*/ {2, 0, 0, 4, -1, -1}, - /*[|-T---|-----------|]*/ {2, 0, 0, 5, -1, -1}, - /*[|--|T---|----------]*/ {3, 1, 1, 2, 6, -1}, - /*[|---|T---|---------]*/ {3, 1, 1, 3, 7, -1}, - /*[|----|T---|--------]*/ {3, 1, 1, 4, 8, -1}, - /*[|-----|T---|-------]*/ {3, 1, 1, 5, 9, -1}, - /*[|------|T---|------]*/ {3, 1, 1, 6, 10, -1}, - /*[|-------|T---|-----]*/ {3, 1, 1, 7, 11, -1}, - /*[|--------|T---|----]*/ {3, 1, 1, 8, 12, -1}, - /*[|---------|T---|---]*/ {3, 1, 1, 9, 13, -1}, - /*[|----------|T---|--]*/ {3, 1, 1, 10, 14, -1}, - /*[|-----------|T----|]*/ {2, 1, 1, 11, -1, -1}, - /*[|------------|T---|]*/ {2, 1, 1, 12, -1, -1}, - /*[|-------------|T--|]*/ {2, 1, 1, 13, -1, -1}, - /*[|--------------|T-|]*/ {2, 1, 1, 14, -1, -1}, - /*[|---------------|T|]*/ {2, 1, 1, 15, -1, -1}, -}; - -/*! - \name FrameInfoDefaults - - Predefined envelope positions for the FIX-FIX case (static framing) -*/ -//@{ -const FRAME_INFO FDK_sbrDecoder_sbr_frame_info1_15 = { - 0, 1, {0, 15, 0, 0, 0, 0}, {1, 0, 0, 0, 0}, -1, 1, {0, 15, 0}, {0, 0, 0}, - 0, 0}; -const FRAME_INFO FDK_sbrDecoder_sbr_frame_info2_15 = { - 0, 2, {0, 8, 15, 0, 0, 0}, {1, 1, 0, 0, 0}, -1, 2, {0, 8, 15}, {0, 0, 0}, - 0, 0}; -const FRAME_INFO FDK_sbrDecoder_sbr_frame_info4_15 = { - 0, 4, {0, 4, 8, 12, 15, 0}, {1, 1, 1, 1, 0}, -1, 2, {0, 8, 15}, {0, 0, 0}, - 0, 0}; -#if (MAX_ENVELOPES >= 8) -const FRAME_INFO FDK_sbrDecoder_sbr_frame_info8_15 = { - 0, - 8, - {0, 2, 4, 6, 8, 10, 12, 14, 15}, - {1, 1, 1, 1, 1, 1, 1, 1}, - -1, - 2, - {0, 8, 15}, - {0, 0, 0}, - 0, - 0}; -#endif - -const FRAME_INFO FDK_sbrDecoder_sbr_frame_info1_16 = { - 0, 1, {0, 16, 0, 0, 0, 0}, {1, 0, 0, 0, 0}, -1, 1, {0, 16, 0}, {0, 0, 0}, - 0, 0}; -const FRAME_INFO FDK_sbrDecoder_sbr_frame_info2_16 = { - 0, 2, {0, 8, 16, 0, 0, 0}, {1, 1, 0, 0, 0}, -1, 2, {0, 8, 16}, {0, 0, 0}, - 0, 0}; -const FRAME_INFO FDK_sbrDecoder_sbr_frame_info4_16 = { - 0, 4, {0, 4, 8, 12, 16, 0}, {1, 1, 1, 1, 0}, -1, 2, {0, 8, 16}, {0, 0, 0}, - 0, 0}; - -#if (MAX_ENVELOPES >= 8) -const FRAME_INFO FDK_sbrDecoder_sbr_frame_info8_16 = { - 0, - 8, - {0, 2, 4, 6, 8, 10, 12, 14, 16}, - {1, 1, 1, 1, 1, 1, 1, 1}, - -1, - 2, - {0, 8, 16}, - {0, 0, 0}, - 0, - 0}; -#endif - -//@} - -/*! - \name SBR_HuffmanTables - - SBR Huffman Table Overview: \n - \n - o envelope level, 1.5 dB: \n - 1) sbr_huffBook_EnvLevel10T[120][2] \n - 2) sbr_huffBook_EnvLevel10F[120][2] \n - \n - o envelope balance, 1.5 dB: \n - 3) sbr_huffBook_EnvBalance10T[48][2] \n - 4) sbr_huffBook_EnvBalance10F[48][2] \n - \n - o envelope level, 3.0 dB: \n - 5) sbr_huffBook_EnvLevel11T[62][2] \n - 6) sbr_huffBook_EnvLevel11F[62][2] \n - \n - o envelope balance, 3.0 dB: \n - 7) sbr_huffBook_EnvBalance11T[24][2] \n - 8) sbr_huffBook_EnvBalance11F[24][2] \n - \n - o noise level, 3.0 dB: \n - 9) sbr_huffBook_NoiseLevel11T[62][2] \n - -) (sbr_huffBook_EnvLevel11F[62][2] is used for freq dir)\n - \n - o noise balance, 3.0 dB: \n - 10) sbr_huffBook_NoiseBalance11T[24][2]\n - -) (sbr_huffBook_EnvBalance11F[24][2] is used for freq dir)\n - \n - (1.5 dB is never used for noise) - -*/ -//@{ -const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvLevel10T[120][2] = { - {1, 2}, {-64, -65}, {3, 4}, {-63, -66}, {5, 6}, - {-62, -67}, {7, 8}, {-61, -68}, {9, 10}, {-60, -69}, - {11, 12}, {-59, -70}, {13, 14}, {-58, -71}, {15, 16}, - {-57, -72}, {17, 18}, {-73, -56}, {19, 21}, {-74, 20}, - {-55, -75}, {22, 26}, {23, 24}, {-54, -76}, {-77, 25}, - {-53, -78}, {27, 34}, {28, 29}, {-52, -79}, {30, 31}, - {-80, -51}, {32, 33}, {-83, -82}, {-81, -50}, {35, 57}, - {36, 40}, {37, 38}, {-88, -84}, {-48, 39}, {-90, -85}, - {41, 46}, {42, 43}, {-49, -87}, {44, 45}, {-89, -86}, - {-124, -123}, {47, 50}, {48, 49}, {-122, -121}, {-120, -119}, - {51, 54}, {52, 53}, {-118, -117}, {-116, -115}, {55, 56}, - {-114, -113}, {-112, -111}, {58, 89}, {59, 74}, {60, 67}, - {61, 64}, {62, 63}, {-110, -109}, {-108, -107}, {65, 66}, - {-106, -105}, {-104, -103}, {68, 71}, {69, 70}, {-102, -101}, - {-100, -99}, {72, 73}, {-98, -97}, {-96, -95}, {75, 82}, - {76, 79}, {77, 78}, {-94, -93}, {-92, -91}, {80, 81}, - {-47, -46}, {-45, -44}, {83, 86}, {84, 85}, {-43, -42}, - {-41, -40}, {87, 88}, {-39, -38}, {-37, -36}, {90, 105}, - {91, 98}, {92, 95}, {93, 94}, {-35, -34}, {-33, -32}, - {96, 97}, {-31, -30}, {-29, -28}, {99, 102}, {100, 101}, - {-27, -26}, {-25, -24}, {103, 104}, {-23, -22}, {-21, -20}, - {106, 113}, {107, 110}, {108, 109}, {-19, -18}, {-17, -16}, - {111, 112}, {-15, -14}, {-13, -12}, {114, 117}, {115, 116}, - {-11, -10}, {-9, -8}, {118, 119}, {-7, -6}, {-5, -4}}; - -const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvLevel10F[120][2] = { - {1, 2}, {-64, -65}, {3, 4}, {-63, -66}, {5, 6}, - {-67, -62}, {7, 8}, {-68, -61}, {9, 10}, {-69, -60}, - {11, 13}, {-70, 12}, {-59, -71}, {14, 16}, {-58, 15}, - {-72, -57}, {17, 19}, {-73, 18}, {-56, -74}, {20, 23}, - {21, 22}, {-55, -75}, {-54, -53}, {24, 27}, {25, 26}, - {-76, -52}, {-77, -51}, {28, 31}, {29, 30}, {-50, -78}, - {-79, -49}, {32, 36}, {33, 34}, {-48, -47}, {-80, 35}, - {-81, -82}, {37, 47}, {38, 41}, {39, 40}, {-83, -46}, - {-45, -84}, {42, 44}, {-85, 43}, {-44, -43}, {45, 46}, - {-88, -87}, {-86, -90}, {48, 66}, {49, 56}, {50, 53}, - {51, 52}, {-92, -42}, {-41, -39}, {54, 55}, {-105, -89}, - {-38, -37}, {57, 60}, {58, 59}, {-94, -91}, {-40, -36}, - {61, 63}, {-20, 62}, {-115, -110}, {64, 65}, {-108, -107}, - {-101, -97}, {67, 89}, {68, 75}, {69, 72}, {70, 71}, - {-95, -93}, {-34, -27}, {73, 74}, {-22, -17}, {-16, -124}, - {76, 82}, {77, 79}, {-123, 78}, {-122, -121}, {80, 81}, - {-120, -119}, {-118, -117}, {83, 86}, {84, 85}, {-116, -114}, - {-113, -112}, {87, 88}, {-111, -109}, {-106, -104}, {90, 105}, - {91, 98}, {92, 95}, {93, 94}, {-103, -102}, {-100, -99}, - {96, 97}, {-98, -96}, {-35, -33}, {99, 102}, {100, 101}, - {-32, -31}, {-30, -29}, {103, 104}, {-28, -26}, {-25, -24}, - {106, 113}, {107, 110}, {108, 109}, {-23, -21}, {-19, -18}, - {111, 112}, {-15, -14}, {-13, -12}, {114, 117}, {115, 116}, - {-11, -10}, {-9, -8}, {118, 119}, {-7, -6}, {-5, -4}}; - -const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvBalance10T[48][2] = { - {-64, 1}, {-63, 2}, {-65, 3}, {-62, 4}, {-66, 5}, {-61, 6}, - {-67, 7}, {-60, 8}, {-68, 9}, {10, 11}, {-69, -59}, {12, 13}, - {-70, -58}, {14, 28}, {15, 21}, {16, 18}, {-57, 17}, {-71, -56}, - {19, 20}, {-88, -87}, {-86, -85}, {22, 25}, {23, 24}, {-84, -83}, - {-82, -81}, {26, 27}, {-80, -79}, {-78, -77}, {29, 36}, {30, 33}, - {31, 32}, {-76, -75}, {-74, -73}, {34, 35}, {-72, -55}, {-54, -53}, - {37, 41}, {38, 39}, {-52, -51}, {-50, 40}, {-49, -48}, {42, 45}, - {43, 44}, {-47, -46}, {-45, -44}, {46, 47}, {-43, -42}, {-41, -40}}; - -const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvBalance10F[48][2] = { - {-64, 1}, {-65, 2}, {-63, 3}, {-66, 4}, {-62, 5}, {-61, 6}, - {-67, 7}, {-68, 8}, {-60, 9}, {10, 11}, {-69, -59}, {-70, 12}, - {-58, 13}, {14, 17}, {-71, 15}, {-57, 16}, {-56, -73}, {18, 32}, - {19, 25}, {20, 22}, {-72, 21}, {-88, -87}, {23, 24}, {-86, -85}, - {-84, -83}, {26, 29}, {27, 28}, {-82, -81}, {-80, -79}, {30, 31}, - {-78, -77}, {-76, -75}, {33, 40}, {34, 37}, {35, 36}, {-74, -55}, - {-54, -53}, {38, 39}, {-52, -51}, {-50, -49}, {41, 44}, {42, 43}, - {-48, -47}, {-46, -45}, {45, 46}, {-44, -43}, {-42, 47}, {-41, -40}}; - -const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvLevel11T[62][2] = { - {-64, 1}, {-65, 2}, {-63, 3}, {-66, 4}, {-62, 5}, {-67, 6}, - {-61, 7}, {-68, 8}, {-60, 9}, {10, 11}, {-69, -59}, {12, 14}, - {-70, 13}, {-71, -58}, {15, 18}, {16, 17}, {-72, -57}, {-73, -74}, - {19, 22}, {-56, 20}, {-55, 21}, {-54, -77}, {23, 31}, {24, 25}, - {-75, -76}, {26, 27}, {-78, -53}, {28, 29}, {-52, -95}, {-94, 30}, - {-93, -92}, {32, 47}, {33, 40}, {34, 37}, {35, 36}, {-91, -90}, - {-89, -88}, {38, 39}, {-87, -86}, {-85, -84}, {41, 44}, {42, 43}, - {-83, -82}, {-81, -80}, {45, 46}, {-79, -51}, {-50, -49}, {48, 55}, - {49, 52}, {50, 51}, {-48, -47}, {-46, -45}, {53, 54}, {-44, -43}, - {-42, -41}, {56, 59}, {57, 58}, {-40, -39}, {-38, -37}, {60, 61}, - {-36, -35}, {-34, -33}}; - -const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvLevel11F[62][2] = { - {-64, 1}, {-65, 2}, {-63, 3}, {-66, 4}, {-62, 5}, {-67, 6}, - {7, 8}, {-61, -68}, {9, 10}, {-60, -69}, {11, 12}, {-59, -70}, - {13, 14}, {-58, -71}, {15, 16}, {-57, -72}, {17, 19}, {-56, 18}, - {-55, -73}, {20, 24}, {21, 22}, {-74, -54}, {-53, 23}, {-75, -76}, - {25, 30}, {26, 27}, {-52, -51}, {28, 29}, {-77, -79}, {-50, -49}, - {31, 39}, {32, 35}, {33, 34}, {-78, -46}, {-82, -88}, {36, 37}, - {-83, -48}, {-47, 38}, {-86, -85}, {40, 47}, {41, 44}, {42, 43}, - {-80, -44}, {-43, -42}, {45, 46}, {-39, -87}, {-84, -40}, {48, 55}, - {49, 52}, {50, 51}, {-95, -94}, {-93, -92}, {53, 54}, {-91, -90}, - {-89, -81}, {56, 59}, {57, 58}, {-45, -41}, {-38, -37}, {60, 61}, - {-36, -35}, {-34, -33}}; - -const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvBalance11T[24][2] = { - {-64, 1}, {-63, 2}, {-65, 3}, {-66, 4}, {-62, 5}, {-61, 6}, - {-67, 7}, {-68, 8}, {-60, 9}, {10, 16}, {11, 13}, {-69, 12}, - {-76, -75}, {14, 15}, {-74, -73}, {-72, -71}, {17, 20}, {18, 19}, - {-70, -59}, {-58, -57}, {21, 22}, {-56, -55}, {-54, 23}, {-53, -52}}; - -const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvBalance11F[24][2] = { - {-64, 1}, {-65, 2}, {-63, 3}, {-66, 4}, {-62, 5}, {-61, 6}, - {-67, 7}, {-68, 8}, {-60, 9}, {10, 13}, {-69, 11}, {-59, 12}, - {-58, -76}, {14, 17}, {15, 16}, {-75, -74}, {-73, -72}, {18, 21}, - {19, 20}, {-71, -70}, {-57, -56}, {22, 23}, {-55, -54}, {-53, -52}}; - -const SCHAR FDK_sbrDecoder_sbr_huffBook_NoiseLevel11T[62][2] = { - {-64, 1}, {-63, 2}, {-65, 3}, {-66, 4}, {-62, 5}, {-67, 6}, - {7, 8}, {-61, -68}, {9, 30}, {10, 15}, {-60, 11}, {-69, 12}, - {13, 14}, {-59, -53}, {-95, -94}, {16, 23}, {17, 20}, {18, 19}, - {-93, -92}, {-91, -90}, {21, 22}, {-89, -88}, {-87, -86}, {24, 27}, - {25, 26}, {-85, -84}, {-83, -82}, {28, 29}, {-81, -80}, {-79, -78}, - {31, 46}, {32, 39}, {33, 36}, {34, 35}, {-77, -76}, {-75, -74}, - {37, 38}, {-73, -72}, {-71, -70}, {40, 43}, {41, 42}, {-58, -57}, - {-56, -55}, {44, 45}, {-54, -52}, {-51, -50}, {47, 54}, {48, 51}, - {49, 50}, {-49, -48}, {-47, -46}, {52, 53}, {-45, -44}, {-43, -42}, - {55, 58}, {56, 57}, {-41, -40}, {-39, -38}, {59, 60}, {-37, -36}, - {-35, 61}, {-34, -33}}; - -const SCHAR FDK_sbrDecoder_sbr_huffBook_NoiseBalance11T[24][2] = { - {-64, 1}, {-65, 2}, {-63, 3}, {4, 9}, {-66, 5}, {-62, 6}, - {7, 8}, {-76, -75}, {-74, -73}, {10, 17}, {11, 14}, {12, 13}, - {-72, -71}, {-70, -69}, {15, 16}, {-68, -67}, {-61, -60}, {18, 21}, - {19, 20}, {-59, -58}, {-57, -56}, {22, 23}, {-55, -54}, {-53, -52}}; -//@} - -/*! - \name parametric stereo - \brief constants used by the parametric stereo part of the decoder - -*/ - -/* constants used in psbitdec.cpp */ - -/* FIX_BORDER can have 0, 1, 2, 4 envelopes */ -const UCHAR FDK_sbrDecoder_aFixNoEnvDecode[4] = {0, 1, 2, 4}; - -/* IID & ICC Huffman codebooks */ -const SCHAR aBookPsIidTimeDecode[28][2] = { - {-64, 1}, {-65, 2}, {-63, 3}, {-66, 4}, {-62, 5}, {-67, 6}, - {-61, 7}, {-68, 8}, {-60, 9}, {-69, 10}, {-59, 11}, {-70, 12}, - {-58, 13}, {-57, 14}, {-71, 15}, {16, 17}, {-56, -72}, {18, 21}, - {19, 20}, {-55, -78}, {-77, -76}, {22, 25}, {23, 24}, {-75, -74}, - {-73, -54}, {26, 27}, {-53, -52}, {-51, -50}}; - -const SCHAR aBookPsIidFreqDecode[28][2] = { - {-64, 1}, {2, 3}, {-63, -65}, {4, 5}, {-62, -66}, {6, 7}, - {-61, -67}, {8, 9}, {-68, -60}, {-59, 10}, {-69, 11}, {-58, 12}, - {-70, 13}, {-71, 14}, {-57, 15}, {16, 17}, {-56, -72}, {18, 19}, - {-55, -54}, {20, 21}, {-73, -53}, {22, 24}, {-74, 23}, {-75, -78}, - {25, 26}, {-77, -76}, {-52, 27}, {-51, -50}}; - -const SCHAR aBookPsIccTimeDecode[14][2] = { - {-64, 1}, {-63, 2}, {-65, 3}, {-62, 4}, {-66, 5}, {-61, 6}, {-67, 7}, - {-60, 8}, {-68, 9}, {-59, 10}, {-69, 11}, {-58, 12}, {-70, 13}, {-71, -57}}; - -const SCHAR aBookPsIccFreqDecode[14][2] = { - {-64, 1}, {-63, 2}, {-65, 3}, {-62, 4}, {-66, 5}, {-61, 6}, {-67, 7}, - {-60, 8}, {-59, 9}, {-68, 10}, {-58, 11}, {-69, 12}, {-57, 13}, {-70, -71}}; - -/* IID-fine Huffman codebooks */ - -const SCHAR aBookPsIidFineTimeDecode[60][2] = { - {1, -64}, {-63, 2}, {3, -65}, {4, 59}, {5, 7}, {6, -67}, - {-68, -60}, {-61, 8}, {9, 11}, {-59, 10}, {-70, -58}, {12, 41}, - {13, 20}, {14, -71}, {-55, 15}, {-53, 16}, {17, -77}, {18, 19}, - {-85, -84}, {-46, -45}, {-57, 21}, {22, 40}, {23, 29}, {-51, 24}, - {25, 26}, {-83, -82}, {27, 28}, {-90, -38}, {-92, -91}, {30, 37}, - {31, 34}, {32, 33}, {-35, -34}, {-37, -36}, {35, 36}, {-94, -93}, - {-89, -39}, {38, -79}, {39, -81}, {-88, -40}, {-74, -54}, {42, -69}, - {43, 44}, {-72, -56}, {45, 52}, {46, 50}, {47, -76}, {-49, 48}, - {-47, 49}, {-87, -41}, {-52, 51}, {-78, -50}, {53, -73}, {54, -75}, - {55, 57}, {56, -80}, {-86, -42}, {-48, 58}, {-44, -43}, {-66, -62}}; - -const SCHAR aBookPsIidFineFreqDecode[60][2] = { - {1, -64}, {2, 4}, {3, -65}, {-66, -62}, {-63, 5}, {6, 7}, - {-67, -61}, {8, 9}, {-68, -60}, {10, 11}, {-69, -59}, {12, 13}, - {-70, -58}, {14, 18}, {-57, 15}, {16, -72}, {-54, 17}, {-75, -53}, - {19, 37}, {-56, 20}, {21, -73}, {22, 29}, {23, -76}, {24, -78}, - {25, 28}, {26, 27}, {-85, -43}, {-83, -45}, {-81, -47}, {-52, 30}, - {-50, 31}, {32, -79}, {33, 34}, {-82, -46}, {35, 36}, {-90, -89}, - {-92, -91}, {38, -71}, {-55, 39}, {40, -74}, {41, 50}, {42, -77}, - {-49, 43}, {44, 47}, {45, 46}, {-86, -42}, {-88, -87}, {48, 49}, - {-39, -38}, {-41, -40}, {-51, 51}, {52, 59}, {53, 56}, {54, 55}, - {-35, -34}, {-37, -36}, {57, 58}, {-94, -93}, {-84, -44}, {-80, -48}}; - -/* constants used in psdec.cpp */ - -/* the values of the following 3 tables are shiftet right by 1 ! */ -const FIXP_DBL ScaleFactors[NO_IID_LEVELS] = { - - 0x5a5ded00, 0x59cd0400, 0x58c29680, 0x564c2e80, 0x52a3d480, - 0x4c8be080, 0x46df3080, 0x40000000, 0x384ba5c0, 0x304c2980, - 0x24e9f640, 0x1b4a2940, 0x11b5c0a0, 0x0b4e2540, 0x0514ea90}; - -const FIXP_DBL ScaleFactorsFine[NO_IID_LEVELS_FINE] = { - - 0x5a825c00, 0x5a821c00, 0x5a815100, 0x5a7ed000, 0x5a76e600, 0x5a5ded00, - 0x5a39b880, 0x59f1fd00, 0x5964d680, 0x5852ca00, 0x564c2e80, 0x54174480, - 0x50ea7500, 0x4c8be080, 0x46df3080, 0x40000000, 0x384ba5c0, 0x304c2980, - 0x288dd240, 0x217a2900, 0x1b4a2940, 0x13c5ece0, 0x0e2b0090, 0x0a178ef0, - 0x072ab798, 0x0514ea90, 0x02dc5944, 0x019bf87c, 0x00e7b173, 0x00824b8b, - 0x00494568}; -const FIXP_DBL Alphas[NO_ICC_LEVELS] = { - - 0x00000000, 0x0b6b5be0, 0x12485f80, 0x1da2fa40, - 0x2637ebc0, 0x3243f6c0, 0x466b7480, 0x6487ed80}; - -const UCHAR bins2groupMap20[NO_IID_GROUPS] = { - 0, 0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; - -const UCHAR FDK_sbrDecoder_aNoIidBins[3] = { - NO_LOW_RES_IID_BINS, NO_MID_RES_IID_BINS, NO_HI_RES_IID_BINS}; - -const UCHAR FDK_sbrDecoder_aNoIccBins[3] = { - NO_LOW_RES_ICC_BINS, NO_MID_RES_ICC_BINS, NO_HI_RES_ICC_BINS}; - -/************************************************************************/ -/*! - \brief Create lookup tables for some arithmetic functions - - The tables would normally be defined as const arrays, - but initialization at run time allows to specify their accuracy. -*/ -/************************************************************************/ - -/* 1/x-table: (example for INV_TABLE_BITS 8) - - The table covers an input range from 0.5 to 1.0 with a step size of 1/512, - starting at 0.5 + 1/512. - Each table entry corresponds to an input interval starting 1/1024 below the - exact value and ending 1/1024 above it. - - The table is actually a 0.5/x-table, so that the output range is again - 0.5...1.0 and the exponent of the result must be increased by 1. - - Input range Index in table result - ------------------------------------------------------------------- - 0.500000...0.500976 - 0.5 / 0.500000 = 1.000000 - 0.500976...0.502930 0 0.5 / 0.501953 = 0.996109 - 0.502930...0.500488 1 0.5 / 0.503906 = 0.992248 - ... - 0.999023...1.000000 255 0.5 / 1.000000 = 0.500000 - - for (i=0; iprevFact_mag[band] = FL2FXCONST_DBL(0.5f); - } - - for (band = 0; band < SBRDEC_MAX_DRC_BANDS; band++) { - hDrcData->currFact_mag[band] = FL2FXCONST_DBL(0.5f); - hDrcData->nextFact_mag[band] = FL2FXCONST_DBL(0.5f); - } - - hDrcData->prevFact_exp = 1; - hDrcData->currFact_exp = 1; - hDrcData->nextFact_exp = 1; - - hDrcData->numBandsCurr = 1; - hDrcData->numBandsNext = 1; - - hDrcData->winSequenceCurr = 0; - hDrcData->winSequenceNext = 0; - - hDrcData->drcInterpolationSchemeCurr = 0; - hDrcData->drcInterpolationSchemeNext = 0; - - hDrcData->enable = 0; -} - -/*! - \brief Swap DRC QMF scaling factors after they have been applied. - - \hDrcData Handle to DRC channel data. - - \return none -*/ -void sbrDecoder_drcUpdateChannel(HANDLE_SBR_DRC_CHANNEL hDrcData) { - if (hDrcData == NULL) { - return; - } - if (hDrcData->enable != 1) { - return; - } - - /* swap previous data */ - FDKmemcpy(hDrcData->currFact_mag, hDrcData->nextFact_mag, - SBRDEC_MAX_DRC_BANDS * sizeof(FIXP_DBL)); - - hDrcData->currFact_exp = hDrcData->nextFact_exp; - - hDrcData->numBandsCurr = hDrcData->numBandsNext; - - FDKmemcpy(hDrcData->bandTopCurr, hDrcData->bandTopNext, - SBRDEC_MAX_DRC_BANDS * sizeof(USHORT)); - - hDrcData->drcInterpolationSchemeCurr = hDrcData->drcInterpolationSchemeNext; - - hDrcData->winSequenceCurr = hDrcData->winSequenceNext; -} - -/*! - \brief Apply DRC factors slot based. - - \hDrcData Handle to DRC channel data. - \qmfRealSlot Pointer to real valued QMF data of one time slot. - \qmfImagSlot Pointer to the imaginary QMF data of one time slot. - \col Number of the time slot. - \numQmfSubSamples Total number of time slots for one frame. - \scaleFactor Pointer to the out scale factor of the time slot. - - \return None. -*/ -void sbrDecoder_drcApplySlot(HANDLE_SBR_DRC_CHANNEL hDrcData, - FIXP_DBL *qmfRealSlot, FIXP_DBL *qmfImagSlot, - int col, int numQmfSubSamples, int maxShift) { - const UCHAR *winBorderToColMap; - - int band, bottomMdct, topMdct, bin, useLP; - int indx = numQmfSubSamples - (numQmfSubSamples >> 1) - 10; /* l_border */ - int frameLenFlag = (numQmfSubSamples == 30) ? 1 : 0; - int frameSize = (frameLenFlag == 1) ? 960 : 1024; - - const FIXP_DBL *fact_mag = NULL; - INT fact_exp = 0; - UINT numBands = 0; - USHORT *bandTop = NULL; - int shortDrc = 0; - - FIXP_DBL alphaValue = FL2FXCONST_DBL(0.0f); - - if (hDrcData == NULL) { - return; - } - if (hDrcData->enable != 1) { - return; - } - - winBorderToColMap = winBorderToColMappingTab[frameLenFlag]; - - useLP = (qmfImagSlot == NULL) ? 1 : 0; - - col += indx; - bottomMdct = 0; - - /* get respective data and calc interpolation factor */ - if (col < (numQmfSubSamples >> 1)) { /* first half of current frame */ - if (hDrcData->winSequenceCurr != 2) { /* long window */ - int j = col + (numQmfSubSamples >> 1); - - if (hDrcData->drcInterpolationSchemeCurr == 0) { - INT k = (frameLenFlag) ? 0x4444445 : 0x4000000; - - alphaValue = (FIXP_DBL)(j * k); - } else { - if (j >= (int)winBorderToColMap[hDrcData->drcInterpolationSchemeCurr]) { - alphaValue = (FIXP_DBL)MAXVAL_DBL; - } - } - } else { /* short windows */ - shortDrc = 1; - } - - fact_mag = hDrcData->currFact_mag; - fact_exp = hDrcData->currFact_exp; - numBands = hDrcData->numBandsCurr; - bandTop = hDrcData->bandTopCurr; - } else if (col < numQmfSubSamples) { /* second half of current frame */ - if (hDrcData->winSequenceNext != 2) { /* next: long window */ - int j = col - (numQmfSubSamples >> 1); - - if (hDrcData->drcInterpolationSchemeNext == 0) { - INT k = (frameLenFlag) ? 0x4444445 : 0x4000000; - - alphaValue = (FIXP_DBL)(j * k); - } else { - if (j >= (int)winBorderToColMap[hDrcData->drcInterpolationSchemeNext]) { - alphaValue = (FIXP_DBL)MAXVAL_DBL; - } - } - - fact_mag = hDrcData->nextFact_mag; - fact_exp = hDrcData->nextFact_exp; - numBands = hDrcData->numBandsNext; - bandTop = hDrcData->bandTopNext; - } else { /* next: short windows */ - if (hDrcData->winSequenceCurr != 2) { /* current: long window */ - alphaValue = (FIXP_DBL)0; - - fact_mag = hDrcData->nextFact_mag; - fact_exp = hDrcData->nextFact_exp; - numBands = hDrcData->numBandsNext; - bandTop = hDrcData->bandTopNext; - } else { /* current: short windows */ - shortDrc = 1; - - fact_mag = hDrcData->currFact_mag; - fact_exp = hDrcData->currFact_exp; - numBands = hDrcData->numBandsCurr; - bandTop = hDrcData->bandTopCurr; - } - } - } else { /* first half of next frame */ - if (hDrcData->winSequenceNext != 2) { /* long window */ - int j = col - (numQmfSubSamples >> 1); - - if (hDrcData->drcInterpolationSchemeNext == 0) { - INT k = (frameLenFlag) ? 0x4444445 : 0x4000000; - - alphaValue = (FIXP_DBL)(j * k); - } else { - if (j >= (int)winBorderToColMap[hDrcData->drcInterpolationSchemeNext]) { - alphaValue = (FIXP_DBL)MAXVAL_DBL; - } - } - } else { /* short windows */ - shortDrc = 1; - } - - fact_mag = hDrcData->nextFact_mag; - fact_exp = hDrcData->nextFact_exp; - numBands = hDrcData->numBandsNext; - bandTop = hDrcData->bandTopNext; - - col -= numQmfSubSamples; - } - - /* process bands */ - for (band = 0; band < (int)numBands; band++) { - int bottomQmf, topQmf; - - FIXP_DBL drcFact_mag = (FIXP_DBL)MAXVAL_DBL; - - topMdct = (bandTop[band] + 1) << 2; - - if (!shortDrc) { /* long window */ - if (frameLenFlag) { - /* 960 framing */ - bottomQmf = fMultIfloor((FIXP_DBL)0x4444445, bottomMdct); - topQmf = fMultIfloor((FIXP_DBL)0x4444445, topMdct); - - topMdct = 30 * topQmf; - } else { - /* 1024 framing */ - topMdct &= ~0x1f; - - bottomQmf = bottomMdct >> 5; - topQmf = topMdct >> 5; - } - - if (band == ((int)numBands - 1)) { - topQmf = (64); - } - - for (bin = bottomQmf; bin < topQmf; bin++) { - FIXP_DBL drcFact1_mag = hDrcData->prevFact_mag[bin]; - FIXP_DBL drcFact2_mag = fact_mag[band]; - - /* normalize scale factors */ - if (hDrcData->prevFact_exp < maxShift) { - drcFact1_mag >>= maxShift - hDrcData->prevFact_exp; - } - if (fact_exp < maxShift) { - drcFact2_mag >>= maxShift - fact_exp; - } - - /* interpolate */ - if (alphaValue == (FIXP_DBL)0) { - drcFact_mag = drcFact1_mag; - } else if (alphaValue == (FIXP_DBL)MAXVAL_DBL) { - drcFact_mag = drcFact2_mag; - } else { - drcFact_mag = - fMult(alphaValue, drcFact2_mag) + - fMult(((FIXP_DBL)MAXVAL_DBL - alphaValue), drcFact1_mag); - } - - /* apply scaling */ - qmfRealSlot[bin] = fMult(qmfRealSlot[bin], drcFact_mag); - if (!useLP) { - qmfImagSlot[bin] = fMult(qmfImagSlot[bin], drcFact_mag); - } - - /* save previous factors */ - if (col == (numQmfSubSamples >> 1) - 1) { - hDrcData->prevFact_mag[bin] = fact_mag[band]; - } - } - } else { /* short windows */ - unsigned startWinIdx, stopWinIdx; - int startCol, stopCol; - FIXP_DBL invFrameSizeDiv8 = - (frameLenFlag) ? (FIXP_DBL)0x1111112 : (FIXP_DBL)0x1000000; - - /* limit top at the frame borders */ - if (topMdct < 0) { - topMdct = 0; - } - if (topMdct >= frameSize) { - topMdct = frameSize - 1; - } - - if (frameLenFlag) { - /* 960 framing */ - topMdct = fMultIfloor((FIXP_DBL)0x78000000, - fMultIfloor((FIXP_DBL)0x22222223, topMdct) << 2); - - startWinIdx = fMultIfloor(invFrameSizeDiv8, bottomMdct) + - 1; /* winBorderToColMap table has offset of 1 */ - stopWinIdx = fMultIceil(invFrameSizeDiv8 - (FIXP_DBL)1, topMdct) + 1; - } else { - /* 1024 framing */ - topMdct &= ~0x03; - - startWinIdx = fMultIfloor(invFrameSizeDiv8, bottomMdct) + 1; - stopWinIdx = fMultIceil(invFrameSizeDiv8, topMdct) + 1; - } - - /* startCol is truncated to the nearest corresponding start subsample in - the QMF of the short window bottom is present in:*/ - startCol = (int)winBorderToColMap[startWinIdx]; - - /* stopCol is rounded upwards to the nearest corresponding stop subsample - in the QMF of the short window top is present in. */ - stopCol = (int)winBorderToColMap[stopWinIdx]; - - bottomQmf = fMultIfloor(invFrameSizeDiv8, - ((bottomMdct % (numQmfSubSamples << 2)) << 5)); - topQmf = fMultIfloor(invFrameSizeDiv8, - ((topMdct % (numQmfSubSamples << 2)) << 5)); - - /* extend last band */ - if (band == ((int)numBands - 1)) { - topQmf = (64); - stopCol = numQmfSubSamples; - stopWinIdx = 10; - } - - if (topQmf == 0) { - if (frameLenFlag) { - FIXP_DBL rem = fMult(invFrameSizeDiv8, - (FIXP_DBL)(topMdct << (DFRACT_BITS - 12))); - if ((LONG)rem & (LONG)0x1F) { - stopWinIdx -= 1; - stopCol = (int)winBorderToColMap[stopWinIdx]; - } - } - topQmf = (64); - } - - /* save previous factors */ - if (stopCol == numQmfSubSamples) { - int tmpBottom = bottomQmf; - - if ((int)winBorderToColMap[8] > startCol) { - tmpBottom = 0; /* band starts in previous short window */ - } - - for (bin = tmpBottom; bin < topQmf; bin++) { - hDrcData->prevFact_mag[bin] = fact_mag[band]; - } - } - - /* apply */ - if ((col >= startCol) && (col < stopCol)) { - if (col >= (int)winBorderToColMap[startWinIdx + 1]) { - bottomQmf = 0; /* band starts in previous short window */ - } - if (col < (int)winBorderToColMap[stopWinIdx - 1]) { - topQmf = (64); /* band ends in next short window */ - } - - drcFact_mag = fact_mag[band]; - - /* normalize scale factor */ - if (fact_exp < maxShift) { - drcFact_mag >>= maxShift - fact_exp; - } - - /* apply scaling */ - for (bin = bottomQmf; bin < topQmf; bin++) { - qmfRealSlot[bin] = fMult(qmfRealSlot[bin], drcFact_mag); - if (!useLP) { - qmfImagSlot[bin] = fMult(qmfImagSlot[bin], drcFact_mag); - } - } - } - } - - bottomMdct = topMdct; - } /* end of bands loop */ - - if (col == (numQmfSubSamples >> 1) - 1) { - hDrcData->prevFact_exp = fact_exp; - } -} - -/*! - \brief Apply DRC factors frame based. - - \hDrcData Handle to DRC channel data. - \qmfRealSlot Pointer to real valued QMF data of the whole frame. - \qmfImagSlot Pointer to the imaginary QMF data of the whole frame. - \numQmfSubSamples Total number of time slots for one frame. - \scaleFactor Pointer to the out scale factor of the frame. - - \return None. -*/ -void sbrDecoder_drcApply(HANDLE_SBR_DRC_CHANNEL hDrcData, - FIXP_DBL **QmfBufferReal, FIXP_DBL **QmfBufferImag, - int numQmfSubSamples, int *scaleFactor) { - int col; - int maxShift = 0; - - if (hDrcData == NULL) { - return; - } - if (hDrcData->enable == 0) { - return; /* Avoid changing the scaleFactor even though the processing is - disabled. */ - } - - /* get max scale factor */ - if (hDrcData->prevFact_exp > maxShift) { - maxShift = hDrcData->prevFact_exp; - } - if (hDrcData->currFact_exp > maxShift) { - maxShift = hDrcData->currFact_exp; - } - if (hDrcData->nextFact_exp > maxShift) { - maxShift = hDrcData->nextFact_exp; - } - - for (col = 0; col < numQmfSubSamples; col++) { - FIXP_DBL *qmfSlotReal = QmfBufferReal[col]; - FIXP_DBL *qmfSlotImag = (QmfBufferImag == NULL) ? NULL : QmfBufferImag[col]; - - sbrDecoder_drcApplySlot(hDrcData, qmfSlotReal, qmfSlotImag, col, - numQmfSubSamples, maxShift); - } - - *scaleFactor += maxShift; -} --- a/libSBRdec/src/sbrdec_drc.h +++ /dev/null @@ -1,149 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): Christian Griebel - - Description: Dynamic range control (DRC) decoder tool for SBR - -*******************************************************************************/ - -#ifndef SBRDEC_DRC_H -#define SBRDEC_DRC_H - -#include "sbrdecoder.h" - -#define SBRDEC_MAX_DRC_CHANNELS (8) -#define SBRDEC_MAX_DRC_BANDS (16) - -typedef struct { - FIXP_DBL prevFact_mag[(64)]; - INT prevFact_exp; - - FIXP_DBL currFact_mag[SBRDEC_MAX_DRC_BANDS]; - FIXP_DBL nextFact_mag[SBRDEC_MAX_DRC_BANDS]; - INT currFact_exp; - INT nextFact_exp; - - UINT numBandsCurr; - UINT numBandsNext; - USHORT bandTopCurr[SBRDEC_MAX_DRC_BANDS]; - USHORT bandTopNext[SBRDEC_MAX_DRC_BANDS]; - - SHORT drcInterpolationSchemeCurr; - SHORT drcInterpolationSchemeNext; - - SHORT enable; - - UCHAR winSequenceCurr; - UCHAR winSequenceNext; - -} SBRDEC_DRC_CHANNEL; - -typedef SBRDEC_DRC_CHANNEL *HANDLE_SBR_DRC_CHANNEL; - -void sbrDecoder_drcInitChannel(HANDLE_SBR_DRC_CHANNEL hDrcData); - -void sbrDecoder_drcUpdateChannel(HANDLE_SBR_DRC_CHANNEL hDrcData); - -void sbrDecoder_drcApplySlot(HANDLE_SBR_DRC_CHANNEL hDrcData, - FIXP_DBL *qmfRealSlot, FIXP_DBL *qmfImagSlot, - int col, int numQmfSubSamples, int maxShift); - -void sbrDecoder_drcApply(HANDLE_SBR_DRC_CHANNEL hDrcData, - FIXP_DBL **QmfBufferReal, FIXP_DBL **QmfBufferImag, - int numQmfSubSamples, int *scaleFactor); - -#endif /* SBRDEC_DRC_H */ --- a/libSBRdec/src/sbrdec_freq_sca.cpp +++ /dev/null @@ -1,835 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Frequency scale calculation -*/ - -#include "sbrdec_freq_sca.h" - -#include "transcendent.h" -#include "sbr_rom.h" -#include "env_extr.h" - -#include "genericStds.h" /* need log() for debug-code only */ - -#define MAX_OCTAVE 29 -#define MAX_SECOND_REGION 50 - -static int numberOfBands(FIXP_SGL bpo_div16, int start, int stop, int warpFlag); -static void CalcBands(UCHAR *diff, UCHAR start, UCHAR stop, UCHAR num_bands); -static SBR_ERROR modifyBands(UCHAR max_band, UCHAR *diff, UCHAR length); -static void cumSum(UCHAR start_value, UCHAR *diff, UCHAR length, - UCHAR *start_adress); - -/*! - \brief Retrieve QMF-band where the SBR range starts - - Convert startFreq which was read from the bitstream into a - QMF-channel number. - - \return Number of start band -*/ -static UCHAR getStartBand( - UINT fs, /*!< Output sampling frequency */ - UCHAR startFreq, /*!< Index to table of possible start bands */ - UINT headerDataFlags) /*!< Info to SBR mode */ -{ - INT band; - UINT fsMapped = fs; - SBR_RATE rate = DUAL; - - if (headerDataFlags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) { - if (headerDataFlags & SBRDEC_QUAD_RATE) { - rate = QUAD; - } - fsMapped = sbrdec_mapToStdSampleRate(fs, 1); - } - - FDK_ASSERT(2 * (rate + 1) <= (4)); - - switch (fsMapped) { - case 192000: - band = FDK_sbrDecoder_sbr_start_freq_192[startFreq]; - break; - case 176400: - band = FDK_sbrDecoder_sbr_start_freq_176[startFreq]; - break; - case 128000: - band = FDK_sbrDecoder_sbr_start_freq_128[startFreq]; - break; - case 96000: - case 88200: - band = FDK_sbrDecoder_sbr_start_freq_88[rate][startFreq]; - break; - case 64000: - band = FDK_sbrDecoder_sbr_start_freq_64[rate][startFreq]; - break; - case 48000: - band = FDK_sbrDecoder_sbr_start_freq_48[rate][startFreq]; - break; - case 44100: - band = FDK_sbrDecoder_sbr_start_freq_44[rate][startFreq]; - break; - case 40000: - band = FDK_sbrDecoder_sbr_start_freq_40[rate][startFreq]; - break; - case 32000: - band = FDK_sbrDecoder_sbr_start_freq_32[rate][startFreq]; - break; - case 24000: - band = FDK_sbrDecoder_sbr_start_freq_24[rate][startFreq]; - break; - case 22050: - band = FDK_sbrDecoder_sbr_start_freq_22[rate][startFreq]; - break; - case 16000: - band = FDK_sbrDecoder_sbr_start_freq_16[rate][startFreq]; - break; - default: - band = 255; - } - - return band; -} - -/*! - \brief Retrieve QMF-band where the SBR range starts - - Convert startFreq which was read from the bitstream into a - QMF-channel number. - - \return Number of start band -*/ -static UCHAR getStopBand( - UINT fs, /*!< Output sampling frequency */ - UCHAR stopFreq, /*!< Index to table of possible start bands */ - UINT headerDataFlags, /*!< Info to SBR mode */ - UCHAR k0) /*!< Start freq index */ -{ - UCHAR k2; - - if (stopFreq < 14) { - INT stopMin; - INT num = 2 * (64); - UCHAR diff_tot[MAX_OCTAVE + MAX_SECOND_REGION]; - UCHAR *diff0 = diff_tot; - UCHAR *diff1 = diff_tot + MAX_OCTAVE; - - if (headerDataFlags & SBRDEC_QUAD_RATE) { - num >>= 1; - } - - if (fs < 32000) { - stopMin = (((2 * 6000 * num) / fs) + 1) >> 1; - } else { - if (fs < 64000) { - stopMin = (((2 * 8000 * num) / fs) + 1) >> 1; - } else { - stopMin = (((2 * 10000 * num) / fs) + 1) >> 1; - } - } - - /* - Choose a stop band between k1 and 64 depending on stopFreq (0..13), - based on a logarithmic scale. - The vectors diff0 and diff1 are used temporarily here. - */ - CalcBands(diff0, stopMin, 64, 13); - shellsort(diff0, 13); - cumSum(stopMin, diff0, 13, diff1); - k2 = diff1[stopFreq]; - } else if (stopFreq == 14) - k2 = 2 * k0; - else - k2 = 3 * k0; - - /* Limit to Nyquist */ - if (k2 > (64)) k2 = (64); - - /* Range checks */ - /* 1 <= difference <= 48; 1 <= fs <= 96000 */ - { - UCHAR max_freq_coeffs = (headerDataFlags & SBRDEC_QUAD_RATE) - ? MAX_FREQ_COEFFS_QUAD_RATE - : MAX_FREQ_COEFFS; - if (((k2 - k0) > max_freq_coeffs) || (k2 <= k0)) { - return 255; - } - } - - if (headerDataFlags & SBRDEC_QUAD_RATE) { - return k2; /* skip other checks: (k2 - k0) must be <= - MAX_FREQ_COEFFS_QUAD_RATE for all fs */ - } - if (headerDataFlags & (SBRDEC_SYNTAX_USAC | SBRDEC_SYNTAX_RSVD50)) { - /* 1 <= difference <= 35; 42000 <= fs <= 96000 */ - if ((fs >= 42000) && ((k2 - k0) > MAX_FREQ_COEFFS_FS44100)) { - return 255; - } - /* 1 <= difference <= 32; 46009 <= fs <= 96000 */ - if ((fs >= 46009) && ((k2 - k0) > MAX_FREQ_COEFFS_FS48000)) { - return 255; - } - } else { - /* 1 <= difference <= 35; fs == 44100 */ - if ((fs == 44100) && ((k2 - k0) > MAX_FREQ_COEFFS_FS44100)) { - return 255; - } - /* 1 <= difference <= 32; 48000 <= fs <= 96000 */ - if ((fs >= 48000) && ((k2 - k0) > MAX_FREQ_COEFFS_FS48000)) { - return 255; - } - } - - return k2; -} - -/*! - \brief Generates master frequency tables - - Frequency tables are calculated according to the selected domain - (linear/logarithmic) and granularity. - IEC 14496-3 4.6.18.3.2.1 - - \return errorCode, 0 if successful -*/ -SBR_ERROR -sbrdecUpdateFreqScale( - UCHAR *v_k_master, /*!< Master table to be created */ - UCHAR *numMaster, /*!< Number of entries in master table */ - UINT fs, /*!< SBR working sampling rate */ - HANDLE_SBR_HEADER_DATA hHeaderData, /*!< Control data from bitstream */ - UINT flags) { - FIXP_SGL bpo_div16; /* bands_per_octave divided by 16 */ - INT dk = 0; - - /* Internal variables */ - UCHAR k0, k2, i; - UCHAR num_bands0 = 0; - UCHAR num_bands1 = 0; - UCHAR diff_tot[MAX_OCTAVE + MAX_SECOND_REGION]; - UCHAR *diff0 = diff_tot; - UCHAR *diff1 = diff_tot + MAX_OCTAVE; - INT k2_achived; - INT k2_diff; - INT incr = 0; - - /* - Determine start band - */ - if (flags & SBRDEC_QUAD_RATE) { - fs >>= 1; - } - - k0 = getStartBand(fs, hHeaderData->bs_data.startFreq, flags); - if (k0 == 255) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - - /* - Determine stop band - */ - k2 = getStopBand(fs, hHeaderData->bs_data.stopFreq, flags, k0); - if (k2 == 255) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - - if (hHeaderData->bs_data.freqScale > 0) { /* Bark */ - INT k1; - - if (hHeaderData->bs_data.freqScale == 1) { - bpo_div16 = FL2FXCONST_SGL(12.0f / 16.0f); - } else if (hHeaderData->bs_data.freqScale == 2) { - bpo_div16 = FL2FXCONST_SGL(10.0f / 16.0f); - } else { - bpo_div16 = FL2FXCONST_SGL(8.0f / 16.0f); - } - - /* Ref: ISO/IEC 23003-3, Figure 12 - Flowchart calculation of fMaster for - * 4:1 system when bs_freq_scale > 0 */ - if (flags & SBRDEC_QUAD_RATE) { - if ((SHORT)k0 < (SHORT)(bpo_div16 >> ((FRACT_BITS - 1) - 4))) { - bpo_div16 = (FIXP_SGL)(k0 & (UCHAR)0xfe) - << ((FRACT_BITS - 1) - 4); /* bpo_div16 = floor(k0/2)*2 */ - } - } - - if (1000 * k2 > 2245 * k0) { /* Two or more regions */ - k1 = 2 * k0; - - num_bands0 = numberOfBands(bpo_div16, k0, k1, 0); - num_bands1 = - numberOfBands(bpo_div16, k1, k2, hHeaderData->bs_data.alterScale); - if (num_bands0 < 1) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - if (num_bands1 < 1) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - - CalcBands(diff0, k0, k1, num_bands0); - shellsort(diff0, num_bands0); - if (diff0[0] == 0) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - - cumSum(k0, diff0, num_bands0, v_k_master); - - CalcBands(diff1, k1, k2, num_bands1); - shellsort(diff1, num_bands1); - if (diff0[num_bands0 - 1] > diff1[0]) { - SBR_ERROR err; - - err = modifyBands(diff0[num_bands0 - 1], diff1, num_bands1); - if (err) return SBRDEC_UNSUPPORTED_CONFIG; - } - - /* Add 2nd region */ - cumSum(k1, diff1, num_bands1, &v_k_master[num_bands0]); - *numMaster = num_bands0 + num_bands1; /* Output nr of bands */ - - } else { /* Only one region */ - k1 = k2; - - num_bands0 = numberOfBands(bpo_div16, k0, k1, 0); - if (num_bands0 < 1) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - CalcBands(diff0, k0, k1, num_bands0); - shellsort(diff0, num_bands0); - if (diff0[0] == 0) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - - cumSum(k0, diff0, num_bands0, v_k_master); - *numMaster = num_bands0; /* Output nr of bands */ - } - } else { /* Linear mode */ - if (hHeaderData->bs_data.alterScale == 0) { - dk = 1; - /* FLOOR to get to few number of bands (next lower even number) */ - num_bands0 = (k2 - k0) & 254; - } else { - dk = 2; - num_bands0 = (((k2 - k0) >> 1) + 1) & 254; /* ROUND to the closest fit */ - } - - if (num_bands0 < 1) { - return SBRDEC_UNSUPPORTED_CONFIG; - /* We must return already here because 'i' can become negative below. */ - } - - k2_achived = k0 + num_bands0 * dk; - k2_diff = k2 - k2_achived; - - for (i = 0; i < num_bands0; i++) diff_tot[i] = dk; - - /* If linear scale wasn't achieved */ - /* and we got too wide SBR area */ - if (k2_diff < 0) { - incr = 1; - i = 0; - } - - /* If linear scale wasn't achieved */ - /* and we got too small SBR area */ - if (k2_diff > 0) { - incr = -1; - i = num_bands0 - 1; - } - - /* Adjust diff vector to get sepc. SBR range */ - while (k2_diff != 0) { - diff_tot[i] = diff_tot[i] - incr; - i = i + incr; - k2_diff = k2_diff + incr; - } - - cumSum(k0, diff_tot, num_bands0, v_k_master); /* cumsum */ - *numMaster = num_bands0; /* Output nr of bands */ - } - - if (*numMaster < 1) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - - /* Ref: ISO/IEC 23003-3 Cor.3, "In 7.5.5.2, add to the requirements:"*/ - if (flags & SBRDEC_QUAD_RATE) { - int k; - for (k = 1; k < *numMaster; k++) { - if (!(v_k_master[k] - v_k_master[k - 1] <= k0 - 2)) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - } - } - - /* - Print out the calculated table - */ - - return SBRDEC_OK; -} - -/*! - \brief Calculate frequency ratio of one SBR band - - All SBR bands should span a constant frequency range in the logarithmic - domain. This function calculates the ratio of any SBR band's upper and lower - frequency. - - \return num_band-th root of k_start/k_stop -*/ -static FIXP_SGL calcFactorPerBand(int k_start, int k_stop, int num_bands) { - /* Scaled bandfactor and step 1 bit right to avoid overflow - * use double data type */ - FIXP_DBL bandfactor = FL2FXCONST_DBL(0.25f); /* Start value */ - FIXP_DBL step = FL2FXCONST_DBL(0.125f); /* Initial increment for factor */ - - int direction = 1; - - /* Because saturation can't be done in INT IIS, - * changed start and stop data type from FIXP_SGL to FIXP_DBL */ - FIXP_DBL start = k_start << (DFRACT_BITS - 8); - FIXP_DBL stop = k_stop << (DFRACT_BITS - 8); - - FIXP_DBL temp; - - int j, i = 0; - - while (step > FL2FXCONST_DBL(0.0f)) { - i++; - temp = stop; - - /* Calculate temp^num_bands: */ - for (j = 0; j < num_bands; j++) - // temp = fMult(temp,bandfactor); - temp = fMultDiv2(temp, bandfactor) << 2; - - if (temp < start) { /* Factor too strong, make it weaker */ - if (direction == 0) - /* Halfen step. Right shift is not done as fract because otherwise the - lowest bit cannot be cleared due to rounding */ - step = (FIXP_DBL)((LONG)step >> 1); - direction = 1; - bandfactor = bandfactor + step; - } else { /* Factor is too weak: make it stronger */ - if (direction == 1) step = (FIXP_DBL)((LONG)step >> 1); - direction = 0; - bandfactor = bandfactor - step; - } - - if (i > 100) { - step = FL2FXCONST_DBL(0.0f); - } - } - return FX_DBL2FX_SGL(bandfactor << 1); -} - -/*! - \brief Calculate number of SBR bands between start and stop band - - Given the number of bands per octave, this function calculates how many - bands fit in the given frequency range. - When the warpFlag is set, the 'band density' is decreased by a factor - of 1/1.3 - - \return number of bands -*/ -static int numberOfBands( - FIXP_SGL bpo_div16, /*!< Input: number of bands per octave divided by 16 */ - int start, /*!< First QMF band of SBR frequency range */ - int stop, /*!< Last QMF band of SBR frequency range + 1 */ - int warpFlag) /*!< Stretching flag */ -{ - FIXP_SGL num_bands_div128; - int num_bands; - - num_bands_div128 = - FX_DBL2FX_SGL(fMult(FDK_getNumOctavesDiv8(start, stop), bpo_div16)); - - if (warpFlag) { - /* Apply the warp factor of 1.3 to get wider bands. We use a value - of 32768/25200 instead of the exact value to avoid critical cases - of rounding. - */ - num_bands_div128 = FX_DBL2FX_SGL( - fMult(num_bands_div128, FL2FXCONST_SGL(25200.0 / 32768.0))); - } - - /* add scaled 1 for rounding to even numbers: */ - num_bands_div128 = num_bands_div128 + FL2FXCONST_SGL(1.0f / 128.0f); - /* scale back to right aligned integer and double the value: */ - num_bands = 2 * ((LONG)num_bands_div128 >> (FRACT_BITS - 7)); - - return (num_bands); -} - -/*! - \brief Calculate width of SBR bands - - Given the desired number of bands within the SBR frequency range, - this function calculates the width of each SBR band in QMF channels. - The bands get wider from start to stop (bark scale). -*/ -static void CalcBands(UCHAR *diff, /*!< Vector of widths to be calculated */ - UCHAR start, /*!< Lower end of subband range */ - UCHAR stop, /*!< Upper end of subband range */ - UCHAR num_bands) /*!< Desired number of bands */ -{ - int i; - int previous; - int current; - FIXP_SGL exact, temp; - FIXP_SGL bandfactor = calcFactorPerBand(start, stop, num_bands); - - previous = stop; /* Start with highest QMF channel */ - exact = (FIXP_SGL)( - stop << (FRACT_BITS - 8)); /* Shift left to gain some accuracy */ - - for (i = num_bands - 1; i >= 0; i--) { - /* Calculate border of next lower sbr band */ - exact = FX_DBL2FX_SGL(fMult(exact, bandfactor)); - - /* Add scaled 0.5 for rounding: - We use a value 128/256 instead of 0.5 to avoid some critical cases of - rounding. */ - temp = exact + FL2FXCONST_SGL(128.0 / 32768.0); - - /* scale back to right alinged integer: */ - current = (LONG)temp >> (FRACT_BITS - 8); - - /* Save width of band i */ - diff[i] = previous - current; - previous = current; - } -} - -/*! - \brief Calculate cumulated sum vector from delta vector -*/ -static void cumSum(UCHAR start_value, UCHAR *diff, UCHAR length, - UCHAR *start_adress) { - int i; - start_adress[0] = start_value; - for (i = 1; i <= length; i++) - start_adress[i] = start_adress[i - 1] + diff[i - 1]; -} - -/*! - \brief Adapt width of frequency bands in the second region - - If SBR spans more than 2 octaves, the upper part of a bark-frequency-scale - is calculated separately. This function tries to avoid that the second region - starts with a band smaller than the highest band of the first region. -*/ -static SBR_ERROR modifyBands(UCHAR max_band_previous, UCHAR *diff, - UCHAR length) { - int change = max_band_previous - diff[0]; - - /* Limit the change so that the last band cannot get narrower than the first - * one */ - if (change > (diff[length - 1] - diff[0]) >> 1) - change = (diff[length - 1] - diff[0]) >> 1; - - diff[0] += change; - diff[length - 1] -= change; - shellsort(diff, length); - - return SBRDEC_OK; -} - -/*! - \brief Update high resolution frequency band table -*/ -static void sbrdecUpdateHiRes(UCHAR *h_hires, UCHAR *num_hires, - UCHAR *v_k_master, UCHAR num_bands, - UCHAR xover_band) { - UCHAR i; - - *num_hires = num_bands - xover_band; - - for (i = xover_band; i <= num_bands; i++) { - h_hires[i - xover_band] = v_k_master[i]; - } -} - -/*! - \brief Build low resolution table out of high resolution table -*/ -static void sbrdecUpdateLoRes(UCHAR *h_lores, UCHAR *num_lores, UCHAR *h_hires, - UCHAR num_hires) { - UCHAR i; - - if ((num_hires & 1) == 0) { - /* If even number of hires bands */ - *num_lores = num_hires >> 1; - /* Use every second lores=hires[0,2,4...] */ - for (i = 0; i <= *num_lores; i++) h_lores[i] = h_hires[i * 2]; - } else { - /* Odd number of hires, which means xover is odd */ - *num_lores = (num_hires + 1) >> 1; - /* Use lores=hires[0,1,3,5 ...] */ - h_lores[0] = h_hires[0]; - for (i = 1; i <= *num_lores; i++) { - h_lores[i] = h_hires[i * 2 - 1]; - } - } -} - -/*! - \brief Derive a low-resolution frequency-table from the master frequency - table -*/ -void sbrdecDownSampleLoRes(UCHAR *v_result, UCHAR num_result, - UCHAR *freqBandTableRef, UCHAR num_Ref) { - int step; - int i, j; - int org_length, result_length; - int v_index[MAX_FREQ_COEFFS >> 1]; - - /* init */ - org_length = num_Ref; - result_length = num_result; - - v_index[0] = 0; /* Always use left border */ - i = 0; - while (org_length > 0) { - /* Create downsample vector */ - i++; - step = org_length / result_length; - org_length = org_length - step; - result_length--; - v_index[i] = v_index[i - 1] + step; - } - - for (j = 0; j <= i; j++) { - /* Use downsample vector to index LoResolution vector */ - v_result[j] = freqBandTableRef[v_index[j]]; - } -} - -/*! - \brief Sorting routine -*/ -void shellsort(UCHAR *in, UCHAR n) { - int i, j, v, w; - int inc = 1; - - do - inc = 3 * inc + 1; - while (inc <= n); - - do { - inc = inc / 3; - for (i = inc; i < n; i++) { - v = in[i]; - j = i; - while ((w = in[j - inc]) > v) { - in[j] = w; - j -= inc; - if (j < inc) break; - } - in[j] = v; - } - } while (inc > 1); -} - -/*! - \brief Reset frequency band tables - \return errorCode, 0 if successful -*/ -SBR_ERROR -resetFreqBandTables(HANDLE_SBR_HEADER_DATA hHeaderData, const UINT flags) { - SBR_ERROR err = SBRDEC_OK; - int k2, kx, lsb, usb; - int intTemp; - UCHAR nBandsLo, nBandsHi; - HANDLE_FREQ_BAND_DATA hFreq = &hHeaderData->freqBandData; - - /* Calculate master frequency function */ - err = sbrdecUpdateFreqScale(hFreq->v_k_master, &hFreq->numMaster, - hHeaderData->sbrProcSmplRate, hHeaderData, flags); - - if (err || (hHeaderData->bs_info.xover_band > hFreq->numMaster)) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - - /* Derive Hiresolution from master frequency function */ - sbrdecUpdateHiRes(hFreq->freqBandTable[1], &nBandsHi, hFreq->v_k_master, - hFreq->numMaster, hHeaderData->bs_info.xover_band); - /* Derive Loresolution from Hiresolution */ - sbrdecUpdateLoRes(hFreq->freqBandTable[0], &nBandsLo, hFreq->freqBandTable[1], - nBandsHi); - - hFreq->nSfb[0] = nBandsLo; - hFreq->nSfb[1] = nBandsHi; - - /* Check index to freqBandTable[0] */ - if (!(nBandsLo > 0) || - (nBandsLo > (((hHeaderData->numberOfAnalysisBands == 16) - ? MAX_FREQ_COEFFS_QUAD_RATE - : MAX_FREQ_COEFFS_DUAL_RATE) >> - 1))) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - - lsb = hFreq->freqBandTable[0][0]; - usb = hFreq->freqBandTable[0][nBandsLo]; - - /* Check for start frequency border k_x: - - ISO/IEC 14496-3 4.6.18.3.6 Requirements - - ISO/IEC 23003-3 7.5.5.2 Modifications and additions to the MPEG-4 SBR - tool - */ - /* Note that lsb > as hHeaderData->numberOfAnalysisBands is a valid SBR config - * for 24 band QMF analysis. */ - if ((lsb > ((flags & SBRDEC_QUAD_RATE) ? 16 : (32))) || (lsb >= usb)) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - - /* Calculate number of noise bands */ - - k2 = hFreq->freqBandTable[1][nBandsHi]; - kx = hFreq->freqBandTable[1][0]; - - if (hHeaderData->bs_data.noise_bands == 0) { - hFreq->nNfb = 1; - } else /* Calculate no of noise bands 1,2 or 3 bands/octave */ - { - /* Fetch number of octaves divided by 32 */ - intTemp = (LONG)FDK_getNumOctavesDiv8(kx, k2) >> 2; - - /* Integer-Multiplication with number of bands: */ - intTemp = intTemp * hHeaderData->bs_data.noise_bands; - - /* Add scaled 0.5 for rounding: */ - intTemp = intTemp + (LONG)FL2FXCONST_SGL(0.5f / 32.0f); - - /* Convert to right-aligned integer: */ - intTemp = intTemp >> (FRACT_BITS - 1 /*sign*/ - 5 /* rescale */); - - if (intTemp == 0) intTemp = 1; - - hFreq->nNfb = intTemp; - } - - hFreq->nInvfBands = hFreq->nNfb; - - if (hFreq->nNfb > MAX_NOISE_COEFFS) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - - /* Get noise bands */ - sbrdecDownSampleLoRes(hFreq->freqBandTableNoise, hFreq->nNfb, - hFreq->freqBandTable[0], nBandsLo); - - /* save old highband; required for overlap in usac - when headerchange occurs at XVAR and VARX frame; */ - hFreq->ov_highSubband = hFreq->highSubband; - - hFreq->lowSubband = lsb; - hFreq->highSubband = usb; - - return SBRDEC_OK; -} --- a/libSBRdec/src/sbrdec_freq_sca.h +++ /dev/null @@ -1,127 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Frequency scale prototypes -*/ -#ifndef SBRDEC_FREQ_SCA_H -#define SBRDEC_FREQ_SCA_H - -#include "sbrdecoder.h" -#include "env_extr.h" - -typedef enum { DUAL, QUAD } SBR_RATE; - -SBR_ERROR -sbrdecUpdateFreqScale(UCHAR *v_k_master, UCHAR *numMaster, UINT fs, - HANDLE_SBR_HEADER_DATA headerData, UINT flags); - -void sbrdecDownSampleLoRes(UCHAR *v_result, UCHAR num_result, - UCHAR *freqBandTableRef, UCHAR num_Ref); - -void shellsort(UCHAR *in, UCHAR n); - -SBR_ERROR -resetFreqBandTables(HANDLE_SBR_HEADER_DATA hHeaderData, const UINT flags); - -#endif --- a/libSBRdec/src/sbrdecoder.cpp +++ /dev/null @@ -1,2023 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief SBR decoder frontend - This module provides a frontend to the SBR decoder. The function openSBR() is - called for initialization. The function sbrDecoder_Apply() is called for each - frame. sbr_Apply() will call the required functions to decode the raw SBR data - (provided by env_extr.cpp), to decode the envelope data and noise floor levels - [decodeSbrData()], and to finally apply SBR to the current frame [sbr_dec()]. - - \sa sbrDecoder_Apply(), \ref documentationOverview -*/ - -/*! - \page documentationOverview Overview of important information resources and - source code documentation - - As part of this documentation you can find more extensive descriptions about - key concepts and algorithms at the following locations: - -

Programming

- - \li Buffer management: sbrDecoder_Apply() and sbr_dec() - \li Internal scale factors to maximize SNR on fixed point processors: - #QMF_SCALE_FACTOR \li Special mantissa-exponent format: Created in - requantizeEnvelopeData() and used in calculateSbrEnvelope() - -

Algorithmic details

- \li About the SBR data format: \ref SBR_HEADER_ELEMENT and \ref - SBR_STANDARD_ELEMENT \li Details about the bitstream decoder: env_extr.cpp \li - Details about the QMF filterbank and the provided polyphase implementation: - qmf_dec.cpp \li Details about the transposer: lpp_tran.cpp \li Details about - the envelope adjuster: env_calc.cpp - -*/ - -#include "sbrdecoder.h" - -#include "FDK_bitstream.h" - -#include "sbrdec_freq_sca.h" -#include "env_extr.h" -#include "sbr_dec.h" -#include "env_dec.h" -#include "sbr_crc.h" -#include "sbr_ram.h" -#include "sbr_rom.h" -#include "lpp_tran.h" -#include "transcendent.h" - -#include "FDK_crc.h" - -#include "sbrdec_drc.h" - -#include "psbitdec.h" - -/* Decoder library info */ -#define SBRDECODER_LIB_VL0 3 -#define SBRDECODER_LIB_VL1 0 -#define SBRDECODER_LIB_VL2 0 -#define SBRDECODER_LIB_TITLE "SBR Decoder" -#ifdef __ANDROID__ -#define SBRDECODER_LIB_BUILD_DATE "" -#define SBRDECODER_LIB_BUILD_TIME "" -#else -#define SBRDECODER_LIB_BUILD_DATE __DATE__ -#define SBRDECODER_LIB_BUILD_TIME __TIME__ -#endif - -static void setFrameErrorFlag(SBR_DECODER_ELEMENT *pSbrElement, UCHAR value) { - if (pSbrElement != NULL) { - switch (value) { - case FRAME_ERROR_ALLSLOTS: - FDKmemset(pSbrElement->frameErrorFlag, FRAME_ERROR, - sizeof(pSbrElement->frameErrorFlag)); - break; - default: - pSbrElement->frameErrorFlag[pSbrElement->useFrameSlot] = value; - } - } -} - -static UCHAR getHeaderSlot(UCHAR currentSlot, UCHAR hdrSlotUsage[(1) + 1]) { - UINT occupied = 0; - int s; - UCHAR slot = hdrSlotUsage[currentSlot]; - - FDK_ASSERT((1) + 1 < 32); - - for (s = 0; s < (1) + 1; s++) { - if ((hdrSlotUsage[s] == slot) && (s != slot)) { - occupied = 1; - break; - } - } - - if (occupied) { - occupied = 0; - - for (s = 0; s < (1) + 1; s++) { - occupied |= 1 << hdrSlotUsage[s]; - } - for (s = 0; s < (1) + 1; s++) { - if (!(occupied & 0x1)) { - slot = s; - break; - } - occupied >>= 1; - } - } - - return slot; -} - -static void copySbrHeader(HANDLE_SBR_HEADER_DATA hDst, - const HANDLE_SBR_HEADER_DATA hSrc) { - /* copy the whole header memory (including pointers) */ - FDKmemcpy(hDst, hSrc, sizeof(SBR_HEADER_DATA)); - - /* update pointers */ - hDst->freqBandData.freqBandTable[0] = hDst->freqBandData.freqBandTableLo; - hDst->freqBandData.freqBandTable[1] = hDst->freqBandData.freqBandTableHi; -} - -static int compareSbrHeader(const HANDLE_SBR_HEADER_DATA hHdr1, - const HANDLE_SBR_HEADER_DATA hHdr2) { - int result = 0; - - /* compare basic data */ - result |= (hHdr1->syncState != hHdr2->syncState) ? 1 : 0; - result |= (hHdr1->status != hHdr2->status) ? 1 : 0; - result |= (hHdr1->frameErrorFlag != hHdr2->frameErrorFlag) ? 1 : 0; - result |= (hHdr1->numberTimeSlots != hHdr2->numberTimeSlots) ? 1 : 0; - result |= - (hHdr1->numberOfAnalysisBands != hHdr2->numberOfAnalysisBands) ? 1 : 0; - result |= (hHdr1->timeStep != hHdr2->timeStep) ? 1 : 0; - result |= (hHdr1->sbrProcSmplRate != hHdr2->sbrProcSmplRate) ? 1 : 0; - - /* compare bitstream data */ - result |= - FDKmemcmp(&hHdr1->bs_data, &hHdr2->bs_data, sizeof(SBR_HEADER_DATA_BS)); - result |= - FDKmemcmp(&hHdr1->bs_dflt, &hHdr2->bs_dflt, sizeof(SBR_HEADER_DATA_BS)); - result |= FDKmemcmp(&hHdr1->bs_info, &hHdr2->bs_info, - sizeof(SBR_HEADER_DATA_BS_INFO)); - - /* compare frequency band data */ - result |= FDKmemcmp(&hHdr1->freqBandData, &hHdr2->freqBandData, - (8 + MAX_NUM_LIMITERS + 1) * sizeof(UCHAR)); - result |= FDKmemcmp(hHdr1->freqBandData.freqBandTableLo, - hHdr2->freqBandData.freqBandTableLo, - (MAX_FREQ_COEFFS / 2 + 1) * sizeof(UCHAR)); - result |= FDKmemcmp(hHdr1->freqBandData.freqBandTableHi, - hHdr2->freqBandData.freqBandTableHi, - (MAX_FREQ_COEFFS + 1) * sizeof(UCHAR)); - result |= FDKmemcmp(hHdr1->freqBandData.freqBandTableNoise, - hHdr2->freqBandData.freqBandTableNoise, - (MAX_NOISE_COEFFS + 1) * sizeof(UCHAR)); - result |= - FDKmemcmp(hHdr1->freqBandData.v_k_master, hHdr2->freqBandData.v_k_master, - (MAX_FREQ_COEFFS + 1) * sizeof(UCHAR)); - - return result; -} - -/*! - \brief Reset SBR decoder. - - Reset should only be called if SBR has been sucessfully detected by - an appropriate checkForPayload() function. - - \return Error code. -*/ -static SBR_ERROR sbrDecoder_ResetElement(HANDLE_SBRDECODER self, - int sampleRateIn, int sampleRateOut, - int samplesPerFrame, - const MP4_ELEMENT_ID elementID, - const int elementIndex, - const int overlap) { - SBR_ERROR sbrError = SBRDEC_OK; - HANDLE_SBR_HEADER_DATA hSbrHeader; - UINT qmfFlags = 0; - - int i, synDownsampleFac; - - /* USAC: assuming theoretical case 8 kHz output sample rate with 4:1 SBR */ - const int sbr_min_sample_rate_in = IS_USAC(self->coreCodec) ? 2000 : 6400; - - /* Check in/out samplerates */ - if (sampleRateIn < sbr_min_sample_rate_in || sampleRateIn > (96000)) { - sbrError = SBRDEC_UNSUPPORTED_CONFIG; - goto bail; - } - - if (sampleRateOut > (96000)) { - sbrError = SBRDEC_UNSUPPORTED_CONFIG; - goto bail; - } - - /* Set QMF mode flags */ - if (self->flags & SBRDEC_LOW_POWER) qmfFlags |= QMF_FLAG_LP; - - if (self->coreCodec == AOT_ER_AAC_ELD) { - if (self->flags & SBRDEC_LD_MPS_QMF) { - qmfFlags |= QMF_FLAG_MPSLDFB; - } else { - qmfFlags |= QMF_FLAG_CLDFB; - } - } - - /* Set downsampling factor for synthesis filter bank */ - if (sampleRateOut == 0) { - /* no single rate mode */ - sampleRateOut = - sampleRateIn - << 1; /* In case of implicit signalling, assume dual rate SBR */ - } - - if (sampleRateIn == sampleRateOut) { - synDownsampleFac = 2; - self->flags |= SBRDEC_DOWNSAMPLE; - } else { - synDownsampleFac = 1; - self->flags &= ~SBRDEC_DOWNSAMPLE; - } - - self->synDownsampleFac = synDownsampleFac; - self->sampleRateOut = sampleRateOut; - - { - for (i = 0; i < (1) + 1; i++) { - int setDflt; - hSbrHeader = &(self->sbrHeader[elementIndex][i]); - setDflt = ((hSbrHeader->syncState == SBR_NOT_INITIALIZED) || - (self->flags & SBRDEC_FORCE_RESET)) - ? 1 - : 0; - - /* init a default header such that we can at least do upsampling later */ - sbrError = initHeaderData(hSbrHeader, sampleRateIn, sampleRateOut, - self->downscaleFactor, samplesPerFrame, - self->flags, setDflt); - - /* Set synchState to UPSAMPLING in case it already is initialized */ - hSbrHeader->syncState = hSbrHeader->syncState > UPSAMPLING - ? UPSAMPLING - : hSbrHeader->syncState; - } - } - - if (sbrError != SBRDEC_OK) { - goto bail; - } - - if (!self->pQmfDomain->globalConf.qmfDomainExplicitConfig) { - self->pQmfDomain->globalConf.flags_requested |= qmfFlags; - self->pQmfDomain->globalConf.nBandsAnalysis_requested = - self->sbrHeader[elementIndex][0].numberOfAnalysisBands; - self->pQmfDomain->globalConf.nBandsSynthesis_requested = - (synDownsampleFac == 1) ? 64 : 32; /* may be overwritten by MPS */ - self->pQmfDomain->globalConf.nBandsSynthesis_requested /= - self->downscaleFactor; - self->pQmfDomain->globalConf.nQmfTimeSlots_requested = - self->sbrHeader[elementIndex][0].numberTimeSlots * - self->sbrHeader[elementIndex][0].timeStep; - self->pQmfDomain->globalConf.nQmfOvTimeSlots_requested = overlap; - self->pQmfDomain->globalConf.nQmfProcBands_requested = 64; /* always 64 */ - self->pQmfDomain->globalConf.nQmfProcChannels_requested = - 1; /* may be overwritten by MPS */ - } - - /* Init SBR channels going to be assigned to a SBR element */ - { - int ch; - for (ch = 0; ch < self->pSbrElement[elementIndex]->nChannels; ch++) { - int headerIndex = - getHeaderSlot(self->pSbrElement[elementIndex]->useFrameSlot, - self->pSbrElement[elementIndex]->useHeaderSlot); - - /* and create sbrDec */ - sbrError = - createSbrDec(self->pSbrElement[elementIndex]->pSbrChannel[ch], - &self->sbrHeader[elementIndex][headerIndex], - &self->pSbrElement[elementIndex]->transposerSettings, - synDownsampleFac, qmfFlags, self->flags, overlap, ch, - self->codecFrameSize); - - if (sbrError != SBRDEC_OK) { - goto bail; - } - } - } - - // FDKmemclear(sbr_OverlapBuffer, sizeof(sbr_OverlapBuffer)); - - if (self->numSbrElements == 1) { - switch (self->coreCodec) { - case AOT_AAC_LC: - case AOT_SBR: - case AOT_PS: - case AOT_ER_AAC_SCAL: - case AOT_DRM_AAC: - case AOT_DRM_SURROUND: - if (CreatePsDec(&self->hParametricStereoDec, samplesPerFrame)) { - sbrError = SBRDEC_CREATE_ERROR; - goto bail; - } - break; - default: - break; - } - } - - /* Init frame delay slot handling */ - self->pSbrElement[elementIndex]->useFrameSlot = 0; - for (i = 0; i < ((1) + 1); i++) { - self->pSbrElement[elementIndex]->useHeaderSlot[i] = i; - } - -bail: - - return sbrError; -} - -/*! - \brief Assign QMF domain provided QMF channels to SBR channels. - - \return void -*/ -static void sbrDecoder_AssignQmfChannels2SbrChannels(HANDLE_SBRDECODER self) { - int ch, el, absCh_offset = 0; - for (el = 0; el < self->numSbrElements; el++) { - if (self->pSbrElement[el] != NULL) { - for (ch = 0; ch < self->pSbrElement[el]->nChannels; ch++) { - FDK_ASSERT(((absCh_offset + ch) < ((8) + (1))) && - ((absCh_offset + ch) < ((8) + (1)))); - self->pSbrElement[el]->pSbrChannel[ch]->SbrDec.qmfDomainInCh = - &self->pQmfDomain->QmfDomainIn[absCh_offset + ch]; - self->pSbrElement[el]->pSbrChannel[ch]->SbrDec.qmfDomainOutCh = - &self->pQmfDomain->QmfDomainOut[absCh_offset + ch]; - } - absCh_offset += self->pSbrElement[el]->nChannels; - } - } -} - -SBR_ERROR sbrDecoder_Open(HANDLE_SBRDECODER *pSelf, - HANDLE_FDK_QMF_DOMAIN pQmfDomain) { - HANDLE_SBRDECODER self = NULL; - SBR_ERROR sbrError = SBRDEC_OK; - int elIdx; - - if ((pSelf == NULL) || (pQmfDomain == NULL)) { - return SBRDEC_INVALID_ARGUMENT; - } - - /* Get memory for this instance */ - self = GetRam_SbrDecoder(); - if (self == NULL) { - sbrError = SBRDEC_MEM_ALLOC_FAILED; - goto bail; - } - - self->pQmfDomain = pQmfDomain; - - /* - Already zero because of calloc - self->numSbrElements = 0; - self->numSbrChannels = 0; - self->codecFrameSize = 0; - */ - - self->numDelayFrames = (1); /* set to the max value by default */ - - /* Initialize header sync state */ - for (elIdx = 0; elIdx < (8); elIdx += 1) { - int i; - for (i = 0; i < (1) + 1; i += 1) { - self->sbrHeader[elIdx][i].syncState = SBR_NOT_INITIALIZED; - } - } - - *pSelf = self; - -bail: - return sbrError; -} - -/** - * \brief determine if the given core codec AOT can be processed or not. - * \param coreCodec core codec audio object type. - * \return 1 if SBR can be processed, 0 if SBR cannot be processed/applied. - */ -static int sbrDecoder_isCoreCodecValid(AUDIO_OBJECT_TYPE coreCodec) { - switch (coreCodec) { - case AOT_AAC_LC: - case AOT_SBR: - case AOT_PS: - case AOT_ER_AAC_SCAL: - case AOT_ER_AAC_ELD: - case AOT_DRM_AAC: - case AOT_DRM_SURROUND: - case AOT_USAC: - return 1; - default: - return 0; - } -} - -static void sbrDecoder_DestroyElement(HANDLE_SBRDECODER self, - const int elementIndex) { - if (self->pSbrElement[elementIndex] != NULL) { - int ch; - - for (ch = 0; ch < SBRDEC_MAX_CH_PER_ELEMENT; ch++) { - if (self->pSbrElement[elementIndex]->pSbrChannel[ch] != NULL) { - deleteSbrDec(self->pSbrElement[elementIndex]->pSbrChannel[ch]); - FreeRam_SbrDecChannel( - &self->pSbrElement[elementIndex]->pSbrChannel[ch]); - self->numSbrChannels -= 1; - } - } - FreeRam_SbrDecElement(&self->pSbrElement[elementIndex]); - self->numSbrElements -= 1; - } -} - -SBR_ERROR sbrDecoder_InitElement( - HANDLE_SBRDECODER self, const int sampleRateIn, const int sampleRateOut, - const int samplesPerFrame, const AUDIO_OBJECT_TYPE coreCodec, - const MP4_ELEMENT_ID elementID, const int elementIndex, - const UCHAR harmonicSBR, const UCHAR stereoConfigIndex, - const UCHAR configMode, UCHAR *configChanged, const INT downscaleFactor) { - SBR_ERROR sbrError = SBRDEC_OK; - int chCnt = 0; - int nSbrElementsStart; - int nSbrChannelsStart; - if (self == NULL) { - return SBRDEC_INVALID_ARGUMENT; - } - - nSbrElementsStart = self->numSbrElements; - nSbrChannelsStart = self->numSbrChannels; - - /* Check core codec AOT */ - if (!sbrDecoder_isCoreCodecValid(coreCodec) || elementIndex >= (8)) { - sbrError = SBRDEC_UNSUPPORTED_CONFIG; - goto bail; - } - - if (elementID != ID_SCE && elementID != ID_CPE && elementID != ID_LFE) { - sbrError = SBRDEC_UNSUPPORTED_CONFIG; - goto bail; - } - - if (self->sampleRateIn == sampleRateIn && - self->codecFrameSize == samplesPerFrame && self->coreCodec == coreCodec && - self->pSbrElement[elementIndex] != NULL && - self->pSbrElement[elementIndex]->elementID == elementID && - !(self->flags & SBRDEC_FORCE_RESET) && - ((sampleRateOut == 0) ? 1 : (self->sampleRateOut == sampleRateOut)) && - ((harmonicSBR == 2) ? 1 - : (self->harmonicSBR == - harmonicSBR)) /* The value 2 signalizes that - harmonicSBR shall be ignored in - the config change detection */ - ) { - /* Nothing to do */ - return SBRDEC_OK; - } else { - if (configMode & AC_CM_DET_CFG_CHANGE) { - *configChanged = 1; - } - } - - /* reaching this point the SBR-decoder gets (re-)configured */ - - /* The flags field is used for all elements! */ - self->flags &= - (SBRDEC_FORCE_RESET | SBRDEC_FLUSH); /* Keep the global flags. They will - be reset after decoding. */ - self->flags |= (downscaleFactor > 1) ? SBRDEC_ELD_DOWNSCALE : 0; - self->flags |= (coreCodec == AOT_ER_AAC_ELD) ? SBRDEC_ELD_GRID : 0; - self->flags |= (coreCodec == AOT_ER_AAC_SCAL) ? SBRDEC_SYNTAX_SCAL : 0; - self->flags |= - (coreCodec == AOT_DRM_AAC) ? SBRDEC_SYNTAX_SCAL | SBRDEC_SYNTAX_DRM : 0; - self->flags |= (coreCodec == AOT_DRM_SURROUND) - ? SBRDEC_SYNTAX_SCAL | SBRDEC_SYNTAX_DRM - : 0; - self->flags |= (coreCodec == AOT_USAC) ? SBRDEC_SYNTAX_USAC : 0; - /* Robustness: Take integer division rounding into consideration. E.g. 22050 - * Hz with 4:1 SBR => 5512 Hz core sampling rate. */ - self->flags |= (sampleRateIn == sampleRateOut / 4) ? SBRDEC_QUAD_RATE : 0; - self->flags |= (harmonicSBR == 1) ? SBRDEC_USAC_HARMONICSBR : 0; - - if (configMode & AC_CM_DET_CFG_CHANGE) { - return SBRDEC_OK; - } - - self->sampleRateIn = sampleRateIn; - self->codecFrameSize = samplesPerFrame; - self->coreCodec = coreCodec; - self->harmonicSBR = harmonicSBR; - self->downscaleFactor = downscaleFactor; - - /* Init SBR elements */ - { - int elChannels, ch; - - if (self->pSbrElement[elementIndex] == NULL) { - self->pSbrElement[elementIndex] = GetRam_SbrDecElement(elementIndex); - if (self->pSbrElement[elementIndex] == NULL) { - sbrError = SBRDEC_MEM_ALLOC_FAILED; - goto bail; - } - self->numSbrElements++; - } else { - self->numSbrChannels -= self->pSbrElement[elementIndex]->nChannels; - } - - /* Save element ID for sanity checks and to have a fallback for concealment. - */ - self->pSbrElement[elementIndex]->elementID = elementID; - - /* Determine amount of channels for this element */ - switch (elementID) { - case ID_NONE: - case ID_CPE: - elChannels = 2; - break; - case ID_LFE: - case ID_SCE: - elChannels = 1; - break; - default: - elChannels = 0; - break; - } - - /* Handle case of Parametric Stereo */ - if (elementIndex == 0 && elementID == ID_SCE) { - switch (coreCodec) { - case AOT_AAC_LC: - case AOT_SBR: - case AOT_PS: - case AOT_ER_AAC_SCAL: - case AOT_DRM_AAC: - case AOT_DRM_SURROUND: - elChannels = 2; - break; - default: - break; - } - } - - /* Sanity check to avoid memory leaks */ - if (elChannels < self->pSbrElement[elementIndex]->nChannels) { - self->numSbrChannels += self->pSbrElement[elementIndex]->nChannels; - sbrError = SBRDEC_PARSE_ERROR; - goto bail; - } - - self->pSbrElement[elementIndex]->nChannels = elChannels; - - for (ch = 0; ch < elChannels; ch++) { - if (self->pSbrElement[elementIndex]->pSbrChannel[ch] == NULL) { - self->pSbrElement[elementIndex]->pSbrChannel[ch] = - GetRam_SbrDecChannel(chCnt); - if (self->pSbrElement[elementIndex]->pSbrChannel[ch] == NULL) { - sbrError = SBRDEC_MEM_ALLOC_FAILED; - goto bail; - } - } - self->numSbrChannels++; - - sbrDecoder_drcInitChannel(&self->pSbrElement[elementIndex] - ->pSbrChannel[ch] - ->SbrDec.sbrDrcChannel); - - chCnt++; - } - } - - if (!self->pQmfDomain->globalConf.qmfDomainExplicitConfig) { - self->pQmfDomain->globalConf.nInputChannels_requested = - self->numSbrChannels; - self->pQmfDomain->globalConf.nOutputChannels_requested = - fMax((INT)self->numSbrChannels, - (INT)self->pQmfDomain->globalConf.nOutputChannels_requested); - } - - /* Make sure each SBR channel has one QMF channel assigned even if - * numSbrChannels or element set-up has changed. */ - sbrDecoder_AssignQmfChannels2SbrChannels(self); - - /* clear error flags for all delay slots */ - FDKmemclear(self->pSbrElement[elementIndex]->frameErrorFlag, - ((1) + 1) * sizeof(UCHAR)); - - { - int overlap; - - if (coreCodec == AOT_ER_AAC_ELD) { - overlap = 0; - } else if (self->flags & SBRDEC_QUAD_RATE) { - overlap = (3 * 4); - } else { - overlap = (3 * 2); - } - /* Initialize this instance */ - sbrError = sbrDecoder_ResetElement(self, sampleRateIn, sampleRateOut, - samplesPerFrame, elementID, elementIndex, - overlap); - } - -bail: - if (sbrError != SBRDEC_OK) { - if ((nSbrElementsStart < self->numSbrElements) || - (nSbrChannelsStart < self->numSbrChannels)) { - /* Free the memory allocated for this element */ - sbrDecoder_DestroyElement(self, elementIndex); - } else if ((elementIndex < (8)) && - (self->pSbrElement[elementIndex] != - NULL)) { /* Set error flag to trigger concealment */ - setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_ERROR); - } - } - - return sbrError; -} - -/** - * \brief Free config dependent SBR memory. - * \param self SBR decoder instance handle - */ -SBR_ERROR sbrDecoder_FreeMem(HANDLE_SBRDECODER *self) { - int i; - int elIdx; - - if (self != NULL && *self != NULL) { - for (i = 0; i < (8); i++) { - sbrDecoder_DestroyElement(*self, i); - } - - for (elIdx = 0; elIdx < (8); elIdx += 1) { - for (i = 0; i < (1) + 1; i += 1) { - (*self)->sbrHeader[elIdx][i].syncState = SBR_NOT_INITIALIZED; - } - } - } - - return SBRDEC_OK; -} - -/** - * \brief Apply decoded SBR header for one element. - * \param self SBR decoder instance handle - * \param hSbrHeader SBR header handle to be processed. - * \param hSbrChannel pointer array to the SBR element channels corresponding to - * the SBR header. - * \param headerStatus header status value returned from SBR header parser. - * \param numElementChannels amount of channels for the SBR element whos header - * is to be processed. - */ -static SBR_ERROR sbrDecoder_HeaderUpdate(HANDLE_SBRDECODER self, - HANDLE_SBR_HEADER_DATA hSbrHeader, - SBR_HEADER_STATUS headerStatus, - HANDLE_SBR_CHANNEL hSbrChannel[], - const int numElementChannels) { - SBR_ERROR errorStatus = SBRDEC_OK; - - /* - change of control data, reset decoder - */ - errorStatus = resetFreqBandTables(hSbrHeader, self->flags); - - if (errorStatus == SBRDEC_OK) { - if (hSbrHeader->syncState == UPSAMPLING && headerStatus != HEADER_RESET) { -#if (SBRDEC_MAX_HB_FADE_FRAMES > 0) - int ch; - for (ch = 0; ch < numElementChannels; ch += 1) { - hSbrChannel[ch]->SbrDec.highBandFadeCnt = SBRDEC_MAX_HB_FADE_FRAMES; - } - -#endif - /* As the default header would limit the frequency range, - lowSubband and highSubband must be patched. */ - hSbrHeader->freqBandData.lowSubband = hSbrHeader->numberOfAnalysisBands; - hSbrHeader->freqBandData.highSubband = hSbrHeader->numberOfAnalysisBands; - } - - /* Trigger a reset before processing this slot */ - hSbrHeader->status |= SBRDEC_HDR_STAT_RESET; - } - - return errorStatus; -} - -INT sbrDecoder_Header(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, - const INT sampleRateIn, const INT sampleRateOut, - const INT samplesPerFrame, - const AUDIO_OBJECT_TYPE coreCodec, - const MP4_ELEMENT_ID elementID, const INT elementIndex, - const UCHAR harmonicSBR, const UCHAR stereoConfigIndex, - const UCHAR configMode, UCHAR *configChanged, - const INT downscaleFactor) { - SBR_HEADER_STATUS headerStatus; - HANDLE_SBR_HEADER_DATA hSbrHeader; - SBR_ERROR sbrError = SBRDEC_OK; - int headerIndex; - UINT flagsSaved = - 0; /* flags should not be changed in AC_CM_DET_CFG_CHANGE - mode after - parsing */ - - if (self == NULL || elementIndex >= (8)) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - - if (!sbrDecoder_isCoreCodecValid(coreCodec)) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - - if (configMode & AC_CM_DET_CFG_CHANGE) { - flagsSaved = self->flags; /* store */ - } - - sbrError = sbrDecoder_InitElement( - self, sampleRateIn, sampleRateOut, samplesPerFrame, coreCodec, elementID, - elementIndex, harmonicSBR, stereoConfigIndex, configMode, configChanged, - downscaleFactor); - - if ((sbrError != SBRDEC_OK) || (elementID == ID_LFE)) { - goto bail; - } - - if (configMode & AC_CM_DET_CFG_CHANGE) { - hSbrHeader = NULL; - } else { - headerIndex = getHeaderSlot(self->pSbrElement[elementIndex]->useFrameSlot, - self->pSbrElement[elementIndex]->useHeaderSlot); - - hSbrHeader = &(self->sbrHeader[elementIndex][headerIndex]); - } - - headerStatus = sbrGetHeaderData(hSbrHeader, hBs, self->flags, 0, configMode); - - if (coreCodec == AOT_USAC) { - if (configMode & AC_CM_DET_CFG_CHANGE) { - self->flags = flagsSaved; /* restore */ - } - return sbrError; - } - - if (configMode & AC_CM_ALLOC_MEM) { - SBR_DECODER_ELEMENT *pSbrElement; - - pSbrElement = self->pSbrElement[elementIndex]; - - /* Sanity check */ - if (pSbrElement != NULL) { - if ((elementID == ID_CPE && pSbrElement->nChannels != 2) || - (elementID != ID_CPE && pSbrElement->nChannels != 1)) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - if (headerStatus == HEADER_RESET) { - sbrError = sbrDecoder_HeaderUpdate(self, hSbrHeader, headerStatus, - pSbrElement->pSbrChannel, - pSbrElement->nChannels); - - if (sbrError == SBRDEC_OK) { - hSbrHeader->syncState = SBR_HEADER; - hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE; - } - /* else { - Since we already have overwritten the old SBR header the only way out - is UPSAMPLING! This will be prepared in the next step. - } */ - } - } - } -bail: - if (configMode & AC_CM_DET_CFG_CHANGE) { - self->flags = flagsSaved; /* restore */ - } - return sbrError; -} - -SBR_ERROR sbrDecoder_SetParam(HANDLE_SBRDECODER self, const SBRDEC_PARAM param, - const INT value) { - SBR_ERROR errorStatus = SBRDEC_OK; - - /* configure the subsystems */ - switch (param) { - case SBR_SYSTEM_BITSTREAM_DELAY: - if (value < 0 || value > (1)) { - errorStatus = SBRDEC_SET_PARAM_FAIL; - break; - } - if (self == NULL) { - errorStatus = SBRDEC_NOT_INITIALIZED; - } else { - self->numDelayFrames = (UCHAR)value; - } - break; - case SBR_QMF_MODE: - if (self == NULL) { - errorStatus = SBRDEC_NOT_INITIALIZED; - } else { - if (value == 1) { - self->flags |= SBRDEC_LOW_POWER; - } else { - self->flags &= ~SBRDEC_LOW_POWER; - } - } - break; - case SBR_LD_QMF_TIME_ALIGN: - if (self == NULL) { - errorStatus = SBRDEC_NOT_INITIALIZED; - } else { - if (value == 1) { - self->flags |= SBRDEC_LD_MPS_QMF; - } else { - self->flags &= ~SBRDEC_LD_MPS_QMF; - } - } - break; - case SBR_FLUSH_DATA: - if (value != 0) { - if (self == NULL) { - errorStatus = SBRDEC_NOT_INITIALIZED; - } else { - self->flags |= SBRDEC_FLUSH; - } - } - break; - case SBR_CLEAR_HISTORY: - if (value != 0) { - if (self == NULL) { - errorStatus = SBRDEC_NOT_INITIALIZED; - } else { - self->flags |= SBRDEC_FORCE_RESET; - } - } - break; - case SBR_BS_INTERRUPTION: { - int elementIndex; - - if (self == NULL) { - errorStatus = SBRDEC_NOT_INITIALIZED; - break; - } - - /* Loop over SBR elements */ - for (elementIndex = 0; elementIndex < self->numSbrElements; - elementIndex++) { - if (self->pSbrElement[elementIndex] != NULL) { - HANDLE_SBR_HEADER_DATA hSbrHeader; - int headerIndex = - getHeaderSlot(self->pSbrElement[elementIndex]->useFrameSlot, - self->pSbrElement[elementIndex]->useHeaderSlot); - - hSbrHeader = &(self->sbrHeader[elementIndex][headerIndex]); - - /* Set sync state UPSAMPLING for the corresponding slot. - This switches off bitstream parsing until a new header arrives. */ - hSbrHeader->syncState = UPSAMPLING; - hSbrHeader->status |= SBRDEC_HDR_STAT_UPDATE; - } - } - } break; - - case SBR_SKIP_QMF: - if (self == NULL) { - errorStatus = SBRDEC_NOT_INITIALIZED; - } else { - if (value == 1) { - self->flags |= SBRDEC_SKIP_QMF_ANA; - } else { - self->flags &= ~SBRDEC_SKIP_QMF_ANA; - } - if (value == 2) { - self->flags |= SBRDEC_SKIP_QMF_SYN; - } else { - self->flags &= ~SBRDEC_SKIP_QMF_SYN; - } - } - break; - default: - errorStatus = SBRDEC_SET_PARAM_FAIL; - break; - } /* switch(param) */ - - return (errorStatus); -} - -static SBRDEC_DRC_CHANNEL *sbrDecoder_drcGetChannel( - const HANDLE_SBRDECODER self, const INT channel) { - SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL; - int elementIndex, elChanIdx = 0, numCh = 0; - - for (elementIndex = 0; (elementIndex < (8)) && (numCh <= channel); - elementIndex++) { - SBR_DECODER_ELEMENT *pSbrElement = self->pSbrElement[elementIndex]; - int c, elChannels; - - elChanIdx = 0; - if (pSbrElement == NULL) break; - - /* Determine amount of channels for this element */ - switch (pSbrElement->elementID) { - case ID_CPE: - elChannels = 2; - break; - case ID_LFE: - case ID_SCE: - elChannels = 1; - break; - case ID_NONE: - default: - elChannels = 0; - break; - } - - /* Limit with actual allocated element channels */ - elChannels = fMin(elChannels, pSbrElement->nChannels); - - for (c = 0; (c < elChannels) && (numCh <= channel); c++) { - if (pSbrElement->pSbrChannel[elChanIdx] != NULL) { - numCh++; - elChanIdx++; - } - } - } - elementIndex -= 1; - elChanIdx -= 1; - - if (elChanIdx < 0 || elementIndex < 0) { - return NULL; - } - - if (self->pSbrElement[elementIndex] != NULL) { - if (self->pSbrElement[elementIndex]->pSbrChannel[elChanIdx] != NULL) { - pSbrDrcChannelData = &self->pSbrElement[elementIndex] - ->pSbrChannel[elChanIdx] - ->SbrDec.sbrDrcChannel; - } - } - - return (pSbrDrcChannelData); -} - -SBR_ERROR sbrDecoder_drcFeedChannel(HANDLE_SBRDECODER self, INT ch, - UINT numBands, FIXP_DBL *pNextFact_mag, - INT nextFact_exp, - SHORT drcInterpolationScheme, - UCHAR winSequence, USHORT *pBandTop) { - SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL; - int band, isValidData = 0; - - if (self == NULL) { - return SBRDEC_NOT_INITIALIZED; - } - if (ch > (8) || pNextFact_mag == NULL) { - return SBRDEC_SET_PARAM_FAIL; - } - - /* Search for gain values different to 1.0f */ - for (band = 0; band < (int)numBands; band += 1) { - if (!((pNextFact_mag[band] == FL2FXCONST_DBL(0.5)) && - (nextFact_exp == 1)) && - !((pNextFact_mag[band] == (FIXP_DBL)MAXVAL_DBL) && - (nextFact_exp == 0))) { - isValidData = 1; - break; - } - } - - /* Find the right SBR channel */ - pSbrDrcChannelData = sbrDecoder_drcGetChannel(self, ch); - - if (pSbrDrcChannelData != NULL) { - if (pSbrDrcChannelData->enable || - isValidData) { /* Activate processing only with real and valid data */ - int i; - - pSbrDrcChannelData->enable = 1; - pSbrDrcChannelData->numBandsNext = numBands; - - pSbrDrcChannelData->winSequenceNext = winSequence; - pSbrDrcChannelData->drcInterpolationSchemeNext = drcInterpolationScheme; - pSbrDrcChannelData->nextFact_exp = nextFact_exp; - - for (i = 0; i < (int)numBands; i++) { - pSbrDrcChannelData->bandTopNext[i] = pBandTop[i]; - pSbrDrcChannelData->nextFact_mag[i] = pNextFact_mag[i]; - } - } - } - - return SBRDEC_OK; -} - -void sbrDecoder_drcDisable(HANDLE_SBRDECODER self, INT ch) { - SBRDEC_DRC_CHANNEL *pSbrDrcChannelData = NULL; - - if ((self == NULL) || (ch > (8)) || (self->numSbrElements == 0) || - (self->numSbrChannels == 0)) { - return; - } - - /* Find the right SBR channel */ - pSbrDrcChannelData = sbrDecoder_drcGetChannel(self, ch); - - if (pSbrDrcChannelData != NULL) { - sbrDecoder_drcInitChannel(pSbrDrcChannelData); - } -} - -SBR_ERROR sbrDecoder_Parse(HANDLE_SBRDECODER self, HANDLE_FDK_BITSTREAM hBs, - UCHAR *pDrmBsBuffer, USHORT drmBsBufferSize, - int *count, int bsPayLen, int crcFlag, - MP4_ELEMENT_ID prevElement, int elementIndex, - UINT acFlags, UINT acElFlags[]) { - SBR_DECODER_ELEMENT *hSbrElement = NULL; - HANDLE_SBR_HEADER_DATA hSbrHeader = NULL; - HANDLE_SBR_CHANNEL *pSbrChannel; - - SBR_FRAME_DATA *hFrameDataLeft = NULL; - SBR_FRAME_DATA *hFrameDataRight = NULL; - SBR_FRAME_DATA frameDataLeftCopy; - SBR_FRAME_DATA frameDataRightCopy; - - SBR_ERROR errorStatus = SBRDEC_OK; - SBR_HEADER_STATUS headerStatus = HEADER_NOT_PRESENT; - - INT startPos = FDKgetValidBits(hBs); - INT CRCLen = 0; - HANDLE_FDK_BITSTREAM hBsOriginal = hBs; - FDK_BITSTREAM bsBwd; - - FDK_CRCINFO crcInfo; - INT crcReg = 0; - USHORT drmSbrCrc = 0; - const int fGlobalIndependencyFlag = acFlags & AC_INDEP; - const int bs_pvc = acElFlags[elementIndex] & AC_EL_USAC_PVC; - const int bs_interTes = acElFlags[elementIndex] & AC_EL_USAC_ITES; - int stereo; - int fDoDecodeSbrData = 1; - - int lastSlot, lastHdrSlot = 0, thisHdrSlot = 0; - - if (*count <= 0) { - setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_ERROR); - return SBRDEC_OK; - } - - /* SBR sanity checks */ - if (self == NULL) { - errorStatus = SBRDEC_NOT_INITIALIZED; - goto bail; - } - - /* Reverse bits of DRM SBR payload */ - if ((self->flags & SBRDEC_SYNTAX_DRM) && *count > 0) { - int dataBytes, dataBits; - - FDK_ASSERT(drmBsBufferSize >= (512)); - dataBits = *count; - - if (dataBits > ((512) * 8)) { - /* do not flip more data than needed */ - dataBits = (512) * 8; - } - - dataBytes = (dataBits + 7) >> 3; - - int j; - - if ((j = (int)FDKgetValidBits(hBs)) != 8) { - FDKpushBiDirectional(hBs, (j - 8)); - } - - j = 0; - for (; dataBytes > 0; dataBytes--) { - int i; - UCHAR tmpByte; - UCHAR buffer = 0x00; - - tmpByte = (UCHAR)FDKreadBits(hBs, 8); - for (i = 0; i < 4; i++) { - int shift = 2 * i + 1; - buffer |= (tmpByte & (0x08 >> i)) << shift; - buffer |= (tmpByte & (0x10 << i)) >> shift; - } - pDrmBsBuffer[j++] = buffer; - FDKpushBack(hBs, 16); - } - - FDKinitBitStream(&bsBwd, pDrmBsBuffer, (512), dataBits, BS_READER); - - /* Use reversed data */ - hBs = &bsBwd; - bsPayLen = *count; - } - - /* Remember start position of SBR element */ - startPos = FDKgetValidBits(hBs); - - /* SBR sanity checks */ - if (self->pSbrElement[elementIndex] == NULL) { - errorStatus = SBRDEC_NOT_INITIALIZED; - goto bail; - } - hSbrElement = self->pSbrElement[elementIndex]; - - lastSlot = (hSbrElement->useFrameSlot > 0) ? hSbrElement->useFrameSlot - 1 - : self->numDelayFrames; - lastHdrSlot = hSbrElement->useHeaderSlot[lastSlot]; - thisHdrSlot = getHeaderSlot( - hSbrElement->useFrameSlot, - hSbrElement->useHeaderSlot); /* Get a free header slot not used by - frames not processed yet. */ - - /* Assign the free slot to store a new header if there is one. */ - hSbrHeader = &self->sbrHeader[elementIndex][thisHdrSlot]; - - pSbrChannel = hSbrElement->pSbrChannel; - stereo = (hSbrElement->elementID == ID_CPE) ? 1 : 0; - - hFrameDataLeft = &self->pSbrElement[elementIndex] - ->pSbrChannel[0] - ->frameData[hSbrElement->useFrameSlot]; - if (stereo) { - hFrameDataRight = &self->pSbrElement[elementIndex] - ->pSbrChannel[1] - ->frameData[hSbrElement->useFrameSlot]; - } - - /* store frameData; new parsed frameData possibly corrupted */ - FDKmemcpy(&frameDataLeftCopy, hFrameDataLeft, sizeof(SBR_FRAME_DATA)); - if (stereo) { - FDKmemcpy(&frameDataRightCopy, hFrameDataRight, sizeof(SBR_FRAME_DATA)); - } - - /* reset PS flag; will be set after PS was found */ - self->flags &= ~SBRDEC_PS_DECODED; - - if (hSbrHeader->status & SBRDEC_HDR_STAT_UPDATE) { - /* Got a new header from extern (e.g. from an ASC) */ - headerStatus = HEADER_OK; - hSbrHeader->status &= ~SBRDEC_HDR_STAT_UPDATE; - } else if (thisHdrSlot != lastHdrSlot) { - /* Copy the last header into this slot otherwise the - header compare will trigger more HEADER_RESETs than needed. */ - copySbrHeader(hSbrHeader, &self->sbrHeader[elementIndex][lastHdrSlot]); - } - - /* - Check if bit stream data is valid and matches the element context - */ - if (((prevElement != ID_SCE) && (prevElement != ID_CPE)) || - prevElement != hSbrElement->elementID) { - /* In case of LFE we also land here, since there is no LFE SBR element (do - * upsampling only) */ - fDoDecodeSbrData = 0; - } - - if (fDoDecodeSbrData) { - if ((INT)FDKgetValidBits(hBs) <= 0) { - fDoDecodeSbrData = 0; - } - } - - /* - SBR CRC-check - */ - if (fDoDecodeSbrData) { - if (crcFlag) { - switch (self->coreCodec) { - case AOT_ER_AAC_ELD: - FDKpushFor(hBs, 10); - /* check sbrcrc later: we don't know the payload length now */ - break; - case AOT_DRM_AAC: - case AOT_DRM_SURROUND: - drmSbrCrc = (USHORT)FDKreadBits(hBs, 8); - /* Setup CRC decoder */ - FDKcrcInit(&crcInfo, 0x001d, 0xFFFF, 8); - /* Start CRC region */ - crcReg = FDKcrcStartReg(&crcInfo, hBs, 0); - break; - default: - CRCLen = bsPayLen - 10; /* change: 0 => i */ - if (CRCLen < 0) { - fDoDecodeSbrData = 0; - } else { - fDoDecodeSbrData = SbrCrcCheck(hBs, CRCLen); - } - break; - } - } - } /* if (fDoDecodeSbrData) */ - - /* - Read in the header data and issue a reset if change occured - */ - if (fDoDecodeSbrData) { - int sbrHeaderPresent; - - if (self->flags & (SBRDEC_SYNTAX_RSVD50 | SBRDEC_SYNTAX_USAC)) { - SBR_HEADER_DATA_BS_INFO newSbrInfo; - int sbrInfoPresent; - - if (bs_interTes) { - self->flags |= SBRDEC_USAC_ITES; - } else { - self->flags &= ~SBRDEC_USAC_ITES; - } - - if (fGlobalIndependencyFlag) { - self->flags |= SBRDEC_USAC_INDEP; - sbrInfoPresent = 1; - sbrHeaderPresent = 1; - } else { - self->flags &= ~SBRDEC_USAC_INDEP; - sbrInfoPresent = FDKreadBit(hBs); - if (sbrInfoPresent) { - sbrHeaderPresent = FDKreadBit(hBs); - } else { - sbrHeaderPresent = 0; - } - } - - if (sbrInfoPresent) { - newSbrInfo.ampResolution = FDKreadBit(hBs); - newSbrInfo.xover_band = FDKreadBits(hBs, 4); - newSbrInfo.sbr_preprocessing = FDKreadBit(hBs); - if (bs_pvc) { - newSbrInfo.pvc_mode = FDKreadBits(hBs, 2); - /* bs_pvc_mode: 0 -> no PVC, 1 -> PVC mode 1, 2 -> PVC mode 2, 3 -> - * reserved */ - if (newSbrInfo.pvc_mode > 2) { - headerStatus = HEADER_ERROR; - } - if (stereo && newSbrInfo.pvc_mode > 0) { - /* bs_pvc is always transmitted but pvc_mode is set to zero in case - * of stereo SBR. The config might be wrong but we cannot tell for - * sure. */ - newSbrInfo.pvc_mode = 0; - } - } else { - newSbrInfo.pvc_mode = 0; - } - if (headerStatus != HEADER_ERROR) { - if (FDKmemcmp(&hSbrHeader->bs_info, &newSbrInfo, - sizeof(SBR_HEADER_DATA_BS_INFO))) { - /* in case of ampResolution and preprocessing change no full reset - * required */ - /* HEADER reset would trigger HBE transposer reset which breaks - * eSbr_3_Eaa.mp4 */ - if ((hSbrHeader->bs_info.pvc_mode != newSbrInfo.pvc_mode) || - (hSbrHeader->bs_info.xover_band != newSbrInfo.xover_band)) { - headerStatus = HEADER_RESET; - } else { - headerStatus = HEADER_OK; - } - - hSbrHeader->bs_info = newSbrInfo; - } else { - headerStatus = HEADER_OK; - } - } - } - if (headerStatus == HEADER_ERROR) { - /* Corrupt SBR info data, do not decode and switch to UPSAMPLING */ - hSbrHeader->syncState = UPSAMPLING; - fDoDecodeSbrData = 0; - sbrHeaderPresent = 0; - } - - if (sbrHeaderPresent && fDoDecodeSbrData) { - int useDfltHeader; - - useDfltHeader = FDKreadBit(hBs); - - if (useDfltHeader) { - sbrHeaderPresent = 0; - if (FDKmemcmp(&hSbrHeader->bs_data, &hSbrHeader->bs_dflt, - sizeof(SBR_HEADER_DATA_BS)) || - hSbrHeader->syncState != SBR_ACTIVE) { - hSbrHeader->bs_data = hSbrHeader->bs_dflt; - headerStatus = HEADER_RESET; - } - } - } - } else { - sbrHeaderPresent = FDKreadBit(hBs); - } - - if (sbrHeaderPresent) { - headerStatus = sbrGetHeaderData(hSbrHeader, hBs, self->flags, 1, 0); - } - - if (headerStatus == HEADER_RESET) { - errorStatus = sbrDecoder_HeaderUpdate( - self, hSbrHeader, headerStatus, pSbrChannel, hSbrElement->nChannels); - - if (errorStatus == SBRDEC_OK) { - hSbrHeader->syncState = SBR_HEADER; - } else { - hSbrHeader->syncState = SBR_NOT_INITIALIZED; - headerStatus = HEADER_ERROR; - } - } - - if (errorStatus != SBRDEC_OK) { - fDoDecodeSbrData = 0; - } - } /* if (fDoDecodeSbrData) */ - - /* - Print debugging output only if state has changed - */ - - /* read frame data */ - if ((hSbrHeader->syncState >= SBR_HEADER) && fDoDecodeSbrData) { - int sbrFrameOk; - /* read the SBR element data */ - if (!stereo && (self->hParametricStereoDec != NULL)) { - /* update slot index for PS bitstream parsing */ - self->hParametricStereoDec->bsLastSlot = - self->hParametricStereoDec->bsReadSlot; - self->hParametricStereoDec->bsReadSlot = hSbrElement->useFrameSlot; - } - sbrFrameOk = sbrGetChannelElement( - hSbrHeader, hFrameDataLeft, (stereo) ? hFrameDataRight : NULL, - &pSbrChannel[0]->prevFrameData, - pSbrChannel[0]->SbrDec.PvcStaticData.pvc_mode_last, hBs, - (stereo) ? NULL : self->hParametricStereoDec, self->flags, - self->pSbrElement[elementIndex]->transposerSettings.overlap); - - if (!sbrFrameOk) { - fDoDecodeSbrData = 0; - } else { - INT valBits; - - if (bsPayLen > 0) { - valBits = bsPayLen - ((INT)startPos - (INT)FDKgetValidBits(hBs)); - } else { - valBits = (INT)FDKgetValidBits(hBs); - } - - if (crcFlag) { - switch (self->coreCodec) { - case AOT_ER_AAC_ELD: { - /* late crc check for eld */ - INT payloadbits = - (INT)startPos - (INT)FDKgetValidBits(hBs) - startPos; - INT crcLen = payloadbits - 10; - FDKpushBack(hBs, payloadbits); - fDoDecodeSbrData = SbrCrcCheck(hBs, crcLen); - FDKpushFor(hBs, crcLen); - } break; - case AOT_DRM_AAC: - case AOT_DRM_SURROUND: - /* End CRC region */ - FDKcrcEndReg(&crcInfo, hBs, crcReg); - /* Check CRC */ - if ((FDKcrcGetCRC(&crcInfo) ^ 0xFF) != drmSbrCrc) { - fDoDecodeSbrData = 0; - if (headerStatus != HEADER_NOT_PRESENT) { - headerStatus = HEADER_ERROR; - hSbrHeader->syncState = SBR_NOT_INITIALIZED; - } - } - break; - default: - break; - } - } - - /* sanity check of remaining bits */ - if (valBits < 0) { - fDoDecodeSbrData = 0; - } else { - switch (self->coreCodec) { - case AOT_SBR: - case AOT_PS: - case AOT_AAC_LC: { - /* This sanity check is only meaningful with General Audio - * bitstreams */ - int alignBits = valBits & 0x7; - - if (valBits > alignBits) { - fDoDecodeSbrData = 0; - } - } break; - default: - /* No sanity check available */ - break; - } - } - } - } else { - /* The returned bit count will not be the actual payload size since we did - not parse the frame data. Return an error so that the caller can react - respectively. */ - errorStatus = SBRDEC_PARSE_ERROR; - } - - if (!fDoDecodeSbrData) { - /* Set error flag for this slot to trigger concealment */ - setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_ERROR); - /* restore old frameData for concealment */ - FDKmemcpy(hFrameDataLeft, &frameDataLeftCopy, sizeof(SBR_FRAME_DATA)); - if (stereo) { - FDKmemcpy(hFrameDataRight, &frameDataRightCopy, sizeof(SBR_FRAME_DATA)); - } - errorStatus = SBRDEC_PARSE_ERROR; - } else { - /* Everything seems to be ok so clear the error flag */ - setFrameErrorFlag(self->pSbrElement[elementIndex], FRAME_OK); - } - - if (!stereo) { - /* Turn coupling off explicitely to avoid access to absent right frame data - that might occur with corrupt bitstreams. */ - hFrameDataLeft->coupling = COUPLING_OFF; - } - -bail: - - if (self != NULL) { - if (self->flags & SBRDEC_SYNTAX_DRM) { - hBs = hBsOriginal; - } - - if (errorStatus != SBRDEC_NOT_INITIALIZED) { - int useOldHdr = - ((headerStatus == HEADER_NOT_PRESENT) || - (headerStatus == HEADER_ERROR) || - (headerStatus == HEADER_RESET && errorStatus == SBRDEC_PARSE_ERROR)) - ? 1 - : 0; - - if (!useOldHdr && (thisHdrSlot != lastHdrSlot) && (hSbrHeader != NULL)) { - useOldHdr |= - (compareSbrHeader(hSbrHeader, - &self->sbrHeader[elementIndex][lastHdrSlot]) == 0) - ? 1 - : 0; - } - - if (hSbrElement != NULL) { - if (useOldHdr != 0) { - /* Use the old header for this frame */ - hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot] = lastHdrSlot; - } else { - /* Use the new header for this frame */ - hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot] = thisHdrSlot; - } - - /* Move frame pointer to the next slot which is up to be decoded/applied - * next */ - hSbrElement->useFrameSlot = - (hSbrElement->useFrameSlot + 1) % (self->numDelayFrames + 1); - } - } - } - - *count -= startPos - (INT)FDKgetValidBits(hBs); - - return errorStatus; -} - -/** - * \brief Render one SBR element into time domain signal. - * \param self SBR decoder handle - * \param timeData pointer to output buffer - * \param channelMapping pointer to UCHAR array where next 2 channel offsets are - * stored. - * \param elementIndex enumerating index of the SBR element to render. - * \param numInChannels number of channels from core coder. - * \param numOutChannels pointer to a location to return number of output - * channels. - * \param psPossible flag indicating if PS is possible or not. - * \return SBRDEC_OK if successfull, else error code - */ -static SBR_ERROR sbrDecoder_DecodeElement( - HANDLE_SBRDECODER self, QDOM_PCM *input, INT_PCM *timeData, - const int timeDataSize, const FDK_channelMapDescr *const mapDescr, - const int mapIdx, int channelIndex, const int elementIndex, - const int numInChannels, int *numOutChannels, const int psPossible) { - SBR_DECODER_ELEMENT *hSbrElement = self->pSbrElement[elementIndex]; - HANDLE_SBR_CHANNEL *pSbrChannel = - self->pSbrElement[elementIndex]->pSbrChannel; - HANDLE_SBR_HEADER_DATA hSbrHeader = - &self->sbrHeader[elementIndex] - [hSbrElement->useHeaderSlot[hSbrElement->useFrameSlot]]; - HANDLE_PS_DEC h_ps_d = self->hParametricStereoDec; - - /* get memory for frame data from scratch */ - SBR_FRAME_DATA *hFrameDataLeft = NULL; - SBR_FRAME_DATA *hFrameDataRight = NULL; - - SBR_ERROR errorStatus = SBRDEC_OK; - - INT strideOut, offset0 = 255, offset0_block = 0, offset1 = 255, - offset1_block = 0; - INT codecFrameSize = self->codecFrameSize; - - int stereo = (hSbrElement->elementID == ID_CPE) ? 1 : 0; - int numElementChannels = - hSbrElement - ->nChannels; /* Number of channels of the current SBR element */ - - hFrameDataLeft = - &hSbrElement->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot]; - if (stereo) { - hFrameDataRight = - &hSbrElement->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot]; - } - - if (self->flags & SBRDEC_FLUSH) { - if (self->numFlushedFrames > self->numDelayFrames) { - int hdrIdx; - /* No valid SBR payload available, hence switch to upsampling (in all - * headers) */ - for (hdrIdx = 0; hdrIdx < ((1) + 1); hdrIdx += 1) { - self->sbrHeader[elementIndex][hdrIdx].syncState = UPSAMPLING; - } - } else { - /* Move frame pointer to the next slot which is up to be decoded/applied - * next */ - hSbrElement->useFrameSlot = - (hSbrElement->useFrameSlot + 1) % (self->numDelayFrames + 1); - /* Update header and frame data pointer because they have already been set - */ - hSbrHeader = - &self->sbrHeader[elementIndex] - [hSbrElement - ->useHeaderSlot[hSbrElement->useFrameSlot]]; - hFrameDataLeft = - &hSbrElement->pSbrChannel[0]->frameData[hSbrElement->useFrameSlot]; - if (stereo) { - hFrameDataRight = - &hSbrElement->pSbrChannel[1]->frameData[hSbrElement->useFrameSlot]; - } - } - } - - /* Update the header error flag */ - hSbrHeader->frameErrorFlag = - hSbrElement->frameErrorFlag[hSbrElement->useFrameSlot]; - - /* - Prepare filterbank for upsampling if no valid bit stream data is available. - */ - if (hSbrHeader->syncState == SBR_NOT_INITIALIZED) { - errorStatus = - initHeaderData(hSbrHeader, self->sampleRateIn, self->sampleRateOut, - self->downscaleFactor, codecFrameSize, self->flags, - 1 /* SET_DEFAULT_HDR */ - ); - - if (errorStatus != SBRDEC_OK) { - return errorStatus; - } - - hSbrHeader->syncState = UPSAMPLING; - - errorStatus = sbrDecoder_HeaderUpdate(self, hSbrHeader, HEADER_NOT_PRESENT, - pSbrChannel, hSbrElement->nChannels); - - if (errorStatus != SBRDEC_OK) { - hSbrHeader->syncState = SBR_NOT_INITIALIZED; - return errorStatus; - } - } - - /* reset */ - if (hSbrHeader->status & SBRDEC_HDR_STAT_RESET) { - int ch; - int applySbrProc = (hSbrHeader->syncState == SBR_ACTIVE || - (hSbrHeader->frameErrorFlag == 0 && - hSbrHeader->syncState == SBR_HEADER)); - for (ch = 0; ch < numElementChannels; ch++) { - SBR_ERROR errorStatusTmp = SBRDEC_OK; - - errorStatusTmp = resetSbrDec( - &pSbrChannel[ch]->SbrDec, hSbrHeader, &pSbrChannel[ch]->prevFrameData, - self->synDownsampleFac, self->flags, pSbrChannel[ch]->frameData); - - if (errorStatusTmp != SBRDEC_OK) { - hSbrHeader->syncState = UPSAMPLING; - } - } - if (applySbrProc) { - hSbrHeader->status &= ~SBRDEC_HDR_STAT_RESET; - } - } - - /* decoding */ - if ((hSbrHeader->syncState == SBR_ACTIVE) || - ((hSbrHeader->syncState == SBR_HEADER) && - (hSbrHeader->frameErrorFlag == 0))) { - errorStatus = SBRDEC_OK; - - decodeSbrData(hSbrHeader, hFrameDataLeft, &pSbrChannel[0]->prevFrameData, - (stereo) ? hFrameDataRight : NULL, - (stereo) ? &pSbrChannel[1]->prevFrameData : NULL); - - /* Now we have a full parameter set and can do parameter - based concealment instead of plain upsampling. */ - hSbrHeader->syncState = SBR_ACTIVE; - } - - if (timeDataSize < - hSbrHeader->numberTimeSlots * hSbrHeader->timeStep * - self->pQmfDomain->globalConf.nBandsSynthesis * - (psPossible ? fMax(2, numInChannels) : numInChannels)) { - return SBRDEC_OUTPUT_BUFFER_TOO_SMALL; - } - - { - self->flags &= ~SBRDEC_PS_DECODED; - C_ALLOC_SCRATCH_START(pPsScratch, struct PS_DEC_COEFFICIENTS, 1) - - /* decode PS data if available */ - if (h_ps_d != NULL && psPossible && (hSbrHeader->syncState == SBR_ACTIVE)) { - int applyPs = 1; - - /* define which frame delay line slot to process */ - h_ps_d->processSlot = hSbrElement->useFrameSlot; - - applyPs = DecodePs(h_ps_d, hSbrHeader->frameErrorFlag, pPsScratch); - self->flags |= (applyPs) ? SBRDEC_PS_DECODED : 0; - } - - offset0 = FDK_chMapDescr_getMapValue(mapDescr, channelIndex, mapIdx); - offset0_block = offset0 * codecFrameSize; - if (stereo || psPossible) { - /* the value of offset1 only matters if the condition is true, however if - it is not true channelIndex+1 may exceed the channel map resutling in an - error, though the value of offset1 is actually meaningless. This is - prevented here. */ - offset1 = FDK_chMapDescr_getMapValue(mapDescr, channelIndex + 1, mapIdx); - offset1_block = offset1 * codecFrameSize; - } - /* Set strides for reading and writing */ - if (psPossible) - strideOut = (numInChannels < 2) ? 2 : numInChannels; - else - strideOut = numInChannels; - - /* use same buffers for left and right channel and apply PS per timeslot */ - /* Process left channel */ - sbr_dec(&pSbrChannel[0]->SbrDec, input + offset0_block, timeData + offset0, - (self->flags & SBRDEC_PS_DECODED) ? &pSbrChannel[1]->SbrDec : NULL, - timeData + offset1, strideOut, hSbrHeader, hFrameDataLeft, - &pSbrChannel[0]->prevFrameData, - (hSbrHeader->syncState == SBR_ACTIVE), h_ps_d, self->flags, - codecFrameSize); - - if (stereo) { - /* Process right channel */ - sbr_dec(&pSbrChannel[1]->SbrDec, input + offset1_block, - timeData + offset1, NULL, NULL, strideOut, hSbrHeader, - hFrameDataRight, &pSbrChannel[1]->prevFrameData, - (hSbrHeader->syncState == SBR_ACTIVE), NULL, self->flags, - codecFrameSize); - } - - C_ALLOC_SCRATCH_END(pPsScratch, struct PS_DEC_COEFFICIENTS, 1) - } - - if (h_ps_d != NULL) { - /* save PS status for next run */ - h_ps_d->psDecodedPrv = (self->flags & SBRDEC_PS_DECODED) ? 1 : 0; - } - - if (psPossible && !(self->flags & SBRDEC_SKIP_QMF_SYN)) { - FDK_ASSERT(strideOut > 1); - if (!(self->flags & SBRDEC_PS_DECODED)) { - /* A decoder which is able to decode PS has to produce a stereo output - * even if no PS data is available. */ - /* So copy left channel to right channel. */ - int copyFrameSize = - codecFrameSize * self->pQmfDomain->QmfDomainOut->fb.no_channels; - copyFrameSize /= self->pQmfDomain->QmfDomainIn->fb.no_channels; - INT_PCM *ptr; - INT i; - FDK_ASSERT(strideOut == 2); - - ptr = timeData; - for (i = copyFrameSize >> 1; i--;) { - INT_PCM tmp; /* This temporal variable is required because some - compilers can't do *ptr++ = *ptr++ correctly. */ - tmp = *ptr++; - *ptr++ = tmp; - tmp = *ptr++; - *ptr++ = tmp; - } - } - *numOutChannels = 2; /* Output minimum two channels when PS is enabled. */ - } - - return errorStatus; -} - -SBR_ERROR sbrDecoder_Apply(HANDLE_SBRDECODER self, INT_PCM *input, - INT_PCM *timeData, const int timeDataSize, - int *numChannels, int *sampleRate, - const FDK_channelMapDescr *const mapDescr, - const int mapIdx, const int coreDecodedOk, - UCHAR *psDecoded) { - SBR_ERROR errorStatus = SBRDEC_OK; - - int psPossible; - int sbrElementNum; - int numCoreChannels; - int numSbrChannels = 0; - - if ((self == NULL) || (timeData == NULL) || (numChannels == NULL) || - (sampleRate == NULL) || (psDecoded == NULL) || - !FDK_chMapDescr_isValid(mapDescr)) { - return SBRDEC_INVALID_ARGUMENT; - } - - psPossible = *psDecoded; - numCoreChannels = *numChannels; - if (numCoreChannels <= 0) { - return SBRDEC_INVALID_ARGUMENT; - } - - if (self->numSbrElements < 1) { - /* exit immediately to avoid access violations */ - return SBRDEC_NOT_INITIALIZED; - } - - /* Sanity check of allocated SBR elements. */ - for (sbrElementNum = 0; sbrElementNum < self->numSbrElements; - sbrElementNum++) { - if (self->pSbrElement[sbrElementNum] == NULL) { - return SBRDEC_NOT_INITIALIZED; - } - } - - if (self->numSbrElements != 1 || self->pSbrElement[0]->elementID != ID_SCE) { - psPossible = 0; - } - - /* Make sure that even if no SBR data was found/parsed *psDecoded is returned - * 1 if psPossible was 0. */ - if (psPossible == 0) { - self->flags &= ~SBRDEC_PS_DECODED; - } - - /* replaces channel based reset inside sbr_dec() */ - if (((self->flags & SBRDEC_LOW_POWER) ? 1 : 0) != - ((self->pQmfDomain->globalConf.flags & QMF_FLAG_LP) ? 1 : 0)) { - if (self->flags & SBRDEC_LOW_POWER) { - self->pQmfDomain->globalConf.flags |= QMF_FLAG_LP; - self->pQmfDomain->globalConf.flags_requested |= QMF_FLAG_LP; - } else { - self->pQmfDomain->globalConf.flags &= ~QMF_FLAG_LP; - self->pQmfDomain->globalConf.flags_requested &= ~QMF_FLAG_LP; - } - if (FDK_QmfDomain_InitFilterBank(self->pQmfDomain, QMF_FLAG_KEEP_STATES)) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - } - if (self->numSbrChannels > self->pQmfDomain->globalConf.nInputChannels) { - return SBRDEC_UNSUPPORTED_CONFIG; - } - - if (self->flags & SBRDEC_FLUSH) { - /* flushing is signalized, hence increment the flush frame counter */ - self->numFlushedFrames++; - } else { - /* no flushing is signalized, hence reset the flush frame counter */ - self->numFlushedFrames = 0; - } - - /* Loop over SBR elements */ - for (sbrElementNum = 0; sbrElementNum < self->numSbrElements; - sbrElementNum++) { - int numElementChan; - - if (psPossible && - self->pSbrElement[sbrElementNum]->pSbrChannel[1] == NULL) { - /* Disable PS and try decoding SBR mono. */ - psPossible = 0; - } - - numElementChan = - (self->pSbrElement[sbrElementNum]->elementID == ID_CPE) ? 2 : 1; - - /* If core signal is bad then force upsampling */ - if (!coreDecodedOk) { - setFrameErrorFlag(self->pSbrElement[sbrElementNum], FRAME_ERROR_ALLSLOTS); - } - - errorStatus = sbrDecoder_DecodeElement( - self, input, timeData, timeDataSize, mapDescr, mapIdx, numSbrChannels, - sbrElementNum, - numCoreChannels, /* is correct even for USC SCI==2 case */ - &numElementChan, psPossible); - - if (errorStatus != SBRDEC_OK) { - goto bail; - } - - numSbrChannels += numElementChan; - - if (numSbrChannels >= numCoreChannels) { - break; - } - } - - /* Update numChannels and samplerate */ - /* Do not mess with output channels in case of USAC. numSbrChannels != - * numChannels for stereoConfigIndex == 2 */ - if (!(self->flags & SBRDEC_SYNTAX_USAC)) { - *numChannels = numSbrChannels; - } - *sampleRate = self->sampleRateOut; - *psDecoded = (self->flags & SBRDEC_PS_DECODED) ? 1 : 0; - - /* Clear reset and flush flag because everything seems to be done - * successfully. */ - self->flags &= ~SBRDEC_FORCE_RESET; - self->flags &= ~SBRDEC_FLUSH; - -bail: - - return errorStatus; -} - -SBR_ERROR sbrDecoder_Close(HANDLE_SBRDECODER *pSelf) { - HANDLE_SBRDECODER self = *pSelf; - int i; - - if (self != NULL) { - if (self->hParametricStereoDec != NULL) { - DeletePsDec(&self->hParametricStereoDec); - } - - for (i = 0; i < (8); i++) { - sbrDecoder_DestroyElement(self, i); - } - - FreeRam_SbrDecoder(pSelf); - } - - return SBRDEC_OK; -} - -INT sbrDecoder_GetLibInfo(LIB_INFO *info) { - int i; - - if (info == NULL) { - return -1; - } - - /* search for next free tab */ - for (i = 0; i < FDK_MODULE_LAST; i++) { - if (info[i].module_id == FDK_NONE) break; - } - if (i == FDK_MODULE_LAST) return -1; - info += i; - - info->module_id = FDK_SBRDEC; - info->version = - LIB_VERSION(SBRDECODER_LIB_VL0, SBRDECODER_LIB_VL1, SBRDECODER_LIB_VL2); - LIB_VERSION_STRING(info); - info->build_date = SBRDECODER_LIB_BUILD_DATE; - info->build_time = SBRDECODER_LIB_BUILD_TIME; - info->title = SBRDECODER_LIB_TITLE; - - /* Set flags */ - info->flags = 0 | CAPF_SBR_HQ | CAPF_SBR_LP | CAPF_SBR_PS_MPEG | - CAPF_SBR_DRM_BS | CAPF_SBR_CONCEALMENT | CAPF_SBR_DRC | - CAPF_SBR_ELD_DOWNSCALE | CAPF_SBR_HBEHQ; - /* End of flags */ - - return 0; -} - -UINT sbrDecoder_GetDelay(const HANDLE_SBRDECODER self) { - UINT outputDelay = 0; - - if (self != NULL) { - UINT flags = self->flags; - - /* See chapter 1.6.7.2 of ISO/IEC 14496-3 for the GA-SBR figures below. */ - - /* Are we initialized? */ - if ((self->numSbrChannels > 0) && (self->numSbrElements > 0)) { - /* Add QMF synthesis delay */ - if ((flags & SBRDEC_ELD_GRID) && IS_LOWDELAY(self->coreCodec)) { - /* Low delay SBR: */ - if (!(flags & SBRDEC_SKIP_QMF_SYN)) { - outputDelay += - (flags & SBRDEC_DOWNSAMPLE) ? 32 : 64; /* QMF synthesis */ - if (flags & SBRDEC_LD_MPS_QMF) { - outputDelay += 32; - } - } - } else if (!IS_USAC(self->coreCodec)) { - /* By the method of elimination this is the GA (AAC-LC, HE-AAC, ...) - * branch: */ - outputDelay += (flags & SBRDEC_DOWNSAMPLE) ? 481 : 962; - if (flags & SBRDEC_SKIP_QMF_SYN) { - outputDelay -= 257; /* QMF synthesis */ - } - } - } - } - - return (outputDelay); -} --- a/libSBRdec/src/transcendent.h +++ /dev/null @@ -1,372 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR decoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief FDK Fixed Point Arithmetic Library Interface -*/ - -#ifndef TRANSCENDENT_H -#define TRANSCENDENT_H - -#include "sbrdecoder.h" -#include "sbr_rom.h" - -/************************************************************************/ -/*! - \brief Get number of octaves between frequencies a and b - - The Result is scaled with 1/8. - The valid range for a and b is 1 to LOG_DUALIS_TABLE_SIZE. - - \return ld(a/b) / 8 -*/ -/************************************************************************/ -static inline FIXP_SGL FDK_getNumOctavesDiv8(INT a, /*!< lower band */ - INT b) /*!< upper band */ -{ - return ((SHORT)((LONG)(CalcLdInt(b) - CalcLdInt(a)) >> (FRACT_BITS - 3))); -} - -/************************************************************************/ -/*! - \brief Add two values given by mantissa and exponent. - - Mantissas are in fract format with values between 0 and 1.
- The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$
-*/ -/************************************************************************/ -inline void FDK_add_MantExp(FIXP_SGL a_m, /*!< Mantissa of 1st operand a */ - SCHAR a_e, /*!< Exponent of 1st operand a */ - FIXP_SGL b_m, /*!< Mantissa of 2nd operand b */ - SCHAR b_e, /*!< Exponent of 2nd operand b */ - FIXP_SGL *ptrSum_m, /*!< Mantissa of result */ - SCHAR *ptrSum_e) /*!< Exponent of result */ -{ - FIXP_DBL accu; - int shift; - int shiftAbs; - - FIXP_DBL shiftedMantissa; - FIXP_DBL otherMantissa; - - /* Equalize exponents of the summands. - For the smaller summand, the exponent is adapted and - for compensation, the mantissa is shifted right. */ - - shift = (int)(a_e - b_e); - - shiftAbs = (shift > 0) ? shift : -shift; - shiftAbs = (shiftAbs < DFRACT_BITS - 1) ? shiftAbs : DFRACT_BITS - 1; - shiftedMantissa = (shift > 0) ? (FX_SGL2FX_DBL(b_m) >> shiftAbs) - : (FX_SGL2FX_DBL(a_m) >> shiftAbs); - otherMantissa = (shift > 0) ? FX_SGL2FX_DBL(a_m) : FX_SGL2FX_DBL(b_m); - *ptrSum_e = (shift > 0) ? a_e : b_e; - - accu = (shiftedMantissa >> 1) + (otherMantissa >> 1); - /* shift by 1 bit to avoid overflow */ - - if ((accu >= (FL2FXCONST_DBL(0.5f) - (FIXP_DBL)1)) || - (accu <= FL2FXCONST_DBL(-0.5f))) - *ptrSum_e += 1; - else - accu = (shiftedMantissa + otherMantissa); - - *ptrSum_m = FX_DBL2FX_SGL(accu); -} - -inline void FDK_add_MantExp(FIXP_DBL a, /*!< Mantissa of 1st operand a */ - SCHAR a_e, /*!< Exponent of 1st operand a */ - FIXP_DBL b, /*!< Mantissa of 2nd operand b */ - SCHAR b_e, /*!< Exponent of 2nd operand b */ - FIXP_DBL *ptrSum, /*!< Mantissa of result */ - SCHAR *ptrSum_e) /*!< Exponent of result */ -{ - FIXP_DBL accu; - int shift; - int shiftAbs; - - FIXP_DBL shiftedMantissa; - FIXP_DBL otherMantissa; - - /* Equalize exponents of the summands. - For the smaller summand, the exponent is adapted and - for compensation, the mantissa is shifted right. */ - - shift = (int)(a_e - b_e); - - shiftAbs = (shift > 0) ? shift : -shift; - shiftAbs = (shiftAbs < DFRACT_BITS - 1) ? shiftAbs : DFRACT_BITS - 1; - shiftedMantissa = (shift > 0) ? (b >> shiftAbs) : (a >> shiftAbs); - otherMantissa = (shift > 0) ? a : b; - *ptrSum_e = (shift > 0) ? a_e : b_e; - - accu = (shiftedMantissa >> 1) + (otherMantissa >> 1); - /* shift by 1 bit to avoid overflow */ - - if ((accu >= (FL2FXCONST_DBL(0.5f) - (FIXP_DBL)1)) || - (accu <= FL2FXCONST_DBL(-0.5f))) - *ptrSum_e += 1; - else - accu = (shiftedMantissa + otherMantissa); - - *ptrSum = accu; -} - -/************************************************************************/ -/*! - \brief Divide two values given by mantissa and exponent. - - Mantissas are in fract format with values between 0 and 1.
- The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$
- - For performance reasons, the division is based on a table lookup - which limits accuracy. -*/ -/************************************************************************/ -static inline void FDK_divide_MantExp( - FIXP_SGL a_m, /*!< Mantissa of dividend a */ - SCHAR a_e, /*!< Exponent of dividend a */ - FIXP_SGL b_m, /*!< Mantissa of divisor b */ - SCHAR b_e, /*!< Exponent of divisor b */ - FIXP_SGL *ptrResult_m, /*!< Mantissa of quotient a/b */ - SCHAR *ptrResult_e) /*!< Exponent of quotient a/b */ - -{ - int preShift, postShift, index, shift; - FIXP_DBL ratio_m; - FIXP_SGL bInv_m = FL2FXCONST_SGL(0.0f); - - preShift = CntLeadingZeros(FX_SGL2FX_DBL(b_m)); - - /* - Shift b into the range from 0..INV_TABLE_SIZE-1, - - E.g. 10 bits must be skipped for INV_TABLE_BITS 8: - - leave 8 bits as index for table - - skip sign bit, - - skip first bit of mantissa, because this is always the same (>0.5) - - We are dealing with energies, so we need not care - about negative numbers - */ - - /* - The first interval has half width so the lowest bit of the index is - needed for a doubled resolution. - */ - shift = (FRACT_BITS - 2 - INV_TABLE_BITS - preShift); - - index = (shift < 0) ? (LONG)b_m << (-shift) : (LONG)b_m >> shift; - - /* The index has INV_TABLE_BITS +1 valid bits here. Clear the other bits. */ - index &= (1 << (INV_TABLE_BITS + 1)) - 1; - - /* Remove offset of half an interval */ - index--; - - /* Now the lowest bit is shifted out */ - index = index >> 1; - - /* Fetch inversed mantissa from table: */ - bInv_m = (index < 0) ? bInv_m : FDK_sbrDecoder_invTable[index]; - - /* Multiply a with the inverse of b: */ - ratio_m = (index < 0) ? FX_SGL2FX_DBL(a_m >> 1) : fMultDiv2(bInv_m, a_m); - - postShift = CntLeadingZeros(ratio_m) - 1; - - *ptrResult_m = FX_DBL2FX_SGL(ratio_m << postShift); - *ptrResult_e = a_e - b_e + 1 + preShift - postShift; -} - -static inline void FDK_divide_MantExp( - FIXP_DBL a_m, /*!< Mantissa of dividend a */ - SCHAR a_e, /*!< Exponent of dividend a */ - FIXP_DBL b_m, /*!< Mantissa of divisor b */ - SCHAR b_e, /*!< Exponent of divisor b */ - FIXP_DBL *ptrResult_m, /*!< Mantissa of quotient a/b */ - SCHAR *ptrResult_e) /*!< Exponent of quotient a/b */ - -{ - int preShift, postShift, index, shift; - FIXP_DBL ratio_m; - FIXP_SGL bInv_m = FL2FXCONST_SGL(0.0f); - - preShift = CntLeadingZeros(b_m); - - /* - Shift b into the range from 0..INV_TABLE_SIZE-1, - - E.g. 10 bits must be skipped for INV_TABLE_BITS 8: - - leave 8 bits as index for table - - skip sign bit, - - skip first bit of mantissa, because this is always the same (>0.5) - - We are dealing with energies, so we need not care - about negative numbers - */ - - /* - The first interval has half width so the lowest bit of the index is - needed for a doubled resolution. - */ - shift = (DFRACT_BITS - 2 - INV_TABLE_BITS - preShift); - - index = (shift < 0) ? (LONG)b_m << (-shift) : (LONG)b_m >> shift; - - /* The index has INV_TABLE_BITS +1 valid bits here. Clear the other bits. */ - index &= (1 << (INV_TABLE_BITS + 1)) - 1; - - /* Remove offset of half an interval */ - index--; - - /* Now the lowest bit is shifted out */ - index = index >> 1; - - /* Fetch inversed mantissa from table: */ - bInv_m = (index < 0) ? bInv_m : FDK_sbrDecoder_invTable[index]; - - /* Multiply a with the inverse of b: */ - ratio_m = (index < 0) ? (a_m >> 1) : fMultDiv2(bInv_m, a_m); - - postShift = CntLeadingZeros(ratio_m) - 1; - - *ptrResult_m = ratio_m << postShift; - *ptrResult_e = a_e - b_e + 1 + preShift - postShift; -} - -/*! - \brief Calculate the squareroot of a number given by mantissa and exponent - - Mantissa is in fract format with values between 0 and 1.
- The base for the exponent is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$
- The operand is addressed via pointers and will be overwritten with the result. - - For performance reasons, the square root is based on a table lookup - which limits accuracy. -*/ -static inline void FDK_sqrt_MantExp( - FIXP_DBL *mantissa, /*!< Pointer to mantissa */ - SCHAR *exponent, const SCHAR *destScale) { - FIXP_DBL input_m = *mantissa; - int input_e = (int)*exponent; - FIXP_DBL result = FL2FXCONST_DBL(0.0f); - int result_e = -FRACT_BITS; - - /* Call lookup square root, which does internally normalization. */ - result = sqrtFixp_lookup(input_m, &input_e); - result_e = input_e; - - /* Write result */ - if (exponent == destScale) { - *mantissa = result; - *exponent = result_e; - } else { - int shift = result_e - *destScale; - *mantissa = (shift >= 0) ? result << (INT)fixMin(DFRACT_BITS - 1, shift) - : result >> (INT)fixMin(DFRACT_BITS - 1, -shift); - *exponent = *destScale; - } -} - -#endif --- a/libSBRenc/include/sbr_encoder.h +++ /dev/null @@ -1,483 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: SBR encoder top level processing prototype - -*******************************************************************************/ - -#ifndef SBR_ENCODER_H -#define SBR_ENCODER_H - -#include "common_fix.h" -#include "FDK_audio.h" - -#include "FDK_bitstream.h" - -/* core coder helpers */ -#define MAX_TRANS_FAC 8 -#define MAX_CODEC_FRAME_RATIO 2 -#define MAX_PAYLOAD_SIZE 256 - -typedef enum codecType { - CODEC_AAC = 0, - CODEC_AACLD = 1, - CODEC_UNSPECIFIED = 99 -} CODEC_TYPE; - -typedef struct { - INT bitRate; - INT nChannels; - INT sampleFreq; - INT transFac; - INT standardBitrate; -} CODEC_PARAM; - -typedef enum { - SBR_MONO, - SBR_LEFT_RIGHT, - SBR_COUPLING, - SBR_SWITCH_LRC -} SBR_STEREO_MODE; - -/* bitstream syntax flags */ -enum { - SBR_SYNTAX_LOW_DELAY = 0x0001, - SBR_SYNTAX_SCALABLE = 0x0002, - SBR_SYNTAX_CRC = 0x0004, - SBR_SYNTAX_DRM_CRC = 0x0008, - SBR_SYNTAX_ELD_REDUCED_DELAY = 0x0010 -}; - -typedef enum { FREQ_RES_LOW = 0, FREQ_RES_HIGH } FREQ_RES; - -typedef struct { - CODEC_TYPE coreCoder; /*!< LC or ELD */ - UINT bitrateFrom; /*!< inclusive */ - UINT bitrateTo; /*!< exclusive */ - - UINT sampleRate; /*!< */ - UCHAR numChannels; /*!< */ - - UCHAR startFreq; /*!< bs_start_freq */ - UCHAR startFreqSpeech; /*!< bs_start_freq for speech config flag */ - UCHAR stopFreq; /*!< bs_stop_freq */ - UCHAR stopFreqSpeech; /*!< bs_stop_freq for speech config flag */ - - UCHAR numNoiseBands; /*!< */ - UCHAR noiseFloorOffset; /*!< */ - SCHAR noiseMaxLevel; /*!< */ - SBR_STEREO_MODE stereoMode; /*!< */ - UCHAR freqScale; /*!< */ -} sbrTuningTable_t; - -typedef struct sbrConfiguration { - /* - core coder dependent configurations - */ - CODEC_PARAM - codecSettings; /*!< Core coder settings. To be set from core coder. */ - INT SendHeaderDataTime; /*!< SBR header send update frequency in ms. */ - INT useWaveCoding; /*!< Flag: usage of wavecoding tool. */ - INT crcSbr; /*!< Flag: usage of SBR-CRC. */ - INT dynBwSupported; /*!< Flag: support for dynamic bandwidth in this - combination. */ - INT parametricCoding; /*!< Flag: usage of parametric coding tool. */ - INT downSampleFactor; /*!< Sampling rate relation between the SBR and the core - encoder. */ - FREQ_RES freq_res_fixfix[2]; /*!< Frequency resolution of envelopes in frame - class FIXFIX, for non-split case and split - case */ - UCHAR fResTransIsLow; /*!< Frequency resolution of envelopes in transient - frames: low (0) or variable (1) */ - - /* - core coder dependent tuning parameters - */ - INT tran_thr; /*!< SBR transient detector threshold (* 100). */ - INT noiseFloorOffset; /*!< Noise floor offset. */ - UINT useSpeechConfig; /*!< Flag: adapt tuning parameters according to speech. - */ - - /* - core coder independent configurations - */ - INT sbrFrameSize; /*!< SBR frame size in samples. Will be calculated from core - coder settings. */ - INT sbr_data_extra; /*!< Flag usage of data extra. */ - INT amp_res; /*!< Amplitude resolution. */ - INT ana_max_level; /*!< Noise insertion maximum level. */ - INT tran_fc; /*!< Transient detector start frequency. */ - INT tran_det_mode; /*!< Transient detector mode. */ - INT spread; /*!< Flag: usage of SBR spread. */ - INT stat; /*!< Flag: usage of static framing. */ - INT e; /*!< Number of envelopes when static framing is chosen. */ - SBR_STEREO_MODE stereoMode; /*!< SBR stereo mode. */ - INT deltaTAcrossFrames; /*!< Flag: allow time-delta coding. */ - FIXP_DBL dF_edge_1stEnv; /*!< Extra fraction delta-F coding is allowed to be - more expensive. */ - FIXP_DBL dF_edge_incr; /*!< Increment dF_edge_1stEnv this much if dT-coding - was used this frame. */ - INT sbr_invf_mode; /*!< Inverse filtering mode. */ - INT sbr_xpos_mode; /*!< Transposer mode. */ - INT sbr_xpos_ctrl; /*!< Transposer control. */ - INT sbr_xpos_level; /*!< Transposer 3rd order level. */ - INT startFreq; /*!< The start frequency table index. */ - INT stopFreq; /*!< The stop frequency table index. */ - INT useSaPan; /*!< Flag: usage of SAPAN stereo. */ - INT dynBwEnabled; /*!< Flag: usage of dynamic bandwidth. */ - INT bParametricStereo; /*!< Flag: usage of parametric stereo coding tool. */ - - /* - header_extra1 configuration - */ - UCHAR freqScale; /*!< Frequency grouping. */ - INT alterScale; /*!< Scale resolution. */ - INT sbr_noise_bands; /*!< Number of noise bands. */ - - /* - header_extra2 configuration - */ - INT sbr_limiter_bands; /*!< Number of limiter bands. */ - INT sbr_limiter_gains; /*!< Gain of limiter. */ - INT sbr_interpol_freq; /*!< Flag: use interpolation in freq. direction. */ - INT sbr_smoothing_length; /*!< Flag: choose length 4 or 0 (=on, off). */ - UCHAR init_amp_res_FF; - FIXP_DBL threshold_AmpRes_FF_m; - SCHAR threshold_AmpRes_FF_e; -} sbrConfiguration, *sbrConfigurationPtr; - -typedef struct SBR_CONFIG_DATA { - UINT sbrSyntaxFlags; /**< SBR syntax flags derived from AOT. */ - INT nChannels; /**< Number of channels. */ - - INT nSfb[2]; /**< Number of SBR scalefactor bands for LO_RES and HI_RES (?) */ - INT num_Master; /**< Number of elements in v_k_master. */ - INT sampleFreq; /**< SBR sampling frequency. */ - INT frameSize; - INT xOverFreq; /**< The SBR start frequency. */ - INT dynXOverFreq; /**< Used crossover frequency when dynamic bandwidth is - enabled. */ - - INT noQmfBands; /**< Number of QMF frequency bands. */ - INT noQmfSlots; /**< Number of QMF slots. */ - - UCHAR *freqBandTable[2]; /**< Frequency table for low and hires, only - MAX_FREQ_COEFFS/2 +1 coeffs actually needed for - lowres. */ - UCHAR - *v_k_master; /**< Master BandTable where freqBandTable is derived from. */ - - SBR_STEREO_MODE stereoMode; - INT noEnvChannels; /**< Number of envelope channels. */ - - INT useWaveCoding; /**< Flag indicates whether to use wave coding at all. */ - INT useParametricCoding; /**< Flag indicates whether to use para coding at - all. */ - INT xposCtrlSwitch; /**< Flag indicates whether to switch xpos ctrl on the - fly. */ - INT switchTransposers; /**< Flag indicates whether to switch xpos on the fly . - */ - UCHAR initAmpResFF; - FIXP_DBL thresholdAmpResFF_m; - SCHAR thresholdAmpResFF_e; -} SBR_CONFIG_DATA, *HANDLE_SBR_CONFIG_DATA; - -typedef struct { - MP4_ELEMENT_ID elType; - INT bitRate; - int instanceTag; - UCHAR fParametricStereo; - UCHAR fDualMono; /**< This flags allows to disable coupling in sbr channel - pair element */ - UCHAR nChannelsInEl; - UCHAR ChannelIndex[2]; -} SBR_ELEMENT_INFO; - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct SBR_ENCODER *HANDLE_SBR_ENCODER; - -/** - * \brief Get the max required input buffer size including delay balancing - * space for N audio channels. - * \param noChannels Number of audio channels. - * \return Max required input buffer size in bytes. - */ -INT sbrEncoder_GetInBufferSize(int noChannels); - -INT sbrEncoder_Open(HANDLE_SBR_ENCODER *phSbrEncoder, INT nElements, - INT nChannels, INT supportPS); - -/** - * \brief Get closest working bitrate to specified desired - * bitrate for a single SBR element. - * \param bitRate The desired target bit rate - * \param numChannels The amount of audio channels - * \param coreSampleRate The sample rate of the core coder - * \param aot The current Audio Object Type - * \return Closest working bit rate to bitRate value - */ -UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, - UINT coreSampleRate, AUDIO_OBJECT_TYPE aot); - -/** - * \brief Check whether downsampled SBR single rate is possible - * with given audio object type. - * \param aot The Audio object type. - * \return 0 when downsampled SBR is not possible, - * 1 when downsampled SBR is possible. - */ -UINT sbrEncoder_IsSingleRatePossible(AUDIO_OBJECT_TYPE aot); - -/** - * \brief Initialize SBR Encoder instance. - * \param phSbrEncoder Pointer to a SBR Encoder instance. - * \param elInfo Structure that describes the element/channel - * arrangement. - * \param noElements Amount of elements described in elInfo. - * \param inputBuffer Pointer to the encoder audio buffer - * \param inputBufferBufSize Buffer offset of one channel (frameSize + delay) - * \param bandwidth Returns the core audio encoder bandwidth (output) - * \param bufferOffset Returns the offset for the audio input data in order - * to do delay balancing. - * \param numChannels Input: Encoder input channels. output: core encoder - * channels. - * \param sampleRate Input: Encoder samplerate. output core encoder - * samplerate. - * \param downSampleFactor Input: Relation between SBR and core coder sampling - * rate; - * \param frameLength Input: Encoder frameLength. output core encoder - * frameLength. - * \param aot Input: AOT.. - * \param delay Input: core encoder delay. Output: total delay - * because of SBR. - * \param transformFactor The core encoder transform factor (blockswitching). - * \param headerPeriod Repetition rate of the SBR header: - * - (-1) means intern configuration. - * - (1-10) corresponds to header repetition rate in - * frames. - * \return 0 on success, and non-zero if failed. - */ -INT sbrEncoder_Init(HANDLE_SBR_ENCODER hSbrEncoder, - SBR_ELEMENT_INFO elInfo[(8)], int noElements, - INT_PCM *inputBuffer, UINT inputBufferBufSize, - INT *coreBandwidth, INT *inputBufferOffset, - INT *numChannels, const UINT syntaxFlags, INT *sampleRate, - UINT *downSampleFactor, INT *frameLength, - AUDIO_OBJECT_TYPE aot, int *delay, int transformFactor, - const int headerPeriod, ULONG statesInitFlag); - -/** - * \brief Do delay line buffers housekeeping. To be called after - * each encoded audio frame. - * \param hEnvEnc SBR Encoder handle. - * \param timeBuffer Pointer to the encoder audio buffer. - * \param timeBufferBufSIze buffer size for one channel - * \return 0 on success, and non-zero if failed. - */ -INT sbrEncoder_UpdateBuffers(HANDLE_SBR_ENCODER hEnvEnc, INT_PCM *timeBuffer, - UINT timeBufferBufSIze); - -/** - * \brief Close SBR encoder instance. - * \param phEbrEncoder Handle of SBR encoder instance to be closed. - * \return void - */ -void sbrEncoder_Close(HANDLE_SBR_ENCODER *phEbrEncoder); - -/** - * \brief Encode SBR data of one complete audio frame. - * \param hEnvEncoder Handle of SBR encoder instance. - * \param samples Time samples, not interleaved. - * \param timeInStride Channel offset of samples buffer. - * \param sbrDataBits Size of SBR payload in bits. - * \param sbrData SBR payload. - * \return 0 on success, and non-zero if failed. - */ -INT sbrEncoder_EncodeFrame(HANDLE_SBR_ENCODER hEnvEncoder, INT_PCM *samples, - UINT samplesBufSize, UINT sbrDataBits[(8)], - UCHAR sbrData[(8)][MAX_PAYLOAD_SIZE]); - -/** - * \brief Write SBR headers of one SBR element. - * \param sbrEncoder Handle of the SBR encoder instance. - * \param hBs Handle of bit stream handle to write SBR header to. - * \param element_index Index of the SBR element which header should be written. - * \param fSendHeaders Flag indicating that the SBR encoder should send more - * headers in the SBR payload or not. - * \return void - */ -void sbrEncoder_GetHeader(HANDLE_SBR_ENCODER sbrEncoder, - HANDLE_FDK_BITSTREAM hBs, INT element_index, - int fSendHeaders); - -/** - * \brief Request to write SBR header. - * \param hSbrEncoder SBR encoder handle. - * \return 0 on success, and non-zero if failed. - */ -INT sbrEncoder_SendHeader(HANDLE_SBR_ENCODER hSbrEncoder); - -/** - * \brief Request if last sbr payload contains an SBR header. - * \param hSbrEncoder SBR encoder handle. - * \return 1 contains sbr header, 0 without sbr header. - */ -INT sbrEncoder_ContainsHeader(HANDLE_SBR_ENCODER hSbrEncoder); - -/** - * \brief SBR header delay in frames. - * \param hSbrEncoder SBR encoder handle. - * \return Delay in frames, -1 on failure. - */ -INT sbrEncoder_GetHeaderDelay(HANDLE_SBR_ENCODER hSbrEncoder); - -/** - * \brief Bitstrem delay in SBR frames. - * \param hSbrEncoder SBR encoder handle. - * \return Delay in frames, -1 on failure. - */ -INT sbrEncoder_GetBsDelay(HANDLE_SBR_ENCODER hSbrEncoder); - -/** - * \brief Prepare SBR payload for SAP. - * \param hSbrEncoder SBR encoder handle. - * \return 0 on success, and non-zero if failed. - */ -INT sbrEncoder_SAPPrepare(HANDLE_SBR_ENCODER hSbrEncoder); - -/** - * \brief SBR encoder bitrate estimation. - * \param hSbrEncoder SBR encoder handle. - * \return Estimated bitrate. - */ -INT sbrEncoder_GetEstimateBitrate(HANDLE_SBR_ENCODER hSbrEncoder); - -/** - * \brief Delay between input data and downsampled output data. - * \param hSbrEncoder SBR encoder handle. - * \return Delay. - */ -INT sbrEncoder_GetInputDataDelay(HANDLE_SBR_ENCODER hSbrEncoder); - -/** - * \brief Delay caused by the SBR decoder. - * \param hSbrEncoder SBR encoder handle. - * \return Delay. - */ -INT sbrEncoder_GetSbrDecDelay(HANDLE_SBR_ENCODER hSbrEncoder); - -/** - * \brief Get decoder library version info. - * \param info Pointer to an allocated LIB_INFO struct, where library info is - * written to. - * \return 0 on sucess. - */ -INT sbrEncoder_GetLibInfo(LIB_INFO *info); - -void sbrPrintRAM(void); - -void sbrPrintROM(void); - -#ifdef __cplusplus -} -#endif - -#endif /* ifndef __SBR_MAIN_H */ --- a/libSBRenc/src/bit_sbr.cpp +++ /dev/null @@ -1,1049 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief SBR bit writing routines $Revision: 93300 $ -*/ - -#include "bit_sbr.h" - -#include "code_env.h" -#include "cmondata.h" -#include "sbr.h" - -#include "ps_main.h" - -typedef enum { SBR_ID_SCE = 1, SBR_ID_CPE } SBR_ELEMENT_TYPE; - -static INT encodeSbrData(HANDLE_SBR_ENV_DATA sbrEnvDataLeft, - HANDLE_SBR_ENV_DATA sbrEnvDataRight, - HANDLE_PARAMETRIC_STEREO hParametricStereo, - HANDLE_COMMON_DATA cmonData, SBR_ELEMENT_TYPE sbrElem, - INT coupling, UINT sbrSyntaxFlags); - -static INT encodeSbrHeader(HANDLE_SBR_HEADER_DATA sbrHeaderData, - HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData, - HANDLE_COMMON_DATA cmonData); - -static INT encodeSbrHeaderData(HANDLE_SBR_HEADER_DATA sbrHeaderData, - HANDLE_FDK_BITSTREAM hBitStream); - -static INT encodeSbrSingleChannelElement( - HANDLE_SBR_ENV_DATA sbrEnvData, HANDLE_FDK_BITSTREAM hBitStream, - HANDLE_PARAMETRIC_STEREO hParametricStereo, const UINT sbrSyntaxFlags); - -static INT encodeSbrChannelPairElement( - HANDLE_SBR_ENV_DATA sbrEnvDataLeft, HANDLE_SBR_ENV_DATA sbrEnvDataRight, - HANDLE_PARAMETRIC_STEREO hParametricStereo, HANDLE_FDK_BITSTREAM hBitStream, - const INT coupling, const UINT sbrSyntaxFlags); - -static INT encodeSbrGrid(HANDLE_SBR_ENV_DATA sbrEnvData, - HANDLE_FDK_BITSTREAM hBitStream); - -static int encodeLowDelaySbrGrid(HANDLE_SBR_ENV_DATA sbrEnvData, - HANDLE_FDK_BITSTREAM hBitStream, - const int transmitFreqs, - const UINT sbrSyntaxFlags); - -static INT encodeSbrDtdf(HANDLE_SBR_ENV_DATA sbrEnvData, - HANDLE_FDK_BITSTREAM hBitStream); - -static INT writeNoiseLevelData(HANDLE_SBR_ENV_DATA sbrEnvData, - HANDLE_FDK_BITSTREAM hBitStream, INT coupling); - -static INT writeEnvelopeData(HANDLE_SBR_ENV_DATA sbrEnvData, - HANDLE_FDK_BITSTREAM hBitStream, INT coupling); - -static INT writeSyntheticCodingData(HANDLE_SBR_ENV_DATA sbrEnvData, - HANDLE_FDK_BITSTREAM hBitStream); - -static INT encodeExtendedData(HANDLE_PARAMETRIC_STEREO hParametricStereo, - HANDLE_FDK_BITSTREAM hBitStream); - -static INT getSbrExtendedDataSize(HANDLE_PARAMETRIC_STEREO hParametricStereo); - -/***************************************************************************** - - functionname: FDKsbrEnc_WriteEnvSingleChannelElement - description: writes pure SBR single channel data element - returns: number of bits written - input: - output: - -*****************************************************************************/ -INT FDKsbrEnc_WriteEnvSingleChannelElement( - HANDLE_SBR_HEADER_DATA sbrHeaderData, - HANDLE_PARAMETRIC_STEREO hParametricStereo, - HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData, HANDLE_SBR_ENV_DATA sbrEnvData, - HANDLE_COMMON_DATA cmonData, UINT sbrSyntaxFlags) - -{ - INT payloadBits = 0; - - cmonData->sbrHdrBits = 0; - cmonData->sbrDataBits = 0; - - /* write pure sbr data */ - if (sbrEnvData != NULL) { - /* write header */ - payloadBits += encodeSbrHeader(sbrHeaderData, sbrBitstreamData, cmonData); - - /* write data */ - payloadBits += encodeSbrData(sbrEnvData, NULL, hParametricStereo, cmonData, - SBR_ID_SCE, 0, sbrSyntaxFlags); - } - return payloadBits; -} - -/***************************************************************************** - - functionname: FDKsbrEnc_WriteEnvChannelPairElement - description: writes pure SBR channel pair data element - returns: number of bits written - input: - output: - -*****************************************************************************/ -INT FDKsbrEnc_WriteEnvChannelPairElement( - HANDLE_SBR_HEADER_DATA sbrHeaderData, - HANDLE_PARAMETRIC_STEREO hParametricStereo, - HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData, - HANDLE_SBR_ENV_DATA sbrEnvDataLeft, HANDLE_SBR_ENV_DATA sbrEnvDataRight, - HANDLE_COMMON_DATA cmonData, UINT sbrSyntaxFlags) - -{ - INT payloadBits = 0; - cmonData->sbrHdrBits = 0; - cmonData->sbrDataBits = 0; - - /* write pure sbr data */ - if ((sbrEnvDataLeft != NULL) && (sbrEnvDataRight != NULL)) { - /* write header */ - payloadBits += encodeSbrHeader(sbrHeaderData, sbrBitstreamData, cmonData); - - /* write data */ - payloadBits += encodeSbrData(sbrEnvDataLeft, sbrEnvDataRight, - hParametricStereo, cmonData, SBR_ID_CPE, - sbrHeaderData->coupling, sbrSyntaxFlags); - } - return payloadBits; -} - -INT FDKsbrEnc_CountSbrChannelPairElement( - HANDLE_SBR_HEADER_DATA sbrHeaderData, - HANDLE_PARAMETRIC_STEREO hParametricStereo, - HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData, - HANDLE_SBR_ENV_DATA sbrEnvDataLeft, HANDLE_SBR_ENV_DATA sbrEnvDataRight, - HANDLE_COMMON_DATA cmonData, UINT sbrSyntaxFlags) { - INT payloadBits; - INT bitPos = FDKgetValidBits(&cmonData->sbrBitbuf); - - payloadBits = FDKsbrEnc_WriteEnvChannelPairElement( - sbrHeaderData, hParametricStereo, sbrBitstreamData, sbrEnvDataLeft, - sbrEnvDataRight, cmonData, sbrSyntaxFlags); - - FDKpushBack(&cmonData->sbrBitbuf, - (FDKgetValidBits(&cmonData->sbrBitbuf) - bitPos)); - - return payloadBits; -} - -void sbrEncoder_GetHeader(SBR_ENCODER *sbrEncoder, HANDLE_FDK_BITSTREAM hBs, - INT element_index, int fSendHeaders) { - encodeSbrHeaderData(&sbrEncoder->sbrElement[element_index]->sbrHeaderData, - hBs); - - if (fSendHeaders == 0) { - /* Prevent header being embedded into the SBR payload. */ - sbrEncoder->sbrElement[element_index]->sbrBitstreamData.NrSendHeaderData = - -1; - sbrEncoder->sbrElement[element_index]->sbrBitstreamData.HeaderActive = 0; - sbrEncoder->sbrElement[element_index] - ->sbrBitstreamData.CountSendHeaderData = -1; - } -} - -/***************************************************************************** - - functionname: encodeSbrHeader - description: encodes SBR Header information - returns: number of bits written - input: - output: - -*****************************************************************************/ -static INT encodeSbrHeader(HANDLE_SBR_HEADER_DATA sbrHeaderData, - HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData, - HANDLE_COMMON_DATA cmonData) { - INT payloadBits = 0; - - if (sbrBitstreamData->HeaderActive) { - payloadBits += FDKwriteBits(&cmonData->sbrBitbuf, 1, 1); - payloadBits += encodeSbrHeaderData(sbrHeaderData, &cmonData->sbrBitbuf); - } else { - payloadBits += FDKwriteBits(&cmonData->sbrBitbuf, 0, 1); - } - - cmonData->sbrHdrBits = payloadBits; - - return payloadBits; -} - -/***************************************************************************** - - functionname: encodeSbrHeaderData - description: writes sbr_header() - bs_protocol_version through bs_header_extra_2 - returns: number of bits written - input: - output: - -*****************************************************************************/ -static INT encodeSbrHeaderData(HANDLE_SBR_HEADER_DATA sbrHeaderData, - HANDLE_FDK_BITSTREAM hBitStream) - -{ - INT payloadBits = 0; - if (sbrHeaderData != NULL) { - payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->sbr_amp_res, - SI_SBR_AMP_RES_BITS); - payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->sbr_start_frequency, - SI_SBR_START_FREQ_BITS); - payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->sbr_stop_frequency, - SI_SBR_STOP_FREQ_BITS); - payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->sbr_xover_band, - SI_SBR_XOVER_BAND_BITS); - - payloadBits += FDKwriteBits(hBitStream, 0, SI_SBR_RESERVED_BITS); - - payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->header_extra_1, - SI_SBR_HEADER_EXTRA_1_BITS); - payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->header_extra_2, - SI_SBR_HEADER_EXTRA_2_BITS); - - if (sbrHeaderData->header_extra_1) { - payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->freqScale, - SI_SBR_FREQ_SCALE_BITS); - payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->alterScale, - SI_SBR_ALTER_SCALE_BITS); - payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->sbr_noise_bands, - SI_SBR_NOISE_BANDS_BITS); - } /* sbrHeaderData->header_extra_1 */ - - if (sbrHeaderData->header_extra_2) { - payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->sbr_limiter_bands, - SI_SBR_LIMITER_BANDS_BITS); - payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->sbr_limiter_gains, - SI_SBR_LIMITER_GAINS_BITS); - payloadBits += FDKwriteBits(hBitStream, sbrHeaderData->sbr_interpol_freq, - SI_SBR_INTERPOL_FREQ_BITS); - payloadBits += - FDKwriteBits(hBitStream, sbrHeaderData->sbr_smoothing_length, - SI_SBR_SMOOTHING_LENGTH_BITS); - - } /* sbrHeaderData->header_extra_2 */ - } /* sbrHeaderData != NULL */ - - return payloadBits; -} - -/***************************************************************************** - - functionname: encodeSbrData - description: encodes sbr Data information - returns: number of bits written - input: - output: - -*****************************************************************************/ -static INT encodeSbrData(HANDLE_SBR_ENV_DATA sbrEnvDataLeft, - HANDLE_SBR_ENV_DATA sbrEnvDataRight, - HANDLE_PARAMETRIC_STEREO hParametricStereo, - HANDLE_COMMON_DATA cmonData, SBR_ELEMENT_TYPE sbrElem, - INT coupling, UINT sbrSyntaxFlags) { - INT payloadBits = 0; - - switch (sbrElem) { - case SBR_ID_SCE: - payloadBits += - encodeSbrSingleChannelElement(sbrEnvDataLeft, &cmonData->sbrBitbuf, - hParametricStereo, sbrSyntaxFlags); - break; - case SBR_ID_CPE: - payloadBits += encodeSbrChannelPairElement( - sbrEnvDataLeft, sbrEnvDataRight, hParametricStereo, - &cmonData->sbrBitbuf, coupling, sbrSyntaxFlags); - break; - default: - /* we never should apply SBR to any other element type */ - FDK_ASSERT(0); - } - - cmonData->sbrDataBits = payloadBits; - - return payloadBits; -} - -#define MODE_FREQ_TANS 1 -#define MODE_NO_FREQ_TRAN 0 -#define LD_TRANSMISSION MODE_FREQ_TANS -static int encodeFreqs(int mode) { return ((mode & MODE_FREQ_TANS) ? 1 : 0); } - -/***************************************************************************** - - functionname: encodeSbrSingleChannelElement - description: encodes sbr SCE information - returns: number of bits written - input: - output: - -*****************************************************************************/ -static INT encodeSbrSingleChannelElement( - HANDLE_SBR_ENV_DATA sbrEnvData, HANDLE_FDK_BITSTREAM hBitStream, - HANDLE_PARAMETRIC_STEREO hParametricStereo, const UINT sbrSyntaxFlags) { - INT i, payloadBits = 0; - - payloadBits += FDKwriteBits(hBitStream, 0, - SI_SBR_DATA_EXTRA_BITS); /* no reserved bits */ - - if (sbrEnvData->ldGrid) { - if (sbrEnvData->hSbrBSGrid->frameClass != FIXFIXonly) { - /* encode normal SbrGrid */ - payloadBits += encodeSbrGrid(sbrEnvData, hBitStream); - } else { - /* use FIXFIXonly frame Grid */ - payloadBits += encodeLowDelaySbrGrid( - sbrEnvData, hBitStream, encodeFreqs(LD_TRANSMISSION), sbrSyntaxFlags); - } - } else { - if (sbrSyntaxFlags & SBR_SYNTAX_SCALABLE) { - payloadBits += FDKwriteBits(hBitStream, 1, SI_SBR_COUPLING_BITS); - } - payloadBits += encodeSbrGrid(sbrEnvData, hBitStream); - } - - payloadBits += encodeSbrDtdf(sbrEnvData, hBitStream); - - for (i = 0; i < sbrEnvData->noOfnoisebands; i++) { - payloadBits += FDKwriteBits(hBitStream, sbrEnvData->sbr_invf_mode_vec[i], - SI_SBR_INVF_MODE_BITS); - } - - payloadBits += writeEnvelopeData(sbrEnvData, hBitStream, 0); - payloadBits += writeNoiseLevelData(sbrEnvData, hBitStream, 0); - - payloadBits += writeSyntheticCodingData(sbrEnvData, hBitStream); - - payloadBits += encodeExtendedData(hParametricStereo, hBitStream); - - return payloadBits; -} - -/***************************************************************************** - - functionname: encodeSbrChannelPairElement - description: encodes sbr CPE information - returns: - input: - output: - -*****************************************************************************/ -static INT encodeSbrChannelPairElement( - HANDLE_SBR_ENV_DATA sbrEnvDataLeft, HANDLE_SBR_ENV_DATA sbrEnvDataRight, - HANDLE_PARAMETRIC_STEREO hParametricStereo, HANDLE_FDK_BITSTREAM hBitStream, - const INT coupling, const UINT sbrSyntaxFlags) { - INT payloadBits = 0; - INT i = 0; - - payloadBits += FDKwriteBits(hBitStream, 0, - SI_SBR_DATA_EXTRA_BITS); /* no reserved bits */ - - payloadBits += FDKwriteBits(hBitStream, coupling, SI_SBR_COUPLING_BITS); - - if (coupling) { - if (sbrEnvDataLeft->ldGrid) { - if (sbrEnvDataLeft->hSbrBSGrid->frameClass != FIXFIXonly) { - /* normal SbrGrid */ - payloadBits += encodeSbrGrid(sbrEnvDataLeft, hBitStream); - - } else { - /* FIXFIXonly frame Grid */ - payloadBits += - encodeLowDelaySbrGrid(sbrEnvDataLeft, hBitStream, - encodeFreqs(LD_TRANSMISSION), sbrSyntaxFlags); - } - } else - payloadBits += encodeSbrGrid(sbrEnvDataLeft, hBitStream); - - payloadBits += encodeSbrDtdf(sbrEnvDataLeft, hBitStream); - payloadBits += encodeSbrDtdf(sbrEnvDataRight, hBitStream); - - for (i = 0; i < sbrEnvDataLeft->noOfnoisebands; i++) { - payloadBits += - FDKwriteBits(hBitStream, sbrEnvDataLeft->sbr_invf_mode_vec[i], - SI_SBR_INVF_MODE_BITS); - } - - payloadBits += writeEnvelopeData(sbrEnvDataLeft, hBitStream, 1); - payloadBits += writeNoiseLevelData(sbrEnvDataLeft, hBitStream, 1); - payloadBits += writeEnvelopeData(sbrEnvDataRight, hBitStream, 1); - payloadBits += writeNoiseLevelData(sbrEnvDataRight, hBitStream, 1); - - payloadBits += writeSyntheticCodingData(sbrEnvDataLeft, hBitStream); - payloadBits += writeSyntheticCodingData(sbrEnvDataRight, hBitStream); - - } else { /* no coupling */ - FDK_ASSERT(sbrEnvDataLeft->ldGrid == sbrEnvDataRight->ldGrid); - - if (sbrEnvDataLeft->ldGrid || sbrEnvDataRight->ldGrid) { - /* sbrEnvDataLeft (left channel) */ - if (sbrEnvDataLeft->hSbrBSGrid->frameClass != FIXFIXonly) { - /* no FIXFIXonly Frame so we dont need encodeLowDelaySbrGrid */ - /* normal SbrGrid */ - payloadBits += encodeSbrGrid(sbrEnvDataLeft, hBitStream); - - } else { - /* FIXFIXonly frame Grid */ - payloadBits += - encodeLowDelaySbrGrid(sbrEnvDataLeft, hBitStream, - encodeFreqs(LD_TRANSMISSION), sbrSyntaxFlags); - } - - /* sbrEnvDataRight (right channel) */ - if (sbrEnvDataRight->hSbrBSGrid->frameClass != FIXFIXonly) { - /* no FIXFIXonly Frame so we dont need encodeLowDelaySbrGrid */ - /* normal SbrGrid */ - payloadBits += encodeSbrGrid(sbrEnvDataRight, hBitStream); - - } else { - /* FIXFIXonly frame Grid */ - payloadBits += - encodeLowDelaySbrGrid(sbrEnvDataRight, hBitStream, - encodeFreqs(LD_TRANSMISSION), sbrSyntaxFlags); - } - } else { - payloadBits += encodeSbrGrid(sbrEnvDataLeft, hBitStream); - payloadBits += encodeSbrGrid(sbrEnvDataRight, hBitStream); - } - payloadBits += encodeSbrDtdf(sbrEnvDataLeft, hBitStream); - payloadBits += encodeSbrDtdf(sbrEnvDataRight, hBitStream); - - for (i = 0; i < sbrEnvDataLeft->noOfnoisebands; i++) { - payloadBits += - FDKwriteBits(hBitStream, sbrEnvDataLeft->sbr_invf_mode_vec[i], - SI_SBR_INVF_MODE_BITS); - } - for (i = 0; i < sbrEnvDataRight->noOfnoisebands; i++) { - payloadBits += - FDKwriteBits(hBitStream, sbrEnvDataRight->sbr_invf_mode_vec[i], - SI_SBR_INVF_MODE_BITS); - } - - payloadBits += writeEnvelopeData(sbrEnvDataLeft, hBitStream, 0); - payloadBits += writeEnvelopeData(sbrEnvDataRight, hBitStream, 0); - payloadBits += writeNoiseLevelData(sbrEnvDataLeft, hBitStream, 0); - payloadBits += writeNoiseLevelData(sbrEnvDataRight, hBitStream, 0); - - payloadBits += writeSyntheticCodingData(sbrEnvDataLeft, hBitStream); - payloadBits += writeSyntheticCodingData(sbrEnvDataRight, hBitStream); - - } /* coupling */ - - payloadBits += encodeExtendedData(hParametricStereo, hBitStream); - - return payloadBits; -} - -static INT ceil_ln2(INT x) { - INT tmp = -1; - while ((1 << ++tmp) < x) - ; - return (tmp); -} - -/***************************************************************************** - - functionname: encodeSbrGrid - description: if hBitStream != NULL writes bits that describes the - time/frequency grouping of a frame; else counts them only - returns: number of bits written or counted - input: - output: - -*****************************************************************************/ -static INT encodeSbrGrid(HANDLE_SBR_ENV_DATA sbrEnvData, - HANDLE_FDK_BITSTREAM hBitStream) { - INT payloadBits = 0; - INT i, temp; - INT bufferFrameStart = sbrEnvData->hSbrBSGrid->bufferFrameStart; - INT numberTimeSlots = sbrEnvData->hSbrBSGrid->numberTimeSlots; - - if (sbrEnvData->ldGrid) - payloadBits += FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->frameClass, - SBR_CLA_BITS_LD); - else - payloadBits += FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->frameClass, - SBR_CLA_BITS); - - switch (sbrEnvData->hSbrBSGrid->frameClass) { - case FIXFIXonly: - FDK_ASSERT(0 /* Fatal error in encodeSbrGrid! */); - break; - case FIXFIX: - temp = ceil_ln2(sbrEnvData->hSbrBSGrid->bs_num_env); - payloadBits += FDKwriteBits(hBitStream, temp, SBR_ENV_BITS); - if ((sbrEnvData->ldGrid) && (sbrEnvData->hSbrBSGrid->bs_num_env == 1)) - payloadBits += FDKwriteBits(hBitStream, sbrEnvData->currentAmpResFF, - SI_SBR_AMP_RES_BITS); - payloadBits += FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->v_f[0], - SBR_RES_BITS); - - break; - - case FIXVAR: - case VARFIX: - if (sbrEnvData->hSbrBSGrid->frameClass == FIXVAR) - temp = sbrEnvData->hSbrBSGrid->bs_abs_bord - - (bufferFrameStart + numberTimeSlots); - else - temp = sbrEnvData->hSbrBSGrid->bs_abs_bord - bufferFrameStart; - - payloadBits += FDKwriteBits(hBitStream, temp, SBR_ABS_BITS); - payloadBits += - FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->n, SBR_NUM_BITS); - - for (i = 0; i < sbrEnvData->hSbrBSGrid->n; i++) { - temp = (sbrEnvData->hSbrBSGrid->bs_rel_bord[i] - 2) >> 1; - payloadBits += FDKwriteBits(hBitStream, temp, SBR_REL_BITS); - } - - temp = ceil_ln2(sbrEnvData->hSbrBSGrid->n + 2); - payloadBits += FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->p, temp); - - for (i = 0; i < sbrEnvData->hSbrBSGrid->n + 1; i++) { - payloadBits += FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->v_f[i], - SBR_RES_BITS); - } - break; - - case VARVAR: - temp = sbrEnvData->hSbrBSGrid->bs_abs_bord_0 - bufferFrameStart; - payloadBits += FDKwriteBits(hBitStream, temp, SBR_ABS_BITS); - temp = sbrEnvData->hSbrBSGrid->bs_abs_bord_1 - - (bufferFrameStart + numberTimeSlots); - payloadBits += FDKwriteBits(hBitStream, temp, SBR_ABS_BITS); - - payloadBits += FDKwriteBits( - hBitStream, sbrEnvData->hSbrBSGrid->bs_num_rel_0, SBR_NUM_BITS); - payloadBits += FDKwriteBits( - hBitStream, sbrEnvData->hSbrBSGrid->bs_num_rel_1, SBR_NUM_BITS); - - for (i = 0; i < sbrEnvData->hSbrBSGrid->bs_num_rel_0; i++) { - temp = (sbrEnvData->hSbrBSGrid->bs_rel_bord_0[i] - 2) >> 1; - payloadBits += FDKwriteBits(hBitStream, temp, SBR_REL_BITS); - } - - for (i = 0; i < sbrEnvData->hSbrBSGrid->bs_num_rel_1; i++) { - temp = (sbrEnvData->hSbrBSGrid->bs_rel_bord_1[i] - 2) >> 1; - payloadBits += FDKwriteBits(hBitStream, temp, SBR_REL_BITS); - } - - temp = ceil_ln2(sbrEnvData->hSbrBSGrid->bs_num_rel_0 + - sbrEnvData->hSbrBSGrid->bs_num_rel_1 + 2); - payloadBits += FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->p, temp); - - temp = sbrEnvData->hSbrBSGrid->bs_num_rel_0 + - sbrEnvData->hSbrBSGrid->bs_num_rel_1 + 1; - - for (i = 0; i < temp; i++) { - payloadBits += FDKwriteBits( - hBitStream, sbrEnvData->hSbrBSGrid->v_fLR[i], SBR_RES_BITS); - } - break; - } - - return payloadBits; -} - -#define SBR_CLA_BITS_LD 1 -/***************************************************************************** - - functionname: encodeLowDelaySbrGrid - description: if hBitStream != NULL writes bits that describes the - time/frequency grouping of a frame; - else counts them only - (this function only write the FIXFIXonly Bitstream data) - returns: number of bits written or counted - input: - output: - -*****************************************************************************/ -static int encodeLowDelaySbrGrid(HANDLE_SBR_ENV_DATA sbrEnvData, - HANDLE_FDK_BITSTREAM hBitStream, - const int transmitFreqs, - const UINT sbrSyntaxFlags) { - int payloadBits = 0; - int i; - - /* write FIXFIXonly Grid */ - /* write frameClass [1 bit] for FIXFIXonly Grid */ - payloadBits += FDKwriteBits(hBitStream, 1, SBR_CLA_BITS_LD); - - /* absolute Borders are fix: 0,X,X,X,nTimeSlots; so we dont have to transmit - * them */ - /* only transmit the transient position! */ - /* with this info (b1) we can reconstruct the Frame on Decoder side : */ - /* border[0] = 0; border[1] = b1; border[2]=b1+2; border[3] = nrTimeSlots */ - - /* use 3 or 4bits for transient border (border) */ - if (sbrEnvData->hSbrBSGrid->numberTimeSlots == 8) - payloadBits += - FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->bs_abs_bord, 3); - else - payloadBits += - FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->bs_abs_bord, 4); - - if (transmitFreqs) { - /* write FreqRes grid */ - for (i = 0; i < sbrEnvData->hSbrBSGrid->bs_num_env; i++) { - payloadBits += FDKwriteBits(hBitStream, sbrEnvData->hSbrBSGrid->v_f[i], - SBR_RES_BITS); - } - } - - return payloadBits; -} - -/***************************************************************************** - - functionname: encodeSbrDtdf - description: writes bits that describes the direction of the envelopes of a -frame returns: number of bits written input: output: - -*****************************************************************************/ -static INT encodeSbrDtdf(HANDLE_SBR_ENV_DATA sbrEnvData, - HANDLE_FDK_BITSTREAM hBitStream) { - INT i, payloadBits = 0, noOfNoiseEnvelopes; - - noOfNoiseEnvelopes = sbrEnvData->noOfEnvelopes > 1 ? 2 : 1; - - for (i = 0; i < sbrEnvData->noOfEnvelopes; ++i) { - payloadBits += - FDKwriteBits(hBitStream, sbrEnvData->domain_vec[i], SBR_DIR_BITS); - } - for (i = 0; i < noOfNoiseEnvelopes; ++i) { - payloadBits += - FDKwriteBits(hBitStream, sbrEnvData->domain_vec_noise[i], SBR_DIR_BITS); - } - - return payloadBits; -} - -/***************************************************************************** - - functionname: writeNoiseLevelData - description: writes bits corresponding to the noise-floor-level - returns: number of bits written - input: - output: - -*****************************************************************************/ -static INT writeNoiseLevelData(HANDLE_SBR_ENV_DATA sbrEnvData, - HANDLE_FDK_BITSTREAM hBitStream, INT coupling) { - INT j, i, payloadBits = 0; - INT nNoiseEnvelopes = sbrEnvData->noOfEnvelopes > 1 ? 2 : 1; - - for (i = 0; i < nNoiseEnvelopes; i++) { - switch (sbrEnvData->domain_vec_noise[i]) { - case FREQ: - if (coupling && sbrEnvData->balance) { - payloadBits += FDKwriteBits( - hBitStream, - sbrEnvData->sbr_noise_levels[i * sbrEnvData->noOfnoisebands], - sbrEnvData->si_sbr_start_noise_bits_balance); - } else { - payloadBits += FDKwriteBits( - hBitStream, - sbrEnvData->sbr_noise_levels[i * sbrEnvData->noOfnoisebands], - sbrEnvData->si_sbr_start_noise_bits); - } - - for (j = 1 + i * sbrEnvData->noOfnoisebands; - j < (sbrEnvData->noOfnoisebands * (1 + i)); j++) { - if (coupling) { - if (sbrEnvData->balance) { - /* coupling && balance */ - payloadBits += FDKwriteBits(hBitStream, - sbrEnvData->hufftableNoiseBalanceFreqC - [sbrEnvData->sbr_noise_levels[j] + - CODE_BOOK_SCF_LAV_BALANCE11], - sbrEnvData->hufftableNoiseBalanceFreqL - [sbrEnvData->sbr_noise_levels[j] + - CODE_BOOK_SCF_LAV_BALANCE11]); - } else { - /* coupling && !balance */ - payloadBits += FDKwriteBits( - hBitStream, - sbrEnvData->hufftableNoiseLevelFreqC - [sbrEnvData->sbr_noise_levels[j] + CODE_BOOK_SCF_LAV11], - sbrEnvData->hufftableNoiseLevelFreqL - [sbrEnvData->sbr_noise_levels[j] + CODE_BOOK_SCF_LAV11]); - } - } else { - /* !coupling */ - payloadBits += FDKwriteBits( - hBitStream, - sbrEnvData - ->hufftableNoiseFreqC[sbrEnvData->sbr_noise_levels[j] + - CODE_BOOK_SCF_LAV11], - sbrEnvData - ->hufftableNoiseFreqL[sbrEnvData->sbr_noise_levels[j] + - CODE_BOOK_SCF_LAV11]); - } - } - break; - - case TIME: - for (j = i * sbrEnvData->noOfnoisebands; - j < (sbrEnvData->noOfnoisebands * (1 + i)); j++) { - if (coupling) { - if (sbrEnvData->balance) { - /* coupling && balance */ - payloadBits += FDKwriteBits(hBitStream, - sbrEnvData->hufftableNoiseBalanceTimeC - [sbrEnvData->sbr_noise_levels[j] + - CODE_BOOK_SCF_LAV_BALANCE11], - sbrEnvData->hufftableNoiseBalanceTimeL - [sbrEnvData->sbr_noise_levels[j] + - CODE_BOOK_SCF_LAV_BALANCE11]); - } else { - /* coupling && !balance */ - payloadBits += FDKwriteBits( - hBitStream, - sbrEnvData->hufftableNoiseLevelTimeC - [sbrEnvData->sbr_noise_levels[j] + CODE_BOOK_SCF_LAV11], - sbrEnvData->hufftableNoiseLevelTimeL - [sbrEnvData->sbr_noise_levels[j] + CODE_BOOK_SCF_LAV11]); - } - } else { - /* !coupling */ - payloadBits += FDKwriteBits( - hBitStream, - sbrEnvData - ->hufftableNoiseLevelTimeC[sbrEnvData->sbr_noise_levels[j] + - CODE_BOOK_SCF_LAV11], - sbrEnvData - ->hufftableNoiseLevelTimeL[sbrEnvData->sbr_noise_levels[j] + - CODE_BOOK_SCF_LAV11]); - } - } - break; - } - } - return payloadBits; -} - -/***************************************************************************** - - functionname: writeEnvelopeData - description: writes bits corresponding to the envelope - returns: number of bits written - input: - output: - -*****************************************************************************/ -static INT writeEnvelopeData(HANDLE_SBR_ENV_DATA sbrEnvData, - HANDLE_FDK_BITSTREAM hBitStream, INT coupling) { - INT payloadBits = 0, j, i, delta; - - for (j = 0; j < sbrEnvData->noOfEnvelopes; - j++) { /* loop over all envelopes */ - if (sbrEnvData->domain_vec[j] == FREQ) { - if (coupling && sbrEnvData->balance) { - payloadBits += FDKwriteBits(hBitStream, sbrEnvData->ienvelope[j][0], - sbrEnvData->si_sbr_start_env_bits_balance); - } else { - payloadBits += FDKwriteBits(hBitStream, sbrEnvData->ienvelope[j][0], - sbrEnvData->si_sbr_start_env_bits); - } - } - - for (i = 1 - sbrEnvData->domain_vec[j]; i < sbrEnvData->noScfBands[j]; - i++) { - delta = sbrEnvData->ienvelope[j][i]; - if (coupling && sbrEnvData->balance) { - FDK_ASSERT(fixp_abs(delta) <= sbrEnvData->codeBookScfLavBalance); - } else { - FDK_ASSERT(fixp_abs(delta) <= sbrEnvData->codeBookScfLav); - } - if (coupling) { - if (sbrEnvData->balance) { - if (sbrEnvData->domain_vec[j]) { - /* coupling && balance && TIME */ - payloadBits += FDKwriteBits( - hBitStream, - sbrEnvData - ->hufftableBalanceTimeC[delta + - sbrEnvData->codeBookScfLavBalance], - sbrEnvData - ->hufftableBalanceTimeL[delta + - sbrEnvData->codeBookScfLavBalance]); - } else { - /* coupling && balance && FREQ */ - payloadBits += FDKwriteBits( - hBitStream, - sbrEnvData - ->hufftableBalanceFreqC[delta + - sbrEnvData->codeBookScfLavBalance], - sbrEnvData - ->hufftableBalanceFreqL[delta + - sbrEnvData->codeBookScfLavBalance]); - } - } else { - if (sbrEnvData->domain_vec[j]) { - /* coupling && !balance && TIME */ - payloadBits += FDKwriteBits( - hBitStream, - sbrEnvData - ->hufftableLevelTimeC[delta + sbrEnvData->codeBookScfLav], - sbrEnvData - ->hufftableLevelTimeL[delta + sbrEnvData->codeBookScfLav]); - } else { - /* coupling && !balance && FREQ */ - payloadBits += FDKwriteBits( - hBitStream, - sbrEnvData - ->hufftableLevelFreqC[delta + sbrEnvData->codeBookScfLav], - sbrEnvData - ->hufftableLevelFreqL[delta + sbrEnvData->codeBookScfLav]); - } - } - } else { - if (sbrEnvData->domain_vec[j]) { - /* !coupling && TIME */ - payloadBits += FDKwriteBits( - hBitStream, - sbrEnvData->hufftableTimeC[delta + sbrEnvData->codeBookScfLav], - sbrEnvData->hufftableTimeL[delta + sbrEnvData->codeBookScfLav]); - } else { - /* !coupling && FREQ */ - payloadBits += FDKwriteBits( - hBitStream, - sbrEnvData->hufftableFreqC[delta + sbrEnvData->codeBookScfLav], - sbrEnvData->hufftableFreqL[delta + sbrEnvData->codeBookScfLav]); - } - } - } - } - return payloadBits; -} - -/***************************************************************************** - - functionname: encodeExtendedData - description: writes bits corresponding to the extended data - returns: number of bits written - input: - output: - -*****************************************************************************/ -static INT encodeExtendedData(HANDLE_PARAMETRIC_STEREO hParametricStereo, - HANDLE_FDK_BITSTREAM hBitStream) { - INT extDataSize; - INT payloadBits = 0; - - extDataSize = getSbrExtendedDataSize(hParametricStereo); - - if (extDataSize != 0) { - INT maxExtSize = (1 << SI_SBR_EXTENSION_SIZE_BITS) - 1; - INT writtenNoBits = 0; /* needed to byte align the extended data */ - - payloadBits += FDKwriteBits(hBitStream, 1, SI_SBR_EXTENDED_DATA_BITS); - FDK_ASSERT(extDataSize <= SBR_EXTENDED_DATA_MAX_CNT); - - if (extDataSize < maxExtSize) { - payloadBits += - FDKwriteBits(hBitStream, extDataSize, SI_SBR_EXTENSION_SIZE_BITS); - } else { - payloadBits += - FDKwriteBits(hBitStream, maxExtSize, SI_SBR_EXTENSION_SIZE_BITS); - payloadBits += FDKwriteBits(hBitStream, extDataSize - maxExtSize, - SI_SBR_EXTENSION_ESC_COUNT_BITS); - } - - /* parametric coding signalled here? */ - if (hParametricStereo) { - writtenNoBits += FDKwriteBits(hBitStream, EXTENSION_ID_PS_CODING, - SI_SBR_EXTENSION_ID_BITS); - writtenNoBits += - FDKsbrEnc_PSEnc_WritePSData(hParametricStereo, hBitStream); - } - - payloadBits += writtenNoBits; - - /* byte alignment */ - writtenNoBits = writtenNoBits % 8; - if (writtenNoBits) - payloadBits += FDKwriteBits(hBitStream, 0, (8 - writtenNoBits)); - } else { - payloadBits += FDKwriteBits(hBitStream, 0, SI_SBR_EXTENDED_DATA_BITS); - } - - return payloadBits; -} - -/***************************************************************************** - - functionname: writeSyntheticCodingData - description: writes bits corresponding to the "synthetic-coding"-extension - returns: number of bits written - input: - output: - -*****************************************************************************/ -static INT writeSyntheticCodingData(HANDLE_SBR_ENV_DATA sbrEnvData, - HANDLE_FDK_BITSTREAM hBitStream) - -{ - INT i; - INT payloadBits = 0; - - payloadBits += FDKwriteBits(hBitStream, sbrEnvData->addHarmonicFlag, 1); - - if (sbrEnvData->addHarmonicFlag) { - for (i = 0; i < sbrEnvData->noHarmonics; i++) { - payloadBits += FDKwriteBits(hBitStream, sbrEnvData->addHarmonic[i], 1); - } - } - - return payloadBits; -} - -/***************************************************************************** - - functionname: getSbrExtendedDataSize - description: counts the number of bits needed for encoding the - extended data (including extension id) - - returns: number of bits needed for the extended data - input: - output: - -*****************************************************************************/ -static INT getSbrExtendedDataSize(HANDLE_PARAMETRIC_STEREO hParametricStereo) { - INT extDataBits = 0; - - /* add your new extended data counting methods here */ - - /* - no extended data - */ - - if (hParametricStereo) { - /* PS extended data */ - extDataBits += SI_SBR_EXTENSION_ID_BITS; - extDataBits += FDKsbrEnc_PSEnc_WritePSData(hParametricStereo, NULL); - } - - return (extDataBits + 7) >> 3; -} --- a/libSBRenc/src/bit_sbr.h +++ /dev/null @@ -1,267 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief SBR bit writing $Revision: 92790 $ -*/ -#ifndef BIT_SBR_H -#define BIT_SBR_H - -#include "sbr_def.h" -#include "cmondata.h" -#include "fram_gen.h" - -struct SBR_ENV_DATA; - -struct SBR_BITSTREAM_DATA { - INT TotalBits; - INT PayloadBits; - INT FillBits; - INT HeaderActive; - INT HeaderActiveDelay; /**< sbr payload and its header is delayed depending on - encoder configuration*/ - INT NrSendHeaderData; /**< input from commandline */ - INT CountSendHeaderData; /**< modulo count. If < 0 then no counting is done - (no SBR headers) */ - INT rightBorderFIX; /**< force VARFIX or FIXFIX frames */ -}; - -typedef struct SBR_BITSTREAM_DATA *HANDLE_SBR_BITSTREAM_DATA; - -struct SBR_HEADER_DATA { - AMP_RES sbr_amp_res; - INT sbr_start_frequency; - INT sbr_stop_frequency; - INT sbr_xover_band; - INT sbr_noise_bands; - INT sbr_data_extra; - INT header_extra_1; - INT header_extra_2; - INT sbr_lc_stereo_mode; - INT sbr_limiter_bands; - INT sbr_limiter_gains; - INT sbr_interpol_freq; - INT sbr_smoothing_length; - INT alterScale; - INT freqScale; - - /* - element of channelpairelement - */ - INT coupling; - INT prev_coupling; - - /* - element of singlechannelelement - */ -}; -typedef struct SBR_HEADER_DATA *HANDLE_SBR_HEADER_DATA; - -struct SBR_ENV_DATA { - INT sbr_xpos_ctrl; - FREQ_RES freq_res_fixfix[2]; - UCHAR fResTransIsLow; - - INVF_MODE sbr_invf_mode; - INVF_MODE sbr_invf_mode_vec[MAX_NUM_NOISE_VALUES]; - - XPOS_MODE sbr_xpos_mode; - - INT ienvelope[MAX_ENVELOPES][MAX_FREQ_COEFFS]; - - INT codeBookScfLavBalance; - INT codeBookScfLav; - const INT *hufftableTimeC; - const INT *hufftableFreqC; - const UCHAR *hufftableTimeL; - const UCHAR *hufftableFreqL; - - const INT *hufftableLevelTimeC; - const INT *hufftableBalanceTimeC; - const INT *hufftableLevelFreqC; - const INT *hufftableBalanceFreqC; - const UCHAR *hufftableLevelTimeL; - const UCHAR *hufftableBalanceTimeL; - const UCHAR *hufftableLevelFreqL; - const UCHAR *hufftableBalanceFreqL; - - const UCHAR *hufftableNoiseTimeL; - const INT *hufftableNoiseTimeC; - const UCHAR *hufftableNoiseFreqL; - const INT *hufftableNoiseFreqC; - - const UCHAR *hufftableNoiseLevelTimeL; - const INT *hufftableNoiseLevelTimeC; - const UCHAR *hufftableNoiseBalanceTimeL; - const INT *hufftableNoiseBalanceTimeC; - const UCHAR *hufftableNoiseLevelFreqL; - const INT *hufftableNoiseLevelFreqC; - const UCHAR *hufftableNoiseBalanceFreqL; - const INT *hufftableNoiseBalanceFreqC; - - HANDLE_SBR_GRID hSbrBSGrid; - - INT noHarmonics; - INT addHarmonicFlag; - UCHAR addHarmonic[MAX_FREQ_COEFFS]; - - /* calculated helper vars */ - INT si_sbr_start_env_bits_balance; - INT si_sbr_start_env_bits; - INT si_sbr_start_noise_bits_balance; - INT si_sbr_start_noise_bits; - - INT noOfEnvelopes; - INT noScfBands[MAX_ENVELOPES]; - INT domain_vec[MAX_ENVELOPES]; - INT domain_vec_noise[MAX_ENVELOPES]; - SCHAR sbr_noise_levels[MAX_FREQ_COEFFS]; - INT noOfnoisebands; - - INT balance; - AMP_RES init_sbr_amp_res; - AMP_RES currentAmpResFF; - FIXP_DBL - ton_HF[SBR_GLOBAL_TONALITY_VALUES]; /* tonality is scaled by - 2^19/0.524288f (fract part of - RELAXATION) */ - FIXP_DBL global_tonality; - - /* extended data */ - INT extended_data; - INT extension_size; - INT extension_id; - UCHAR extended_data_buffer[SBR_EXTENDED_DATA_MAX_CNT]; - - UCHAR ldGrid; -}; -typedef struct SBR_ENV_DATA *HANDLE_SBR_ENV_DATA; - -INT FDKsbrEnc_WriteEnvSingleChannelElement( - struct SBR_HEADER_DATA *sbrHeaderData, - struct T_PARAMETRIC_STEREO *hParametricStereo, - struct SBR_BITSTREAM_DATA *sbrBitstreamData, - struct SBR_ENV_DATA *sbrEnvData, struct COMMON_DATA *cmonData, - UINT sbrSyntaxFlags); - -INT FDKsbrEnc_WriteEnvChannelPairElement( - struct SBR_HEADER_DATA *sbrHeaderData, - struct T_PARAMETRIC_STEREO *hParametricStereo, - struct SBR_BITSTREAM_DATA *sbrBitstreamData, - struct SBR_ENV_DATA *sbrEnvDataLeft, struct SBR_ENV_DATA *sbrEnvDataRight, - struct COMMON_DATA *cmonData, UINT sbrSyntaxFlags); - -INT FDKsbrEnc_CountSbrChannelPairElement( - struct SBR_HEADER_DATA *sbrHeaderData, - struct T_PARAMETRIC_STEREO *hParametricStereo, - struct SBR_BITSTREAM_DATA *sbrBitstreamData, - struct SBR_ENV_DATA *sbrEnvDataLeft, struct SBR_ENV_DATA *sbrEnvDataRight, - struct COMMON_DATA *cmonData, UINT sbrSyntaxFlags); - -/* debugging and tuning functions */ - -/*#define SBR_ENV_STATISTICS */ - -/*#define SBR_PAYLOAD_MONITOR*/ - -#endif --- a/libSBRenc/src/cmondata.h +++ /dev/null @@ -1,127 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Core Coder's and SBR's shared data structure definition $Revision: - 92790 $ -*/ -#ifndef CMONDATA_H -#define CMONDATA_H - -#include "FDK_bitstream.h" - -struct COMMON_DATA { - INT sbrHdrBits; /**< number of SBR header bits */ - INT sbrDataBits; /**< number of SBR data bits */ - INT sbrFillBits; /**< number of SBR fill bits */ - FDK_BITSTREAM sbrBitbuf; /**< the SBR data bitbuffer */ - FDK_BITSTREAM tmpWriteBitbuf; /**< helper var for writing header*/ - INT xOverFreq; /**< the SBR crossover frequency */ - INT dynBwEnabled; /**< indicates if dynamic bandwidth is enabled */ - INT sbrNumChannels; /**< number of channels (meaning mono or stereo) */ - INT dynXOverFreqEnc; /**< encoder dynamic crossover frequency */ -}; - -typedef struct COMMON_DATA *HANDLE_COMMON_DATA; - -#endif --- a/libSBRenc/src/code_env.cpp +++ /dev/null @@ -1,602 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -#include "code_env.h" -#include "sbrenc_rom.h" - -/***************************************************************************** - - functionname: FDKsbrEnc_InitSbrHuffmanTables - description: initializes Huffman Tables dependent on chosen amp_res - returns: error handle - input: - output: - -*****************************************************************************/ -INT FDKsbrEnc_InitSbrHuffmanTables(HANDLE_SBR_ENV_DATA sbrEnvData, - HANDLE_SBR_CODE_ENVELOPE henv, - HANDLE_SBR_CODE_ENVELOPE hnoise, - AMP_RES amp_res) { - if ((!henv) || (!hnoise) || (!sbrEnvData)) return (1); /* not init. */ - - sbrEnvData->init_sbr_amp_res = amp_res; - - switch (amp_res) { - case SBR_AMP_RES_3_0: - /*envelope data*/ - - /*Level/Pan - coding */ - sbrEnvData->hufftableLevelTimeC = v_Huff_envelopeLevelC11T; - sbrEnvData->hufftableLevelTimeL = v_Huff_envelopeLevelL11T; - sbrEnvData->hufftableBalanceTimeC = bookSbrEnvBalanceC11T; - sbrEnvData->hufftableBalanceTimeL = bookSbrEnvBalanceL11T; - - sbrEnvData->hufftableLevelFreqC = v_Huff_envelopeLevelC11F; - sbrEnvData->hufftableLevelFreqL = v_Huff_envelopeLevelL11F; - sbrEnvData->hufftableBalanceFreqC = bookSbrEnvBalanceC11F; - sbrEnvData->hufftableBalanceFreqL = bookSbrEnvBalanceL11F; - - /*Right/Left - coding */ - sbrEnvData->hufftableTimeC = v_Huff_envelopeLevelC11T; - sbrEnvData->hufftableTimeL = v_Huff_envelopeLevelL11T; - sbrEnvData->hufftableFreqC = v_Huff_envelopeLevelC11F; - sbrEnvData->hufftableFreqL = v_Huff_envelopeLevelL11F; - - sbrEnvData->codeBookScfLavBalance = CODE_BOOK_SCF_LAV_BALANCE11; - sbrEnvData->codeBookScfLav = CODE_BOOK_SCF_LAV11; - - sbrEnvData->si_sbr_start_env_bits = SI_SBR_START_ENV_BITS_AMP_RES_3_0; - sbrEnvData->si_sbr_start_env_bits_balance = - SI_SBR_START_ENV_BITS_BALANCE_AMP_RES_3_0; - break; - - case SBR_AMP_RES_1_5: - /*envelope data*/ - - /*Level/Pan - coding */ - sbrEnvData->hufftableLevelTimeC = v_Huff_envelopeLevelC10T; - sbrEnvData->hufftableLevelTimeL = v_Huff_envelopeLevelL10T; - sbrEnvData->hufftableBalanceTimeC = bookSbrEnvBalanceC10T; - sbrEnvData->hufftableBalanceTimeL = bookSbrEnvBalanceL10T; - - sbrEnvData->hufftableLevelFreqC = v_Huff_envelopeLevelC10F; - sbrEnvData->hufftableLevelFreqL = v_Huff_envelopeLevelL10F; - sbrEnvData->hufftableBalanceFreqC = bookSbrEnvBalanceC10F; - sbrEnvData->hufftableBalanceFreqL = bookSbrEnvBalanceL10F; - - /*Right/Left - coding */ - sbrEnvData->hufftableTimeC = v_Huff_envelopeLevelC10T; - sbrEnvData->hufftableTimeL = v_Huff_envelopeLevelL10T; - sbrEnvData->hufftableFreqC = v_Huff_envelopeLevelC10F; - sbrEnvData->hufftableFreqL = v_Huff_envelopeLevelL10F; - - sbrEnvData->codeBookScfLavBalance = CODE_BOOK_SCF_LAV_BALANCE10; - sbrEnvData->codeBookScfLav = CODE_BOOK_SCF_LAV10; - - sbrEnvData->si_sbr_start_env_bits = SI_SBR_START_ENV_BITS_AMP_RES_1_5; - sbrEnvData->si_sbr_start_env_bits_balance = - SI_SBR_START_ENV_BITS_BALANCE_AMP_RES_1_5; - break; - - default: - return (1); /* undefined amp_res mode */ - } - - /* these are common to both amp_res values */ - /*Noise data*/ - - /*Level/Pan - coding */ - sbrEnvData->hufftableNoiseLevelTimeC = v_Huff_NoiseLevelC11T; - sbrEnvData->hufftableNoiseLevelTimeL = v_Huff_NoiseLevelL11T; - sbrEnvData->hufftableNoiseBalanceTimeC = bookSbrNoiseBalanceC11T; - sbrEnvData->hufftableNoiseBalanceTimeL = bookSbrNoiseBalanceL11T; - - sbrEnvData->hufftableNoiseLevelFreqC = v_Huff_envelopeLevelC11F; - sbrEnvData->hufftableNoiseLevelFreqL = v_Huff_envelopeLevelL11F; - sbrEnvData->hufftableNoiseBalanceFreqC = bookSbrEnvBalanceC11F; - sbrEnvData->hufftableNoiseBalanceFreqL = bookSbrEnvBalanceL11F; - - /*Right/Left - coding */ - sbrEnvData->hufftableNoiseTimeC = v_Huff_NoiseLevelC11T; - sbrEnvData->hufftableNoiseTimeL = v_Huff_NoiseLevelL11T; - sbrEnvData->hufftableNoiseFreqC = v_Huff_envelopeLevelC11F; - sbrEnvData->hufftableNoiseFreqL = v_Huff_envelopeLevelL11F; - - sbrEnvData->si_sbr_start_noise_bits = SI_SBR_START_NOISE_BITS_AMP_RES_3_0; - sbrEnvData->si_sbr_start_noise_bits_balance = - SI_SBR_START_NOISE_BITS_BALANCE_AMP_RES_3_0; - - /* init envelope tables and codebooks */ - henv->codeBookScfLavBalanceTime = sbrEnvData->codeBookScfLavBalance; - henv->codeBookScfLavBalanceFreq = sbrEnvData->codeBookScfLavBalance; - henv->codeBookScfLavLevelTime = sbrEnvData->codeBookScfLav; - henv->codeBookScfLavLevelFreq = sbrEnvData->codeBookScfLav; - henv->codeBookScfLavTime = sbrEnvData->codeBookScfLav; - henv->codeBookScfLavFreq = sbrEnvData->codeBookScfLav; - - henv->hufftableLevelTimeL = sbrEnvData->hufftableLevelTimeL; - henv->hufftableBalanceTimeL = sbrEnvData->hufftableBalanceTimeL; - henv->hufftableTimeL = sbrEnvData->hufftableTimeL; - henv->hufftableLevelFreqL = sbrEnvData->hufftableLevelFreqL; - henv->hufftableBalanceFreqL = sbrEnvData->hufftableBalanceFreqL; - henv->hufftableFreqL = sbrEnvData->hufftableFreqL; - - henv->codeBookScfLavFreq = sbrEnvData->codeBookScfLav; - henv->codeBookScfLavTime = sbrEnvData->codeBookScfLav; - - henv->start_bits = sbrEnvData->si_sbr_start_env_bits; - henv->start_bits_balance = sbrEnvData->si_sbr_start_env_bits_balance; - - /* init noise tables and codebooks */ - - hnoise->codeBookScfLavBalanceTime = CODE_BOOK_SCF_LAV_BALANCE11; - hnoise->codeBookScfLavBalanceFreq = CODE_BOOK_SCF_LAV_BALANCE11; - hnoise->codeBookScfLavLevelTime = CODE_BOOK_SCF_LAV11; - hnoise->codeBookScfLavLevelFreq = CODE_BOOK_SCF_LAV11; - hnoise->codeBookScfLavTime = CODE_BOOK_SCF_LAV11; - hnoise->codeBookScfLavFreq = CODE_BOOK_SCF_LAV11; - - hnoise->hufftableLevelTimeL = sbrEnvData->hufftableNoiseLevelTimeL; - hnoise->hufftableBalanceTimeL = sbrEnvData->hufftableNoiseBalanceTimeL; - hnoise->hufftableTimeL = sbrEnvData->hufftableNoiseTimeL; - hnoise->hufftableLevelFreqL = sbrEnvData->hufftableNoiseLevelFreqL; - hnoise->hufftableBalanceFreqL = sbrEnvData->hufftableNoiseBalanceFreqL; - hnoise->hufftableFreqL = sbrEnvData->hufftableNoiseFreqL; - - hnoise->start_bits = sbrEnvData->si_sbr_start_noise_bits; - hnoise->start_bits_balance = sbrEnvData->si_sbr_start_noise_bits_balance; - - /* No delta coding in time from the previous frame due to 1.5dB FIx-FIX rule - */ - henv->upDate = 0; - hnoise->upDate = 0; - return (0); -} - -/******************************************************************************* - Functionname: indexLow2High - ******************************************************************************* - - Description: Nice small patch-functions in order to cope with non-factor-2 - ratios between high-res and low-res - - Arguments: INT offset, INT index, FREQ_RES res - - Return: INT - -*******************************************************************************/ -static INT indexLow2High(INT offset, INT index, FREQ_RES res) { - if (res == FREQ_RES_LOW) { - if (offset >= 0) { - if (index < offset) - return (index); - else - return (2 * index - offset); - } else { - offset = -offset; - if (index < offset) - return (2 * index + index); - else - return (2 * index + offset); - } - } else - return (index); -} - -/******************************************************************************* - Functionname: mapLowResEnergyVal - ******************************************************************************* - - Description: - - Arguments: INT currVal,INT* prevData, INT offset, INT index, FREQ_RES res - - Return: none - -*******************************************************************************/ -static void mapLowResEnergyVal(SCHAR currVal, SCHAR *prevData, INT offset, - INT index, FREQ_RES res) { - if (res == FREQ_RES_LOW) { - if (offset >= 0) { - if (index < offset) - prevData[index] = currVal; - else { - prevData[2 * index - offset] = currVal; - prevData[2 * index + 1 - offset] = currVal; - } - } else { - offset = -offset; - if (index < offset) { - prevData[3 * index] = currVal; - prevData[3 * index + 1] = currVal; - prevData[3 * index + 2] = currVal; - } else { - prevData[2 * index + offset] = currVal; - prevData[2 * index + 1 + offset] = currVal; - } - } - } else - prevData[index] = currVal; -} - -/******************************************************************************* - Functionname: computeBits - ******************************************************************************* - - Description: - - Arguments: INT delta, - INT codeBookScfLavLevel, - INT codeBookScfLavBalance, - const UCHAR * hufftableLevel, - const UCHAR * hufftableBalance, INT coupling, INT channel) - - Return: INT - -*******************************************************************************/ -static INT computeBits(SCHAR *delta, INT codeBookScfLavLevel, - INT codeBookScfLavBalance, const UCHAR *hufftableLevel, - const UCHAR *hufftableBalance, INT coupling, - INT channel) { - INT index; - INT delta_bits = 0; - - if (coupling) { - if (channel == 1) { - if (*delta < 0) - index = fixMax(*delta, -codeBookScfLavBalance); - else - index = fixMin(*delta, codeBookScfLavBalance); - - if (index != *delta) { - *delta = index; - return (10000); - } - - delta_bits = hufftableBalance[index + codeBookScfLavBalance]; - } else { - if (*delta < 0) - index = fixMax(*delta, -codeBookScfLavLevel); - else - index = fixMin(*delta, codeBookScfLavLevel); - - if (index != *delta) { - *delta = index; - return (10000); - } - delta_bits = hufftableLevel[index + codeBookScfLavLevel]; - } - } else { - if (*delta < 0) - index = fixMax(*delta, -codeBookScfLavLevel); - else - index = fixMin(*delta, codeBookScfLavLevel); - - if (index != *delta) { - *delta = index; - return (10000); - } - delta_bits = hufftableLevel[index + codeBookScfLavLevel]; - } - - return (delta_bits); -} - -/******************************************************************************* - Functionname: FDKsbrEnc_codeEnvelope - ******************************************************************************* - - Description: - - Arguments: INT *sfb_nrg, - const FREQ_RES *freq_res, - SBR_CODE_ENVELOPE * h_sbrCodeEnvelope, - INT *directionVec, INT scalable, INT nEnvelopes, INT channel, - INT headerActive) - - Return: none - h_sbrCodeEnvelope->sfb_nrg_prev is modified ! - sfb_nrg is modified - h_sbrCodeEnvelope->update is modfied ! - *directionVec is modified - -*******************************************************************************/ -void FDKsbrEnc_codeEnvelope(SCHAR *sfb_nrg, const FREQ_RES *freq_res, - SBR_CODE_ENVELOPE *h_sbrCodeEnvelope, - INT *directionVec, INT coupling, INT nEnvelopes, - INT channel, INT headerActive) { - INT i, no_of_bands, band; - FIXP_DBL tmp1, tmp2, tmp3, dF_edge_1stEnv; - SCHAR *ptr_nrg; - - INT codeBookScfLavLevelTime; - INT codeBookScfLavLevelFreq; - INT codeBookScfLavBalanceTime; - INT codeBookScfLavBalanceFreq; - const UCHAR *hufftableLevelTimeL; - const UCHAR *hufftableBalanceTimeL; - const UCHAR *hufftableLevelFreqL; - const UCHAR *hufftableBalanceFreqL; - - INT offset = h_sbrCodeEnvelope->offset; - INT envDataTableCompFactor; - - INT delta_F_bits = 0, delta_T_bits = 0; - INT use_dT; - - SCHAR delta_F[MAX_FREQ_COEFFS]; - SCHAR delta_T[MAX_FREQ_COEFFS]; - SCHAR last_nrg, curr_nrg; - - tmp1 = FL2FXCONST_DBL(0.5f) >> (DFRACT_BITS - 16 - 1); - tmp2 = h_sbrCodeEnvelope->dF_edge_1stEnv >> (DFRACT_BITS - 16); - tmp3 = (FIXP_DBL)fMult(h_sbrCodeEnvelope->dF_edge_incr, - ((FIXP_DBL)h_sbrCodeEnvelope->dF_edge_incr_fac) << 15); - - dF_edge_1stEnv = tmp1 + tmp2 + tmp3; - - if (coupling) { - codeBookScfLavLevelTime = h_sbrCodeEnvelope->codeBookScfLavLevelTime; - codeBookScfLavLevelFreq = h_sbrCodeEnvelope->codeBookScfLavLevelFreq; - codeBookScfLavBalanceTime = h_sbrCodeEnvelope->codeBookScfLavBalanceTime; - codeBookScfLavBalanceFreq = h_sbrCodeEnvelope->codeBookScfLavBalanceFreq; - hufftableLevelTimeL = h_sbrCodeEnvelope->hufftableLevelTimeL; - hufftableBalanceTimeL = h_sbrCodeEnvelope->hufftableBalanceTimeL; - hufftableLevelFreqL = h_sbrCodeEnvelope->hufftableLevelFreqL; - hufftableBalanceFreqL = h_sbrCodeEnvelope->hufftableBalanceFreqL; - } else { - codeBookScfLavLevelTime = h_sbrCodeEnvelope->codeBookScfLavTime; - codeBookScfLavLevelFreq = h_sbrCodeEnvelope->codeBookScfLavFreq; - codeBookScfLavBalanceTime = h_sbrCodeEnvelope->codeBookScfLavTime; - codeBookScfLavBalanceFreq = h_sbrCodeEnvelope->codeBookScfLavFreq; - hufftableLevelTimeL = h_sbrCodeEnvelope->hufftableTimeL; - hufftableBalanceTimeL = h_sbrCodeEnvelope->hufftableTimeL; - hufftableLevelFreqL = h_sbrCodeEnvelope->hufftableFreqL; - hufftableBalanceFreqL = h_sbrCodeEnvelope->hufftableFreqL; - } - - if (coupling == 1 && channel == 1) - envDataTableCompFactor = - 1; /*should be one when the new huffman-tables are ready*/ - else - envDataTableCompFactor = 0; - - if (h_sbrCodeEnvelope->deltaTAcrossFrames == 0) h_sbrCodeEnvelope->upDate = 0; - - /* no delta coding in time in case of a header */ - if (headerActive) h_sbrCodeEnvelope->upDate = 0; - - for (i = 0; i < nEnvelopes; i++) { - if (freq_res[i] == FREQ_RES_HIGH) - no_of_bands = h_sbrCodeEnvelope->nSfb[FREQ_RES_HIGH]; - else - no_of_bands = h_sbrCodeEnvelope->nSfb[FREQ_RES_LOW]; - - ptr_nrg = sfb_nrg; - curr_nrg = *ptr_nrg; - - delta_F[0] = curr_nrg >> envDataTableCompFactor; - - if (coupling && channel == 1) - delta_F_bits = h_sbrCodeEnvelope->start_bits_balance; - else - delta_F_bits = h_sbrCodeEnvelope->start_bits; - - if (h_sbrCodeEnvelope->upDate != 0) { - delta_T[0] = (curr_nrg - h_sbrCodeEnvelope->sfb_nrg_prev[0]) >> - envDataTableCompFactor; - - delta_T_bits = computeBits(&delta_T[0], codeBookScfLavLevelTime, - codeBookScfLavBalanceTime, hufftableLevelTimeL, - hufftableBalanceTimeL, coupling, channel); - } - - mapLowResEnergyVal(curr_nrg, h_sbrCodeEnvelope->sfb_nrg_prev, offset, 0, - freq_res[i]); - - /* ensure that nrg difference is not higher than codeBookScfLavXXXFreq */ - if (coupling && channel == 1) { - for (band = no_of_bands - 1; band > 0; band--) { - if (ptr_nrg[band] - ptr_nrg[band - 1] > codeBookScfLavBalanceFreq) { - ptr_nrg[band - 1] = ptr_nrg[band] - codeBookScfLavBalanceFreq; - } - } - for (band = 1; band < no_of_bands; band++) { - if (ptr_nrg[band - 1] - ptr_nrg[band] > codeBookScfLavBalanceFreq) { - ptr_nrg[band] = ptr_nrg[band - 1] - codeBookScfLavBalanceFreq; - } - } - } else { - for (band = no_of_bands - 1; band > 0; band--) { - if (ptr_nrg[band] - ptr_nrg[band - 1] > codeBookScfLavLevelFreq) { - ptr_nrg[band - 1] = ptr_nrg[band] - codeBookScfLavLevelFreq; - } - } - for (band = 1; band < no_of_bands; band++) { - if (ptr_nrg[band - 1] - ptr_nrg[band] > codeBookScfLavLevelFreq) { - ptr_nrg[band] = ptr_nrg[band - 1] - codeBookScfLavLevelFreq; - } - } - } - - /* Coding loop*/ - for (band = 1; band < no_of_bands; band++) { - last_nrg = (*ptr_nrg); - ptr_nrg++; - curr_nrg = (*ptr_nrg); - - delta_F[band] = (curr_nrg - last_nrg) >> envDataTableCompFactor; - - delta_F_bits += computeBits( - &delta_F[band], codeBookScfLavLevelFreq, codeBookScfLavBalanceFreq, - hufftableLevelFreqL, hufftableBalanceFreqL, coupling, channel); - - if (h_sbrCodeEnvelope->upDate != 0) { - delta_T[band] = - curr_nrg - - h_sbrCodeEnvelope - ->sfb_nrg_prev[indexLow2High(offset, band, freq_res[i])]; - delta_T[band] = delta_T[band] >> envDataTableCompFactor; - } - - mapLowResEnergyVal(curr_nrg, h_sbrCodeEnvelope->sfb_nrg_prev, offset, - band, freq_res[i]); - - if (h_sbrCodeEnvelope->upDate != 0) { - delta_T_bits += computeBits( - &delta_T[band], codeBookScfLavLevelTime, codeBookScfLavBalanceTime, - hufftableLevelTimeL, hufftableBalanceTimeL, coupling, channel); - } - } - - /* Replace sfb_nrg with deltacoded samples and set flag */ - if (i == 0) { - INT tmp_bits; - tmp_bits = (((delta_T_bits * dF_edge_1stEnv) >> (DFRACT_BITS - 18)) + - (FIXP_DBL)1) >> - 1; - use_dT = (h_sbrCodeEnvelope->upDate != 0 && (delta_F_bits > tmp_bits)); - } else - use_dT = (delta_T_bits < delta_F_bits && h_sbrCodeEnvelope->upDate != 0); - - if (use_dT) { - directionVec[i] = TIME; - FDKmemcpy(sfb_nrg, delta_T, no_of_bands * sizeof(SCHAR)); - } else { - h_sbrCodeEnvelope->upDate = 0; - directionVec[i] = FREQ; - FDKmemcpy(sfb_nrg, delta_F, no_of_bands * sizeof(SCHAR)); - } - sfb_nrg += no_of_bands; - h_sbrCodeEnvelope->upDate = 1; - } -} - -/******************************************************************************* - Functionname: FDKsbrEnc_InitSbrCodeEnvelope - ******************************************************************************* - - Description: - - Arguments: - - Return: - -*******************************************************************************/ -INT FDKsbrEnc_InitSbrCodeEnvelope(HANDLE_SBR_CODE_ENVELOPE h_sbrCodeEnvelope, - INT *nSfb, INT deltaTAcrossFrames, - FIXP_DBL dF_edge_1stEnv, - FIXP_DBL dF_edge_incr) { - FDKmemclear(h_sbrCodeEnvelope, sizeof(SBR_CODE_ENVELOPE)); - - h_sbrCodeEnvelope->deltaTAcrossFrames = deltaTAcrossFrames; - h_sbrCodeEnvelope->dF_edge_1stEnv = dF_edge_1stEnv; - h_sbrCodeEnvelope->dF_edge_incr = dF_edge_incr; - h_sbrCodeEnvelope->dF_edge_incr_fac = 0; - h_sbrCodeEnvelope->upDate = 0; - h_sbrCodeEnvelope->nSfb[FREQ_RES_LOW] = nSfb[FREQ_RES_LOW]; - h_sbrCodeEnvelope->nSfb[FREQ_RES_HIGH] = nSfb[FREQ_RES_HIGH]; - h_sbrCodeEnvelope->offset = 2 * h_sbrCodeEnvelope->nSfb[FREQ_RES_LOW] - - h_sbrCodeEnvelope->nSfb[FREQ_RES_HIGH]; - - return (0); -} --- a/libSBRenc/src/code_env.h +++ /dev/null @@ -1,161 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief DPCM Envelope coding $Revision: 92790 $ -*/ - -#ifndef CODE_ENV_H -#define CODE_ENV_H - -#include "sbr_def.h" -#include "bit_sbr.h" -#include "fram_gen.h" - -typedef struct { - INT offset; - INT upDate; - INT nSfb[2]; - SCHAR sfb_nrg_prev[MAX_FREQ_COEFFS]; - INT deltaTAcrossFrames; - FIXP_DBL dF_edge_1stEnv; - FIXP_DBL dF_edge_incr; - INT dF_edge_incr_fac; - - INT codeBookScfLavTime; - INT codeBookScfLavFreq; - - INT codeBookScfLavLevelTime; - INT codeBookScfLavLevelFreq; - INT codeBookScfLavBalanceTime; - INT codeBookScfLavBalanceFreq; - - INT start_bits; - INT start_bits_balance; - - const UCHAR *hufftableTimeL; - const UCHAR *hufftableFreqL; - - const UCHAR *hufftableLevelTimeL; - const UCHAR *hufftableBalanceTimeL; - const UCHAR *hufftableLevelFreqL; - const UCHAR *hufftableBalanceFreqL; -} SBR_CODE_ENVELOPE; -typedef SBR_CODE_ENVELOPE *HANDLE_SBR_CODE_ENVELOPE; - -void FDKsbrEnc_codeEnvelope(SCHAR *sfb_nrg, const FREQ_RES *freq_res, - SBR_CODE_ENVELOPE *h_sbrCodeEnvelope, - INT *directionVec, INT coupling, INT nEnvelopes, - INT channel, INT headerActive); - -INT FDKsbrEnc_InitSbrCodeEnvelope(HANDLE_SBR_CODE_ENVELOPE h_sbrCodeEnvelope, - INT *nSfb, INT deltaTAcrossFrames, - FIXP_DBL dF_edge_1stEnv, - FIXP_DBL dF_edge_incr); - -INT FDKsbrEnc_InitSbrHuffmanTables(struct SBR_ENV_DATA *sbrEnvData, - HANDLE_SBR_CODE_ENVELOPE henv, - HANDLE_SBR_CODE_ENVELOPE hnoise, - AMP_RES amp_res); - -#endif --- a/libSBRenc/src/env_bit.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Remaining SBR Bit Writing Routines -*/ - -#include "env_bit.h" -#include "cmondata.h" - -#ifndef min -#define min(a, b) (a < b ? a : b) -#endif - -#ifndef max -#define max(a, b) (a > b ? a : b) -#endif - -/* ***************************** crcAdvance **********************************/ -/** - * @fn - * @brief updates crc data register - * @return none - * - * This function updates the crc register - * - */ -static void crcAdvance(USHORT crcPoly, USHORT crcMask, USHORT *crc, - ULONG bValue, INT bBits) { - INT i; - USHORT flag; - - for (i = bBits - 1; i >= 0; i--) { - flag = ((*crc) & crcMask) ? (1) : (0); - flag ^= (bValue & (1 << i)) ? (1) : (0); - - (*crc) <<= 1; - if (flag) (*crc) ^= crcPoly; - } -} - -/* ***************************** FDKsbrEnc_InitSbrBitstream - * **********************************/ -/** - * @fn - * @brief Inittialisation of sbr bitstream, write of dummy header and CRC - * @return none - * - * - * - */ - -INT FDKsbrEnc_InitSbrBitstream( - HANDLE_COMMON_DATA hCmonData, - UCHAR *memoryBase, /*!< Pointer to bitstream buffer */ - INT memorySize, /*!< Length of bitstream buffer in bytes */ - HANDLE_FDK_CRCINFO hCrcInfo, UINT sbrSyntaxFlags) /*!< SBR syntax flags */ -{ - INT crcRegion = 0; - - /* reset bit buffer */ - FDKresetBitbuffer(&hCmonData->sbrBitbuf, BS_WRITER); - - FDKinitBitStream(&hCmonData->tmpWriteBitbuf, memoryBase, memorySize, 0, - BS_WRITER); - - if (sbrSyntaxFlags & SBR_SYNTAX_CRC) { - if (sbrSyntaxFlags & SBR_SYNTAX_DRM_CRC) { /* Init and start CRC region */ - FDKwriteBits(&hCmonData->sbrBitbuf, 0x0, SI_SBR_DRM_CRC_BITS); - FDKcrcInit(hCrcInfo, 0x001d, 0xFFFF, SI_SBR_DRM_CRC_BITS); - crcRegion = FDKcrcStartReg(hCrcInfo, &hCmonData->sbrBitbuf, 0); - } else { - FDKwriteBits(&hCmonData->sbrBitbuf, 0x0, SI_SBR_CRC_BITS); - } - } - - return (crcRegion); -} - -/* ************************** FDKsbrEnc_AssembleSbrBitstream - * *******************************/ -/** - * @fn - * @brief Formats the SBR payload - * @return nothing - * - * Also the CRC will be calculated here. - * - */ - -void FDKsbrEnc_AssembleSbrBitstream(HANDLE_COMMON_DATA hCmonData, - HANDLE_FDK_CRCINFO hCrcInfo, INT crcRegion, - UINT sbrSyntaxFlags) { - USHORT crcReg = SBR_CRCINIT; - INT numCrcBits, i; - - /* check if SBR is present */ - if (hCmonData == NULL) return; - - hCmonData->sbrFillBits = 0; /* Fill bits are written only for GA streams */ - - if (sbrSyntaxFlags & SBR_SYNTAX_DRM_CRC) { - /* - * Calculate and write DRM CRC - */ - FDKcrcEndReg(hCrcInfo, &hCmonData->sbrBitbuf, crcRegion); - FDKwriteBits(&hCmonData->tmpWriteBitbuf, FDKcrcGetCRC(hCrcInfo) ^ 0xFF, - SI_SBR_DRM_CRC_BITS); - } else { - if (!(sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)) { - /* Do alignment here, because its defined as part of the - * sbr_extension_data */ - int sbrLoad = hCmonData->sbrHdrBits + hCmonData->sbrDataBits; - - if (sbrSyntaxFlags & SBR_SYNTAX_CRC) { - sbrLoad += SI_SBR_CRC_BITS; - } - - sbrLoad += 4; /* Do byte Align with 4 bit offset. ISO/IEC 14496-3:2005(E) - page 39. */ - - hCmonData->sbrFillBits = (8 - (sbrLoad % 8)) % 8; - - /* - append fill bits - */ - FDKwriteBits(&hCmonData->sbrBitbuf, 0, hCmonData->sbrFillBits); - - FDK_ASSERT(FDKgetValidBits(&hCmonData->sbrBitbuf) % 8 == 4); - } - - /* - calculate crc - */ - if (sbrSyntaxFlags & SBR_SYNTAX_CRC) { - FDK_BITSTREAM tmpCRCBuf = hCmonData->sbrBitbuf; - FDKresetBitbuffer(&tmpCRCBuf, BS_READER); - - numCrcBits = hCmonData->sbrHdrBits + hCmonData->sbrDataBits + - hCmonData->sbrFillBits; - - for (i = 0; i < numCrcBits; i++) { - INT bit; - bit = FDKreadBits(&tmpCRCBuf, 1); - crcAdvance(SBR_CRC_POLY, SBR_CRC_MASK, &crcReg, bit, 1); - } - crcReg &= (SBR_CRC_RANGE); - - /* - * Write CRC data. - */ - FDKwriteBits(&hCmonData->tmpWriteBitbuf, crcReg, SI_SBR_CRC_BITS); - } - } - - FDKsyncCache(&hCmonData->tmpWriteBitbuf); -} --- a/libSBRenc/src/env_bit.h +++ /dev/null @@ -1,135 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Remaining SBR Bit Writing Routines -*/ - -#ifndef ENV_BIT_H -#define ENV_BIT_H - -#include "sbr_encoder.h" -#include "FDK_crc.h" - -/* G(x) = x^10 + x^9 + x^5 + x^4 + x + 1 */ -#define SBR_CRC_POLY (0x0233) -#define SBR_CRC_MASK (0x0200) -#define SBR_CRC_RANGE (0x03FF) -#define SBR_CRC_MAXREGS 1 -#define SBR_CRCINIT (0x0) - -#define SI_SBR_CRC_ENABLE_BITS 0 -#define SI_SBR_CRC_BITS 10 -#define SI_SBR_DRM_CRC_BITS 8 - -struct COMMON_DATA; - -INT FDKsbrEnc_InitSbrBitstream(struct COMMON_DATA *hCmonData, UCHAR *memoryBase, - INT memorySize, HANDLE_FDK_CRCINFO hCrcInfo, - UINT sbrSyntaxFlags); - -void FDKsbrEnc_AssembleSbrBitstream(struct COMMON_DATA *hCmonData, - HANDLE_FDK_CRCINFO hCrcInfo, INT crcRegion, - UINT sbrSyntaxFlags); - -#endif /* #ifndef ENV_BIT_H */ --- a/libSBRenc/src/env_est.cpp +++ /dev/null @@ -1,1985 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -#include "env_est.h" -#include "tran_det.h" - -#include "qmf.h" - -#include "fram_gen.h" -#include "bit_sbr.h" -#include "cmondata.h" -#include "sbrenc_ram.h" - -#include "genericStds.h" - -#define QUANT_ERROR_THRES 200 -#define Y_NRG_SCALE 5 /* noCols = 32 -> shift(5) */ -#define MAX_NRG_SLOTS_LD 16 - -static const UCHAR panTable[2][10] = {{0, 2, 4, 6, 8, 12, 16, 20, 24}, - {0, 2, 4, 8, 12, 0, 0, 0, 0}}; -static const UCHAR maxIndex[2] = {9, 5}; - -/****************************************************************************** - Functionname: FDKsbrEnc_GetTonality -******************************************************************************/ -/***************************************************************************/ -/*! - - \brief Calculates complete energy per band from the energy values - of the QMF subsamples. - - \brief quotaMatrix - calculated in FDKsbrEnc_CalculateTonalityQuotas() - \brief noEstPerFrame - number of estimations per frame - \brief startIndex - start index for the quota matrix - \brief Energies - energy matrix - \brief startBand - start band - \brief stopBand - number of QMF bands - \brief numberCols - number of QMF subsamples - - \return mean tonality of the 5 bands with the highest energy - scaled by 2^(RELAXATION_SHIFT+2)*RELAXATION_FRACT - -****************************************************************************/ -static FIXP_DBL FDKsbrEnc_GetTonality(const FIXP_DBL *const *quotaMatrix, - const INT noEstPerFrame, - const INT startIndex, - const FIXP_DBL *const *Energies, - const UCHAR startBand, const INT stopBand, - const INT numberCols) { - UCHAR b, e, k; - INT no_enMaxBand[SBR_MAX_ENERGY_VALUES] = {-1, -1, -1, -1, -1}; - FIXP_DBL energyMax[SBR_MAX_ENERGY_VALUES] = { - FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), - FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f)}; - FIXP_DBL energyMaxMin = MAXVAL_DBL; /* min. energy in energyMax array */ - UCHAR posEnergyMaxMin = 0; /* min. energy in energyMax array position */ - FIXP_DBL tonalityBand[SBR_MAX_ENERGY_VALUES] = { - FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f), - FL2FXCONST_DBL(0.0f), FL2FXCONST_DBL(0.0f)}; - FIXP_DBL globalTonality = FL2FXCONST_DBL(0.0f); - FIXP_DBL energyBand[64]; - INT maxNEnergyValues; /* max. number of max. energy values */ - - /*** Sum up energies for each band ***/ - FDK_ASSERT(numberCols == 15 || numberCols == 16); - /* numberCols is always 15 or 16 for ELD. In case of 16 bands, the - energyBands are initialized with the [15]th column. - The rest of the column energies are added in the next step. */ - if (numberCols == 15) { - for (b = startBand; b < stopBand; b++) { - energyBand[b] = FL2FXCONST_DBL(0.0f); - } - } else { - for (b = startBand; b < stopBand; b++) { - energyBand[b] = Energies[15][b] >> 4; - } - } - - for (k = 0; k < 15; k++) { - for (b = startBand; b < stopBand; b++) { - energyBand[b] += Energies[k][b] >> 4; - } - } - - /*** Determine 5 highest band-energies ***/ - maxNEnergyValues = fMin(SBR_MAX_ENERGY_VALUES, stopBand - startBand); - - /* Get min. value in energyMax array */ - energyMaxMin = energyMax[0] = energyBand[startBand]; - no_enMaxBand[0] = startBand; - posEnergyMaxMin = 0; - for (k = 1; k < maxNEnergyValues; k++) { - energyMax[k] = energyBand[startBand + k]; - no_enMaxBand[k] = startBand + k; - if (energyMaxMin > energyMax[k]) { - energyMaxMin = energyMax[k]; - posEnergyMaxMin = k; - } - } - - for (b = startBand + maxNEnergyValues; b < stopBand; b++) { - if (energyBand[b] > energyMaxMin) { - energyMax[posEnergyMaxMin] = energyBand[b]; - no_enMaxBand[posEnergyMaxMin] = b; - - /* Again, get min. value in energyMax array */ - energyMaxMin = energyMax[0]; - posEnergyMaxMin = 0; - for (k = 1; k < maxNEnergyValues; k++) { - if (energyMaxMin > energyMax[k]) { - energyMaxMin = energyMax[k]; - posEnergyMaxMin = k; - } - } - } - } - /*** End determine 5 highest band-energies ***/ - - /* Get tonality values for 5 highest energies */ - for (e = 0; e < maxNEnergyValues; e++) { - tonalityBand[e] = FL2FXCONST_DBL(0.0f); - for (k = 0; k < noEstPerFrame; k++) { - tonalityBand[e] += quotaMatrix[startIndex + k][no_enMaxBand[e]] >> 1; - } - globalTonality += - tonalityBand[e] >> 2; /* headroom of 2+1 (max. 5 additions) */ - } - - return globalTonality; -} - -/***************************************************************************/ -/*! - - \brief Calculates energy form real and imaginary part of - the QMF subsamples - - \return none - -****************************************************************************/ -LNK_SECTION_CODE_L1 -static void FDKsbrEnc_getEnergyFromCplxQmfData( - FIXP_DBL **RESTRICT energyValues, /*!< the result of the operation */ - FIXP_DBL **RESTRICT realValues, /*!< the real part of the QMF subsamples */ - FIXP_DBL **RESTRICT - imagValues, /*!< the imaginary part of the QMF subsamples */ - INT numberBands, /*!< number of QMF bands */ - INT numberCols, /*!< number of QMF subsamples */ - INT *qmfScale, /*!< sclefactor of QMF subsamples */ - INT *energyScale) /*!< scalefactor of energies */ -{ - int j, k; - int scale; - FIXP_DBL max_val = FL2FXCONST_DBL(0.0f); - - /* Get Scratch buffer */ - C_ALLOC_SCRATCH_START(tmpNrg, FIXP_DBL, 32 * 64 / 2) - - /* Get max possible scaling of QMF data */ - scale = DFRACT_BITS; - for (k = 0; k < numberCols; k++) { - scale = fixMin(scale, fixMin(getScalefactor(realValues[k], numberBands), - getScalefactor(imagValues[k], numberBands))); - } - - /* Tweak scaling stability for zero signal to non-zero signal transitions */ - if (scale >= DFRACT_BITS - 1) { - scale = (FRACT_BITS - 1 - *qmfScale); - } - /* prevent scaling of QMF values to -1.f */ - scale = fixMax(0, scale - 1); - - /* Update QMF scale */ - *qmfScale += scale; - - /* - Calculate energy of each time slot pair, max energy - and shift QMF values as far as possible to the left. - */ - { - FIXP_DBL *nrgValues = tmpNrg; - for (k = 0; k < numberCols; k += 2) { - /* Load band vector addresses of 2 consecutive timeslots */ - FIXP_DBL *RESTRICT r0 = realValues[k]; - FIXP_DBL *RESTRICT i0 = imagValues[k]; - FIXP_DBL *RESTRICT r1 = realValues[k + 1]; - FIXP_DBL *RESTRICT i1 = imagValues[k + 1]; - for (j = 0; j < numberBands; j++) { - FIXP_DBL energy; - FIXP_DBL tr0, tr1, ti0, ti1; - - /* Read QMF values of 2 timeslots */ - tr0 = r0[j]; - tr1 = r1[j]; - ti0 = i0[j]; - ti1 = i1[j]; - - /* Scale QMF Values and Calc Energy average of both timeslots */ - tr0 <<= scale; - ti0 <<= scale; - energy = fPow2AddDiv2(fPow2Div2(tr0), ti0) >> 1; - - tr1 <<= scale; - ti1 <<= scale; - energy += fPow2AddDiv2(fPow2Div2(tr1), ti1) >> 1; - - /* Write timeslot pair energy to scratch */ - *nrgValues++ = energy; - max_val = fixMax(max_val, energy); - - /* Write back scaled QMF values */ - r0[j] = tr0; - r1[j] = tr1; - i0[j] = ti0; - i1[j] = ti1; - } - } - } - /* energyScale: scalefactor energies of current frame */ - *energyScale = - 2 * (*qmfScale) - - 1; /* if qmfScale > 0: nr of right shifts otherwise nr of left shifts */ - - /* Scale timeslot pair energies and write to output buffer */ - scale = CountLeadingBits(max_val); - { - FIXP_DBL *nrgValues = tmpNrg; - for (k = 0; k> 1; k++) { - scaleValues(energyValues[k], nrgValues, numberBands, scale); - nrgValues += numberBands; - } - *energyScale += scale; - } - - /* Free Scratch buffer */ - C_ALLOC_SCRATCH_END(tmpNrg, FIXP_DBL, 32 * 64 / 2) -} - -LNK_SECTION_CODE_L1 -static void FDKsbrEnc_getEnergyFromCplxQmfDataFull( - FIXP_DBL **RESTRICT energyValues, /*!< the result of the operation */ - FIXP_DBL **RESTRICT realValues, /*!< the real part of the QMF subsamples */ - FIXP_DBL **RESTRICT - imagValues, /*!< the imaginary part of the QMF subsamples */ - int numberBands, /*!< number of QMF bands */ - int numberCols, /*!< number of QMF subsamples */ - int *qmfScale, /*!< scalefactor of QMF subsamples */ - int *energyScale) /*!< scalefactor of energies */ -{ - int j, k; - int scale; - FIXP_DBL max_val = FL2FXCONST_DBL(0.0f); - - /* Get Scratch buffer */ - C_ALLOC_SCRATCH_START(tmpNrg, FIXP_DBL, MAX_NRG_SLOTS_LD * 64) - - FDK_ASSERT(numberCols <= MAX_NRG_SLOTS_LD); - FDK_ASSERT(numberBands <= 64); - - /* Get max possible scaling of QMF data */ - scale = DFRACT_BITS; - for (k = 0; k < numberCols; k++) { - scale = fixMin(scale, fixMin(getScalefactor(realValues[k], numberBands), - getScalefactor(imagValues[k], numberBands))); - } - - /* Tweak scaling stability for zero signal to non-zero signal transitions */ - if (scale >= DFRACT_BITS - 1) { - scale = (FRACT_BITS - 1 - *qmfScale); - } - /* prevent scaling of QFM values to -1.f */ - scale = fixMax(0, scale - 1); - - /* Update QMF scale */ - *qmfScale += scale; - - /* - Calculate energy of each time slot pair, max energy - and shift QMF values as far as possible to the left. - */ - { - FIXP_DBL *nrgValues = tmpNrg; - for (k = 0; k < numberCols; k++) { - /* Load band vector addresses of 1 timeslot */ - FIXP_DBL *RESTRICT r0 = realValues[k]; - FIXP_DBL *RESTRICT i0 = imagValues[k]; - for (j = 0; j < numberBands; j++) { - FIXP_DBL energy; - FIXP_DBL tr0, ti0; - - /* Read QMF values of 1 timeslot */ - tr0 = r0[j]; - ti0 = i0[j]; - - /* Scale QMF Values and Calc Energy */ - tr0 <<= scale; - ti0 <<= scale; - energy = fPow2AddDiv2(fPow2Div2(tr0), ti0); - *nrgValues++ = energy; - - max_val = fixMax(max_val, energy); - - /* Write back scaled QMF values */ - r0[j] = tr0; - i0[j] = ti0; - } - } - } - /* energyScale: scalefactor energies of current frame */ - *energyScale = - 2 * (*qmfScale) - - 1; /* if qmfScale > 0: nr of right shifts otherwise nr of left shifts */ - - /* Scale timeslot pair energies and write to output buffer */ - scale = CountLeadingBits(max_val); - { - FIXP_DBL *nrgValues = tmpNrg; - for (k = 0; k < numberCols; k++) { - scaleValues(energyValues[k], nrgValues, numberBands, scale); - nrgValues += numberBands; - } - *energyScale += scale; - } - - /* Free Scratch buffer */ - C_ALLOC_SCRATCH_END(tmpNrg, FIXP_DBL, MAX_NRG_SLOTS_LD * 64) -} - -/***************************************************************************/ -/*! - - \brief Quantisation of the panorama value (balance) - - \return the quantized pan value - -****************************************************************************/ -static INT mapPanorama(INT nrgVal, /*! integer value of the energy */ - INT ampRes, /*! amplitude resolution [1.5/3dB] */ - INT *quantError /*! quantization error of energy val*/ -) { - int i; - INT min_val, val; - UCHAR panIndex; - INT sign; - - sign = nrgVal > 0 ? 1 : -1; - - nrgVal *= sign; - - min_val = FDK_INT_MAX; - panIndex = 0; - for (i = 0; i < maxIndex[ampRes]; i++) { - val = fixp_abs((nrgVal - (INT)panTable[ampRes][i])); - - if (val < min_val) { - min_val = val; - panIndex = i; - } - } - - *quantError = min_val; - - return panTable[ampRes][maxIndex[ampRes] - 1] + - sign * panTable[ampRes][panIndex]; -} - -/***************************************************************************/ -/*! - - \brief Quantisation of the noise floor levels - - \return void - -****************************************************************************/ -static void sbrNoiseFloorLevelsQuantisation( - SCHAR *RESTRICT iNoiseLevels, /*! quantized noise levels */ - FIXP_DBL *RESTRICT - NoiseLevels, /*! the noise levels. Exponent = LD_DATA_SHIFT */ - INT coupling /*! the coupling flag */ -) { - INT i; - INT tmp, dummy; - - /* Quantisation, similar to sfb quant... */ - for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) { - /* tmp = NoiseLevels[i] > (PFLOAT)30.0f ? 30: (INT) (NoiseLevels[i] + - * (PFLOAT)0.5); */ - /* 30>>LD_DATA_SHIFT = 0.46875 */ - if ((FIXP_DBL)NoiseLevels[i] > FL2FXCONST_DBL(0.46875f)) { - tmp = 30; - } else { - /* tmp = (INT)((FIXP_DBL)NoiseLevels[i] + (FL2FXCONST_DBL(0.5f)>>(*/ - /* FRACT_BITS+ */ /* 6-1)));*/ - /* tmp = tmp >> (DFRACT_BITS-1-LD_DATA_SHIFT); */ /* conversion to integer - happens here */ - /* rounding is done by shifting one bit less than necessary to the right, - * adding '1' and then shifting the final bit */ - tmp = ((((INT)NoiseLevels[i]) >> - (DFRACT_BITS - 1 - LD_DATA_SHIFT))); /* conversion to integer */ - if (tmp != 0) tmp += 1; - } - - if (coupling) { - tmp = tmp < -30 ? -30 : tmp; - tmp = mapPanorama(tmp, 1, &dummy); - } - iNoiseLevels[i] = tmp; - } -} - -/***************************************************************************/ -/*! - - \brief Calculation of noise floor for coupling - - \return void - -****************************************************************************/ -static void coupleNoiseFloor( - FIXP_DBL *RESTRICT noise_level_left, /*! noise level left (modified)*/ - FIXP_DBL *RESTRICT noise_level_right /*! noise level right (modified)*/ -) { - FIXP_DBL cmpValLeft, cmpValRight; - INT i; - FIXP_DBL temp1, temp2; - - for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) { - /* Calculation of the power function using ld64: - z = x^y; - z' = CalcLd64(z) = y*CalcLd64(x)/64; - z = CalcInvLd64(z'); - */ - cmpValLeft = NOISE_FLOOR_OFFSET_64 - noise_level_left[i]; - cmpValRight = NOISE_FLOOR_OFFSET_64 - noise_level_right[i]; - - if (cmpValRight < FL2FXCONST_DBL(0.0f)) { - temp1 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_right[i]); - } else { - temp1 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_right[i]); - temp1 = temp1 << (DFRACT_BITS - 1 - LD_DATA_SHIFT - - 1); /* INT to fract conversion of result, if input of - CalcInvLdData is positiv */ - } - - if (cmpValLeft < FL2FXCONST_DBL(0.0f)) { - temp2 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_left[i]); - } else { - temp2 = CalcInvLdData(NOISE_FLOOR_OFFSET_64 - noise_level_left[i]); - temp2 = temp2 << (DFRACT_BITS - 1 - LD_DATA_SHIFT - - 1); /* INT to fract conversion of result, if input of - CalcInvLdData is positiv */ - } - - if ((cmpValLeft < FL2FXCONST_DBL(0.0f)) && - (cmpValRight < FL2FXCONST_DBL(0.0f))) { - noise_level_left[i] = - NOISE_FLOOR_OFFSET_64 - - (CalcLdData( - ((temp1 >> 1) + - (temp2 >> 1)))); /* no scaling needed! both values are dfract */ - noise_level_right[i] = CalcLdData(temp2) - CalcLdData(temp1); - } - - if ((cmpValLeft >= FL2FXCONST_DBL(0.0f)) && - (cmpValRight >= FL2FXCONST_DBL(0.0f))) { - noise_level_left[i] = NOISE_FLOOR_OFFSET_64 - - (CalcLdData(((temp1 >> 1) + (temp2 >> 1))) + - FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */ - noise_level_right[i] = CalcLdData(temp2) - CalcLdData(temp1); - } - - if ((cmpValLeft >= FL2FXCONST_DBL(0.0f)) && - (cmpValRight < FL2FXCONST_DBL(0.0f))) { - noise_level_left[i] = NOISE_FLOOR_OFFSET_64 - - (CalcLdData(((temp1 >> (7 + 1)) + (temp2 >> 1))) + - FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */ - noise_level_right[i] = - (CalcLdData(temp2) + FL2FXCONST_DBL(0.109375f)) - CalcLdData(temp1); - } - - if ((cmpValLeft < FL2FXCONST_DBL(0.0f)) && - (cmpValRight >= FL2FXCONST_DBL(0.0f))) { - noise_level_left[i] = NOISE_FLOOR_OFFSET_64 - - (CalcLdData(((temp1 >> 1) + (temp2 >> (7 + 1)))) + - FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */ - noise_level_right[i] = CalcLdData(temp2) - - (CalcLdData(temp1) + - FL2FXCONST_DBL(0.109375f)); /* scaled with 7/64 */ - } - } -} - -/***************************************************************************/ -/*! - - \brief Calculation of energy starting in lower band (li) up to upper band -(ui) over slots (start_pos) to (stop_pos) - - \return void - -****************************************************************************/ - -static FIXP_DBL getEnvSfbEnergy( - INT li, /*! lower band */ - INT ui, /*! upper band */ - INT start_pos, /*! start slot */ - INT stop_pos, /*! stop slot */ - INT border_pos, /*! slots scaling border */ - FIXP_DBL **YBuffer, /*! sfb energy buffer */ - INT YBufferSzShift, /*! Energy buffer index scale */ - INT scaleNrg0, /*! scaling of lower slots */ - INT scaleNrg1) /*! scaling of upper slots */ -{ - /* use dynamic scaling for outer energy loop; - energies are critical and every bit is important */ - int sc0, sc1, k, l; - - FIXP_DBL nrgSum, nrg1, nrg2, accu1, accu2; - INT dynScale, dynScale1, dynScale2; - if (ui - li == 0) - dynScale = DFRACT_BITS - 1; - else - dynScale = CalcLdInt(ui - li) >> (DFRACT_BITS - 1 - LD_DATA_SHIFT); - - sc0 = fixMin(scaleNrg0, Y_NRG_SCALE); - sc1 = fixMin(scaleNrg1, Y_NRG_SCALE); - /* dynScale{1,2} is set such that the right shift below is positive */ - dynScale1 = fixMin((scaleNrg0 - sc0), dynScale); - dynScale2 = fixMin((scaleNrg1 - sc1), dynScale); - nrgSum = accu1 = accu2 = (FIXP_DBL)0; - - for (k = li; k < ui; k++) { - nrg1 = nrg2 = (FIXP_DBL)0; - for (l = start_pos; l < border_pos; l++) { - nrg1 += YBuffer[l >> YBufferSzShift][k] >> sc0; - } - for (; l < stop_pos; l++) { - nrg2 += YBuffer[l >> YBufferSzShift][k] >> sc1; - } - accu1 += (nrg1 >> dynScale1); - accu2 += (nrg2 >> dynScale2); - } - /* This shift factor is always positive. See comment above. */ - nrgSum += - (accu1 >> fixMin((scaleNrg0 - sc0 - dynScale1), (DFRACT_BITS - 1))) + - (accu2 >> fixMin((scaleNrg1 - sc1 - dynScale2), (DFRACT_BITS - 1))); - - return nrgSum; -} - -/***************************************************************************/ -/*! - - \brief Energy compensation in missing harmonic mode - - \return void - -****************************************************************************/ -static FIXP_DBL mhLoweringEnergy(FIXP_DBL nrg, INT M) { - /* - Compensating for the fact that we in the decoder map the "average energy to - every QMF band, and use this when we calculate the boost-factor. Since the - mapped energy isn't the average energy but the maximum energy in case of - missing harmonic creation, we will in the boost function calculate that too - much limiting has been applied and hence we will boost the signal although - it isn't called for. Hence we need to compensate for this by lowering the - transmitted energy values for the sines so they will get the correct level - after the boost is applied. - */ - if (M > 2) { - INT tmpScale; - tmpScale = CountLeadingBits(nrg); - nrg <<= tmpScale; - nrg = fMult(nrg, FL2FXCONST_DBL(0.398107267f)); /* The maximum boost - is 1.584893, so the - maximum attenuation - should be - square(1/1.584893) = - 0.398107267 */ - nrg >>= tmpScale; - } else { - if (M > 1) { - nrg >>= 1; - } - } - - return nrg; -} - -/***************************************************************************/ -/*! - - \brief Energy compensation in none missing harmonic mode - - \return void - -****************************************************************************/ -static FIXP_DBL nmhLoweringEnergy(FIXP_DBL nrg, const FIXP_DBL nrgSum, - const INT nrgSum_scale, const INT M) { - if (nrg > FL2FXCONST_DBL(0)) { - int sc = 0; - /* gain = nrgSum / (nrg*(M+1)) */ - FIXP_DBL gain = fMult(fDivNorm(nrgSum, nrg, &sc), GetInvInt(M + 1)); - sc += nrgSum_scale; - - /* reduce nrg if gain smaller 1.f */ - if (!((sc >= 0) && (gain > ((FIXP_DBL)MAXVAL_DBL >> sc)))) { - nrg = fMult(scaleValue(gain, sc), nrg); - } - } - return nrg; -} - -/***************************************************************************/ -/*! - - \brief calculates the envelope values from the energies, depending on - framing and stereo mode - - \return void - -****************************************************************************/ -static void calculateSbrEnvelope( - FIXP_DBL **RESTRICT YBufferLeft, /*! energy buffer left */ - FIXP_DBL **RESTRICT YBufferRight, /*! energy buffer right */ - int *RESTRICT YBufferScaleLeft, /*! scale energy buffer left */ - int *RESTRICT YBufferScaleRight, /*! scale energy buffer right */ - const SBR_FRAME_INFO *frame_info, /*! frame info vector */ - SCHAR *RESTRICT sfb_nrgLeft, /*! sfb energy buffer left */ - SCHAR *RESTRICT sfb_nrgRight, /*! sfb energy buffer right */ - HANDLE_SBR_CONFIG_DATA h_con, /*! handle to config data */ - HANDLE_ENV_CHANNEL h_sbr, /*! envelope channel handle */ - SBR_STEREO_MODE stereoMode, /*! stereo coding mode */ - INT *maxQuantError, /*! maximum quantization error, for panorama. */ - int YBufferSzShift) /*! Energy buffer index scale */ - -{ - int env, j, m = 0; - INT no_of_bands, start_pos, stop_pos, li, ui; - FREQ_RES freq_res; - - INT ca = 2 - h_sbr->encEnvData.init_sbr_amp_res; - INT oneBitLess = 0; - if (ca == 2) - oneBitLess = - 1; /* LD_DATA_SHIFT => ld64 scaling; one bit less for rounding */ - - INT quantError; - INT nEnvelopes = frame_info->nEnvelopes; - INT short_env = frame_info->shortEnv - 1; - INT timeStep = h_sbr->sbrExtractEnvelope.time_step; - INT commonScale, scaleLeft0, scaleLeft1; - INT scaleRight0 = 0, scaleRight1 = 0; - - commonScale = fixMin(YBufferScaleLeft[0], YBufferScaleLeft[1]); - - if (stereoMode == SBR_COUPLING) { - commonScale = fixMin(commonScale, YBufferScaleRight[0]); - commonScale = fixMin(commonScale, YBufferScaleRight[1]); - } - - commonScale = commonScale - 7; - - scaleLeft0 = YBufferScaleLeft[0] - commonScale; - scaleLeft1 = YBufferScaleLeft[1] - commonScale; - FDK_ASSERT((scaleLeft0 >= 0) && (scaleLeft1 >= 0)); - - if (stereoMode == SBR_COUPLING) { - scaleRight0 = YBufferScaleRight[0] - commonScale; - scaleRight1 = YBufferScaleRight[1] - commonScale; - FDK_ASSERT((scaleRight0 >= 0) && (scaleRight1 >= 0)); - *maxQuantError = 0; - } - - for (env = 0; env < nEnvelopes; env++) { - FIXP_DBL pNrgLeft[32]; - FIXP_DBL pNrgRight[32]; - int envNrg_scale; - FIXP_DBL envNrgLeft = FL2FXCONST_DBL(0.0f); - FIXP_DBL envNrgRight = FL2FXCONST_DBL(0.0f); - int missingHarmonic[32]; - int count[32]; - - start_pos = timeStep * frame_info->borders[env]; - stop_pos = timeStep * frame_info->borders[env + 1]; - freq_res = frame_info->freqRes[env]; - no_of_bands = h_con->nSfb[freq_res]; - envNrg_scale = DFRACT_BITS - fNormz((FIXP_DBL)no_of_bands); - if (env == short_env) { - j = fMax(2, timeStep); /* consider at least 2 QMF slots less for short - envelopes (envelopes just before transients) */ - if ((stop_pos - start_pos - j) > 0) { - stop_pos = stop_pos - j; - } - } - for (j = 0; j < no_of_bands; j++) { - FIXP_DBL nrgLeft = FL2FXCONST_DBL(0.0f); - FIXP_DBL nrgRight = FL2FXCONST_DBL(0.0f); - - li = h_con->freqBandTable[freq_res][j]; - ui = h_con->freqBandTable[freq_res][j + 1]; - - if (freq_res == FREQ_RES_HIGH) { - if (j == 0 && ui - li > 1) { - li++; - } - } else { - if (j == 0 && ui - li > 2) { - li++; - } - } - - /* - Find out whether a sine will be missing in the scale-factor - band that we're currently processing. - */ - missingHarmonic[j] = 0; - - if (h_sbr->encEnvData.addHarmonicFlag) { - if (freq_res == FREQ_RES_HIGH) { - if (h_sbr->encEnvData - .addHarmonic[j]) { /*A missing sine in the current band*/ - missingHarmonic[j] = 1; - } - } else { - INT i; - INT startBandHigh = 0; - INT stopBandHigh = 0; - - while (h_con->freqBandTable[FREQ_RES_HIGH][startBandHigh] < - h_con->freqBandTable[FREQ_RES_LOW][j]) - startBandHigh++; - while (h_con->freqBandTable[FREQ_RES_HIGH][stopBandHigh] < - h_con->freqBandTable[FREQ_RES_LOW][j + 1]) - stopBandHigh++; - - for (i = startBandHigh; i < stopBandHigh; i++) { - if (h_sbr->encEnvData.addHarmonic[i]) { - missingHarmonic[j] = 1; - } - } - } - } - - /* - If a sine is missing in a scalefactorband, with more than one qmf - channel use the nrg from the channel with the largest nrg rather than - the mean. Compensate for the boost calculation in the decdoder. - */ - int border_pos = - fixMin(stop_pos, h_sbr->sbrExtractEnvelope.YBufferWriteOffset - << YBufferSzShift); - - if (missingHarmonic[j]) { - int k; - count[j] = stop_pos - start_pos; - nrgLeft = FL2FXCONST_DBL(0.0f); - - for (k = li; k < ui; k++) { - FIXP_DBL tmpNrg; - tmpNrg = getEnvSfbEnergy(k, k + 1, start_pos, stop_pos, border_pos, - YBufferLeft, YBufferSzShift, scaleLeft0, - scaleLeft1); - - nrgLeft = fixMax(nrgLeft, tmpNrg); - } - - /* Energy lowering compensation */ - nrgLeft = mhLoweringEnergy(nrgLeft, ui - li); - - if (stereoMode == SBR_COUPLING) { - nrgRight = FL2FXCONST_DBL(0.0f); - - for (k = li; k < ui; k++) { - FIXP_DBL tmpNrg; - tmpNrg = getEnvSfbEnergy(k, k + 1, start_pos, stop_pos, border_pos, - YBufferRight, YBufferSzShift, scaleRight0, - scaleRight1); - - nrgRight = fixMax(nrgRight, tmpNrg); - } - - /* Energy lowering compensation */ - nrgRight = mhLoweringEnergy(nrgRight, ui - li); - } - } /* end missingHarmonic */ - else { - count[j] = (stop_pos - start_pos) * (ui - li); - - nrgLeft = getEnvSfbEnergy(li, ui, start_pos, stop_pos, border_pos, - YBufferLeft, YBufferSzShift, scaleLeft0, - scaleLeft1); - - if (stereoMode == SBR_COUPLING) { - nrgRight = getEnvSfbEnergy(li, ui, start_pos, stop_pos, border_pos, - YBufferRight, YBufferSzShift, scaleRight0, - scaleRight1); - } - } /* !missingHarmonic */ - - /* save energies */ - pNrgLeft[j] = nrgLeft; - pNrgRight[j] = nrgRight; - envNrgLeft += (nrgLeft >> envNrg_scale); - envNrgRight += (nrgRight >> envNrg_scale); - } /* j */ - - for (j = 0; j < no_of_bands; j++) { - FIXP_DBL nrgLeft2 = FL2FXCONST_DBL(0.0f); - FIXP_DBL nrgLeft = pNrgLeft[j]; - FIXP_DBL nrgRight = pNrgRight[j]; - - /* None missing harmonic Energy lowering compensation */ - if (!missingHarmonic[j] && h_sbr->fLevelProtect) { - /* in case of missing energy in base band, - reduce reference energy to prevent overflows in decoder output */ - nrgLeft = - nmhLoweringEnergy(nrgLeft, envNrgLeft, envNrg_scale, no_of_bands); - if (stereoMode == SBR_COUPLING) { - nrgRight = nmhLoweringEnergy(nrgRight, envNrgRight, envNrg_scale, - no_of_bands); - } - } - - if (stereoMode == SBR_COUPLING) { - /* calc operation later with log */ - nrgLeft2 = nrgLeft; - nrgLeft = (nrgRight + nrgLeft) >> 1; - } - - /* nrgLeft = f20_log2(nrgLeft / (PFLOAT)(count * 64))+(PFLOAT)44; */ - /* If nrgLeft == 0 then the Log calculations below do fail. */ - if (nrgLeft > FL2FXCONST_DBL(0.0f)) { - FIXP_DBL tmp0, tmp1, tmp2, tmp3; - INT tmpScale; - - tmpScale = CountLeadingBits(nrgLeft); - nrgLeft = nrgLeft << tmpScale; - - tmp0 = CalcLdData(nrgLeft); /* scaled by 1/64 */ - tmp1 = ((FIXP_DBL)(commonScale + tmpScale)) - << (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1); /* scaled by 1/64 */ - tmp2 = ((FIXP_DBL)(count[j] * 64)) << (DFRACT_BITS - 1 - 14 - 1); - tmp2 = CalcLdData(tmp2); /* scaled by 1/64 */ - tmp3 = FL2FXCONST_DBL(0.6875f - 0.21875f - 0.015625f) >> - 1; /* scaled by 1/64 */ - - nrgLeft = ((tmp0 - tmp2) >> 1) + (tmp3 - tmp1); - } else { - nrgLeft = FL2FXCONST_DBL(-1.0f); - } - - /* ld64 to integer conversion */ - nrgLeft = fixMin(fixMax(nrgLeft, FL2FXCONST_DBL(0.0f)), - (FL2FXCONST_DBL(0.5f) >> oneBitLess)); - nrgLeft = (FIXP_DBL)(LONG)nrgLeft >> - (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1 - oneBitLess - 1); - sfb_nrgLeft[m] = ((INT)nrgLeft + 1) >> 1; /* rounding */ - - if (stereoMode == SBR_COUPLING) { - FIXP_DBL scaleFract; - int sc0, sc1; - - nrgLeft2 = fixMax((FIXP_DBL)0x1, nrgLeft2); - nrgRight = fixMax((FIXP_DBL)0x1, nrgRight); - - sc0 = CountLeadingBits(nrgLeft2); - sc1 = CountLeadingBits(nrgRight); - - scaleFract = - ((FIXP_DBL)(sc0 - sc1)) - << (DFRACT_BITS - 1 - - LD_DATA_SHIFT); /* scale value in ld64 representation */ - nrgRight = CalcLdData(nrgLeft2 << sc0) - CalcLdData(nrgRight << sc1) - - scaleFract; - - /* ld64 to integer conversion */ - nrgRight = (FIXP_DBL)(LONG)(nrgRight) >> - (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1 - oneBitLess); - nrgRight = (nrgRight + (FIXP_DBL)1) >> 1; /* rounding */ - - sfb_nrgRight[m] = mapPanorama( - nrgRight, h_sbr->encEnvData.init_sbr_amp_res, &quantError); - - *maxQuantError = fixMax(quantError, *maxQuantError); - } - - m++; - } /* j */ - - /* Do energy compensation for sines that are present in two - QMF-bands in the original, but will only occur in one band in - the decoder due to the synthetic sine coding.*/ - if (h_con->useParametricCoding) { - m -= no_of_bands; - for (j = 0; j < no_of_bands; j++) { - if (freq_res == FREQ_RES_HIGH && - h_sbr->sbrExtractEnvelope.envelopeCompensation[j]) { - sfb_nrgLeft[m] -= - (ca * - fixp_abs( - (INT)h_sbr->sbrExtractEnvelope.envelopeCompensation[j])); - } - sfb_nrgLeft[m] = fixMax(0, sfb_nrgLeft[m]); - m++; - } - } /* useParametricCoding */ - - } /* env loop */ -} - -/***************************************************************************/ -/*! - - \brief calculates the noise floor and the envelope values from the - energies, depending on framing and stereo mode - - FDKsbrEnc_extractSbrEnvelope is the main function for encoding and writing the - envelope and the noise floor. The function includes the following processes: - - -Analysis subband filtering. - -Encoding SA and pan parameters (if enabled). - -Transient detection. - -****************************************************************************/ - -LNK_SECTION_CODE_L1 -void FDKsbrEnc_extractSbrEnvelope1( - HANDLE_SBR_CONFIG_DATA h_con, /*! handle to config data */ - HANDLE_SBR_HEADER_DATA sbrHeaderData, - HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData, HANDLE_ENV_CHANNEL hEnvChan, - HANDLE_COMMON_DATA hCmonData, SBR_ENV_TEMP_DATA *eData, - SBR_FRAME_TEMP_DATA *fData) { - HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &hEnvChan->sbrExtractEnvelope; - - if (sbrExtrEnv->YBufferSzShift == 0) - FDKsbrEnc_getEnergyFromCplxQmfDataFull( - &sbrExtrEnv->YBuffer[sbrExtrEnv->YBufferWriteOffset], - sbrExtrEnv->rBuffer + sbrExtrEnv->rBufferReadOffset, - sbrExtrEnv->iBuffer + sbrExtrEnv->rBufferReadOffset, h_con->noQmfBands, - sbrExtrEnv->no_cols, &hEnvChan->qmfScale, &sbrExtrEnv->YBufferScale[1]); - else - FDKsbrEnc_getEnergyFromCplxQmfData( - &sbrExtrEnv->YBuffer[sbrExtrEnv->YBufferWriteOffset], - sbrExtrEnv->rBuffer + sbrExtrEnv->rBufferReadOffset, - sbrExtrEnv->iBuffer + sbrExtrEnv->rBufferReadOffset, h_con->noQmfBands, - sbrExtrEnv->no_cols, &hEnvChan->qmfScale, &sbrExtrEnv->YBufferScale[1]); - - /* Energie values = - * sbrExtrEnv->YBuffer[sbrExtrEnv->YBufferWriteOffset][x].floatVal * - * (1<<2*7-sbrExtrEnv->YBufferScale[1]) */ - - /* - Precalculation of Tonality Quotas COEFF Transform OK - */ - FDKsbrEnc_CalculateTonalityQuotas( - &hEnvChan->TonCorr, sbrExtrEnv->rBuffer, sbrExtrEnv->iBuffer, - h_con->freqBandTable[HI][h_con->nSfb[HI]], hEnvChan->qmfScale); - - if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { - FIXP_DBL tonality = FDKsbrEnc_GetTonality( - hEnvChan->TonCorr.quotaMatrix, - hEnvChan->TonCorr.numberOfEstimatesPerFrame, - hEnvChan->TonCorr.startIndexMatrix, - sbrExtrEnv->YBuffer + sbrExtrEnv->YBufferWriteOffset, - h_con->freqBandTable[HI][0] + 1, h_con->noQmfBands, - sbrExtrEnv->no_cols); - - hEnvChan->encEnvData.ton_HF[1] = hEnvChan->encEnvData.ton_HF[0]; - hEnvChan->encEnvData.ton_HF[0] = tonality; - - /* tonality is scaled by 2^19/0.524288f (fract part of RELAXATION) */ - hEnvChan->encEnvData.global_tonality = - (hEnvChan->encEnvData.ton_HF[0] >> 1) + - (hEnvChan->encEnvData.ton_HF[1] >> 1); - } - - /* - Transient detection COEFF Transform OK - */ - - if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { - FDKsbrEnc_fastTransientDetect(&hEnvChan->sbrFastTransientDetector, - sbrExtrEnv->YBuffer, sbrExtrEnv->YBufferScale, - sbrExtrEnv->YBufferWriteOffset, - eData->transient_info); - - } else { - FDKsbrEnc_transientDetect( - &hEnvChan->sbrTransientDetector, sbrExtrEnv->YBuffer, - sbrExtrEnv->YBufferScale, eData->transient_info, - sbrExtrEnv->YBufferWriteOffset, sbrExtrEnv->YBufferSzShift, - sbrExtrEnv->time_step, hEnvChan->SbrEnvFrame.frameMiddleSlot); - } - - /* - Generate flags for 2 env in a FIXFIX-frame. - Remove this function to get always 1 env per FIXFIX-frame. - */ - - /* - frame Splitter COEFF Transform OK - */ - FDKsbrEnc_frameSplitter( - sbrExtrEnv->YBuffer, sbrExtrEnv->YBufferScale, - &hEnvChan->sbrTransientDetector, h_con->freqBandTable[1], - eData->transient_info, sbrExtrEnv->YBufferWriteOffset, - sbrExtrEnv->YBufferSzShift, h_con->nSfb[1], sbrExtrEnv->time_step, - sbrExtrEnv->no_cols, &hEnvChan->encEnvData.global_tonality); -} - -/***************************************************************************/ -/*! - - \brief calculates the noise floor and the envelope values from the - energies, depending on framing and stereo mode - - FDKsbrEnc_extractSbrEnvelope is the main function for encoding and writing the - envelope and the noise floor. The function includes the following processes: - - -Determine time/frequency division of current granule. - -Sending transient info to bitstream. - -Set amp_res to 1.5 dB if the current frame contains only one envelope. - -Lock dynamic bandwidth frequency change if the next envelope not starts on a - frame boundary. - -MDCT transposer (needed to detect where harmonics will be missing). - -Spectrum Estimation (used for pulse train and missing harmonics detection). - -Pulse train detection. - -Inverse Filtering detection. - -Waveform Coding. - -Missing Harmonics detection. - -Extract envelope of current frame. - -Noise floor estimation. - -Noise floor quantisation and coding. - -Encode envelope of current frame. - -Send the encoded data to the bitstream. - -Write to bitstream. - -****************************************************************************/ - -LNK_SECTION_CODE_L1 -void FDKsbrEnc_extractSbrEnvelope2( - HANDLE_SBR_CONFIG_DATA h_con, /*! handle to config data */ - HANDLE_SBR_HEADER_DATA sbrHeaderData, - HANDLE_PARAMETRIC_STEREO hParametricStereo, - HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData, HANDLE_ENV_CHANNEL h_envChan0, - HANDLE_ENV_CHANNEL h_envChan1, HANDLE_COMMON_DATA hCmonData, - SBR_ENV_TEMP_DATA *eData, SBR_FRAME_TEMP_DATA *fData, int clearOutput) { - HANDLE_ENV_CHANNEL h_envChan[MAX_NUM_CHANNELS] = {h_envChan0, h_envChan1}; - int ch, i, j, c, YSzShift = h_envChan[0]->sbrExtractEnvelope.YBufferSzShift; - - SBR_STEREO_MODE stereoMode = h_con->stereoMode; - int nChannels = h_con->nChannels; - const int *v_tuning; - static const int v_tuningHEAAC[6] = {0, 2, 4, 0, 0, 0}; - - static const int v_tuningELD[6] = {0, 2, 3, 0, 0, 0}; - - if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) - v_tuning = v_tuningELD; - else - v_tuning = v_tuningHEAAC; - - /* - Select stereo mode. - */ - if (stereoMode == SBR_COUPLING) { - if (eData[0].transient_info[1] && eData[1].transient_info[1]) { - eData[0].transient_info[0] = - fixMin(eData[1].transient_info[0], eData[0].transient_info[0]); - eData[1].transient_info[0] = eData[0].transient_info[0]; - } else { - if (eData[0].transient_info[1] && !eData[1].transient_info[1]) { - eData[1].transient_info[0] = eData[0].transient_info[0]; - } else { - if (!eData[0].transient_info[1] && eData[1].transient_info[1]) - eData[0].transient_info[0] = eData[1].transient_info[0]; - else { - eData[0].transient_info[0] = - fixMax(eData[1].transient_info[0], eData[0].transient_info[0]); - eData[1].transient_info[0] = eData[0].transient_info[0]; - } - } - } - } - - /* - Determine time/frequency division of current granule - */ - eData[0].frame_info = FDKsbrEnc_frameInfoGenerator( - &h_envChan[0]->SbrEnvFrame, eData[0].transient_info, - sbrBitstreamData->rightBorderFIX, - h_envChan[0]->sbrExtractEnvelope.pre_transient_info, - h_envChan[0]->encEnvData.ldGrid, v_tuning); - - h_envChan[0]->encEnvData.hSbrBSGrid = &h_envChan[0]->SbrEnvFrame.SbrGrid; - - /* AAC LD patch for transient prediction */ - if (h_envChan[0]->encEnvData.ldGrid && eData[0].transient_info[2]) { - /* if next frame will start with transient, set shortEnv to - * numEnvelopes(shortend Envelope = shortEnv-1)*/ - h_envChan[0]->SbrEnvFrame.SbrFrameInfo.shortEnv = - h_envChan[0]->SbrEnvFrame.SbrFrameInfo.nEnvelopes; - } - - switch (stereoMode) { - case SBR_LEFT_RIGHT: - case SBR_SWITCH_LRC: - eData[1].frame_info = FDKsbrEnc_frameInfoGenerator( - &h_envChan[1]->SbrEnvFrame, eData[1].transient_info, - sbrBitstreamData->rightBorderFIX, - h_envChan[1]->sbrExtractEnvelope.pre_transient_info, - h_envChan[1]->encEnvData.ldGrid, v_tuning); - - h_envChan[1]->encEnvData.hSbrBSGrid = &h_envChan[1]->SbrEnvFrame.SbrGrid; - - if (h_envChan[1]->encEnvData.ldGrid && eData[1].transient_info[2]) { - /* if next frame will start with transient, set shortEnv to - * numEnvelopes(shortend Envelope = shortEnv-1)*/ - h_envChan[1]->SbrEnvFrame.SbrFrameInfo.shortEnv = - h_envChan[1]->SbrEnvFrame.SbrFrameInfo.nEnvelopes; - } - - /* compare left and right frame_infos */ - if (eData[0].frame_info->nEnvelopes != eData[1].frame_info->nEnvelopes) { - stereoMode = SBR_LEFT_RIGHT; - } else { - for (i = 0; i < eData[0].frame_info->nEnvelopes + 1; i++) { - if (eData[0].frame_info->borders[i] != - eData[1].frame_info->borders[i]) { - stereoMode = SBR_LEFT_RIGHT; - break; - } - } - for (i = 0; i < eData[0].frame_info->nEnvelopes; i++) { - if (eData[0].frame_info->freqRes[i] != - eData[1].frame_info->freqRes[i]) { - stereoMode = SBR_LEFT_RIGHT; - break; - } - } - if (eData[0].frame_info->shortEnv != eData[1].frame_info->shortEnv) { - stereoMode = SBR_LEFT_RIGHT; - } - } - break; - case SBR_COUPLING: - eData[1].frame_info = eData[0].frame_info; - h_envChan[1]->encEnvData.hSbrBSGrid = &h_envChan[0]->SbrEnvFrame.SbrGrid; - break; - case SBR_MONO: - /* nothing to do */ - break; - default: - FDK_ASSERT(0); - } - - for (ch = 0; ch < nChannels; ch++) { - HANDLE_ENV_CHANNEL hEnvChan = h_envChan[ch]; - HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &hEnvChan->sbrExtractEnvelope; - SBR_ENV_TEMP_DATA *ed = &eData[ch]; - - /* - Send transient info to bitstream and store for next call - */ - sbrExtrEnv->pre_transient_info[0] = ed->transient_info[0]; /* tran_pos */ - sbrExtrEnv->pre_transient_info[1] = ed->transient_info[1]; /* tran_flag */ - hEnvChan->encEnvData.noOfEnvelopes = ed->nEnvelopes = - ed->frame_info->nEnvelopes; /* number of envelopes of current frame */ - - /* - Check if the current frame is divided into one envelope only. If so, set - the amplitude resolution to 1.5 dB, otherwise may set back to chosen value - */ - if ((hEnvChan->encEnvData.hSbrBSGrid->frameClass == FIXFIX) && - (ed->nEnvelopes == 1)) { - if (h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { - /* Note: global_tonaliy_float_value == - ((float)hEnvChan->encEnvData.global_tonality/((INT64)(1)<<(31-(19+2)))/0.524288*(2.0/3.0))); - threshold_float_value == - ((float)h_con->thresholdAmpResFF_m/((INT64)(1)<<(31-(h_con->thresholdAmpResFF_e)))/0.524288*(2.0/3.0))); - */ - /* decision of SBR_AMP_RES */ - if (fIsLessThan(/* global_tonality > threshold ? */ - h_con->thresholdAmpResFF_m, h_con->thresholdAmpResFF_e, - hEnvChan->encEnvData.global_tonality, - RELAXATION_SHIFT + 2)) { - hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5; - } else { - hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_3_0; - } - } else - hEnvChan->encEnvData.currentAmpResFF = SBR_AMP_RES_1_5; - - if (hEnvChan->encEnvData.currentAmpResFF != - hEnvChan->encEnvData.init_sbr_amp_res) { - FDKsbrEnc_InitSbrHuffmanTables( - &hEnvChan->encEnvData, &hEnvChan->sbrCodeEnvelope, - &hEnvChan->sbrCodeNoiseFloor, hEnvChan->encEnvData.currentAmpResFF); - } - } else { - if (sbrHeaderData->sbr_amp_res != hEnvChan->encEnvData.init_sbr_amp_res) { - FDKsbrEnc_InitSbrHuffmanTables( - &hEnvChan->encEnvData, &hEnvChan->sbrCodeEnvelope, - &hEnvChan->sbrCodeNoiseFloor, sbrHeaderData->sbr_amp_res); - } - } - - if (!clearOutput) { - /* - Tonality correction parameter extraction (inverse filtering level, noise - floor additional sines). - */ - FDKsbrEnc_TonCorrParamExtr( - &hEnvChan->TonCorr, hEnvChan->encEnvData.sbr_invf_mode_vec, - ed->noiseFloor, &hEnvChan->encEnvData.addHarmonicFlag, - hEnvChan->encEnvData.addHarmonic, sbrExtrEnv->envelopeCompensation, - ed->frame_info, ed->transient_info, h_con->freqBandTable[HI], - h_con->nSfb[HI], hEnvChan->encEnvData.sbr_xpos_mode, - h_con->sbrSyntaxFlags); - } - - /* Low energy in low band fix */ - if (hEnvChan->sbrTransientDetector.prevLowBandEnergy < - hEnvChan->sbrTransientDetector.prevHighBandEnergy && - hEnvChan->sbrTransientDetector.prevHighBandEnergy > FL2FX_DBL(0.03) - /* The fix needs the non-fast transient detector running. - It sets prevLowBandEnergy and prevHighBandEnergy. */ - && !(h_con->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY)) { - hEnvChan->fLevelProtect = 1; - - for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) - hEnvChan->encEnvData.sbr_invf_mode_vec[i] = INVF_HIGH_LEVEL; - } else { - hEnvChan->fLevelProtect = 0; - } - - hEnvChan->encEnvData.sbr_invf_mode = - hEnvChan->encEnvData.sbr_invf_mode_vec[0]; - - hEnvChan->encEnvData.noOfnoisebands = - hEnvChan->TonCorr.sbrNoiseFloorEstimate.noNoiseBands; - - } /* ch */ - - /* - Save number of scf bands per envelope - */ - for (ch = 0; ch < nChannels; ch++) { - for (i = 0; i < eData[ch].nEnvelopes; i++) { - h_envChan[ch]->encEnvData.noScfBands[i] = - (eData[ch].frame_info->freqRes[i] == FREQ_RES_HIGH - ? h_con->nSfb[FREQ_RES_HIGH] - : h_con->nSfb[FREQ_RES_LOW]); - } - } - - /* - Extract envelope of current frame. - */ - switch (stereoMode) { - case SBR_MONO: - calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL, - h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL, - eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con, - h_envChan[0], SBR_MONO, NULL, YSzShift); - break; - case SBR_LEFT_RIGHT: - calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL, - h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL, - eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con, - h_envChan[0], SBR_MONO, NULL, YSzShift); - calculateSbrEnvelope(h_envChan[1]->sbrExtractEnvelope.YBuffer, NULL, - h_envChan[1]->sbrExtractEnvelope.YBufferScale, NULL, - eData[1].frame_info, eData[1].sfb_nrg, NULL, h_con, - h_envChan[1], SBR_MONO, NULL, YSzShift); - break; - case SBR_COUPLING: - calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, - h_envChan[1]->sbrExtractEnvelope.YBuffer, - h_envChan[0]->sbrExtractEnvelope.YBufferScale, - h_envChan[1]->sbrExtractEnvelope.YBufferScale, - eData[0].frame_info, eData[0].sfb_nrg, - eData[1].sfb_nrg, h_con, h_envChan[0], SBR_COUPLING, - &fData->maxQuantError, YSzShift); - break; - case SBR_SWITCH_LRC: - calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, NULL, - h_envChan[0]->sbrExtractEnvelope.YBufferScale, NULL, - eData[0].frame_info, eData[0].sfb_nrg, NULL, h_con, - h_envChan[0], SBR_MONO, NULL, YSzShift); - calculateSbrEnvelope(h_envChan[1]->sbrExtractEnvelope.YBuffer, NULL, - h_envChan[1]->sbrExtractEnvelope.YBufferScale, NULL, - eData[1].frame_info, eData[1].sfb_nrg, NULL, h_con, - h_envChan[1], SBR_MONO, NULL, YSzShift); - calculateSbrEnvelope(h_envChan[0]->sbrExtractEnvelope.YBuffer, - h_envChan[1]->sbrExtractEnvelope.YBuffer, - h_envChan[0]->sbrExtractEnvelope.YBufferScale, - h_envChan[1]->sbrExtractEnvelope.YBufferScale, - eData[0].frame_info, eData[0].sfb_nrg_coupling, - eData[1].sfb_nrg_coupling, h_con, h_envChan[0], - SBR_COUPLING, &fData->maxQuantError, YSzShift); - break; - } - - /* - Noise floor quantisation and coding. - */ - - switch (stereoMode) { - case SBR_MONO: - sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor, - 0); - - FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res, - &h_envChan[0]->sbrCodeNoiseFloor, - h_envChan[0]->encEnvData.domain_vec_noise, 0, - (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0, - sbrBitstreamData->HeaderActive); - - break; - case SBR_LEFT_RIGHT: - sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor, - 0); - - FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res, - &h_envChan[0]->sbrCodeNoiseFloor, - h_envChan[0]->encEnvData.domain_vec_noise, 0, - (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0, - sbrBitstreamData->HeaderActive); - - sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor, - 0); - - FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res, - &h_envChan[1]->sbrCodeNoiseFloor, - h_envChan[1]->encEnvData.domain_vec_noise, 0, - (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 0, - sbrBitstreamData->HeaderActive); - - break; - - case SBR_COUPLING: - coupleNoiseFloor(eData[0].noiseFloor, eData[1].noiseFloor); - - sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor, - 0); - - FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res, - &h_envChan[0]->sbrCodeNoiseFloor, - h_envChan[0]->encEnvData.domain_vec_noise, 1, - (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0, - sbrBitstreamData->HeaderActive); - - sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor, - 1); - - FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res, - &h_envChan[1]->sbrCodeNoiseFloor, - h_envChan[1]->encEnvData.domain_vec_noise, 1, - (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 1, - sbrBitstreamData->HeaderActive); - - break; - case SBR_SWITCH_LRC: - sbrNoiseFloorLevelsQuantisation(eData[0].noise_level, eData[0].noiseFloor, - 0); - sbrNoiseFloorLevelsQuantisation(eData[1].noise_level, eData[1].noiseFloor, - 0); - coupleNoiseFloor(eData[0].noiseFloor, eData[1].noiseFloor); - sbrNoiseFloorLevelsQuantisation(eData[0].noise_level_coupling, - eData[0].noiseFloor, 0); - sbrNoiseFloorLevelsQuantisation(eData[1].noise_level_coupling, - eData[1].noiseFloor, 1); - break; - } - - /* - Encode envelope of current frame. - */ - switch (stereoMode) { - case SBR_MONO: - sbrHeaderData->coupling = 0; - h_envChan[0]->encEnvData.balance = 0; - FDKsbrEnc_codeEnvelope( - eData[0].sfb_nrg, eData[0].frame_info->freqRes, - &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec, - sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0, - sbrBitstreamData->HeaderActive); - break; - case SBR_LEFT_RIGHT: - sbrHeaderData->coupling = 0; - - h_envChan[0]->encEnvData.balance = 0; - h_envChan[1]->encEnvData.balance = 0; - - FDKsbrEnc_codeEnvelope( - eData[0].sfb_nrg, eData[0].frame_info->freqRes, - &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec, - sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0, - sbrBitstreamData->HeaderActive); - FDKsbrEnc_codeEnvelope( - eData[1].sfb_nrg, eData[1].frame_info->freqRes, - &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec, - sbrHeaderData->coupling, eData[1].frame_info->nEnvelopes, 0, - sbrBitstreamData->HeaderActive); - break; - case SBR_COUPLING: - sbrHeaderData->coupling = 1; - h_envChan[0]->encEnvData.balance = 0; - h_envChan[1]->encEnvData.balance = 1; - - FDKsbrEnc_codeEnvelope( - eData[0].sfb_nrg, eData[0].frame_info->freqRes, - &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec, - sbrHeaderData->coupling, eData[0].frame_info->nEnvelopes, 0, - sbrBitstreamData->HeaderActive); - FDKsbrEnc_codeEnvelope( - eData[1].sfb_nrg, eData[1].frame_info->freqRes, - &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec, - sbrHeaderData->coupling, eData[1].frame_info->nEnvelopes, 1, - sbrBitstreamData->HeaderActive); - break; - case SBR_SWITCH_LRC: { - INT payloadbitsLR; - INT payloadbitsCOUPLING; - - SCHAR sfbNrgPrevTemp[MAX_NUM_CHANNELS][MAX_FREQ_COEFFS]; - SCHAR noisePrevTemp[MAX_NUM_CHANNELS][MAX_NUM_NOISE_COEFFS]; - INT upDateNrgTemp[MAX_NUM_CHANNELS]; - INT upDateNoiseTemp[MAX_NUM_CHANNELS]; - INT domainVecTemp[MAX_NUM_CHANNELS][MAX_ENVELOPES]; - INT domainVecNoiseTemp[MAX_NUM_CHANNELS][MAX_ENVELOPES]; - - INT tempFlagRight = 0; - INT tempFlagLeft = 0; - - /* - Store previous values, in order to be able to "undo" what is being - done. - */ - - for (ch = 0; ch < nChannels; ch++) { - FDKmemcpy(sfbNrgPrevTemp[ch], - h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev, - MAX_FREQ_COEFFS * sizeof(SCHAR)); - - FDKmemcpy(noisePrevTemp[ch], - h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev, - MAX_NUM_NOISE_COEFFS * sizeof(SCHAR)); - - upDateNrgTemp[ch] = h_envChan[ch]->sbrCodeEnvelope.upDate; - upDateNoiseTemp[ch] = h_envChan[ch]->sbrCodeNoiseFloor.upDate; - - /* - forbid time coding in the first envelope in case of a different - previous stereomode - */ - if (sbrHeaderData->prev_coupling) { - h_envChan[ch]->sbrCodeEnvelope.upDate = 0; - h_envChan[ch]->sbrCodeNoiseFloor.upDate = 0; - } - } /* ch */ - - /* - Code ordinary Left/Right stereo - */ - FDKsbrEnc_codeEnvelope(eData[0].sfb_nrg, eData[0].frame_info->freqRes, - &h_envChan[0]->sbrCodeEnvelope, - h_envChan[0]->encEnvData.domain_vec, 0, - eData[0].frame_info->nEnvelopes, 0, - sbrBitstreamData->HeaderActive); - FDKsbrEnc_codeEnvelope(eData[1].sfb_nrg, eData[1].frame_info->freqRes, - &h_envChan[1]->sbrCodeEnvelope, - h_envChan[1]->encEnvData.domain_vec, 0, - eData[1].frame_info->nEnvelopes, 0, - sbrBitstreamData->HeaderActive); - - c = 0; - for (i = 0; i < eData[0].nEnvelopes; i++) { - for (j = 0; j < h_envChan[0]->encEnvData.noScfBands[i]; j++) { - h_envChan[0]->encEnvData.ienvelope[i][j] = eData[0].sfb_nrg[c]; - h_envChan[1]->encEnvData.ienvelope[i][j] = eData[1].sfb_nrg[c]; - c++; - } - } - - FDKsbrEnc_codeEnvelope(eData[0].noise_level, fData->res, - &h_envChan[0]->sbrCodeNoiseFloor, - h_envChan[0]->encEnvData.domain_vec_noise, 0, - (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0, - sbrBitstreamData->HeaderActive); - - for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) - h_envChan[0]->encEnvData.sbr_noise_levels[i] = eData[0].noise_level[i]; - - FDKsbrEnc_codeEnvelope(eData[1].noise_level, fData->res, - &h_envChan[1]->sbrCodeNoiseFloor, - h_envChan[1]->encEnvData.domain_vec_noise, 0, - (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 0, - sbrBitstreamData->HeaderActive); - - for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) - h_envChan[1]->encEnvData.sbr_noise_levels[i] = eData[1].noise_level[i]; - - sbrHeaderData->coupling = 0; - h_envChan[0]->encEnvData.balance = 0; - h_envChan[1]->encEnvData.balance = 0; - - payloadbitsLR = FDKsbrEnc_CountSbrChannelPairElement( - sbrHeaderData, hParametricStereo, sbrBitstreamData, - &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData, - h_con->sbrSyntaxFlags); - - /* - swap saved stored with current values - */ - for (ch = 0; ch < nChannels; ch++) { - INT itmp; - for (i = 0; i < MAX_FREQ_COEFFS; i++) { - /* - swap sfb energies - */ - itmp = h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev[i]; - h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev[i] = - sfbNrgPrevTemp[ch][i]; - sfbNrgPrevTemp[ch][i] = itmp; - } - for (i = 0; i < MAX_NUM_NOISE_COEFFS; i++) { - /* - swap noise energies - */ - itmp = h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev[i]; - h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev[i] = - noisePrevTemp[ch][i]; - noisePrevTemp[ch][i] = itmp; - } - /* swap update flags */ - itmp = h_envChan[ch]->sbrCodeEnvelope.upDate; - h_envChan[ch]->sbrCodeEnvelope.upDate = upDateNrgTemp[ch]; - upDateNrgTemp[ch] = itmp; - - itmp = h_envChan[ch]->sbrCodeNoiseFloor.upDate; - h_envChan[ch]->sbrCodeNoiseFloor.upDate = upDateNoiseTemp[ch]; - upDateNoiseTemp[ch] = itmp; - - /* - save domain vecs - */ - FDKmemcpy(domainVecTemp[ch], h_envChan[ch]->encEnvData.domain_vec, - sizeof(INT) * MAX_ENVELOPES); - FDKmemcpy(domainVecNoiseTemp[ch], - h_envChan[ch]->encEnvData.domain_vec_noise, - sizeof(INT) * MAX_ENVELOPES); - - /* - forbid time coding in the first envelope in case of a different - previous stereomode - */ - - if (!sbrHeaderData->prev_coupling) { - h_envChan[ch]->sbrCodeEnvelope.upDate = 0; - h_envChan[ch]->sbrCodeNoiseFloor.upDate = 0; - } - } /* ch */ - - /* - Coupling - */ - - FDKsbrEnc_codeEnvelope( - eData[0].sfb_nrg_coupling, eData[0].frame_info->freqRes, - &h_envChan[0]->sbrCodeEnvelope, h_envChan[0]->encEnvData.domain_vec, - 1, eData[0].frame_info->nEnvelopes, 0, - sbrBitstreamData->HeaderActive); - - FDKsbrEnc_codeEnvelope( - eData[1].sfb_nrg_coupling, eData[1].frame_info->freqRes, - &h_envChan[1]->sbrCodeEnvelope, h_envChan[1]->encEnvData.domain_vec, - 1, eData[1].frame_info->nEnvelopes, 1, - sbrBitstreamData->HeaderActive); - - c = 0; - for (i = 0; i < eData[0].nEnvelopes; i++) { - for (j = 0; j < h_envChan[0]->encEnvData.noScfBands[i]; j++) { - h_envChan[0]->encEnvData.ienvelope[i][j] = - eData[0].sfb_nrg_coupling[c]; - h_envChan[1]->encEnvData.ienvelope[i][j] = - eData[1].sfb_nrg_coupling[c]; - c++; - } - } - - FDKsbrEnc_codeEnvelope(eData[0].noise_level_coupling, fData->res, - &h_envChan[0]->sbrCodeNoiseFloor, - h_envChan[0]->encEnvData.domain_vec_noise, 1, - (eData[0].frame_info->nEnvelopes > 1 ? 2 : 1), 0, - sbrBitstreamData->HeaderActive); - - for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) - h_envChan[0]->encEnvData.sbr_noise_levels[i] = - eData[0].noise_level_coupling[i]; - - FDKsbrEnc_codeEnvelope(eData[1].noise_level_coupling, fData->res, - &h_envChan[1]->sbrCodeNoiseFloor, - h_envChan[1]->encEnvData.domain_vec_noise, 1, - (eData[1].frame_info->nEnvelopes > 1 ? 2 : 1), 1, - sbrBitstreamData->HeaderActive); - - for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) - h_envChan[1]->encEnvData.sbr_noise_levels[i] = - eData[1].noise_level_coupling[i]; - - sbrHeaderData->coupling = 1; - - h_envChan[0]->encEnvData.balance = 0; - h_envChan[1]->encEnvData.balance = 1; - - tempFlagLeft = h_envChan[0]->encEnvData.addHarmonicFlag; - tempFlagRight = h_envChan[1]->encEnvData.addHarmonicFlag; - - payloadbitsCOUPLING = FDKsbrEnc_CountSbrChannelPairElement( - sbrHeaderData, hParametricStereo, sbrBitstreamData, - &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData, - h_con->sbrSyntaxFlags); - - h_envChan[0]->encEnvData.addHarmonicFlag = tempFlagLeft; - h_envChan[1]->encEnvData.addHarmonicFlag = tempFlagRight; - - if (payloadbitsCOUPLING < payloadbitsLR) { - /* - copy coded coupling envelope and noise data to l/r - */ - for (ch = 0; ch < nChannels; ch++) { - SBR_ENV_TEMP_DATA *ed = &eData[ch]; - FDKmemcpy(ed->sfb_nrg, ed->sfb_nrg_coupling, - MAX_NUM_ENVELOPE_VALUES * sizeof(SCHAR)); - FDKmemcpy(ed->noise_level, ed->noise_level_coupling, - MAX_NUM_NOISE_VALUES * sizeof(SCHAR)); - } - - sbrHeaderData->coupling = 1; - h_envChan[0]->encEnvData.balance = 0; - h_envChan[1]->encEnvData.balance = 1; - } else { - /* - restore saved l/r items - */ - for (ch = 0; ch < nChannels; ch++) { - FDKmemcpy(h_envChan[ch]->sbrCodeEnvelope.sfb_nrg_prev, - sfbNrgPrevTemp[ch], MAX_FREQ_COEFFS * sizeof(SCHAR)); - - h_envChan[ch]->sbrCodeEnvelope.upDate = upDateNrgTemp[ch]; - - FDKmemcpy(h_envChan[ch]->sbrCodeNoiseFloor.sfb_nrg_prev, - noisePrevTemp[ch], MAX_NUM_NOISE_COEFFS * sizeof(SCHAR)); - - FDKmemcpy(h_envChan[ch]->encEnvData.domain_vec, domainVecTemp[ch], - sizeof(INT) * MAX_ENVELOPES); - FDKmemcpy(h_envChan[ch]->encEnvData.domain_vec_noise, - domainVecNoiseTemp[ch], sizeof(INT) * MAX_ENVELOPES); - - h_envChan[ch]->sbrCodeNoiseFloor.upDate = upDateNoiseTemp[ch]; - } - - sbrHeaderData->coupling = 0; - h_envChan[0]->encEnvData.balance = 0; - h_envChan[1]->encEnvData.balance = 0; - } - } break; - } /* switch */ - - /* tell the envelope encoders how long it has been, since we last sent - a frame starting with a dF-coded envelope */ - if (stereoMode == SBR_MONO) { - if (h_envChan[0]->encEnvData.domain_vec[0] == TIME) - h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac++; - else - h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac = 0; - } else { - if (h_envChan[0]->encEnvData.domain_vec[0] == TIME || - h_envChan[1]->encEnvData.domain_vec[0] == TIME) { - h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac++; - h_envChan[1]->sbrCodeEnvelope.dF_edge_incr_fac++; - } else { - h_envChan[0]->sbrCodeEnvelope.dF_edge_incr_fac = 0; - h_envChan[1]->sbrCodeEnvelope.dF_edge_incr_fac = 0; - } - } - - /* - Send the encoded data to the bitstream - */ - for (ch = 0; ch < nChannels; ch++) { - SBR_ENV_TEMP_DATA *ed = &eData[ch]; - c = 0; - for (i = 0; i < ed->nEnvelopes; i++) { - for (j = 0; j < h_envChan[ch]->encEnvData.noScfBands[i]; j++) { - h_envChan[ch]->encEnvData.ienvelope[i][j] = ed->sfb_nrg[c]; - - c++; - } - } - for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) { - h_envChan[ch]->encEnvData.sbr_noise_levels[i] = ed->noise_level[i]; - } - } /* ch */ - - /* - Write bitstream - */ - if (nChannels == 2) { - FDKsbrEnc_WriteEnvChannelPairElement( - sbrHeaderData, hParametricStereo, sbrBitstreamData, - &h_envChan[0]->encEnvData, &h_envChan[1]->encEnvData, hCmonData, - h_con->sbrSyntaxFlags); - } else { - FDKsbrEnc_WriteEnvSingleChannelElement( - sbrHeaderData, hParametricStereo, sbrBitstreamData, - &h_envChan[0]->encEnvData, hCmonData, h_con->sbrSyntaxFlags); - } - - /* - * Update buffers. - */ - for (ch = 0; ch < nChannels; ch++) { - int YBufferLength = h_envChan[ch]->sbrExtractEnvelope.no_cols >> - h_envChan[ch]->sbrExtractEnvelope.YBufferSzShift; - for (i = 0; i < h_envChan[ch]->sbrExtractEnvelope.YBufferWriteOffset; i++) { - FDKmemcpy(h_envChan[ch]->sbrExtractEnvelope.YBuffer[i], - h_envChan[ch]->sbrExtractEnvelope.YBuffer[i + YBufferLength], - sizeof(FIXP_DBL) * 64); - } - h_envChan[ch]->sbrExtractEnvelope.YBufferScale[0] = - h_envChan[ch]->sbrExtractEnvelope.YBufferScale[1]; - } - - sbrHeaderData->prev_coupling = sbrHeaderData->coupling; -} - -/***************************************************************************/ -/*! - - \brief creates an envelope extractor handle - - \return error status - -****************************************************************************/ -INT FDKsbrEnc_CreateExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut, - INT channel, INT chInEl, - UCHAR *dynamic_RAM) { - INT i; - FIXP_DBL *rBuffer, *iBuffer; - INT n; - FIXP_DBL *YBufferDyn; - - FDKmemclear(hSbrCut, sizeof(SBR_EXTRACT_ENVELOPE)); - - if (NULL == (hSbrCut->p_YBuffer = GetRam_Sbr_envYBuffer(channel))) { - goto bail; - } - - for (i = 0; i < (32 >> 1); i++) { - hSbrCut->YBuffer[i] = hSbrCut->p_YBuffer + (i * 64); - } - YBufferDyn = GetRam_Sbr_envYBuffer(chInEl, dynamic_RAM); - for (n = 0; i < 32; i++, n++) { - hSbrCut->YBuffer[i] = YBufferDyn + (n * 64); - } - - rBuffer = GetRam_Sbr_envRBuffer(0, dynamic_RAM); - iBuffer = GetRam_Sbr_envIBuffer(0, dynamic_RAM); - - for (i = 0; i < 32; i++) { - hSbrCut->rBuffer[i] = rBuffer + (i * 64); - hSbrCut->iBuffer[i] = iBuffer + (i * 64); - } - - return 0; - -bail: - FDKsbrEnc_deleteExtractSbrEnvelope(hSbrCut); - - return -1; -} - -/***************************************************************************/ -/*! - - \brief Initialize an envelope extractor instance. - - \return error status - -****************************************************************************/ -INT FDKsbrEnc_InitExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut, - int no_cols, int no_rows, int start_index, - int time_slots, int time_step, - int tran_off, ULONG statesInitFlag, - int chInEl, UCHAR *dynamic_RAM, - UINT sbrSyntaxFlags) { - int YBufferLength, rBufferLength; - int i; - - if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { - int off = TRANSIENT_OFFSET_LD; - hSbrCut->YBufferWriteOffset = (no_cols >> 1) + off * time_step; - } else { - hSbrCut->YBufferWriteOffset = tran_off * time_step; - } - hSbrCut->rBufferReadOffset = 0; - - YBufferLength = hSbrCut->YBufferWriteOffset + no_cols; - rBufferLength = no_cols; - - hSbrCut->pre_transient_info[0] = 0; - hSbrCut->pre_transient_info[1] = 0; - - hSbrCut->no_cols = no_cols; - hSbrCut->no_rows = no_rows; - hSbrCut->start_index = start_index; - - hSbrCut->time_slots = time_slots; - hSbrCut->time_step = time_step; - - FDK_ASSERT(no_rows <= 64); - - /* Use half the Energy values if time step is 2 or greater */ - if (time_step >= 2) - hSbrCut->YBufferSzShift = 1; - else - hSbrCut->YBufferSzShift = 0; - - YBufferLength >>= hSbrCut->YBufferSzShift; - hSbrCut->YBufferWriteOffset >>= hSbrCut->YBufferSzShift; - - FDK_ASSERT(YBufferLength <= 32); - - FIXP_DBL *YBufferDyn = GetRam_Sbr_envYBuffer(chInEl, dynamic_RAM); - INT n = 0; - for (i = (32 >> 1); i < 32; i++, n++) { - hSbrCut->YBuffer[i] = YBufferDyn + (n * 64); - } - - if (statesInitFlag) { - for (i = 0; i < YBufferLength; i++) { - FDKmemclear(hSbrCut->YBuffer[i], 64 * sizeof(FIXP_DBL)); - } - } - - for (i = 0; i < rBufferLength; i++) { - FDKmemclear(hSbrCut->rBuffer[i], 64 * sizeof(FIXP_DBL)); - FDKmemclear(hSbrCut->iBuffer[i], 64 * sizeof(FIXP_DBL)); - } - - FDKmemclear(hSbrCut->envelopeCompensation, sizeof(UCHAR) * MAX_FREQ_COEFFS); - - if (statesInitFlag) { - hSbrCut->YBufferScale[0] = hSbrCut->YBufferScale[1] = FRACT_BITS - 1; - } - - return (0); -} - -/***************************************************************************/ -/*! - - \brief deinitializes an envelope extractor handle - - \return void - -****************************************************************************/ - -void FDKsbrEnc_deleteExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut) { - if (hSbrCut) { - FreeRam_Sbr_envYBuffer(&hSbrCut->p_YBuffer); - } -} - -INT FDKsbrEnc_GetEnvEstDelay(HANDLE_SBR_EXTRACT_ENVELOPE hSbr) { - return hSbr->no_rows * - ((hSbr->YBufferWriteOffset) * - 2 /* mult 2 because nrg's are grouped half */ - - hSbr->rBufferReadOffset); /* in reference hold half spec and calc - nrg's on overlapped spec */ -} --- a/libSBRenc/src/env_est.h +++ /dev/null @@ -1,223 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Envelope estimation structs and prototypes $Revision: 92790 $ -*/ -#ifndef ENV_EST_H -#define ENV_EST_H - -#include "sbr_def.h" -#include "sbr_encoder.h" /* SBR econfig structs */ -#include "ps_main.h" -#include "bit_sbr.h" -#include "fram_gen.h" -#include "tran_det.h" -#include "code_env.h" -#include "ton_corr.h" - -typedef struct { - FIXP_DBL *rBuffer[32]; - FIXP_DBL *iBuffer[32]; - - FIXP_DBL *p_YBuffer; - - FIXP_DBL *YBuffer[32]; - int YBufferScale[2]; - - UCHAR envelopeCompensation[MAX_FREQ_COEFFS]; - UCHAR pre_transient_info[2]; - - int YBufferWriteOffset; - int YBufferSzShift; - int rBufferReadOffset; - - int no_cols; - int no_rows; - int start_index; - - int time_slots; - int time_step; -} SBR_EXTRACT_ENVELOPE; -typedef SBR_EXTRACT_ENVELOPE *HANDLE_SBR_EXTRACT_ENVELOPE; - -struct ENV_CHANNEL { - FAST_TRAN_DETECTOR sbrFastTransientDetector; - SBR_TRANSIENT_DETECTOR sbrTransientDetector; - SBR_CODE_ENVELOPE sbrCodeEnvelope; - SBR_CODE_ENVELOPE sbrCodeNoiseFloor; - SBR_EXTRACT_ENVELOPE sbrExtractEnvelope; - - SBR_ENVELOPE_FRAME SbrEnvFrame; - SBR_TON_CORR_EST TonCorr; - - struct SBR_ENV_DATA encEnvData; - - int qmfScale; - UCHAR fLevelProtect; -}; -typedef struct ENV_CHANNEL *HANDLE_ENV_CHANNEL; - -/************ Function Declarations ***************/ - -INT FDKsbrEnc_CreateExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut, - INT channel, INT chInEl, - UCHAR *dynamic_RAM); - -INT FDKsbrEnc_InitExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbr, - int no_cols, int no_rows, int start_index, - int time_slots, int time_step, - int tran_off, ULONG statesInitFlag, - int chInEl, UCHAR *dynamic_RAM, - UINT sbrSyntaxFlags); - -void FDKsbrEnc_deleteExtractSbrEnvelope(HANDLE_SBR_EXTRACT_ENVELOPE hSbrCut); - -typedef struct { - FREQ_RES res[MAX_NUM_NOISE_VALUES]; - int maxQuantError; - -} SBR_FRAME_TEMP_DATA; - -typedef struct { - const SBR_FRAME_INFO *frame_info; - FIXP_DBL noiseFloor[MAX_NUM_NOISE_VALUES]; - SCHAR sfb_nrg_coupling - [MAX_NUM_ENVELOPE_VALUES]; /* only used if stereomode = SWITCH_L_R_C */ - SCHAR sfb_nrg[MAX_NUM_ENVELOPE_VALUES]; - SCHAR noise_level_coupling - [MAX_NUM_NOISE_VALUES]; /* only used if stereomode = SWITCH_L_R_C */ - SCHAR noise_level[MAX_NUM_NOISE_VALUES]; - UCHAR transient_info[3]; - UCHAR nEnvelopes; -} SBR_ENV_TEMP_DATA; - -/* - * Extract features from QMF data. Afterwards, the QMF data is not required - * anymore. - */ -void FDKsbrEnc_extractSbrEnvelope1(HANDLE_SBR_CONFIG_DATA h_con, - HANDLE_SBR_HEADER_DATA sbrHeaderData, - HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData, - HANDLE_ENV_CHANNEL h_envChan, - HANDLE_COMMON_DATA cmonData, - SBR_ENV_TEMP_DATA *eData, - SBR_FRAME_TEMP_DATA *fData); - -/* - * Process the previously features extracted by FDKsbrEnc_extractSbrEnvelope1 - * and create/encode SBR envelopes. - */ -void FDKsbrEnc_extractSbrEnvelope2(HANDLE_SBR_CONFIG_DATA h_con, - HANDLE_SBR_HEADER_DATA sbrHeaderData, - HANDLE_PARAMETRIC_STEREO hParametricStereo, - HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData, - HANDLE_ENV_CHANNEL sbrEnvChannel0, - HANDLE_ENV_CHANNEL sbrEnvChannel1, - HANDLE_COMMON_DATA cmonData, - SBR_ENV_TEMP_DATA *eData, - SBR_FRAME_TEMP_DATA *fData, int clearOutput); - -INT FDKsbrEnc_GetEnvEstDelay(HANDLE_SBR_EXTRACT_ENVELOPE hSbr); - -#endif --- a/libSBRenc/src/fram_gen.cpp +++ /dev/null @@ -1,1965 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -#include "fram_gen.h" -#include "sbr_misc.h" - -#include "genericStds.h" - -static const SBR_FRAME_INFO frameInfo1_2048 = {1, {0, 16}, {FREQ_RES_HIGH}, - 0, 1, {0, 16}}; - -static const SBR_FRAME_INFO frameInfo2_2048 = { - 2, {0, 8, 16}, {FREQ_RES_HIGH, FREQ_RES_HIGH}, 0, 2, {0, 8, 16}}; - -static const SBR_FRAME_INFO frameInfo4_2048 = { - 4, - {0, 4, 8, 12, 16}, - {FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH}, - 0, - 2, - {0, 8, 16}}; - -static const SBR_FRAME_INFO frameInfo1_2304 = {1, {0, 18}, {FREQ_RES_HIGH}, - 0, 1, {0, 18}}; - -static const SBR_FRAME_INFO frameInfo2_2304 = { - 2, {0, 9, 18}, {FREQ_RES_HIGH, FREQ_RES_HIGH}, 0, 2, {0, 9, 18}}; - -static const SBR_FRAME_INFO frameInfo4_2304 = { - 4, - {0, 5, 9, 14, 18}, - {FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH}, - 0, - 2, - {0, 9, 18}}; - -static const SBR_FRAME_INFO frameInfo1_1920 = {1, {0, 15}, {FREQ_RES_HIGH}, - 0, 1, {0, 15}}; - -static const SBR_FRAME_INFO frameInfo2_1920 = { - 2, {0, 8, 15}, {FREQ_RES_HIGH, FREQ_RES_HIGH}, 0, 2, {0, 8, 15}}; - -static const SBR_FRAME_INFO frameInfo4_1920 = { - 4, - {0, 4, 8, 12, 15}, - {FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH}, - 0, - 2, - {0, 8, 15}}; - -static const SBR_FRAME_INFO frameInfo1_1152 = {1, {0, 9}, {FREQ_RES_HIGH}, - 0, 1, {0, 9}}; - -static const SBR_FRAME_INFO frameInfo2_1152 = { - 2, {0, 5, 9}, {FREQ_RES_HIGH, FREQ_RES_HIGH}, 0, 2, {0, 5, 9}}; - -static const SBR_FRAME_INFO frameInfo4_1152 = { - 4, - {0, 2, 5, 7, 9}, - {FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH}, - 0, - 2, - {0, 5, 9}}; - -/* AACLD frame info */ -static const SBR_FRAME_INFO frameInfo1_512LD = {1, {0, 8}, {FREQ_RES_HIGH}, - 0, 1, {0, 8}}; - -static const SBR_FRAME_INFO frameInfo2_512LD = { - 2, {0, 4, 8}, {FREQ_RES_HIGH, FREQ_RES_HIGH}, 0, 2, {0, 4, 8}}; - -static const SBR_FRAME_INFO frameInfo4_512LD = { - 4, - {0, 2, 4, 6, 8}, - {FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH}, - 0, - 2, - {0, 4, 8}}; - -static int calcFillLengthMax( - int tranPos, /*!< input : transient position (ref: tran det) */ - int numberTimeSlots /*!< input : number of timeslots */ -); - -static void fillFrameTran( - const int *v_tuningSegm, /*!< tuning: desired segment lengths */ - const int *v_tuningFreq, /*!< tuning: desired frequency resolutions */ - int tran, /*!< input : position of transient */ - int *v_bord, /*!< memNew: borders */ - int *length_v_bord, /*!< memNew: # borders */ - int *v_freq, /*!< memNew: frequency resolutions */ - int *length_v_freq, /*!< memNew: # frequency resolutions */ - int *bmin, /*!< hlpNew: first mandatory border */ - int *bmax /*!< hlpNew: last mandatory border */ -); - -static void fillFramePre(INT dmax, INT *v_bord, INT *length_v_bord, INT *v_freq, - INT *length_v_freq, INT bmin, INT rest); - -static void fillFramePost(INT *parts, INT *d, INT dmax, INT *v_bord, - INT *length_v_bord, INT *v_freq, INT *length_v_freq, - INT bmax, INT bufferFrameStart, INT numberTimeSlots, - INT fmax); - -static void fillFrameInter(INT *nL, const int *v_tuningSegm, INT *v_bord, - INT *length_v_bord, INT bmin, INT *v_freq, - INT *length_v_freq, INT *v_bordFollow, - INT *length_v_bordFollow, INT *v_freqFollow, - INT *length_v_freqFollow, INT i_fillFollow, INT dmin, - INT dmax, INT numberTimeSlots); - -static void calcFrameClass(FRAME_CLASS *frameClass, FRAME_CLASS *frameClassOld, - INT tranFlag, INT *spreadFlag); - -static void specialCase(INT *spreadFlag, INT allowSpread, INT *v_bord, - INT *length_v_bord, INT *v_freq, INT *length_v_freq, - INT *parts, INT d); - -static void calcCmonBorder(INT *i_cmon, INT *i_tran, INT *v_bord, - INT *length_v_bord, INT tran, INT bufferFrameStart, - INT numberTimeSlots); - -static void keepForFollowUp(INT *v_bordFollow, INT *length_v_bordFollow, - INT *v_freqFollow, INT *length_v_freqFollow, - INT *i_tranFollow, INT *i_fillFollow, INT *v_bord, - INT *length_v_bord, INT *v_freq, INT i_cmon, - INT i_tran, INT parts, INT numberTimeSlots); - -static void calcCtrlSignal(HANDLE_SBR_GRID hSbrGrid, FRAME_CLASS frameClass, - INT *v_bord, INT length_v_bord, INT *v_freq, - INT length_v_freq, INT i_cmon, INT i_tran, - INT spreadFlag, INT nL); - -static void ctrlSignal2FrameInfo(HANDLE_SBR_GRID hSbrGrid, - HANDLE_SBR_FRAME_INFO hFrameInfo, - FREQ_RES *freq_res_fixfix); - -/* table for 8 time slot index */ -static const int envelopeTable_8[8][5] = { - /* transientIndex nEnv, tranIdx, shortEnv, border1, border2, ... */ - /* borders from left to right side; -1 = not in use */ - /*[|T-|------]*/ {2, 0, 0, 1, -1}, - /*[|-T-|-----]*/ {2, 0, 0, 2, -1}, - /*[--|T-|----]*/ {3, 1, 1, 2, 4}, - /*[---|T-|---]*/ {3, 1, 1, 3, 5}, - /*[----|T-|--]*/ {3, 1, 1, 4, 6}, - /*[-----|T--|]*/ {2, 1, 1, 5, -1}, - /*[------|T-|]*/ {2, 1, 1, 6, -1}, - /*[-------|T|]*/ {2, 1, 1, 7, -1}, -}; - -/* table for 16 time slot index */ -static const int envelopeTable_16[16][6] = { - /* transientIndex nEnv, tranIdx, shortEnv, border1, border2, ... */ - /* length from left to right side; -1 = not in use */ - /*[|T---|------------|]*/ {2, 0, 0, 4, -1, -1}, - /*[|-T---|-----------|]*/ {2, 0, 0, 5, -1, -1}, - /*[|--|T---|----------]*/ {3, 1, 1, 2, 6, -1}, - /*[|---|T---|---------]*/ {3, 1, 1, 3, 7, -1}, - /*[|----|T---|--------]*/ {3, 1, 1, 4, 8, -1}, - /*[|-----|T---|-------]*/ {3, 1, 1, 5, 9, -1}, - /*[|------|T---|------]*/ {3, 1, 1, 6, 10, -1}, - /*[|-------|T---|-----]*/ {3, 1, 1, 7, 11, -1}, - /*[|--------|T---|----]*/ {3, 1, 1, 8, 12, -1}, - /*[|---------|T---|---]*/ {3, 1, 1, 9, 13, -1}, - /*[|----------|T---|--]*/ {3, 1, 1, 10, 14, -1}, - /*[|-----------|T----|]*/ {2, 1, 1, 11, -1, -1}, - /*[|------------|T---|]*/ {2, 1, 1, 12, -1, -1}, - /*[|-------------|T--|]*/ {2, 1, 1, 13, -1, -1}, - /*[|--------------|T-|]*/ {2, 1, 1, 14, -1, -1}, - /*[|---------------|T|]*/ {2, 1, 1, 15, -1, -1}, -}; - -/* table for 15 time slot index */ -static const int envelopeTable_15[15][6] = { - /* transientIndex nEnv, tranIdx, shortEnv, border1, border2, ... */ - /* length from left to right side; -1 = not in use */ - /*[|T---|------------]*/ {2, 0, 0, 4, -1, -1}, - /*[|-T---|-----------]*/ {2, 0, 0, 5, -1, -1}, - /*[|--|T---|---------]*/ {3, 1, 1, 2, 6, -1}, - /*[|---|T---|--------]*/ {3, 1, 1, 3, 7, -1}, - /*[|----|T---|-------]*/ {3, 1, 1, 4, 8, -1}, - /*[|-----|T---|------]*/ {3, 1, 1, 5, 9, -1}, - /*[|------|T---|-----]*/ {3, 1, 1, 6, 10, -1}, - /*[|-------|T---|----]*/ {3, 1, 1, 7, 11, -1}, - /*[|--------|T---|---]*/ {3, 1, 1, 8, 12, -1}, - /*[|---------|T---|--]*/ {3, 1, 1, 9, 13, -1}, - /*[|----------|T----|]*/ {2, 1, 1, 10, -1, -1}, - /*[|-----------|T---|]*/ {2, 1, 1, 11, -1, -1}, - /*[|------------|T--|]*/ {2, 1, 1, 12, -1, -1}, - /*[|-------------|T-|]*/ {2, 1, 1, 13, -1, -1}, - /*[|--------------|T|]*/ {2, 1, 1, 14, -1, -1}, -}; - -static const int minFrameTranDistance = 4; - -static const FREQ_RES freqRes_table_8[] = { - FREQ_RES_LOW, FREQ_RES_LOW, FREQ_RES_LOW, FREQ_RES_LOW, FREQ_RES_LOW, - FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH, FREQ_RES_HIGH}; - -static const FREQ_RES freqRes_table_16[16] = { - /* size of envelope */ - /* 0-4 */ FREQ_RES_LOW, - FREQ_RES_LOW, - FREQ_RES_LOW, - FREQ_RES_LOW, - FREQ_RES_LOW, - /* 5-9 */ FREQ_RES_LOW, - FREQ_RES_HIGH, - FREQ_RES_HIGH, - FREQ_RES_HIGH, - FREQ_RES_HIGH, - /* 10-16 */ FREQ_RES_HIGH, - FREQ_RES_HIGH, - FREQ_RES_HIGH, - FREQ_RES_HIGH, - FREQ_RES_HIGH, - FREQ_RES_HIGH}; - -static void generateFixFixOnly(HANDLE_SBR_FRAME_INFO hSbrFrameInfo, - HANDLE_SBR_GRID hSbrGrid, int tranPosInternal, - int numberTimeSlots, UCHAR fResTransIsLow); - -/*! - Functionname: FDKsbrEnc_frameInfoGenerator - - Description: produces the FRAME_INFO struct for the current frame - - Arguments: hSbrEnvFrame - pointer to sbr envelope handle - v_pre_transient_info - pointer to transient info vector - v_transient_info - pointer to previous transient info -vector v_tuning - pointer to tuning vector - - Return: frame_info - pointer to SBR_FRAME_INFO struct - -*******************************************************************************/ -HANDLE_SBR_FRAME_INFO -FDKsbrEnc_frameInfoGenerator(HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame, - UCHAR *v_transient_info, const INT rightBorderFIX, - UCHAR *v_transient_info_pre, int ldGrid, - const int *v_tuning) { - INT numEnv, tranPosInternal = 0, bmin = 0, bmax = 0, parts, d, i_cmon = 0, - i_tran = 0, nL; - INT fmax = 0; - - INT *v_bord = hSbrEnvFrame->v_bord; - INT *v_freq = hSbrEnvFrame->v_freq; - INT *v_bordFollow = hSbrEnvFrame->v_bordFollow; - INT *v_freqFollow = hSbrEnvFrame->v_freqFollow; - - INT *length_v_bordFollow = &hSbrEnvFrame->length_v_bordFollow; - INT *length_v_freqFollow = &hSbrEnvFrame->length_v_freqFollow; - INT *length_v_bord = &hSbrEnvFrame->length_v_bord; - INT *length_v_freq = &hSbrEnvFrame->length_v_freq; - INT *spreadFlag = &hSbrEnvFrame->spreadFlag; - INT *i_tranFollow = &hSbrEnvFrame->i_tranFollow; - INT *i_fillFollow = &hSbrEnvFrame->i_fillFollow; - FRAME_CLASS *frameClassOld = &hSbrEnvFrame->frameClassOld; - FRAME_CLASS frameClass = FIXFIX; - - INT allowSpread = hSbrEnvFrame->allowSpread; - INT numEnvStatic = hSbrEnvFrame->numEnvStatic; - INT staticFraming = hSbrEnvFrame->staticFraming; - INT dmin = hSbrEnvFrame->dmin; - INT dmax = hSbrEnvFrame->dmax; - - INT bufferFrameStart = hSbrEnvFrame->SbrGrid.bufferFrameStart; - INT numberTimeSlots = hSbrEnvFrame->SbrGrid.numberTimeSlots; - INT frameMiddleSlot = hSbrEnvFrame->frameMiddleSlot; - - INT tranPos = v_transient_info[0]; - INT tranFlag = v_transient_info[1]; - - const int *v_tuningSegm = v_tuning; - const int *v_tuningFreq = v_tuning + 3; - - hSbrEnvFrame->v_tuningSegm = v_tuningSegm; - - if (ldGrid) { - /* in case there was a transient at the very end of the previous frame, - * start with a transient envelope */ - if (!tranFlag && v_transient_info_pre[1] && - (numberTimeSlots - v_transient_info_pre[0] < minFrameTranDistance)) { - tranFlag = 1; - tranPos = 0; - } - } - - /* - * Synopsis: - * - * The frame generator creates the time-/frequency-grid for one SBR frame. - * Input signals are provided by the transient detector and the frame - * splitter (transientDetectNew() & FrameSplitter() in tran_det.c). The - * framing is controlled by adjusting tuning parameters stored in - * FRAME_GEN_TUNING. The parameter values are dependent on frame lengths - * and bitrates, and may in the future be signal dependent. - * - * The envelope borders are stored for frame generator internal use in - * aBorders. The contents of aBorders represent positions along the time - * axis given in the figures in fram_gen.h (the "frame-generator" rows). - * The unit is "time slot". The figures in fram_gen.h also define the - * detection ranges for the transient detector. For every border in - * aBorders, there is a corresponding entry in aFreqRes, which defines the - * frequency resolution of the envelope following (delimited by) the - * border. - * - * When no transients are present, FIXFIX class frames are used. The - * frame splitter decides whether to use one or two envelopes in the - * FIXFIX frame. "Sparse transients" (separated by a few frames without - * transients) are handeled by [FIXVAR, VARFIX] pairs or (depending on - * tuning and transient position relative the nominal frame boundaries) - * by [FIXVAR, VARVAR, VARFIX] triples. "Tight transients" (in - * consecutive frames) are handeled by [..., VARVAR, VARVAR, ...] - * sequences. - * - * The generator assumes that transients are "sparse", and designs - * borders for [FIXVAR, VARFIX] pairs right away, where the first frame - * corresponds to the present frame. At the next call of the generator - * it is known whether the transient actually is "sparse" or not. If - * 'yes', the already calculated VARFIX borders are used. If 'no', new - * borders, meeting the requirements of the "tight" transient, are - * calculated. - * - * The generator produces two outputs: A "clear-text bitstream" stored in - * SBR_GRID, and a straight-forward representation of the grid stored in - * SBR_FRAME_INFO. The former is subsequently converted to the actual - * bitstream sbr_grid() (encodeSbrGrid() in bit_sbr.c). The latter is - * used by other encoder functions, such as the envelope estimator - * (calculateSbrEnvelope() in env_est.c) and the noise floor and missing - * harmonics detector (TonCorrParamExtr() in nf_est.c). - */ - - if (staticFraming) { - /*-------------------------------------------------------------------------- - Ignore transient detector - ---------------------------------------------------------------------------*/ - - frameClass = FIXFIX; - numEnv = numEnvStatic; /* {1,2,4,8} */ - *frameClassOld = FIXFIX; /* for change to dyn */ - hSbrEnvFrame->SbrGrid.bs_num_env = numEnv; - hSbrEnvFrame->SbrGrid.frameClass = frameClass; - } else { - /*-------------------------------------------------------------------------- - Calculate frame class to use - ---------------------------------------------------------------------------*/ - if (rightBorderFIX) { - tranFlag = 0; - *spreadFlag = 0; - } - calcFrameClass(&frameClass, frameClassOld, tranFlag, spreadFlag); - - /* patch for new frame class FIXFIXonly for AAC LD */ - if (tranFlag && ldGrid) { - frameClass = FIXFIXonly; - *frameClassOld = FIXFIX; - } - - /* - * every transient is processed below by inserting - * - * - one border at the onset of the transient - * - one or more "decay borders" (after the onset of the transient) - * - optionally one "attack border" (before the onset of the transient) - * - * those borders are referred to as "mandatory borders" and are - * defined by the 'segmentLength' array in FRAME_GEN_TUNING - * - * the frequency resolutions of the corresponding envelopes are - * defined by the 'segmentRes' array in FRAME_GEN_TUNING - */ - - /*-------------------------------------------------------------------------- - Design frame (or follow-up old design) - ---------------------------------------------------------------------------*/ - if (tranFlag) { - /* Always for FixVar, often but not always for VarVar */ - - /*-------------------------------------------------------------------------- - Design part of T/F-grid around the new transient - ---------------------------------------------------------------------------*/ - - tranPosInternal = - frameMiddleSlot + tranPos + bufferFrameStart; /* FH 00-06-26 */ - /* - add mandatory borders around transient - */ - - fillFrameTran(v_tuningSegm, v_tuningFreq, tranPosInternal, v_bord, - length_v_bord, v_freq, length_v_freq, &bmin, &bmax); - - /* make sure we stay within the maximum SBR frame overlap */ - fmax = calcFillLengthMax(tranPos, numberTimeSlots); - } - - switch (frameClass) { - case FIXFIXonly: - FDK_ASSERT(ldGrid); - tranPosInternal = tranPos; - generateFixFixOnly(&(hSbrEnvFrame->SbrFrameInfo), - &(hSbrEnvFrame->SbrGrid), tranPosInternal, - numberTimeSlots, hSbrEnvFrame->fResTransIsLow); - - return &(hSbrEnvFrame->SbrFrameInfo); - - case FIXVAR: - - /*-------------------------------------------------------------------------- - Design remaining parts of T/F-grid (assuming next frame is VarFix) - ---------------------------------------------------------------------------*/ - - /*-------------------------------------------------------------------------- - Fill region before new transient: - ---------------------------------------------------------------------------*/ - fillFramePre(dmax, v_bord, length_v_bord, v_freq, length_v_freq, bmin, - bmin - bufferFrameStart); /* FH 00-06-26 */ - - /*-------------------------------------------------------------------------- - Fill region after new transient: - ---------------------------------------------------------------------------*/ - fillFramePost(&parts, &d, dmax, v_bord, length_v_bord, v_freq, - length_v_freq, bmax, bufferFrameStart, numberTimeSlots, - fmax); - - /*-------------------------------------------------------------------------- - Take care of special case: - ---------------------------------------------------------------------------*/ - if (parts == 1 && d < dmin) /* no fill, short last envelope */ - specialCase(spreadFlag, allowSpread, v_bord, length_v_bord, v_freq, - length_v_freq, &parts, d); - - /*-------------------------------------------------------------------------- - Calculate common border (split-point) - ---------------------------------------------------------------------------*/ - calcCmonBorder(&i_cmon, &i_tran, v_bord, length_v_bord, tranPosInternal, - bufferFrameStart, numberTimeSlots); /* FH 00-06-26 */ - - /*-------------------------------------------------------------------------- - Extract data for proper follow-up in next frame - ---------------------------------------------------------------------------*/ - keepForFollowUp(v_bordFollow, length_v_bordFollow, v_freqFollow, - length_v_freqFollow, i_tranFollow, i_fillFollow, v_bord, - length_v_bord, v_freq, i_cmon, i_tran, parts, - numberTimeSlots); /* FH 00-06-26 */ - - /*-------------------------------------------------------------------------- - Calculate control signal - ---------------------------------------------------------------------------*/ - calcCtrlSignal(&hSbrEnvFrame->SbrGrid, frameClass, v_bord, - *length_v_bord, v_freq, *length_v_freq, i_cmon, i_tran, - *spreadFlag, DC); - break; - case VARFIX: - /*-------------------------------------------------------------------------- - Follow-up old transient - calculate control signal - ---------------------------------------------------------------------------*/ - calcCtrlSignal(&hSbrEnvFrame->SbrGrid, frameClass, v_bordFollow, - *length_v_bordFollow, v_freqFollow, *length_v_freqFollow, - DC, *i_tranFollow, *spreadFlag, DC); - break; - case VARVAR: - if (*spreadFlag) { /* spread across three frames */ - /*-------------------------------------------------------------------------- - Follow-up old transient - calculate control signal - ---------------------------------------------------------------------------*/ - calcCtrlSignal(&hSbrEnvFrame->SbrGrid, frameClass, v_bordFollow, - *length_v_bordFollow, v_freqFollow, - *length_v_freqFollow, DC, *i_tranFollow, *spreadFlag, - DC); - - *spreadFlag = 0; - - /*-------------------------------------------------------------------------- - Extract data for proper follow-up in next frame - ---------------------------------------------------------------------------*/ - v_bordFollow[0] = hSbrEnvFrame->SbrGrid.bs_abs_bord_1 - - numberTimeSlots; /* FH 00-06-26 */ - v_freqFollow[0] = 1; - *length_v_bordFollow = 1; - *length_v_freqFollow = 1; - - *i_tranFollow = -DC; - *i_fillFollow = -DC; - } else { - /*-------------------------------------------------------------------------- - Design remaining parts of T/F-grid (assuming next frame is VarFix) - adapt or fill region before new transient: - ---------------------------------------------------------------------------*/ - fillFrameInter(&nL, v_tuningSegm, v_bord, length_v_bord, bmin, v_freq, - length_v_freq, v_bordFollow, length_v_bordFollow, - v_freqFollow, length_v_freqFollow, *i_fillFollow, dmin, - dmax, numberTimeSlots); - - /*-------------------------------------------------------------------------- - Fill after transient: - ---------------------------------------------------------------------------*/ - fillFramePost(&parts, &d, dmax, v_bord, length_v_bord, v_freq, - length_v_freq, bmax, bufferFrameStart, numberTimeSlots, - fmax); - - /*-------------------------------------------------------------------------- - Take care of special case: - ---------------------------------------------------------------------------*/ - if (parts == 1 && d < dmin) /*% no fill, short last envelope */ - specialCase(spreadFlag, allowSpread, v_bord, length_v_bord, v_freq, - length_v_freq, &parts, d); - - /*-------------------------------------------------------------------------- - Calculate common border (split-point) - ---------------------------------------------------------------------------*/ - calcCmonBorder(&i_cmon, &i_tran, v_bord, length_v_bord, - tranPosInternal, bufferFrameStart, numberTimeSlots); - - /*-------------------------------------------------------------------------- - Extract data for proper follow-up in next frame - ---------------------------------------------------------------------------*/ - keepForFollowUp(v_bordFollow, length_v_bordFollow, v_freqFollow, - length_v_freqFollow, i_tranFollow, i_fillFollow, - v_bord, length_v_bord, v_freq, i_cmon, i_tran, parts, - numberTimeSlots); - - /*-------------------------------------------------------------------------- - Calculate control signal - ---------------------------------------------------------------------------*/ - calcCtrlSignal(&hSbrEnvFrame->SbrGrid, frameClass, v_bord, - *length_v_bord, v_freq, *length_v_freq, i_cmon, i_tran, - 0, nL); - } - break; - case FIXFIX: - if (tranPos == 0) - numEnv = 1; - else - numEnv = 2; - - hSbrEnvFrame->SbrGrid.bs_num_env = numEnv; - hSbrEnvFrame->SbrGrid.frameClass = frameClass; - - break; - default: - FDK_ASSERT(0); - } - } - - /*------------------------------------------------------------------------- - Convert control signal to frame info struct - ---------------------------------------------------------------------------*/ - ctrlSignal2FrameInfo(&hSbrEnvFrame->SbrGrid, &hSbrEnvFrame->SbrFrameInfo, - hSbrEnvFrame->freq_res_fixfix); - - return &hSbrEnvFrame->SbrFrameInfo; -} - -/***************************************************************************/ -/*! - \brief Gnerates frame info for FIXFIXonly frame class used for low delay - version - - \return nothing - ****************************************************************************/ -static void generateFixFixOnly(HANDLE_SBR_FRAME_INFO hSbrFrameInfo, - HANDLE_SBR_GRID hSbrGrid, int tranPosInternal, - int numberTimeSlots, UCHAR fResTransIsLow) { - int nEnv, i, k = 0, tranIdx; - const int *pTable = NULL; - const FREQ_RES *freqResTable = NULL; - - switch (numberTimeSlots) { - case 8: { - pTable = envelopeTable_8[tranPosInternal]; - } - freqResTable = freqRes_table_8; - break; - case 15: - pTable = envelopeTable_15[tranPosInternal]; - freqResTable = freqRes_table_16; - break; - case 16: - pTable = envelopeTable_16[tranPosInternal]; - freqResTable = freqRes_table_16; - break; - } - - /* look number of envolpes in table */ - nEnv = pTable[0]; - /* look up envolpe distribution in table */ - for (i = 1; i < nEnv; i++) hSbrFrameInfo->borders[i] = pTable[i + 2]; - - /* open and close frame border */ - hSbrFrameInfo->borders[0] = 0; - hSbrFrameInfo->borders[nEnv] = numberTimeSlots; - - /* adjust segment-frequency-resolution according to the segment-length */ - for (i = 0; i < nEnv; i++) { - k = hSbrFrameInfo->borders[i + 1] - hSbrFrameInfo->borders[i]; - if (!fResTransIsLow) - hSbrFrameInfo->freqRes[i] = freqResTable[k]; - else - hSbrFrameInfo->freqRes[i] = FREQ_RES_LOW; - - hSbrGrid->v_f[i] = hSbrFrameInfo->freqRes[i]; - } - - hSbrFrameInfo->nEnvelopes = nEnv; - hSbrFrameInfo->shortEnv = pTable[2]; - /* transient idx */ - tranIdx = pTable[1]; - - /* add noise floors */ - hSbrFrameInfo->bordersNoise[0] = 0; - hSbrFrameInfo->bordersNoise[1] = - hSbrFrameInfo->borders[tranIdx ? tranIdx : 1]; - hSbrFrameInfo->bordersNoise[2] = numberTimeSlots; - hSbrFrameInfo->nNoiseEnvelopes = 2; - - hSbrGrid->frameClass = FIXFIXonly; - hSbrGrid->bs_abs_bord = tranPosInternal; - hSbrGrid->bs_num_env = nEnv; -} - -/******************************************************************************* - Functionname: FDKsbrEnc_initFrameInfoGenerator - ******************************************************************************* - - Description: - - Arguments: hSbrEnvFrame - pointer to sbr envelope handle - allowSpread - commandline parameter - numEnvStatic - commandline parameter - staticFraming - commandline parameter - - Return: none - -*******************************************************************************/ -void FDKsbrEnc_initFrameInfoGenerator(HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame, - INT allowSpread, INT numEnvStatic, - INT staticFraming, INT timeSlots, - const FREQ_RES *freq_res_fixfix, - UCHAR fResTransIsLow, - INT ldGrid) { /* FH 00-06-26 */ - - FDKmemclear(hSbrEnvFrame, sizeof(SBR_ENVELOPE_FRAME)); - - /* Initialisation */ - hSbrEnvFrame->frameClassOld = FIXFIX; - hSbrEnvFrame->spreadFlag = 0; - - hSbrEnvFrame->allowSpread = allowSpread; - hSbrEnvFrame->numEnvStatic = numEnvStatic; - hSbrEnvFrame->staticFraming = staticFraming; - hSbrEnvFrame->freq_res_fixfix[0] = freq_res_fixfix[0]; - hSbrEnvFrame->freq_res_fixfix[1] = freq_res_fixfix[1]; - hSbrEnvFrame->fResTransIsLow = fResTransIsLow; - - hSbrEnvFrame->length_v_bord = 0; - hSbrEnvFrame->length_v_bordFollow = 0; - - hSbrEnvFrame->length_v_freq = 0; - hSbrEnvFrame->length_v_freqFollow = 0; - - hSbrEnvFrame->i_tranFollow = 0; - hSbrEnvFrame->i_fillFollow = 0; - - hSbrEnvFrame->SbrGrid.numberTimeSlots = timeSlots; - - if (ldGrid) { - /*case CODEC_AACLD:*/ - hSbrEnvFrame->dmin = 2; - hSbrEnvFrame->dmax = 16; - hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_512LD; - hSbrEnvFrame->SbrGrid.bufferFrameStart = 0; - } else - switch (timeSlots) { - case NUMBER_TIME_SLOTS_1920: - hSbrEnvFrame->dmin = 4; - hSbrEnvFrame->dmax = 12; - hSbrEnvFrame->SbrGrid.bufferFrameStart = 0; - hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_1920; - break; - case NUMBER_TIME_SLOTS_2048: - hSbrEnvFrame->dmin = 4; - hSbrEnvFrame->dmax = 12; - hSbrEnvFrame->SbrGrid.bufferFrameStart = 0; - hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_2048; - break; - case NUMBER_TIME_SLOTS_1152: - hSbrEnvFrame->dmin = 2; - hSbrEnvFrame->dmax = 8; - hSbrEnvFrame->SbrGrid.bufferFrameStart = 0; - hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_1152; - break; - case NUMBER_TIME_SLOTS_2304: - hSbrEnvFrame->dmin = 4; - hSbrEnvFrame->dmax = 15; - hSbrEnvFrame->SbrGrid.bufferFrameStart = 0; - hSbrEnvFrame->frameMiddleSlot = FRAME_MIDDLE_SLOT_2304; - break; - default: - FDK_ASSERT(0); - } -} - -/******************************************************************************* - Functionname: fillFrameTran - ******************************************************************************* - - Description: Add mandatory borders, as described by the tuning vector - and the current transient position - - Arguments: - modified: - v_bord - int pointer to v_bord vector - length_v_bord - length of v_bord vector - v_freq - int pointer to v_freq vector - length_v_freq - length of v_freq vector - bmin - int pointer to bmin (call by reference) - bmax - int pointer to bmax (call by reference) - not modified: - tran - position of transient - v_tuningSegm - int pointer to v_tuningSegm vector - v_tuningFreq - int pointer to v_tuningFreq vector - - Return: none - -*******************************************************************************/ -static void fillFrameTran( - const int *v_tuningSegm, /*!< tuning: desired segment lengths */ - const int *v_tuningFreq, /*!< tuning: desired frequency resolutions */ - int tran, /*!< input : position of transient */ - int *v_bord, /*!< memNew: borders */ - int *length_v_bord, /*!< memNew: # borders */ - int *v_freq, /*!< memNew: frequency resolutions */ - int *length_v_freq, /*!< memNew: # frequency resolutions */ - int *bmin, /*!< hlpNew: first mandatory border */ - int *bmax /*!< hlpNew: last mandatory border */ -) { - int bord, i; - - *length_v_bord = 0; - *length_v_freq = 0; - - /* add attack env leading border (optional) */ - if (v_tuningSegm[0]) { - /* v_bord = [(Ba)] start of attack env */ - FDKsbrEnc_AddRight(v_bord, length_v_bord, (tran - v_tuningSegm[0])); - - /* v_freq = [(Fa)] res of attack env */ - FDKsbrEnc_AddRight(v_freq, length_v_freq, v_tuningFreq[0]); - } - - /* add attack env trailing border/first decay env leading border */ - bord = tran; - FDKsbrEnc_AddRight(v_bord, length_v_bord, tran); /* v_bord = [(Ba),Bd1] */ - - /* add first decay env trailing border/2:nd decay env leading border */ - if (v_tuningSegm[1]) { - bord += v_tuningSegm[1]; - - /* v_bord = [(Ba),Bd1,Bd2] */ - FDKsbrEnc_AddRight(v_bord, length_v_bord, bord); - - /* v_freq = [(Fa),Fd1] */ - FDKsbrEnc_AddRight(v_freq, length_v_freq, v_tuningFreq[1]); - } - - /* add 2:nd decay env trailing border (optional) */ - if (v_tuningSegm[2] != 0) { - bord += v_tuningSegm[2]; - - /* v_bord = [(Ba),Bd1, Bd2,(Bd3)] */ - FDKsbrEnc_AddRight(v_bord, length_v_bord, bord); - - /* v_freq = [(Fa),Fd1,(Fd2)] */ - FDKsbrEnc_AddRight(v_freq, length_v_freq, v_tuningFreq[2]); - } - - /* v_freq = [(Fa),Fd1,(Fd2),1] */ - FDKsbrEnc_AddRight(v_freq, length_v_freq, 1); - - /* calc min and max values of mandatory borders */ - *bmin = v_bord[0]; - for (i = 0; i < *length_v_bord; i++) - if (v_bord[i] < *bmin) *bmin = v_bord[i]; - - *bmax = v_bord[0]; - for (i = 0; i < *length_v_bord; i++) - if (v_bord[i] > *bmax) *bmax = v_bord[i]; -} - -/******************************************************************************* - Functionname: fillFramePre - ******************************************************************************* - - Description: Add borders before mandatory borders, if needed - - Arguments: - modified: - v_bord - int pointer to v_bord vector - length_v_bord - length of v_bord vector - v_freq - int pointer to v_freq vector - length_v_freq - length of v_freq vector - not modified: - dmax - int value - bmin - int value - rest - int value - - Return: none - -*******************************************************************************/ -static void fillFramePre(INT dmax, INT *v_bord, INT *length_v_bord, INT *v_freq, - INT *length_v_freq, INT bmin, INT rest) { - /* - input state: - v_bord = [(Ba),Bd1, Bd2 ,(Bd3)] - v_freq = [(Fa),Fd1,(Fd2),1 ] - */ - - INT parts, d, j, S, s = 0, segm, bord; - - /* - start with one envelope - */ - - parts = 1; - d = rest; - - /* - calc # of additional envelopes and corresponding lengths - */ - - while (d > dmax) { - parts++; - - segm = rest / parts; - S = (segm - 2) >> 1; - s = fixMin(8, 2 * S + 2); - d = rest - (parts - 1) * s; - } - - /* - add borders before mandatory borders - */ - - bord = bmin; - - for (j = 0; j <= parts - 2; j++) { - bord = bord - s; - - /* v_bord = [...,(Bf),(Ba),Bd1, Bd2 ,(Bd3)] */ - FDKsbrEnc_AddLeft(v_bord, length_v_bord, bord); - - /* v_freq = [...,(1 ),(Fa),Fd1,(Fd2), 1 ] */ - FDKsbrEnc_AddLeft(v_freq, length_v_freq, 1); - } -} - -/***************************************************************************/ -/*! - \brief Overlap control - - Calculate max length of trailing fill segments, such that we always get a - border within the frame overlap region - - \return void - -****************************************************************************/ -static int calcFillLengthMax( - int tranPos, /*!< input : transient position (ref: tran det) */ - int numberTimeSlots /*!< input : number of timeslots */ -) { - int fmax; - - /* - calculate transient position within envelope buffer - */ - switch (numberTimeSlots) { - case NUMBER_TIME_SLOTS_2048: - if (tranPos < 4) - fmax = 6; - else if (tranPos == 4 || tranPos == 5) - fmax = 4; - else - fmax = 8; - break; - - case NUMBER_TIME_SLOTS_1920: - if (tranPos < 4) - fmax = 5; - else if (tranPos == 4 || tranPos == 5) - fmax = 3; - else - fmax = 7; - break; - - default: - fmax = 8; - break; - } - - return fmax; -} - -/******************************************************************************* - Functionname: fillFramePost - ******************************************************************************* - - Description: -Add borders after mandatory borders, if needed - Make a preliminary design of next frame, - assuming no transient is present there - - Arguments: - modified: - parts - int pointer to parts (call by reference) - d - int pointer to d (call by reference) - v_bord - int pointer to v_bord vector - length_v_bord - length of v_bord vector - v_freq - int pointer to v_freq vector - length_v_freq - length of v_freq vector - not modified: - bmax - int value - dmax - int value - - Return: none - -*******************************************************************************/ -static void fillFramePost(INT *parts, INT *d, INT dmax, INT *v_bord, - INT *length_v_bord, INT *v_freq, INT *length_v_freq, - INT bmax, INT bufferFrameStart, INT numberTimeSlots, - INT fmax) { - INT j, rest, segm, S, s = 0, bord; - - /* - input state: - v_bord = [...,(Bf),(Ba),Bd1, Bd2 ,(Bd3)] - v_freq = [...,(1 ),(Fa),Fd1,(Fd2),1 ] - */ - - rest = bufferFrameStart + 2 * numberTimeSlots - bmax; - *d = rest; - - if (*d > 0) { - *parts = 1; /* start with one envelope */ - - /* calc # of additional envelopes and corresponding lengths */ - - while (*d > dmax) { - *parts = *parts + 1; - - segm = rest / (*parts); - S = (segm - 2) >> 1; - s = fixMin(fmax, 2 * S + 2); - *d = rest - (*parts - 1) * s; - } - - /* add borders after mandatory borders */ - - bord = bmax; - for (j = 0; j <= *parts - 2; j++) { - bord += s; - - /* v_bord = [...,(Bf),(Ba),Bd1, Bd2 ,(Bd3),(Bf)] */ - FDKsbrEnc_AddRight(v_bord, length_v_bord, bord); - - /* v_freq = [...,(1 ),(Fa),Fd1,(Fd2), 1 , 1! ,1] */ - FDKsbrEnc_AddRight(v_freq, length_v_freq, 1); - } - } else { - *parts = 1; - - /* remove last element from v_bord and v_freq */ - - *length_v_bord = *length_v_bord - 1; - *length_v_freq = *length_v_freq - 1; - } -} - -/******************************************************************************* - Functionname: fillFrameInter - ******************************************************************************* - - Description: - - Arguments: nL - - v_tuningSegm - - v_bord - - length_v_bord - - bmin - - v_freq - - length_v_freq - - v_bordFollow - - length_v_bordFollow - - v_freqFollow - - length_v_freqFollow - - i_fillFollow - - dmin - - dmax - - - Return: none - -*******************************************************************************/ -static void fillFrameInter(INT *nL, const int *v_tuningSegm, INT *v_bord, - INT *length_v_bord, INT bmin, INT *v_freq, - INT *length_v_freq, INT *v_bordFollow, - INT *length_v_bordFollow, INT *v_freqFollow, - INT *length_v_freqFollow, INT i_fillFollow, INT dmin, - INT dmax, INT numberTimeSlots) { - INT middle, b_new, numBordFollow, bordMaxFollow, i; - - if (numberTimeSlots != NUMBER_TIME_SLOTS_1152) { - /* % remove fill borders: */ - if (i_fillFollow >= 1) { - *length_v_bordFollow = i_fillFollow; - *length_v_freqFollow = i_fillFollow; - } - - numBordFollow = *length_v_bordFollow; - bordMaxFollow = v_bordFollow[numBordFollow - 1]; - - /* remove even more borders if needed */ - middle = bmin - bordMaxFollow; - while (middle < 0) { - numBordFollow--; - bordMaxFollow = v_bordFollow[numBordFollow - 1]; - middle = bmin - bordMaxFollow; - } - - *length_v_bordFollow = numBordFollow; - *length_v_freqFollow = numBordFollow; - *nL = numBordFollow - 1; - - b_new = *length_v_bord; - - if (middle <= dmax) { - if (middle >= dmin) { /* concatenate */ - FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow, - *length_v_bordFollow); - FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow, - *length_v_freqFollow); - } - - else { - if (v_tuningSegm[0] != 0) { /* remove one new border and concatenate */ - *length_v_bord = b_new - 1; - FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow, - *length_v_bordFollow); - - *length_v_freq = b_new - 1; - FDKsbrEnc_AddVecLeft(v_freq + 1, length_v_freq, v_freqFollow, - *length_v_freqFollow); - } else { - if (*length_v_bordFollow > - 1) { /* remove one old border and concatenate */ - FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow, - *length_v_bordFollow - 1); - FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow, - *length_v_bordFollow - 1); - - *nL = *nL - 1; - } else { /* remove new "transient" border and concatenate */ - - for (i = 0; i < *length_v_bord - 1; i++) v_bord[i] = v_bord[i + 1]; - - for (i = 0; i < *length_v_freq - 1; i++) v_freq[i] = v_freq[i + 1]; - - *length_v_bord = b_new - 1; - *length_v_freq = b_new - 1; - - FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow, - *length_v_bordFollow); - FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow, - *length_v_freqFollow); - } - } - } - } else { /* middle > dmax */ - - fillFramePre(dmax, v_bord, length_v_bord, v_freq, length_v_freq, bmin, - middle); - FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow, - *length_v_bordFollow); - FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow, - *length_v_freqFollow); - } - - } else { /* numberTimeSlots==NUMBER_TIME_SLOTS_1152 */ - - INT l, m; - - /*------------------------------------------------------------------------ - remove fill borders - ------------------------------------------------------------------------*/ - if (i_fillFollow >= 1) { - *length_v_bordFollow = i_fillFollow; - *length_v_freqFollow = i_fillFollow; - } - - numBordFollow = *length_v_bordFollow; - bordMaxFollow = v_bordFollow[numBordFollow - 1]; - - /*------------------------------------------------------------------------ - remove more borders if necessary to eliminate overlap - ------------------------------------------------------------------------*/ - - /* check for overlap */ - middle = bmin - bordMaxFollow; - - /* intervals: - i) middle < 0 : overlap, must remove borders - ii) 0 <= middle < dmin : no overlap but too tight, must remove - borders iii) dmin <= middle <= dmax : ok, just concatenate iv) dmax - <= middle : too wide, must add borders - */ - - /* first remove old non-fill-borders... */ - while (middle < 0) { - /* ...but don't remove all of them */ - if (numBordFollow == 1) break; - - numBordFollow--; - bordMaxFollow = v_bordFollow[numBordFollow - 1]; - middle = bmin - bordMaxFollow; - } - - /* if this isn't enough, remove new non-fill borders */ - if (middle < 0) { - for (l = 0, m = 0; l < *length_v_bord; l++) { - if (v_bord[l] > bordMaxFollow) { - v_bord[m] = v_bord[l]; - v_freq[m] = v_freq[l]; - m++; - } - } - - *length_v_bord = l; - *length_v_freq = l; - - bmin = v_bord[0]; - } - - /*------------------------------------------------------------------------ - update modified follow-up data - ------------------------------------------------------------------------*/ - - *length_v_bordFollow = numBordFollow; - *length_v_freqFollow = numBordFollow; - - /* left relative borders correspond to follow-up */ - *nL = numBordFollow - 1; - - /*------------------------------------------------------------------------ - take care of intervals ii through iv - ------------------------------------------------------------------------*/ - - /* now middle should be >= 0 */ - middle = bmin - bordMaxFollow; - - if (middle <= dmin) /* (ii) */ - { - b_new = *length_v_bord; - - if (v_tuningSegm[0] != 0) { - /* remove new "luxury" border and concatenate */ - *length_v_bord = b_new - 1; - FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow, - *length_v_bordFollow); - - *length_v_freq = b_new - 1; - FDKsbrEnc_AddVecLeft(v_freq + 1, length_v_freq, v_freqFollow, - *length_v_freqFollow); - - } else if (*length_v_bordFollow > 1) { - /* remove old border and concatenate */ - FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow, - *length_v_bordFollow - 1); - FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow, - *length_v_bordFollow - 1); - - *nL = *nL - 1; - } else { - /* remove new border and concatenate */ - for (i = 0; i < *length_v_bord - 1; i++) v_bord[i] = v_bord[i + 1]; - - for (i = 0; i < *length_v_freq - 1; i++) v_freq[i] = v_freq[i + 1]; - - *length_v_bord = b_new - 1; - *length_v_freq = b_new - 1; - - FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow, - *length_v_bordFollow); - FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow, - *length_v_freqFollow); - } - } else if ((middle >= dmin) && (middle <= dmax)) /* (iii) */ - { - /* concatenate */ - FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow, - *length_v_bordFollow); - FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow, - *length_v_freqFollow); - - } else /* (iv) */ - { - fillFramePre(dmax, v_bord, length_v_bord, v_freq, length_v_freq, bmin, - middle); - FDKsbrEnc_AddVecLeft(v_bord, length_v_bord, v_bordFollow, - *length_v_bordFollow); - FDKsbrEnc_AddVecLeft(v_freq, length_v_freq, v_freqFollow, - *length_v_freqFollow); - } - } -} - -/******************************************************************************* - Functionname: calcFrameClass - ******************************************************************************* - - Description: - - Arguments: INT* frameClass, INT* frameClassOld, INT tranFlag, INT* spreadFlag) - - Return: none - -*******************************************************************************/ -static void calcFrameClass(FRAME_CLASS *frameClass, FRAME_CLASS *frameClassOld, - INT tranFlag, INT *spreadFlag) { - switch (*frameClassOld) { - case FIXFIXonly: - case FIXFIX: - if (tranFlag) - *frameClass = FIXVAR; - else - *frameClass = FIXFIX; - break; - case FIXVAR: - if (tranFlag) { - *frameClass = VARVAR; - *spreadFlag = 0; - } else { - if (*spreadFlag) - *frameClass = VARVAR; - else - *frameClass = VARFIX; - } - break; - case VARFIX: - if (tranFlag) - *frameClass = FIXVAR; - else - *frameClass = FIXFIX; - break; - case VARVAR: - if (tranFlag) { - *frameClass = VARVAR; - *spreadFlag = 0; - } else { - if (*spreadFlag) - *frameClass = VARVAR; - else - *frameClass = VARFIX; - } - break; - }; - - *frameClassOld = *frameClass; -} - -/******************************************************************************* - Functionname: specialCase - ******************************************************************************* - - Description: - - Arguments: spreadFlag - allowSpread - v_bord - length_v_bord - v_freq - length_v_freq - parts - d - - Return: none - -*******************************************************************************/ -static void specialCase(INT *spreadFlag, INT allowSpread, INT *v_bord, - INT *length_v_bord, INT *v_freq, INT *length_v_freq, - INT *parts, INT d) { - INT L; - - L = *length_v_bord; - - if (allowSpread) { /* add one "step 8" */ - *spreadFlag = 1; - FDKsbrEnc_AddRight(v_bord, length_v_bord, v_bord[L - 1] + 8); - FDKsbrEnc_AddRight(v_freq, length_v_freq, 1); - (*parts)++; - } else { - if (d == 1) { /* stretch one slot */ - *length_v_bord = L - 1; - *length_v_freq = L - 1; - } else { - if ((v_bord[L - 1] - v_bord[L - 2]) > 2) { /* compress one quant step */ - v_bord[L - 1] = v_bord[L - 1] - 2; - v_freq[*length_v_freq - 1] = 0; /* use low res for short segment */ - } - } - } -} - -/******************************************************************************* - Functionname: calcCmonBorder - ******************************************************************************* - - Description: - - Arguments: i_cmon - i_tran - v_bord - length_v_bord - tran - - Return: none - -*******************************************************************************/ -static void calcCmonBorder(INT *i_cmon, INT *i_tran, INT *v_bord, - INT *length_v_bord, INT tran, INT bufferFrameStart, - INT numberTimeSlots) { /* FH 00-06-26 */ - INT i; - - for (i = 0; i < *length_v_bord; i++) - if (v_bord[i] >= bufferFrameStart + numberTimeSlots) { /* FH 00-06-26 */ - *i_cmon = i; - break; - } - - /* keep track of transient: */ - for (i = 0; i < *length_v_bord; i++) - if (v_bord[i] >= tran) { - *i_tran = i; - break; - } else - *i_tran = EMPTY; -} - -/******************************************************************************* - Functionname: keepForFollowUp - ******************************************************************************* - - Description: - - Arguments: v_bordFollow - length_v_bordFollow - v_freqFollow - length_v_freqFollow - i_tranFollow - i_fillFollow - v_bord - length_v_bord - v_freq - i_cmon - i_tran - parts) - - Return: none - -*******************************************************************************/ -static void keepForFollowUp(INT *v_bordFollow, INT *length_v_bordFollow, - INT *v_freqFollow, INT *length_v_freqFollow, - INT *i_tranFollow, INT *i_fillFollow, INT *v_bord, - INT *length_v_bord, INT *v_freq, INT i_cmon, - INT i_tran, INT parts, - INT numberTimeSlots) { /* FH 00-06-26 */ - INT L, i, j; - - L = *length_v_bord; - - (*length_v_bordFollow) = 0; - (*length_v_freqFollow) = 0; - - for (j = 0, i = i_cmon; i < L; i++, j++) { - v_bordFollow[j] = v_bord[i] - numberTimeSlots; /* FH 00-06-26 */ - v_freqFollow[j] = v_freq[i]; - (*length_v_bordFollow)++; - (*length_v_freqFollow)++; - } - if (i_tran != EMPTY) - *i_tranFollow = i_tran - i_cmon; - else - *i_tranFollow = EMPTY; - *i_fillFollow = L - (parts - 1) - i_cmon; -} - -/******************************************************************************* - Functionname: calcCtrlSignal - ******************************************************************************* - - Description: - - Arguments: hSbrGrid - frameClass - v_bord - length_v_bord - v_freq - length_v_freq - i_cmon - i_tran - spreadFlag - nL - - Return: none - -*******************************************************************************/ -static void calcCtrlSignal(HANDLE_SBR_GRID hSbrGrid, FRAME_CLASS frameClass, - INT *v_bord, INT length_v_bord, INT *v_freq, - INT length_v_freq, INT i_cmon, INT i_tran, - INT spreadFlag, INT nL) { - INT i, r, a, n, p, b, aL, aR, ntot, nmax, nR; - - INT *v_f = hSbrGrid->v_f; - INT *v_fLR = hSbrGrid->v_fLR; - INT *v_r = hSbrGrid->bs_rel_bord; - INT *v_rL = hSbrGrid->bs_rel_bord_0; - INT *v_rR = hSbrGrid->bs_rel_bord_1; - - INT length_v_r = 0; - INT length_v_rR = 0; - INT length_v_rL = 0; - - switch (frameClass) { - case FIXVAR: - /* absolute border: */ - - a = v_bord[i_cmon]; - - /* relative borders: */ - length_v_r = 0; - i = i_cmon; - - while (i >= 1) { - r = v_bord[i] - v_bord[i - 1]; - FDKsbrEnc_AddRight(v_r, &length_v_r, r); - i--; - } - - /* number of relative borders: */ - n = length_v_r; - - /* freq res: */ - for (i = 0; i < i_cmon; i++) v_f[i] = v_freq[i_cmon - 1 - i]; - v_f[i_cmon] = 1; - - /* pointer: */ - p = (i_cmon >= i_tran && i_tran != EMPTY) ? (i_cmon - i_tran + 1) : (0); - - hSbrGrid->frameClass = frameClass; - hSbrGrid->bs_abs_bord = a; - hSbrGrid->n = n; - hSbrGrid->p = p; - - break; - case VARFIX: - /* absolute border: */ - a = v_bord[0]; - - /* relative borders: */ - length_v_r = 0; - - for (i = 1; i < length_v_bord; i++) { - r = v_bord[i] - v_bord[i - 1]; - FDKsbrEnc_AddRight(v_r, &length_v_r, r); - } - - /* number of relative borders: */ - n = length_v_r; - - /* freq res: */ - FDKmemcpy(v_f, v_freq, length_v_freq * sizeof(INT)); - - /* pointer: */ - p = (i_tran >= 0 && i_tran != EMPTY) ? (i_tran + 1) : (0); - - hSbrGrid->frameClass = frameClass; - hSbrGrid->bs_abs_bord = a; - hSbrGrid->n = n; - hSbrGrid->p = p; - - break; - case VARVAR: - if (spreadFlag) { - /* absolute borders: */ - b = length_v_bord; - - aL = v_bord[0]; - aR = v_bord[b - 1]; - - /* number of relative borders: */ - ntot = b - 2; - - nmax = 2; /* n: {0,1,2} */ - if (ntot > nmax) { - nL = nmax; - nR = ntot - nmax; - } else { - nL = ntot; - nR = 0; - } - - /* relative borders: */ - length_v_rL = 0; - for (i = 1; i <= nL; i++) { - r = v_bord[i] - v_bord[i - 1]; - FDKsbrEnc_AddRight(v_rL, &length_v_rL, r); - } - - length_v_rR = 0; - i = b - 1; - while (i >= b - nR) { - r = v_bord[i] - v_bord[i - 1]; - FDKsbrEnc_AddRight(v_rR, &length_v_rR, r); - i--; - } - - /* pointer (only one due to constraint in frame info): */ - p = (i_tran > 0 && i_tran != EMPTY) ? (b - i_tran) : (0); - - /* freq res: */ - - for (i = 0; i < b - 1; i++) v_fLR[i] = v_freq[i]; - } else { - length_v_bord = i_cmon + 1; - - /* absolute borders: */ - b = length_v_bord; - - aL = v_bord[0]; - aR = v_bord[b - 1]; - - /* number of relative borders: */ - ntot = b - 2; - nR = ntot - nL; - - /* relative borders: */ - length_v_rL = 0; - for (i = 1; i <= nL; i++) { - r = v_bord[i] - v_bord[i - 1]; - FDKsbrEnc_AddRight(v_rL, &length_v_rL, r); - } - - length_v_rR = 0; - i = b - 1; - while (i >= b - nR) { - r = v_bord[i] - v_bord[i - 1]; - FDKsbrEnc_AddRight(v_rR, &length_v_rR, r); - i--; - } - - /* pointer (only one due to constraint in frame info): */ - p = (i_cmon >= i_tran && i_tran != EMPTY) ? (i_cmon - i_tran + 1) : (0); - - /* freq res: */ - for (i = 0; i < b - 1; i++) v_fLR[i] = v_freq[i]; - } - - hSbrGrid->frameClass = frameClass; - hSbrGrid->bs_abs_bord_0 = aL; - hSbrGrid->bs_abs_bord_1 = aR; - hSbrGrid->bs_num_rel_0 = nL; - hSbrGrid->bs_num_rel_1 = nR; - hSbrGrid->p = p; - - break; - - default: - /* do nothing */ - break; - } -} - -/******************************************************************************* - Functionname: createDefFrameInfo - ******************************************************************************* - - Description: Copies the default (static) frameInfo structs to the frameInfo - passed by reference; only used for FIXFIX frames - - Arguments: hFrameInfo - HANLDE_SBR_FRAME_INFO - nEnv - INT - nTimeSlots - INT - - Return: none; hSbrFrameInfo contains a copy of the default frameInfo - - Written: Andreas Schneider - Revised: -*******************************************************************************/ -static void createDefFrameInfo(HANDLE_SBR_FRAME_INFO hSbrFrameInfo, INT nEnv, - INT nTimeSlots) { - switch (nEnv) { - case 1: - switch (nTimeSlots) { - case NUMBER_TIME_SLOTS_1920: - FDKmemcpy(hSbrFrameInfo, &frameInfo1_1920, sizeof(SBR_FRAME_INFO)); - break; - case NUMBER_TIME_SLOTS_2048: - FDKmemcpy(hSbrFrameInfo, &frameInfo1_2048, sizeof(SBR_FRAME_INFO)); - break; - case NUMBER_TIME_SLOTS_1152: - FDKmemcpy(hSbrFrameInfo, &frameInfo1_1152, sizeof(SBR_FRAME_INFO)); - break; - case NUMBER_TIME_SLOTS_2304: - FDKmemcpy(hSbrFrameInfo, &frameInfo1_2304, sizeof(SBR_FRAME_INFO)); - break; - case NUMBER_TIME_SLOTS_512LD: - FDKmemcpy(hSbrFrameInfo, &frameInfo1_512LD, sizeof(SBR_FRAME_INFO)); - break; - default: - FDK_ASSERT(0); - } - break; - case 2: - switch (nTimeSlots) { - case NUMBER_TIME_SLOTS_1920: - FDKmemcpy(hSbrFrameInfo, &frameInfo2_1920, sizeof(SBR_FRAME_INFO)); - break; - case NUMBER_TIME_SLOTS_2048: - FDKmemcpy(hSbrFrameInfo, &frameInfo2_2048, sizeof(SBR_FRAME_INFO)); - break; - case NUMBER_TIME_SLOTS_1152: - FDKmemcpy(hSbrFrameInfo, &frameInfo2_1152, sizeof(SBR_FRAME_INFO)); - break; - case NUMBER_TIME_SLOTS_2304: - FDKmemcpy(hSbrFrameInfo, &frameInfo2_2304, sizeof(SBR_FRAME_INFO)); - break; - case NUMBER_TIME_SLOTS_512LD: - FDKmemcpy(hSbrFrameInfo, &frameInfo2_512LD, sizeof(SBR_FRAME_INFO)); - break; - default: - FDK_ASSERT(0); - } - break; - case 4: - switch (nTimeSlots) { - case NUMBER_TIME_SLOTS_1920: - FDKmemcpy(hSbrFrameInfo, &frameInfo4_1920, sizeof(SBR_FRAME_INFO)); - break; - case NUMBER_TIME_SLOTS_2048: - FDKmemcpy(hSbrFrameInfo, &frameInfo4_2048, sizeof(SBR_FRAME_INFO)); - break; - case NUMBER_TIME_SLOTS_1152: - FDKmemcpy(hSbrFrameInfo, &frameInfo4_1152, sizeof(SBR_FRAME_INFO)); - break; - case NUMBER_TIME_SLOTS_2304: - FDKmemcpy(hSbrFrameInfo, &frameInfo4_2304, sizeof(SBR_FRAME_INFO)); - break; - case NUMBER_TIME_SLOTS_512LD: - FDKmemcpy(hSbrFrameInfo, &frameInfo4_512LD, sizeof(SBR_FRAME_INFO)); - break; - default: - FDK_ASSERT(0); - } - break; - default: - FDK_ASSERT(0); - } -} - -/******************************************************************************* - Functionname: ctrlSignal2FrameInfo - ******************************************************************************* - - Description: Convert "clear-text" sbr_grid() to "frame info" used by the - envelope and noise floor estimators. - This is basically (except for "low level" calculations) the - bitstream decoder defined in the MPEG-4 standard, sub clause - 4.6.18.3.3, Time / Frequency Grid. See inline comments for - explanation of the shorten and noise border algorithms. - - Arguments: hSbrGrid - source - hSbrFrameInfo - destination - freq_res_fixfix - frequency resolution for FIXFIX frames - - Return: void; hSbrFrameInfo contains the updated FRAME_INFO struct - -*******************************************************************************/ -static void ctrlSignal2FrameInfo( - HANDLE_SBR_GRID hSbrGrid, /* input : the grid handle */ - HANDLE_SBR_FRAME_INFO hSbrFrameInfo, /* output: the frame info handle */ - FREQ_RES - *freq_res_fixfix /* in/out: frequency resolution for FIXFIX frames */ -) { - INT frameSplit = 0; - INT nEnv = 0, border = 0, i, k, p /*?*/; - INT *v_r = hSbrGrid->bs_rel_bord; - INT *v_f = hSbrGrid->v_f; - - FRAME_CLASS frameClass = hSbrGrid->frameClass; - INT bufferFrameStart = hSbrGrid->bufferFrameStart; - INT numberTimeSlots = hSbrGrid->numberTimeSlots; - - switch (frameClass) { - case FIXFIX: - createDefFrameInfo(hSbrFrameInfo, hSbrGrid->bs_num_env, numberTimeSlots); - - frameSplit = (hSbrFrameInfo->nEnvelopes > 1); - for (i = 0; i < hSbrFrameInfo->nEnvelopes; i++) { - hSbrGrid->v_f[i] = hSbrFrameInfo->freqRes[i] = - freq_res_fixfix[frameSplit]; - } - break; - - case FIXVAR: - case VARFIX: - nEnv = hSbrGrid->n + 1; /* read n [SBR_NUM_BITS bits] */ /*? snd*/ - FDK_ASSERT(nEnv <= MAX_ENVELOPES_FIXVAR_VARFIX); - - hSbrFrameInfo->nEnvelopes = nEnv; - - border = hSbrGrid->bs_abs_bord; /* read the absolute border */ - - if (nEnv == 1) - hSbrFrameInfo->nNoiseEnvelopes = 1; - else - hSbrFrameInfo->nNoiseEnvelopes = 2; - - break; - - default: - /* do nothing */ - break; - } - - switch (frameClass) { - case FIXVAR: - hSbrFrameInfo->borders[0] = - bufferFrameStart; /* start-position of 1st envelope */ - - hSbrFrameInfo->borders[nEnv] = border; - - for (k = 0, i = nEnv - 1; k < nEnv - 1; k++, i--) { - border -= v_r[k]; - hSbrFrameInfo->borders[i] = border; - } - - /* make either envelope nr. nEnv + 1 - p short; or don't shorten if p == 0 - */ - p = hSbrGrid->p; - if (p == 0) { - hSbrFrameInfo->shortEnv = 0; - } else { - hSbrFrameInfo->shortEnv = nEnv + 1 - p; - } - - for (k = 0, i = nEnv - 1; k < nEnv; k++, i--) { - hSbrFrameInfo->freqRes[i] = (FREQ_RES)v_f[k]; - } - - /* if either there is no short envelope or the last envelope is short... - */ - if (p == 0 || p == 1) { - hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv - 1]; - } else { - hSbrFrameInfo->bordersNoise[1] = - hSbrFrameInfo->borders[hSbrFrameInfo->shortEnv]; - } - - break; - - case VARFIX: - /* in this case 'border' indicates the start of the 1st envelope */ - hSbrFrameInfo->borders[0] = border; - - for (k = 0; k < nEnv - 1; k++) { - border += v_r[k]; - hSbrFrameInfo->borders[k + 1] = border; - } - - hSbrFrameInfo->borders[nEnv] = bufferFrameStart + numberTimeSlots; - - p = hSbrGrid->p; - if (p == 0 || p == 1) { - hSbrFrameInfo->shortEnv = 0; - } else { - hSbrFrameInfo->shortEnv = p - 1; - } - - for (k = 0; k < nEnv; k++) { - hSbrFrameInfo->freqRes[k] = (FREQ_RES)v_f[k]; - } - - switch (p) { - case 0: - hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[1]; - break; - case 1: - hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv - 1]; - break; - default: - hSbrFrameInfo->bordersNoise[1] = - hSbrFrameInfo->borders[hSbrFrameInfo->shortEnv]; - break; - } - break; - - case VARVAR: - nEnv = hSbrGrid->bs_num_rel_0 + hSbrGrid->bs_num_rel_1 + 1; - FDK_ASSERT(nEnv <= MAX_ENVELOPES_VARVAR); /* just to be sure */ - hSbrFrameInfo->nEnvelopes = nEnv; - - hSbrFrameInfo->borders[0] = border = hSbrGrid->bs_abs_bord_0; - - for (k = 0, i = 1; k < hSbrGrid->bs_num_rel_0; k++, i++) { - border += hSbrGrid->bs_rel_bord_0[k]; - hSbrFrameInfo->borders[i] = border; - } - - border = hSbrGrid->bs_abs_bord_1; - hSbrFrameInfo->borders[nEnv] = border; - - for (k = 0, i = nEnv - 1; k < hSbrGrid->bs_num_rel_1; k++, i--) { - border -= hSbrGrid->bs_rel_bord_1[k]; - hSbrFrameInfo->borders[i] = border; - } - - p = hSbrGrid->p; - if (p == 0) { - hSbrFrameInfo->shortEnv = 0; - } else { - hSbrFrameInfo->shortEnv = nEnv + 1 - p; - } - - for (k = 0; k < nEnv; k++) { - hSbrFrameInfo->freqRes[k] = (FREQ_RES)hSbrGrid->v_fLR[k]; - } - - if (nEnv == 1) { - hSbrFrameInfo->nNoiseEnvelopes = 1; - hSbrFrameInfo->bordersNoise[0] = hSbrGrid->bs_abs_bord_0; - hSbrFrameInfo->bordersNoise[1] = hSbrGrid->bs_abs_bord_1; - } else { - hSbrFrameInfo->nNoiseEnvelopes = 2; - hSbrFrameInfo->bordersNoise[0] = hSbrGrid->bs_abs_bord_0; - - if (p == 0 || p == 1) { - hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv - 1]; - } else { - hSbrFrameInfo->bordersNoise[1] = - hSbrFrameInfo->borders[hSbrFrameInfo->shortEnv]; - } - hSbrFrameInfo->bordersNoise[2] = hSbrGrid->bs_abs_bord_1; - } - break; - - default: - /* do nothing */ - break; - } - - if (frameClass == VARFIX || frameClass == FIXVAR) { - hSbrFrameInfo->bordersNoise[0] = hSbrFrameInfo->borders[0]; - if (nEnv == 1) { - hSbrFrameInfo->bordersNoise[1] = hSbrFrameInfo->borders[nEnv]; - } else { - hSbrFrameInfo->bordersNoise[2] = hSbrFrameInfo->borders[nEnv]; - } - } -} --- a/libSBRenc/src/fram_gen.h +++ /dev/null @@ -1,343 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Framing generator prototypes and structs $Revision: 92790 $ -*/ -#ifndef FRAM_GEN_H -#define FRAM_GEN_H - -#include "sbr_def.h" /* for MAX_ENVELOPES and MAX_NOISE_ENVELOPES in struct FRAME_INFO and CODEC_TYPE */ -#include "sbr_encoder.h" /* for FREQ_RES */ - -#define MAX_ENVELOPES_VARVAR \ - MAX_ENVELOPES /*!< worst case number of envelopes in a VARVAR frame */ -#define MAX_ENVELOPES_FIXVAR_VARFIX \ - 4 /*!< worst case number of envelopes in VARFIX and FIXVAR frames */ -#define MAX_NUM_REL \ - 3 /*!< maximum number of relative borders in any VAR frame */ - -/* SBR frame class definitions */ -typedef enum { - FIXFIX = - 0, /*!< bs_frame_class: leading and trailing frame borders are fixed */ - FIXVAR, /*!< bs_frame_class: leading frame border is fixed, trailing frame - border is variable */ - VARFIX, /*!< bs_frame_class: leading frame border is variable, trailing frame - border is fixed */ - VARVAR /*!< bs_frame_class: leading and trailing frame borders are variable */ - , - FIXFIXonly /*!< bs_frame_class: leading border fixed (0), trailing border - fixed (nrTimeSlots) and encased borders are dynamically derived - from the tranPos */ -} FRAME_CLASS; - -/* helper constants */ -#define DC 4711 /*!< helper constant: don't care */ -#define EMPTY (-99) /*!< helper constant: empty */ - -/* system constants: AAC+SBR, DRM Frame-Length */ -#define FRAME_MIDDLE_SLOT_1920 4 -#define NUMBER_TIME_SLOTS_1920 15 - -#define LD_PRETRAN_OFF 3 -#define FRAME_MIDDLE_SLOT_512LD 4 -#define NUMBER_TIME_SLOTS_512LD 8 -#define TRANSIENT_OFFSET_LD 0 - -/* -system constants: AAC+SBR or aacPRO (hybrid format), Standard Frame-Length, -Multi-Rate ---------------------------------------------------------------------------- -Number of slots (numberTimeSlots): 16 (NUMBER_TIME_SLOTS_2048) -Detector-offset (frameMiddleSlot): 4 -Overlap : 3 -Buffer-offset : 8 (BUFFER_FRAME_START_2048 = 0) - - - |<------------tranPos---------->| - |c|d|e|f|0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f| - FixFix | | - FixVar | :<- ->: - VarFix :<- ->: | - VarVar :<- ->: :<- ->: - 0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 -................................................................................ - -|-|-|-|-|-|-|-|-B-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-B-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-| - -frame-generator:0 16 24 32 -analysis-buffer:8 24 32 40 -*/ -#define FRAME_MIDDLE_SLOT_2048 4 -#define NUMBER_TIME_SLOTS_2048 16 - -/* -system constants: mp3PRO, Multi-Rate & Single-Rate --------------------------------------------------- -Number of slots (numberTimeSlots): 9 (NUMBER_TIME_SLOTS_1152) -Detector-offset (frameMiddleSlot): 4 (FRAME_MIDDLE_SLOT_1152) -Overlap : 3 -Buffer-offset : 4.5 (BUFFER_FRAME_START_1152 = 0) - - - |<----tranPos---->| - |5|6|7|8|0|1|2|3|4|5|6|7|8| - FixFix | | - FixVar | :<- ->: - VarFix :<- ->: | - VarVar :<- ->: :<- ->: - 0 1 2 3 4 5 6 7 8 0 1 2 3 - ............................................. - - -|-|-|-|-B-|-|-|-|-|-|-|-|-B-|-|-|-|-|-|-|-|-| - -frame-generator: 0 9 13 18 -analysis-buffer: 4.5 13.5 22.5 -*/ -#define FRAME_MIDDLE_SLOT_1152 4 -#define NUMBER_TIME_SLOTS_1152 9 - -/* system constants: Layer2+SBR */ -#define FRAME_MIDDLE_SLOT_2304 8 -#define NUMBER_TIME_SLOTS_2304 18 - -/*! - \struct SBR_GRID - \brief sbr_grid() signals to be converted to bitstream elements - - The variables hold the signals (e.g. lengths and numbers) in "clear text" -*/ - -typedef struct { - /* system constants */ - INT bufferFrameStart; /*!< frame generator vs analysis buffer time alignment - (currently set to 0, offset added elsewhere) */ - INT numberTimeSlots; /*!< number of SBR timeslots per frame */ - - /* will be adjusted for every frame */ - FRAME_CLASS frameClass; /*!< SBR frame class */ - INT bs_num_env; /*!< bs_num_env, number of envelopes for FIXFIX */ - INT bs_abs_bord; /*!< bs_abs_bord, absolute border for VARFIX and FIXVAR */ - INT n; /*!< number of relative borders for VARFIX and FIXVAR */ - INT p; /*!< pointer-to-transient-border */ - INT bs_rel_bord[MAX_NUM_REL]; /*!< bs_rel_bord, relative borders for all VAR - */ - INT v_f[MAX_ENVELOPES_FIXVAR_VARFIX]; /*!< envelope frequency resolutions for - FIXVAR and VARFIX */ - - INT bs_abs_bord_0; /*!< bs_abs_bord_0, leading absolute border for VARVAR */ - INT bs_abs_bord_1; /*!< bs_abs_bord_1, trailing absolute border for VARVAR */ - INT bs_num_rel_0; /*!< bs_num_rel_0, number of relative borders associated - with leading absolute border for VARVAR */ - INT bs_num_rel_1; /*!< bs_num_rel_1, number of relative borders associated - with trailing absolute border for VARVAR */ - INT bs_rel_bord_0[MAX_NUM_REL]; /*!< bs_rel_bord_0, relative borders - associated with leading absolute border - for VARVAR */ - INT bs_rel_bord_1[MAX_NUM_REL]; /*!< bs_rel_bord_1, relative borders - associated with trailing absolute border - for VARVAR */ - INT v_fLR[MAX_ENVELOPES_VARVAR]; /*!< envelope frequency resolutions for - VARVAR */ - -} SBR_GRID; -typedef SBR_GRID *HANDLE_SBR_GRID; - -/*! - \struct SBR_FRAME_INFO - \brief time/frequency grid description for one frame -*/ -typedef struct { - INT nEnvelopes; /*!< number of envelopes */ - INT borders[MAX_ENVELOPES + 1]; /*!< envelope borders in SBR timeslots */ - FREQ_RES freqRes[MAX_ENVELOPES]; /*!< frequency resolution of each envelope */ - INT shortEnv; /*!< number of an envelope to be shortened (starting at 1) or 0 - for no shortened envelope */ - INT nNoiseEnvelopes; /*!< number of noise floors */ - INT bordersNoise[MAX_NOISE_ENVELOPES + - 1]; /*!< noise floor borders in SBR timeslots */ -} SBR_FRAME_INFO; -/* WARNING: When rearranging the elements of this struct keep in mind that the - * static initializations in the corresponding C-file have to be rearranged as - * well! snd 2002/01/23 - */ -typedef SBR_FRAME_INFO *HANDLE_SBR_FRAME_INFO; - -/*! - \struct SBR_ENVELOPE_FRAME - \brief frame generator main struct - - Contains tuning parameters, time/frequency grid description, sbr_grid() - bitstream elements, and generator internal signals -*/ -typedef struct { - /* system constants */ - INT frameMiddleSlot; /*!< transient detector offset in SBR timeslots */ - - /* basic tuning parameters */ - INT staticFraming; /*!< 1: run static framing in time, i.e. exclusive use of - bs_frame_class = FIXFIX */ - INT numEnvStatic; /*!< number of envelopes per frame for static framing */ - FREQ_RES - freq_res_fixfix[2]; /*!< envelope frequency resolution to use for - bs_frame_class = FIXFIX; single env and split */ - UCHAR - fResTransIsLow; /*!< frequency resolution for transient frames - always - low (0) or according to table (1) */ - - /* expert tuning parameters */ - const int *v_tuningSegm; /*!< segment lengths to use around transient */ - const int *v_tuningFreq; /*!< frequency resolutions to use around transient */ - INT dmin; /*!< minimum length of dependent segments */ - INT dmax; /*!< maximum length of dependent segments */ - INT allowSpread; /*!< 1: allow isolated transient to influence grid of 3 - consecutive frames */ - - /* internally used signals */ - FRAME_CLASS frameClassOld; /*!< frame class used for previous frame */ - INT spreadFlag; /*!< 1: use VARVAR instead of VARFIX to follow up old - transient */ - - INT v_bord[2 * MAX_ENVELOPES_VARVAR + 1]; /*!< borders for current frame and - preliminary borders for next - frame (fixed borders excluded) */ - INT length_v_bord; /*!< helper variable: length of v_bord */ - INT v_freq[2 * MAX_ENVELOPES_VARVAR + 1]; /*!< frequency resolutions for - current frame and preliminary - resolutions for next frame */ - INT length_v_freq; /*!< helper variable: length of v_freq */ - - INT v_bordFollow[MAX_ENVELOPES_VARVAR]; /*!< preliminary borders for current - frame (calculated during previous - frame) */ - INT length_v_bordFollow; /*!< helper variable: length of v_bordFollow */ - INT i_tranFollow; /*!< points to transient border in v_bordFollow (may be - negative, see keepForFollowUp()) */ - INT i_fillFollow; /*!< points to first fill border in v_bordFollow */ - INT v_freqFollow[MAX_ENVELOPES_VARVAR]; /*!< preliminary frequency resolutions - for current frame (calculated - during previous frame) */ - INT length_v_freqFollow; /*!< helper variable: length of v_freqFollow */ - - /* externally needed signals */ - SBR_GRID - SbrGrid; /*!< sbr_grid() signals to be converted to bitstream elements */ - SBR_FRAME_INFO - SbrFrameInfo; /*!< time/frequency grid description for one frame */ -} SBR_ENVELOPE_FRAME; -typedef SBR_ENVELOPE_FRAME *HANDLE_SBR_ENVELOPE_FRAME; - -void FDKsbrEnc_initFrameInfoGenerator(HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame, - INT allowSpread, INT numEnvStatic, - INT staticFraming, INT timeSlots, - const FREQ_RES *freq_res_fixfix, - UCHAR fResTransIsLow, INT ldGrid); - -HANDLE_SBR_FRAME_INFO -FDKsbrEnc_frameInfoGenerator(HANDLE_SBR_ENVELOPE_FRAME hSbrEnvFrame, - UCHAR *v_transient_info, const INT rightBorderFIX, - UCHAR *v_transient_info_pre, int ldGrid, - const int *v_tuning); - -#endif --- a/libSBRenc/src/invf_est.cpp +++ /dev/null @@ -1,610 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -#include "invf_est.h" -#include "sbr_misc.h" - -#include "genericStds.h" - -#define MAX_NUM_REGIONS 10 -#define SCALE_FAC_QUO 512.0f -#define SCALE_FAC_NRG 256.0f - -#ifndef min -#define min(a, b) (a < b ? a : b) -#endif - -#ifndef max -#define max(a, b) (a > b ? a : b) -#endif - -static const FIXP_DBL quantStepsSbr[4] = { - 0x00400000, 0x02800000, 0x03800000, - 0x04c00000}; /* table scaled with SCALE_FAC_QUO */ -static const FIXP_DBL quantStepsOrig[4] = { - 0x00000000, 0x00c00000, 0x01c00000, - 0x02800000}; /* table scaled with SCALE_FAC_QUO */ -static const FIXP_DBL nrgBorders[4] = { - 0x0c800000, 0x0f000000, 0x11800000, - 0x14000000}; /* table scaled with SCALE_FAC_NRG */ - -static const DETECTOR_PARAMETERS detectorParamsAAC = { - quantStepsSbr, - quantStepsOrig, - nrgBorders, - 4, /* Number of borders SBR. */ - 4, /* Number of borders orig. */ - 4, /* Number of borders Nrg. */ - { - /* Region space. */ - {INVF_MID_LEVEL, INVF_LOW_LEVEL, INVF_OFF, INVF_OFF, - INVF_OFF}, /* | */ - {INVF_MID_LEVEL, INVF_LOW_LEVEL, INVF_OFF, INVF_OFF, - INVF_OFF}, /* | */ - {INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_LOW_LEVEL, INVF_OFF, - INVF_OFF}, /* regionSbr */ - {INVF_HIGH_LEVEL, INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_OFF, - INVF_OFF}, /* | */ - {INVF_HIGH_LEVEL, INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_OFF, - INVF_OFF} /* | */ - }, /*------------------------ regionOrig ---------------------------------*/ - { - /* Region space transient. */ - {INVF_LOW_LEVEL, INVF_LOW_LEVEL, INVF_LOW_LEVEL, INVF_OFF, - INVF_OFF}, /* | */ - {INVF_LOW_LEVEL, INVF_LOW_LEVEL, INVF_LOW_LEVEL, INVF_OFF, - INVF_OFF}, /* | */ - {INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_MID_LEVEL, INVF_OFF, - INVF_OFF}, /* regionSbr */ - {INVF_HIGH_LEVEL, INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_OFF, - INVF_OFF}, /* | */ - {INVF_HIGH_LEVEL, INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_OFF, - INVF_OFF} /* | */ - }, /*------------------------ regionOrig ---------------------------------*/ - {-4, -3, -2, -1, - 0} /* Reduction factor of the inverse filtering for low energies.*/ -}; - -static const FIXP_DBL hysteresis = - 0x00400000; /* Delta value for hysteresis. scaled with SCALE_FAC_QUO */ - -/* - * AAC+SBR PARAMETERS for Speech - *********************************/ -static const DETECTOR_PARAMETERS detectorParamsAACSpeech = { - quantStepsSbr, - quantStepsOrig, - nrgBorders, - 4, /* Number of borders SBR. */ - 4, /* Number of borders orig. */ - 4, /* Number of borders Nrg. */ - { - /* Region space. */ - {INVF_MID_LEVEL, INVF_MID_LEVEL, INVF_LOW_LEVEL, INVF_OFF, - INVF_OFF}, /* | */ - {INVF_MID_LEVEL, INVF_MID_LEVEL, INVF_LOW_LEVEL, INVF_OFF, - INVF_OFF}, /* | */ - {INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_MID_LEVEL, INVF_OFF, - INVF_OFF}, /* regionSbr */ - {INVF_HIGH_LEVEL, INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_OFF, - INVF_OFF}, /* | */ - {INVF_HIGH_LEVEL, INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_OFF, - INVF_OFF} /* | */ - }, /*------------------------ regionOrig ---------------------------------*/ - { - /* Region space transient. */ - {INVF_MID_LEVEL, INVF_MID_LEVEL, INVF_LOW_LEVEL, INVF_OFF, - INVF_OFF}, /* | */ - {INVF_MID_LEVEL, INVF_MID_LEVEL, INVF_LOW_LEVEL, INVF_OFF, - INVF_OFF}, /* | */ - {INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_MID_LEVEL, INVF_OFF, - INVF_OFF}, /* regionSbr */ - {INVF_HIGH_LEVEL, INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_OFF, - INVF_OFF}, /* | */ - {INVF_HIGH_LEVEL, INVF_HIGH_LEVEL, INVF_MID_LEVEL, INVF_OFF, - INVF_OFF} /* | */ - }, /*------------------------ regionOrig ---------------------------------*/ - {-4, -3, -2, -1, - 0} /* Reduction factor of the inverse filtering for low energies.*/ -}; - -/* - * Smoothing filters. - ************************/ -typedef const FIXP_DBL FIR_FILTER[5]; - -static const FIR_FILTER fir_0 = {0x7fffffff, 0x00000000, 0x00000000, 0x00000000, - 0x00000000}; -static const FIR_FILTER fir_1 = {0x2aaaaa80, 0x555554ff, 0x00000000, 0x00000000, - 0x00000000}; -static const FIR_FILTER fir_2 = {0x10000000, 0x30000000, 0x40000000, 0x00000000, - 0x00000000}; -static const FIR_FILTER fir_3 = {0x077f80e8, 0x199999a0, 0x2bb3b240, 0x33333340, - 0x00000000}; -static const FIR_FILTER fir_4 = {0x04130598, 0x0ebdb000, 0x1becfa60, 0x2697a4c0, - 0x2aaaaa80}; - -static const FIR_FILTER *const fir_table[5] = {&fir_0, &fir_1, &fir_2, &fir_3, - &fir_4}; - -/**************************************************************************/ -/*! - \brief Calculates the values used for the detector. - - - \return none - -*/ -/**************************************************************************/ -static void calculateDetectorValues( - FIXP_DBL **quotaMatrixOrig, /*!< Matrix holding the tonality values of the - original. */ - SCHAR *indexVector, /*!< Index vector to obtain the patched data. */ - FIXP_DBL *nrgVector, /*!< Energy vector. */ - DETECTOR_VALUES *detectorValues, /*!< pointer to DETECTOR_VALUES struct. */ - INT startChannel, /*!< Start channel. */ - INT stopChannel, /*!< Stop channel. */ - INT startIndex, /*!< Start index. */ - INT stopIndex, /*!< Stop index. */ - INT numberOfStrongest /*!< The number of sorted tonal components to be - considered. */ -) { - INT i, temp, j; - - const FIXP_DBL *filter = *fir_table[INVF_SMOOTHING_LENGTH]; - FIXP_DBL origQuotaMeanStrongest, sbrQuotaMeanStrongest; - FIXP_DBL origQuota, sbrQuota; - FIXP_DBL invIndex, invChannel, invTemp; - FIXP_DBL quotaVecOrig[64], quotaVecSbr[64]; - - FDKmemclear(quotaVecOrig, 64 * sizeof(FIXP_DBL)); - FDKmemclear(quotaVecSbr, 64 * sizeof(FIXP_DBL)); - - invIndex = GetInvInt(stopIndex - startIndex); - invChannel = GetInvInt(stopChannel - startChannel); - - /* - Calculate the mean value, over the current time segment, for the original, - the HFR and the difference, over all channels in the current frequency range. - NOTE: the averaging is done on the values quota/(1 - quota + RELAXATION). - */ - - /* The original, the sbr signal and the total energy */ - detectorValues->avgNrg = FL2FXCONST_DBL(0.0f); - for (j = startIndex; j < stopIndex; j++) { - for (i = startChannel; i < stopChannel; i++) { - quotaVecOrig[i] += fMult(quotaMatrixOrig[j][i], invIndex); - - if (indexVector[i] != -1) - quotaVecSbr[i] += fMult(quotaMatrixOrig[j][indexVector[i]], invIndex); - } - detectorValues->avgNrg += fMult(nrgVector[j], invIndex); - } - - /* - Calculate the mean value, over the current frequency range, for the original, - the HFR and the difference. Also calculate the same mean values for the three - vectors, but only includeing the x strongest copmponents. - */ - - origQuota = FL2FXCONST_DBL(0.0f); - sbrQuota = FL2FXCONST_DBL(0.0f); - for (i = startChannel; i < stopChannel; i++) { - origQuota += fMultDiv2(quotaVecOrig[i], invChannel); - sbrQuota += fMultDiv2(quotaVecSbr[i], invChannel); - } - - /* - Calculate the mean value for the x strongest components - */ - FDKsbrEnc_Shellsort_fract(quotaVecOrig + startChannel, - stopChannel - startChannel); - FDKsbrEnc_Shellsort_fract(quotaVecSbr + startChannel, - stopChannel - startChannel); - - origQuotaMeanStrongest = FL2FXCONST_DBL(0.0f); - sbrQuotaMeanStrongest = FL2FXCONST_DBL(0.0f); - - temp = min(stopChannel - startChannel, numberOfStrongest); - invTemp = GetInvInt(temp); - - for (i = 0; i < temp; i++) { - origQuotaMeanStrongest += - fMultDiv2(quotaVecOrig[i + stopChannel - temp], invTemp); - sbrQuotaMeanStrongest += - fMultDiv2(quotaVecSbr[i + stopChannel - temp], invTemp); - } - - /* - The value for the strongest component - */ - detectorValues->origQuotaMax = quotaVecOrig[stopChannel - 1]; - detectorValues->sbrQuotaMax = quotaVecSbr[stopChannel - 1]; - - /* - Buffer values - */ - FDKmemmove(detectorValues->origQuotaMean, detectorValues->origQuotaMean + 1, - INVF_SMOOTHING_LENGTH * sizeof(FIXP_DBL)); - FDKmemmove(detectorValues->sbrQuotaMean, detectorValues->sbrQuotaMean + 1, - INVF_SMOOTHING_LENGTH * sizeof(FIXP_DBL)); - FDKmemmove(detectorValues->origQuotaMeanStrongest, - detectorValues->origQuotaMeanStrongest + 1, - INVF_SMOOTHING_LENGTH * sizeof(FIXP_DBL)); - FDKmemmove(detectorValues->sbrQuotaMeanStrongest, - detectorValues->sbrQuotaMeanStrongest + 1, - INVF_SMOOTHING_LENGTH * sizeof(FIXP_DBL)); - - detectorValues->origQuotaMean[INVF_SMOOTHING_LENGTH] = origQuota << 1; - detectorValues->sbrQuotaMean[INVF_SMOOTHING_LENGTH] = sbrQuota << 1; - detectorValues->origQuotaMeanStrongest[INVF_SMOOTHING_LENGTH] = - origQuotaMeanStrongest << 1; - detectorValues->sbrQuotaMeanStrongest[INVF_SMOOTHING_LENGTH] = - sbrQuotaMeanStrongest << 1; - - /* - Filter values - */ - detectorValues->origQuotaMeanFilt = FL2FXCONST_DBL(0.0f); - detectorValues->sbrQuotaMeanFilt = FL2FXCONST_DBL(0.0f); - detectorValues->origQuotaMeanStrongestFilt = FL2FXCONST_DBL(0.0f); - detectorValues->sbrQuotaMeanStrongestFilt = FL2FXCONST_DBL(0.0f); - - for (i = 0; i < INVF_SMOOTHING_LENGTH + 1; i++) { - detectorValues->origQuotaMeanFilt += - fMult(detectorValues->origQuotaMean[i], filter[i]); - detectorValues->sbrQuotaMeanFilt += - fMult(detectorValues->sbrQuotaMean[i], filter[i]); - detectorValues->origQuotaMeanStrongestFilt += - fMult(detectorValues->origQuotaMeanStrongest[i], filter[i]); - detectorValues->sbrQuotaMeanStrongestFilt += - fMult(detectorValues->sbrQuotaMeanStrongest[i], filter[i]); - } -} - -/**************************************************************************/ -/*! - \brief Returns the region in which the input value belongs. - - - - \return region. - -*/ -/**************************************************************************/ -static INT findRegion( - FIXP_DBL currVal, /*!< The current value. */ - const FIXP_DBL *borders, /*!< The border of the regions. */ - const INT numBorders /*!< The number of borders. */ -) { - INT i; - - if (currVal < borders[0]) { - return 0; - } - - for (i = 1; i < numBorders; i++) { - if (currVal >= borders[i - 1] && currVal < borders[i]) { - return i; - } - } - - if (currVal >= borders[numBorders - 1]) { - return numBorders; - } - - return 0; /* We never get here, it's just to avoid compiler warnings.*/ -} - -/**************************************************************************/ -/*! - \brief Makes a clever decision based on the quota vector. - - - \return decision on which invf mode to use - -*/ -/**************************************************************************/ -static INVF_MODE decisionAlgorithm( - const DETECTOR_PARAMETERS - *detectorParams, /*!< Struct with the detector parameters. */ - DETECTOR_VALUES *detectorValues, /*!< Struct with the detector values. */ - INT transientFlag, /*!< Flag indicating if there is a transient present.*/ - INT *prevRegionSbr, /*!< The previous region in which the Sbr value was. */ - INT *prevRegionOrig /*!< The previous region in which the Orig value was. */ -) { - INT invFiltLevel, regionSbr, regionOrig, regionNrg; - - /* - Current thresholds. - */ - const INT numRegionsSbr = detectorParams->numRegionsSbr; - const INT numRegionsOrig = detectorParams->numRegionsOrig; - const INT numRegionsNrg = detectorParams->numRegionsNrg; - - FIXP_DBL quantStepsSbrTmp[MAX_NUM_REGIONS]; - FIXP_DBL quantStepsOrigTmp[MAX_NUM_REGIONS]; - - /* - Current detector values. - */ - FIXP_DBL origQuotaMeanFilt; - FIXP_DBL sbrQuotaMeanFilt; - FIXP_DBL nrg; - - /* 0.375 = 3.0 / 8.0; 0.31143075889 = log2(RELAXATION)/64.0; 0.625 = - * log(16)/64.0; 0.6875 = 44/64.0 */ - origQuotaMeanFilt = - (fMultDiv2(FL2FXCONST_DBL(2.f * 0.375f), - (FIXP_DBL)(CalcLdData(max(detectorValues->origQuotaMeanFilt, - (FIXP_DBL)1)) + - FL2FXCONST_DBL(0.31143075889f)))) - << 0; /* scaled by 1/2^9 */ - sbrQuotaMeanFilt = - (fMultDiv2(FL2FXCONST_DBL(2.f * 0.375f), - (FIXP_DBL)(CalcLdData(max(detectorValues->sbrQuotaMeanFilt, - (FIXP_DBL)1)) + - FL2FXCONST_DBL(0.31143075889f)))) - << 0; /* scaled by 1/2^9 */ - /* If energy is zero then we will get different results for different word - * lengths. */ - nrg = - (fMultDiv2(FL2FXCONST_DBL(2.f * 0.375f), - (FIXP_DBL)(CalcLdData(detectorValues->avgNrg + (FIXP_DBL)1) + - FL2FXCONST_DBL(0.0625f) + FL2FXCONST_DBL(0.6875f)))) - << 0; /* scaled by 1/2^8; 2^44 -> qmf energy scale */ - - FDKmemcpy(quantStepsSbrTmp, detectorParams->quantStepsSbr, - numRegionsSbr * sizeof(FIXP_DBL)); - FDKmemcpy(quantStepsOrigTmp, detectorParams->quantStepsOrig, - numRegionsOrig * sizeof(FIXP_DBL)); - - if (*prevRegionSbr < numRegionsSbr) - quantStepsSbrTmp[*prevRegionSbr] = - detectorParams->quantStepsSbr[*prevRegionSbr] + hysteresis; - if (*prevRegionSbr > 0) - quantStepsSbrTmp[*prevRegionSbr - 1] = - detectorParams->quantStepsSbr[*prevRegionSbr - 1] - hysteresis; - - if (*prevRegionOrig < numRegionsOrig) - quantStepsOrigTmp[*prevRegionOrig] = - detectorParams->quantStepsOrig[*prevRegionOrig] + hysteresis; - if (*prevRegionOrig > 0) - quantStepsOrigTmp[*prevRegionOrig - 1] = - detectorParams->quantStepsOrig[*prevRegionOrig - 1] - hysteresis; - - regionSbr = findRegion(sbrQuotaMeanFilt, quantStepsSbrTmp, numRegionsSbr); - regionOrig = findRegion(origQuotaMeanFilt, quantStepsOrigTmp, numRegionsOrig); - regionNrg = findRegion(nrg, detectorParams->nrgBorders, numRegionsNrg); - - *prevRegionSbr = regionSbr; - *prevRegionOrig = regionOrig; - - /* Use different settings if a transient is present*/ - invFiltLevel = - (transientFlag == 1) - ? detectorParams->regionSpaceTransient[regionSbr][regionOrig] - : detectorParams->regionSpace[regionSbr][regionOrig]; - - /* Compensate for low energy.*/ - invFiltLevel = - max(invFiltLevel + detectorParams->EnergyCompFactor[regionNrg], 0); - - return (INVF_MODE)(invFiltLevel); -} - -/**************************************************************************/ -/*! - \brief Estiamtion of the inverse filtering level required - in the decoder. - - A second order LPC is calculated for every filterbank channel, using - the covariance method. THe ratio between the energy of the predicted - signal and the energy of the non-predictable signal is calcualted. - - \return none. - -*/ -/**************************************************************************/ -void FDKsbrEnc_qmfInverseFilteringDetector( - HANDLE_SBR_INV_FILT_EST - hInvFilt, /*!< Handle to the SBR_INV_FILT_EST struct. */ - FIXP_DBL **quotaMatrix, /*!< The matrix holding the tonality values of the - original. */ - FIXP_DBL *nrgVector, /*!< The energy vector. */ - SCHAR *indexVector, /*!< Index vector to obtain the patched data. */ - INT startIndex, /*!< Start index. */ - INT stopIndex, /*!< Stop index. */ - INT transientFlag, /*!< Flag indicating if a transient is present or not.*/ - INVF_MODE *infVec /*!< Vector holding the inverse filtering levels. */ -) { - INT band; - - /* - * Do the inverse filtering level estimation. - *****************************************************/ - for (band = 0; band < hInvFilt->noDetectorBands; band++) { - INT startChannel = hInvFilt->freqBandTableInvFilt[band]; - INT stopChannel = hInvFilt->freqBandTableInvFilt[band + 1]; - - calculateDetectorValues(quotaMatrix, indexVector, nrgVector, - &hInvFilt->detectorValues[band], startChannel, - stopChannel, startIndex, stopIndex, - hInvFilt->numberOfStrongest); - - infVec[band] = decisionAlgorithm( - hInvFilt->detectorParams, &hInvFilt->detectorValues[band], - transientFlag, &hInvFilt->prevRegionSbr[band], - &hInvFilt->prevRegionOrig[band]); - } -} - -/**************************************************************************/ -/*! - \brief Initialize an instance of the inverse filtering level estimator. - - - \return errorCode, noError if successful. - -*/ -/**************************************************************************/ -INT FDKsbrEnc_initInvFiltDetector( - HANDLE_SBR_INV_FILT_EST - hInvFilt, /*!< Pointer to a handle to the SBR_INV_FILT_EST struct. */ - INT *freqBandTableDetector, /*!< Frequency band table for the inverse - filtering. */ - INT numDetectorBands, /*!< Number of inverse filtering bands. */ - UINT - useSpeechConfig /*!< Flag: adapt tuning parameters according to speech*/ -) { - INT i; - - FDKmemclear(hInvFilt, sizeof(SBR_INV_FILT_EST)); - - hInvFilt->detectorParams = - (useSpeechConfig) ? &detectorParamsAACSpeech : &detectorParamsAAC; - - hInvFilt->noDetectorBandsMax = numDetectorBands; - - /* - Memory initialisation - */ - for (i = 0; i < hInvFilt->noDetectorBandsMax; i++) { - FDKmemclear(&hInvFilt->detectorValues[i], sizeof(DETECTOR_VALUES)); - hInvFilt->prevInvfMode[i] = INVF_OFF; - hInvFilt->prevRegionOrig[i] = 0; - hInvFilt->prevRegionSbr[i] = 0; - } - - /* - Reset the inverse fltering detector. - */ - FDKsbrEnc_resetInvFiltDetector(hInvFilt, freqBandTableDetector, - hInvFilt->noDetectorBandsMax); - - return (0); -} - -/**************************************************************************/ -/*! - \brief resets sbr inverse filtering structure. - - - - \return errorCode, noError if successful. - -*/ -/**************************************************************************/ -INT FDKsbrEnc_resetInvFiltDetector( - HANDLE_SBR_INV_FILT_EST - hInvFilt, /*!< Handle to the SBR_INV_FILT_EST struct. */ - INT *freqBandTableDetector, /*!< Frequency band table for the inverse - filtering. */ - INT numDetectorBands) /*!< Number of inverse filtering bands. */ -{ - hInvFilt->numberOfStrongest = 1; - FDKmemcpy(hInvFilt->freqBandTableInvFilt, freqBandTableDetector, - (numDetectorBands + 1) * sizeof(INT)); - hInvFilt->noDetectorBands = numDetectorBands; - - return (0); -} --- a/libSBRenc/src/invf_est.h +++ /dev/null @@ -1,181 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Inverse Filtering detection prototypes $Revision: 92790 $ -*/ -#ifndef INVF_EST_H -#define INVF_EST_H - -#include "sbr_encoder.h" -#include "sbr_def.h" - -#define INVF_SMOOTHING_LENGTH 2 - -typedef struct { - const FIXP_DBL *quantStepsSbr; - const FIXP_DBL *quantStepsOrig; - const FIXP_DBL *nrgBorders; - INT numRegionsSbr; - INT numRegionsOrig; - INT numRegionsNrg; - INVF_MODE regionSpace[5][5]; - INVF_MODE regionSpaceTransient[5][5]; - INT EnergyCompFactor[5]; - -} DETECTOR_PARAMETERS; - -typedef struct { - FIXP_DBL origQuotaMean[INVF_SMOOTHING_LENGTH + 1]; - FIXP_DBL sbrQuotaMean[INVF_SMOOTHING_LENGTH + 1]; - FIXP_DBL origQuotaMeanStrongest[INVF_SMOOTHING_LENGTH + 1]; - FIXP_DBL sbrQuotaMeanStrongest[INVF_SMOOTHING_LENGTH + 1]; - - FIXP_DBL origQuotaMeanFilt; - FIXP_DBL sbrQuotaMeanFilt; - FIXP_DBL origQuotaMeanStrongestFilt; - FIXP_DBL sbrQuotaMeanStrongestFilt; - - FIXP_DBL origQuotaMax; - FIXP_DBL sbrQuotaMax; - - FIXP_DBL avgNrg; -} DETECTOR_VALUES; - -typedef struct { - INT numberOfStrongest; - - INT prevRegionSbr[MAX_NUM_NOISE_VALUES]; - INT prevRegionOrig[MAX_NUM_NOISE_VALUES]; - - INT freqBandTableInvFilt[MAX_NUM_NOISE_VALUES]; - INT noDetectorBands; - INT noDetectorBandsMax; - - const DETECTOR_PARAMETERS *detectorParams; - - INVF_MODE prevInvfMode[MAX_NUM_NOISE_VALUES]; - DETECTOR_VALUES detectorValues[MAX_NUM_NOISE_VALUES]; - - FIXP_DBL nrgAvg; - FIXP_DBL wmQmf[MAX_NUM_NOISE_VALUES]; -} SBR_INV_FILT_EST; - -typedef SBR_INV_FILT_EST *HANDLE_SBR_INV_FILT_EST; - -void FDKsbrEnc_qmfInverseFilteringDetector(HANDLE_SBR_INV_FILT_EST hInvFilt, - FIXP_DBL **quotaMatrix, - FIXP_DBL *nrgVector, - SCHAR *indexVector, INT startIndex, - INT stopIndex, INT transientFlag, - INVF_MODE *infVec); - -INT FDKsbrEnc_initInvFiltDetector(HANDLE_SBR_INV_FILT_EST hInvFilt, - INT *freqBandTableDetector, - INT numDetectorBands, UINT useSpeechConfig); - -INT FDKsbrEnc_resetInvFiltDetector(HANDLE_SBR_INV_FILT_EST hInvFilt, - INT *freqBandTableDetector, - INT numDetectorBands); - -#endif /* _QMF_INV_FILT_H */ --- a/libSBRenc/src/mh_det.cpp +++ /dev/null @@ -1,1396 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -#include "mh_det.h" - -#include "sbrenc_ram.h" -#include "sbr_misc.h" - -#include "genericStds.h" - -#define SFM_SHIFT 2 /* Attention: SFM_SCALE depends on SFM_SHIFT */ -#define SFM_SCALE (MAXVAL_DBL >> SFM_SHIFT) /* 1.0 >> SFM_SHIFT */ - -/*!< Detector Parameters for AAC core codec. */ -static const DETECTOR_PARAMETERS_MH paramsAac = { - 9, /*!< deltaTime */ - { - FL2FXCONST_DBL(20.0f * RELAXATION_FLOAT), /*!< thresHoldDiff */ - FL2FXCONST_DBL(1.26f * RELAXATION_FLOAT), /*!< thresHoldDiffGuide */ - FL2FXCONST_DBL(15.0f * RELAXATION_FLOAT), /*!< thresHoldTone */ - FL2FXCONST_DBL((1.0f / 15.0f) * - RELAXATION_FLOAT), /*!< invThresHoldTone */ - FL2FXCONST_DBL(1.26f * RELAXATION_FLOAT), /*!< thresHoldToneGuide */ - FL2FXCONST_DBL(0.3f) >> SFM_SHIFT, /*!< sfmThresSbr */ - FL2FXCONST_DBL(0.1f) >> SFM_SHIFT, /*!< sfmThresOrig */ - FL2FXCONST_DBL(0.3f), /*!< decayGuideOrig */ - FL2FXCONST_DBL(0.5f), /*!< decayGuideDiff */ - FL2FXCONST_DBL(-0.000112993269), - /* LD64(FL2FXCONST_DBL(0.995f)) */ /*!< derivThresMaxLD64 */ - FL2FXCONST_DBL(-0.000112993269), - /* LD64(FL2FXCONST_DBL(0.995f)) */ /*!< derivThresBelowLD64 */ - FL2FXCONST_DBL( - -0.005030126483f) /* LD64(FL2FXCONST_DBL(0.8f)) */ /*!< - derivThresAboveLD64 - */ - }, - 50 /*!< maxComp */ -}; - -/*!< Detector Parameters for AAC LD core codec. */ -static const DETECTOR_PARAMETERS_MH paramsAacLd = { - 16, /*!< Delta time. */ - { - FL2FXCONST_DBL(25.0f * RELAXATION_FLOAT), /*!< thresHoldDiff */ - FL2FXCONST_DBL(1.26f * RELAXATION_FLOAT), /*!< tresHoldDiffGuide */ - FL2FXCONST_DBL(15.0f * RELAXATION_FLOAT), /*!< thresHoldTone */ - FL2FXCONST_DBL((1.0f / 15.0f) * - RELAXATION_FLOAT), /*!< invThresHoldTone */ - FL2FXCONST_DBL(1.26f * RELAXATION_FLOAT), /*!< thresHoldToneGuide */ - FL2FXCONST_DBL(0.3f) >> SFM_SHIFT, /*!< sfmThresSbr */ - FL2FXCONST_DBL(0.1f) >> SFM_SHIFT, /*!< sfmThresOrig */ - FL2FXCONST_DBL(0.3f), /*!< decayGuideOrig */ - FL2FXCONST_DBL(0.2f), /*!< decayGuideDiff */ - FL2FXCONST_DBL(-0.000112993269), - /* LD64(FL2FXCONST_DBL(0.995f)) */ /*!< derivThresMaxLD64 */ - FL2FXCONST_DBL(-0.000112993269), - /* LD64(FL2FXCONST_DBL(0.995f)) */ /*!< derivThresBelowLD64 */ - FL2FXCONST_DBL( - -0.005030126483f) /* LD64(FL2FXCONST_DBL(0.8f)) */ /*!< - derivThresAboveLD64 - */ - }, - 50 /*!< maxComp */ -}; - -/**************************************************************************/ -/*! - \brief Calculates the difference in tonality between original and SBR - for a given time and frequency region. - - The values for pDiffMapped2Scfb are scaled by RELAXATION - - \return none. - -*/ -/**************************************************************************/ -static void diff(FIXP_DBL *RESTRICT pTonalityOrig, FIXP_DBL *pDiffMapped2Scfb, - const UCHAR *RESTRICT pFreqBandTable, INT nScfb, - SCHAR *indexVector) { - UCHAR i, ll, lu, k; - FIXP_DBL maxValOrig, maxValSbr, tmp; - INT scale; - - for (i = 0; i < nScfb; i++) { - ll = pFreqBandTable[i]; - lu = pFreqBandTable[i + 1]; - - maxValOrig = FL2FXCONST_DBL(0.0f); - maxValSbr = FL2FXCONST_DBL(0.0f); - - for (k = ll; k < lu; k++) { - maxValOrig = fixMax(maxValOrig, pTonalityOrig[k]); - maxValSbr = fixMax(maxValSbr, pTonalityOrig[indexVector[k]]); - } - - if ((maxValSbr >= RELAXATION)) { - tmp = fDivNorm(maxValOrig, maxValSbr, &scale); - pDiffMapped2Scfb[i] = - scaleValue(fMult(tmp, RELAXATION_FRACT), - fixMax(-(DFRACT_BITS - 1), (scale - RELAXATION_SHIFT))); - } else { - pDiffMapped2Scfb[i] = maxValOrig; - } - } -} - -/**************************************************************************/ -/*! - \brief Calculates a flatness measure of the tonality measures. - - Calculation of the power function and using scalefactor for basis: - Using log2: - z = (2^k * x)^y; - z' = CalcLd(z) = y*CalcLd(x) + y*k; - z = CalcInvLd(z'); - - Using ld64: - z = (2^k * x)^y; - z' = CalcLd64(z) = y*CalcLd64(x)/64 + y*k/64; - z = CalcInvLd64(z'); - - The values pSfmOrigVec and pSfmSbrVec are scaled by the factor 1/4.0 - - \return none. - -*/ -/**************************************************************************/ -static void calculateFlatnessMeasure(FIXP_DBL *pQuotaBuffer, SCHAR *indexVector, - FIXP_DBL *pSfmOrigVec, - FIXP_DBL *pSfmSbrVec, - const UCHAR *pFreqBandTable, INT nSfb) { - INT i, j; - FIXP_DBL invBands, tmp1, tmp2; - INT shiftFac0, shiftFacSum0; - INT shiftFac1, shiftFacSum1; - FIXP_DBL accu; - - for (i = 0; i < nSfb; i++) { - INT ll = pFreqBandTable[i]; - INT lu = pFreqBandTable[i + 1]; - pSfmOrigVec[i] = (FIXP_DBL)(MAXVAL_DBL >> 2); - pSfmSbrVec[i] = (FIXP_DBL)(MAXVAL_DBL >> 2); - - if (lu - ll > 1) { - FIXP_DBL amOrig, amTransp, gmOrig, gmTransp, sfmOrig, sfmTransp; - invBands = GetInvInt(lu - ll); - shiftFacSum0 = 0; - shiftFacSum1 = 0; - amOrig = amTransp = FL2FXCONST_DBL(0.0f); - gmOrig = gmTransp = (FIXP_DBL)MAXVAL_DBL; - - for (j = ll; j < lu; j++) { - sfmOrig = pQuotaBuffer[j]; - sfmTransp = pQuotaBuffer[indexVector[j]]; - - amOrig += fMult(sfmOrig, invBands); - amTransp += fMult(sfmTransp, invBands); - - shiftFac0 = CountLeadingBits(sfmOrig); - shiftFac1 = CountLeadingBits(sfmTransp); - - gmOrig = fMult(gmOrig, sfmOrig << shiftFac0); - gmTransp = fMult(gmTransp, sfmTransp << shiftFac1); - - shiftFacSum0 += shiftFac0; - shiftFacSum1 += shiftFac1; - } - - if (gmOrig > FL2FXCONST_DBL(0.0f)) { - tmp1 = CalcLdData(gmOrig); /* CalcLd64(x)/64 */ - tmp1 = fMult(invBands, tmp1); /* y*CalcLd64(x)/64 */ - - /* y*k/64 */ - accu = (FIXP_DBL)-shiftFacSum0 << (DFRACT_BITS - 1 - 8); - tmp2 = fMultDiv2(invBands, accu) << (2 + 1); - - tmp2 = tmp1 + tmp2; /* y*CalcLd64(x)/64 + y*k/64 */ - gmOrig = CalcInvLdData(tmp2); /* CalcInvLd64(z'); */ - } else { - gmOrig = FL2FXCONST_DBL(0.0f); - } - - if (gmTransp > FL2FXCONST_DBL(0.0f)) { - tmp1 = CalcLdData(gmTransp); /* CalcLd64(x)/64 */ - tmp1 = fMult(invBands, tmp1); /* y*CalcLd64(x)/64 */ - - /* y*k/64 */ - accu = (FIXP_DBL)-shiftFacSum1 << (DFRACT_BITS - 1 - 8); - tmp2 = fMultDiv2(invBands, accu) << (2 + 1); - - tmp2 = tmp1 + tmp2; /* y*CalcLd64(x)/64 + y*k/64 */ - gmTransp = CalcInvLdData(tmp2); /* CalcInvLd64(z'); */ - } else { - gmTransp = FL2FXCONST_DBL(0.0f); - } - if (amOrig != FL2FXCONST_DBL(0.0f)) - pSfmOrigVec[i] = - FDKsbrEnc_LSI_divide_scale_fract(gmOrig, amOrig, SFM_SCALE); - - if (amTransp != FL2FXCONST_DBL(0.0f)) - pSfmSbrVec[i] = - FDKsbrEnc_LSI_divide_scale_fract(gmTransp, amTransp, SFM_SCALE); - } - } -} - -/**************************************************************************/ -/*! - \brief Calculates the input to the missing harmonics detection. - - - \return none. - -*/ -/**************************************************************************/ -static void calculateDetectorInput( - FIXP_DBL **RESTRICT pQuotaBuffer, /*!< Pointer to tonality matrix. */ - SCHAR *RESTRICT indexVector, FIXP_DBL **RESTRICT tonalityDiff, - FIXP_DBL **RESTRICT pSfmOrig, FIXP_DBL **RESTRICT pSfmSbr, - const UCHAR *freqBandTable, INT nSfb, INT noEstPerFrame, INT move) { - INT est; - - /* - New estimate. - */ - for (est = 0; est < noEstPerFrame; est++) { - diff(pQuotaBuffer[est + move], tonalityDiff[est + move], freqBandTable, - nSfb, indexVector); - - calculateFlatnessMeasure(pQuotaBuffer[est + move], indexVector, - pSfmOrig[est + move], pSfmSbr[est + move], - freqBandTable, nSfb); - } -} - -/**************************************************************************/ -/*! - \brief Checks that the detection is not due to a LP filter - - This function determines if a newly detected missing harmonics is not - in fact just a low-pass filtere input signal. If so, the detection is - removed. - - \return none. - -*/ -/**************************************************************************/ -static void removeLowPassDetection(UCHAR *RESTRICT pAddHarmSfb, - UCHAR **RESTRICT pDetectionVectors, - INT start, INT stop, INT nSfb, - const UCHAR *RESTRICT pFreqBandTable, - FIXP_DBL *RESTRICT pNrgVector, - THRES_HOLDS mhThresh) - -{ - INT i, est; - INT maxDerivPos = pFreqBandTable[nSfb]; - INT numBands = pFreqBandTable[nSfb]; - FIXP_DBL nrgLow, nrgHigh; - FIXP_DBL nrgLD64, nrgLowLD64, nrgHighLD64, nrgDiffLD64; - FIXP_DBL valLD64, maxValLD64, maxValAboveLD64; - INT bLPsignal = 0; - - maxValLD64 = FL2FXCONST_DBL(-1.0f); - for (i = numBands - 1 - 2; i > pFreqBandTable[0]; i--) { - nrgLow = pNrgVector[i]; - nrgHigh = pNrgVector[i + 2]; - - if (nrgLow != FL2FXCONST_DBL(0.0f) && nrgLow > nrgHigh) { - nrgLowLD64 = CalcLdData(nrgLow >> 1); - nrgDiffLD64 = CalcLdData((nrgLow >> 1) - (nrgHigh >> 1)); - valLD64 = nrgDiffLD64 - nrgLowLD64; - if (valLD64 > maxValLD64) { - maxDerivPos = i; - maxValLD64 = valLD64; - } - if (maxValLD64 > mhThresh.derivThresMaxLD64) { - break; - } - } - } - - /* Find the largest "gradient" above. (should be relatively flat, hence we - expect a low value if the signal is LP.*/ - maxValAboveLD64 = FL2FXCONST_DBL(-1.0f); - for (i = numBands - 1 - 2; i > maxDerivPos + 2; i--) { - nrgLow = pNrgVector[i]; - nrgHigh = pNrgVector[i + 2]; - - if (nrgLow != FL2FXCONST_DBL(0.0f) && nrgLow > nrgHigh) { - nrgLowLD64 = CalcLdData(nrgLow >> 1); - nrgDiffLD64 = CalcLdData((nrgLow >> 1) - (nrgHigh >> 1)); - valLD64 = nrgDiffLD64 - nrgLowLD64; - if (valLD64 > maxValAboveLD64) { - maxValAboveLD64 = valLD64; - } - } else { - if (nrgHigh != FL2FXCONST_DBL(0.0f) && nrgHigh > nrgLow) { - nrgHighLD64 = CalcLdData(nrgHigh >> 1); - nrgDiffLD64 = CalcLdData((nrgHigh >> 1) - (nrgLow >> 1)); - valLD64 = nrgDiffLD64 - nrgHighLD64; - if (valLD64 > maxValAboveLD64) { - maxValAboveLD64 = valLD64; - } - } - } - } - - if (maxValLD64 > mhThresh.derivThresMaxLD64 && - maxValAboveLD64 < mhThresh.derivThresAboveLD64) { - bLPsignal = 1; - - for (i = maxDerivPos - 1; i > maxDerivPos - 5 && i >= 0; i--) { - if (pNrgVector[i] != FL2FXCONST_DBL(0.0f) && - pNrgVector[i] > pNrgVector[maxDerivPos + 2]) { - nrgDiffLD64 = CalcLdData((pNrgVector[i] >> 1) - - (pNrgVector[maxDerivPos + 2] >> 1)); - nrgLD64 = CalcLdData(pNrgVector[i] >> 1); - valLD64 = nrgDiffLD64 - nrgLD64; - if (valLD64 < mhThresh.derivThresBelowLD64) { - bLPsignal = 0; - break; - } - } else { - bLPsignal = 0; - break; - } - } - } - - if (bLPsignal) { - for (i = 0; i < nSfb; i++) { - if (maxDerivPos >= pFreqBandTable[i] && - maxDerivPos < pFreqBandTable[i + 1]) - break; - } - - if (pAddHarmSfb[i]) { - pAddHarmSfb[i] = 0; - for (est = start; est < stop; est++) { - pDetectionVectors[est][i] = 0; - } - } - } -} - -/**************************************************************************/ -/*! - \brief Checks if it is allowed to detect a missing tone, that wasn't - detected previously. - - - \return newDetectionAllowed flag. - -*/ -/**************************************************************************/ -static INT isDetectionOfNewToneAllowed( - const SBR_FRAME_INFO *pFrameInfo, INT *pDetectionStartPos, - INT noEstPerFrame, INT prevTransientFrame, INT prevTransientPos, - INT prevTransientFlag, INT transientPosOffset, INT transientFlag, - INT transientPos, INT deltaTime, - HANDLE_SBR_MISSING_HARMONICS_DETECTOR h_sbrMissingHarmonicsDetector) { - INT transientFrame, newDetectionAllowed; - - /* Determine if this is a frame where a transient starts... - * If the transient flag was set the previous frame but not the - * transient frame flag, the transient frame flag is set in the current frame. - *****************************************************************************/ - transientFrame = 0; - if (transientFlag) { - if (transientPos + transientPosOffset < - pFrameInfo->borders[pFrameInfo->nEnvelopes]) { - transientFrame = 1; - if (noEstPerFrame > 1) { - if (transientPos + transientPosOffset > - h_sbrMissingHarmonicsDetector->timeSlots >> 1) { - *pDetectionStartPos = noEstPerFrame; - } else { - *pDetectionStartPos = noEstPerFrame >> 1; - } - - } else { - *pDetectionStartPos = noEstPerFrame; - } - } - } else { - if (prevTransientFlag && !prevTransientFrame) { - transientFrame = 1; - *pDetectionStartPos = 0; - } - } - - /* - * Determine if detection of new missing harmonics are allowed. - * If the frame contains a transient it's ok. If the previous - * frame contained a transient it needs to be sufficiently close - * to the start of the current frame. - ****************************************************************/ - newDetectionAllowed = 0; - if (transientFrame) { - newDetectionAllowed = 1; - } else { - if (prevTransientFrame && - fixp_abs(pFrameInfo->borders[0] - - (prevTransientPos + transientPosOffset - - h_sbrMissingHarmonicsDetector->timeSlots)) < deltaTime) { - newDetectionAllowed = 1; - *pDetectionStartPos = 0; - } - } - - h_sbrMissingHarmonicsDetector->previousTransientFlag = transientFlag; - h_sbrMissingHarmonicsDetector->previousTransientFrame = transientFrame; - h_sbrMissingHarmonicsDetector->previousTransientPos = transientPos; - - return (newDetectionAllowed); -} - -/**************************************************************************/ -/*! - \brief Cleans up the detection after a transient. - - - \return none. - -*/ -/**************************************************************************/ -static void transientCleanUp(FIXP_DBL **quotaBuffer, INT nSfb, - UCHAR **detectionVectors, UCHAR *pAddHarmSfb, - UCHAR *pPrevAddHarmSfb, INT **signBuffer, - const UCHAR *pFreqBandTable, INT start, INT stop, - INT newDetectionAllowed, FIXP_DBL *pNrgVector, - THRES_HOLDS mhThresh) { - INT i, j, est; - - for (est = start; est < stop; est++) { - for (i = 0; i < nSfb; i++) { - pAddHarmSfb[i] = pAddHarmSfb[i] || detectionVectors[est][i]; - } - } - - if (newDetectionAllowed == 1) { - /* - * Check for duplication of sines located - * on the border of two scf-bands. - *************************************************/ - for (i = 0; i < nSfb - 1; i++) { - /* detection in adjacent channels.*/ - if (pAddHarmSfb[i] && pAddHarmSfb[i + 1]) { - FIXP_DBL maxVal1, maxVal2; - INT maxPos1, maxPos2, maxPosTime1, maxPosTime2; - - INT li = pFreqBandTable[i]; - INT ui = pFreqBandTable[i + 1]; - - /* Find maximum tonality in the the two scf bands.*/ - maxPosTime1 = start; - maxPos1 = li; - maxVal1 = quotaBuffer[start][li]; - for (est = start; est < stop; est++) { - for (j = li; j < ui; j++) { - if (quotaBuffer[est][j] > maxVal1) { - maxVal1 = quotaBuffer[est][j]; - maxPos1 = j; - maxPosTime1 = est; - } - } - } - - li = pFreqBandTable[i + 1]; - ui = pFreqBandTable[i + 2]; - - /* Find maximum tonality in the the two scf bands.*/ - maxPosTime2 = start; - maxPos2 = li; - maxVal2 = quotaBuffer[start][li]; - for (est = start; est < stop; est++) { - for (j = li; j < ui; j++) { - if (quotaBuffer[est][j] > maxVal2) { - maxVal2 = quotaBuffer[est][j]; - maxPos2 = j; - maxPosTime2 = est; - } - } - } - - /* If the maximum values are in adjacent QMF-channels, we need to remove - the lowest of the two.*/ - if (maxPos2 - maxPos1 < 2) { - if (pPrevAddHarmSfb[i] == 1 && pPrevAddHarmSfb[i + 1] == 0) { - /* Keep the lower, remove the upper.*/ - pAddHarmSfb[i + 1] = 0; - for (est = start; est < stop; est++) { - detectionVectors[est][i + 1] = 0; - } - } else { - if (pPrevAddHarmSfb[i] == 0 && pPrevAddHarmSfb[i + 1] == 1) { - /* Keep the upper, remove the lower.*/ - pAddHarmSfb[i] = 0; - for (est = start; est < stop; est++) { - detectionVectors[est][i] = 0; - } - } else { - /* If the maximum values are in adjacent QMF-channels, and if the - signs indicate that it is the same sine, we need to remove the - lowest of the two.*/ - if (maxVal1 > maxVal2) { - if (signBuffer[maxPosTime1][maxPos2] < 0 && - signBuffer[maxPosTime1][maxPos1] > 0) { - /* Keep the lower, remove the upper.*/ - pAddHarmSfb[i + 1] = 0; - for (est = start; est < stop; est++) { - detectionVectors[est][i + 1] = 0; - } - } - } else { - if (signBuffer[maxPosTime2][maxPos2] < 0 && - signBuffer[maxPosTime2][maxPos1] > 0) { - /* Keep the upper, remove the lower.*/ - pAddHarmSfb[i] = 0; - for (est = start; est < stop; est++) { - detectionVectors[est][i] = 0; - } - } - } - } - } - } - } - } - - /* Make sure that the detection is not the cut-off of a low pass filter. */ - removeLowPassDetection(pAddHarmSfb, detectionVectors, start, stop, nSfb, - pFreqBandTable, pNrgVector, mhThresh); - } else { - /* - * If a missing harmonic wasn't missing the previous frame - * the transient-flag needs to be set in order to be allowed to detect it. - *************************************************************************/ - for (i = 0; i < nSfb; i++) { - if (pAddHarmSfb[i] - pPrevAddHarmSfb[i] > 0) pAddHarmSfb[i] = 0; - } - } -} - -/*****************************************************************************/ -/*! - \brief Detection for one tonality estimate. - - This is the actual missing harmonics detection, using information from the - previous detection. - - If a missing harmonic was detected (in a previous frame) due to too high - tonality differences, but there was not enough tonality difference in the - current frame, the detection algorithm still continues to trace the strongest - tone in the scalefactor band (assuming that this is the tone that is going to - be replaced in the decoder). This is done to avoid abrupt endings of sines - fading out (e.g. in the glockenspiel). - - The function also tries to estimate where one sine is going to be replaced - with multiple sines (due to the patching). This is done by comparing the - tonality flatness measure of the original and the SBR signal. - - The function also tries to estimate (for the scalefactor bands only - containing one qmf subband) when a strong tone in the original will be - replaced by a strong tone in the adjacent QMF subband. - - \return none. - -*/ -/**************************************************************************/ -static void detection(FIXP_DBL *quotaBuffer, FIXP_DBL *pDiffVecScfb, INT nSfb, - UCHAR *pHarmVec, const UCHAR *pFreqBandTable, - FIXP_DBL *sfmOrig, FIXP_DBL *sfmSbr, - GUIDE_VECTORS guideVectors, GUIDE_VECTORS newGuideVectors, - THRES_HOLDS mhThresh) { - INT i, j, ll, lu; - FIXP_DBL thresTemp, thresOrig; - - /* - * Do detection on the difference vector, i.e. the difference between - * the original and the transposed. - *********************************************************************/ - for (i = 0; i < nSfb; i++) { - thresTemp = (guideVectors.guideVectorDiff[i] != FL2FXCONST_DBL(0.0f)) - ? fMax(fMult(mhThresh.decayGuideDiff, - guideVectors.guideVectorDiff[i]), - mhThresh.thresHoldDiffGuide) - : mhThresh.thresHoldDiff; - - thresTemp = fMin(thresTemp, mhThresh.thresHoldDiff); - - if (pDiffVecScfb[i] > thresTemp) { - pHarmVec[i] = 1; - newGuideVectors.guideVectorDiff[i] = pDiffVecScfb[i]; - } else { - /* If the guide wasn't zero, but the current level is to low, - start tracking the decay on the tone in the original rather - than the difference.*/ - if (guideVectors.guideVectorDiff[i] != FL2FXCONST_DBL(0.0f)) { - guideVectors.guideVectorOrig[i] = mhThresh.thresHoldToneGuide; - } - } - } - - /* - * Trace tones in the original signal that at one point - * have been detected because they will be replaced by - * multiple tones in the sbr signal. - ****************************************************/ - - for (i = 0; i < nSfb; i++) { - ll = pFreqBandTable[i]; - lu = pFreqBandTable[i + 1]; - - thresOrig = - fixMax(fMult(guideVectors.guideVectorOrig[i], mhThresh.decayGuideOrig), - mhThresh.thresHoldToneGuide); - thresOrig = fixMin(thresOrig, mhThresh.thresHoldTone); - - if (guideVectors.guideVectorOrig[i] != FL2FXCONST_DBL(0.0f)) { - for (j = ll; j < lu; j++) { - if (quotaBuffer[j] > thresOrig) { - pHarmVec[i] = 1; - newGuideVectors.guideVectorOrig[i] = quotaBuffer[j]; - } - } - } - } - - /* - * Check for multiple sines in the transposed signal, - * where there is only one in the original. - ****************************************************/ - thresOrig = mhThresh.thresHoldTone; - - for (i = 0; i < nSfb; i++) { - ll = pFreqBandTable[i]; - lu = pFreqBandTable[i + 1]; - - if (pHarmVec[i] == 0) { - if (lu - ll > 1) { - for (j = ll; j < lu; j++) { - if (quotaBuffer[j] > thresOrig && - (sfmSbr[i] > mhThresh.sfmThresSbr && - sfmOrig[i] < mhThresh.sfmThresOrig)) { - pHarmVec[i] = 1; - newGuideVectors.guideVectorOrig[i] = quotaBuffer[j]; - } - } - } else { - if (i < nSfb - 1) { - ll = pFreqBandTable[i]; - - if (i > 0) { - if (quotaBuffer[ll] > mhThresh.thresHoldTone && - (pDiffVecScfb[i + 1] < mhThresh.invThresHoldTone || - pDiffVecScfb[i - 1] < mhThresh.invThresHoldTone)) { - pHarmVec[i] = 1; - newGuideVectors.guideVectorOrig[i] = quotaBuffer[ll]; - } - } else { - if (quotaBuffer[ll] > mhThresh.thresHoldTone && - pDiffVecScfb[i + 1] < mhThresh.invThresHoldTone) { - pHarmVec[i] = 1; - newGuideVectors.guideVectorOrig[i] = quotaBuffer[ll]; - } - } - } - } - } - } -} - -/**************************************************************************/ -/*! - \brief Do detection for every tonality estimate, using forward prediction. - - - \return none. - -*/ -/**************************************************************************/ -static void detectionWithPrediction( - FIXP_DBL **quotaBuffer, FIXP_DBL **pDiffVecScfb, INT **signBuffer, INT nSfb, - const UCHAR *pFreqBandTable, FIXP_DBL **sfmOrig, FIXP_DBL **sfmSbr, - UCHAR **detectionVectors, UCHAR *pPrevAddHarmSfb, - GUIDE_VECTORS *guideVectors, INT noEstPerFrame, INT detectionStart, - INT totNoEst, INT newDetectionAllowed, INT *pAddHarmFlag, - UCHAR *pAddHarmSfb, FIXP_DBL *pNrgVector, - const DETECTOR_PARAMETERS_MH *mhParams) { - INT est = 0, i; - INT start; - - FDKmemclear(pAddHarmSfb, nSfb * sizeof(UCHAR)); - - if (newDetectionAllowed) { - /* Since we don't want to use the transient region for detection (since the - tonality values tend to be a bit unreliable for this region) the - guide-values are copied to the current starting point. */ - if (totNoEst > 1) { - start = detectionStart + 1; - - if (start != 0) { - FDKmemcpy(guideVectors[start].guideVectorDiff, - guideVectors[0].guideVectorDiff, nSfb * sizeof(FIXP_DBL)); - FDKmemcpy(guideVectors[start].guideVectorOrig, - guideVectors[0].guideVectorOrig, nSfb * sizeof(FIXP_DBL)); - FDKmemclear(guideVectors[start - 1].guideVectorDetected, - nSfb * sizeof(UCHAR)); - } - } else { - start = 0; - } - } else { - start = 0; - } - - for (est = start; est < totNoEst; est++) { - /* - * Do detection on the current frame using - * guide-info from the previous. - *******************************************/ - if (est > 0) { - FDKmemcpy(guideVectors[est].guideVectorDetected, - detectionVectors[est - 1], nSfb * sizeof(UCHAR)); - } - - FDKmemclear(detectionVectors[est], nSfb * sizeof(UCHAR)); - - if (est < totNoEst - 1) { - FDKmemclear(guideVectors[est + 1].guideVectorDiff, - nSfb * sizeof(FIXP_DBL)); - FDKmemclear(guideVectors[est + 1].guideVectorOrig, - nSfb * sizeof(FIXP_DBL)); - FDKmemclear(guideVectors[est + 1].guideVectorDetected, - nSfb * sizeof(UCHAR)); - - detection(quotaBuffer[est], pDiffVecScfb[est], nSfb, - detectionVectors[est], pFreqBandTable, sfmOrig[est], - sfmSbr[est], guideVectors[est], guideVectors[est + 1], - mhParams->thresHolds); - } else { - FDKmemclear(guideVectors[est].guideVectorDiff, nSfb * sizeof(FIXP_DBL)); - FDKmemclear(guideVectors[est].guideVectorOrig, nSfb * sizeof(FIXP_DBL)); - FDKmemclear(guideVectors[est].guideVectorDetected, nSfb * sizeof(UCHAR)); - - detection(quotaBuffer[est], pDiffVecScfb[est], nSfb, - detectionVectors[est], pFreqBandTable, sfmOrig[est], - sfmSbr[est], guideVectors[est], guideVectors[est], - mhParams->thresHolds); - } - } - - /* Clean up the detection.*/ - transientCleanUp(quotaBuffer, nSfb, detectionVectors, pAddHarmSfb, - pPrevAddHarmSfb, signBuffer, pFreqBandTable, start, totNoEst, - newDetectionAllowed, pNrgVector, mhParams->thresHolds); - - /* Set flag... */ - *pAddHarmFlag = 0; - for (i = 0; i < nSfb; i++) { - if (pAddHarmSfb[i]) { - *pAddHarmFlag = 1; - break; - } - } - - FDKmemcpy(pPrevAddHarmSfb, pAddHarmSfb, nSfb * sizeof(UCHAR)); - FDKmemcpy(guideVectors[0].guideVectorDetected, pAddHarmSfb, - nSfb * sizeof(INT)); - - for (i = 0; i < nSfb; i++) { - guideVectors[0].guideVectorDiff[i] = FL2FXCONST_DBL(0.0f); - guideVectors[0].guideVectorOrig[i] = FL2FXCONST_DBL(0.0f); - - if (pAddHarmSfb[i] == 1) { - /* If we had a detection use the guide-value in the next frame from the - last estimate were the detection was done.*/ - for (est = start; est < totNoEst; est++) { - if (guideVectors[est].guideVectorDiff[i] != FL2FXCONST_DBL(0.0f)) { - guideVectors[0].guideVectorDiff[i] = - guideVectors[est].guideVectorDiff[i]; - } - if (guideVectors[est].guideVectorOrig[i] != FL2FXCONST_DBL(0.0f)) { - guideVectors[0].guideVectorOrig[i] = - guideVectors[est].guideVectorOrig[i]; - } - } - } - } -} - -/**************************************************************************/ -/*! - \brief Calculates a compensation vector for the energy data. - - This function calculates a compensation vector for the energy data (i.e. - envelope data) that is calculated elsewhere. This is since, one sine on - the border of two scalefactor bands, will be replace by one sine in the - middle of either scalefactor band. However, since the sine that is replaced - will influence the energy estimate in both scalefactor bands (in the envelops - calculation function) a compensation value is required in order to avoid - noise substitution in the decoder next to the synthetic sine. - - \return none. - -*/ -/**************************************************************************/ -static void calculateCompVector(UCHAR *pAddHarmSfb, FIXP_DBL **pTonalityMatrix, - INT **pSignMatrix, UCHAR *pEnvComp, INT nSfb, - const UCHAR *freqBandTable, INT totNoEst, - INT maxComp, UCHAR *pPrevEnvComp, - INT newDetectionAllowed) { - INT scfBand, est, l, ll, lu, maxPosF, maxPosT; - FIXP_DBL maxVal; - INT compValue; - FIXP_DBL tmp; - - FDKmemclear(pEnvComp, nSfb * sizeof(UCHAR)); - - for (scfBand = 0; scfBand < nSfb; scfBand++) { - if (pAddHarmSfb[scfBand]) { /* A missing sine was detected */ - ll = freqBandTable[scfBand]; - lu = freqBandTable[scfBand + 1]; - - maxPosF = 0; /* First find the maximum*/ - maxPosT = 0; - maxVal = FL2FXCONST_DBL(0.0f); - - for (est = 0; est < totNoEst; est++) { - for (l = ll; l < lu; l++) { - if (pTonalityMatrix[est][l] > maxVal) { - maxVal = pTonalityMatrix[est][l]; - maxPosF = l; - maxPosT = est; - } - } - } - - /* - * If the maximum tonality is at the lower border of the - * scalefactor band, we check the sign of the adjacent channels - * to see if this sine is shared by the lower channel. If so, the - * energy of the single sine will be present in two scalefactor bands - * in the SBR data, which will cause problems in the decoder, when we - * add a sine to just one of the channels. - *********************************************************************/ - if (maxPosF == ll && scfBand) { - if (!pAddHarmSfb[scfBand - 1]) { /* No detection below*/ - if (pSignMatrix[maxPosT][maxPosF - 1] > 0 && - pSignMatrix[maxPosT][maxPosF] < 0) { - /* The comp value is calulated as the tonallity value, i.e we want - to reduce the envelope data for this channel with as much as the - tonality that is spread from the channel above. (ld64(RELAXATION) - = 0.31143075889) */ - tmp = fixp_abs( - (FIXP_DBL)CalcLdData(pTonalityMatrix[maxPosT][maxPosF - 1]) + - RELAXATION_LD64); - tmp = (tmp >> (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1)) + - (FIXP_DBL)1; /* shift one bit less for rounding */ - compValue = ((INT)(LONG)tmp) >> 1; - - /* limit the comp-value*/ - if (compValue > maxComp) compValue = maxComp; - - pEnvComp[scfBand - 1] = compValue; - } - } - } - - /* - * Same as above, but for the upper end of the scalefactor-band. - ***************************************************************/ - if (maxPosF == lu - 1 && scfBand + 1 < nSfb) { /* Upper border*/ - if (!pAddHarmSfb[scfBand + 1]) { - if (pSignMatrix[maxPosT][maxPosF] > 0 && - pSignMatrix[maxPosT][maxPosF + 1] < 0) { - tmp = fixp_abs( - (FIXP_DBL)CalcLdData(pTonalityMatrix[maxPosT][maxPosF + 1]) + - RELAXATION_LD64); - tmp = (tmp >> (DFRACT_BITS - 1 - LD_DATA_SHIFT - 1)) + - (FIXP_DBL)1; /* shift one bit less for rounding */ - compValue = ((INT)(LONG)tmp) >> 1; - - if (compValue > maxComp) compValue = maxComp; - - pEnvComp[scfBand + 1] = compValue; - } - } - } - } - } - - if (newDetectionAllowed == 0) { - for (scfBand = 0; scfBand < nSfb; scfBand++) { - if (pEnvComp[scfBand] != 0 && pPrevEnvComp[scfBand] == 0) - pEnvComp[scfBand] = 0; - } - } - - /* remember the value for the next frame.*/ - FDKmemcpy(pPrevEnvComp, pEnvComp, nSfb * sizeof(UCHAR)); -} - -/**************************************************************************/ -/*! - \brief Detects where strong tonal components will be missing after - HFR in the decoder. - - - \return none. - -*/ -/**************************************************************************/ -void FDKsbrEnc_SbrMissingHarmonicsDetectorQmf( - HANDLE_SBR_MISSING_HARMONICS_DETECTOR h_sbrMHDet, FIXP_DBL **pQuotaBuffer, - INT **pSignBuffer, SCHAR *indexVector, const SBR_FRAME_INFO *pFrameInfo, - const UCHAR *pTranInfo, INT *pAddHarmonicsFlag, - UCHAR *pAddHarmonicsScaleFactorBands, const UCHAR *freqBandTable, INT nSfb, - UCHAR *envelopeCompensation, FIXP_DBL *pNrgVector) { - INT transientFlag = pTranInfo[1]; - INT transientPos = pTranInfo[0]; - INT newDetectionAllowed; - INT transientDetStart = 0; - - UCHAR **detectionVectors = h_sbrMHDet->detectionVectors; - INT move = h_sbrMHDet->move; - INT noEstPerFrame = h_sbrMHDet->noEstPerFrame; - INT totNoEst = h_sbrMHDet->totNoEst; - INT prevTransientFlag = h_sbrMHDet->previousTransientFlag; - INT prevTransientFrame = h_sbrMHDet->previousTransientFrame; - INT transientPosOffset = h_sbrMHDet->transientPosOffset; - INT prevTransientPos = h_sbrMHDet->previousTransientPos; - GUIDE_VECTORS *guideVectors = h_sbrMHDet->guideVectors; - INT deltaTime = h_sbrMHDet->mhParams->deltaTime; - INT maxComp = h_sbrMHDet->mhParams->maxComp; - - int est; - - /* - Buffer values. - */ - FDK_ASSERT(move <= (MAX_NO_OF_ESTIMATES >> 1)); - FDK_ASSERT(noEstPerFrame <= (MAX_NO_OF_ESTIMATES >> 1)); - - FIXP_DBL *sfmSbr[MAX_NO_OF_ESTIMATES]; - FIXP_DBL *sfmOrig[MAX_NO_OF_ESTIMATES]; - FIXP_DBL *tonalityDiff[MAX_NO_OF_ESTIMATES]; - - for (est = 0; est < MAX_NO_OF_ESTIMATES / 2; est++) { - sfmSbr[est] = h_sbrMHDet->sfmSbr[est]; - sfmOrig[est] = h_sbrMHDet->sfmOrig[est]; - tonalityDiff[est] = h_sbrMHDet->tonalityDiff[est]; - } - - C_ALLOC_SCRATCH_START(_scratch, FIXP_DBL, - 3 * MAX_NO_OF_ESTIMATES / 2 * MAX_FREQ_COEFFS) - FIXP_DBL *scratch = _scratch; - for (; est < MAX_NO_OF_ESTIMATES; est++) { - sfmSbr[est] = scratch; - scratch += MAX_FREQ_COEFFS; - sfmOrig[est] = scratch; - scratch += MAX_FREQ_COEFFS; - tonalityDiff[est] = scratch; - scratch += MAX_FREQ_COEFFS; - } - - /* Determine if we're allowed to detect "missing harmonics" that wasn't - detected before. In order to be allowed to do new detection, there must be - a transient in the current frame, or a transient in the previous frame - sufficiently close to the current frame. */ - newDetectionAllowed = isDetectionOfNewToneAllowed( - pFrameInfo, &transientDetStart, noEstPerFrame, prevTransientFrame, - prevTransientPos, prevTransientFlag, transientPosOffset, transientFlag, - transientPos, deltaTime, h_sbrMHDet); - - /* Calulate the variables that will be used subsequently for the actual - * detection */ - calculateDetectorInput(pQuotaBuffer, indexVector, tonalityDiff, sfmOrig, - sfmSbr, freqBandTable, nSfb, noEstPerFrame, move); - - /* Do the actual detection using information from previous detections */ - detectionWithPrediction(pQuotaBuffer, tonalityDiff, pSignBuffer, nSfb, - freqBandTable, sfmOrig, sfmSbr, detectionVectors, - h_sbrMHDet->guideScfb, guideVectors, noEstPerFrame, - transientDetStart, totNoEst, newDetectionAllowed, - pAddHarmonicsFlag, pAddHarmonicsScaleFactorBands, - pNrgVector, h_sbrMHDet->mhParams); - - /* Calculate the comp vector, so that the energy can be - compensated for a sine between two QMF-bands. */ - calculateCompVector(pAddHarmonicsScaleFactorBands, pQuotaBuffer, pSignBuffer, - envelopeCompensation, nSfb, freqBandTable, totNoEst, - maxComp, h_sbrMHDet->prevEnvelopeCompensation, - newDetectionAllowed); - - for (est = 0; est < move; est++) { - FDKmemcpy(tonalityDiff[est], tonalityDiff[est + noEstPerFrame], - sizeof(FIXP_DBL) * MAX_FREQ_COEFFS); - FDKmemcpy(sfmOrig[est], sfmOrig[est + noEstPerFrame], - sizeof(FIXP_DBL) * MAX_FREQ_COEFFS); - FDKmemcpy(sfmSbr[est], sfmSbr[est + noEstPerFrame], - sizeof(FIXP_DBL) * MAX_FREQ_COEFFS); - } - C_ALLOC_SCRATCH_END(_scratch, FIXP_DBL, - 3 * MAX_NO_OF_ESTIMATES / 2 * MAX_FREQ_COEFFS) -} - -/**************************************************************************/ -/*! - \brief Initialize an instance of the missing harmonics detector. - - - \return errorCode, noError if OK. - -*/ -/**************************************************************************/ -INT FDKsbrEnc_CreateSbrMissingHarmonicsDetector( - HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet, INT chan) { - HANDLE_SBR_MISSING_HARMONICS_DETECTOR hs = hSbrMHDet; - INT i; - - UCHAR *detectionVectors = GetRam_Sbr_detectionVectors(chan); - UCHAR *guideVectorDetected = GetRam_Sbr_guideVectorDetected(chan); - FIXP_DBL *guideVectorDiff = GetRam_Sbr_guideVectorDiff(chan); - FIXP_DBL *guideVectorOrig = GetRam_Sbr_guideVectorOrig(chan); - - FDKmemclear(hs, sizeof(SBR_MISSING_HARMONICS_DETECTOR)); - - hs->prevEnvelopeCompensation = GetRam_Sbr_prevEnvelopeCompensation(chan); - hs->guideScfb = GetRam_Sbr_guideScfb(chan); - - if ((NULL == detectionVectors) || (NULL == guideVectorDetected) || - (NULL == guideVectorDiff) || (NULL == guideVectorOrig) || - (NULL == hs->prevEnvelopeCompensation) || (NULL == hs->guideScfb)) { - goto bail; - } - - for (i = 0; i < MAX_NO_OF_ESTIMATES; i++) { - hs->guideVectors[i].guideVectorDiff = - guideVectorDiff + (i * MAX_FREQ_COEFFS); - hs->guideVectors[i].guideVectorOrig = - guideVectorOrig + (i * MAX_FREQ_COEFFS); - hs->detectionVectors[i] = detectionVectors + (i * MAX_FREQ_COEFFS); - hs->guideVectors[i].guideVectorDetected = - guideVectorDetected + (i * MAX_FREQ_COEFFS); - } - - return 0; - -bail: - hs->guideVectors[0].guideVectorDiff = guideVectorDiff; - hs->guideVectors[0].guideVectorOrig = guideVectorOrig; - hs->detectionVectors[0] = detectionVectors; - hs->guideVectors[0].guideVectorDetected = guideVectorDetected; - - FDKsbrEnc_DeleteSbrMissingHarmonicsDetector(hs); - return -1; -} - -/**************************************************************************/ -/*! - \brief Initialize an instance of the missing harmonics detector. - - - \return errorCode, noError if OK. - -*/ -/**************************************************************************/ -INT FDKsbrEnc_InitSbrMissingHarmonicsDetector( - HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet, INT sampleFreq, - INT frameSize, INT nSfb, INT qmfNoChannels, INT totNoEst, INT move, - INT noEstPerFrame, UINT sbrSyntaxFlags) { - HANDLE_SBR_MISSING_HARMONICS_DETECTOR hs = hSbrMHDet; - int i; - - FDK_ASSERT(totNoEst <= MAX_NO_OF_ESTIMATES); - - if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { - switch (frameSize) { - case 1024: - case 512: - hs->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; - hs->timeSlots = 16; - break; - case 960: - case 480: - hs->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; - hs->timeSlots = 15; - break; - default: - return -1; - } - } else { - switch (frameSize) { - case 2048: - case 1024: - hs->transientPosOffset = FRAME_MIDDLE_SLOT_2048; - hs->timeSlots = NUMBER_TIME_SLOTS_2048; - break; - case 1920: - case 960: - hs->transientPosOffset = FRAME_MIDDLE_SLOT_1920; - hs->timeSlots = NUMBER_TIME_SLOTS_1920; - break; - default: - return -1; - } - } - - if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { - hs->mhParams = ¶msAacLd; - } else - hs->mhParams = ¶msAac; - - hs->qmfNoChannels = qmfNoChannels; - hs->sampleFreq = sampleFreq; - hs->nSfb = nSfb; - - hs->totNoEst = totNoEst; - hs->move = move; - hs->noEstPerFrame = noEstPerFrame; - - for (i = 0; i < totNoEst; i++) { - FDKmemclear(hs->guideVectors[i].guideVectorDiff, - sizeof(FIXP_DBL) * MAX_FREQ_COEFFS); - FDKmemclear(hs->guideVectors[i].guideVectorOrig, - sizeof(FIXP_DBL) * MAX_FREQ_COEFFS); - FDKmemclear(hs->detectionVectors[i], sizeof(UCHAR) * MAX_FREQ_COEFFS); - FDKmemclear(hs->guideVectors[i].guideVectorDetected, - sizeof(UCHAR) * MAX_FREQ_COEFFS); - } - - // for(i=0; itonalityDiff[i], sizeof(FIXP_DBL) * MAX_FREQ_COEFFS); - FDKmemclear(hs->sfmOrig[i], sizeof(FIXP_DBL) * MAX_FREQ_COEFFS); - FDKmemclear(hs->sfmSbr[i], sizeof(FIXP_DBL) * MAX_FREQ_COEFFS); - } - - FDKmemclear(hs->prevEnvelopeCompensation, sizeof(UCHAR) * MAX_FREQ_COEFFS); - FDKmemclear(hs->guideScfb, sizeof(UCHAR) * MAX_FREQ_COEFFS); - - hs->previousTransientFlag = 0; - hs->previousTransientFrame = 0; - hs->previousTransientPos = 0; - - return (0); -} - -/**************************************************************************/ -/*! - \brief Deletes an instance of the missing harmonics detector. - - - \return none. - -*/ -/**************************************************************************/ -void FDKsbrEnc_DeleteSbrMissingHarmonicsDetector( - HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet) { - if (hSbrMHDet) { - HANDLE_SBR_MISSING_HARMONICS_DETECTOR hs = hSbrMHDet; - - FreeRam_Sbr_detectionVectors(&hs->detectionVectors[0]); - FreeRam_Sbr_guideVectorDetected(&hs->guideVectors[0].guideVectorDetected); - FreeRam_Sbr_guideVectorDiff(&hs->guideVectors[0].guideVectorDiff); - FreeRam_Sbr_guideVectorOrig(&hs->guideVectors[0].guideVectorOrig); - FreeRam_Sbr_prevEnvelopeCompensation(&hs->prevEnvelopeCompensation); - FreeRam_Sbr_guideScfb(&hs->guideScfb); - } -} - -/**************************************************************************/ -/*! - \brief Resets an instance of the missing harmonics detector. - - - \return error code, noError if OK. - -*/ -/**************************************************************************/ -INT FDKsbrEnc_ResetSbrMissingHarmonicsDetector( - HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMissingHarmonicsDetector, - INT nSfb) { - int i; - FIXP_DBL tempGuide[MAX_FREQ_COEFFS]; - UCHAR tempGuideInt[MAX_FREQ_COEFFS]; - INT nSfbPrev; - - nSfbPrev = hSbrMissingHarmonicsDetector->nSfb; - hSbrMissingHarmonicsDetector->nSfb = nSfb; - - FDKmemcpy(tempGuideInt, hSbrMissingHarmonicsDetector->guideScfb, - nSfbPrev * sizeof(UCHAR)); - - if (nSfb > nSfbPrev) { - for (i = 0; i < (nSfb - nSfbPrev); i++) { - hSbrMissingHarmonicsDetector->guideScfb[i] = 0; - } - - for (i = 0; i < nSfbPrev; i++) { - hSbrMissingHarmonicsDetector->guideScfb[i + (nSfb - nSfbPrev)] = - tempGuideInt[i]; - } - } else { - for (i = 0; i < nSfb; i++) { - hSbrMissingHarmonicsDetector->guideScfb[i] = - tempGuideInt[i + (nSfbPrev - nSfb)]; - } - } - - FDKmemcpy(tempGuide, - hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDiff, - nSfbPrev * sizeof(FIXP_DBL)); - - if (nSfb > nSfbPrev) { - for (i = 0; i < (nSfb - nSfbPrev); i++) { - hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDiff[i] = - FL2FXCONST_DBL(0.0f); - } - - for (i = 0; i < nSfbPrev; i++) { - hSbrMissingHarmonicsDetector->guideVectors[0] - .guideVectorDiff[i + (nSfb - nSfbPrev)] = tempGuide[i]; - } - } else { - for (i = 0; i < nSfb; i++) { - hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDiff[i] = - tempGuide[i + (nSfbPrev - nSfb)]; - } - } - - FDKmemcpy(tempGuide, - hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorOrig, - nSfbPrev * sizeof(FIXP_DBL)); - - if (nSfb > nSfbPrev) { - for (i = 0; i < (nSfb - nSfbPrev); i++) { - hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorOrig[i] = - FL2FXCONST_DBL(0.0f); - } - - for (i = 0; i < nSfbPrev; i++) { - hSbrMissingHarmonicsDetector->guideVectors[0] - .guideVectorOrig[i + (nSfb - nSfbPrev)] = tempGuide[i]; - } - } else { - for (i = 0; i < nSfb; i++) { - hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorOrig[i] = - tempGuide[i + (nSfbPrev - nSfb)]; - } - } - - FDKmemcpy(tempGuideInt, - hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDetected, - nSfbPrev * sizeof(UCHAR)); - - if (nSfb > nSfbPrev) { - for (i = 0; i < (nSfb - nSfbPrev); i++) { - hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDetected[i] = 0; - } - - for (i = 0; i < nSfbPrev; i++) { - hSbrMissingHarmonicsDetector->guideVectors[0] - .guideVectorDetected[i + (nSfb - nSfbPrev)] = tempGuideInt[i]; - } - } else { - for (i = 0; i < nSfb; i++) { - hSbrMissingHarmonicsDetector->guideVectors[0].guideVectorDetected[i] = - tempGuideInt[i + (nSfbPrev - nSfb)]; - } - } - - FDKmemcpy(tempGuideInt, - hSbrMissingHarmonicsDetector->prevEnvelopeCompensation, - nSfbPrev * sizeof(UCHAR)); - - if (nSfb > nSfbPrev) { - for (i = 0; i < (nSfb - nSfbPrev); i++) { - hSbrMissingHarmonicsDetector->prevEnvelopeCompensation[i] = 0; - } - - for (i = 0; i < nSfbPrev; i++) { - hSbrMissingHarmonicsDetector - ->prevEnvelopeCompensation[i + (nSfb - nSfbPrev)] = tempGuideInt[i]; - } - } else { - for (i = 0; i < nSfb; i++) { - hSbrMissingHarmonicsDetector->prevEnvelopeCompensation[i] = - tempGuideInt[i + (nSfbPrev - nSfb)]; - } - } - - return 0; -} --- a/libSBRenc/src/mh_det.h +++ /dev/null @@ -1,204 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief missing harmonics detection header file $Revision: 92790 $ -*/ - -#ifndef MH_DET_H -#define MH_DET_H - -#include "sbr_encoder.h" -#include "fram_gen.h" - -typedef struct { - FIXP_DBL thresHoldDiff; /*!< threshold for tonality difference */ - FIXP_DBL thresHoldDiffGuide; /*!< threshold for tonality difference for the - guide */ - FIXP_DBL thresHoldTone; /*!< threshold for tonality for a sine */ - FIXP_DBL invThresHoldTone; - FIXP_DBL thresHoldToneGuide; /*!< threshold for tonality for a sine for the - guide */ - FIXP_DBL sfmThresSbr; /*!< tonality flatness measure threshold for the SBR - signal.*/ - FIXP_DBL sfmThresOrig; /*!< tonality flatness measure threshold for the - original signal.*/ - FIXP_DBL decayGuideOrig; /*!< decay value of the tonality value of the guide - for the tone. */ - FIXP_DBL decayGuideDiff; /*!< decay value of the tonality value of the guide - for the tonality difference. */ - FIXP_DBL derivThresMaxLD64; /*!< threshold for detecting LP character in a - signal. */ - FIXP_DBL derivThresBelowLD64; /*!< threshold for detecting LP character in a - signal. */ - FIXP_DBL derivThresAboveLD64; /*!< threshold for detecting LP character in a - signal. */ -} THRES_HOLDS; - -typedef struct { - INT deltaTime; /*!< maximum allowed transient distance (from frame border in - number of qmf subband sample) for a frame to be considered a - transient frame.*/ - THRES_HOLDS thresHolds; /*!< the thresholds used for detection. */ - INT maxComp; /*!< maximum alllowed compensation factor for the envelope data. - */ -} DETECTOR_PARAMETERS_MH; - -typedef struct { - FIXP_DBL *guideVectorDiff; - FIXP_DBL *guideVectorOrig; - UCHAR *guideVectorDetected; -} GUIDE_VECTORS; - -typedef struct { - INT qmfNoChannels; - INT nSfb; - INT sampleFreq; - INT previousTransientFlag; - INT previousTransientFrame; - INT previousTransientPos; - - INT noVecPerFrame; - INT transientPosOffset; - - INT move; - INT totNoEst; - INT noEstPerFrame; - INT timeSlots; - - UCHAR *guideScfb; - UCHAR *prevEnvelopeCompensation; - UCHAR *detectionVectors[MAX_NO_OF_ESTIMATES]; - FIXP_DBL tonalityDiff[MAX_NO_OF_ESTIMATES / 2][MAX_FREQ_COEFFS]; - FIXP_DBL sfmOrig[MAX_NO_OF_ESTIMATES / 2][MAX_FREQ_COEFFS]; - FIXP_DBL sfmSbr[MAX_NO_OF_ESTIMATES / 2][MAX_FREQ_COEFFS]; - const DETECTOR_PARAMETERS_MH *mhParams; - GUIDE_VECTORS guideVectors[MAX_NO_OF_ESTIMATES]; -} SBR_MISSING_HARMONICS_DETECTOR; - -typedef SBR_MISSING_HARMONICS_DETECTOR *HANDLE_SBR_MISSING_HARMONICS_DETECTOR; - -void FDKsbrEnc_SbrMissingHarmonicsDetectorQmf( - HANDLE_SBR_MISSING_HARMONICS_DETECTOR h_sbrMissingHarmonicsDetector, - FIXP_DBL **pQuotaBuffer, INT **pSignBuffer, SCHAR *indexVector, - const SBR_FRAME_INFO *pFrameInfo, const UCHAR *pTranInfo, - INT *pAddHarmonicsFlag, UCHAR *pAddHarmonicsScaleFactorBands, - const UCHAR *freqBandTable, INT nSfb, UCHAR *envelopeCompensation, - FIXP_DBL *pNrgVector); - -INT FDKsbrEnc_CreateSbrMissingHarmonicsDetector( - HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMHDet, INT chan); - -INT FDKsbrEnc_InitSbrMissingHarmonicsDetector( - HANDLE_SBR_MISSING_HARMONICS_DETECTOR h_sbrMissingHarmonicsDetector, - INT sampleFreq, INT frameSize, INT nSfb, INT qmfNoChannels, INT totNoEst, - INT move, INT noEstPerFrame, UINT sbrSyntaxFlags); - -void FDKsbrEnc_DeleteSbrMissingHarmonicsDetector( - HANDLE_SBR_MISSING_HARMONICS_DETECTOR h_sbrMissingHarmonicsDetector); - -INT FDKsbrEnc_ResetSbrMissingHarmonicsDetector( - HANDLE_SBR_MISSING_HARMONICS_DETECTOR hSbrMissingHarmonicsDetector, - INT nSfb); - -#endif --- a/libSBRenc/src/nf_est.cpp +++ /dev/null @@ -1,612 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -#include "nf_est.h" - -#include "sbr_misc.h" - -#include "genericStds.h" - -/* smoothFilter[4] = {0.05857864376269f, 0.2f, 0.34142135623731f, 0.4f}; */ -static const FIXP_DBL smoothFilter[4] = {0x077f813d, 0x19999995, 0x2bb3b1f5, - 0x33333335}; - -/* static const INT smoothFilterLength = 4; */ - -static const FIXP_DBL QuantOffset = (INT)0xfc000000; /* ld64(0.25) */ - -#ifndef min -#define min(a, b) (a < b ? a : b) -#endif - -#ifndef max -#define max(a, b) (a > b ? a : b) -#endif - -#define NOISE_FLOOR_OFFSET_SCALING (4) - -/**************************************************************************/ -/*! - \brief The function applies smoothing to the noise levels. - - - - \return none - -*/ -/**************************************************************************/ -static void smoothingOfNoiseLevels( - FIXP_DBL *NoiseLevels, /*!< pointer to noise-floor levels.*/ - INT nEnvelopes, /*!< Number of noise floor envelopes.*/ - INT noNoiseBands, /*!< Number of noise bands for every noise floor envelope. - */ - FIXP_DBL prevNoiseLevels[NF_SMOOTHING_LENGTH] - [MAX_NUM_NOISE_VALUES], /*!< Previous noise floor - envelopes. */ - const FIXP_DBL * - pSmoothFilter, /*!< filter used for smoothing the noise floor levels. */ - INT transientFlag) /*!< flag indicating if a transient is present*/ - -{ - INT i, band, env; - FIXP_DBL accu; - - for (env = 0; env < nEnvelopes; env++) { - if (transientFlag) { - for (i = 0; i < NF_SMOOTHING_LENGTH; i++) { - FDKmemcpy(prevNoiseLevels[i], NoiseLevels + env * noNoiseBands, - noNoiseBands * sizeof(FIXP_DBL)); - } - } else { - for (i = 1; i < NF_SMOOTHING_LENGTH; i++) { - FDKmemcpy(prevNoiseLevels[i - 1], prevNoiseLevels[i], - noNoiseBands * sizeof(FIXP_DBL)); - } - FDKmemcpy(prevNoiseLevels[NF_SMOOTHING_LENGTH - 1], - NoiseLevels + env * noNoiseBands, - noNoiseBands * sizeof(FIXP_DBL)); - } - - for (band = 0; band < noNoiseBands; band++) { - accu = FL2FXCONST_DBL(0.0f); - for (i = 0; i < NF_SMOOTHING_LENGTH; i++) { - accu += fMultDiv2(pSmoothFilter[i], prevNoiseLevels[i][band]); - } - FDK_ASSERT((band + env * noNoiseBands) < MAX_NUM_NOISE_VALUES); - NoiseLevels[band + env * noNoiseBands] = accu << 1; - } - } -} - -/**************************************************************************/ -/*! - \brief Does the noise floor level estiamtion. - - The noiseLevel samples are scaled by the factor 0.25 - - \return none - -*/ -/**************************************************************************/ -static void qmfBasedNoiseFloorDetection( - FIXP_DBL *noiseLevel, /*!< Pointer to vector to - store the noise levels - in.*/ - FIXP_DBL **quotaMatrixOrig, /*!< Matrix holding the quota - values of the original. */ - SCHAR *indexVector, /*!< Index vector to obtain the - patched data. */ - INT startIndex, /*!< Start index. */ - INT stopIndex, /*!< Stop index. */ - INT startChannel, /*!< Start channel of the current - noise floor band.*/ - INT stopChannel, /*!< Stop channel of the current - noise floor band. */ - FIXP_DBL ana_max_level, /*!< Maximum level of the - adaptive noise.*/ - FIXP_DBL noiseFloorOffset, /*!< Noise floor offset. */ - INT missingHarmonicFlag, /*!< Flag indicating if a - strong tonal component - is missing.*/ - FIXP_DBL weightFac, /*!< Weightening factor for the - difference between orig and sbr. - */ - INVF_MODE diffThres, /*!< Threshold value to control the - inverse filtering decision.*/ - INVF_MODE inverseFilteringLevel) /*!< Inverse filtering - level of the current - band.*/ -{ - INT scale, l, k; - FIXP_DBL meanOrig = FL2FXCONST_DBL(0.0f), meanSbr = FL2FXCONST_DBL(0.0f), - diff; - FIXP_DBL invIndex = GetInvInt(stopIndex - startIndex); - FIXP_DBL invChannel = GetInvInt(stopChannel - startChannel); - FIXP_DBL accu; - - /* - Calculate the mean value, over the current time segment, for the original, the - HFR and the difference, over all channels in the current frequency range. - */ - - if (missingHarmonicFlag == 1) { - for (l = startChannel; l < stopChannel; l++) { - /* tonalityOrig */ - accu = FL2FXCONST_DBL(0.0f); - for (k = startIndex; k < stopIndex; k++) { - accu += fMultDiv2(quotaMatrixOrig[k][l], invIndex); - } - meanOrig = fixMax(meanOrig, (accu << 1)); - - /* tonalitySbr */ - accu = FL2FXCONST_DBL(0.0f); - for (k = startIndex; k < stopIndex; k++) { - accu += fMultDiv2(quotaMatrixOrig[k][indexVector[l]], invIndex); - } - meanSbr = fixMax(meanSbr, (accu << 1)); - } - } else { - for (l = startChannel; l < stopChannel; l++) { - /* tonalityOrig */ - accu = FL2FXCONST_DBL(0.0f); - for (k = startIndex; k < stopIndex; k++) { - accu += fMultDiv2(quotaMatrixOrig[k][l], invIndex); - } - meanOrig += fMult((accu << 1), invChannel); - - /* tonalitySbr */ - accu = FL2FXCONST_DBL(0.0f); - for (k = startIndex; k < stopIndex; k++) { - accu += fMultDiv2(quotaMatrixOrig[k][indexVector[l]], invIndex); - } - meanSbr += fMult((accu << 1), invChannel); - } - } - - /* Small fix to avoid noise during silent passages.*/ - if (meanOrig <= FL2FXCONST_DBL(0.000976562f * RELAXATION_FLOAT) && - meanSbr <= FL2FXCONST_DBL(0.000976562f * RELAXATION_FLOAT)) { - meanOrig = FL2FXCONST_DBL(101.5936673f * RELAXATION_FLOAT); - meanSbr = FL2FXCONST_DBL(101.5936673f * RELAXATION_FLOAT); - } - - meanOrig = fixMax(meanOrig, RELAXATION); - meanSbr = fixMax(meanSbr, RELAXATION); - - if (missingHarmonicFlag == 1 || inverseFilteringLevel == INVF_MID_LEVEL || - inverseFilteringLevel == INVF_LOW_LEVEL || - inverseFilteringLevel == INVF_OFF || inverseFilteringLevel <= diffThres) { - diff = RELAXATION; - } else { - accu = fDivNorm(meanSbr, meanOrig, &scale); - - diff = fixMax(RELAXATION, fMult(RELAXATION_FRACT, fMult(weightFac, accu)) >> - (RELAXATION_SHIFT - scale)); - } - - /* - * noise Level is now a positive value, i.e. - * the more harmonic the signal is the higher noise level, - * this makes no sense so we change the sign. - *********************************************************/ - accu = fDivNorm(diff, meanOrig, &scale); - scale -= 2; - - if ((scale > 0) && (accu > ((FIXP_DBL)MAXVAL_DBL) >> scale)) { - *noiseLevel = (FIXP_DBL)MAXVAL_DBL; - } else { - *noiseLevel = scaleValue(accu, scale); - } - - /* - * Add a noise floor offset to compensate for bias in the detector - *****************************************************************/ - if (!missingHarmonicFlag) { - *noiseLevel = fixMin(fMult(*noiseLevel, noiseFloorOffset), - (FIXP_DBL)MAXVAL_DBL >> NOISE_FLOOR_OFFSET_SCALING) - << NOISE_FLOOR_OFFSET_SCALING; - } - - /* - * check to see that we don't exceed the maximum allowed level - **************************************************************/ - *noiseLevel = - fixMin(*noiseLevel, - ana_max_level); /* ana_max_level is scaled with factor 0.25 */ -} - -/**************************************************************************/ -/*! - \brief Does the noise floor level estiamtion. - The function calls the Noisefloor estimation function - for the time segments decided based upon the transient - information. The block is always divided into one or two segments. - - - \return none - -*/ -/**************************************************************************/ -void FDKsbrEnc_sbrNoiseFloorEstimateQmf( - HANDLE_SBR_NOISE_FLOOR_ESTIMATE - h_sbrNoiseFloorEstimate, /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct - */ - const SBR_FRAME_INFO - *frame_info, /*!< Time frequency grid of the current frame. */ - FIXP_DBL - *noiseLevels, /*!< Pointer to vector to store the noise levels in.*/ - FIXP_DBL **quotaMatrixOrig, /*!< Matrix holding the quota values of the - original. */ - SCHAR *indexVector, /*!< Index vector to obtain the patched data. */ - INT missingHarmonicsFlag, /*!< Flag indicating if a strong tonal component - will be missing. */ - INT startIndex, /*!< Start index. */ - UINT numberOfEstimatesPerFrame, /*!< The number of tonality estimates per - frame. */ - int transientFrame, /*!< A flag indicating if a transient is present. */ - INVF_MODE *pInvFiltLevels, /*!< Pointer to the vector holding the inverse - filtering levels. */ - UINT sbrSyntaxFlags) - -{ - INT nNoiseEnvelopes, startPos[2], stopPos[2], env, band; - - INT noNoiseBands = h_sbrNoiseFloorEstimate->noNoiseBands; - INT *freqBandTable = h_sbrNoiseFloorEstimate->freqBandTableQmf; - - nNoiseEnvelopes = frame_info->nNoiseEnvelopes; - - startPos[0] = startIndex; - - if (nNoiseEnvelopes == 1) { - stopPos[0] = startIndex + min(numberOfEstimatesPerFrame, 2); - } else { - stopPos[0] = startIndex + 1; - startPos[1] = startIndex + 1; - stopPos[1] = startIndex + min(numberOfEstimatesPerFrame, 2); - } - - /* - * Estimate the noise floor. - **************************************/ - for (env = 0; env < nNoiseEnvelopes; env++) { - for (band = 0; band < noNoiseBands; band++) { - FDK_ASSERT((band + env * noNoiseBands) < MAX_NUM_NOISE_VALUES); - qmfBasedNoiseFloorDetection( - &noiseLevels[band + env * noNoiseBands], quotaMatrixOrig, indexVector, - startPos[env], stopPos[env], freqBandTable[band], - freqBandTable[band + 1], h_sbrNoiseFloorEstimate->ana_max_level, - h_sbrNoiseFloorEstimate->noiseFloorOffset[band], missingHarmonicsFlag, - h_sbrNoiseFloorEstimate->weightFac, - h_sbrNoiseFloorEstimate->diffThres, pInvFiltLevels[band]); - } - } - - /* - * Smoothing of the values. - **************************/ - smoothingOfNoiseLevels(noiseLevels, nNoiseEnvelopes, - h_sbrNoiseFloorEstimate->noNoiseBands, - h_sbrNoiseFloorEstimate->prevNoiseLevels, - h_sbrNoiseFloorEstimate->smoothFilter, transientFrame); - - /* quantisation*/ - for (env = 0; env < nNoiseEnvelopes; env++) { - for (band = 0; band < noNoiseBands; band++) { - FDK_ASSERT((band + env * noNoiseBands) < MAX_NUM_NOISE_VALUES); - noiseLevels[band + env * noNoiseBands] = - (FIXP_DBL)NOISE_FLOOR_OFFSET_64 - - (FIXP_DBL)CalcLdData(noiseLevels[band + env * noNoiseBands] + - (FIXP_DBL)1) + - QuantOffset; - } - } -} - -/**************************************************************************/ -/*! - \brief - - - \return errorCode, noError if successful - -*/ -/**************************************************************************/ -static INT downSampleLoRes(INT *v_result, /*!< */ - INT num_result, /*!< */ - const UCHAR *freqBandTableRef, /*!< */ - INT num_Ref) /*!< */ -{ - INT step; - INT i, j; - INT org_length, result_length; - INT v_index[MAX_FREQ_COEFFS / 2]; - - /* init */ - org_length = num_Ref; - result_length = num_result; - - v_index[0] = 0; /* Always use left border */ - i = 0; - while (org_length > 0) /* Create downsample vector */ - { - i++; - step = org_length / result_length; /* floor; */ - org_length = org_length - step; - result_length--; - v_index[i] = v_index[i - 1] + step; - } - - if (i != num_result) /* Should never happen */ - return (1); /* error downsampling */ - - for (j = 0; j <= i; - j++) /* Use downsample vector to index LoResolution vector. */ - { - v_result[j] = freqBandTableRef[v_index[j]]; - } - - return (0); -} - -/**************************************************************************/ -/*! - \brief Initialize an instance of the noise floor level estimation module. - - - \return errorCode, noError if successful - -*/ -/**************************************************************************/ -INT FDKsbrEnc_InitSbrNoiseFloorEstimate( - HANDLE_SBR_NOISE_FLOOR_ESTIMATE - h_sbrNoiseFloorEstimate, /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct - */ - INT ana_max_level, /*!< Maximum level of the adaptive noise. */ - const UCHAR *freqBandTable, /*!< Frequency band table. */ - INT nSfb, /*!< Number of frequency bands. */ - INT noiseBands, /*!< Number of noise bands per octave. */ - INT noiseFloorOffset, /*!< Noise floor offset. */ - INT timeSlots, /*!< Number of time slots in a frame. */ - UINT useSpeechConfig /*!< Flag: adapt tuning parameters according to speech - */ -) { - INT i, qexp, qtmp; - FIXP_DBL tmp, exp; - - FDKmemclear(h_sbrNoiseFloorEstimate, sizeof(SBR_NOISE_FLOOR_ESTIMATE)); - - h_sbrNoiseFloorEstimate->smoothFilter = smoothFilter; - if (useSpeechConfig) { - h_sbrNoiseFloorEstimate->weightFac = (FIXP_DBL)MAXVAL_DBL; - h_sbrNoiseFloorEstimate->diffThres = INVF_LOW_LEVEL; - } else { - h_sbrNoiseFloorEstimate->weightFac = FL2FXCONST_DBL(0.25f); - h_sbrNoiseFloorEstimate->diffThres = INVF_MID_LEVEL; - } - - h_sbrNoiseFloorEstimate->timeSlots = timeSlots; - h_sbrNoiseFloorEstimate->noiseBands = noiseBands; - - /* h_sbrNoiseFloorEstimate->ana_max_level is scaled by 0.25 */ - switch (ana_max_level) { - case 6: - h_sbrNoiseFloorEstimate->ana_max_level = (FIXP_DBL)MAXVAL_DBL; - break; - case 3: - h_sbrNoiseFloorEstimate->ana_max_level = FL2FXCONST_DBL(0.5); - break; - case -3: - h_sbrNoiseFloorEstimate->ana_max_level = FL2FXCONST_DBL(0.125); - break; - default: - /* Should not enter here */ - h_sbrNoiseFloorEstimate->ana_max_level = (FIXP_DBL)MAXVAL_DBL; - break; - } - - /* - calculate number of noise bands and allocate - */ - if (FDKsbrEnc_resetSbrNoiseFloorEstimate(h_sbrNoiseFloorEstimate, - freqBandTable, nSfb)) - return (1); - - if (noiseFloorOffset == 0) { - tmp = ((FIXP_DBL)MAXVAL_DBL) >> NOISE_FLOOR_OFFSET_SCALING; - } else { - /* noiseFloorOffset has to be smaller than 12, because - the result of the calculation below must be smaller than 1: - (2^(noiseFloorOffset/3))*2^4<1 */ - FDK_ASSERT(noiseFloorOffset < 12); - - /* Assumes the noise floor offset in tuning table are in q31 */ - /* Change the qformat here when non-zero values would be filled */ - exp = fDivNorm((FIXP_DBL)noiseFloorOffset, 3, &qexp); - tmp = fPow(2, DFRACT_BITS - 1, exp, qexp, &qtmp); - tmp = scaleValue(tmp, qtmp - NOISE_FLOOR_OFFSET_SCALING); - } - - for (i = 0; i < h_sbrNoiseFloorEstimate->noNoiseBands; i++) { - h_sbrNoiseFloorEstimate->noiseFloorOffset[i] = tmp; - } - - return (0); -} - -/**************************************************************************/ -/*! - \brief Resets the current instance of the noise floor estiamtion - module. - - - \return errorCode, noError if successful - -*/ -/**************************************************************************/ -INT FDKsbrEnc_resetSbrNoiseFloorEstimate( - HANDLE_SBR_NOISE_FLOOR_ESTIMATE - h_sbrNoiseFloorEstimate, /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct - */ - const UCHAR *freqBandTable, /*!< Frequency band table. */ - INT nSfb /*!< Number of bands in the frequency band table. */ -) { - INT k2, kx; - - /* - * Calculate number of noise bands - ***********************************/ - k2 = freqBandTable[nSfb]; - kx = freqBandTable[0]; - if (h_sbrNoiseFloorEstimate->noiseBands == 0) { - h_sbrNoiseFloorEstimate->noNoiseBands = 1; - } else { - /* - * Calculate number of noise bands 1,2 or 3 bands/octave - ********************************************************/ - FIXP_DBL tmp, ratio, lg2; - INT ratio_e, qlg2, nNoiseBands; - - ratio = fDivNorm(k2, kx, &ratio_e); - lg2 = fLog2(ratio, ratio_e, &qlg2); - tmp = fMult((FIXP_DBL)(h_sbrNoiseFloorEstimate->noiseBands << 24), lg2); - tmp = scaleValue(tmp, qlg2 - 23); - - nNoiseBands = (INT)((tmp + (FIXP_DBL)1) >> 1); - - if (nNoiseBands > MAX_NUM_NOISE_COEFFS) { - nNoiseBands = MAX_NUM_NOISE_COEFFS; - } - - if (nNoiseBands == 0) { - nNoiseBands = 1; - } - - h_sbrNoiseFloorEstimate->noNoiseBands = nNoiseBands; - } - - return (downSampleLoRes(h_sbrNoiseFloorEstimate->freqBandTableQmf, - h_sbrNoiseFloorEstimate->noNoiseBands, freqBandTable, - nSfb)); -} - -/**************************************************************************/ -/*! - \brief Deletes the current instancce of the noise floor level - estimation module. - - - \return none - -*/ -/**************************************************************************/ -void FDKsbrEnc_deleteSbrNoiseFloorEstimate( - HANDLE_SBR_NOISE_FLOOR_ESTIMATE - h_sbrNoiseFloorEstimate) /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct - */ -{ - if (h_sbrNoiseFloorEstimate) { - /* - nothing to do - */ - } -} --- a/libSBRenc/src/nf_est.h +++ /dev/null @@ -1,185 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Noise floor estimation structs and prototypes $Revision: 92790 $ -*/ - -#ifndef NF_EST_H -#define NF_EST_H - -#include "sbr_encoder.h" -#include "fram_gen.h" - -#define NF_SMOOTHING_LENGTH 4 /*!< Smoothing length of the noise floors. */ - -typedef struct { - FIXP_DBL - prevNoiseLevels[NF_SMOOTHING_LENGTH] - [MAX_NUM_NOISE_VALUES]; /*!< The previous noise levels. */ - FIXP_DBL noiseFloorOffset - [MAX_NUM_NOISE_VALUES]; /*!< Noise floor offset, scaled with - NOISE_FLOOR_OFFSET_SCALING */ - const FIXP_DBL *smoothFilter; /*!< Smoothing filter to use. */ - FIXP_DBL ana_max_level; /*!< Max level allowed. */ - FIXP_DBL weightFac; /*!< Weightening factor for the difference between orig - and sbr. */ - INT freqBandTableQmf[MAX_NUM_NOISE_VALUES + - 1]; /*!< Frequncy band table for the noise floor bands.*/ - INT noNoiseBands; /*!< Number of noisebands. */ - INT noiseBands; /*!< NoiseBands switch 4 bit.*/ - INT timeSlots; /*!< Number of timeslots in a frame. */ - INVF_MODE diffThres; /*!< Threshold value to control the inverse filtering - decision */ -} SBR_NOISE_FLOOR_ESTIMATE; - -typedef SBR_NOISE_FLOOR_ESTIMATE *HANDLE_SBR_NOISE_FLOOR_ESTIMATE; - -void FDKsbrEnc_sbrNoiseFloorEstimateQmf( - HANDLE_SBR_NOISE_FLOOR_ESTIMATE - h_sbrNoiseFloorEstimate, /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct - */ - const SBR_FRAME_INFO - *frame_info, /*!< Time frequency grid of the current frame. */ - FIXP_DBL - *noiseLevels, /*!< Pointer to vector to store the noise levels in.*/ - FIXP_DBL **quotaMatrixOrig, /*!< Matrix holding the quota values of the - original. */ - SCHAR *indexVector, /*!< Index vector to obtain the patched data. */ - INT missingHarmonicsFlag, /*!< Flag indicating if a strong tonal component - will be missing. */ - INT startIndex, /*!< Start index. */ - UINT numberOfEstimatesPerFrame, /*!< The number of tonality estimates per - frame. */ - INT transientFrame, /*!< A flag indicating if a transient is present. */ - INVF_MODE *pInvFiltLevels, /*!< Pointer to the vector holding the inverse - filtering levels. */ - UINT sbrSyntaxFlags); - -INT FDKsbrEnc_InitSbrNoiseFloorEstimate( - HANDLE_SBR_NOISE_FLOOR_ESTIMATE - h_sbrNoiseFloorEstimate, /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct - */ - INT ana_max_level, /*!< Maximum level of the adaptive noise. */ - const UCHAR *freqBandTable, /*!< Frequany band table. */ - INT nSfb, /*!< Number of frequency bands. */ - INT noiseBands, /*!< Number of noise bands per octave. */ - INT noiseFloorOffset, /*!< Noise floor offset. */ - INT timeSlots, /*!< Number of time slots in a frame. */ - UINT useSpeechConfig /*!< Flag: adapt tuning parameters according to speech - */ -); - -INT FDKsbrEnc_resetSbrNoiseFloorEstimate( - HANDLE_SBR_NOISE_FLOOR_ESTIMATE - h_sbrNoiseFloorEstimate, /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct - */ - const UCHAR *freqBandTable, /*!< Frequany band table. */ - INT nSfb); /*!< Number of bands in the frequency band table. */ - -void FDKsbrEnc_deleteSbrNoiseFloorEstimate( - HANDLE_SBR_NOISE_FLOOR_ESTIMATE - h_sbrNoiseFloorEstimate); /*!< Handle to SBR_NOISE_FLOOR_ESTIMATE struct - */ - -#endif --- a/libSBRenc/src/ps_bitenc.cpp +++ /dev/null @@ -1,624 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): N. Rettelbach - - Description: Parametric Stereo bitstream encoder - -*******************************************************************************/ - -#include "ps_bitenc.h" - -#include "ps_main.h" - -static inline UCHAR FDKsbrEnc_WriteBits_ps(HANDLE_FDK_BITSTREAM hBitStream, - UINT value, - const UINT numberOfBits) { - /* hBitStream == NULL happens here intentionally */ - if (hBitStream != NULL) { - FDKwriteBits(hBitStream, value, numberOfBits); - } - return numberOfBits; -} - -#define SI_SBR_EXTENSION_SIZE_BITS 4 -#define SI_SBR_EXTENSION_ESC_COUNT_BITS 8 -#define SI_SBR_EXTENSION_ID_BITS 2 -#define EXTENSION_ID_PS_CODING 2 -#define PS_EXT_ID_V0 0 - -static const INT iidDeltaCoarse_Offset = 14; -static const INT iidDeltaCoarse_MaxVal = 28; -static const INT iidDeltaFine_Offset = 30; -static const INT iidDeltaFine_MaxVal = 60; - -/* PS Stereo Huffmantable: iidDeltaFreqCoarse */ -static const UINT iidDeltaFreqCoarse_Length[] = { - 17, 17, 17, 17, 16, 15, 13, 10, 9, 7, 6, 5, 4, 3, 1, - 3, 4, 5, 6, 6, 8, 11, 13, 14, 14, 15, 17, 18, 18}; -static const UINT iidDeltaFreqCoarse_Code[] = { - 0x0001fffb, 0x0001fffc, 0x0001fffd, 0x0001fffa, 0x0000fffc, 0x00007ffc, - 0x00001ffd, 0x000003fe, 0x000001fe, 0x0000007e, 0x0000003c, 0x0000001d, - 0x0000000d, 0x00000005, 0000000000, 0x00000004, 0x0000000c, 0x0000001c, - 0x0000003d, 0x0000003e, 0x000000fe, 0x000007fe, 0x00001ffc, 0x00003ffc, - 0x00003ffd, 0x00007ffd, 0x0001fffe, 0x0003fffe, 0x0003ffff}; - -/* PS Stereo Huffmantable: iidDeltaFreqFine */ -static const UINT iidDeltaFreqFine_Length[] = { - 18, 18, 18, 18, 18, 18, 18, 18, 18, 17, 18, 17, 17, 16, 16, 15, - 14, 14, 13, 12, 12, 11, 10, 10, 8, 7, 6, 5, 4, 3, 1, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 14, 14, 15, 16, 16, - 17, 17, 18, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18}; -static const UINT iidDeltaFreqFine_Code[] = { - 0x0001feb4, 0x0001feb5, 0x0001fd76, 0x0001fd77, 0x0001fd74, 0x0001fd75, - 0x0001fe8a, 0x0001fe8b, 0x0001fe88, 0x0000fe80, 0x0001feb6, 0x0000fe82, - 0x0000feb8, 0x00007f42, 0x00007fae, 0x00003faf, 0x00001fd1, 0x00001fe9, - 0x00000fe9, 0x000007ea, 0x000007fb, 0x000003fb, 0x000001fb, 0x000001ff, - 0x0000007c, 0x0000003c, 0x0000001c, 0x0000000c, 0000000000, 0x00000001, - 0x00000001, 0x00000002, 0x00000001, 0x0000000d, 0x0000001d, 0x0000003d, - 0x0000007d, 0x000000fc, 0x000001fc, 0x000003fc, 0x000003f4, 0x000007eb, - 0x00000fea, 0x00001fea, 0x00001fd6, 0x00003fd0, 0x00007faf, 0x00007f43, - 0x0000feb9, 0x0000fe83, 0x0001feb7, 0x0000fe81, 0x0001fe89, 0x0001fe8e, - 0x0001fe8f, 0x0001fe8c, 0x0001fe8d, 0x0001feb2, 0x0001feb3, 0x0001feb0, - 0x0001feb1}; - -/* PS Stereo Huffmantable: iidDeltaTimeCoarse */ -static const UINT iidDeltaTimeCoarse_Length[] = { - 19, 19, 19, 20, 20, 20, 17, 15, 12, 10, 8, 6, 4, 2, 1, - 3, 5, 7, 9, 11, 13, 14, 17, 19, 20, 20, 20, 20, 20}; -static const UINT iidDeltaTimeCoarse_Code[] = { - 0x0007fff9, 0x0007fffa, 0x0007fffb, 0x000ffff8, 0x000ffff9, 0x000ffffa, - 0x0001fffd, 0x00007ffe, 0x00000ffe, 0x000003fe, 0x000000fe, 0x0000003e, - 0x0000000e, 0x00000002, 0000000000, 0x00000006, 0x0000001e, 0x0000007e, - 0x000001fe, 0x000007fe, 0x00001ffe, 0x00003ffe, 0x0001fffc, 0x0007fff8, - 0x000ffffb, 0x000ffffc, 0x000ffffd, 0x000ffffe, 0x000fffff}; - -/* PS Stereo Huffmantable: iidDeltaTimeFine */ -static const UINT iidDeltaTimeFine_Length[] = { - 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, - 14, 13, 13, 13, 12, 12, 11, 10, 9, 9, 7, 6, 5, 3, 1, 2, - 5, 6, 7, 8, 9, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, - 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}; -static const UINT iidDeltaTimeFine_Code[] = { - 0x00004ed4, 0x00004ed5, 0x00004ece, 0x00004ecf, 0x00004ecc, 0x00004ed6, - 0x00004ed8, 0x00004f46, 0x00004f60, 0x00002718, 0x00002719, 0x00002764, - 0x00002765, 0x0000276d, 0x000027b1, 0x000013b7, 0x000013d6, 0x000009c7, - 0x000009e9, 0x000009ed, 0x000004ee, 0x000004f7, 0x00000278, 0x00000139, - 0x0000009a, 0x0000009f, 0x00000020, 0x00000011, 0x0000000a, 0x00000003, - 0x00000001, 0000000000, 0x0000000b, 0x00000012, 0x00000021, 0x0000004c, - 0x0000009b, 0x0000013a, 0x00000279, 0x00000270, 0x000004ef, 0x000004e2, - 0x000009ea, 0x000009d8, 0x000013d7, 0x000013d0, 0x000027b2, 0x000027a2, - 0x0000271a, 0x0000271b, 0x00004f66, 0x00004f67, 0x00004f61, 0x00004f47, - 0x00004ed9, 0x00004ed7, 0x00004ecd, 0x00004ed2, 0x00004ed3, 0x00004ed0, - 0x00004ed1}; - -static const INT iccDelta_Offset = 7; -static const INT iccDelta_MaxVal = 14; -/* PS Stereo Huffmantable: iccDeltaFreq */ -static const UINT iccDeltaFreq_Length[] = {14, 14, 12, 10, 7, 5, 3, 1, - 2, 4, 6, 8, 9, 11, 13}; -static const UINT iccDeltaFreq_Code[] = { - 0x00003fff, 0x00003ffe, 0x00000ffe, 0x000003fe, 0x0000007e, - 0x0000001e, 0x00000006, 0000000000, 0x00000002, 0x0000000e, - 0x0000003e, 0x000000fe, 0x000001fe, 0x000007fe, 0x00001ffe}; - -/* PS Stereo Huffmantable: iccDeltaTime */ -static const UINT iccDeltaTime_Length[] = {14, 13, 11, 9, 7, 5, 3, 1, - 2, 4, 6, 8, 10, 12, 14}; -static const UINT iccDeltaTime_Code[] = { - 0x00003ffe, 0x00001ffe, 0x000007fe, 0x000001fe, 0x0000007e, - 0x0000001e, 0x00000006, 0000000000, 0x00000002, 0x0000000e, - 0x0000003e, 0x000000fe, 0x000003fe, 0x00000ffe, 0x00003fff}; - -static const INT ipdDelta_Offset = 0; -static const INT ipdDelta_MaxVal = 7; -/* PS Stereo Huffmantable: ipdDeltaFreq */ -static const UINT ipdDeltaFreq_Length[] = {1, 3, 4, 4, 4, 4, 4, 4}; -static const UINT ipdDeltaFreq_Code[] = {0x00000001, 0000000000, 0x00000006, - 0x00000004, 0x00000002, 0x00000003, - 0x00000005, 0x00000007}; - -/* PS Stereo Huffmantable: ipdDeltaTime */ -static const UINT ipdDeltaTime_Length[] = {1, 3, 4, 5, 5, 4, 4, 3}; -static const UINT ipdDeltaTime_Code[] = {0x00000001, 0x00000002, 0x00000002, - 0x00000003, 0x00000002, 0000000000, - 0x00000003, 0x00000003}; - -static const INT opdDelta_Offset = 0; -static const INT opdDelta_MaxVal = 7; -/* PS Stereo Huffmantable: opdDeltaFreq */ -static const UINT opdDeltaFreq_Length[] = {1, 3, 4, 4, 5, 5, 4, 3}; -static const UINT opdDeltaFreq_Code[] = { - 0x00000001, 0x00000001, 0x00000006, 0x00000004, - 0x0000000f, 0x0000000e, 0x00000005, 0000000000, -}; - -/* PS Stereo Huffmantable: opdDeltaTime */ -static const UINT opdDeltaTime_Length[] = {1, 3, 4, 5, 5, 4, 4, 3}; -static const UINT opdDeltaTime_Code[] = {0x00000001, 0x00000002, 0x00000001, - 0x00000007, 0x00000006, 0000000000, - 0x00000002, 0x00000003}; - -static INT getNoBands(const INT mode) { - INT noBands = 0; - - switch (mode) { - case 0: - case 3: /* coarse */ - noBands = PS_BANDS_COARSE; - break; - case 1: - case 4: /* mid */ - noBands = PS_BANDS_MID; - break; - case 2: - case 5: /* fine not supported */ - default: /* coarse as default */ - noBands = PS_BANDS_COARSE; - } - - return noBands; -} - -static INT getIIDRes(INT iidMode) { - if (iidMode < 3) - return PS_IID_RES_COARSE; - else - return PS_IID_RES_FINE; -} - -static INT encodeDeltaFreq(HANDLE_FDK_BITSTREAM hBitBuf, const INT *val, - const INT nBands, const UINT *codeTable, - const UINT *lengthTable, const INT tableOffset, - const INT maxVal, INT *error) { - INT bitCnt = 0; - INT lastVal = 0; - INT band; - - for (band = 0; band < nBands; band++) { - INT delta = (val[band] - lastVal) + tableOffset; - lastVal = val[band]; - if ((delta > maxVal) || (delta < 0)) { - *error = 1; - delta = delta > 0 ? maxVal : 0; - } - bitCnt += - FDKsbrEnc_WriteBits_ps(hBitBuf, codeTable[delta], lengthTable[delta]); - } - - return bitCnt; -} - -static INT encodeDeltaTime(HANDLE_FDK_BITSTREAM hBitBuf, const INT *val, - const INT *valLast, const INT nBands, - const UINT *codeTable, const UINT *lengthTable, - const INT tableOffset, const INT maxVal, - INT *error) { - INT bitCnt = 0; - INT band; - - for (band = 0; band < nBands; band++) { - INT delta = (val[band] - valLast[band]) + tableOffset; - if ((delta > maxVal) || (delta < 0)) { - *error = 1; - delta = delta > 0 ? maxVal : 0; - } - bitCnt += - FDKsbrEnc_WriteBits_ps(hBitBuf, codeTable[delta], lengthTable[delta]); - } - - return bitCnt; -} - -INT FDKsbrEnc_EncodeIid(HANDLE_FDK_BITSTREAM hBitBuf, const INT *iidVal, - const INT *iidValLast, const INT nBands, - const PS_IID_RESOLUTION res, const PS_DELTA mode, - INT *error) { - const UINT *codeTable; - const UINT *lengthTable; - INT bitCnt = 0; - - bitCnt = 0; - - switch (mode) { - case PS_DELTA_FREQ: - switch (res) { - case PS_IID_RES_COARSE: - codeTable = iidDeltaFreqCoarse_Code; - lengthTable = iidDeltaFreqCoarse_Length; - bitCnt += encodeDeltaFreq(hBitBuf, iidVal, nBands, codeTable, - lengthTable, iidDeltaCoarse_Offset, - iidDeltaCoarse_MaxVal, error); - break; - case PS_IID_RES_FINE: - codeTable = iidDeltaFreqFine_Code; - lengthTable = iidDeltaFreqFine_Length; - bitCnt += - encodeDeltaFreq(hBitBuf, iidVal, nBands, codeTable, lengthTable, - iidDeltaFine_Offset, iidDeltaFine_MaxVal, error); - break; - default: - *error = 1; - } - break; - - case PS_DELTA_TIME: - switch (res) { - case PS_IID_RES_COARSE: - codeTable = iidDeltaTimeCoarse_Code; - lengthTable = iidDeltaTimeCoarse_Length; - bitCnt += encodeDeltaTime( - hBitBuf, iidVal, iidValLast, nBands, codeTable, lengthTable, - iidDeltaCoarse_Offset, iidDeltaCoarse_MaxVal, error); - break; - case PS_IID_RES_FINE: - codeTable = iidDeltaTimeFine_Code; - lengthTable = iidDeltaTimeFine_Length; - bitCnt += encodeDeltaTime(hBitBuf, iidVal, iidValLast, nBands, - codeTable, lengthTable, iidDeltaFine_Offset, - iidDeltaFine_MaxVal, error); - break; - default: - *error = 1; - } - break; - - default: - *error = 1; - } - - return bitCnt; -} - -INT FDKsbrEnc_EncodeIcc(HANDLE_FDK_BITSTREAM hBitBuf, const INT *iccVal, - const INT *iccValLast, const INT nBands, - const PS_DELTA mode, INT *error) { - const UINT *codeTable; - const UINT *lengthTable; - INT bitCnt = 0; - - switch (mode) { - case PS_DELTA_FREQ: - codeTable = iccDeltaFreq_Code; - lengthTable = iccDeltaFreq_Length; - bitCnt += encodeDeltaFreq(hBitBuf, iccVal, nBands, codeTable, lengthTable, - iccDelta_Offset, iccDelta_MaxVal, error); - break; - - case PS_DELTA_TIME: - codeTable = iccDeltaTime_Code; - lengthTable = iccDeltaTime_Length; - - bitCnt += - encodeDeltaTime(hBitBuf, iccVal, iccValLast, nBands, codeTable, - lengthTable, iccDelta_Offset, iccDelta_MaxVal, error); - break; - - default: - *error = 1; - } - - return bitCnt; -} - -INT FDKsbrEnc_EncodeIpd(HANDLE_FDK_BITSTREAM hBitBuf, const INT *ipdVal, - const INT *ipdValLast, const INT nBands, - const PS_DELTA mode, INT *error) { - const UINT *codeTable; - const UINT *lengthTable; - INT bitCnt = 0; - - switch (mode) { - case PS_DELTA_FREQ: - codeTable = ipdDeltaFreq_Code; - lengthTable = ipdDeltaFreq_Length; - bitCnt += encodeDeltaFreq(hBitBuf, ipdVal, nBands, codeTable, lengthTable, - ipdDelta_Offset, ipdDelta_MaxVal, error); - break; - - case PS_DELTA_TIME: - codeTable = ipdDeltaTime_Code; - lengthTable = ipdDeltaTime_Length; - - bitCnt += - encodeDeltaTime(hBitBuf, ipdVal, ipdValLast, nBands, codeTable, - lengthTable, ipdDelta_Offset, ipdDelta_MaxVal, error); - break; - - default: - *error = 1; - } - - return bitCnt; -} - -INT FDKsbrEnc_EncodeOpd(HANDLE_FDK_BITSTREAM hBitBuf, const INT *opdVal, - const INT *opdValLast, const INT nBands, - const PS_DELTA mode, INT *error) { - const UINT *codeTable; - const UINT *lengthTable; - INT bitCnt = 0; - - switch (mode) { - case PS_DELTA_FREQ: - codeTable = opdDeltaFreq_Code; - lengthTable = opdDeltaFreq_Length; - bitCnt += encodeDeltaFreq(hBitBuf, opdVal, nBands, codeTable, lengthTable, - opdDelta_Offset, opdDelta_MaxVal, error); - break; - - case PS_DELTA_TIME: - codeTable = opdDeltaTime_Code; - lengthTable = opdDeltaTime_Length; - - bitCnt += - encodeDeltaTime(hBitBuf, opdVal, opdValLast, nBands, codeTable, - lengthTable, opdDelta_Offset, opdDelta_MaxVal, error); - break; - - default: - *error = 1; - } - - return bitCnt; -} - -static INT encodeIpdOpd(HANDLE_PS_OUT psOut, HANDLE_FDK_BITSTREAM hBitBuf) { - INT bitCnt = 0; - INT error = 0; - INT env; - - FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enableIpdOpd, 1); - - if (psOut->enableIpdOpd == 1) { - INT *ipdLast = psOut->ipdLast; - INT *opdLast = psOut->opdLast; - - for (env = 0; env < psOut->nEnvelopes; env++) { - bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaIPD[env], 1); - bitCnt += FDKsbrEnc_EncodeIpd(hBitBuf, psOut->ipd[env], ipdLast, - getNoBands(psOut->iidMode), - psOut->deltaIPD[env], &error); - - bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaOPD[env], 1); - bitCnt += FDKsbrEnc_EncodeOpd(hBitBuf, psOut->opd[env], opdLast, - getNoBands(psOut->iidMode), - psOut->deltaOPD[env], &error); - } - /* reserved bit */ - bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, 0, 1); - } - - return bitCnt; -} - -static INT getEnvIdx(const INT nEnvelopes, const INT frameClass) { - INT envIdx = 0; - - switch (nEnvelopes) { - case 0: - envIdx = 0; - break; - - case 1: - if (frameClass == 0) - envIdx = 1; - else - envIdx = 0; - break; - - case 2: - if (frameClass == 0) - envIdx = 2; - else - envIdx = 1; - break; - - case 3: - envIdx = 2; - break; - - case 4: - envIdx = 3; - break; - - default: - /* unsupported number of envelopes */ - envIdx = 0; - } - - return envIdx; -} - -static INT encodePSExtension(const HANDLE_PS_OUT psOut, - HANDLE_FDK_BITSTREAM hBitBuf) { - INT bitCnt = 0; - - if (psOut->enableIpdOpd == 1) { - INT ipdOpdBits = 0; - INT extSize = (2 + encodeIpdOpd(psOut, NULL) + 7) >> 3; - - if (extSize < 15) { - bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, extSize, 4); - } else { - bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, 15, 4); - bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, (extSize - 15), 8); - } - - /* write ipd opd data */ - ipdOpdBits += FDKsbrEnc_WriteBits_ps(hBitBuf, PS_EXT_ID_V0, 2); - ipdOpdBits += encodeIpdOpd(psOut, hBitBuf); - - /* byte align the ipd opd data */ - if (ipdOpdBits % 8) - ipdOpdBits += FDKsbrEnc_WriteBits_ps(hBitBuf, 0, (8 - (ipdOpdBits % 8))); - - bitCnt += ipdOpdBits; - } - - return (bitCnt); -} - -INT FDKsbrEnc_WritePSBitstream(const HANDLE_PS_OUT psOut, - HANDLE_FDK_BITSTREAM hBitBuf) { - INT psExtEnable = 0; - INT bitCnt = 0; - INT error = 0; - INT env; - - if (psOut != NULL) { - /* PS HEADER */ - bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enablePSHeader, 1); - - if (psOut->enablePSHeader) { - bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enableIID, 1); - if (psOut->enableIID) { - bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->iidMode, 3); - } - bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->enableICC, 1); - if (psOut->enableICC) { - bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->iccMode, 3); - } - if (psOut->enableIpdOpd) { - psExtEnable = 1; - } - bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psExtEnable, 1); - } - - /* Frame class, number of envelopes */ - bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->frameClass, 1); - bitCnt += FDKsbrEnc_WriteBits_ps( - hBitBuf, getEnvIdx(psOut->nEnvelopes, psOut->frameClass), 2); - - if (psOut->frameClass == 1) { - for (env = 0; env < psOut->nEnvelopes; env++) { - bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->frameBorder[env], 5); - } - } - - if (psOut->enableIID == 1) { - INT *iidLast = psOut->iidLast; - for (env = 0; env < psOut->nEnvelopes; env++) { - bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaIID[env], 1); - bitCnt += FDKsbrEnc_EncodeIid( - hBitBuf, psOut->iid[env], iidLast, getNoBands(psOut->iidMode), - (PS_IID_RESOLUTION)getIIDRes(psOut->iidMode), psOut->deltaIID[env], - &error); - - iidLast = psOut->iid[env]; - } - } - - if (psOut->enableICC == 1) { - INT *iccLast = psOut->iccLast; - for (env = 0; env < psOut->nEnvelopes; env++) { - bitCnt += FDKsbrEnc_WriteBits_ps(hBitBuf, psOut->deltaICC[env], 1); - bitCnt += FDKsbrEnc_EncodeIcc(hBitBuf, psOut->icc[env], iccLast, - getNoBands(psOut->iccMode), - psOut->deltaICC[env], &error); - - iccLast = psOut->icc[env]; - } - } - - if (psExtEnable != 0) { - bitCnt += encodePSExtension(psOut, hBitBuf); - } - - } /* if(psOut != NULL) */ - - return bitCnt; -} --- a/libSBRenc/src/ps_bitenc.h +++ /dev/null @@ -1,173 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): N. Rettelbach - - Description: Parametric Stereo bitstream encoder - -*******************************************************************************/ - -#include "ps_main.h" -#include "ps_const.h" -#include "FDK_bitstream.h" - -#ifndef PS_BITENC_H -#define PS_BITENC_H - -typedef struct T_PS_OUT { - INT enablePSHeader; - INT enableIID; - INT iidMode; - INT enableICC; - INT iccMode; - INT enableIpdOpd; - - INT frameClass; - INT nEnvelopes; - /* ENV data */ - INT frameBorder[PS_MAX_ENVELOPES]; - - /* iid data */ - PS_DELTA deltaIID[PS_MAX_ENVELOPES]; - INT iid[PS_MAX_ENVELOPES][PS_MAX_BANDS]; - INT iidLast[PS_MAX_BANDS]; - - /* icc data */ - PS_DELTA deltaICC[PS_MAX_ENVELOPES]; - INT icc[PS_MAX_ENVELOPES][PS_MAX_BANDS]; - INT iccLast[PS_MAX_BANDS]; - - /* ipd data */ - PS_DELTA deltaIPD[PS_MAX_ENVELOPES]; - INT ipd[PS_MAX_ENVELOPES][PS_MAX_BANDS]; - INT ipdLast[PS_MAX_BANDS]; - - /* opd data */ - PS_DELTA deltaOPD[PS_MAX_ENVELOPES]; - INT opd[PS_MAX_ENVELOPES][PS_MAX_BANDS]; - INT opdLast[PS_MAX_BANDS]; - -} PS_OUT, *HANDLE_PS_OUT; - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -INT FDKsbrEnc_EncodeIid(HANDLE_FDK_BITSTREAM hBitBuf, const INT *iidVal, - const INT *iidValLast, const INT nBands, - const PS_IID_RESOLUTION res, const PS_DELTA mode, - INT *error); - -INT FDKsbrEnc_EncodeIcc(HANDLE_FDK_BITSTREAM hBitBuf, const INT *iccVal, - const INT *iccValLast, const INT nBands, - const PS_DELTA mode, INT *error); - -INT FDKsbrEnc_EncodeIpd(HANDLE_FDK_BITSTREAM hBitBuf, const INT *ipdVal, - const INT *ipdValLast, const INT nBands, - const PS_DELTA mode, INT *error); - -INT FDKsbrEnc_EncodeOpd(HANDLE_FDK_BITSTREAM hBitBuf, const INT *opdVal, - const INT *opdValLast, const INT nBands, - const PS_DELTA mode, INT *error); - -INT FDKsbrEnc_WritePSBitstream(const HANDLE_PS_OUT psOut, - HANDLE_FDK_BITSTREAM hBitBuf); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* defined(PSENC_ENABLE) */ --- a/libSBRenc/src/ps_const.h +++ /dev/null @@ -1,150 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): N. Rettelbach - - Description: Parametric Stereo constants - -*******************************************************************************/ - -#ifndef PS_CONST_H -#define PS_CONST_H - -#define MAX_PS_CHANNELS (2) -#define HYBRID_MAX_QMF_BANDS (3) -#define HYBRID_FILTER_LENGTH (13) -#define HYBRID_FILTER_DELAY ((HYBRID_FILTER_LENGTH - 1) / 2) - -#define HYBRID_FRAMESIZE (32) -#define HYBRID_READ_OFFSET (10) - -#define MAX_HYBRID_BANDS ((64 - HYBRID_MAX_QMF_BANDS + 10)) - -typedef enum { - PS_RES_COARSE = 0, - PS_RES_MID = 1, - PS_RES_FINE = 2 -} PS_RESOLUTION; - -typedef enum { - PS_BANDS_COARSE = 10, - PS_BANDS_MID = 20, - PS_MAX_BANDS = PS_BANDS_MID -} PS_BANDS; - -typedef enum { PS_IID_RES_COARSE = 0, PS_IID_RES_FINE } PS_IID_RESOLUTION; - -typedef enum { PS_ICC_ROT_A = 0, PS_ICC_ROT_B } PS_ICC_ROTATION_MODE; - -typedef enum { PS_DELTA_FREQ, PS_DELTA_TIME } PS_DELTA; - -typedef enum { - PS_MAX_ENVELOPES = 4 - -} PS_CONSTS; - -typedef enum { - PSENC_OK = 0x0000, /*!< No error happened. All fine. */ - PSENC_INVALID_HANDLE = - 0x0020, /*!< Handle passed to function call was invalid. */ - PSENC_MEMORY_ERROR = 0x0021, /*!< Memory allocation failed. */ - PSENC_INIT_ERROR = 0x0040, /*!< General initialization error. */ - PSENC_ENCODE_ERROR = 0x0060 /*!< The encoding process was interrupted by an - unexpected error. */ - -} FDK_PSENC_ERROR; - -#endif --- a/libSBRenc/src/ps_encode.cpp +++ /dev/null @@ -1,1031 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): M. Neuendorf, N. Rettelbach, M. Multrus - - Description: PS parameter extraction, encoding - -*******************************************************************************/ - -/*! - \file - \brief PS parameter extraction, encoding functions $Revision: 96441 $ -*/ - -#include "ps_main.h" -#include "ps_encode.h" -#include "qmf.h" -#include "sbr_misc.h" -#include "sbrenc_ram.h" - -#include "genericStds.h" - -inline void FDKsbrEnc_addFIXP_DBL(const FIXP_DBL *X, const FIXP_DBL *Y, - FIXP_DBL *Z, INT n) { - for (INT i = 0; i < n; i++) Z[i] = (X[i] >> 1) + (Y[i] >> 1); -} - -#define LOG10_2_10 3.01029995664f /* 10.0f*log10(2.f) */ - -static const INT - iidGroupBordersLoRes[QMF_GROUPS_LO_RES + SUBQMF_GROUPS_LO_RES + 1] = { - 0, 1, 2, 3, 4, 5, /* 6 subqmf subbands - 0th qmf subband */ - 6, 7, /* 2 subqmf subbands - 1st qmf subband */ - 8, 9, /* 2 subqmf subbands - 2nd qmf subband */ - 10, 11, 12, 13, 14, 15, 16, 18, 21, 25, 30, 42, 71}; - -static const UCHAR - iidGroupWidthLdLoRes[QMF_GROUPS_LO_RES + SUBQMF_GROUPS_LO_RES] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 4, 5}; - -static const INT subband2parameter20[QMF_GROUPS_LO_RES + SUBQMF_GROUPS_LO_RES] = - {1, 0, 0, 1, 2, 3, /* 6 subqmf subbands - 0th qmf subband */ - 4, 5, /* 2 subqmf subbands - 1st qmf subband */ - 6, 7, /* 2 subqmf subbands - 2nd qmf subband */ - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; - -typedef enum { - MAX_TIME_DIFF_FRAMES = 20, - MAX_PS_NOHEADER_CNT = 10, - MAX_NOENV_CNT = 10, - DO_NOT_USE_THIS_MODE = 0x7FFFFF -} __PS_CONSTANTS; - -static const FIXP_DBL iidQuant_fx[15] = { - (FIXP_DBL)0xce000000, (FIXP_DBL)0xdc000000, (FIXP_DBL)0xe4000000, - (FIXP_DBL)0xec000000, (FIXP_DBL)0xf2000000, (FIXP_DBL)0xf8000000, - (FIXP_DBL)0xfc000000, (FIXP_DBL)0x00000000, (FIXP_DBL)0x04000000, - (FIXP_DBL)0x08000000, (FIXP_DBL)0x0e000000, (FIXP_DBL)0x14000000, - (FIXP_DBL)0x1c000000, (FIXP_DBL)0x24000000, (FIXP_DBL)0x32000000}; - -static const FIXP_DBL iidQuantFine_fx[31] = { - (FIXP_DBL)0x9c000001, (FIXP_DBL)0xa6000001, (FIXP_DBL)0xb0000001, - (FIXP_DBL)0xba000001, (FIXP_DBL)0xc4000000, (FIXP_DBL)0xce000000, - (FIXP_DBL)0xd4000000, (FIXP_DBL)0xda000000, (FIXP_DBL)0xe0000000, - (FIXP_DBL)0xe6000000, (FIXP_DBL)0xec000000, (FIXP_DBL)0xf0000000, - (FIXP_DBL)0xf4000000, (FIXP_DBL)0xf8000000, (FIXP_DBL)0xfc000000, - (FIXP_DBL)0x00000000, (FIXP_DBL)0x04000000, (FIXP_DBL)0x08000000, - (FIXP_DBL)0x0c000000, (FIXP_DBL)0x10000000, (FIXP_DBL)0x14000000, - (FIXP_DBL)0x1a000000, (FIXP_DBL)0x20000000, (FIXP_DBL)0x26000000, - (FIXP_DBL)0x2c000000, (FIXP_DBL)0x32000000, (FIXP_DBL)0x3c000000, - (FIXP_DBL)0x45ffffff, (FIXP_DBL)0x4fffffff, (FIXP_DBL)0x59ffffff, - (FIXP_DBL)0x63ffffff}; - -static const FIXP_DBL iccQuant[8] = { - (FIXP_DBL)0x7fffffff, (FIXP_DBL)0x77ef9d7f, (FIXP_DBL)0x6babc97f, - (FIXP_DBL)0x4ceaf27f, (FIXP_DBL)0x2f0ed3c0, (FIXP_DBL)0x00000000, - (FIXP_DBL)0xb49ba601, (FIXP_DBL)0x80000000}; - -static FDK_PSENC_ERROR InitPSData(HANDLE_PS_DATA hPsData) { - FDK_PSENC_ERROR error = PSENC_OK; - - if (hPsData == NULL) { - error = PSENC_INVALID_HANDLE; - } else { - int i, env; - FDKmemclear(hPsData, sizeof(PS_DATA)); - - for (i = 0; i < PS_MAX_BANDS; i++) { - hPsData->iidIdxLast[i] = 0; - hPsData->iccIdxLast[i] = 0; - } - - hPsData->iidEnable = hPsData->iidEnableLast = 0; - hPsData->iccEnable = hPsData->iccEnableLast = 0; - hPsData->iidQuantMode = hPsData->iidQuantModeLast = PS_IID_RES_COARSE; - hPsData->iccQuantMode = hPsData->iccQuantModeLast = PS_ICC_ROT_A; - - for (env = 0; env < PS_MAX_ENVELOPES; env++) { - hPsData->iccDiffMode[env] = PS_DELTA_FREQ; - hPsData->iccDiffMode[env] = PS_DELTA_FREQ; - - for (i = 0; i < PS_MAX_BANDS; i++) { - hPsData->iidIdx[env][i] = 0; - hPsData->iccIdx[env][i] = 0; - } - } - - hPsData->nEnvelopesLast = 0; - - hPsData->headerCnt = MAX_PS_NOHEADER_CNT; - hPsData->iidTimeCnt = MAX_TIME_DIFF_FRAMES; - hPsData->iccTimeCnt = MAX_TIME_DIFF_FRAMES; - hPsData->noEnvCnt = MAX_NOENV_CNT; - } - - return error; -} - -static FIXP_DBL quantizeCoef(const FIXP_DBL *RESTRICT input, const INT nBands, - const FIXP_DBL *RESTRICT quantTable, - const INT idxOffset, const INT nQuantSteps, - INT *RESTRICT quantOut) { - INT idx, band; - FIXP_DBL quantErr = FL2FXCONST_DBL(0.f); - - for (band = 0; band < nBands; band++) { - for (idx = 0; idx < nQuantSteps - 1; idx++) { - if (fixp_abs((input[band] >> 1) - (quantTable[idx + 1] >> 1)) > - fixp_abs((input[band] >> 1) - (quantTable[idx] >> 1))) { - break; - } - } - quantErr += (fixp_abs(input[band] - quantTable[idx]) >> - PS_QUANT_SCALE); /* don't scale before subtraction; diff - smaller (64-25)/64 */ - quantOut[band] = idx - idxOffset; - } - - return quantErr; -} - -static INT getICCMode(const INT nBands, const INT rotType) { - INT mode = 0; - - switch (nBands) { - case PS_BANDS_COARSE: - mode = PS_RES_COARSE; - break; - case PS_BANDS_MID: - mode = PS_RES_MID; - break; - default: - mode = 0; - } - if (rotType == PS_ICC_ROT_B) { - mode += 3; - } - - return mode; -} - -static INT getIIDMode(const INT nBands, const INT iidRes) { - INT mode = 0; - - switch (nBands) { - case PS_BANDS_COARSE: - mode = PS_RES_COARSE; - break; - case PS_BANDS_MID: - mode = PS_RES_MID; - break; - default: - mode = 0; - break; - } - - if (iidRes == PS_IID_RES_FINE) { - mode += 3; - } - - return mode; -} - -static INT envelopeReducible(FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS], - FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS], - INT psBands, INT nEnvelopes) { -#define THRESH_SCALE 7 - - INT reducible = 1; /* true */ - INT e = 0, b = 0; - FIXP_DBL dIid = FL2FXCONST_DBL(0.f); - FIXP_DBL dIcc = FL2FXCONST_DBL(0.f); - - FIXP_DBL iidErrThreshold, iccErrThreshold; - FIXP_DBL iidMeanError, iccMeanError; - - /* square values to prevent sqrt, - multiply bands to prevent division; bands shifted DFRACT_BITS instead - (DFRACT_BITS-1) because fMultDiv2 used*/ - iidErrThreshold = - fMultDiv2(FL2FXCONST_DBL(6.5f * 6.5f / (IID_SCALE_FT * IID_SCALE_FT)), - (FIXP_DBL)(psBands << ((DFRACT_BITS)-THRESH_SCALE))); - iccErrThreshold = - fMultDiv2(FL2FXCONST_DBL(0.75f * 0.75f), - (FIXP_DBL)(psBands << ((DFRACT_BITS)-THRESH_SCALE))); - - if (nEnvelopes <= 1) { - reducible = 0; - } else { - /* mean error criterion */ - for (e = 0; (e < nEnvelopes / 2) && (reducible != 0); e++) { - iidMeanError = iccMeanError = FL2FXCONST_DBL(0.f); - for (b = 0; b < psBands; b++) { - dIid = (iid[2 * e][b] >> 1) - - (iid[2 * e + 1][b] >> 1); /* scale 1 bit; squared -> 2 bit */ - dIcc = (icc[2 * e][b] >> 1) - (icc[2 * e + 1][b] >> 1); - iidMeanError += fPow2Div2(dIid) >> (5 - 1); /* + (bands=20) scale = 5 */ - iccMeanError += fPow2Div2(dIcc) >> (5 - 1); - } /* --> scaling = 7 bit = THRESH_SCALE !! */ - - /* instead sqrt values are squared! - instead of division, multiply threshold with psBands - scaling necessary!! */ - - /* quit as soon as threshold is reached */ - if ((iidMeanError > (iidErrThreshold)) || - (iccMeanError > (iccErrThreshold))) { - reducible = 0; - } - } - } /* nEnvelopes != 1 */ - - return reducible; -} - -static void processIidData(PS_DATA *psData, - FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS], - const INT psBands, const INT nEnvelopes, - const FIXP_DBL quantErrorThreshold) { - INT iidIdxFine[PS_MAX_ENVELOPES][PS_MAX_BANDS]; - INT iidIdxCoarse[PS_MAX_ENVELOPES][PS_MAX_BANDS]; - - FIXP_DBL errIID = FL2FXCONST_DBL(0.f); - FIXP_DBL errIIDFine = FL2FXCONST_DBL(0.f); - INT bitsIidFreq = 0; - INT bitsIidTime = 0; - INT bitsFineTot = 0; - INT bitsCoarseTot = 0; - INT error = 0; - INT env, band; - INT diffMode[PS_MAX_ENVELOPES], diffModeFine[PS_MAX_ENVELOPES]; - INT loudnDiff = 0; - INT iidTransmit = 0; - - /* Quantize IID coefficients */ - for (env = 0; env < nEnvelopes; env++) { - errIID += - quantizeCoef(iid[env], psBands, iidQuant_fx, 7, 15, iidIdxCoarse[env]); - errIIDFine += quantizeCoef(iid[env], psBands, iidQuantFine_fx, 15, 31, - iidIdxFine[env]); - } - - /* normalize error to number of envelopes, ps bands - errIID /= psBands*nEnvelopes; - errIIDFine /= psBands*nEnvelopes; */ - - /* Check if IID coefficients should be used in this frame */ - psData->iidEnable = 0; - for (env = 0; env < nEnvelopes; env++) { - for (band = 0; band < psBands; band++) { - loudnDiff += fixp_abs(iidIdxCoarse[env][band]); - iidTransmit++; - } - } - - if (loudnDiff > - fMultI(FL2FXCONST_DBL(0.7f), iidTransmit)) { /* 0.7f empiric value */ - psData->iidEnable = 1; - } - - /* if iid not active -> RESET data */ - if (psData->iidEnable == 0) { - psData->iidTimeCnt = MAX_TIME_DIFF_FRAMES; - for (env = 0; env < nEnvelopes; env++) { - psData->iidDiffMode[env] = PS_DELTA_FREQ; - FDKmemclear(psData->iidIdx[env], sizeof(INT) * psBands); - } - return; - } - - /* count COARSE quantization bits for first envelope*/ - bitsIidFreq = FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[0], NULL, psBands, - PS_IID_RES_COARSE, PS_DELTA_FREQ, &error); - - if ((psData->iidTimeCnt >= MAX_TIME_DIFF_FRAMES) || - (psData->iidQuantModeLast == PS_IID_RES_FINE)) { - bitsIidTime = DO_NOT_USE_THIS_MODE; - } else { - bitsIidTime = - FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[0], psData->iidIdxLast, psBands, - PS_IID_RES_COARSE, PS_DELTA_TIME, &error); - } - - /* decision DELTA_FREQ vs DELTA_TIME */ - if (bitsIidTime > bitsIidFreq) { - diffMode[0] = PS_DELTA_FREQ; - bitsCoarseTot = bitsIidFreq; - } else { - diffMode[0] = PS_DELTA_TIME; - bitsCoarseTot = bitsIidTime; - } - - /* count COARSE quantization bits for following envelopes*/ - for (env = 1; env < nEnvelopes; env++) { - bitsIidFreq = FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[env], NULL, psBands, - PS_IID_RES_COARSE, PS_DELTA_FREQ, &error); - bitsIidTime = - FDKsbrEnc_EncodeIid(NULL, iidIdxCoarse[env], iidIdxCoarse[env - 1], - psBands, PS_IID_RES_COARSE, PS_DELTA_TIME, &error); - - /* decision DELTA_FREQ vs DELTA_TIME */ - if (bitsIidTime > bitsIidFreq) { - diffMode[env] = PS_DELTA_FREQ; - bitsCoarseTot += bitsIidFreq; - } else { - diffMode[env] = PS_DELTA_TIME; - bitsCoarseTot += bitsIidTime; - } - } - - /* count FINE quantization bits for first envelope*/ - bitsIidFreq = FDKsbrEnc_EncodeIid(NULL, iidIdxFine[0], NULL, psBands, - PS_IID_RES_FINE, PS_DELTA_FREQ, &error); - - if ((psData->iidTimeCnt >= MAX_TIME_DIFF_FRAMES) || - (psData->iidQuantModeLast == PS_IID_RES_COARSE)) { - bitsIidTime = DO_NOT_USE_THIS_MODE; - } else { - bitsIidTime = - FDKsbrEnc_EncodeIid(NULL, iidIdxFine[0], psData->iidIdxLast, psBands, - PS_IID_RES_FINE, PS_DELTA_TIME, &error); - } - - /* decision DELTA_FREQ vs DELTA_TIME */ - if (bitsIidTime > bitsIidFreq) { - diffModeFine[0] = PS_DELTA_FREQ; - bitsFineTot = bitsIidFreq; - } else { - diffModeFine[0] = PS_DELTA_TIME; - bitsFineTot = bitsIidTime; - } - - /* count FINE quantization bits for following envelopes*/ - for (env = 1; env < nEnvelopes; env++) { - bitsIidFreq = FDKsbrEnc_EncodeIid(NULL, iidIdxFine[env], NULL, psBands, - PS_IID_RES_FINE, PS_DELTA_FREQ, &error); - bitsIidTime = - FDKsbrEnc_EncodeIid(NULL, iidIdxFine[env], iidIdxFine[env - 1], psBands, - PS_IID_RES_FINE, PS_DELTA_TIME, &error); - - /* decision DELTA_FREQ vs DELTA_TIME */ - if (bitsIidTime > bitsIidFreq) { - diffModeFine[env] = PS_DELTA_FREQ; - bitsFineTot += bitsIidFreq; - } else { - diffModeFine[env] = PS_DELTA_TIME; - bitsFineTot += bitsIidTime; - } - } - - if (bitsFineTot == bitsCoarseTot) { - /* if same number of bits is needed, use the quantization with lower error - */ - if (errIIDFine < errIID) { - bitsCoarseTot = DO_NOT_USE_THIS_MODE; - } else { - bitsFineTot = DO_NOT_USE_THIS_MODE; - } - } else { - /* const FIXP_DBL minThreshold = - * FL2FXCONST_DBL(0.2f/(IID_SCALE_FT*PS_QUANT_SCALE_FT)*(psBands*nEnvelopes)); - */ - const FIXP_DBL minThreshold = - (FIXP_DBL)((LONG)0x00019999 * (psBands * nEnvelopes)); - - /* decision RES_FINE vs RES_COARSE */ - /* test if errIIDFine*quantErrorThreshold < errIID */ - /* shiftVal 2 comes from scaling of quantErrorThreshold */ - if (fixMax(((errIIDFine >> 1) + (minThreshold >> 1)) >> 1, - fMult(quantErrorThreshold, errIIDFine)) < (errIID >> 2)) { - bitsCoarseTot = DO_NOT_USE_THIS_MODE; - } else if (fixMax(((errIID >> 1) + (minThreshold >> 1)) >> 1, - fMult(quantErrorThreshold, errIID)) < (errIIDFine >> 2)) { - bitsFineTot = DO_NOT_USE_THIS_MODE; - } - } - - /* decision RES_FINE vs RES_COARSE */ - if (bitsFineTot < bitsCoarseTot) { - psData->iidQuantMode = PS_IID_RES_FINE; - for (env = 0; env < nEnvelopes; env++) { - psData->iidDiffMode[env] = diffModeFine[env]; - FDKmemcpy(psData->iidIdx[env], iidIdxFine[env], psBands * sizeof(INT)); - } - } else { - psData->iidQuantMode = PS_IID_RES_COARSE; - for (env = 0; env < nEnvelopes; env++) { - psData->iidDiffMode[env] = diffMode[env]; - FDKmemcpy(psData->iidIdx[env], iidIdxCoarse[env], psBands * sizeof(INT)); - } - } - - /* Count DELTA_TIME encoding streaks */ - for (env = 0; env < nEnvelopes; env++) { - if (psData->iidDiffMode[env] == PS_DELTA_TIME) - psData->iidTimeCnt++; - else - psData->iidTimeCnt = 0; - } -} - -static INT similarIid(PS_DATA *psData, const INT psBands, - const INT nEnvelopes) { - const INT diffThr = (psData->iidQuantMode == PS_IID_RES_COARSE) ? 2 : 3; - const INT sumDiffThr = diffThr * psBands / 4; - INT similar = 0; - INT diff = 0; - INT sumDiff = 0; - INT env = 0; - INT b = 0; - if ((nEnvelopes == psData->nEnvelopesLast) && (nEnvelopes == 1)) { - similar = 1; - for (env = 0; env < nEnvelopes; env++) { - sumDiff = 0; - b = 0; - do { - diff = fixp_abs(psData->iidIdx[env][b] - psData->iidIdxLast[b]); - sumDiff += diff; - if ((diff > diffThr) /* more than x quantization steps in any band */ - || (sumDiff > sumDiffThr)) { /* more than x quantisations steps - overall difference */ - similar = 0; - } - b++; - } while ((b < psBands) && (similar > 0)); - } - } /* nEnvelopes==1 */ - - return similar; -} - -static INT similarIcc(PS_DATA *psData, const INT psBands, - const INT nEnvelopes) { - const INT diffThr = 2; - const INT sumDiffThr = diffThr * psBands / 4; - INT similar = 0; - INT diff = 0; - INT sumDiff = 0; - INT env = 0; - INT b = 0; - if ((nEnvelopes == psData->nEnvelopesLast) && (nEnvelopes == 1)) { - similar = 1; - for (env = 0; env < nEnvelopes; env++) { - sumDiff = 0; - b = 0; - do { - diff = fixp_abs(psData->iccIdx[env][b] - psData->iccIdxLast[b]); - sumDiff += diff; - if ((diff > diffThr) /* more than x quantisation step in any band */ - || (sumDiff > sumDiffThr)) { /* more than x quantisations steps - overall difference */ - similar = 0; - } - b++; - } while ((b < psBands) && (similar > 0)); - } - } /* nEnvelopes==1 */ - - return similar; -} - -static void processIccData( - PS_DATA *psData, - FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS], /* const input values: - unable to declare as - const, since it does - not poINT to const - memory */ - const INT psBands, const INT nEnvelopes) { - FIXP_DBL errICC = FL2FXCONST_DBL(0.f); - INT env, band; - INT bitsIccFreq, bitsIccTime; - INT error = 0; - INT inCoherence = 0, iccTransmit = 0; - INT *iccIdxLast; - - iccIdxLast = psData->iccIdxLast; - - /* Quantize ICC coefficients */ - for (env = 0; env < nEnvelopes; env++) { - errICC += - quantizeCoef(icc[env], psBands, iccQuant, 0, 8, psData->iccIdx[env]); - } - - /* Check if ICC coefficients should be used */ - psData->iccEnable = 0; - for (env = 0; env < nEnvelopes; env++) { - for (band = 0; band < psBands; band++) { - inCoherence += psData->iccIdx[env][band]; - iccTransmit++; - } - } - if (inCoherence > - fMultI(FL2FXCONST_DBL(0.5f), iccTransmit)) { /* 0.5f empiric value */ - psData->iccEnable = 1; - } - - if (psData->iccEnable == 0) { - psData->iccTimeCnt = MAX_TIME_DIFF_FRAMES; - for (env = 0; env < nEnvelopes; env++) { - psData->iccDiffMode[env] = PS_DELTA_FREQ; - FDKmemclear(psData->iccIdx[env], sizeof(INT) * psBands); - } - return; - } - - for (env = 0; env < nEnvelopes; env++) { - bitsIccFreq = FDKsbrEnc_EncodeIcc(NULL, psData->iccIdx[env], NULL, psBands, - PS_DELTA_FREQ, &error); - - if (psData->iccTimeCnt < MAX_TIME_DIFF_FRAMES) { - bitsIccTime = FDKsbrEnc_EncodeIcc(NULL, psData->iccIdx[env], iccIdxLast, - psBands, PS_DELTA_TIME, &error); - } else { - bitsIccTime = DO_NOT_USE_THIS_MODE; - } - - if (bitsIccFreq > bitsIccTime) { - psData->iccDiffMode[env] = PS_DELTA_TIME; - psData->iccTimeCnt++; - } else { - psData->iccDiffMode[env] = PS_DELTA_FREQ; - psData->iccTimeCnt = 0; - } - iccIdxLast = psData->iccIdx[env]; - } -} - -static void calculateIID(FIXP_DBL ldPwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS], - FIXP_DBL ldPwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS], - FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS], - INT nEnvelopes, INT psBands) { - INT i = 0; - INT env = 0; - for (env = 0; env < nEnvelopes; env++) { - for (i = 0; i < psBands; i++) { - /* iid[env][i] = 10.0f*(float)log10(pwrL[env][i]/pwrR[env][i]); - */ - FIXP_DBL IID = fMultDiv2(FL2FXCONST_DBL(LOG10_2_10 / IID_SCALE_FT), - (ldPwrL[env][i] - ldPwrR[env][i])); - - IID = fixMin(IID, (FIXP_DBL)(MAXVAL_DBL >> (LD_DATA_SHIFT + 1))); - IID = fixMax(IID, (FIXP_DBL)(MINVAL_DBL >> (LD_DATA_SHIFT + 1))); - iid[env][i] = IID << (LD_DATA_SHIFT + 1); - } - } -} - -static void calculateICC(FIXP_DBL pwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS], - FIXP_DBL pwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS], - FIXP_DBL pwrCr[PS_MAX_ENVELOPES][PS_MAX_BANDS], - FIXP_DBL pwrCi[PS_MAX_ENVELOPES][PS_MAX_BANDS], - FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS], - INT nEnvelopes, INT psBands) { - INT i = 0; - INT env = 0; - INT border = psBands; - - switch (psBands) { - case PS_BANDS_COARSE: - border = 5; - break; - case PS_BANDS_MID: - border = 11; - break; - default: - break; - } - - for (env = 0; env < nEnvelopes; env++) { - for (i = 0; i < border; i++) { - /* icc[env][i] = min( pwrCr[env][i] / (float) sqrt(pwrL[env][i] * - * pwrR[env][i]) , 1.f); - */ - int scale; - FIXP_DBL invNrg = invSqrtNorm2( - fMax(fMult(pwrL[env][i], pwrR[env][i]), (FIXP_DBL)1), &scale); - icc[env][i] = - SATURATE_LEFT_SHIFT(fMult(pwrCr[env][i], invNrg), scale, DFRACT_BITS); - } - - for (; i < psBands; i++) { - int denom_e; - FIXP_DBL denom_m = fMultNorm(pwrL[env][i], pwrR[env][i], &denom_e); - - if (denom_m == (FIXP_DBL)0) { - icc[env][i] = (FIXP_DBL)MAXVAL_DBL; - } else { - int num_e, result_e; - FIXP_DBL num_m, result_m; - - num_e = CountLeadingBits( - fixMax(fixp_abs(pwrCr[env][i]), fixp_abs(pwrCi[env][i]))); - num_m = fPow2Div2((pwrCr[env][i] << num_e)) + - fPow2Div2((pwrCi[env][i] << num_e)); - - result_m = fDivNorm(num_m, denom_m, &result_e); - result_e += (-2 * num_e + 1) - denom_e; - icc[env][i] = scaleValueSaturate(sqrtFixp(result_m >> (result_e & 1)), - (result_e + (result_e & 1)) >> 1); - } - } - } -} - -void FDKsbrEnc_initPsBandNrgScale(HANDLE_PS_ENCODE hPsEncode) { - INT group, bin; - INT nIidGroups = hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups; - - FDKmemclear(hPsEncode->psBandNrgScale, PS_MAX_BANDS * sizeof(SCHAR)); - - for (group = 0; group < nIidGroups; group++) { - /* Translate group to bin */ - bin = hPsEncode->subband2parameterIndex[group]; - - /* Translate from 20 bins to 10 bins */ - if (hPsEncode->psEncMode == PS_BANDS_COARSE) { - bin = bin >> 1; - } - - hPsEncode->psBandNrgScale[bin] = - (hPsEncode->psBandNrgScale[bin] == 0) - ? (hPsEncode->iidGroupWidthLd[group] + 5) - : (fixMax(hPsEncode->iidGroupWidthLd[group], - hPsEncode->psBandNrgScale[bin]) + - 1); - } -} - -FDK_PSENC_ERROR FDKsbrEnc_CreatePSEncode(HANDLE_PS_ENCODE *phPsEncode) { - FDK_PSENC_ERROR error = PSENC_OK; - - if (phPsEncode == NULL) { - error = PSENC_INVALID_HANDLE; - } else { - HANDLE_PS_ENCODE hPsEncode = NULL; - if (NULL == (hPsEncode = GetRam_PsEncode())) { - error = PSENC_MEMORY_ERROR; - goto bail; - } - FDKmemclear(hPsEncode, sizeof(PS_ENCODE)); - *phPsEncode = hPsEncode; /* return allocated handle */ - } -bail: - return error; -} - -FDK_PSENC_ERROR FDKsbrEnc_InitPSEncode(HANDLE_PS_ENCODE hPsEncode, - const PS_BANDS psEncMode, - const FIXP_DBL iidQuantErrorThreshold) { - FDK_PSENC_ERROR error = PSENC_OK; - - if (NULL == hPsEncode) { - error = PSENC_INVALID_HANDLE; - } else { - if (PSENC_OK != (InitPSData(&hPsEncode->psData))) { - goto bail; - } - - switch (psEncMode) { - case PS_BANDS_COARSE: - case PS_BANDS_MID: - hPsEncode->nQmfIidGroups = QMF_GROUPS_LO_RES; - hPsEncode->nSubQmfIidGroups = SUBQMF_GROUPS_LO_RES; - FDKmemcpy(hPsEncode->iidGroupBorders, iidGroupBordersLoRes, - (hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups + 1) * - sizeof(INT)); - FDKmemcpy(hPsEncode->subband2parameterIndex, subband2parameter20, - (hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups) * - sizeof(INT)); - FDKmemcpy(hPsEncode->iidGroupWidthLd, iidGroupWidthLdLoRes, - (hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups) * - sizeof(UCHAR)); - break; - default: - error = PSENC_INIT_ERROR; - goto bail; - } - - hPsEncode->psEncMode = psEncMode; - hPsEncode->iidQuantErrorThreshold = iidQuantErrorThreshold; - FDKsbrEnc_initPsBandNrgScale(hPsEncode); - } -bail: - return error; -} - -FDK_PSENC_ERROR FDKsbrEnc_DestroyPSEncode(HANDLE_PS_ENCODE *phPsEncode) { - FDK_PSENC_ERROR error = PSENC_OK; - - if (NULL != phPsEncode) { - FreeRam_PsEncode(phPsEncode); - } - - return error; -} - -typedef struct { - FIXP_DBL pwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS]; - FIXP_DBL pwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS]; - FIXP_DBL ldPwrL[PS_MAX_ENVELOPES][PS_MAX_BANDS]; - FIXP_DBL ldPwrR[PS_MAX_ENVELOPES][PS_MAX_BANDS]; - FIXP_DBL pwrCr[PS_MAX_ENVELOPES][PS_MAX_BANDS]; - FIXP_DBL pwrCi[PS_MAX_ENVELOPES][PS_MAX_BANDS]; - -} PS_PWR_DATA; - -FDK_PSENC_ERROR FDKsbrEnc_PSEncode( - HANDLE_PS_ENCODE hPsEncode, HANDLE_PS_OUT hPsOut, UCHAR *dynBandScale, - UINT maxEnvelopes, - FIXP_DBL *hybridData[HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2], - const INT frameSize, const INT sendHeader) { - FDK_PSENC_ERROR error = PSENC_OK; - - HANDLE_PS_DATA hPsData = &hPsEncode->psData; - FIXP_DBL iid[PS_MAX_ENVELOPES][PS_MAX_BANDS]; - FIXP_DBL icc[PS_MAX_ENVELOPES][PS_MAX_BANDS]; - int envBorder[PS_MAX_ENVELOPES + 1]; - - int group, bin, col, subband, band; - int i = 0; - - int env = 0; - int psBands = (int)hPsEncode->psEncMode; - int nIidGroups = hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups; - int nEnvelopes = fixMin(maxEnvelopes, (UINT)PS_MAX_ENVELOPES); - - C_ALLOC_SCRATCH_START(pwrData, PS_PWR_DATA, 1) - - for (env = 0; env < nEnvelopes + 1; env++) { - envBorder[env] = fMultI(GetInvInt(nEnvelopes), frameSize * env); - } - - for (env = 0; env < nEnvelopes; env++) { - /* clear energy array */ - for (band = 0; band < psBands; band++) { - pwrData->pwrL[env][band] = pwrData->pwrR[env][band] = - pwrData->pwrCr[env][band] = pwrData->pwrCi[env][band] = FIXP_DBL(1); - } - - /**** calculate energies and correlation ****/ - - /* start with hybrid data */ - for (group = 0; group < nIidGroups; group++) { - /* Translate group to bin */ - bin = hPsEncode->subband2parameterIndex[group]; - - /* Translate from 20 bins to 10 bins */ - if (hPsEncode->psEncMode == PS_BANDS_COARSE) { - bin >>= 1; - } - - /* determine group border */ - int bScale = hPsEncode->psBandNrgScale[bin]; - - FIXP_DBL pwrL_env_bin = pwrData->pwrL[env][bin]; - FIXP_DBL pwrR_env_bin = pwrData->pwrR[env][bin]; - FIXP_DBL pwrCr_env_bin = pwrData->pwrCr[env][bin]; - FIXP_DBL pwrCi_env_bin = pwrData->pwrCi[env][bin]; - - int scale = (int)dynBandScale[bin]; - for (col = envBorder[env]; col < envBorder[env + 1]; col++) { - for (subband = hPsEncode->iidGroupBorders[group]; - subband < hPsEncode->iidGroupBorders[group + 1]; subband++) { - FIXP_DBL l_real = (hybridData[col][0][0][subband]) << scale; - FIXP_DBL l_imag = (hybridData[col][0][1][subband]) << scale; - FIXP_DBL r_real = (hybridData[col][1][0][subband]) << scale; - FIXP_DBL r_imag = (hybridData[col][1][1][subband]) << scale; - - pwrL_env_bin += (fPow2Div2(l_real) + fPow2Div2(l_imag)) >> bScale; - pwrR_env_bin += (fPow2Div2(r_real) + fPow2Div2(r_imag)) >> bScale; - pwrCr_env_bin += - (fMultDiv2(l_real, r_real) + fMultDiv2(l_imag, r_imag)) >> bScale; - pwrCi_env_bin += - (fMultDiv2(r_real, l_imag) - fMultDiv2(l_real, r_imag)) >> bScale; - } - } - /* assure, nrg's of left and right channel are not negative; necessary on - * 16 bit multiply units */ - pwrData->pwrL[env][bin] = fixMax((FIXP_DBL)0, pwrL_env_bin); - pwrData->pwrR[env][bin] = fixMax((FIXP_DBL)0, pwrR_env_bin); - - pwrData->pwrCr[env][bin] = pwrCr_env_bin; - pwrData->pwrCi[env][bin] = pwrCi_env_bin; - - } /* nIidGroups */ - - /* calc logarithmic energy */ - LdDataVector(pwrData->pwrL[env], pwrData->ldPwrL[env], psBands); - LdDataVector(pwrData->pwrR[env], pwrData->ldPwrR[env], psBands); - - } /* nEnvelopes */ - - /* calculate iid and icc */ - calculateIID(pwrData->ldPwrL, pwrData->ldPwrR, iid, nEnvelopes, psBands); - calculateICC(pwrData->pwrL, pwrData->pwrR, pwrData->pwrCr, pwrData->pwrCi, - icc, nEnvelopes, psBands); - - /*** Envelope Reduction ***/ - while (envelopeReducible(iid, icc, psBands, nEnvelopes)) { - int e = 0; - /* sum energies of two neighboring envelopes */ - nEnvelopes >>= 1; - for (e = 0; e < nEnvelopes; e++) { - FDKsbrEnc_addFIXP_DBL(pwrData->pwrL[2 * e], pwrData->pwrL[2 * e + 1], - pwrData->pwrL[e], psBands); - FDKsbrEnc_addFIXP_DBL(pwrData->pwrR[2 * e], pwrData->pwrR[2 * e + 1], - pwrData->pwrR[e], psBands); - FDKsbrEnc_addFIXP_DBL(pwrData->pwrCr[2 * e], pwrData->pwrCr[2 * e + 1], - pwrData->pwrCr[e], psBands); - FDKsbrEnc_addFIXP_DBL(pwrData->pwrCi[2 * e], pwrData->pwrCi[2 * e + 1], - pwrData->pwrCi[e], psBands); - - /* calc logarithmic energy */ - LdDataVector(pwrData->pwrL[e], pwrData->ldPwrL[e], psBands); - LdDataVector(pwrData->pwrR[e], pwrData->ldPwrR[e], psBands); - - /* reduce number of envelopes and adjust borders */ - envBorder[e] = envBorder[2 * e]; - } - envBorder[nEnvelopes] = envBorder[2 * nEnvelopes]; - - /* re-calculate iid and icc */ - calculateIID(pwrData->ldPwrL, pwrData->ldPwrR, iid, nEnvelopes, psBands); - calculateICC(pwrData->pwrL, pwrData->pwrR, pwrData->pwrCr, pwrData->pwrCi, - icc, nEnvelopes, psBands); - } - - /* */ - if (sendHeader) { - hPsData->headerCnt = MAX_PS_NOHEADER_CNT; - hPsData->iidTimeCnt = MAX_TIME_DIFF_FRAMES; - hPsData->iccTimeCnt = MAX_TIME_DIFF_FRAMES; - hPsData->noEnvCnt = MAX_NOENV_CNT; - } - - /*** Parameter processing, quantisation etc ***/ - processIidData(hPsData, iid, psBands, nEnvelopes, - hPsEncode->iidQuantErrorThreshold); - processIccData(hPsData, icc, psBands, nEnvelopes); - - /*** Initialize output struct ***/ - - /* PS Header on/off ? */ - if ((hPsData->headerCnt < MAX_PS_NOHEADER_CNT) && - ((hPsData->iidQuantMode == hPsData->iidQuantModeLast) && - (hPsData->iccQuantMode == hPsData->iccQuantModeLast)) && - ((hPsData->iidEnable == hPsData->iidEnableLast) && - (hPsData->iccEnable == hPsData->iccEnableLast))) { - hPsOut->enablePSHeader = 0; - } else { - hPsOut->enablePSHeader = 1; - hPsData->headerCnt = 0; - } - - /* nEnvelopes = 0 ? */ - if ((hPsData->noEnvCnt < MAX_NOENV_CNT) && - (similarIid(hPsData, psBands, nEnvelopes)) && - (similarIcc(hPsData, psBands, nEnvelopes))) { - hPsOut->nEnvelopes = nEnvelopes = 0; - hPsData->noEnvCnt++; - } else { - hPsData->noEnvCnt = 0; - } - - if (nEnvelopes > 0) { - hPsOut->enableIID = hPsData->iidEnable; - hPsOut->iidMode = getIIDMode(psBands, hPsData->iidQuantMode); - - hPsOut->enableICC = hPsData->iccEnable; - hPsOut->iccMode = getICCMode(psBands, hPsData->iccQuantMode); - - hPsOut->enableIpdOpd = 0; - hPsOut->frameClass = 0; - hPsOut->nEnvelopes = nEnvelopes; - - for (env = 0; env < nEnvelopes; env++) { - hPsOut->frameBorder[env] = envBorder[env + 1]; - hPsOut->deltaIID[env] = (PS_DELTA)hPsData->iidDiffMode[env]; - hPsOut->deltaICC[env] = (PS_DELTA)hPsData->iccDiffMode[env]; - for (band = 0; band < psBands; band++) { - hPsOut->iid[env][band] = hPsData->iidIdx[env][band]; - hPsOut->icc[env][band] = hPsData->iccIdx[env][band]; - } - } - - /* IPD OPD not supported right now */ - FDKmemclear(hPsOut->ipd, - PS_MAX_ENVELOPES * PS_MAX_BANDS * sizeof(PS_DELTA)); - for (env = 0; env < PS_MAX_ENVELOPES; env++) { - hPsOut->deltaIPD[env] = PS_DELTA_FREQ; - hPsOut->deltaOPD[env] = PS_DELTA_FREQ; - } - - FDKmemclear(hPsOut->ipdLast, PS_MAX_BANDS * sizeof(INT)); - FDKmemclear(hPsOut->opdLast, PS_MAX_BANDS * sizeof(INT)); - - for (band = 0; band < PS_MAX_BANDS; band++) { - hPsOut->iidLast[band] = hPsData->iidIdxLast[band]; - hPsOut->iccLast[band] = hPsData->iccIdxLast[band]; - } - - /* save iids and iccs for differential time coding in the next frame */ - hPsData->nEnvelopesLast = nEnvelopes; - hPsData->iidEnableLast = hPsData->iidEnable; - hPsData->iccEnableLast = hPsData->iccEnable; - hPsData->iidQuantModeLast = hPsData->iidQuantMode; - hPsData->iccQuantModeLast = hPsData->iccQuantMode; - for (i = 0; i < psBands; i++) { - hPsData->iidIdxLast[i] = hPsData->iidIdx[nEnvelopes - 1][i]; - hPsData->iccIdxLast[i] = hPsData->iccIdx[nEnvelopes - 1][i]; - } - } /* Envelope > 0 */ - - C_ALLOC_SCRATCH_END(pwrData, PS_PWR_DATA, 1) - - return error; -} --- a/libSBRenc/src/ps_encode.h +++ /dev/null @@ -1,185 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): M. Neuendorf, N. Rettelbach, M. Multrus - - Description: PS Parameter extraction, encoding - -*******************************************************************************/ - -/*! - \file - \brief PS parameter extraction, encoding functions $Revision: 92790 $ -*/ - -#ifndef PS_ENCODE_H -#define PS_ENCODE_H - -#include "ps_const.h" -#include "ps_bitenc.h" - -#define IID_SCALE_FT (64.f) /* maxVal in Quant tab is +/- 50 */ -#define IID_SCALE 6 /* maxVal in Quant tab is +/- 50 */ -#define IID_MAXVAL (1 << IID_SCALE) - -#define PS_QUANT_SCALE_FT \ - (64.f) /* error smaller (64-25)/64 * 20 bands * 4 env -> QuantScale 64 */ -#define PS_QUANT_SCALE \ - 6 /* error smaller (64-25)/64 * 20 bands * 4 env -> QuantScale 6 bit */ - -#define QMF_GROUPS_LO_RES 12 -#define SUBQMF_GROUPS_LO_RES 10 -#define QMF_GROUPS_HI_RES 18 -#define SUBQMF_GROUPS_HI_RES 30 - -typedef struct T_PS_DATA { - INT iidEnable; - INT iidEnableLast; - INT iidQuantMode; - INT iidQuantModeLast; - INT iidDiffMode[PS_MAX_ENVELOPES]; - INT iidIdx[PS_MAX_ENVELOPES][PS_MAX_BANDS]; - INT iidIdxLast[PS_MAX_BANDS]; - - INT iccEnable; - INT iccEnableLast; - INT iccQuantMode; - INT iccQuantModeLast; - INT iccDiffMode[PS_MAX_ENVELOPES]; - INT iccIdx[PS_MAX_ENVELOPES][PS_MAX_BANDS]; - INT iccIdxLast[PS_MAX_BANDS]; - - INT nEnvelopesLast; - - INT headerCnt; - INT iidTimeCnt; - INT iccTimeCnt; - INT noEnvCnt; - -} PS_DATA, *HANDLE_PS_DATA; - -typedef struct T_PS_ENCODE { - PS_DATA psData; - - PS_BANDS psEncMode; - INT nQmfIidGroups; - INT nSubQmfIidGroups; - INT iidGroupBorders[QMF_GROUPS_HI_RES + SUBQMF_GROUPS_HI_RES + 1]; - INT subband2parameterIndex[QMF_GROUPS_HI_RES + SUBQMF_GROUPS_HI_RES]; - UCHAR iidGroupWidthLd[QMF_GROUPS_HI_RES + SUBQMF_GROUPS_HI_RES]; - FIXP_DBL iidQuantErrorThreshold; - - UCHAR psBandNrgScale[PS_MAX_BANDS]; - -} PS_ENCODE; - -typedef struct T_PS_ENCODE *HANDLE_PS_ENCODE; - -FDK_PSENC_ERROR FDKsbrEnc_CreatePSEncode(HANDLE_PS_ENCODE *phPsEncode); - -FDK_PSENC_ERROR FDKsbrEnc_InitPSEncode(HANDLE_PS_ENCODE hPsEncode, - const PS_BANDS psEncMode, - const FIXP_DBL iidQuantErrorThreshold); - -FDK_PSENC_ERROR FDKsbrEnc_DestroyPSEncode(HANDLE_PS_ENCODE *phPsEncode); - -FDK_PSENC_ERROR FDKsbrEnc_PSEncode( - HANDLE_PS_ENCODE hPsEncode, HANDLE_PS_OUT hPsOut, UCHAR *dynBandScale, - UINT maxEnvelopes, - FIXP_DBL *hybridData[HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2], - const INT frameSize, const INT sendHeader); - -#endif --- a/libSBRenc/src/ps_main.cpp +++ /dev/null @@ -1,606 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): M. Multrus - - Description: PS Wrapper, Downmix - -*******************************************************************************/ - -#include "ps_main.h" - -/* Includes ******************************************************************/ -#include "ps_bitenc.h" -#include "sbrenc_ram.h" - -/*--------------- function declarations --------------------*/ -static void psFindBestScaling( - HANDLE_PARAMETRIC_STEREO hParametricStereo, - FIXP_DBL *hybridData[HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2], - UCHAR *dynBandScale, FIXP_DBL *maxBandValue, SCHAR *dmxScale); - -/*------------- function definitions ----------------*/ -FDK_PSENC_ERROR PSEnc_Create(HANDLE_PARAMETRIC_STEREO *phParametricStereo) { - FDK_PSENC_ERROR error = PSENC_OK; - HANDLE_PARAMETRIC_STEREO hParametricStereo = NULL; - - if (phParametricStereo == NULL) { - error = PSENC_INVALID_HANDLE; - } else { - int i; - - if (NULL == (hParametricStereo = GetRam_ParamStereo())) { - error = PSENC_MEMORY_ERROR; - goto bail; - } - FDKmemclear(hParametricStereo, sizeof(PARAMETRIC_STEREO)); - - if (PSENC_OK != - (error = FDKsbrEnc_CreatePSEncode(&hParametricStereo->hPsEncode))) { - error = PSENC_MEMORY_ERROR; - goto bail; - } - - for (i = 0; i < MAX_PS_CHANNELS; i++) { - if (FDKhybridAnalysisOpen( - &hParametricStereo->fdkHybAnaFilter[i], - hParametricStereo->__staticHybAnaStatesLF[i], - sizeof(hParametricStereo->__staticHybAnaStatesLF[i]), - hParametricStereo->__staticHybAnaStatesHF[i], - sizeof(hParametricStereo->__staticHybAnaStatesHF[i])) != 0) { - error = PSENC_MEMORY_ERROR; - goto bail; - } - } - } - -bail: - if (phParametricStereo != NULL) { - *phParametricStereo = hParametricStereo; /* return allocated handle */ - } - - if (error != PSENC_OK) { - PSEnc_Destroy(phParametricStereo); - } - return error; -} - -FDK_PSENC_ERROR PSEnc_Init(HANDLE_PARAMETRIC_STEREO hParametricStereo, - const HANDLE_PSENC_CONFIG hPsEncConfig, - INT noQmfSlots, INT noQmfBands, UCHAR *dynamic_RAM) { - FDK_PSENC_ERROR error = PSENC_OK; - - if ((NULL == hParametricStereo) || (NULL == hPsEncConfig)) { - error = PSENC_INVALID_HANDLE; - } else { - int ch, i; - - hParametricStereo->initPS = 1; - hParametricStereo->noQmfSlots = noQmfSlots; - hParametricStereo->noQmfBands = noQmfBands; - - /* clear delay lines */ - FDKmemclear(hParametricStereo->qmfDelayLines, - sizeof(hParametricStereo->qmfDelayLines)); - - hParametricStereo->qmfDelayScale = FRACT_BITS - 1; - - /* create configuration for hybrid filter bank */ - for (ch = 0; ch < MAX_PS_CHANNELS; ch++) { - FDKhybridAnalysisInit(&hParametricStereo->fdkHybAnaFilter[ch], - THREE_TO_TEN, 64, 64, 1); - } /* ch */ - - FDKhybridSynthesisInit(&hParametricStereo->fdkHybSynFilter, THREE_TO_TEN, - 64, 64); - - /* determine average delay */ - hParametricStereo->psDelay = - (HYBRID_FILTER_DELAY * hParametricStereo->noQmfBands); - - if ((hPsEncConfig->maxEnvelopes < PSENC_NENV_1) || - (hPsEncConfig->maxEnvelopes > PSENC_NENV_MAX)) { - hPsEncConfig->maxEnvelopes = PSENC_NENV_DEFAULT; - } - hParametricStereo->maxEnvelopes = hPsEncConfig->maxEnvelopes; - - if (PSENC_OK != - (error = FDKsbrEnc_InitPSEncode( - hParametricStereo->hPsEncode, (PS_BANDS)hPsEncConfig->nStereoBands, - hPsEncConfig->iidQuantErrorThreshold))) { - goto bail; - } - - for (ch = 0; ch < MAX_PS_CHANNELS; ch++) { - FIXP_DBL *pDynReal = GetRam_Sbr_envRBuffer(ch, dynamic_RAM); - FIXP_DBL *pDynImag = GetRam_Sbr_envIBuffer(ch, dynamic_RAM); - - for (i = 0; i < HYBRID_FRAMESIZE; i++) { - hParametricStereo->pHybridData[i + HYBRID_READ_OFFSET][ch][0] = - &pDynReal[i * MAX_HYBRID_BANDS]; - hParametricStereo->pHybridData[i + HYBRID_READ_OFFSET][ch][1] = - &pDynImag[i * MAX_HYBRID_BANDS]; - ; - } - - for (i = 0; i < HYBRID_READ_OFFSET; i++) { - hParametricStereo->pHybridData[i][ch][0] = - hParametricStereo->__staticHybridData[i][ch][0]; - hParametricStereo->pHybridData[i][ch][1] = - hParametricStereo->__staticHybridData[i][ch][1]; - } - } /* ch */ - - /* clear static hybrid buffer */ - FDKmemclear(hParametricStereo->__staticHybridData, - sizeof(hParametricStereo->__staticHybridData)); - - /* clear bs buffer */ - FDKmemclear(hParametricStereo->psOut, sizeof(hParametricStereo->psOut)); - - hParametricStereo->psOut[0].enablePSHeader = - 1; /* write ps header in first frame */ - - /* clear scaling buffer */ - FDKmemclear(hParametricStereo->dynBandScale, sizeof(UCHAR) * PS_MAX_BANDS); - FDKmemclear(hParametricStereo->maxBandValue, - sizeof(FIXP_DBL) * PS_MAX_BANDS); - - } /* valid handle */ -bail: - return error; -} - -FDK_PSENC_ERROR PSEnc_Destroy(HANDLE_PARAMETRIC_STEREO *phParametricStereo) { - FDK_PSENC_ERROR error = PSENC_OK; - - if (NULL != phParametricStereo) { - HANDLE_PARAMETRIC_STEREO hParametricStereo = *phParametricStereo; - if (hParametricStereo != NULL) { - FDKsbrEnc_DestroyPSEncode(&hParametricStereo->hPsEncode); - FreeRam_ParamStereo(phParametricStereo); - } - } - - return error; -} - -static FDK_PSENC_ERROR ExtractPSParameters( - HANDLE_PARAMETRIC_STEREO hParametricStereo, const int sendHeader, - FIXP_DBL *hybridData[HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2]) { - FDK_PSENC_ERROR error = PSENC_OK; - - if (hParametricStereo == NULL) { - error = PSENC_INVALID_HANDLE; - } else { - /* call ps encode function */ - if (hParametricStereo->initPS) { - hParametricStereo->psOut[1] = hParametricStereo->psOut[0]; - } - hParametricStereo->psOut[0] = hParametricStereo->psOut[1]; - - if (PSENC_OK != - (error = FDKsbrEnc_PSEncode( - hParametricStereo->hPsEncode, &hParametricStereo->psOut[1], - hParametricStereo->dynBandScale, hParametricStereo->maxEnvelopes, - hybridData, hParametricStereo->noQmfSlots, sendHeader))) { - goto bail; - } - - if (hParametricStereo->initPS) { - hParametricStereo->psOut[0] = hParametricStereo->psOut[1]; - hParametricStereo->initPS = 0; - } - } -bail: - return error; -} - -static FDK_PSENC_ERROR DownmixPSQmfData( - HANDLE_PARAMETRIC_STEREO hParametricStereo, - HANDLE_QMF_FILTER_BANK sbrSynthQmf, FIXP_DBL **RESTRICT mixRealQmfData, - FIXP_DBL **RESTRICT mixImagQmfData, INT_PCM *downsampledOutSignal, - const UINT downsampledOutSignalBufSize, - FIXP_DBL *hybridData[HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2], - const INT noQmfSlots, const INT psQmfScale[MAX_PS_CHANNELS], - SCHAR *qmfScale) { - FDK_PSENC_ERROR error = PSENC_OK; - - if (hParametricStereo == NULL) { - error = PSENC_INVALID_HANDLE; - } else { - int n, k; - C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, 2 * 64) - - /* define scalings */ - int dynQmfScale = fixMax( - 0, hParametricStereo->dmxScale - - 1); /* scale one bit more for addition of left and right */ - int downmixScale = psQmfScale[0] - dynQmfScale; - const FIXP_DBL maxStereoScaleFactor = MAXVAL_DBL; /* 2.f/2.f */ - - for (n = 0; n < noQmfSlots; n++) { - FIXP_DBL tmpHybrid[2][MAX_HYBRID_BANDS]; - - for (k = 0; k < 71; k++) { - int dynScale, sc; /* scaling */ - FIXP_DBL tmpLeftReal, tmpRightReal, tmpLeftImag, tmpRightImag; - FIXP_DBL tmpScaleFactor, stereoScaleFactor; - - tmpLeftReal = hybridData[n][0][0][k]; - tmpLeftImag = hybridData[n][0][1][k]; - tmpRightReal = hybridData[n][1][0][k]; - tmpRightImag = hybridData[n][1][1][k]; - - sc = fixMax( - 0, CntLeadingZeros(fixMax( - fixMax(fixp_abs(tmpLeftReal), fixp_abs(tmpLeftImag)), - fixMax(fixp_abs(tmpRightReal), fixp_abs(tmpRightImag)))) - - 2); - - tmpLeftReal <<= sc; - tmpLeftImag <<= sc; - tmpRightReal <<= sc; - tmpRightImag <<= sc; - dynScale = fixMin(sc - dynQmfScale, DFRACT_BITS - 1); - - /* calc stereo scale factor to avoid loss of energy in bands */ - /* stereo scale factor = min(2.0f, sqrt( (abs(l(k, n)^2 + abs(r(k, n)^2 - * )))/(0.5f*abs(l(k, n) + r(k, n))) )) */ - stereoScaleFactor = fPow2Div2(tmpLeftReal) + fPow2Div2(tmpLeftImag) + - fPow2Div2(tmpRightReal) + fPow2Div2(tmpRightImag); - - /* might be that tmpScaleFactor becomes negative, so fabs(.) */ - tmpScaleFactor = - fixp_abs(stereoScaleFactor + fMult(tmpLeftReal, tmpRightReal) + - fMult(tmpLeftImag, tmpRightImag)); - - /* min(2.0f, sqrt(stereoScaleFactor/(0.5f*tmpScaleFactor))) */ - if ((stereoScaleFactor >> 1) < - fMult(maxStereoScaleFactor, tmpScaleFactor)) { - int sc_num = CountLeadingBits(stereoScaleFactor); - int sc_denum = CountLeadingBits(tmpScaleFactor); - sc = -(sc_num - sc_denum); - - tmpScaleFactor = schur_div((stereoScaleFactor << (sc_num)) >> 1, - tmpScaleFactor << sc_denum, 16); - - /* prevent odd scaling for next sqrt calculation */ - if (sc & 0x1) { - sc++; - tmpScaleFactor >>= 1; - } - stereoScaleFactor = sqrtFixp(tmpScaleFactor); - stereoScaleFactor <<= (sc >> 1); - } else { - stereoScaleFactor = maxStereoScaleFactor; - } - - /* write data to hybrid output */ - tmpHybrid[0][k] = fMultDiv2(stereoScaleFactor, - (FIXP_DBL)(tmpLeftReal + tmpRightReal)) >> - dynScale; - tmpHybrid[1][k] = fMultDiv2(stereoScaleFactor, - (FIXP_DBL)(tmpLeftImag + tmpRightImag)) >> - dynScale; - - } /* hybrid bands - k */ - - FDKhybridSynthesisApply(&hParametricStereo->fdkHybSynFilter, tmpHybrid[0], - tmpHybrid[1], mixRealQmfData[n], - mixImagQmfData[n]); - - qmfSynthesisFilteringSlot( - sbrSynthQmf, mixRealQmfData[n], mixImagQmfData[n], downmixScale - 7, - downmixScale - 7, - downsampledOutSignal + (n * sbrSynthQmf->no_channels), 1, - pWorkBuffer); - - } /* slots */ - - *qmfScale = -downmixScale + 7; - - C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, 2 * 64) - - { - const INT noQmfSlots2 = hParametricStereo->noQmfSlots >> 1; - const int noQmfBands = hParametricStereo->noQmfBands; - - INT scale, i, j, slotOffset; - - FIXP_DBL tmp[2][64]; - - for (i = 0; i < noQmfSlots2; i++) { - FDKmemcpy(tmp[0], hParametricStereo->qmfDelayLines[0][i], - noQmfBands * sizeof(FIXP_DBL)); - FDKmemcpy(tmp[1], hParametricStereo->qmfDelayLines[1][i], - noQmfBands * sizeof(FIXP_DBL)); - - FDKmemcpy(hParametricStereo->qmfDelayLines[0][i], - mixRealQmfData[i + noQmfSlots2], - noQmfBands * sizeof(FIXP_DBL)); - FDKmemcpy(hParametricStereo->qmfDelayLines[1][i], - mixImagQmfData[i + noQmfSlots2], - noQmfBands * sizeof(FIXP_DBL)); - - FDKmemcpy(mixRealQmfData[i + noQmfSlots2], mixRealQmfData[i], - noQmfBands * sizeof(FIXP_DBL)); - FDKmemcpy(mixImagQmfData[i + noQmfSlots2], mixImagQmfData[i], - noQmfBands * sizeof(FIXP_DBL)); - - FDKmemcpy(mixRealQmfData[i], tmp[0], noQmfBands * sizeof(FIXP_DBL)); - FDKmemcpy(mixImagQmfData[i], tmp[1], noQmfBands * sizeof(FIXP_DBL)); - } - - if (hParametricStereo->qmfDelayScale > *qmfScale) { - scale = hParametricStereo->qmfDelayScale - *qmfScale; - slotOffset = 0; - } else { - scale = *qmfScale - hParametricStereo->qmfDelayScale; - slotOffset = noQmfSlots2; - } - - for (i = 0; i < noQmfSlots2; i++) { - for (j = 0; j < noQmfBands; j++) { - mixRealQmfData[i + slotOffset][j] >>= scale; - mixImagQmfData[i + slotOffset][j] >>= scale; - } - } - - scale = *qmfScale; - *qmfScale = fMin(*qmfScale, hParametricStereo->qmfDelayScale); - hParametricStereo->qmfDelayScale = scale; - } - - } /* valid handle */ - - return error; -} - -INT FDKsbrEnc_PSEnc_WritePSData(HANDLE_PARAMETRIC_STEREO hParametricStereo, - HANDLE_FDK_BITSTREAM hBitstream) { - return ( - (hParametricStereo != NULL) - ? FDKsbrEnc_WritePSBitstream(&hParametricStereo->psOut[0], hBitstream) - : 0); -} - -FDK_PSENC_ERROR FDKsbrEnc_PSEnc_ParametricStereoProcessing( - HANDLE_PARAMETRIC_STEREO hParametricStereo, INT_PCM *samples[2], - UINT samplesBufSize, QMF_FILTER_BANK **hQmfAnalysis, - FIXP_DBL **RESTRICT downmixedRealQmfData, - FIXP_DBL **RESTRICT downmixedImagQmfData, INT_PCM *downsampledOutSignal, - HANDLE_QMF_FILTER_BANK sbrSynthQmf, SCHAR *qmfScale, const int sendHeader) { - FDK_PSENC_ERROR error = PSENC_OK; - INT psQmfScale[MAX_PS_CHANNELS] = {0}; - int psCh, i; - C_AALLOC_SCRATCH_START(pWorkBuffer, FIXP_DBL, 4 * 64) - - for (psCh = 0; psCh < MAX_PS_CHANNELS; psCh++) { - for (i = 0; i < hQmfAnalysis[psCh]->no_col; i++) { - qmfAnalysisFilteringSlot( - hQmfAnalysis[psCh], &pWorkBuffer[2 * 64], /* qmfReal[64] */ - &pWorkBuffer[3 * 64], /* qmfImag[64] */ - samples[psCh] + i * hQmfAnalysis[psCh]->no_channels, 1, - &pWorkBuffer[0 * 64] /* qmf workbuffer 2*64 */ - ); - - FDKhybridAnalysisApply( - &hParametricStereo->fdkHybAnaFilter[psCh], - &pWorkBuffer[2 * 64], /* qmfReal[64] */ - &pWorkBuffer[3 * 64], /* qmfImag[64] */ - hParametricStereo->pHybridData[i + HYBRID_READ_OFFSET][psCh][0], - hParametricStereo->pHybridData[i + HYBRID_READ_OFFSET][psCh][1]); - - } /* no_col loop i */ - - psQmfScale[psCh] = hQmfAnalysis[psCh]->outScalefactor; - - } /* for psCh */ - - C_AALLOC_SCRATCH_END(pWorkBuffer, FIXP_DBL, 4 * 64) - - /* find best scaling in new QMF and Hybrid data */ - psFindBestScaling( - hParametricStereo, &hParametricStereo->pHybridData[HYBRID_READ_OFFSET], - hParametricStereo->dynBandScale, hParametricStereo->maxBandValue, - &hParametricStereo->dmxScale); - - /* extract the ps parameters */ - if (PSENC_OK != - (error = ExtractPSParameters(hParametricStereo, sendHeader, - &hParametricStereo->pHybridData[0]))) { - goto bail; - } - - /* save hybrid date for next frame */ - for (i = 0; i < HYBRID_READ_OFFSET; i++) { - FDKmemcpy( - hParametricStereo->pHybridData[i][0][0], - hParametricStereo->pHybridData[hParametricStereo->noQmfSlots + i][0][0], - MAX_HYBRID_BANDS * sizeof(FIXP_DBL)); /* left, real */ - FDKmemcpy( - hParametricStereo->pHybridData[i][0][1], - hParametricStereo->pHybridData[hParametricStereo->noQmfSlots + i][0][1], - MAX_HYBRID_BANDS * sizeof(FIXP_DBL)); /* left, imag */ - FDKmemcpy( - hParametricStereo->pHybridData[i][1][0], - hParametricStereo->pHybridData[hParametricStereo->noQmfSlots + i][1][0], - MAX_HYBRID_BANDS * sizeof(FIXP_DBL)); /* right, real */ - FDKmemcpy( - hParametricStereo->pHybridData[i][1][1], - hParametricStereo->pHybridData[hParametricStereo->noQmfSlots + i][1][1], - MAX_HYBRID_BANDS * sizeof(FIXP_DBL)); /* right, imag */ - } - - /* downmix and hybrid synthesis */ - if (PSENC_OK != - (error = DownmixPSQmfData( - hParametricStereo, sbrSynthQmf, downmixedRealQmfData, - downmixedImagQmfData, downsampledOutSignal, samplesBufSize, - &hParametricStereo->pHybridData[HYBRID_READ_OFFSET], - hParametricStereo->noQmfSlots, psQmfScale, qmfScale))) { - goto bail; - } - -bail: - - return error; -} - -static void psFindBestScaling( - HANDLE_PARAMETRIC_STEREO hParametricStereo, - FIXP_DBL *hybridData[HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2], - UCHAR *dynBandScale, FIXP_DBL *maxBandValue, SCHAR *dmxScale) { - HANDLE_PS_ENCODE hPsEncode = hParametricStereo->hPsEncode; - - INT group, bin, col, band; - const INT frameSize = hParametricStereo->noQmfSlots; - const INT psBands = (INT)hPsEncode->psEncMode; - const INT nIidGroups = hPsEncode->nQmfIidGroups + hPsEncode->nSubQmfIidGroups; - - /* group wise scaling */ - FIXP_DBL maxVal[2][PS_MAX_BANDS]; - FIXP_DBL maxValue = FL2FXCONST_DBL(0.f); - - FDKmemclear(maxVal, sizeof(maxVal)); - - /* start with hybrid data */ - for (group = 0; group < nIidGroups; group++) { - /* Translate group to bin */ - bin = hPsEncode->subband2parameterIndex[group]; - - /* Translate from 20 bins to 10 bins */ - if (hPsEncode->psEncMode == PS_BANDS_COARSE) { - bin >>= 1; - } - - /* QMF downmix scaling */ - for (col = 0; col < frameSize; col++) { - int i, section = (col < frameSize - HYBRID_READ_OFFSET) ? 0 : 1; - FIXP_DBL tmp = maxVal[section][bin]; - for (i = hPsEncode->iidGroupBorders[group]; - i < hPsEncode->iidGroupBorders[group + 1]; i++) { - tmp = fixMax(tmp, (FIXP_DBL)fixp_abs(hybridData[col][0][0][i])); - tmp = fixMax(tmp, (FIXP_DBL)fixp_abs(hybridData[col][0][1][i])); - tmp = fixMax(tmp, (FIXP_DBL)fixp_abs(hybridData[col][1][0][i])); - tmp = fixMax(tmp, (FIXP_DBL)fixp_abs(hybridData[col][1][1][i])); - } - maxVal[section][bin] = tmp; - } - } /* nIidGroups */ - - /* convert maxSpec to maxScaling, find scaling space */ - for (band = 0; band < psBands; band++) { -#ifndef MULT_16x16 - dynBandScale[band] = - CountLeadingBits(fixMax(maxVal[0][band], maxBandValue[band])); -#else - dynBandScale[band] = fixMax( - 0, CountLeadingBits(fixMax(maxVal[0][band], maxBandValue[band])) - - FRACT_BITS); -#endif - maxValue = fixMax(maxValue, fixMax(maxVal[0][band], maxVal[1][band])); - maxBandValue[band] = fixMax(maxVal[0][band], maxVal[1][band]); - } - - /* calculate maximal scaling for QMF downmix */ -#ifndef MULT_16x16 - *dmxScale = fixMin(DFRACT_BITS, CountLeadingBits(maxValue)); -#else - *dmxScale = fixMax(0, fixMin(FRACT_BITS, CountLeadingBits((maxValue)))); -#endif -} --- a/libSBRenc/src/ps_main.h +++ /dev/null @@ -1,270 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): Markus Multrus - - Description: PS Wrapper, Downmix header file - -*******************************************************************************/ - -#ifndef PS_MAIN_H -#define PS_MAIN_H - -/* Includes ******************************************************************/ - -#include "sbr_def.h" -#include "qmf.h" -#include "ps_encode.h" -#include "FDK_bitstream.h" -#include "FDK_hybrid.h" - -/* Data Types ****************************************************************/ -typedef enum { - PSENC_STEREO_BANDS_INVALID = 0, - PSENC_STEREO_BANDS_10 = 10, - PSENC_STEREO_BANDS_20 = 20 - -} PSENC_STEREO_BANDS_CONFIG; - -typedef enum { - PSENC_NENV_1 = 1, - PSENC_NENV_2 = 2, - PSENC_NENV_4 = 4, - PSENC_NENV_DEFAULT = PSENC_NENV_2, - PSENC_NENV_MAX = PSENC_NENV_4 - -} PSENC_NENV_CONFIG; - -typedef struct { - UINT bitrateFrom; /* inclusive */ - UINT bitrateTo; /* exclusive */ - PSENC_STEREO_BANDS_CONFIG nStereoBands; - PSENC_NENV_CONFIG nEnvelopes; - LONG iidQuantErrorThreshold; /* quantization threshold to switch between - coarse and fine iid quantization */ - -} psTuningTable_t; - -/* Function / Class Declarations *********************************************/ - -typedef struct T_PARAMETRIC_STEREO { - HANDLE_PS_ENCODE hPsEncode; - PS_OUT psOut[2]; - - FIXP_DBL __staticHybridData[HYBRID_READ_OFFSET][MAX_PS_CHANNELS][2] - [MAX_HYBRID_BANDS]; - FIXP_DBL - *pHybridData[HYBRID_READ_OFFSET + HYBRID_FRAMESIZE][MAX_PS_CHANNELS][2]; - - FIXP_DBL qmfDelayLines[2][32 >> 1][64]; - int qmfDelayScale; - - INT psDelay; - UINT maxEnvelopes; - UCHAR dynBandScale[PS_MAX_BANDS]; - FIXP_DBL maxBandValue[PS_MAX_BANDS]; - SCHAR dmxScale; - INT initPS; - INT noQmfSlots; - INT noQmfBands; - - FIXP_DBL __staticHybAnaStatesLF[MAX_PS_CHANNELS][2 * HYBRID_FILTER_LENGTH * - HYBRID_MAX_QMF_BANDS]; - FIXP_DBL __staticHybAnaStatesHF[MAX_PS_CHANNELS][2 * HYBRID_FILTER_DELAY * - (64 - HYBRID_MAX_QMF_BANDS)]; - FDK_ANA_HYB_FILTER fdkHybAnaFilter[MAX_PS_CHANNELS]; - FDK_SYN_HYB_FILTER fdkHybSynFilter; - -} PARAMETRIC_STEREO; - -typedef struct T_PSENC_CONFIG { - INT frameSize; - INT qmfFilterMode; - INT sbrPsDelay; - PSENC_STEREO_BANDS_CONFIG nStereoBands; - PSENC_NENV_CONFIG maxEnvelopes; - FIXP_DBL iidQuantErrorThreshold; - -} PSENC_CONFIG, *HANDLE_PSENC_CONFIG; - -typedef struct T_PARAMETRIC_STEREO *HANDLE_PARAMETRIC_STEREO; - -/** - * \brief Create a parametric stereo encoder instance. - * - * \param phParametricStereo A pointer to a parametric stereo handle to be - * allocated. Initialized on return. - * - * \return - * - PSENC_OK, on succes. - * - PSENC_INVALID_HANDLE, PSENC_MEMORY_ERROR, on failure. - */ -FDK_PSENC_ERROR PSEnc_Create(HANDLE_PARAMETRIC_STEREO *phParametricStereo); - -/** - * \brief Initialize a parametric stereo encoder instance. - * - * \param hParametricStereo Meta Data handle. - * \param hPsEncConfig Filled parametric stereo configuration - * structure. - * \param noQmfSlots Number of slots within one audio frame. - * \param noQmfBands Number of QMF bands. - * \param dynamic_RAM Pointer to preallocated workbuffer. - * - * \return - * - PSENC_OK, on succes. - * - PSENC_INVALID_HANDLE, PSENC_INIT_ERROR, on failure. - */ -FDK_PSENC_ERROR PSEnc_Init(HANDLE_PARAMETRIC_STEREO hParametricStereo, - const HANDLE_PSENC_CONFIG hPsEncConfig, - INT noQmfSlots, INT noQmfBands, UCHAR *dynamic_RAM); - -/** - * \brief Destroy parametric stereo encoder instance. - * - * Deallocate instance and free whole memory. - * - * \param phParametricStereo Pointer to the parametric stereo handle to be - * deallocated. - * - * \return - * - PSENC_OK, on succes. - * - PSENC_INVALID_HANDLE, on failure. - */ -FDK_PSENC_ERROR PSEnc_Destroy(HANDLE_PARAMETRIC_STEREO *phParametricStereo); - -/** - * \brief Apply parametric stereo processing. - * - * \param hParametricStereo Meta Data handle. - * \param samples Pointer to 2 channel audio input signal. - * \param timeInStride, Stride factor of input buffer. - * \param hQmfAnalysis, Pointer to QMF analysis filterbanks. - * \param downmixedRealQmfData Pointer to real QMF buffer to be written to. - * \param downmixedImagQmfData Pointer to imag QMF buffer to be written to. - * \param downsampledOutSignal Pointer to buffer where to write downmixed - * timesignal. - * \param sbrSynthQmf Pointer to QMF synthesis filterbank. - * \param qmfScale Return scaling factor of the qmf data. - * \param sendHeader Signal whether to write header data. - * - * \return - * - PSENC_OK, on succes. - * - PSENC_INVALID_HANDLE, PSENC_ENCODE_ERROR, on failure. - */ -FDK_PSENC_ERROR FDKsbrEnc_PSEnc_ParametricStereoProcessing( - HANDLE_PARAMETRIC_STEREO hParametricStereo, INT_PCM *samples[2], - UINT timeInStride, QMF_FILTER_BANK **hQmfAnalysis, - FIXP_DBL **RESTRICT downmixedRealQmfData, - FIXP_DBL **RESTRICT downmixedImagQmfData, INT_PCM *downsampledOutSignal, - HANDLE_QMF_FILTER_BANK sbrSynthQmf, SCHAR *qmfScale, const int sendHeader); - -/** - * \brief Write parametric stereo bitstream. - * - * Write ps_data() element to bitstream and return number of written bits. - * Returns number of written bits only, if hBitstream == NULL. - * - * \param hParametricStereo Meta Data handle. - * \param hBitstream Bitstream buffer handle. - * - * \return - * - number of written bits. - */ -INT FDKsbrEnc_PSEnc_WritePSData(HANDLE_PARAMETRIC_STEREO hParametricStereo, - HANDLE_FDK_BITSTREAM hBitstream); - -#endif /* PS_MAIN_H */ --- a/libSBRenc/src/resampler.cpp +++ /dev/null @@ -1,444 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief FDK resampler tool box:$Revision: 91655 $ - \author M. Werner -*/ - -#include "resampler.h" - -#include "genericStds.h" - -/**************************************************************************/ -/* BIQUAD Filter Specifications */ -/**************************************************************************/ - -#define B1 0 -#define B2 1 -#define A1 2 -#define A2 3 - -#define BQC(x) FL2FXCONST_SGL(x / 2) - -struct FILTER_PARAM { - const FIXP_SGL *coeffa; /*! SOS matrix One row/section. Scaled using BQC(). - Order of coefficients: B1,B2,A1,A2. B0=A0=1.0 */ - FIXP_DBL g; /*! overall gain */ - int Wc; /*! normalized passband bandwidth at input samplerate * 1000 */ - int noCoeffs; /*! number of filter coeffs */ - int delay; /*! delay in samples at input samplerate */ -}; - -#define BIQUAD_COEFSTEP 4 - -/** - *\brief Low Pass - Wc = 0,5, order 30, Stop Band -96dB. Wc criteria is "almost 0dB passband", not - the usual -3db gain point. [b,a]=cheby2(30,96,0.505) [sos,g]=tf2sos(b,a) - bandwidth 0.48 - */ -static const FIXP_SGL sos48[] = { - BQC(1.98941075681938), BQC(0.999999996890811), - BQC(0.863264527201963), BQC(0.189553799960663), - BQC(1.90733804822445), BQC(1.00000001736189), - BQC(0.836321575841691), BQC(0.203505809266564), - BQC(1.75616665495325), BQC(0.999999946079721), - BQC(0.784699225121588), BQC(0.230471265506986), - BQC(1.55727745512726), BQC(1.00000011737815), - BQC(0.712515423588351), BQC(0.268752723900498), - BQC(1.33407591943643), BQC(0.999999795953228), - BQC(0.625059117330989), BQC(0.316194685288965), - BQC(1.10689898412458), BQC(1.00000035057114), - BQC(0.52803514366398), BQC(0.370517843224669), - BQC(0.89060371078454), BQC(0.999999343962822), - BQC(0.426920462165257), BQC(0.429608200207746), - BQC(0.694438261209433), BQC(1.0000008629792), - BQC(0.326530699561716), BQC(0.491714450654174), - BQC(0.523237800935322), BQC(1.00000101349782), - BQC(0.230829556274851), BQC(0.555559034843281), - BQC(0.378631165929563), BQC(0.99998986482665), - BQC(0.142906422036095), BQC(0.620338874442411), - BQC(0.260786911308437), BQC(1.00003261460178), - BQC(0.0651008576256505), BQC(0.685759923926262), - BQC(0.168409429188098), BQC(0.999933049695828), - BQC(-0.000790067789975562), BQC(0.751905896602325), - BQC(0.100724533818628), BQC(1.00009472669872), - BQC(-0.0533772830257041), BQC(0.81930744384525), - BQC(0.0561434357867363), BQC(0.999911636304276), - BQC(-0.0913550299236405), BQC(0.88883625875915), - BQC(0.0341680678662057), BQC(1.00003667508676), - BQC(-0.113405185536697), BQC(0.961756638268446)}; - -static const FIXP_DBL g48 = - FL2FXCONST_DBL(0.002712866530047) - (FIXP_DBL)0x8000; - -static const struct FILTER_PARAM param_set48 = { - sos48, g48, 480, 15, 4 /* LF 2 */ -}; - -/** - *\brief Low Pass - Wc = 0,5, order 24, Stop Band -96dB. Wc criteria is "almost 0dB passband", not - the usual -3db gain point. [b,a]=cheby2(24,96,0.5) [sos,g]=tf2sos(b,a) - bandwidth 0.45 - */ -static const FIXP_SGL sos45[] = { - BQC(1.982962601444), BQC(1.00000000007504), BQC(0.646113303737836), - BQC(0.10851149979981), BQC(1.85334094281111), BQC(0.999999999677192), - BQC(0.612073220102006), BQC(0.130022141698044), BQC(1.62541051415425), - BQC(1.00000000080398), BQC(0.547879702855959), BQC(0.171165825133192), - BQC(1.34554656923247), BQC(0.9999999980169), BQC(0.460373914508491), - BQC(0.228677463376354), BQC(1.05656568503116), BQC(1.00000000569363), - BQC(0.357891894038287), BQC(0.298676843912185), BQC(0.787967587877312), - BQC(0.999999984415017), BQC(0.248826893211877), BQC(0.377441803512978), - BQC(0.555480971120497), BQC(1.00000003583307), BQC(0.140614263345315), - BQC(0.461979302213679), BQC(0.364986207070964), BQC(0.999999932084303), - BQC(0.0392669446074516), BQC(0.55033451180825), BQC(0.216827267631558), - BQC(1.00000010534682), BQC(-0.0506232228865103), BQC(0.641691581560946), - BQC(0.108951672277119), BQC(0.999999871167516), BQC(-0.125584840183225), - BQC(0.736367748771803), BQC(0.0387988607229035), BQC(1.00000011205574), - BQC(-0.182814849097974), BQC(0.835802108714964), BQC(0.0042866175809225), - BQC(0.999999954830813), BQC(-0.21965740617151), BQC(0.942623047782363)}; - -static const FIXP_DBL g45 = - FL2FXCONST_DBL(0.00242743980909524) - (FIXP_DBL)0x8000; - -static const struct FILTER_PARAM param_set45 = { - sos45, g45, 450, 12, 4 /* LF 2 */ -}; - -/* - Created by Octave 2.1.73, Mon Oct 13 17:31:32 2008 CEST - Wc = 0,5, order 16, Stop Band -96dB damping. - [b,a]=cheby2(16,96,0.5) - [sos,g]=tf2sos(b,a) - bandwidth = 0.41 - */ - -static const FIXP_SGL sos41[] = { - BQC(1.96193625292), BQC(0.999999999999964), BQC(0.169266178786789), - BQC(0.0128823300475907), BQC(1.68913437662092), BQC(1.00000000000053), - BQC(0.124751503206552), BQC(0.0537472273950989), BQC(1.27274692366017), - BQC(0.999999999995674), BQC(0.0433108625178357), BQC(0.131015753236317), - BQC(0.85214175088395), BQC(1.00000000001813), BQC(-0.0625658152550408), - BQC(0.237763778993806), BQC(0.503841579939009), BQC(0.999999999953223), - BQC(-0.179176128722865), BQC(0.367475236424474), BQC(0.249990711986162), - BQC(1.00000000007952), BQC(-0.294425165824676), BQC(0.516594857170212), - BQC(0.087971668680286), BQC(0.999999999915528), BQC(-0.398956566777928), - BQC(0.686417767801123), BQC(0.00965373325350294), BQC(1.00000000003744), - BQC(-0.48579173764817), BQC(0.884931534239068)}; - -static const FIXP_DBL g41 = FL2FXCONST_DBL(0.00155956951169248); - -static const struct FILTER_PARAM param_set41 = { - sos41, g41, 410, 8, 5 /* LF 3 */ -}; - -/* - # Created by Octave 2.1.73, Mon Oct 13 17:55:33 2008 CEST - Wc = 0,5, order 12, Stop Band -96dB damping. - [b,a]=cheby2(12,96,0.5); - [sos,g]=tf2sos(b,a) -*/ -static const FIXP_SGL sos35[] = { - BQC(1.93299325235762), BQC(0.999999999999985), BQC(-0.140733187246596), - BQC(0.0124139497836062), BQC(1.4890416764109), BQC(1.00000000000011), - BQC(-0.198215402588504), BQC(0.0746730616584138), BQC(0.918450161309795), - BQC(0.999999999999619), BQC(-0.30133912791941), BQC(0.192276468839529), - BQC(0.454877024246818), BQC(1.00000000000086), BQC(-0.432337328809815), - BQC(0.356852933642815), BQC(0.158017147118507), BQC(0.999999999998876), - BQC(-0.574817494249777), BQC(0.566380436970833), BQC(0.0171834649478749), - BQC(1.00000000000055), BQC(-0.718581178041165), BQC(0.83367484487889)}; - -static const FIXP_DBL g35 = FL2FXCONST_DBL(0.00162580994125131); - -static const struct FILTER_PARAM param_set35 = {sos35, g35, 350, 6, 4}; - -/* - # Created by Octave 2.1.73, Mon Oct 13 18:15:38 2008 CEST - Wc = 0,5, order 8, Stop Band -96dB damping. - [b,a]=cheby2(8,96,0.5); - [sos,g]=tf2sos(b,a) -*/ -static const FIXP_SGL sos25[] = { - BQC(1.85334094301225), BQC(1.0), - BQC(-0.702127214212663), BQC(0.132452403998767), - BQC(1.056565682167), BQC(0.999999999999997), - BQC(-0.789503667880785), BQC(0.236328693569128), - BQC(0.364986307455489), BQC(0.999999999999996), - BQC(-0.955191189843375), BQC(0.442966457936379), - BQC(0.0387985751642125), BQC(1.0), - BQC(-1.19817786088084), BQC(0.770493895456328)}; - -static const FIXP_DBL g25 = FL2FXCONST_DBL(0.000945182835294559); - -static const struct FILTER_PARAM param_set25 = {sos25, g25, 250, 4, 5}; - -/* Must be sorted in descending order */ -static const struct FILTER_PARAM *const filter_paramSet[] = { - ¶m_set48, ¶m_set45, ¶m_set41, ¶m_set35, ¶m_set25}; - -/**************************************************************************/ -/* Resampler Functions */ -/**************************************************************************/ - -/*! - \brief Reset downsampler instance and clear delay lines - - \return success of operation -*/ - -INT FDKaacEnc_InitDownsampler( - DOWNSAMPLER *DownSampler, /*!< pointer to downsampler instance */ - int Wc, /*!< normalized cutoff freq * 1000* */ - int ratio) /*!< downsampler ratio */ - -{ - UINT i; - const struct FILTER_PARAM *currentSet = NULL; - - FDKmemclear(DownSampler->downFilter.states, - sizeof(DownSampler->downFilter.states)); - DownSampler->downFilter.ptr = 0; - - /* - find applicable parameter set - */ - currentSet = filter_paramSet[0]; - for (i = 1; i < sizeof(filter_paramSet) / sizeof(struct FILTER_PARAM *); - i++) { - if (filter_paramSet[i]->Wc <= Wc) { - break; - } - currentSet = filter_paramSet[i]; - } - - DownSampler->downFilter.coeffa = currentSet->coeffa; - - DownSampler->downFilter.gain = currentSet->g; - FDK_ASSERT(currentSet->noCoeffs <= MAXNR_SECTIONS * 2); - - DownSampler->downFilter.noCoeffs = currentSet->noCoeffs; - DownSampler->delay = currentSet->delay; - DownSampler->downFilter.Wc = currentSet->Wc; - - DownSampler->ratio = ratio; - DownSampler->pending = ratio - 1; - return (1); -} - -/*! - \brief faster simple folding operation - Filter: - H(z) = A(z)/B(z) - with - A(z) = a[0]*z^0 + a[1]*z^1 + a[2]*z^2 ... a[n]*z^n - - \return filtered value -*/ - -static inline INT_PCM AdvanceFilter( - LP_FILTER *downFilter, /*!< pointer to iir filter instance */ - INT_PCM *pInput, /*!< input of filter */ - int downRatio) { - INT_PCM output; - int i, n; - -#define BIQUAD_SCALE 12 - - FIXP_DBL y = FL2FXCONST_DBL(0.0f); - FIXP_DBL input; - - for (n = 0; n < downRatio; n++) { - FIXP_BQS(*states)[2] = downFilter->states; - const FIXP_SGL *coeff = downFilter->coeffa; - int s1, s2; - - s1 = downFilter->ptr; - s2 = s1 ^ 1; - -#if (SAMPLE_BITS == 16) - input = ((FIXP_DBL)pInput[n]) << (DFRACT_BITS - SAMPLE_BITS - BIQUAD_SCALE); -#elif (SAMPLE_BITS == 32) - input = pInput[n] >> BIQUAD_SCALE; -#else -#error NOT IMPLEMENTED -#endif - - FIXP_BQS state1, state2, state1b, state2b; - - state1 = states[0][s1]; - state2 = states[0][s2]; - - /* Loop over sections */ - for (i = 0; i < downFilter->noCoeffs; i++) { - FIXP_DBL state0; - - /* Load merged states (from next section) */ - state1b = states[i + 1][s1]; - state2b = states[i + 1][s2]; - - state0 = input + fMult(state1, coeff[B1]) + fMult(state2, coeff[B2]); - y = state0 - fMult(state1b, coeff[A1]) - fMult(state2b, coeff[A2]); - - /* Store new feed forward merge state */ - states[i + 1][s2] = y << 1; - /* Store new feed backward state */ - states[i][s2] = input << 1; - - /* Feedback output to next section. */ - input = y; - - /* Transfer merged states */ - state1 = state1b; - state2 = state2b; - - /* Step to next coef set */ - coeff += BIQUAD_COEFSTEP; - } - downFilter->ptr ^= 1; - } - /* Apply global gain */ - y = fMult(y, downFilter->gain); - - /* Apply final gain/scaling to output */ -#if (SAMPLE_BITS == 16) - output = (INT_PCM)SATURATE_RIGHT_SHIFT( - y + (FIXP_DBL)(1 << (DFRACT_BITS - SAMPLE_BITS - BIQUAD_SCALE - 1)), - DFRACT_BITS - SAMPLE_BITS - BIQUAD_SCALE, SAMPLE_BITS); - // output = (INT_PCM) SATURATE_RIGHT_SHIFT(y, - // DFRACT_BITS-SAMPLE_BITS-BIQUAD_SCALE, SAMPLE_BITS); -#else - output = SATURATE_LEFT_SHIFT(y, BIQUAD_SCALE, SAMPLE_BITS); -#endif - - return output; -} - -/*! - \brief FDKaacEnc_Downsample numInSamples of type INT_PCM - Returns number of output samples in numOutSamples - - \return success of operation -*/ - -INT FDKaacEnc_Downsample( - DOWNSAMPLER *DownSampler, /*!< pointer to downsampler instance */ - INT_PCM *inSamples, /*!< pointer to input samples */ - INT numInSamples, /*!< number of input samples */ - INT_PCM *outSamples, /*!< pointer to output samples */ - INT *numOutSamples /*!< pointer tp number of output samples */ -) { - INT i; - *numOutSamples = 0; - - for (i = 0; i < numInSamples; i += DownSampler->ratio) { - *outSamples = AdvanceFilter(&(DownSampler->downFilter), &inSamples[i], - DownSampler->ratio); - outSamples++; - } - *numOutSamples = numInSamples / DownSampler->ratio; - - return 0; -} --- a/libSBRenc/src/resampler.h +++ /dev/null @@ -1,159 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -#ifndef RESAMPLER_H -#define RESAMPLER_H -/*! - \file - \brief Fixed Point Resampler Tool Box $Revision: 92790 $ -*/ - -#include "common_fix.h" - -/**************************************************************************/ -/* BIQUAD Filter Structure */ -/**************************************************************************/ - -#define MAXNR_SECTIONS (15) - -typedef FIXP_DBL FIXP_BQS; - -typedef struct { - FIXP_BQS states[MAXNR_SECTIONS + 1][2]; /*! state buffer */ - const FIXP_SGL *coeffa; /*! pointer to filter coeffs */ - FIXP_DBL gain; /*! overall gain factor */ - int Wc; /*! normalized cutoff freq * 1000 */ - int noCoeffs; /*! number of filter coeffs sets */ - int ptr; /*! index to rinbuffers */ -} LP_FILTER; - -/**************************************************************************/ -/* Downsampler Structure */ -/**************************************************************************/ - -typedef struct { - LP_FILTER downFilter; /*! filter instance */ - int ratio; /*! downsampling ration */ - int delay; /*! downsampling delay (source fs) */ - int pending; /*! number of pending output samples */ -} DOWNSAMPLER; - -/** - * \brief Initialized a given downsampler structure. - */ -INT FDKaacEnc_InitDownsampler( - DOWNSAMPLER *DownSampler, /*!< pointer to downsampler instance */ - INT Wc, /*!< normalized cutoff freq * 1000 */ - INT ratio); /*!< downsampler ratio */ - -/** - * \brief Downsample a set of audio samples. numInSamples must be at least equal - * to the downsampler ratio. - */ -INT FDKaacEnc_Downsample( - DOWNSAMPLER *DownSampler, /*!< pointer to downsampler instance */ - INT_PCM *inSamples, /*!< pointer to input samples */ - INT numInSamples, /*!< number of input samples */ - INT_PCM *outSamples, /*!< pointer to output samples */ - INT *numOutSamples); /*!< pointer tp number of output samples */ - -#endif /* RESAMPLER_H */ --- a/libSBRenc/src/sbr.h +++ /dev/null @@ -1,194 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Main SBR structs definitions $Revision: 92790 $ -*/ - -#ifndef SBR_H -#define SBR_H - -#include "fram_gen.h" -#include "bit_sbr.h" -#include "tran_det.h" -#include "code_env.h" -#include "env_est.h" -#include "cmondata.h" - -#include "qmf.h" -#include "resampler.h" - -#include "ton_corr.h" - -/* SBR bitstream delay */ -#define MAX_DELAY_FRAMES 2 - -/* sbr encoder downsampling type */ -typedef enum { SBRENC_DS_NONE, SBRENC_DS_TIME, SBRENC_DS_QMF } SBRENC_DS_TYPE; - -typedef struct SBR_CHANNEL { - struct ENV_CHANNEL hEnvChannel; - // INT_PCM *pDSOutBuffer; /**< Pointer to - // downsampled audio output of SBR encoder */ - DOWNSAMPLER downSampler; - -} SBR_CHANNEL; -typedef SBR_CHANNEL* HANDLE_SBR_CHANNEL; - -typedef struct SBR_ELEMENT { - HANDLE_SBR_CHANNEL sbrChannel[2]; - QMF_FILTER_BANK* hQmfAnalysis[2]; - SBR_CONFIG_DATA sbrConfigData; - SBR_HEADER_DATA sbrHeaderData; - SBR_BITSTREAM_DATA sbrBitstreamData; - COMMON_DATA CmonData; - INT dynXOverFreqDelay[5]; /**< to delay a frame (I don't like it that much - that way - hrc) */ - SBR_ELEMENT_INFO elInfo; - - UCHAR payloadDelayLine[1 + MAX_DELAY_FRAMES][MAX_PAYLOAD_SIZE]; - UINT payloadDelayLineSize[1 + MAX_DELAY_FRAMES]; /* Sizes in bits */ - -} SBR_ELEMENT, *HANDLE_SBR_ELEMENT; - -typedef struct SBR_ENCODER { - HANDLE_SBR_ELEMENT sbrElement[(8)]; - HANDLE_SBR_CHANNEL pSbrChannel[(8)]; - QMF_FILTER_BANK QmfAnalysis[(8)]; - DOWNSAMPLER lfeDownSampler; - int lfeChIdx; /* -1 default for no lfe, else assign channel index. */ - int noElements; /* Number of elements. */ - int nChannels; /* Total channel count across all elements. */ - int frameSize; /* SBR framelength. */ - int bufferOffset; /* Offset for SBR parameter extraction in time domain input - buffer. */ - int downsampledOffset; /* Offset of downsampled/mixed output for core encoder. - */ - int downmixSize; /* Size in samples of downsampled/mixed output for core - encoder. */ - INT downSampleFactor; /* Sampling rate relation between the SBR and the core - encoder. */ - SBRENC_DS_TYPE - downsamplingMethod; /* Method of downsmapling, time-domain, QMF or none. - */ - int nBitstrDelay; /* Amount of SBR frames to be delayed in bitstream domain. - */ - int sbrDecDelay; /* SBR decoder delay in samples */ - INT estimateBitrate; /* Estimate bitrate of SBR encoder. */ - INT inputDataDelay; /* Delay caused by downsampler, in/out buffer at - sbrEncoder_EncodeFrame. */ - - UCHAR* dynamicRam; - UCHAR* pSBRdynamic_RAM; - - HANDLE_PARAMETRIC_STEREO hParametricStereo; - QMF_FILTER_BANK qmfSynthesisPS; - - /* parameters describing allocation volume of present instance */ - INT maxElements; - INT maxChannels; - INT supportPS; - -} SBR_ENCODER; - -#endif /* SBR_H */ --- a/libSBRenc/src/sbr_def.h +++ /dev/null @@ -1,276 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief SBR main definitions $Revision: 92790 $ -*/ -#ifndef SBR_DEF_H -#define SBR_DEF_H - -#include "common_fix.h" - -#define noError 0 -#define HANDLE_ERROR_INFO INT -#define ERROR(a, b) 1 - -/* #define SBR_ENV_STATISTICS_BITRATE */ -#undef SBR_ENV_STATISTICS_BITRATE - -/* #define SBR_ENV_STATISTICS */ -#undef SBR_ENV_STATISTICS - -/* #define SBR_PAYLOAD_MONITOR */ -#undef SBR_PAYLOAD_MONITOR - -#define SWAP(a, b) tempr = a, a = b, b = tempr -#define TRUE 1 -#define FALSE 0 - -/* Constants */ -#define EPS 1e-12 -#define LOG2 0.69314718056f /* natural logarithm of 2 */ -#define ILOG2 1.442695041f /* 1/LOG2 */ -#define RELAXATION_FLOAT (1e-6f) -#define RELAXATION (FL2FXCONST_DBL(RELAXATION_FLOAT)) -#define RELAXATION_FRACT \ - (FL2FXCONST_DBL(0.524288f)) /* 0.524288f is fractional part of RELAXATION */ -#define RELAXATION_SHIFT (19) -#define RELAXATION_LD64 \ - (FL2FXCONST_DBL(0.31143075889f)) /* (ld64(RELAXATION) \ - */ - -/************ Definitions ***************/ -#define SBR_COMP_MODE_DELTA 0 -#define SBR_COMP_MODE_CTS 1 -#define SBR_MAX_ENERGY_VALUES 5 -#define SBR_GLOBAL_TONALITY_VALUES 2 - -#define MAX_NUM_CHANNELS 2 - -#define MAX_NOISE_ENVELOPES 2 -#define MAX_NUM_NOISE_COEFFS 5 -#define MAX_NUM_NOISE_VALUES (MAX_NUM_NOISE_COEFFS * MAX_NOISE_ENVELOPES) - -#define MAX_NUM_ENVELOPE_VALUES (MAX_ENVELOPES * MAX_FREQ_COEFFS) -#define MAX_ENVELOPES 5 -#define MAX_FREQ_COEFFS 48 - -#define MAX_FREQ_COEFFS_FS44100 35 -#define MAX_FREQ_COEFFS_FS48000 32 - -#define NO_OF_ESTIMATES_LC 4 -#define NO_OF_ESTIMATES_LD 3 -#define MAX_NO_OF_ESTIMATES 4 - -#define NOISE_FLOOR_OFFSET 6 -#define NOISE_FLOOR_OFFSET_64 (FL2FXCONST_DBL(0.09375f)) - -#define LOW_RES 0 -#define HIGH_RES 1 - -#define LO 0 -#define HI 1 - -#define LENGTH_SBR_FRAME_INFO 35 /* 19 */ - -#define SBR_NSFB_LOW_RES 9 /* 8 */ -#define SBR_NSFB_HIGH_RES 18 /* 16 */ - -#define SBR_XPOS_CTRL_DEFAULT 2 - -#define SBR_FREQ_SCALE_DEFAULT 2 -#define SBR_ALTER_SCALE_DEFAULT 1 -#define SBR_NOISE_BANDS_DEFAULT 2 - -#define SBR_LIMITER_BANDS_DEFAULT 2 -#define SBR_LIMITER_GAINS_DEFAULT 2 -#define SBR_LIMITER_GAINS_INFINITE 3 -#define SBR_INTERPOL_FREQ_DEFAULT 1 -#define SBR_SMOOTHING_LENGTH_DEFAULT 0 - -/* sbr_header */ -#define SI_SBR_AMP_RES_BITS 1 -#define SI_SBR_COUPLING_BITS 1 -#define SI_SBR_START_FREQ_BITS 4 -#define SI_SBR_STOP_FREQ_BITS 4 -#define SI_SBR_XOVER_BAND_BITS 3 -#define SI_SBR_RESERVED_BITS 2 -#define SI_SBR_DATA_EXTRA_BITS 1 -#define SI_SBR_HEADER_EXTRA_1_BITS 1 -#define SI_SBR_HEADER_EXTRA_2_BITS 1 - -/* sbr_header extra 1 */ -#define SI_SBR_FREQ_SCALE_BITS 2 -#define SI_SBR_ALTER_SCALE_BITS 1 -#define SI_SBR_NOISE_BANDS_BITS 2 - -/* sbr_header extra 2 */ -#define SI_SBR_LIMITER_BANDS_BITS 2 -#define SI_SBR_LIMITER_GAINS_BITS 2 -#define SI_SBR_INTERPOL_FREQ_BITS 1 -#define SI_SBR_SMOOTHING_LENGTH_BITS 1 - -/* sbr_grid */ -#define SBR_CLA_BITS 2 /*!< size of bs_frame_class */ -#define SBR_CLA_BITS_LD 1 /*!< size of bs_frame_class */ -#define SBR_ENV_BITS 2 /*!< size of bs_num_env_raw */ -#define SBR_ABS_BITS 2 /*!< size of bs_abs_bord_raw for HE-AAC */ -#define SBR_NUM_BITS 2 /*!< size of bs_num_rel */ -#define SBR_REL_BITS 2 /*!< size of bs_rel_bord_raw */ -#define SBR_RES_BITS 1 /*!< size of bs_freq_res_flag */ -#define SBR_DIR_BITS 1 /*!< size of bs_df_flag */ - -/* sbr_data */ -#define SI_SBR_INVF_MODE_BITS 2 - -#define SI_SBR_START_ENV_BITS_AMP_RES_3_0 6 -#define SI_SBR_START_ENV_BITS_BALANCE_AMP_RES_3_0 5 -#define SI_SBR_START_NOISE_BITS_AMP_RES_3_0 5 -#define SI_SBR_START_NOISE_BITS_BALANCE_AMP_RES_3_0 5 - -#define SI_SBR_START_ENV_BITS_AMP_RES_1_5 7 -#define SI_SBR_START_ENV_BITS_BALANCE_AMP_RES_1_5 6 - -#define SI_SBR_EXTENDED_DATA_BITS 1 -#define SI_SBR_EXTENSION_SIZE_BITS 4 -#define SI_SBR_EXTENSION_ESC_COUNT_BITS 8 -#define SI_SBR_EXTENSION_ID_BITS 2 - -#define SBR_EXTENDED_DATA_MAX_CNT (15 + 255) - -#define EXTENSION_ID_PS_CODING 2 - -/* Envelope coding constants */ -#define FREQ 0 -#define TIME 1 - -/* qmf data scaling */ -#define QMF_SCALE_OFFSET 7 - -/* huffman tables */ -#define CODE_BOOK_SCF_LAV00 60 -#define CODE_BOOK_SCF_LAV01 31 -#define CODE_BOOK_SCF_LAV10 60 -#define CODE_BOOK_SCF_LAV11 31 -#define CODE_BOOK_SCF_LAV_BALANCE11 12 -#define CODE_BOOK_SCF_LAV_BALANCE10 24 - -typedef enum { SBR_AMP_RES_1_5 = 0, SBR_AMP_RES_3_0 } AMP_RES; - -typedef enum { - XPOS_MDCT, - XPOS_MDCT_CROSS, - XPOS_LC, - XPOS_RESERVED, - XPOS_SWITCHED /* not a real choice but used here to control behaviour */ -} XPOS_MODE; - -typedef enum { - INVF_OFF = 0, - INVF_LOW_LEVEL, - INVF_MID_LEVEL, - INVF_HIGH_LEVEL, - INVF_SWITCHED /* not a real choice but used here to control behaviour */ -} INVF_MODE; - -#endif --- a/libSBRenc/src/sbr_encoder.cpp +++ /dev/null @@ -1,2577 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): Andreas Ehret, Tobias Chalupka - - Description: SBR encoder top level processing. - -*******************************************************************************/ - -#include "sbr_encoder.h" - -#include "sbrenc_ram.h" -#include "sbrenc_rom.h" -#include "sbrenc_freq_sca.h" -#include "env_bit.h" -#include "cmondata.h" -#include "sbr_misc.h" -#include "sbr.h" -#include "qmf.h" - -#include "ps_main.h" - -#define SBRENCODER_LIB_VL0 4 -#define SBRENCODER_LIB_VL1 0 -#define SBRENCODER_LIB_VL2 0 - -/***************************************************************************/ -/* - * SBR Delay balancing definitions. - */ - -/* - input buffer (1ch) - - |------------ 1537 -------------|-----|---------- 2048 -------------| - (core2sbr delay ) ds (read, core and ds area) -*/ - -#define SFB(dwnsmp) \ - (32 << (dwnsmp - \ - 1)) /* SBR Frequency bands: 64 for dual-rate, 32 for single-rate */ -#define STS(fl) \ - (((fl) == 1024) ? 32 \ - : 30) /* SBR Time Slots: 32 for core frame length 1024, 30 \ - for core frame length 960 */ - -#define DELAY_QMF_ANA(dwnsmp) \ - ((320 << ((dwnsmp)-1)) - (32 << ((dwnsmp)-1))) /* Full bandwidth */ -#define DELAY_HYB_ANA (10 * 64) /* + 0.5 */ /* */ -#define DELAY_HYB_SYN (6 * 64 - 32) /* */ -#define DELAY_QMF_POSTPROC(dwnsmp) \ - (32 * (dwnsmp)) /* QMF postprocessing delay */ -#define DELAY_DEC_QMF(dwnsmp) (6 * SFB(dwnsmp)) /* Decoder QMF overlap */ -#define DELAY_QMF_SYN(dwnsmp) \ - (1 << (dwnsmp - \ - 1)) /* QMF_NO_POLY/2=2.5, rounded down to 2, half for single-rate */ -#define DELAY_QMF_DS (32) /* QMF synthesis for downsampled time signal */ - -/* Delay in QMF paths */ -#define DELAY_SBR(fl, dwnsmp) \ - (DELAY_QMF_ANA(dwnsmp) + (SFB(dwnsmp) * STS(fl) - 1) + DELAY_QMF_SYN(dwnsmp)) -#define DELAY_PS(fl, dwnsmp) \ - (DELAY_QMF_ANA(dwnsmp) + DELAY_HYB_ANA + DELAY_DEC_QMF(dwnsmp) + \ - (SFB(dwnsmp) * STS(fl) - 1) + DELAY_HYB_SYN + DELAY_QMF_SYN(dwnsmp)) -#define DELAY_ELDSBR(fl, dwnsmp) \ - ((((fl) / 2) * (dwnsmp)) - 1 + DELAY_QMF_POSTPROC(dwnsmp)) -#define DELAY_ELDv2SBR(fl, dwnsmp) \ - ((((fl) / 2) * (dwnsmp)) - 1 + 80 * (dwnsmp)) /* 80 is the delay caused \ - by the sum of the CLD \ - analysis and the MPSLD \ - synthesis filterbank */ - -/* Delay in core path (core and downsampler not taken into account) */ -#define DELAY_COREPATH_SBR(fl, dwnsmp) \ - ((DELAY_QMF_ANA(dwnsmp) + DELAY_DEC_QMF(dwnsmp) + DELAY_QMF_SYN(dwnsmp))) -#define DELAY_COREPATH_ELDSBR(fl, dwnsmp) ((DELAY_QMF_POSTPROC(dwnsmp))) -#define DELAY_COREPATH_ELDv2SBR(fl, dwnsmp) (128 * (dwnsmp)) /* 4 slots */ -#define DELAY_COREPATH_PS(fl, dwnsmp) \ - ((DELAY_QMF_ANA(dwnsmp) + DELAY_QMF_DS + \ - /*(DELAY_AAC(fl)*2) + */ DELAY_QMF_ANA(dwnsmp) + DELAY_DEC_QMF(dwnsmp) + \ - DELAY_HYB_SYN + DELAY_QMF_SYN(dwnsmp))) /* 2048 - 463*2 */ - -/* Delay differences between SBR- and downsampled path for SBR and SBR+PS */ -#define DELAY_AAC2SBR(fl, dwnsmp) \ - ((DELAY_COREPATH_SBR(fl, dwnsmp)) - DELAY_SBR((fl), (dwnsmp))) -#define DELAY_ELD2SBR(fl, dwnsmp) \ - ((DELAY_COREPATH_ELDSBR(fl, dwnsmp)) - DELAY_ELDSBR(fl, dwnsmp)) -#define DELAY_AAC2PS(fl, dwnsmp) \ - ((DELAY_COREPATH_PS(fl, dwnsmp)) - DELAY_PS(fl, dwnsmp)) /* 2048 - 463*2 */ - -/* Assumption: The sample delay resulting of of DELAY_AAC2PS is always smaller - * than the sample delay implied by DELAY_AAC2SBR */ -#define MAX_DS_FILTER_DELAY \ - (5) /* the additional max downsampler filter delay (source fs) */ -#define MAX_SAMPLE_DELAY \ - (DELAY_AAC2SBR(1024, 2) + MAX_DS_FILTER_DELAY) /* maximum delay: frame \ - length of 1024 and \ - dual-rate sbr */ - -/***************************************************************************/ - -/*************** Delay parameters for sbrEncoder_Init_delay() **************/ -typedef struct { - int dsDelay; /* the delay of the (time-domain) downsampler itself */ - int delay; /* overall delay / samples */ - int sbrDecDelay; /* SBR decoder's delay */ - int corePathOffset; /* core path offset / samples; added by - sbrEncoder_Init_delay() */ - int sbrPathOffset; /* SBR path offset / samples; added by - sbrEncoder_Init_delay() */ - int bitstrDelay; /* bitstream delay / frames; added by sbrEncoder_Init_delay() - */ - int delayInput2Core; /* delay of the input to the core / samples */ -} DELAY_PARAM; -/***************************************************************************/ - -#define INVALID_TABLE_IDX -1 - -/***************************************************************************/ -/*! - - \brief Selects the SBR tuning settings to use dependent on number of - channels, bitrate, sample rate and core coder - - \return Index to the appropriate table - -****************************************************************************/ -#define DISTANCE_CEIL_VALUE 5000000 -static INT getSbrTuningTableIndex( - UINT bitrate, /*! the total bitrate in bits/sec */ - UINT numChannels, /*! the number of channels for the core coder */ - UINT sampleRate, /*! the sampling rate of the core coder */ - AUDIO_OBJECT_TYPE core, UINT *pBitRateClosest) { - int i, bitRateClosestLowerIndex = -1, bitRateClosestUpperIndex = -1, - found = 0; - UINT bitRateClosestUpper = 0, bitRateClosestLower = DISTANCE_CEIL_VALUE; - -#define isForThisCore(i) \ - ((sbrTuningTable[i].coreCoder == CODEC_AACLD && core == AOT_ER_AAC_ELD) || \ - (sbrTuningTable[i].coreCoder == CODEC_AAC && core != AOT_ER_AAC_ELD)) - - for (i = 0; i < sbrTuningTableSize; i++) { - if (isForThisCore(i)) /* tuning table is for this core codec */ - { - if (numChannels == sbrTuningTable[i].numChannels && - sampleRate == sbrTuningTable[i].sampleRate) { - found = 1; - if ((bitrate >= sbrTuningTable[i].bitrateFrom) && - (bitrate < sbrTuningTable[i].bitrateTo)) { - return i; - } else { - if (sbrTuningTable[i].bitrateFrom > bitrate) { - if (sbrTuningTable[i].bitrateFrom < bitRateClosestLower) { - bitRateClosestLower = sbrTuningTable[i].bitrateFrom; - bitRateClosestLowerIndex = i; - } - } - if (sbrTuningTable[i].bitrateTo <= bitrate) { - if (sbrTuningTable[i].bitrateTo > bitRateClosestUpper) { - bitRateClosestUpper = sbrTuningTable[i].bitrateTo - 1; - bitRateClosestUpperIndex = i; - } - } - } - } - } - } - - if (bitRateClosestUpperIndex >= 0) { - return bitRateClosestUpperIndex; - } - - if (pBitRateClosest != NULL) { - /* If there was at least one matching tuning entry pick the least distance - * bit rate */ - if (found) { - int distanceUpper = DISTANCE_CEIL_VALUE, - distanceLower = DISTANCE_CEIL_VALUE; - if (bitRateClosestLowerIndex >= 0) { - distanceLower = - sbrTuningTable[bitRateClosestLowerIndex].bitrateFrom - bitrate; - } - if (bitRateClosestUpperIndex >= 0) { - distanceUpper = - bitrate - sbrTuningTable[bitRateClosestUpperIndex].bitrateTo; - } - if (distanceUpper < distanceLower) { - *pBitRateClosest = bitRateClosestUpper; - } else { - *pBitRateClosest = bitRateClosestLower; - } - } else { - *pBitRateClosest = 0; - } - } - - return INVALID_TABLE_IDX; -} - -/***************************************************************************/ -/*! - - \brief Selects the PS tuning settings to use dependent on bitrate - and core coder - - \return Index to the appropriate table - -****************************************************************************/ -static INT getPsTuningTableIndex(UINT bitrate, UINT *pBitRateClosest) { - INT i, paramSets = sizeof(psTuningTable) / sizeof(psTuningTable[0]); - int bitRateClosestLowerIndex = -1, bitRateClosestUpperIndex = -1; - UINT bitRateClosestUpper = 0, bitRateClosestLower = DISTANCE_CEIL_VALUE; - - for (i = 0; i < paramSets; i++) { - if ((bitrate >= psTuningTable[i].bitrateFrom) && - (bitrate < psTuningTable[i].bitrateTo)) { - return i; - } else { - if (psTuningTable[i].bitrateFrom > bitrate) { - if (psTuningTable[i].bitrateFrom < bitRateClosestLower) { - bitRateClosestLower = psTuningTable[i].bitrateFrom; - bitRateClosestLowerIndex = i; - } - } - if (psTuningTable[i].bitrateTo <= bitrate) { - if (psTuningTable[i].bitrateTo > bitRateClosestUpper) { - bitRateClosestUpper = psTuningTable[i].bitrateTo - 1; - bitRateClosestUpperIndex = i; - } - } - } - } - - if (bitRateClosestUpperIndex >= 0) { - return bitRateClosestUpperIndex; - } - - if (pBitRateClosest != NULL) { - int distanceUpper = DISTANCE_CEIL_VALUE, - distanceLower = DISTANCE_CEIL_VALUE; - if (bitRateClosestLowerIndex >= 0) { - distanceLower = - sbrTuningTable[bitRateClosestLowerIndex].bitrateFrom - bitrate; - } - if (bitRateClosestUpperIndex >= 0) { - distanceUpper = - bitrate - sbrTuningTable[bitRateClosestUpperIndex].bitrateTo; - } - if (distanceUpper < distanceLower) { - *pBitRateClosest = bitRateClosestUpper; - } else { - *pBitRateClosest = bitRateClosestLower; - } - } - - return INVALID_TABLE_IDX; -} - -/***************************************************************************/ -/*! - - \brief In case of downsampled SBR we may need to lower the stop freq - of a tuning setting to fit into the lower half of the - spectrum ( which is sampleRate/4 ) - - \return the adapted stop frequency index (-1 -> error) - - \ingroup SbrEncCfg - -****************************************************************************/ -static INT FDKsbrEnc_GetDownsampledStopFreq(const INT sampleRateCore, - const INT startFreq, INT stopFreq, - const INT downSampleFactor) { - INT maxStopFreqRaw = sampleRateCore / 2; - INT startBand, stopBand; - HANDLE_ERROR_INFO err; - - while (stopFreq > 0 && FDKsbrEnc_getSbrStopFreqRAW(stopFreq, sampleRateCore) > - maxStopFreqRaw) { - stopFreq--; - } - - if (FDKsbrEnc_getSbrStopFreqRAW(stopFreq, sampleRateCore) > maxStopFreqRaw) - return -1; - - err = FDKsbrEnc_FindStartAndStopBand( - sampleRateCore << (downSampleFactor - 1), sampleRateCore, - 32 << (downSampleFactor - 1), startFreq, stopFreq, &startBand, &stopBand); - if (err) return -1; - - return stopFreq; -} - -/***************************************************************************/ -/*! - - \brief tells us, if for the given coreCoder, bitrate, number of channels - and input sampling rate an SBR setting is available. If yes, it - tells us also the core sampling rate we would need to run with - - \return a flag indicating success: yes (1) or no (0) - -****************************************************************************/ -static UINT FDKsbrEnc_IsSbrSettingAvail( - UINT bitrate, /*! the total bitrate in bits/sec */ - UINT vbrMode, /*! the vbr paramter, 0 means constant bitrate */ - UINT numOutputChannels, /*! the number of channels for the core coder */ - UINT sampleRateInput, /*! the input sample rate [in Hz] */ - UINT sampleRateCore, /*! the core's sampling rate */ - AUDIO_OBJECT_TYPE core) { - INT idx = INVALID_TABLE_IDX; - - if (sampleRateInput < 16000) return 0; - - if (bitrate == 0) { - /* map vbr quality to bitrate */ - if (vbrMode < 30) - bitrate = 24000; - else if (vbrMode < 40) - bitrate = 28000; - else if (vbrMode < 60) - bitrate = 32000; - else if (vbrMode < 75) - bitrate = 40000; - else - bitrate = 48000; - bitrate *= numOutputChannels; - } - - idx = getSbrTuningTableIndex(bitrate, numOutputChannels, sampleRateCore, core, - NULL); - - return (idx == INVALID_TABLE_IDX ? 0 : 1); -} - -/***************************************************************************/ -/*! - - \brief Adjusts the SBR settings according to the chosen core coder - settings which are accessible via config->codecSettings - - \return A flag indicating success: yes (1) or no (0) - -****************************************************************************/ -static UINT FDKsbrEnc_AdjustSbrSettings( - const sbrConfigurationPtr config, /*! output, modified */ - UINT bitRate, /*! the total bitrate in bits/sec */ - UINT numChannels, /*! the core coder number of channels */ - UINT sampleRateCore, /*! the core coder sampling rate in Hz */ - UINT sampleRateSbr, /*! the sbr coder sampling rate in Hz */ - UINT transFac, /*! the short block to long block ratio */ - UINT standardBitrate, /*! the standard bitrate per channel in bits/sec */ - UINT vbrMode, /*! the vbr paramter, 0 poor quality .. 100 high quality*/ - UINT useSpeechConfig, /*!< adapt tuning parameters for speech ? */ - UINT lcsMode, /*! the low complexity stereo mode */ - UINT bParametricStereo, /*!< use parametric stereo */ - AUDIO_OBJECT_TYPE core) /* Core audio codec object type */ -{ - INT idx = INVALID_TABLE_IDX; - /* set the core codec settings */ - config->codecSettings.bitRate = bitRate; - config->codecSettings.nChannels = numChannels; - config->codecSettings.sampleFreq = sampleRateCore; - config->codecSettings.transFac = transFac; - config->codecSettings.standardBitrate = standardBitrate; - - if (bitRate < 28000) { - config->threshold_AmpRes_FF_m = (FIXP_DBL)MAXVAL_DBL; - config->threshold_AmpRes_FF_e = 7; - } else if (bitRate >= 28000 && bitRate <= 48000) { - /* The float threshold is 75 - 0.524288f is fractional part of RELAXATION, the quotaMatrix and therefore - tonality are scaled by this 2/3 is because the original implementation - divides the tonality values by 3, here it's divided by 2 128 compensates - the necessary shiftfactor of 7 */ - config->threshold_AmpRes_FF_m = - FL2FXCONST_DBL(75.0f * 0.524288f / (2.0f / 3.0f) / 128.0f); - config->threshold_AmpRes_FF_e = 7; - } else if (bitRate > 48000) { - config->threshold_AmpRes_FF_m = FL2FXCONST_DBL(0); - config->threshold_AmpRes_FF_e = 0; - } - - if (bitRate == 0) { - /* map vbr quality to bitrate */ - if (vbrMode < 30) - bitRate = 24000; - else if (vbrMode < 40) - bitRate = 28000; - else if (vbrMode < 60) - bitRate = 32000; - else if (vbrMode < 75) - bitRate = 40000; - else - bitRate = 48000; - bitRate *= numChannels; - /* fix to enable mono vbrMode<40 @ 44.1 of 48kHz */ - if (numChannels == 1) { - if (sampleRateSbr == 44100 || sampleRateSbr == 48000) { - if (vbrMode < 40) bitRate = 32000; - } - } - } - - idx = - getSbrTuningTableIndex(bitRate, numChannels, sampleRateCore, core, NULL); - - if (idx != INVALID_TABLE_IDX) { - config->startFreq = sbrTuningTable[idx].startFreq; - config->stopFreq = sbrTuningTable[idx].stopFreq; - if (useSpeechConfig) { - config->startFreq = sbrTuningTable[idx].startFreqSpeech; - config->stopFreq = sbrTuningTable[idx].stopFreqSpeech; - } - - /* Adapt stop frequency in case of downsampled SBR - only 32 bands then */ - if (1 == config->downSampleFactor) { - INT dsStopFreq = FDKsbrEnc_GetDownsampledStopFreq( - sampleRateCore, config->startFreq, config->stopFreq, - config->downSampleFactor); - if (dsStopFreq < 0) { - return 0; - } - - config->stopFreq = dsStopFreq; - } - - config->sbr_noise_bands = sbrTuningTable[idx].numNoiseBands; - if (core == AOT_ER_AAC_ELD) config->init_amp_res_FF = SBR_AMP_RES_1_5; - config->noiseFloorOffset = sbrTuningTable[idx].noiseFloorOffset; - - config->ana_max_level = sbrTuningTable[idx].noiseMaxLevel; - config->stereoMode = sbrTuningTable[idx].stereoMode; - config->freqScale = sbrTuningTable[idx].freqScale; - - if (numChannels == 1) { - /* stereo case */ - switch (core) { - case AOT_AAC_LC: - if (bitRate <= (useSpeechConfig ? 24000U : 20000U)) { - config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency - resolution for - non-split frames */ - config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency - resolution for split - frames */ - } - break; - case AOT_ER_AAC_ELD: - if (bitRate < 36000) - config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency - resolution for split - frames */ - if (bitRate < 26000) { - config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency - resolution for - non-split frames */ - config->fResTransIsLow = - 1; /* for transient frames, set low frequency resolution */ - } - break; - default: - break; - } - } else { - /* stereo case */ - switch (core) { - case AOT_AAC_LC: - if (bitRate <= 28000) { - config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency - resolution for - non-split frames */ - config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency - resolution for split - frames */ - } - break; - case AOT_ER_AAC_ELD: - if (bitRate < 72000) { - config->freq_res_fixfix[1] = FREQ_RES_LOW; /* set low frequency - resolution for split - frames */ - } - if (bitRate < 52000) { - config->freq_res_fixfix[0] = FREQ_RES_LOW; /* set low frequency - resolution for - non-split frames */ - config->fResTransIsLow = - 1; /* for transient frames, set low frequency resolution */ - } - break; - default: - break; - } - if (bitRate <= 28000) { - /* - additionally restrict frequency resolution in FIXFIX frames - to further reduce SBR payload size */ - config->freq_res_fixfix[0] = FREQ_RES_LOW; - config->freq_res_fixfix[1] = FREQ_RES_LOW; - } - } - - /* adjust usage of parametric coding dependent on bitrate and speech config - * flag */ - if (useSpeechConfig) config->parametricCoding = 0; - - if (core == AOT_ER_AAC_ELD) { - if (bitRate < 28000) config->init_amp_res_FF = SBR_AMP_RES_3_0; - config->SendHeaderDataTime = -1; - } - - if (numChannels == 1) { - if (bitRate < 16000) { - config->parametricCoding = 0; - } - } else { - if (bitRate < 20000) { - config->parametricCoding = 0; - } - } - - config->useSpeechConfig = useSpeechConfig; - - /* PS settings */ - config->bParametricStereo = bParametricStereo; - - return 1; - } else { - return 0; - } -} - -/***************************************************************************** - - functionname: FDKsbrEnc_InitializeSbrDefaults - description: initializes the SBR configuration - returns: error status - input: - core codec type, - - factor of SBR to core frame length, - - core frame length - output: initialized SBR configuration - -*****************************************************************************/ -static UINT FDKsbrEnc_InitializeSbrDefaults(sbrConfigurationPtr config, - INT downSampleFactor, - UINT codecGranuleLen, - const INT isLowDelay) { - if ((downSampleFactor < 1 || downSampleFactor > 2) || - (codecGranuleLen * downSampleFactor > 64 * 32)) - return (0); /* error */ - - config->SendHeaderDataTime = 1000; - config->useWaveCoding = 0; - config->crcSbr = 0; - config->dynBwSupported = 1; - if (isLowDelay) - config->tran_thr = 6000; - else - config->tran_thr = 13000; - - config->parametricCoding = 1; - - config->sbrFrameSize = codecGranuleLen * downSampleFactor; - config->downSampleFactor = downSampleFactor; - - /* sbr default parameters */ - config->sbr_data_extra = 0; - config->amp_res = SBR_AMP_RES_3_0; - config->tran_fc = 0; - config->tran_det_mode = 1; - config->spread = 1; - config->stat = 0; - config->e = 1; - config->deltaTAcrossFrames = 1; - config->dF_edge_1stEnv = FL2FXCONST_DBL(0.3f); - config->dF_edge_incr = FL2FXCONST_DBL(0.3f); - - config->sbr_invf_mode = INVF_SWITCHED; - config->sbr_xpos_mode = XPOS_LC; - config->sbr_xpos_ctrl = SBR_XPOS_CTRL_DEFAULT; - config->sbr_xpos_level = 0; - config->useSaPan = 0; - config->dynBwEnabled = 0; - - /* the following parameters are overwritten by the - FDKsbrEnc_AdjustSbrSettings() function since they are included in the - tuning table */ - config->stereoMode = SBR_SWITCH_LRC; - config->ana_max_level = 6; - config->noiseFloorOffset = 0; - config->startFreq = 5; /* 5.9 respectively 6.0 kHz at fs = 44.1/48 kHz */ - config->stopFreq = 9; /* 16.2 respectively 16.8 kHz at fs = 44.1/48 kHz */ - config->freq_res_fixfix[0] = FREQ_RES_HIGH; /* non-split case */ - config->freq_res_fixfix[1] = FREQ_RES_HIGH; /* split case */ - config->fResTransIsLow = 0; /* for transient frames, set variable frequency - resolution according to freqResTable */ - - /* header_extra_1 */ - config->freqScale = SBR_FREQ_SCALE_DEFAULT; - config->alterScale = SBR_ALTER_SCALE_DEFAULT; - config->sbr_noise_bands = SBR_NOISE_BANDS_DEFAULT; - - /* header_extra_2 */ - config->sbr_limiter_bands = SBR_LIMITER_BANDS_DEFAULT; - config->sbr_limiter_gains = SBR_LIMITER_GAINS_DEFAULT; - config->sbr_interpol_freq = SBR_INTERPOL_FREQ_DEFAULT; - config->sbr_smoothing_length = SBR_SMOOTHING_LENGTH_DEFAULT; - - return 1; -} - -/***************************************************************************** - - functionname: DeleteEnvChannel - description: frees memory of one SBR channel - returns: - - input: handle of channel - output: released handle - -*****************************************************************************/ -static void deleteEnvChannel(HANDLE_ENV_CHANNEL hEnvCut) { - if (hEnvCut) { - FDKsbrEnc_DeleteTonCorrParamExtr(&hEnvCut->TonCorr); - - FDKsbrEnc_deleteExtractSbrEnvelope(&hEnvCut->sbrExtractEnvelope); - } -} - -/***************************************************************************** - - functionname: sbrEncoder_ChannelClose - description: close the channel coding handle - returns: - input: phSbrChannel - output: - -*****************************************************************************/ -static void sbrEncoder_ChannelClose(HANDLE_SBR_CHANNEL hSbrChannel) { - if (hSbrChannel != NULL) { - deleteEnvChannel(&hSbrChannel->hEnvChannel); - } -} - -/***************************************************************************** - - functionname: sbrEncoder_ElementClose - description: close the channel coding handle - returns: - input: phSbrChannel - output: - -*****************************************************************************/ -static void sbrEncoder_ElementClose(HANDLE_SBR_ELEMENT *phSbrElement) { - HANDLE_SBR_ELEMENT hSbrElement = *phSbrElement; - - if (hSbrElement != NULL) { - if (hSbrElement->sbrConfigData.v_k_master) - FreeRam_Sbr_v_k_master(&hSbrElement->sbrConfigData.v_k_master); - if (hSbrElement->sbrConfigData.freqBandTable[LO]) - FreeRam_Sbr_freqBandTableLO( - &hSbrElement->sbrConfigData.freqBandTable[LO]); - if (hSbrElement->sbrConfigData.freqBandTable[HI]) - FreeRam_Sbr_freqBandTableHI( - &hSbrElement->sbrConfigData.freqBandTable[HI]); - - FreeRam_SbrElement(phSbrElement); - } - return; -} - -void sbrEncoder_Close(HANDLE_SBR_ENCODER *phSbrEncoder) { - HANDLE_SBR_ENCODER hSbrEncoder = *phSbrEncoder; - - if (hSbrEncoder != NULL) { - int el, ch; - - for (el = 0; el < (8); el++) { - if (hSbrEncoder->sbrElement[el] != NULL) { - sbrEncoder_ElementClose(&hSbrEncoder->sbrElement[el]); - } - } - - /* Close sbr Channels */ - for (ch = 0; ch < (8); ch++) { - if (hSbrEncoder->pSbrChannel[ch]) { - sbrEncoder_ChannelClose(hSbrEncoder->pSbrChannel[ch]); - FreeRam_SbrChannel(&hSbrEncoder->pSbrChannel[ch]); - } - - if (hSbrEncoder->QmfAnalysis[ch].FilterStates) - FreeRam_Sbr_QmfStatesAnalysis( - (FIXP_QAS **)&hSbrEncoder->QmfAnalysis[ch].FilterStates); - } - - if (hSbrEncoder->hParametricStereo) - PSEnc_Destroy(&hSbrEncoder->hParametricStereo); - if (hSbrEncoder->qmfSynthesisPS.FilterStates) - FreeRam_PsQmfStatesSynthesis( - (FIXP_DBL **)&hSbrEncoder->qmfSynthesisPS.FilterStates); - - /* Release Overlay */ - if (hSbrEncoder->pSBRdynamic_RAM) - FreeRam_SbrDynamic_RAM((FIXP_DBL **)&hSbrEncoder->pSBRdynamic_RAM); - - FreeRam_SbrEncoder(phSbrEncoder); - } -} - -/***************************************************************************** - - functionname: updateFreqBandTable - description: updates vk_master - returns: - - input: config handle - output: error info - -*****************************************************************************/ -static INT updateFreqBandTable(HANDLE_SBR_CONFIG_DATA sbrConfigData, - HANDLE_SBR_HEADER_DATA sbrHeaderData, - const INT downSampleFactor) { - INT k0, k2; - - if (FDKsbrEnc_FindStartAndStopBand( - sbrConfigData->sampleFreq, - sbrConfigData->sampleFreq >> (downSampleFactor - 1), - sbrConfigData->noQmfBands, sbrHeaderData->sbr_start_frequency, - sbrHeaderData->sbr_stop_frequency, &k0, &k2)) - return (1); - - if (FDKsbrEnc_UpdateFreqScale( - sbrConfigData->v_k_master, &sbrConfigData->num_Master, k0, k2, - sbrHeaderData->freqScale, sbrHeaderData->alterScale)) - return (1); - - sbrHeaderData->sbr_xover_band = 0; - - if (FDKsbrEnc_UpdateHiRes(sbrConfigData->freqBandTable[HI], - &sbrConfigData->nSfb[HI], sbrConfigData->v_k_master, - sbrConfigData->num_Master, - &sbrHeaderData->sbr_xover_band)) - return (1); - - FDKsbrEnc_UpdateLoRes( - sbrConfigData->freqBandTable[LO], &sbrConfigData->nSfb[LO], - sbrConfigData->freqBandTable[HI], sbrConfigData->nSfb[HI]); - - sbrConfigData->xOverFreq = - (sbrConfigData->freqBandTable[LOW_RES][0] * sbrConfigData->sampleFreq / - sbrConfigData->noQmfBands + - 1) >> - 1; - - return (0); -} - -/***************************************************************************** - - functionname: resetEnvChannel - description: resets parameters and allocates memory - returns: error status - input: - output: hEnv - -*****************************************************************************/ -static INT resetEnvChannel(HANDLE_SBR_CONFIG_DATA sbrConfigData, - HANDLE_SBR_HEADER_DATA sbrHeaderData, - HANDLE_ENV_CHANNEL hEnv) { - /* note !!! hEnv->encEnvData.noOfnoisebands will be updated later in function - * FDKsbrEnc_extractSbrEnvelope !!!*/ - hEnv->TonCorr.sbrNoiseFloorEstimate.noiseBands = - sbrHeaderData->sbr_noise_bands; - - if (FDKsbrEnc_ResetTonCorrParamExtr( - &hEnv->TonCorr, sbrConfigData->xposCtrlSwitch, - sbrConfigData->freqBandTable[HI][0], sbrConfigData->v_k_master, - sbrConfigData->num_Master, sbrConfigData->sampleFreq, - sbrConfigData->freqBandTable, sbrConfigData->nSfb, - sbrConfigData->noQmfBands)) - return (1); - - hEnv->sbrCodeNoiseFloor.nSfb[LO] = - hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands; - hEnv->sbrCodeNoiseFloor.nSfb[HI] = - hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands; - - hEnv->sbrCodeEnvelope.nSfb[LO] = sbrConfigData->nSfb[LO]; - hEnv->sbrCodeEnvelope.nSfb[HI] = sbrConfigData->nSfb[HI]; - - hEnv->encEnvData.noHarmonics = sbrConfigData->nSfb[HI]; - - hEnv->sbrCodeEnvelope.upDate = 0; - hEnv->sbrCodeNoiseFloor.upDate = 0; - - return (0); -} - -/* ****************************** FDKsbrEnc_SbrGetXOverFreq - * ******************************/ -/** - * @fn - * @brief calculates the closest possible crossover frequency - * @return the crossover frequency SBR accepts - * - */ -static INT FDKsbrEnc_SbrGetXOverFreq( - HANDLE_SBR_ELEMENT hEnv, /*!< handle to SBR encoder instance */ - INT xoverFreq) /*!< from core coder suggested crossover frequency */ -{ - INT band; - INT lastDiff, newDiff; - INT cutoffSb; - - UCHAR *RESTRICT pVKMaster = hEnv->sbrConfigData.v_k_master; - - /* Check if there is a matching cutoff frequency in the master table */ - cutoffSb = (4 * xoverFreq * hEnv->sbrConfigData.noQmfBands / - hEnv->sbrConfigData.sampleFreq + - 1) >> - 1; - lastDiff = cutoffSb; - for (band = 0; band < hEnv->sbrConfigData.num_Master; band++) { - newDiff = fixp_abs((INT)pVKMaster[band] - cutoffSb); - - if (newDiff >= lastDiff) { - band--; - break; - } - - lastDiff = newDiff; - } - - return ((pVKMaster[band] * hEnv->sbrConfigData.sampleFreq / - hEnv->sbrConfigData.noQmfBands + - 1) >> - 1); -} - -/***************************************************************************** - - functionname: FDKsbrEnc_EnvEncodeFrame - description: performs the sbr envelope calculation for one element - returns: - input: - output: - -*****************************************************************************/ -INT FDKsbrEnc_EnvEncodeFrame( - HANDLE_SBR_ENCODER hEnvEncoder, int iElement, - INT_PCM *samples, /*!< time samples, always deinterleaved */ - UINT samplesBufSize, /*!< time buffer channel stride */ - UINT *sbrDataBits, /*!< Size of SBR payload */ - UCHAR *sbrData, /*!< SBR payload */ - int clearOutput /*!< Do not consider any input signal */ -) { - HANDLE_SBR_ELEMENT hSbrElement = NULL; - FDK_CRCINFO crcInfo; - INT crcReg; - INT ch; - INT band; - INT cutoffSb; - INT newXOver; - - if (hEnvEncoder == NULL) return -1; - - hSbrElement = hEnvEncoder->sbrElement[iElement]; - - if (hSbrElement == NULL) return -1; - - /* header bitstream handling */ - HANDLE_SBR_BITSTREAM_DATA sbrBitstreamData = &hSbrElement->sbrBitstreamData; - - INT psHeaderActive = 0; - sbrBitstreamData->HeaderActive = 0; - - /* Anticipate PS header because of internal PS bitstream delay in order to be - * in sync with SBR header. */ - if (sbrBitstreamData->CountSendHeaderData == - (sbrBitstreamData->NrSendHeaderData - 1)) { - psHeaderActive = 1; - } - - /* Signal SBR header to be written into bitstream */ - if (sbrBitstreamData->CountSendHeaderData == 0) { - sbrBitstreamData->HeaderActive = 1; - } - - /* Increment header interval counter */ - if (sbrBitstreamData->NrSendHeaderData == 0) { - sbrBitstreamData->CountSendHeaderData = 1; - } else { - if (sbrBitstreamData->CountSendHeaderData >= 0) { - sbrBitstreamData->CountSendHeaderData++; - sbrBitstreamData->CountSendHeaderData %= - sbrBitstreamData->NrSendHeaderData; - } - } - - if (hSbrElement->CmonData.dynBwEnabled) { - INT i; - for (i = 4; i > 0; i--) - hSbrElement->dynXOverFreqDelay[i] = hSbrElement->dynXOverFreqDelay[i - 1]; - - hSbrElement->dynXOverFreqDelay[0] = hSbrElement->CmonData.dynXOverFreqEnc; - if (hSbrElement->dynXOverFreqDelay[1] > hSbrElement->dynXOverFreqDelay[2]) - newXOver = hSbrElement->dynXOverFreqDelay[2]; - else - newXOver = hSbrElement->dynXOverFreqDelay[1]; - - /* has the crossover frequency changed? */ - if (hSbrElement->sbrConfigData.dynXOverFreq != newXOver) { - /* get corresponding master band */ - cutoffSb = ((4 * newXOver * hSbrElement->sbrConfigData.noQmfBands / - hSbrElement->sbrConfigData.sampleFreq) + - 1) >> - 1; - - for (band = 0; band < hSbrElement->sbrConfigData.num_Master; band++) { - if (cutoffSb == hSbrElement->sbrConfigData.v_k_master[band]) break; - } - FDK_ASSERT(band < hSbrElement->sbrConfigData.num_Master); - - hSbrElement->sbrConfigData.dynXOverFreq = newXOver; - hSbrElement->sbrHeaderData.sbr_xover_band = band; - hSbrElement->sbrBitstreamData.HeaderActive = 1; - psHeaderActive = 1; /* ps header is one frame delayed */ - - /* - update vk_master table - */ - if (updateFreqBandTable(&hSbrElement->sbrConfigData, - &hSbrElement->sbrHeaderData, - hEnvEncoder->downSampleFactor)) - return (1); - - /* reset SBR channels */ - INT nEnvCh = hSbrElement->sbrConfigData.nChannels; - for (ch = 0; ch < nEnvCh; ch++) { - if (resetEnvChannel(&hSbrElement->sbrConfigData, - &hSbrElement->sbrHeaderData, - &hSbrElement->sbrChannel[ch]->hEnvChannel)) - return (1); - } - } - } - - /* - allocate space for dummy header and crc - */ - crcReg = FDKsbrEnc_InitSbrBitstream( - &hSbrElement->CmonData, - hSbrElement->payloadDelayLine[hEnvEncoder->nBitstrDelay], - MAX_PAYLOAD_SIZE * sizeof(UCHAR), &crcInfo, - hSbrElement->sbrConfigData.sbrSyntaxFlags); - - /* Temporal Envelope Data */ - SBR_FRAME_TEMP_DATA _fData; - SBR_FRAME_TEMP_DATA *fData = &_fData; - SBR_ENV_TEMP_DATA eData[MAX_NUM_CHANNELS]; - - /* Init Temporal Envelope Data */ - { - int i; - - FDKmemclear(&eData[0], sizeof(SBR_ENV_TEMP_DATA)); - FDKmemclear(&eData[1], sizeof(SBR_ENV_TEMP_DATA)); - FDKmemclear(fData, sizeof(SBR_FRAME_TEMP_DATA)); - - for (i = 0; i < MAX_NUM_NOISE_VALUES; i++) fData->res[i] = FREQ_RES_HIGH; - } - - if (!clearOutput) { - /* - * Transform audio data into QMF domain - */ - for (ch = 0; ch < hSbrElement->sbrConfigData.nChannels; ch++) { - HANDLE_ENV_CHANNEL h_envChan = &hSbrElement->sbrChannel[ch]->hEnvChannel; - HANDLE_SBR_EXTRACT_ENVELOPE sbrExtrEnv = &h_envChan->sbrExtractEnvelope; - - if (hSbrElement->elInfo.fParametricStereo == 0) { - QMF_SCALE_FACTOR tmpScale; - FIXP_DBL **pQmfReal, **pQmfImag; - C_AALLOC_SCRATCH_START(qmfWorkBuffer, FIXP_DBL, 64 * 2) - - /* Obtain pointers to QMF buffers. */ - pQmfReal = sbrExtrEnv->rBuffer; - pQmfImag = sbrExtrEnv->iBuffer; - - qmfAnalysisFiltering( - hSbrElement->hQmfAnalysis[ch], pQmfReal, pQmfImag, &tmpScale, - samples + hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize, 0, - 1, qmfWorkBuffer); - - h_envChan->qmfScale = tmpScale.lb_scale + 7; - - C_AALLOC_SCRATCH_END(qmfWorkBuffer, FIXP_DBL, 64 * 2) - - } /* fParametricStereo == 0 */ - - /* - Parametric Stereo processing - */ - if (hSbrElement->elInfo.fParametricStereo) { - INT error = noError; - - /* Limit Parametric Stereo to one instance */ - FDK_ASSERT(ch == 0); - - if (error == noError) { - /* parametric stereo processing: - - input: - o left and right time domain samples - - processing: - o stereo qmf analysis - o stereo hybrid analysis - o ps parameter extraction - o downmix + hybrid synthesis - - output: - o downmixed qmf data is written to sbrExtrEnv->rBuffer and - sbrExtrEnv->iBuffer - */ - SCHAR qmfScale; - INT_PCM *pSamples[2] = { - samples + hSbrElement->elInfo.ChannelIndex[0] * samplesBufSize, - samples + hSbrElement->elInfo.ChannelIndex[1] * samplesBufSize}; - error = FDKsbrEnc_PSEnc_ParametricStereoProcessing( - hEnvEncoder->hParametricStereo, pSamples, samplesBufSize, - hSbrElement->hQmfAnalysis, sbrExtrEnv->rBuffer, - sbrExtrEnv->iBuffer, - samples + hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize, - &hEnvEncoder->qmfSynthesisPS, &qmfScale, psHeaderActive); - h_envChan->qmfScale = (int)qmfScale; - } - - } /* if (hEnvEncoder->hParametricStereo) */ - - /* - - Extract Envelope relevant things from QMF data - - */ - FDKsbrEnc_extractSbrEnvelope1(&hSbrElement->sbrConfigData, - &hSbrElement->sbrHeaderData, - &hSbrElement->sbrBitstreamData, h_envChan, - &hSbrElement->CmonData, &eData[ch], fData); - - } /* hEnvEncoder->sbrConfigData.nChannels */ - } - - /* - Process Envelope relevant things and calculate envelope data and write - payload - */ - FDKsbrEnc_extractSbrEnvelope2( - &hSbrElement->sbrConfigData, &hSbrElement->sbrHeaderData, - (hSbrElement->elInfo.fParametricStereo) ? hEnvEncoder->hParametricStereo - : NULL, - &hSbrElement->sbrBitstreamData, &hSbrElement->sbrChannel[0]->hEnvChannel, - (hSbrElement->sbrConfigData.stereoMode != SBR_MONO) - ? &hSbrElement->sbrChannel[1]->hEnvChannel - : NULL, - &hSbrElement->CmonData, eData, fData, clearOutput); - - hSbrElement->sbrBitstreamData.rightBorderFIX = 0; - - /* - format payload, calculate crc - */ - FDKsbrEnc_AssembleSbrBitstream(&hSbrElement->CmonData, &crcInfo, crcReg, - hSbrElement->sbrConfigData.sbrSyntaxFlags); - - /* - save new payload, set to zero length if greater than MAX_PAYLOAD_SIZE - */ - hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] = - FDKgetValidBits(&hSbrElement->CmonData.sbrBitbuf); - - if (hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] > - (MAX_PAYLOAD_SIZE << 3)) - hSbrElement->payloadDelayLineSize[hEnvEncoder->nBitstrDelay] = 0; - - /* While filling the Delay lines, sbrData is NULL */ - if (sbrData) { - *sbrDataBits = hSbrElement->payloadDelayLineSize[0]; - FDKmemcpy(sbrData, hSbrElement->payloadDelayLine[0], - (hSbrElement->payloadDelayLineSize[0] + 7) >> 3); - } - - /* delay header active flag */ - if (hSbrElement->sbrBitstreamData.HeaderActive == 1) { - hSbrElement->sbrBitstreamData.HeaderActiveDelay = - 1 + hEnvEncoder->nBitstrDelay; - } else { - if (hSbrElement->sbrBitstreamData.HeaderActiveDelay > 0) { - hSbrElement->sbrBitstreamData.HeaderActiveDelay--; - } - } - - return (0); -} - -/***************************************************************************** - - functionname: FDKsbrEnc_Downsample - description: performs downsampling and delay compensation of the core path - returns: - input: - output: - -*****************************************************************************/ -INT FDKsbrEnc_Downsample( - HANDLE_SBR_ENCODER hSbrEncoder, - INT_PCM *samples, /*!< time samples, always deinterleaved */ - UINT samplesBufSize, /*!< time buffer size per channel */ - UINT numChannels, /*!< number of channels */ - UINT *sbrDataBits, /*!< Size of SBR payload */ - UCHAR *sbrData, /*!< SBR payload */ - int clearOutput /*!< Do not consider any input signal */ -) { - HANDLE_SBR_ELEMENT hSbrElement = NULL; - INT nOutSamples; - int el; - if (hSbrEncoder->downSampleFactor > 1) { - /* Do downsampling */ - - /* Loop over elements (LFE is handled later) */ - for (el = 0; el < hSbrEncoder->noElements; el++) { - hSbrElement = hSbrEncoder->sbrElement[el]; - if (hSbrEncoder->sbrElement[el] != NULL) { - if (hSbrEncoder->downsamplingMethod == SBRENC_DS_TIME) { - int ch; - int nChannels = hSbrElement->sbrConfigData.nChannels; - - for (ch = 0; ch < nChannels; ch++) { - FDKaacEnc_Downsample( - &hSbrElement->sbrChannel[ch]->downSampler, - samples + - hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize + - hSbrEncoder->bufferOffset / numChannels, - hSbrElement->sbrConfigData.frameSize, - samples + hSbrElement->elInfo.ChannelIndex[ch] * samplesBufSize, - &nOutSamples); - } - } - } - } - - /* Handle LFE (if existing) */ - if (hSbrEncoder->lfeChIdx != -1) { /* lfe downsampler */ - FDKaacEnc_Downsample(&hSbrEncoder->lfeDownSampler, - samples + hSbrEncoder->lfeChIdx * samplesBufSize + - hSbrEncoder->bufferOffset / numChannels, - hSbrEncoder->frameSize, - samples + hSbrEncoder->lfeChIdx * samplesBufSize, - &nOutSamples); - } - } else { - /* No downsampling. Still, some buffer shifting for correct delay */ - int samples2Copy = hSbrEncoder->frameSize; - if (hSbrEncoder->bufferOffset / (int)numChannels < samples2Copy) { - for (int c = 0; c < (int)numChannels; c++) { - /* Do memmove while taking care of overlapping memory areas. (memcpy - does not necessarily take care) Distinguish between oeverlapping and - non overlapping version due to reasons of complexity. */ - FDKmemmove(samples + c * samplesBufSize, - samples + c * samplesBufSize + - hSbrEncoder->bufferOffset / numChannels, - samples2Copy * sizeof(INT_PCM)); - } - } else { - for (int c = 0; c < (int)numChannels; c++) { - /* Simple memcpy since the memory areas are not overlapping */ - FDKmemcpy(samples + c * samplesBufSize, - samples + c * samplesBufSize + - hSbrEncoder->bufferOffset / numChannels, - samples2Copy * sizeof(INT_PCM)); - } - } - } - - return 0; -} - -/***************************************************************************** - - functionname: createEnvChannel - description: initializes parameters and allocates memory - returns: error status - input: - output: hEnv - -*****************************************************************************/ - -static INT createEnvChannel(HANDLE_ENV_CHANNEL hEnv, INT channel, - UCHAR *dynamic_RAM) { - FDKmemclear(hEnv, sizeof(struct ENV_CHANNEL)); - - if (FDKsbrEnc_CreateTonCorrParamExtr(&hEnv->TonCorr, channel)) { - return (1); - } - - if (FDKsbrEnc_CreateExtractSbrEnvelope(&hEnv->sbrExtractEnvelope, channel, - /*chan*/ 0, dynamic_RAM)) { - return (1); - } - - return 0; -} - -/***************************************************************************** - - functionname: initEnvChannel - description: initializes parameters - returns: error status - input: - output: - -*****************************************************************************/ -static INT initEnvChannel(HANDLE_SBR_CONFIG_DATA sbrConfigData, - HANDLE_SBR_HEADER_DATA sbrHeaderData, - HANDLE_ENV_CHANNEL hEnv, sbrConfigurationPtr params, - ULONG statesInitFlag, INT chanInEl, - UCHAR *dynamic_RAM) { - int frameShift, tran_off = 0; - INT e; - INT tran_fc; - INT timeSlots, timeStep, startIndex; - INT noiseBands[2] = {3, 3}; - - e = 1 << params->e; - - FDK_ASSERT(params->e >= 0); - - hEnv->encEnvData.freq_res_fixfix[0] = params->freq_res_fixfix[0]; - hEnv->encEnvData.freq_res_fixfix[1] = params->freq_res_fixfix[1]; - hEnv->encEnvData.fResTransIsLow = params->fResTransIsLow; - - hEnv->fLevelProtect = 0; - - hEnv->encEnvData.ldGrid = - (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) ? 1 : 0; - - hEnv->encEnvData.sbr_xpos_mode = (XPOS_MODE)params->sbr_xpos_mode; - - if (hEnv->encEnvData.sbr_xpos_mode == XPOS_SWITCHED) { - /* - no other type than XPOS_MDCT or XPOS_SPEECH allowed, - but enable switching - */ - sbrConfigData->switchTransposers = TRUE; - hEnv->encEnvData.sbr_xpos_mode = XPOS_MDCT; - } else { - sbrConfigData->switchTransposers = FALSE; - } - - hEnv->encEnvData.sbr_xpos_ctrl = params->sbr_xpos_ctrl; - - /* extended data */ - if (params->parametricCoding) { - hEnv->encEnvData.extended_data = 1; - } else { - hEnv->encEnvData.extended_data = 0; - } - - hEnv->encEnvData.extension_size = 0; - - startIndex = QMF_FILTER_PROTOTYPE_SIZE - sbrConfigData->noQmfBands; - - switch (params->sbrFrameSize) { - case 2304: - timeSlots = 18; - break; - case 2048: - case 1024: - case 512: - timeSlots = 16; - break; - case 1920: - case 960: - case 480: - timeSlots = 15; - break; - case 1152: - timeSlots = 9; - break; - default: - return (1); /* Illegal frame size */ - } - - timeStep = sbrConfigData->noQmfSlots / timeSlots; - - if (FDKsbrEnc_InitTonCorrParamExtr( - params->sbrFrameSize, &hEnv->TonCorr, sbrConfigData, timeSlots, - params->sbr_xpos_ctrl, params->ana_max_level, - sbrHeaderData->sbr_noise_bands, params->noiseFloorOffset, - params->useSpeechConfig)) - return (1); - - hEnv->encEnvData.noOfnoisebands = - hEnv->TonCorr.sbrNoiseFloorEstimate.noNoiseBands; - - noiseBands[0] = hEnv->encEnvData.noOfnoisebands; - noiseBands[1] = hEnv->encEnvData.noOfnoisebands; - - hEnv->encEnvData.sbr_invf_mode = (INVF_MODE)params->sbr_invf_mode; - - if (hEnv->encEnvData.sbr_invf_mode == INVF_SWITCHED) { - hEnv->encEnvData.sbr_invf_mode = INVF_MID_LEVEL; - hEnv->TonCorr.switchInverseFilt = TRUE; - } else { - hEnv->TonCorr.switchInverseFilt = FALSE; - } - - tran_fc = params->tran_fc; - - if (tran_fc == 0) { - tran_fc = fixMin( - 5000, FDKsbrEnc_getSbrStartFreqRAW(sbrHeaderData->sbr_start_frequency, - params->codecSettings.sampleFreq)); - } - - tran_fc = - (tran_fc * 4 * sbrConfigData->noQmfBands / sbrConfigData->sampleFreq + - 1) >> - 1; - - if (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { - frameShift = LD_PRETRAN_OFF; - tran_off = LD_PRETRAN_OFF + FRAME_MIDDLE_SLOT_512LD * timeStep; - } else { - frameShift = 0; - switch (timeSlots) { - /* The factor of 2 is by definition. */ - case NUMBER_TIME_SLOTS_2048: - tran_off = 8 + FRAME_MIDDLE_SLOT_2048 * timeStep; - break; - case NUMBER_TIME_SLOTS_1920: - tran_off = 7 + FRAME_MIDDLE_SLOT_1920 * timeStep; - break; - default: - return 1; - } - } - if (FDKsbrEnc_InitExtractSbrEnvelope( - &hEnv->sbrExtractEnvelope, sbrConfigData->noQmfSlots, - sbrConfigData->noQmfBands, startIndex, timeSlots, timeStep, tran_off, - statesInitFlag, chanInEl, dynamic_RAM, sbrConfigData->sbrSyntaxFlags)) - return (1); - - if (FDKsbrEnc_InitSbrCodeEnvelope(&hEnv->sbrCodeEnvelope, sbrConfigData->nSfb, - params->deltaTAcrossFrames, - params->dF_edge_1stEnv, - params->dF_edge_incr)) - return (1); - - if (FDKsbrEnc_InitSbrCodeEnvelope(&hEnv->sbrCodeNoiseFloor, noiseBands, - params->deltaTAcrossFrames, 0, 0)) - return (1); - - sbrConfigData->initAmpResFF = params->init_amp_res_FF; - - if (FDKsbrEnc_InitSbrHuffmanTables(&hEnv->encEnvData, &hEnv->sbrCodeEnvelope, - &hEnv->sbrCodeNoiseFloor, - sbrHeaderData->sbr_amp_res)) - return (1); - - FDKsbrEnc_initFrameInfoGenerator( - &hEnv->SbrEnvFrame, params->spread, e, params->stat, timeSlots, - hEnv->encEnvData.freq_res_fixfix, hEnv->encEnvData.fResTransIsLow, - hEnv->encEnvData.ldGrid); - - if (sbrConfigData->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) - - { - INT bandwidth_qmf_slot = - (sbrConfigData->sampleFreq >> 1) / (sbrConfigData->noQmfBands); - if (FDKsbrEnc_InitSbrFastTransientDetector( - &hEnv->sbrFastTransientDetector, sbrConfigData->noQmfSlots, - bandwidth_qmf_slot, sbrConfigData->noQmfBands, - sbrConfigData->freqBandTable[0][0])) - return (1); - } - - /* The transient detector has to be initialized also if the fast transient - detector was active, because the values from the transient detector - structure are used. */ - if (FDKsbrEnc_InitSbrTransientDetector( - &hEnv->sbrTransientDetector, sbrConfigData->sbrSyntaxFlags, - sbrConfigData->frameSize, sbrConfigData->sampleFreq, params, tran_fc, - sbrConfigData->noQmfSlots, sbrConfigData->noQmfBands, - hEnv->sbrExtractEnvelope.YBufferWriteOffset, - hEnv->sbrExtractEnvelope.YBufferSzShift, frameShift, tran_off)) - return (1); - - sbrConfigData->xposCtrlSwitch = params->sbr_xpos_ctrl; - - hEnv->encEnvData.noHarmonics = sbrConfigData->nSfb[HI]; - hEnv->encEnvData.addHarmonicFlag = 0; - - return (0); -} - -INT sbrEncoder_Open(HANDLE_SBR_ENCODER *phSbrEncoder, INT nElements, - INT nChannels, INT supportPS) { - INT i; - INT errorStatus = 1; - HANDLE_SBR_ENCODER hSbrEncoder = NULL; - - if (phSbrEncoder == NULL) { - goto bail; - } - - hSbrEncoder = GetRam_SbrEncoder(); - if (hSbrEncoder == NULL) { - goto bail; - } - FDKmemclear(hSbrEncoder, sizeof(SBR_ENCODER)); - - if (NULL == - (hSbrEncoder->pSBRdynamic_RAM = (UCHAR *)GetRam_SbrDynamic_RAM())) { - goto bail; - } - hSbrEncoder->dynamicRam = hSbrEncoder->pSBRdynamic_RAM; - - /* Create SBR elements */ - for (i = 0; i < nElements; i++) { - hSbrEncoder->sbrElement[i] = GetRam_SbrElement(i); - if (hSbrEncoder->sbrElement[i] == NULL) { - goto bail; - } - FDKmemclear(hSbrEncoder->sbrElement[i], sizeof(SBR_ELEMENT)); - hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[LO] = - GetRam_Sbr_freqBandTableLO(i); - hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[HI] = - GetRam_Sbr_freqBandTableHI(i); - hSbrEncoder->sbrElement[i]->sbrConfigData.v_k_master = - GetRam_Sbr_v_k_master(i); - if ((hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[LO] == NULL) || - (hSbrEncoder->sbrElement[i]->sbrConfigData.freqBandTable[HI] == NULL) || - (hSbrEncoder->sbrElement[i]->sbrConfigData.v_k_master == NULL)) { - goto bail; - } - } - - /* Create SBR channels */ - for (i = 0; i < nChannels; i++) { - hSbrEncoder->pSbrChannel[i] = GetRam_SbrChannel(i); - if (hSbrEncoder->pSbrChannel[i] == NULL) { - goto bail; - } - - if (createEnvChannel(&hSbrEncoder->pSbrChannel[i]->hEnvChannel, i, - hSbrEncoder->dynamicRam)) { - goto bail; - } - } - - /* Create QMF States */ - for (i = 0; i < fixMax(nChannels, (supportPS) ? 2 : 0); i++) { - hSbrEncoder->QmfAnalysis[i].FilterStates = GetRam_Sbr_QmfStatesAnalysis(i); - if (hSbrEncoder->QmfAnalysis[i].FilterStates == NULL) { - goto bail; - } - } - - /* Create Parametric Stereo handle */ - if (supportPS) { - if (PSEnc_Create(&hSbrEncoder->hParametricStereo)) { - goto bail; - } - - hSbrEncoder->qmfSynthesisPS.FilterStates = GetRam_PsQmfStatesSynthesis(); - if (hSbrEncoder->qmfSynthesisPS.FilterStates == NULL) { - goto bail; - } - } /* supportPS */ - - *phSbrEncoder = hSbrEncoder; - - errorStatus = 0; - return errorStatus; - -bail: - /* Close SBR encoder instance */ - sbrEncoder_Close(&hSbrEncoder); - return errorStatus; -} - -static INT FDKsbrEnc_Reallocate(HANDLE_SBR_ENCODER hSbrEncoder, - SBR_ELEMENT_INFO elInfo[(8)], - const INT noElements) { - INT totalCh = 0; - INT totalQmf = 0; - INT coreEl; - INT el = -1; - - hSbrEncoder->lfeChIdx = -1; /* default value, until lfe found */ - - for (coreEl = 0; coreEl < noElements; coreEl++) { - /* SBR only handles SCE and CPE's */ - if (elInfo[coreEl].elType == ID_SCE || elInfo[coreEl].elType == ID_CPE) { - el++; - } else { - if (elInfo[coreEl].elType == ID_LFE) { - hSbrEncoder->lfeChIdx = elInfo[coreEl].ChannelIndex[0]; - } - continue; - } - - SBR_ELEMENT_INFO *pelInfo = &elInfo[coreEl]; - HANDLE_SBR_ELEMENT hSbrElement = hSbrEncoder->sbrElement[el]; - - int ch; - for (ch = 0; ch < pelInfo->nChannelsInEl; ch++) { - hSbrElement->sbrChannel[ch] = hSbrEncoder->pSbrChannel[totalCh]; - totalCh++; - } - /* analysis QMF */ - for (ch = 0; - ch < ((pelInfo->fParametricStereo) ? 2 : pelInfo->nChannelsInEl); - ch++) { - hSbrElement->elInfo.ChannelIndex[ch] = pelInfo->ChannelIndex[ch]; - hSbrElement->hQmfAnalysis[ch] = &hSbrEncoder->QmfAnalysis[totalQmf++]; - } - - /* Copy Element info */ - hSbrElement->elInfo.elType = pelInfo->elType; - hSbrElement->elInfo.instanceTag = pelInfo->instanceTag; - hSbrElement->elInfo.nChannelsInEl = pelInfo->nChannelsInEl; - hSbrElement->elInfo.fParametricStereo = pelInfo->fParametricStereo; - hSbrElement->elInfo.fDualMono = pelInfo->fDualMono; - } /* coreEl */ - - return 0; -} - -/***************************************************************************** - - functionname: FDKsbrEnc_bsBufInit - description: initializes bitstream buffer - returns: initialized bitstream buffer in env encoder - input: - output: hEnv - -*****************************************************************************/ -static INT FDKsbrEnc_bsBufInit(HANDLE_SBR_ELEMENT hSbrElement, - int nBitstrDelay) { - UCHAR *bitstreamBuffer; - - /* initialize the bitstream buffer */ - bitstreamBuffer = hSbrElement->payloadDelayLine[nBitstrDelay]; - FDKinitBitStream(&hSbrElement->CmonData.sbrBitbuf, bitstreamBuffer, - MAX_PAYLOAD_SIZE * sizeof(UCHAR), 0, BS_WRITER); - - return (0); -} - -/***************************************************************************** - - functionname: FDKsbrEnc_EnvInit - description: initializes parameters - returns: error status - input: - output: hEnv - -*****************************************************************************/ -static INT FDKsbrEnc_EnvInit(HANDLE_SBR_ELEMENT hSbrElement, - sbrConfigurationPtr params, INT *coreBandWith, - AUDIO_OBJECT_TYPE aot, int nElement, - const int headerPeriod, ULONG statesInitFlag, - const SBRENC_DS_TYPE downsamplingMethod, - UCHAR *dynamic_RAM) { - int ch, i; - - if ((params->codecSettings.nChannels < 1) || - (params->codecSettings.nChannels > MAX_NUM_CHANNELS)) { - return (1); - } - - /* init and set syntax flags */ - hSbrElement->sbrConfigData.sbrSyntaxFlags = 0; - - switch (aot) { - case AOT_ER_AAC_ELD: - hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_LOW_DELAY; - break; - default: - break; - } - if (params->crcSbr) { - hSbrElement->sbrConfigData.sbrSyntaxFlags |= SBR_SYNTAX_CRC; - } - - hSbrElement->sbrConfigData.noQmfBands = 64 >> (2 - params->downSampleFactor); - switch (hSbrElement->sbrConfigData.noQmfBands) { - case 64: - hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize >> 6; - break; - case 32: - hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize >> 5; - break; - default: - hSbrElement->sbrConfigData.noQmfSlots = params->sbrFrameSize >> 6; - return (2); - } - - /* - now initialize sbrConfigData, sbrHeaderData and sbrBitstreamData, - */ - hSbrElement->sbrConfigData.nChannels = params->codecSettings.nChannels; - - if (params->codecSettings.nChannels == 2) { - if ((hSbrElement->elInfo.elType == ID_CPE) && - ((hSbrElement->elInfo.fDualMono == 1))) { - hSbrElement->sbrConfigData.stereoMode = SBR_LEFT_RIGHT; - } else { - hSbrElement->sbrConfigData.stereoMode = params->stereoMode; - } - } else { - hSbrElement->sbrConfigData.stereoMode = SBR_MONO; - } - - hSbrElement->sbrConfigData.frameSize = params->sbrFrameSize; - - hSbrElement->sbrConfigData.sampleFreq = - params->downSampleFactor * params->codecSettings.sampleFreq; - - hSbrElement->sbrBitstreamData.CountSendHeaderData = 0; - if (params->SendHeaderDataTime > 0) { - if (headerPeriod == -1) { - hSbrElement->sbrBitstreamData.NrSendHeaderData = (INT)( - params->SendHeaderDataTime * hSbrElement->sbrConfigData.sampleFreq / - (1000 * hSbrElement->sbrConfigData.frameSize)); - hSbrElement->sbrBitstreamData.NrSendHeaderData = - fixMax(hSbrElement->sbrBitstreamData.NrSendHeaderData, 1); - } else { - /* assure header period at least once per second */ - hSbrElement->sbrBitstreamData.NrSendHeaderData = fixMin( - fixMax(headerPeriod, 1), (hSbrElement->sbrConfigData.sampleFreq / - hSbrElement->sbrConfigData.frameSize)); - } - } else { - hSbrElement->sbrBitstreamData.NrSendHeaderData = 0; - } - - hSbrElement->sbrHeaderData.sbr_data_extra = params->sbr_data_extra; - hSbrElement->sbrBitstreamData.HeaderActive = 0; - hSbrElement->sbrBitstreamData.rightBorderFIX = 0; - hSbrElement->sbrHeaderData.sbr_start_frequency = params->startFreq; - hSbrElement->sbrHeaderData.sbr_stop_frequency = params->stopFreq; - hSbrElement->sbrHeaderData.sbr_xover_band = 0; - hSbrElement->sbrHeaderData.sbr_lc_stereo_mode = 0; - - /* data_extra */ - if (params->sbr_xpos_ctrl != SBR_XPOS_CTRL_DEFAULT) - hSbrElement->sbrHeaderData.sbr_data_extra = 1; - - hSbrElement->sbrHeaderData.sbr_amp_res = (AMP_RES)params->amp_res; - - /* header_extra_1 */ - hSbrElement->sbrHeaderData.freqScale = params->freqScale; - hSbrElement->sbrHeaderData.alterScale = params->alterScale; - hSbrElement->sbrHeaderData.sbr_noise_bands = params->sbr_noise_bands; - hSbrElement->sbrHeaderData.header_extra_1 = 0; - - if ((params->freqScale != SBR_FREQ_SCALE_DEFAULT) || - (params->alterScale != SBR_ALTER_SCALE_DEFAULT) || - (params->sbr_noise_bands != SBR_NOISE_BANDS_DEFAULT)) { - hSbrElement->sbrHeaderData.header_extra_1 = 1; - } - - /* header_extra_2 */ - hSbrElement->sbrHeaderData.sbr_limiter_bands = params->sbr_limiter_bands; - hSbrElement->sbrHeaderData.sbr_limiter_gains = params->sbr_limiter_gains; - - if ((hSbrElement->sbrConfigData.sampleFreq > 48000) && - (hSbrElement->sbrHeaderData.sbr_start_frequency >= 9)) { - hSbrElement->sbrHeaderData.sbr_limiter_gains = SBR_LIMITER_GAINS_INFINITE; - } - - hSbrElement->sbrHeaderData.sbr_interpol_freq = params->sbr_interpol_freq; - hSbrElement->sbrHeaderData.sbr_smoothing_length = - params->sbr_smoothing_length; - hSbrElement->sbrHeaderData.header_extra_2 = 0; - - if ((params->sbr_limiter_bands != SBR_LIMITER_BANDS_DEFAULT) || - (params->sbr_limiter_gains != SBR_LIMITER_GAINS_DEFAULT) || - (params->sbr_interpol_freq != SBR_INTERPOL_FREQ_DEFAULT) || - (params->sbr_smoothing_length != SBR_SMOOTHING_LENGTH_DEFAULT)) { - hSbrElement->sbrHeaderData.header_extra_2 = 1; - } - - /* other switches */ - hSbrElement->sbrConfigData.useWaveCoding = params->useWaveCoding; - hSbrElement->sbrConfigData.useParametricCoding = params->parametricCoding; - hSbrElement->sbrConfigData.thresholdAmpResFF_m = - params->threshold_AmpRes_FF_m; - hSbrElement->sbrConfigData.thresholdAmpResFF_e = - params->threshold_AmpRes_FF_e; - - /* init freq band table */ - if (updateFreqBandTable(&hSbrElement->sbrConfigData, - &hSbrElement->sbrHeaderData, - params->downSampleFactor)) { - return (1); - } - - /* now create envelope ext and QMF for each available channel */ - for (ch = 0; ch < hSbrElement->sbrConfigData.nChannels; ch++) { - if (initEnvChannel(&hSbrElement->sbrConfigData, &hSbrElement->sbrHeaderData, - &hSbrElement->sbrChannel[ch]->hEnvChannel, params, - statesInitFlag, ch, dynamic_RAM)) { - return (1); - } - - } /* nChannels */ - - /* reset and intialize analysis qmf */ - for (ch = 0; ch < ((hSbrElement->elInfo.fParametricStereo) - ? 2 - : hSbrElement->sbrConfigData.nChannels); - ch++) { - int err; - UINT qmfFlags = - (hSbrElement->sbrConfigData.sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) - ? QMF_FLAG_CLDFB - : 0; - if (statesInitFlag) - qmfFlags &= ~QMF_FLAG_KEEP_STATES; - else - qmfFlags |= QMF_FLAG_KEEP_STATES; - - err = qmfInitAnalysisFilterBank( - hSbrElement->hQmfAnalysis[ch], - (FIXP_QAS *)hSbrElement->hQmfAnalysis[ch]->FilterStates, - hSbrElement->sbrConfigData.noQmfSlots, - hSbrElement->sbrConfigData.noQmfBands, - hSbrElement->sbrConfigData.noQmfBands, - hSbrElement->sbrConfigData.noQmfBands, qmfFlags); - if (0 != err) { - return err; - } - } - - /* */ - hSbrElement->CmonData.xOverFreq = hSbrElement->sbrConfigData.xOverFreq; - hSbrElement->CmonData.dynBwEnabled = - (params->dynBwSupported && params->dynBwEnabled); - hSbrElement->CmonData.dynXOverFreqEnc = - FDKsbrEnc_SbrGetXOverFreq(hSbrElement, hSbrElement->CmonData.xOverFreq); - for (i = 0; i < 5; i++) - hSbrElement->dynXOverFreqDelay[i] = hSbrElement->CmonData.dynXOverFreqEnc; - hSbrElement->CmonData.sbrNumChannels = hSbrElement->sbrConfigData.nChannels; - hSbrElement->sbrConfigData.dynXOverFreq = hSbrElement->CmonData.xOverFreq; - - /* Update Bandwith to be passed to the core encoder */ - *coreBandWith = hSbrElement->CmonData.xOverFreq; - - return (0); -} - -INT sbrEncoder_GetInBufferSize(int noChannels) { - INT temp; - - temp = (2048); - temp += 1024 + MAX_SAMPLE_DELAY; - temp *= noChannels; - temp *= sizeof(INT_PCM); - return temp; -} - -/* - * Encode Dummy SBR payload frames to fill the delay lines. - */ -static INT FDKsbrEnc_DelayCompensation(HANDLE_SBR_ENCODER hEnvEnc, - INT_PCM *timeBuffer, - UINT timeBufferBufSize) { - int n, el; - - for (n = hEnvEnc->nBitstrDelay; n > 0; n--) { - for (el = 0; el < hEnvEnc->noElements; el++) { - if (FDKsbrEnc_EnvEncodeFrame( - hEnvEnc, el, - timeBuffer + hEnvEnc->downsampledOffset / hEnvEnc->nChannels, - timeBufferBufSize, NULL, NULL, 1)) - return -1; - } - sbrEncoder_UpdateBuffers(hEnvEnc, timeBuffer, timeBufferBufSize); - } - return 0; -} - -UINT sbrEncoder_LimitBitRate(UINT bitRate, UINT numChannels, - UINT coreSampleRate, AUDIO_OBJECT_TYPE aot) { - UINT newBitRate = bitRate; - INT index; - - FDK_ASSERT(numChannels > 0 && numChannels <= 2); - if (aot == AOT_PS) { - if (numChannels == 1) { - index = getPsTuningTableIndex(bitRate, &newBitRate); - if (index == INVALID_TABLE_IDX) { - bitRate = newBitRate; - } - } else { - return 0; - } - } - index = getSbrTuningTableIndex(bitRate, numChannels, coreSampleRate, aot, - &newBitRate); - if (index != INVALID_TABLE_IDX) { - newBitRate = bitRate; - } - - return newBitRate; -} - -UINT sbrEncoder_IsSingleRatePossible(AUDIO_OBJECT_TYPE aot) { - UINT isPossible = (AOT_PS == aot) ? 0 : 1; - return isPossible; -} - -/*****************************************************************************/ -/* */ -/*functionname: sbrEncoder_Init_delay */ -/*description: Determine Delay balancing and new encoder delay */ -/* */ -/*returns: - error status */ -/*input: - frame length of the core (i.e. e.g. AAC) */ -/* - number of channels */ -/* - downsample factor (1 for downsampled, 2 for dual-rate SBR) */ -/* - low delay presence */ -/* - ps presence */ -/* - downsampling method: QMF-, time domain or no downsampling */ -/* - various delay values (see DELAY_PARAM struct description) */ -/* */ -/*Example: Delay balancing for a HE-AACv1 encoder (time-domain downsampling) */ -/*========================================================================== */ -/* */ -/* +--------+ +--------+ +--------+ +--------+ +--------+ */ -/* |core | |ds 2:1 | |AAC | |QMF | |QMF | */ -/* +-+path +------------+ +-+core +-+analysis+-+overlap +-+ */ -/* | |offset | | | | | |32 bands| | | | */ -/* | +--------+ +--------+ +--------+ +--------+ +--------+ | */ -/* | core path +-------++ */ -/* | |QMF | */ -/*->+ +synth. +-> */ -/* | |64 bands| */ -/* | +-------++ */ -/* | +--------+ +--------+ +--------+ +--------+ | */ -/* | |SBR path| |QMF | |subband | |bs delay| | */ -/* +-+offset +-+analysis+-+sample +-+(full +-----------------------+ */ -/* | | |64 bands| |buffer | | frames)| */ -/* +--------+ +--------+ +--------+ +--------+ */ -/* SBR path */ -/* */ -/*****************************************************************************/ -static INT sbrEncoder_Init_delay( - const int coreFrameLength, /* input */ - const int numChannels, /* input */ - const int downSampleFactor, /* input */ - const int lowDelay, /* input */ - const int usePs, /* input */ - const int is212, /* input */ - const SBRENC_DS_TYPE downsamplingMethod, /* input */ - DELAY_PARAM *hDelayParam /* input/output */ -) { - int delayCorePath = 0; /* delay in core path */ - int delaySbrPath = 0; /* delay difference in QMF aka SBR path */ - int delayInput2Core = 0; /* delay from the input to the core */ - int delaySbrDec = 0; /* delay of the decoder's SBR module */ - - int delayCore = hDelayParam->delay; /* delay of the core */ - - /* Added delay by the SBR delay initialization */ - int corePathOffset = 0; /* core path */ - int sbrPathOffset = 0; /* sbr path */ - int bitstreamDelay = 0; /* sbr path, framewise */ - - int flCore = coreFrameLength; /* core frame length */ - - int returnValue = 0; /* return value - 0 means: no error */ - - /* 1) Calculate actual delay for core and SBR path */ - if (is212) { - delayCorePath = DELAY_COREPATH_ELDv2SBR(flCore, downSampleFactor); - delaySbrPath = DELAY_ELDv2SBR(flCore, downSampleFactor); - delaySbrDec = ((flCore) / 2) * (downSampleFactor); - } else if (lowDelay) { - delayCorePath = DELAY_COREPATH_ELDSBR(flCore, downSampleFactor); - delaySbrPath = DELAY_ELDSBR(flCore, downSampleFactor); - delaySbrDec = DELAY_QMF_POSTPROC(downSampleFactor); - } else if (usePs) { - delayCorePath = DELAY_COREPATH_PS(flCore, downSampleFactor); - delaySbrPath = DELAY_PS(flCore, downSampleFactor); - delaySbrDec = DELAY_COREPATH_SBR(flCore, downSampleFactor); - } else { - delayCorePath = DELAY_COREPATH_SBR(flCore, downSampleFactor); - delaySbrPath = DELAY_SBR(flCore, downSampleFactor); - delaySbrDec = DELAY_COREPATH_SBR(flCore, downSampleFactor); - } - delayCorePath += delayCore * downSampleFactor; - delayCorePath += - (downsamplingMethod == SBRENC_DS_TIME) ? hDelayParam->dsDelay : 0; - - /* 2) Manage coupling of paths */ - if (downsamplingMethod == SBRENC_DS_QMF && delayCorePath > delaySbrPath) { - /* In case of QMF downsampling, both paths are coupled, i.e. the SBR path - offset would be added to both the SBR path and to the core path - as well, thus making it impossible to achieve delay balancing. - To overcome that problem, a framewise delay is added to the SBR path - first, until the overall delay of the core path is shorter than - the delay of the SBR path. When this is achieved, the missing delay - difference can be added as downsampled offset to the core path. - */ - while (delayCorePath > delaySbrPath) { - /* Add one frame delay to SBR path */ - delaySbrPath += flCore * downSampleFactor; - bitstreamDelay += 1; - } - } - - /* 3) Calculate necessary additional delay to balance the paths */ - if (delayCorePath > delaySbrPath) { - /* Delay QMF input */ - while (delayCorePath > delaySbrPath + (int)flCore * (int)downSampleFactor) { - /* Do bitstream frame-wise delay balancing if there are - more than SBR framelength samples delay difference */ - delaySbrPath += flCore * downSampleFactor; - bitstreamDelay += 1; - } - /* Multiply input offset by input channels */ - corePathOffset = 0; - sbrPathOffset = (delayCorePath - delaySbrPath) * numChannels; - } else { - /* Delay AAC data */ - /* Multiply downsampled offset by AAC core channels. Divide by 2 because of - half samplerate of downsampled data. */ - corePathOffset = ((delaySbrPath - delayCorePath) * numChannels) >> - (downSampleFactor - 1); - sbrPathOffset = 0; - } - - /* 4) Calculate delay from input to core */ - if (usePs) { - delayInput2Core = - (DELAY_QMF_ANA(downSampleFactor) + DELAY_QMF_DS + DELAY_HYB_SYN) + - (downSampleFactor * corePathOffset) + 1; - } else if (downsamplingMethod == SBRENC_DS_TIME) { - delayInput2Core = corePathOffset + hDelayParam->dsDelay; - } else { - delayInput2Core = corePathOffset; - } - - /* 6) Set output parameters */ - hDelayParam->delay = FDKmax(delayCorePath, delaySbrPath); /* overall delay */ - hDelayParam->sbrDecDelay = delaySbrDec; /* SBR decoder delay */ - hDelayParam->delayInput2Core = delayInput2Core; /* delay input - core */ - hDelayParam->bitstrDelay = bitstreamDelay; /* bitstream delay, in frames */ - hDelayParam->corePathOffset = corePathOffset; /* offset added to core path */ - hDelayParam->sbrPathOffset = sbrPathOffset; /* offset added to SBR path */ - - return returnValue; -} - -/***************************************************************************** - - functionname: sbrEncoder_Init - description: initializes the SBR encoder - returns: error status - -*****************************************************************************/ -INT sbrEncoder_Init(HANDLE_SBR_ENCODER hSbrEncoder, - SBR_ELEMENT_INFO elInfo[(8)], int noElements, - INT_PCM *inputBuffer, UINT inputBufferBufSize, - INT *coreBandwidth, INT *inputBufferOffset, - INT *numChannels, const UINT syntaxFlags, - INT *coreSampleRate, UINT *downSampleFactor, - INT *frameLength, AUDIO_OBJECT_TYPE aot, int *delay, - int transformFactor, const int headerPeriod, - ULONG statesInitFlag) { - HANDLE_ERROR_INFO errorInfo = noError; - sbrConfiguration sbrConfig[(8)]; - INT error = 0; - INT lowestBandwidth; - /* Save input parameters */ - INT inputSampleRate = *coreSampleRate; - int coreFrameLength = *frameLength; - int inputBandWidth = *coreBandwidth; - int inputChannels = *numChannels; - - SBRENC_DS_TYPE downsamplingMethod = SBRENC_DS_NONE; - int highestSbrStartFreq, highestSbrStopFreq; - int lowDelay = 0; - int usePs = 0; - int is212 = 0; - - DELAY_PARAM delayParam; - - /* check whether SBR setting is available for the current encoder - * configuration (bitrate, samplerate) */ - if (!sbrEncoder_IsSingleRatePossible(aot)) { - *downSampleFactor = 2; - } - - if (aot == AOT_PS) { - usePs = 1; - } - if (aot == AOT_ER_AAC_ELD) { - lowDelay = 1; - } else if (aot == AOT_ER_AAC_LD) { - error = 1; - goto bail; - } - - /* Parametric Stereo */ - if (usePs) { - if (*numChannels == 2 && noElements == 1) { - /* Override Element type in case of Parametric stereo */ - elInfo[0].elType = ID_SCE; - elInfo[0].fParametricStereo = 1; - elInfo[0].nChannelsInEl = 1; - /* core encoder gets downmixed mono signal */ - *numChannels = 1; - } else { - error = 1; - goto bail; - } - } /* usePs */ - - /* set the core's sample rate */ - switch (*downSampleFactor) { - case 1: - *coreSampleRate = inputSampleRate; - downsamplingMethod = SBRENC_DS_NONE; - break; - case 2: - *coreSampleRate = inputSampleRate >> 1; - downsamplingMethod = usePs ? SBRENC_DS_QMF : SBRENC_DS_TIME; - break; - default: - *coreSampleRate = inputSampleRate >> 1; - return 0; /* return error */ - } - - /* check whether SBR setting is available for the current encoder - * configuration (bitrate, coreSampleRate) */ - { - int el, coreEl; - - /* Check if every element config is feasible */ - for (coreEl = 0; coreEl < noElements; coreEl++) { - /* SBR only handles SCE and CPE's */ - if (elInfo[coreEl].elType != ID_SCE && elInfo[coreEl].elType != ID_CPE) { - continue; - } - /* check if desired configuration is available */ - if (!FDKsbrEnc_IsSbrSettingAvail(elInfo[coreEl].bitRate, 0, - elInfo[coreEl].nChannelsInEl, - inputSampleRate, *coreSampleRate, aot)) { - error = 1; - goto bail; - } - } - - hSbrEncoder->nChannels = *numChannels; - hSbrEncoder->frameSize = coreFrameLength * *downSampleFactor; - hSbrEncoder->downsamplingMethod = downsamplingMethod; - hSbrEncoder->downSampleFactor = *downSampleFactor; - hSbrEncoder->estimateBitrate = 0; - hSbrEncoder->inputDataDelay = 0; - is212 = ((aot == AOT_ER_AAC_ELD) && (syntaxFlags & AC_LD_MPS)) ? 1 : 0; - - /* Open SBR elements */ - el = -1; - highestSbrStartFreq = highestSbrStopFreq = 0; - lowestBandwidth = 99999; - - /* Loop through each core encoder element and get a matching SBR element - * config */ - for (coreEl = 0; coreEl < noElements; coreEl++) { - /* SBR only handles SCE and CPE's */ - if (elInfo[coreEl].elType == ID_SCE || elInfo[coreEl].elType == ID_CPE) { - el++; - } else { - continue; - } - - /* Set parametric Stereo Flag. */ - if (usePs) { - elInfo[coreEl].fParametricStereo = 1; - } else { - elInfo[coreEl].fParametricStereo = 0; - } - - /* - * Init sbrConfig structure - */ - if (!FDKsbrEnc_InitializeSbrDefaults(&sbrConfig[el], *downSampleFactor, - coreFrameLength, IS_LOWDELAY(aot))) { - error = 1; - goto bail; - } - - /* - * Modify sbrConfig structure according to Element parameters - */ - if (!FDKsbrEnc_AdjustSbrSettings( - &sbrConfig[el], elInfo[coreEl].bitRate, - elInfo[coreEl].nChannelsInEl, *coreSampleRate, inputSampleRate, - transformFactor, 24000, 0, 0, /* useSpeechConfig */ - 0, /* lcsMode */ - usePs, /* bParametricStereo */ - aot)) { - error = 1; - goto bail; - } - - /* Find common frequency border for all SBR elements */ - highestSbrStartFreq = - fixMax(highestSbrStartFreq, sbrConfig[el].startFreq); - highestSbrStopFreq = fixMax(highestSbrStopFreq, sbrConfig[el].stopFreq); - - } /* first element loop */ - - /* Set element count (can be less than core encoder element count) */ - hSbrEncoder->noElements = el + 1; - - FDKsbrEnc_Reallocate(hSbrEncoder, elInfo, noElements); - - for (el = 0; el < hSbrEncoder->noElements; el++) { - int bandwidth = *coreBandwidth; - - /* Use lowest common bandwidth */ - sbrConfig[el].startFreq = highestSbrStartFreq; - sbrConfig[el].stopFreq = highestSbrStopFreq; - - /* initialize SBR element, and get core bandwidth */ - error = FDKsbrEnc_EnvInit(hSbrEncoder->sbrElement[el], &sbrConfig[el], - &bandwidth, aot, el, headerPeriod, - statesInitFlag, hSbrEncoder->downsamplingMethod, - hSbrEncoder->dynamicRam); - - if (error != 0) { - error = 2; - goto bail; - } - - /* Get lowest core encoder bandwidth to be returned later. */ - lowestBandwidth = fixMin(lowestBandwidth, bandwidth); - - } /* second element loop */ - - /* Initialize a downsampler for each channel in each SBR element */ - if (hSbrEncoder->downsamplingMethod == SBRENC_DS_TIME) { - for (el = 0; el < hSbrEncoder->noElements; el++) { - HANDLE_SBR_ELEMENT hSbrEl = hSbrEncoder->sbrElement[el]; - INT Wc, ch; - - Wc = 500; /* Cutoff frequency with full bandwidth */ - - for (ch = 0; ch < hSbrEl->elInfo.nChannelsInEl; ch++) { - FDKaacEnc_InitDownsampler(&hSbrEl->sbrChannel[ch]->downSampler, Wc, - *downSampleFactor); - FDK_ASSERT(hSbrEl->sbrChannel[ch]->downSampler.delay <= - MAX_DS_FILTER_DELAY); - } - } /* third element loop */ - - /* lfe */ - FDKaacEnc_InitDownsampler(&hSbrEncoder->lfeDownSampler, 0, - *downSampleFactor); - } - - /* Get delay information */ - delayParam.dsDelay = - hSbrEncoder->sbrElement[0]->sbrChannel[0]->downSampler.delay; - delayParam.delay = *delay; - - error = sbrEncoder_Init_delay(coreFrameLength, *numChannels, - *downSampleFactor, lowDelay, usePs, is212, - downsamplingMethod, &delayParam); - - if (error != 0) { - error = 3; - goto bail; - } - - hSbrEncoder->nBitstrDelay = delayParam.bitstrDelay; - hSbrEncoder->sbrDecDelay = delayParam.sbrDecDelay; - hSbrEncoder->inputDataDelay = delayParam.delayInput2Core; - - /* Assign core encoder Bandwidth */ - *coreBandwidth = lowestBandwidth; - - /* Estimate sbr bitrate, 2.5 kBit/s per sbr channel */ - hSbrEncoder->estimateBitrate += 2500 * (*numChannels); - - /* Initialize bitstream buffer for each element */ - for (el = 0; el < hSbrEncoder->noElements; el++) { - FDKsbrEnc_bsBufInit(hSbrEncoder->sbrElement[el], delayParam.bitstrDelay); - } - - /* initialize parametric stereo */ - if (usePs) { - PSENC_CONFIG psEncConfig; - FDK_ASSERT(hSbrEncoder->noElements == 1); - INT psTuningTableIdx = getPsTuningTableIndex(elInfo[0].bitRate, NULL); - - psEncConfig.frameSize = coreFrameLength; // sbrConfig.sbrFrameSize; - psEncConfig.qmfFilterMode = 0; - psEncConfig.sbrPsDelay = 0; - - /* tuning parameters */ - if (psTuningTableIdx != INVALID_TABLE_IDX) { - psEncConfig.nStereoBands = psTuningTable[psTuningTableIdx].nStereoBands; - psEncConfig.maxEnvelopes = psTuningTable[psTuningTableIdx].nEnvelopes; - psEncConfig.iidQuantErrorThreshold = - (FIXP_DBL)psTuningTable[psTuningTableIdx].iidQuantErrorThreshold; - - /* calculation is not quite linear, increased number of envelopes causes - * more bits */ - /* assume avg. 50 bits per frame for 10 stereo bands / 1 envelope - * configuration */ - hSbrEncoder->estimateBitrate += - ((((*coreSampleRate) * 5 * psEncConfig.nStereoBands * - psEncConfig.maxEnvelopes) / - hSbrEncoder->frameSize)); - - } else { - error = ERROR(CDI, "Invalid ps tuning table index."); - goto bail; - } - - qmfInitSynthesisFilterBank( - &hSbrEncoder->qmfSynthesisPS, - (FIXP_DBL *)hSbrEncoder->qmfSynthesisPS.FilterStates, - hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfSlots, - hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands >> 1, - hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands >> 1, - hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands >> 1, - (statesInitFlag) ? 0 : QMF_FLAG_KEEP_STATES); - - if (errorInfo == noError) { - /* update delay */ - psEncConfig.sbrPsDelay = - FDKsbrEnc_GetEnvEstDelay(&hSbrEncoder->sbrElement[0] - ->sbrChannel[0] - ->hEnvChannel.sbrExtractEnvelope); - - errorInfo = - PSEnc_Init(hSbrEncoder->hParametricStereo, &psEncConfig, - hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfSlots, - hSbrEncoder->sbrElement[0]->sbrConfigData.noQmfBands, - hSbrEncoder->dynamicRam); - } - } - - hSbrEncoder->downsampledOffset = delayParam.corePathOffset; - hSbrEncoder->bufferOffset = delayParam.sbrPathOffset; - *delay = delayParam.delay; - - { hSbrEncoder->downmixSize = coreFrameLength * (*numChannels); } - - /* Delay Compensation: fill bitstream delay buffer with zero input signal */ - if (hSbrEncoder->nBitstrDelay > 0) { - error = FDKsbrEnc_DelayCompensation(hSbrEncoder, inputBuffer, - inputBufferBufSize); - if (error != 0) goto bail; - } - - /* Set Output frame length */ - *frameLength = coreFrameLength * *downSampleFactor; - /* Input buffer offset */ - *inputBufferOffset = - fixMax(delayParam.sbrPathOffset, delayParam.corePathOffset); - } - - return error; - -bail: - /* Restore input settings */ - *coreSampleRate = inputSampleRate; - *frameLength = coreFrameLength; - *numChannels = inputChannels; - *coreBandwidth = inputBandWidth; - - return error; -} - -INT sbrEncoder_EncodeFrame(HANDLE_SBR_ENCODER hSbrEncoder, INT_PCM *samples, - UINT samplesBufSize, UINT sbrDataBits[(8)], - UCHAR sbrData[(8)][MAX_PAYLOAD_SIZE]) { - INT error; - int el; - - for (el = 0; el < hSbrEncoder->noElements; el++) { - if (hSbrEncoder->sbrElement[el] != NULL) { - error = FDKsbrEnc_EnvEncodeFrame( - hSbrEncoder, el, - samples + hSbrEncoder->downsampledOffset / hSbrEncoder->nChannels, - samplesBufSize, &sbrDataBits[el], sbrData[el], 0); - if (error) return error; - } - } - - error = FDKsbrEnc_Downsample( - hSbrEncoder, - samples + hSbrEncoder->downsampledOffset / hSbrEncoder->nChannels, - samplesBufSize, hSbrEncoder->nChannels, &sbrDataBits[el], sbrData[el], 0); - if (error) return error; - - return 0; -} - -INT sbrEncoder_UpdateBuffers(HANDLE_SBR_ENCODER hSbrEncoder, - INT_PCM *timeBuffer, UINT timeBufferBufSize) { - if (hSbrEncoder->downsampledOffset > 0) { - int c; - int nd = hSbrEncoder->downmixSize / hSbrEncoder->nChannels; - - for (c = 0; c < hSbrEncoder->nChannels; c++) { - /* Move delayed downsampled data */ - FDKmemcpy(timeBuffer + timeBufferBufSize * c, - timeBuffer + timeBufferBufSize * c + nd, - sizeof(INT_PCM) * - (hSbrEncoder->downsampledOffset / hSbrEncoder->nChannels)); - } - } else { - int c; - - for (c = 0; c < hSbrEncoder->nChannels; c++) { - /* Move delayed input data */ - FDKmemcpy( - timeBuffer + timeBufferBufSize * c, - timeBuffer + timeBufferBufSize * c + hSbrEncoder->frameSize, - sizeof(INT_PCM) * hSbrEncoder->bufferOffset / hSbrEncoder->nChannels); - } - } - if (hSbrEncoder->nBitstrDelay > 0) { - int el; - - for (el = 0; el < hSbrEncoder->noElements; el++) { - FDKmemmove( - hSbrEncoder->sbrElement[el]->payloadDelayLine[0], - hSbrEncoder->sbrElement[el]->payloadDelayLine[1], - sizeof(UCHAR) * (hSbrEncoder->nBitstrDelay * MAX_PAYLOAD_SIZE)); - - FDKmemmove(&hSbrEncoder->sbrElement[el]->payloadDelayLineSize[0], - &hSbrEncoder->sbrElement[el]->payloadDelayLineSize[1], - sizeof(UINT) * (hSbrEncoder->nBitstrDelay)); - } - } - return 0; -} - -INT sbrEncoder_SendHeader(HANDLE_SBR_ENCODER hSbrEncoder) { - INT error = -1; - if (hSbrEncoder) { - int el; - for (el = 0; el < hSbrEncoder->noElements; el++) { - if ((hSbrEncoder->noElements == 1) && - (hSbrEncoder->sbrElement[0]->elInfo.fParametricStereo == 1)) { - hSbrEncoder->sbrElement[el]->sbrBitstreamData.CountSendHeaderData = - hSbrEncoder->sbrElement[el]->sbrBitstreamData.NrSendHeaderData - 1; - } else { - hSbrEncoder->sbrElement[el]->sbrBitstreamData.CountSendHeaderData = 0; - } - } - error = 0; - } - return error; -} - -INT sbrEncoder_ContainsHeader(HANDLE_SBR_ENCODER hSbrEncoder) { - INT sbrHeader = 1; - if (hSbrEncoder) { - int el; - for (el = 0; el < hSbrEncoder->noElements; el++) { - sbrHeader &= - (hSbrEncoder->sbrElement[el]->sbrBitstreamData.HeaderActiveDelay == 1) - ? 1 - : 0; - } - } - return sbrHeader; -} - -INT sbrEncoder_GetHeaderDelay(HANDLE_SBR_ENCODER hSbrEncoder) { - INT delay = -1; - - if (hSbrEncoder) { - if ((hSbrEncoder->noElements == 1) && - (hSbrEncoder->sbrElement[0]->elInfo.fParametricStereo == 1)) { - delay = hSbrEncoder->nBitstrDelay + 1; - } else { - delay = hSbrEncoder->nBitstrDelay; - } - } - return delay; -} -INT sbrEncoder_GetBsDelay(HANDLE_SBR_ENCODER hSbrEncoder) { - INT delay = -1; - - if (hSbrEncoder) { - delay = hSbrEncoder->nBitstrDelay; - } - return delay; -} - -INT sbrEncoder_SAPPrepare(HANDLE_SBR_ENCODER hSbrEncoder) { - INT error = -1; - if (hSbrEncoder) { - int el; - for (el = 0; el < hSbrEncoder->noElements; el++) { - hSbrEncoder->sbrElement[el]->sbrBitstreamData.rightBorderFIX = 1; - } - error = 0; - } - return error; -} - -INT sbrEncoder_GetEstimateBitrate(HANDLE_SBR_ENCODER hSbrEncoder) { - INT estimateBitrate = 0; - - if (hSbrEncoder) { - estimateBitrate += hSbrEncoder->estimateBitrate; - } - - return estimateBitrate; -} - -INT sbrEncoder_GetInputDataDelay(HANDLE_SBR_ENCODER hSbrEncoder) { - INT delay = -1; - - if (hSbrEncoder) { - delay = hSbrEncoder->inputDataDelay; - } - return delay; -} - -INT sbrEncoder_GetSbrDecDelay(HANDLE_SBR_ENCODER hSbrEncoder) { - INT delay = -1; - - if (hSbrEncoder) { - delay = hSbrEncoder->sbrDecDelay; - } - return delay; -} - -INT sbrEncoder_GetLibInfo(LIB_INFO *info) { - int i; - - if (info == NULL) { - return -1; - } - /* search for next free tab */ - for (i = 0; i < FDK_MODULE_LAST; i++) { - if (info[i].module_id == FDK_NONE) break; - } - if (i == FDK_MODULE_LAST) { - return -1; - } - info += i; - - info->module_id = FDK_SBRENC; - info->version = - LIB_VERSION(SBRENCODER_LIB_VL0, SBRENCODER_LIB_VL1, SBRENCODER_LIB_VL2); - LIB_VERSION_STRING(info); -#ifdef __ANDROID__ - info->build_date = ""; - info->build_time = ""; -#else - info->build_date = __DATE__; - info->build_time = __TIME__; -#endif - info->title = "SBR Encoder"; - - /* Set flags */ - info->flags = 0 | CAPF_SBR_HQ | CAPF_SBR_PS_MPEG; - /* End of flags */ - - return 0; -} --- a/libSBRenc/src/sbr_misc.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Sbr miscellaneous helper functions $Revision: 36750 $ -*/ -#include "sbr_misc.h" - -void FDKsbrEnc_Shellsort_fract(FIXP_DBL *in, INT n) { - FIXP_DBL v; - INT i, j; - INT inc = 1; - - do - inc = 3 * inc + 1; - while (inc <= n); - - do { - inc = inc / 3; - for (i = inc + 1; i <= n; i++) { - v = in[i - 1]; - j = i; - while (in[j - inc - 1] > v) { - in[j - 1] = in[j - inc - 1]; - j -= inc; - if (j <= inc) break; - } - in[j - 1] = v; - } - } while (inc > 1); -} - -/* Sorting routine */ -void FDKsbrEnc_Shellsort_int(INT *in, INT n) { - INT i, j, v; - INT inc = 1; - - do - inc = 3 * inc + 1; - while (inc <= n); - - do { - inc = inc / 3; - for (i = inc + 1; i <= n; i++) { - v = in[i - 1]; - j = i; - while (in[j - inc - 1] > v) { - in[j - 1] = in[j - inc - 1]; - j -= inc; - if (j <= inc) break; - } - in[j - 1] = v; - } - } while (inc > 1); -} - -/******************************************************************************* - Functionname: FDKsbrEnc_AddVecLeft - ******************************************************************************* - - Description: - - Arguments: INT* dst, INT* length_dst, INT* src, INT length_src - - Return: none - -*******************************************************************************/ -void FDKsbrEnc_AddVecLeft(INT *dst, INT *length_dst, INT *src, INT length_src) { - INT i; - - for (i = length_src - 1; i >= 0; i--) - FDKsbrEnc_AddLeft(dst, length_dst, src[i]); -} - -/******************************************************************************* - Functionname: FDKsbrEnc_AddLeft - ******************************************************************************* - - Description: - - Arguments: INT* vector, INT* length_vector, INT value - - Return: none - -*******************************************************************************/ -void FDKsbrEnc_AddLeft(INT *vector, INT *length_vector, INT value) { - INT i; - - for (i = *length_vector; i > 0; i--) vector[i] = vector[i - 1]; - vector[0] = value; - (*length_vector)++; -} - -/******************************************************************************* - Functionname: FDKsbrEnc_AddRight - ******************************************************************************* - - Description: - - Arguments: INT* vector, INT* length_vector, INT value - - Return: none - -*******************************************************************************/ -void FDKsbrEnc_AddRight(INT *vector, INT *length_vector, INT value) { - vector[*length_vector] = value; - (*length_vector)++; -} - -/******************************************************************************* - Functionname: FDKsbrEnc_AddVecRight - ******************************************************************************* - - Description: - - Arguments: INT* dst, INT* length_dst, INT* src, INT length_src) - - Return: none - -*******************************************************************************/ -void FDKsbrEnc_AddVecRight(INT *dst, INT *length_dst, INT *src, - INT length_src) { - INT i; - for (i = 0; i < length_src; i++) FDKsbrEnc_AddRight(dst, length_dst, src[i]); -} - -/***************************************************************************** - - functionname: FDKsbrEnc_LSI_divide_scale_fract - - description: Calculates division with best precision and scales the result. - - return: num*scale/denom - -*****************************************************************************/ -FIXP_DBL FDKsbrEnc_LSI_divide_scale_fract(FIXP_DBL num, FIXP_DBL denom, - FIXP_DBL scale) { - FIXP_DBL tmp = FL2FXCONST_DBL(0.0f); - if (num != FL2FXCONST_DBL(0.0f)) { - INT shiftCommon; - INT shiftNum = CountLeadingBits(num); - INT shiftDenom = CountLeadingBits(denom); - INT shiftScale = CountLeadingBits(scale); - - num = num << shiftNum; - scale = scale << shiftScale; - - tmp = fMultDiv2(num, scale); - - if (denom > (tmp >> fixMin(shiftNum + shiftScale - 1, (DFRACT_BITS - 1)))) { - denom = denom << shiftDenom; - tmp = schur_div(tmp, denom, 15); - shiftCommon = - fixMin((shiftNum - shiftDenom + shiftScale - 1), (DFRACT_BITS - 1)); - if (shiftCommon < 0) - tmp <<= -shiftCommon; - else - tmp >>= shiftCommon; - } else { - tmp = /*FL2FXCONST_DBL(1.0)*/ (FIXP_DBL)MAXVAL_DBL; - } - } - - return (tmp); -} --- a/libSBRenc/src/sbr_misc.h +++ /dev/null @@ -1,127 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Sbr miscellaneous helper functions prototypes $Revision: 92790 $ - \author -*/ - -#ifndef SBR_MISC_H -#define SBR_MISC_H - -#include "sbr_encoder.h" - -/* Sorting routines */ -void FDKsbrEnc_Shellsort_fract(FIXP_DBL *in, INT n); -void FDKsbrEnc_Shellsort_int(INT *in, INT n); - -void FDKsbrEnc_AddLeft(INT *vector, INT *length_vector, INT value); -void FDKsbrEnc_AddRight(INT *vector, INT *length_vector, INT value); -void FDKsbrEnc_AddVecLeft(INT *dst, INT *length_dst, INT *src, INT length_src); -void FDKsbrEnc_AddVecRight(INT *dst, INT *length_vector_dst, INT *src, - INT length_src); - -FIXP_DBL FDKsbrEnc_LSI_divide_scale_fract(FIXP_DBL num, FIXP_DBL denom, - FIXP_DBL scale); - -#endif --- a/libSBRenc/src/sbrenc_freq_sca.cpp +++ /dev/null @@ -1,674 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief frequency scale $Revision: 95225 $ -*/ - -#include "sbrenc_freq_sca.h" -#include "sbr_misc.h" - -#include "genericStds.h" - -/* StartFreq */ -static INT getStartFreq(INT fsCore, const INT start_freq); - -/* StopFreq */ -static INT getStopFreq(INT fsCore, const INT stop_freq); - -static INT numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor); -static void CalcBands(INT *diff, INT start, INT stop, INT num_bands); -static INT modifyBands(INT max_band, INT *diff, INT length); -static void cumSum(INT start_value, INT *diff, INT length, UCHAR *start_adress); - -/******************************************************************************* - Functionname: FDKsbrEnc_getSbrStartFreqRAW - ******************************************************************************* - Description: - - Arguments: - - Return: - *******************************************************************************/ - -INT FDKsbrEnc_getSbrStartFreqRAW(INT startFreq, INT fsCore) { - INT result; - - if (startFreq < 0 || startFreq > 15) { - return -1; - } - /* Update startFreq struct */ - result = getStartFreq(fsCore, startFreq); - - result = - (result * (fsCore >> 5) + 1) >> 1; /* (result*fsSBR/QMFbands+1)>>1; */ - - return (result); - -} /* End FDKsbrEnc_getSbrStartFreqRAW */ - -/******************************************************************************* - Functionname: getSbrStopFreq - ******************************************************************************* - Description: - - Arguments: - - Return: - *******************************************************************************/ -INT FDKsbrEnc_getSbrStopFreqRAW(INT stopFreq, INT fsCore) { - INT result; - - if (stopFreq < 0 || stopFreq > 13) return -1; - - /* Uppdate stopFreq struct */ - result = getStopFreq(fsCore, stopFreq); - result = - (result * (fsCore >> 5) + 1) >> 1; /* (result*fsSBR/QMFbands+1)>>1; */ - - return (result); -} /* End getSbrStopFreq */ - -/******************************************************************************* - Functionname: getStartFreq - ******************************************************************************* - Description: - - Arguments: fsCore - core sampling rate - - - Return: - *******************************************************************************/ -static INT getStartFreq(INT fsCore, const INT start_freq) { - INT k0_min; - - switch (fsCore) { - case 8000: - k0_min = 24; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */ - break; - case 11025: - k0_min = 17; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */ - break; - case 12000: - k0_min = 16; /* (3000 * nQmfChannels / fsSBR ) + 0.5 */ - break; - case 16000: - k0_min = 16; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */ - break; - case 22050: - k0_min = 12; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */ - break; - case 24000: - k0_min = 11; /* (4000 * nQmfChannels / fsSBR ) + 0.5 */ - break; - case 32000: - k0_min = 10; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */ - break; - case 44100: - k0_min = 7; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */ - break; - case 48000: - k0_min = 7; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */ - break; - case 96000: - k0_min = 3; /* (5000 * nQmfChannels / fsSBR ) + 0.5 */ - break; - default: - k0_min = 11; /* illegal fs */ - } - - switch (fsCore) { - case 8000: { - INT v_offset[] = {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7}; - return (k0_min + v_offset[start_freq]); - } - case 11025: { - INT v_offset[] = {-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13}; - return (k0_min + v_offset[start_freq]); - } - case 12000: { - INT v_offset[] = {-5, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}; - return (k0_min + v_offset[start_freq]); - } - case 16000: { - INT v_offset[] = {-6, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16}; - return (k0_min + v_offset[start_freq]); - } - case 22050: - case 24000: - case 32000: { - INT v_offset[] = {-4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20}; - return (k0_min + v_offset[start_freq]); - } - case 44100: - case 48000: - case 96000: { - INT v_offset[] = {-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24}; - return (k0_min + v_offset[start_freq]); - } - default: { - INT v_offset[] = {0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24, 28, 33}; - return (k0_min + v_offset[start_freq]); - } - } -} /* End getStartFreq */ - -/******************************************************************************* - Functionname: getStopFreq - ******************************************************************************* - Description: - - Arguments: - - Return: - *******************************************************************************/ -static INT getStopFreq(INT fsCore, const INT stop_freq) { - INT result, i; - INT k1_min; - INT v_dstop[13]; - - INT *v_stop_freq = NULL; - INT v_stop_freq_16[14] = {48, 49, 50, 51, 52, 54, 55, - 56, 57, 59, 60, 61, 63, 64}; - INT v_stop_freq_22[14] = {35, 37, 38, 40, 42, 44, 46, - 48, 51, 53, 56, 58, 61, 64}; - INT v_stop_freq_24[14] = {32, 34, 36, 38, 40, 42, 44, - 46, 49, 52, 55, 58, 61, 64}; - INT v_stop_freq_32[14] = {32, 34, 36, 38, 40, 42, 44, - 46, 49, 52, 55, 58, 61, 64}; - INT v_stop_freq_44[14] = {23, 25, 27, 29, 32, 34, 37, - 40, 43, 47, 51, 55, 59, 64}; - INT v_stop_freq_48[14] = {21, 23, 25, 27, 30, 32, 35, - 38, 42, 45, 49, 54, 59, 64}; - INT v_stop_freq_64[14] = {20, 22, 24, 26, 29, 31, 34, - 37, 41, 45, 49, 54, 59, 64}; - INT v_stop_freq_88[14] = {15, 17, 19, 21, 23, 26, 29, - 33, 37, 41, 46, 51, 57, 64}; - INT v_stop_freq_96[14] = {13, 15, 17, 19, 21, 24, 27, - 31, 35, 39, 44, 50, 57, 64}; - INT v_stop_freq_192[14] = {7, 8, 10, 12, 14, 16, 19, - 23, 27, 32, 38, 46, 54, 64}; - - switch (fsCore) { - case 8000: - k1_min = 48; - v_stop_freq = v_stop_freq_16; - break; - case 11025: - k1_min = 35; - v_stop_freq = v_stop_freq_22; - break; - case 12000: - k1_min = 32; - v_stop_freq = v_stop_freq_24; - break; - case 16000: - k1_min = 32; - v_stop_freq = v_stop_freq_32; - break; - case 22050: - k1_min = 23; - v_stop_freq = v_stop_freq_44; - break; - case 24000: - k1_min = 21; - v_stop_freq = v_stop_freq_48; - break; - case 32000: - k1_min = 20; - v_stop_freq = v_stop_freq_64; - break; - case 44100: - k1_min = 15; - v_stop_freq = v_stop_freq_88; - break; - case 48000: - k1_min = 13; - v_stop_freq = v_stop_freq_96; - break; - case 96000: - k1_min = 7; - v_stop_freq = v_stop_freq_192; - break; - default: - k1_min = 21; /* illegal fs */ - } - - /* Ensure increasing bandwidth */ - for (i = 0; i <= 12; i++) { - v_dstop[i] = v_stop_freq[i + 1] - v_stop_freq[i]; - } - - FDKsbrEnc_Shellsort_int(v_dstop, 13); /* Sort bandwidth changes */ - - result = k1_min; - for (i = 0; i < stop_freq; i++) { - result = result + v_dstop[i]; - } - - return (result); - -} /* End getStopFreq */ - -/******************************************************************************* - Functionname: FDKsbrEnc_FindStartAndStopBand - ******************************************************************************* - Description: - - Arguments: srSbr SBR sampling freqency - srCore AAC core sampling freqency - noChannels Number of QMF channels - startFreq SBR start frequency in QMF bands - stopFreq SBR start frequency in QMF bands - - *k0 Output parameter - *k2 Output parameter - - Return: Error code (0 is OK) - *******************************************************************************/ -INT FDKsbrEnc_FindStartAndStopBand(const INT srSbr, const INT srCore, - const INT noChannels, const INT startFreq, - const INT stopFreq, INT *k0, INT *k2) { - /* Update startFreq struct */ - *k0 = getStartFreq(srCore, startFreq); - - /* Test if start freq is outside corecoder range */ - if (srSbr * noChannels < *k0 * srCore) { - return ( - 1); /* raise the cross-over frequency and/or lower the number - of target bands per octave (or lower the sampling frequency) */ - } - - /*Update stopFreq struct */ - if (stopFreq < 14) { - *k2 = getStopFreq(srCore, stopFreq); - } else if (stopFreq == 14) { - *k2 = 2 * *k0; - } else { - *k2 = 3 * *k0; - } - - /* limit to Nyqvist */ - if (*k2 > noChannels) { - *k2 = noChannels; - } - - /* Test for invalid k0 k2 combinations */ - if ((srCore == 22050) && ((*k2 - *k0) > MAX_FREQ_COEFFS_FS44100)) - return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for - fs=44.1kHz */ - - if ((srCore >= 24000) && ((*k2 - *k0) > MAX_FREQ_COEFFS_FS48000)) - return (1); /* Number of bands exceeds valid range of MAX_FREQ_COEFFS for - fs>=48kHz */ - - if ((*k2 - *k0) > MAX_FREQ_COEFFS) - return (1); /*Number of bands exceeds valid range of MAX_FREQ_COEFFS */ - - if ((*k2 - *k0) < 0) return (1); /* Number of bands is negative */ - - return (0); -} - -/******************************************************************************* - Functionname: FDKsbrEnc_UpdateFreqScale - ******************************************************************************* - Description: - - Arguments: - - Return: - *******************************************************************************/ -INT FDKsbrEnc_UpdateFreqScale(UCHAR *v_k_master, INT *h_num_bands, const INT k0, - const INT k2, const INT freqScale, - const INT alterScale) - -{ - INT b_p_o = 0; /* bands_per_octave */ - FIXP_DBL warp = FL2FXCONST_DBL(0.0f); - INT dk = 0; - - /* Internal variables */ - INT k1 = 0, i; - INT num_bands0; - INT num_bands1; - INT diff_tot[MAX_OCTAVE + MAX_SECOND_REGION]; - INT *diff0 = diff_tot; - INT *diff1 = diff_tot + MAX_OCTAVE; - INT k2_achived; - INT k2_diff; - INT incr = 0; - - /* Init */ - if (freqScale == 1) b_p_o = 12; - if (freqScale == 2) b_p_o = 10; - if (freqScale == 3) b_p_o = 8; - - if (freqScale > 0) /*Bark*/ - { - if (alterScale == 0) - warp = FL2FXCONST_DBL(0.5f); /* 1.0/(1.0*2.0) */ - else - warp = FL2FXCONST_DBL(1.0f / 2.6f); /* 1.0/(1.3*2.0); */ - - if (4 * k2 >= 9 * k0) /*two or more regions (how many times the basis band - is copied)*/ - { - k1 = 2 * k0; - - num_bands0 = numberOfBands(b_p_o, k0, k1, FL2FXCONST_DBL(0.5f)); - num_bands1 = numberOfBands(b_p_o, k1, k2, warp); - - CalcBands(diff0, k0, k1, num_bands0); /*CalcBands1 => diff0 */ - FDKsbrEnc_Shellsort_int(diff0, num_bands0); /*SortBands sort diff0 */ - - if (diff0[0] == 0) /* too wide FB bands for target tuning */ - { - return (1); /* raise the cross-over frequency and/or lower the number - of target bands per octave (or lower the sampling - frequency */ - } - - cumSum(k0, diff0, num_bands0, v_k_master); /* cumsum */ - - CalcBands(diff1, k1, k2, num_bands1); /* CalcBands2 => diff1 */ - FDKsbrEnc_Shellsort_int(diff1, num_bands1); /* SortBands sort diff1 */ - if (diff0[num_bands0 - 1] > diff1[0]) /* max(1) > min(2) */ - { - if (modifyBands(diff0[num_bands0 - 1], diff1, num_bands1)) return (1); - } - - /* Add 2'nd region */ - cumSum(k1, diff1, num_bands1, &v_k_master[num_bands0]); - *h_num_bands = num_bands0 + num_bands1; /* Output nr of bands */ - - } else /* one region */ - { - k1 = k2; - - num_bands0 = numberOfBands(b_p_o, k0, k1, FL2FXCONST_DBL(0.5f)); - CalcBands(diff0, k0, k1, num_bands0); /* CalcBands1 => diff0 */ - FDKsbrEnc_Shellsort_int(diff0, num_bands0); /* SortBands sort diff0 */ - - if (diff0[0] == 0) /* too wide FB bands for target tuning */ - { - return (1); /* raise the cross-over frequency and/or lower the number - of target bands per octave (or lower the sampling - frequency */ - } - - cumSum(k0, diff0, num_bands0, v_k_master); /* cumsum */ - *h_num_bands = num_bands0; /* Output nr of bands */ - } - } else /* Linear mode */ - { - if (alterScale == 0) { - dk = 1; - num_bands0 = 2 * ((k2 - k0) / 2); /* FLOOR to get to few number of bands*/ - } else { - dk = 2; - num_bands0 = - 2 * (((k2 - k0) / dk + 1) / 2); /* ROUND to get closest fit */ - } - - k2_achived = k0 + num_bands0 * dk; - k2_diff = k2 - k2_achived; - - for (i = 0; i < num_bands0; i++) diff_tot[i] = dk; - - /* If linear scale wasn't achived */ - /* and we got wide SBR are */ - if (k2_diff < 0) { - incr = 1; - i = 0; - } - - /* If linear scale wasn't achived */ - /* and we got small SBR are */ - if (k2_diff > 0) { - incr = -1; - i = num_bands0 - 1; - } - - /* Adjust diff vector to get sepc. SBR range */ - while (k2_diff != 0) { - diff_tot[i] = diff_tot[i] - incr; - i = i + incr; - k2_diff = k2_diff + incr; - } - - cumSum(k0, diff_tot, num_bands0, v_k_master); /* cumsum */ - *h_num_bands = num_bands0; /* Output nr of bands */ - } - - if (*h_num_bands < 1) return (1); /*To small sbr area */ - - return (0); -} /* End FDKsbrEnc_UpdateFreqScale */ - -static INT numberOfBands(INT b_p_o, INT start, INT stop, FIXP_DBL warp_factor) { - INT result = 0; - /* result = 2* (INT) ( (double)b_p_o * - * (double)(FDKlog((double)stop/(double)start)/FDKlog((double)2)) * - * (double)FX_DBL2FL(warp_factor) + 0.5); */ - result = ((b_p_o * fMult((CalcLdInt(stop) - CalcLdInt(start)), warp_factor) + - (FL2FX_DBL(0.5f) >> LD_DATA_SHIFT)) >> - ((DFRACT_BITS - 1) - LD_DATA_SHIFT)) - << 1; /* do not optimize anymore (rounding!!) */ - - return (result); -} - -static void CalcBands(INT *diff, INT start, INT stop, INT num_bands) { - INT i, qb, qe, qtmp; - INT previous; - INT current; - FIXP_DBL base, exp, tmp; - - previous = start; - for (i = 1; i <= num_bands; i++) { - base = fDivNorm((FIXP_DBL)stop, (FIXP_DBL)start, &qb); - exp = fDivNorm((FIXP_DBL)i, (FIXP_DBL)num_bands, &qe); - tmp = fPow(base, qb, exp, qe, &qtmp); - tmp = fMult(tmp, (FIXP_DBL)(start << 24)); - current = (INT)scaleValue(tmp, qtmp - 23); - current = (current + 1) >> 1; /* rounding*/ - diff[i - 1] = current - previous; - previous = current; - } - -} /* End CalcBands */ - -static void cumSum(INT start_value, INT *diff, INT length, - UCHAR *start_adress) { - INT i; - start_adress[0] = start_value; - for (i = 1; i <= length; i++) - start_adress[i] = start_adress[i - 1] + diff[i - 1]; -} /* End cumSum */ - -static INT modifyBands(INT max_band_previous, INT *diff, INT length) { - INT change = max_band_previous - diff[0]; - - /* Limit the change so that the last band cannot get narrower than the first - * one */ - if (change > (diff[length - 1] - diff[0]) / 2) - change = (diff[length - 1] - diff[0]) / 2; - - diff[0] += change; - diff[length - 1] -= change; - FDKsbrEnc_Shellsort_int(diff, length); - - return (0); -} /* End modifyBands */ - -/******************************************************************************* - Functionname: FDKsbrEnc_UpdateHiRes - ******************************************************************************* - Description: - - - Arguments: - - Return: - *******************************************************************************/ -INT FDKsbrEnc_UpdateHiRes(UCHAR *h_hires, INT *num_hires, UCHAR *v_k_master, - INT num_master, INT *xover_band) { - INT i; - INT max1, max2; - - if ((v_k_master[*xover_band] > - 32) || /* v_k_master[*xover_band] > noQMFChannels(dualRate)/divider */ - (*xover_band > num_master)) { - /* xover_band error, too big for this startFreq. Will be clipped */ - - /* Calculate maximum value for xover_band */ - max1 = 0; - max2 = num_master; - while ((v_k_master[max1 + 1] < 32) && /* noQMFChannels(dualRate)/divider */ - ((max1 + 1) < max2)) { - max1++; - } - - *xover_band = max1; - } - - *num_hires = num_master - *xover_band; - for (i = *xover_band; i <= num_master; i++) { - h_hires[i - *xover_band] = v_k_master[i]; - } - - return (0); -} /* End FDKsbrEnc_UpdateHiRes */ - -/******************************************************************************* - Functionname: FDKsbrEnc_UpdateLoRes - ******************************************************************************* - Description: - - Arguments: - - Return: - *******************************************************************************/ -void FDKsbrEnc_UpdateLoRes(UCHAR *h_lores, INT *num_lores, UCHAR *h_hires, - INT num_hires) { - INT i; - - if (num_hires % 2 == 0) /* if even number of hires bands */ - { - *num_lores = num_hires / 2; - /* Use every second lores=hires[0,2,4...] */ - for (i = 0; i <= *num_lores; i++) h_lores[i] = h_hires[i * 2]; - - } else /* odd number of hires which means xover is odd */ - { - *num_lores = (num_hires + 1) / 2; - - /* Use lores=hires[0,1,3,5 ...] */ - h_lores[0] = h_hires[0]; - for (i = 1; i <= *num_lores; i++) { - h_lores[i] = h_hires[i * 2 - 1]; - } - } - -} /* End FDKsbrEnc_UpdateLoRes */ --- a/libSBRenc/src/sbrenc_freq_sca.h +++ /dev/null @@ -1,132 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief frequency scale prototypes $Revision: 92790 $ -*/ -#ifndef SBRENC_FREQ_SCA_H -#define SBRENC_FREQ_SCA_H - -#include "sbr_encoder.h" -#include "sbr_def.h" - -#define MAX_OCTAVE 29 -#define MAX_SECOND_REGION 50 - -INT FDKsbrEnc_UpdateFreqScale(UCHAR *v_k_master, INT *h_num_bands, const INT k0, - const INT k2, const INT freq_scale, - const INT alter_scale); - -INT FDKsbrEnc_UpdateHiRes(UCHAR *h_hires, INT *num_hires, UCHAR *v_k_master, - INT num_master, INT *xover_band); - -void FDKsbrEnc_UpdateLoRes(UCHAR *v_lores, INT *num_lores, UCHAR *v_hires, - INT num_hires); - -INT FDKsbrEnc_FindStartAndStopBand(const INT srSbr, const INT srCore, - const INT noChannels, const INT startFreq, - const INT stop_freq, INT *k0, INT *k2); - -INT FDKsbrEnc_getSbrStartFreqRAW(INT startFreq, INT fsCore); -INT FDKsbrEnc_getSbrStopFreqRAW(INT stopFreq, INT fsCore); -#endif --- a/libSBRenc/src/sbrenc_ram.cpp +++ /dev/null @@ -1,249 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Memory layout - $Revision: 92864 $ - - This module declares all static and dynamic memory spaces -*/ -#include "sbrenc_ram.h" - -#include "sbr.h" -#include "genericStds.h" - -C_AALLOC_MEM(Ram_SbrDynamic_RAM, FIXP_DBL, - ((SBR_ENC_DYN_RAM_SIZE) / sizeof(FIXP_DBL))) - -/*! - \name StaticSbrData - - Static memory areas, must not be overwritten in other sections of the encoder -*/ -/* @{ */ - -/*! static sbr encoder instance for one encoder (2 channels) - all major static and dynamic memory areas are located - in module sbr_ram and sbr rom -*/ -C_ALLOC_MEM(Ram_SbrEncoder, SBR_ENCODER, 1) -C_ALLOC_MEM2(Ram_SbrChannel, SBR_CHANNEL, 1, (8)) -C_ALLOC_MEM2(Ram_SbrElement, SBR_ELEMENT, 1, (8)) - -/*! Filter states for QMF-analysis.
- Dimension: #MAXNRSBRCHANNELS * #SBR_QMF_FILTER_LENGTH -*/ -C_AALLOC_MEM2_L(Ram_Sbr_QmfStatesAnalysis, FIXP_QAS, 640, (8), SECT_DATA_L1) - -/*! Matrix holding the quota values for all estimates, all channels - Dimension #MAXNRSBRCHANNELS * +#SBR_QMF_CHANNELS* #MAX_NO_OF_ESTIMATES -*/ -C_ALLOC_MEM2_L(Ram_Sbr_quotaMatrix, FIXP_DBL, (MAX_NO_OF_ESTIMATES * 64), (8), - SECT_DATA_L1) - -/*! Matrix holding the sign values for all estimates, all channels - Dimension #MAXNRSBRCHANNELS * +#SBR_QMF_CHANNELS* #MAX_NO_OF_ESTIMATES -*/ -C_ALLOC_MEM2(Ram_Sbr_signMatrix, INT, (MAX_NO_OF_ESTIMATES * 64), (8)) - -/*! Frequency band table (low res)
- Dimension #MAX_FREQ_COEFFS/2+1 -*/ -C_ALLOC_MEM2(Ram_Sbr_freqBandTableLO, UCHAR, (MAX_FREQ_COEFFS / 2 + 1), (8)) - -/*! Frequency band table (high res)
- Dimension #MAX_FREQ_COEFFS +1 -*/ -C_ALLOC_MEM2(Ram_Sbr_freqBandTableHI, UCHAR, (MAX_FREQ_COEFFS + 1), (8)) - -/*! vk matser table
- Dimension #MAX_FREQ_COEFFS +1 -*/ -C_ALLOC_MEM2(Ram_Sbr_v_k_master, UCHAR, (MAX_FREQ_COEFFS + 1), (8)) - -/* - Missing harmonics detection -*/ - -/*! sbr_detectionVectors
- Dimension #MAX_NUM_CHANNELS*#MAX_NO_OF_ESTIMATES*#MAX_FREQ_COEFFS] -*/ -C_ALLOC_MEM2(Ram_Sbr_detectionVectors, UCHAR, - (MAX_NO_OF_ESTIMATES * MAX_FREQ_COEFFS), (8)) - -/*! sbr_prevCompVec[
- Dimension #MAX_NUM_CHANNELS*#MAX_FREQ_COEFFS] -*/ -C_ALLOC_MEM2(Ram_Sbr_prevEnvelopeCompensation, UCHAR, MAX_FREQ_COEFFS, (8)) -/*! sbr_guideScfb[
- Dimension #MAX_NUM_CHANNELS*#MAX_FREQ_COEFFS] -*/ -C_ALLOC_MEM2(Ram_Sbr_guideScfb, UCHAR, MAX_FREQ_COEFFS, (8)) - -/*! sbr_guideVectorDetected
- Dimension #MAX_NUM_CHANNELS*#MAX_NO_OF_ESTIMATES*#MAX_FREQ_COEFFS] -*/ -C_ALLOC_MEM2(Ram_Sbr_guideVectorDetected, UCHAR, - (MAX_NO_OF_ESTIMATES * MAX_FREQ_COEFFS), (8)) -C_ALLOC_MEM2(Ram_Sbr_guideVectorDiff, FIXP_DBL, - (MAX_NO_OF_ESTIMATES * MAX_FREQ_COEFFS), (8)) -C_ALLOC_MEM2(Ram_Sbr_guideVectorOrig, FIXP_DBL, - (MAX_NO_OF_ESTIMATES * MAX_FREQ_COEFFS), (8)) - -/* - Static Parametric Stereo memory -*/ -C_AALLOC_MEM_L(Ram_PsQmfStatesSynthesis, FIXP_DBL, 640 / 2, SECT_DATA_L1) - -C_ALLOC_MEM_L(Ram_PsEncode, PS_ENCODE, 1, SECT_DATA_L1) -C_ALLOC_MEM(Ram_ParamStereo, PARAMETRIC_STEREO, 1) - -/* @} */ - -/*! - \name DynamicSbrData - - Dynamic memory areas, might be reused in other algorithm sections, - e.g. the core encoder. -*/ -/* @{ */ - -/*! Energy buffer for envelope extraction
- Dimension #MAXNRSBRCHANNELS * +#SBR_QMF_SLOTS * #SBR_QMF_CHANNELS -*/ -C_ALLOC_MEM2(Ram_Sbr_envYBuffer, FIXP_DBL, (32 / 2 * 64), (8)) - -FIXP_DBL* GetRam_Sbr_envYBuffer(int n, UCHAR* dynamic_RAM) { - FDK_ASSERT(dynamic_RAM != 0); - /* The reinterpret_cast is used to suppress a compiler warning. We know that - * (dynamic_RAM + OFFSET_NRG + (n*Y_2_BUF_BYTE)) is sufficiently aligned, so - * the cast is safe */ - return reinterpret_cast( - reinterpret_cast(dynamic_RAM + OFFSET_NRG + (n * Y_2_BUF_BYTE))); -} - -/* - * QMF data - */ -/* The SBR encoder uses a single channel overlapping buffer set (always n=0), - * but PS does not. */ -FIXP_DBL* GetRam_Sbr_envRBuffer(int n, UCHAR* dynamic_RAM) { - FDK_ASSERT(dynamic_RAM != 0); - /* The reinterpret_cast is used to suppress a compiler warning. We know that - * (dynamic_RAM + OFFSET_QMF + (n*(ENV_R_BUFF_BYTE+ENV_I_BUFF_BYTE))) is - * sufficiently aligned, so the cast is safe */ - return reinterpret_cast(reinterpret_cast( - dynamic_RAM + OFFSET_QMF + (n * (ENV_R_BUFF_BYTE + ENV_I_BUFF_BYTE)))); -} -FIXP_DBL* GetRam_Sbr_envIBuffer(int n, UCHAR* dynamic_RAM) { - FDK_ASSERT(dynamic_RAM != 0); - /* The reinterpret_cast is used to suppress a compiler warning. We know that - * (dynamic_RAM + OFFSET_QMF + (ENV_R_BUFF_BYTE) + - * (n*(ENV_R_BUFF_BYTE+ENV_I_BUFF_BYTE))) is sufficiently aligned, so the cast - * is safe */ - return reinterpret_cast( - reinterpret_cast(dynamic_RAM + OFFSET_QMF + (ENV_R_BUFF_BYTE) + - (n * (ENV_R_BUFF_BYTE + ENV_I_BUFF_BYTE)))); -} - -/* @} */ --- a/libSBRenc/src/sbrenc_ram.h +++ /dev/null @@ -1,199 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! -\file -\brief Memory layout -$Revision: 92790 $ -*/ -#ifndef SBRENC_RAM_H -#define SBRENC_RAM_H - -#include "sbr_def.h" -#include "env_est.h" -#include "sbr_encoder.h" -#include "sbr.h" - -#include "ps_main.h" -#include "ps_encode.h" - -#define ENV_TRANSIENTS_BYTE ((sizeof(FIXP_DBL) * (MAX_NUM_CHANNELS * 3 * 32))) - -#define ENV_R_BUFF_BYTE ((sizeof(FIXP_DBL) * ((32) * MAX_HYBRID_BANDS))) -#define ENV_I_BUFF_BYTE ((sizeof(FIXP_DBL) * ((32) * MAX_HYBRID_BANDS))) -#define Y_BUF_CH_BYTE \ - ((2 * sizeof(FIXP_DBL) * (((32) - (32 / 2)) * MAX_HYBRID_BANDS))) - -#define ENV_R_BUF_PS_BYTE ((sizeof(FIXP_DBL) * 32 * 64 / 2)) -#define ENV_I_BUF_PS_BYTE ((sizeof(FIXP_DBL) * 32 * 64 / 2)) - -#define TON_BUF_CH_BYTE \ - ((sizeof(FIXP_DBL) * (MAX_NO_OF_ESTIMATES * MAX_FREQ_COEFFS))) - -#define Y_2_BUF_BYTE (Y_BUF_CH_BYTE) - -/* Workbuffer RAM - Allocation */ -/* - ++++++++++++++++++++++++++++++++++++++++++++++++++++ - | OFFSET_QMF | OFFSET_NRG | - ++++++++++++++++++++++++++++++++++++++++++++++++++++ - ------------------------- ------------------------- - | | 0.5 * | - | sbr_envRBuffer | sbr_envYBuffer_size | - | sbr_envIBuffer | | - ------------------------- ------------------------- - -*/ -#define BUF_NRG_SIZE ((MAX_NUM_CHANNELS * Y_2_BUF_BYTE)) -#define BUF_QMF_SIZE (ENV_R_BUFF_BYTE + ENV_I_BUFF_BYTE) - -/* Size of the shareable memory region than can be reused */ -#define SBR_ENC_DYN_RAM_SIZE (BUF_QMF_SIZE + BUF_NRG_SIZE) - -#define OFFSET_QMF (0) -#define OFFSET_NRG (OFFSET_QMF + BUF_QMF_SIZE) - -/* - ***************************************************************************************************** - */ - -H_ALLOC_MEM(Ram_SbrDynamic_RAM, FIXP_DBL) - -H_ALLOC_MEM(Ram_SbrEncoder, SBR_ENCODER) -H_ALLOC_MEM(Ram_SbrChannel, SBR_CHANNEL) -H_ALLOC_MEM(Ram_SbrElement, SBR_ELEMENT) - -H_ALLOC_MEM(Ram_Sbr_quotaMatrix, FIXP_DBL) -H_ALLOC_MEM(Ram_Sbr_signMatrix, INT) - -H_ALLOC_MEM(Ram_Sbr_QmfStatesAnalysis, FIXP_QAS) - -H_ALLOC_MEM(Ram_Sbr_freqBandTableLO, UCHAR) -H_ALLOC_MEM(Ram_Sbr_freqBandTableHI, UCHAR) -H_ALLOC_MEM(Ram_Sbr_v_k_master, UCHAR) - -H_ALLOC_MEM(Ram_Sbr_detectionVectors, UCHAR) -H_ALLOC_MEM(Ram_Sbr_prevEnvelopeCompensation, UCHAR) -H_ALLOC_MEM(Ram_Sbr_guideScfb, UCHAR) -H_ALLOC_MEM(Ram_Sbr_guideVectorDetected, UCHAR) - -/* Dynamic Memory Allocation */ - -H_ALLOC_MEM(Ram_Sbr_envYBuffer, FIXP_DBL) -FIXP_DBL* GetRam_Sbr_envYBuffer(int n, UCHAR* dynamic_RAM); -FIXP_DBL* GetRam_Sbr_envRBuffer(int n, UCHAR* dynamic_RAM); -FIXP_DBL* GetRam_Sbr_envIBuffer(int n, UCHAR* dynamic_RAM); - -H_ALLOC_MEM(Ram_Sbr_guideVectorDiff, FIXP_DBL) -H_ALLOC_MEM(Ram_Sbr_guideVectorOrig, FIXP_DBL) - -H_ALLOC_MEM(Ram_PsQmfStatesSynthesis, FIXP_DBL) - -H_ALLOC_MEM(Ram_PsEncode, PS_ENCODE) - -FIXP_DBL* FDKsbrEnc_SliceRam_PsRqmf(FIXP_DBL* rQmfData, UCHAR* dynamic_RAM, - int n, int i, int qmfSlots); -FIXP_DBL* FDKsbrEnc_SliceRam_PsIqmf(FIXP_DBL* iQmfData, UCHAR* dynamic_RAM, - int n, int i, int qmfSlots); - -H_ALLOC_MEM(Ram_ParamStereo, PARAMETRIC_STEREO) -#endif --- a/libSBRenc/src/sbrenc_rom.cpp +++ /dev/null @@ -1,910 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): Tobias Chalupka - - Description: Definition of constant tables - -*******************************************************************************/ - -/*! - \file - \brief Definition of constant tables - $Revision: 95404 $ - - This module contains most of the constant data that can be stored in ROM. -*/ - -#include "sbrenc_rom.h" -#include "genericStds.h" - -//@{ -/******************************************************************************* - - Table Overview: - - o envelope level, 1.5 dB: - 1a) v_Huff_envelopeLevelC10T[121] - 1b) v_Huff_envelopeLevelL10T[121] - 2a) v_Huff_envelopeLevelC10F[121] - 2b) v_Huff_envelopeLevelL10F[121] - - o envelope balance, 1.5 dB: - 3a) bookSbrEnvBalanceC10T[49] - 3b) bookSbrEnvBalanceL10T[49] - 4a) bookSbrEnvBalanceC10F[49] - 4b) bookSbrEnvBalanceL10F[49] - - o envelope level, 3.0 dB: - 5a) v_Huff_envelopeLevelC11T[63] - 5b) v_Huff_envelopeLevelL11T[63] - 6a) v_Huff_envelopeLevelC11F[63] - 6b) v_Huff_envelopeLevelC11F[63] - - o envelope balance, 3.0 dB: - 7a) bookSbrEnvBalanceC11T[25] - 7b) bookSbrEnvBalanceL11T[25] - 8a) bookSbrEnvBalanceC11F[25] - 8b) bookSbrEnvBalanceL11F[25] - - o noise level, 3.0 dB: - 9a) v_Huff_NoiseLevelC11T[63] - 9b) v_Huff_NoiseLevelL11T[63] - - ) (v_Huff_envelopeLevelC11F[63] is used for freq dir) - - ) (v_Huff_envelopeLevelL11F[63] is used for freq dir) - - o noise balance, 3.0 dB: - 10a) bookSbrNoiseBalanceC11T[25] - 10b) bookSbrNoiseBalanceL11T[25] - - ) (bookSbrEnvBalanceC11F[25] is used for freq dir) - - ) (bookSbrEnvBalanceL11F[25] is used for freq dir) - - - (1.5 dB is never used for noise) - -********************************************************************************/ - -/*******************************************************************************/ -/* table : envelope level, 1.5 dB */ -/* theor range : [-58,58], CODE_BOOK_SCF_LAV = 58 */ -/* implem range: [-60,60], CODE_BOOK_SCF_LAV10 = 60 */ -/* raw stats : envelopeLevel_00 (yes, wrong suffix in name) KK 01-03-09 */ -/*******************************************************************************/ - -/* direction: time - contents : codewords - raw table: HuffCode3C2FIX.m/envelopeLevel_00T_cF.mat/v_nChex_cF - built by : FH 01-07-05 */ - -const INT v_Huff_envelopeLevelC10T[121] = { - 0x0003FFD6, 0x0003FFD7, 0x0003FFD8, 0x0003FFD9, 0x0003FFDA, 0x0003FFDB, - 0x0007FFB8, 0x0007FFB9, 0x0007FFBA, 0x0007FFBB, 0x0007FFBC, 0x0007FFBD, - 0x0007FFBE, 0x0007FFBF, 0x0007FFC0, 0x0007FFC1, 0x0007FFC2, 0x0007FFC3, - 0x0007FFC4, 0x0007FFC5, 0x0007FFC6, 0x0007FFC7, 0x0007FFC8, 0x0007FFC9, - 0x0007FFCA, 0x0007FFCB, 0x0007FFCC, 0x0007FFCD, 0x0007FFCE, 0x0007FFCF, - 0x0007FFD0, 0x0007FFD1, 0x0007FFD2, 0x0007FFD3, 0x0001FFE6, 0x0003FFD4, - 0x0000FFF0, 0x0001FFE9, 0x0003FFD5, 0x0001FFE7, 0x0000FFF1, 0x0000FFEC, - 0x0000FFED, 0x0000FFEE, 0x00007FF4, 0x00003FF9, 0x00003FF7, 0x00001FFA, - 0x00001FF9, 0x00000FFB, 0x000007FC, 0x000003FC, 0x000001FD, 0x000000FD, - 0x0000007D, 0x0000003D, 0x0000001D, 0x0000000D, 0x00000005, 0x00000001, - 0x00000000, 0x00000004, 0x0000000C, 0x0000001C, 0x0000003C, 0x0000007C, - 0x000000FC, 0x000001FC, 0x000003FD, 0x00000FFA, 0x00001FF8, 0x00003FF6, - 0x00003FF8, 0x00007FF5, 0x0000FFEF, 0x0001FFE8, 0x0000FFF2, 0x0007FFD4, - 0x0007FFD5, 0x0007FFD6, 0x0007FFD7, 0x0007FFD8, 0x0007FFD9, 0x0007FFDA, - 0x0007FFDB, 0x0007FFDC, 0x0007FFDD, 0x0007FFDE, 0x0007FFDF, 0x0007FFE0, - 0x0007FFE1, 0x0007FFE2, 0x0007FFE3, 0x0007FFE4, 0x0007FFE5, 0x0007FFE6, - 0x0007FFE7, 0x0007FFE8, 0x0007FFE9, 0x0007FFEA, 0x0007FFEB, 0x0007FFEC, - 0x0007FFED, 0x0007FFEE, 0x0007FFEF, 0x0007FFF0, 0x0007FFF1, 0x0007FFF2, - 0x0007FFF3, 0x0007FFF4, 0x0007FFF5, 0x0007FFF6, 0x0007FFF7, 0x0007FFF8, - 0x0007FFF9, 0x0007FFFA, 0x0007FFFB, 0x0007FFFC, 0x0007FFFD, 0x0007FFFE, - 0x0007FFFF}; - -/* direction: time - contents : codeword lengths - raw table: HuffCode3C2FIX.m/envelopeLevel_00T_cF.mat/v_nLhex_cF - built by : FH 01-07-05 */ - -const UCHAR v_Huff_envelopeLevelL10T[121] = { - 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, - 0x13, 0x11, 0x12, 0x10, 0x11, 0x12, 0x11, 0x10, 0x10, 0x10, 0x10, - 0x0F, 0x0E, 0x0E, 0x0D, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, - 0x06, 0x05, 0x04, 0x03, 0x02, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0A, 0x0C, 0x0D, 0x0E, 0x0E, 0x0F, 0x10, 0x11, 0x10, - 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13}; - -/* direction: freq - contents : codewords - raw table: HuffCode3C2FIX.m/envelopeLevel_00F_cF.mat/v_nChex_cF - built by : FH 01-07-05 */ - -const INT v_Huff_envelopeLevelC10F[121] = { - 0x0007FFE7, 0x0007FFE8, 0x000FFFD2, 0x000FFFD3, 0x000FFFD4, 0x000FFFD5, - 0x000FFFD6, 0x000FFFD7, 0x000FFFD8, 0x0007FFDA, 0x000FFFD9, 0x000FFFDA, - 0x000FFFDB, 0x000FFFDC, 0x0007FFDB, 0x000FFFDD, 0x0007FFDC, 0x0007FFDD, - 0x000FFFDE, 0x0003FFE4, 0x000FFFDF, 0x000FFFE0, 0x000FFFE1, 0x0007FFDE, - 0x000FFFE2, 0x000FFFE3, 0x000FFFE4, 0x0007FFDF, 0x000FFFE5, 0x0007FFE0, - 0x0003FFE8, 0x0007FFE1, 0x0003FFE0, 0x0003FFE9, 0x0001FFEF, 0x0003FFE5, - 0x0001FFEC, 0x0001FFED, 0x0001FFEE, 0x0000FFF4, 0x0000FFF3, 0x0000FFF0, - 0x00007FF7, 0x00007FF6, 0x00003FFA, 0x00001FFA, 0x00001FF9, 0x00000FFA, - 0x00000FF8, 0x000007F9, 0x000003FB, 0x000001FC, 0x000001FA, 0x000000FB, - 0x0000007C, 0x0000003C, 0x0000001C, 0x0000000C, 0x00000005, 0x00000001, - 0x00000000, 0x00000004, 0x0000000D, 0x0000001D, 0x0000003D, 0x000000FA, - 0x000000FC, 0x000001FB, 0x000003FA, 0x000007F8, 0x000007FA, 0x000007FB, - 0x00000FF9, 0x00000FFB, 0x00001FF8, 0x00001FFB, 0x00003FF8, 0x00003FF9, - 0x0000FFF1, 0x0000FFF2, 0x0001FFEA, 0x0001FFEB, 0x0003FFE1, 0x0003FFE2, - 0x0003FFEA, 0x0003FFE3, 0x0003FFE6, 0x0003FFE7, 0x0003FFEB, 0x000FFFE6, - 0x0007FFE2, 0x000FFFE7, 0x000FFFE8, 0x000FFFE9, 0x000FFFEA, 0x000FFFEB, - 0x000FFFEC, 0x0007FFE3, 0x000FFFED, 0x000FFFEE, 0x000FFFEF, 0x000FFFF0, - 0x0007FFE4, 0x000FFFF1, 0x0003FFEC, 0x000FFFF2, 0x000FFFF3, 0x0007FFE5, - 0x0007FFE6, 0x000FFFF4, 0x000FFFF5, 0x000FFFF6, 0x000FFFF7, 0x000FFFF8, - 0x000FFFF9, 0x000FFFFA, 0x000FFFFB, 0x000FFFFC, 0x000FFFFD, 0x000FFFFE, - 0x000FFFFF}; - -/* direction: freq - contents : codeword lengths - raw table: HuffCode3C2FIX.m/envelopeLevel_00F_cF.mat/v_nLhex_cF - built by : FH 01-07-05 */ - -const UCHAR v_Huff_envelopeLevelL10F[121] = { - 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x13, 0x14, - 0x14, 0x14, 0x14, 0x13, 0x14, 0x13, 0x13, 0x14, 0x12, 0x14, 0x14, - 0x14, 0x13, 0x14, 0x14, 0x14, 0x13, 0x14, 0x13, 0x12, 0x13, 0x12, - 0x12, 0x11, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x10, 0x0F, 0x0F, - 0x0E, 0x0D, 0x0D, 0x0C, 0x0C, 0x0B, 0x0A, 0x09, 0x09, 0x08, 0x07, - 0x06, 0x05, 0x04, 0x03, 0x02, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08, - 0x08, 0x09, 0x0A, 0x0B, 0x0B, 0x0B, 0x0C, 0x0C, 0x0D, 0x0D, 0x0E, - 0x0E, 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, - 0x12, 0x14, 0x13, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x13, 0x14, - 0x14, 0x14, 0x14, 0x13, 0x14, 0x12, 0x14, 0x14, 0x13, 0x13, 0x14, - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14}; - -/*******************************************************************************/ -/* table : envelope balance, 1.5 dB */ -/* theor range : [-48,48], CODE_BOOK_SCF_LAV = 48 */ -/* implem range: same but mapped to [-24,24], CODE_BOOK_SCF_LAV_BALANCE10 = 24 - */ -/* raw stats : envelopePan_00 (yes, wrong suffix in name) KK 01-03-09 */ -/*******************************************************************************/ - -/* direction: time - contents : codewords - raw table: HuffCode3C.m/envelopePan_00T.mat/v_nBhex - built by : FH 01-05-15 */ - -const INT bookSbrEnvBalanceC10T[49] = { - 0x0000FFE4, 0x0000FFE5, 0x0000FFE6, 0x0000FFE7, 0x0000FFE8, 0x0000FFE9, - 0x0000FFEA, 0x0000FFEB, 0x0000FFEC, 0x0000FFED, 0x0000FFEE, 0x0000FFEF, - 0x0000FFF0, 0x0000FFF1, 0x0000FFF2, 0x0000FFF3, 0x0000FFF4, 0x0000FFE2, - 0x00000FFC, 0x000007FC, 0x000001FE, 0x0000007E, 0x0000001E, 0x00000006, - 0x00000000, 0x00000002, 0x0000000E, 0x0000003E, 0x000000FE, 0x000007FD, - 0x00000FFD, 0x00007FF0, 0x0000FFE3, 0x0000FFF5, 0x0000FFF6, 0x0000FFF7, - 0x0000FFF8, 0x0000FFF9, 0x0000FFFA, 0x0001FFF6, 0x0001FFF7, 0x0001FFF8, - 0x0001FFF9, 0x0001FFFA, 0x0001FFFB, 0x0001FFFC, 0x0001FFFD, 0x0001FFFE, - 0x0001FFFF}; - -/* direction: time - contents : codeword lengths - raw table: HuffCode3C.m/envelopePan_00T.mat/v_nLhex - built by : FH 01-05-15 */ - -const UCHAR bookSbrEnvBalanceL10T[49] = { - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, - 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x0C, 0x0B, - 0x09, 0x07, 0x05, 0x03, 0x01, 0x02, 0x04, 0x06, 0x08, 0x0B, - 0x0C, 0x0F, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}; - -/* direction: freq - contents : codewords - raw table: HuffCode3C.m/envelopePan_00F.mat/v_nBhex - built by : FH 01-05-15 */ - -const INT bookSbrEnvBalanceC10F[49] = { - 0x0003FFE2, 0x0003FFE3, 0x0003FFE4, 0x0003FFE5, 0x0003FFE6, 0x0003FFE7, - 0x0003FFE8, 0x0003FFE9, 0x0003FFEA, 0x0003FFEB, 0x0003FFEC, 0x0003FFED, - 0x0003FFEE, 0x0003FFEF, 0x0003FFF0, 0x0000FFF7, 0x0001FFF0, 0x00003FFC, - 0x000007FE, 0x000007FC, 0x000000FE, 0x0000007E, 0x0000000E, 0x00000002, - 0x00000000, 0x00000006, 0x0000001E, 0x0000003E, 0x000001FE, 0x000007FD, - 0x00000FFE, 0x00007FFA, 0x0000FFF6, 0x0003FFF1, 0x0003FFF2, 0x0003FFF3, - 0x0003FFF4, 0x0003FFF5, 0x0003FFF6, 0x0003FFF7, 0x0003FFF8, 0x0003FFF9, - 0x0003FFFA, 0x0003FFFB, 0x0003FFFC, 0x0003FFFD, 0x0003FFFE, 0x0007FFFE, - 0x0007FFFF}; - -/* direction: freq - contents : codeword lengths - raw table: HuffCode3C.m/envelopePan_00F.mat/v_nLhex - built by : FH 01-05-15 */ - -const UCHAR bookSbrEnvBalanceL10F[49] = { - 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, - 0x12, 0x12, 0x12, 0x12, 0x12, 0x10, 0x11, 0x0E, 0x0B, 0x0B, - 0x08, 0x07, 0x04, 0x02, 0x01, 0x03, 0x05, 0x06, 0x09, 0x0B, - 0x0C, 0x0F, 0x10, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, - 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13}; - -/*******************************************************************************/ -/* table : envelope level, 3.0 dB */ -/* theor range : [-29,29], CODE_BOOK_SCF_LAV = 29 */ -/* implem range: [-31,31], CODE_BOOK_SCF_LAV11 = 31 */ -/* raw stats : envelopeLevel_11 KK 00-02-03 */ -/*******************************************************************************/ - -/* direction: time - contents : codewords - raw table: HuffCode2.m - built by : FH 00-02-04 */ - -const INT v_Huff_envelopeLevelC11T[63] = { - 0x0003FFED, 0x0003FFEE, 0x0007FFDE, 0x0007FFDF, 0x0007FFE0, 0x0007FFE1, - 0x0007FFE2, 0x0007FFE3, 0x0007FFE4, 0x0007FFE5, 0x0007FFE6, 0x0007FFE7, - 0x0007FFE8, 0x0007FFE9, 0x0007FFEA, 0x0007FFEB, 0x0007FFEC, 0x0001FFF4, - 0x0000FFF7, 0x0000FFF9, 0x0000FFF8, 0x00003FFB, 0x00003FFA, 0x00003FF8, - 0x00001FFA, 0x00000FFC, 0x000007FC, 0x000000FE, 0x0000003E, 0x0000000E, - 0x00000002, 0x00000000, 0x00000006, 0x0000001E, 0x0000007E, 0x000001FE, - 0x000007FD, 0x00001FFB, 0x00003FF9, 0x00003FFC, 0x00007FFA, 0x0000FFF6, - 0x0001FFF5, 0x0003FFEC, 0x0007FFED, 0x0007FFEE, 0x0007FFEF, 0x0007FFF0, - 0x0007FFF1, 0x0007FFF2, 0x0007FFF3, 0x0007FFF4, 0x0007FFF5, 0x0007FFF6, - 0x0007FFF7, 0x0007FFF8, 0x0007FFF9, 0x0007FFFA, 0x0007FFFB, 0x0007FFFC, - 0x0007FFFD, 0x0007FFFE, 0x0007FFFF}; - -/* direction: time - contents : codeword lengths - raw table: HuffCode2.m - built by : FH 00-02-04 */ - -const UCHAR v_Huff_envelopeLevelL11T[63] = { - 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x11, 0x10, 0x10, 0x10, 0x0E, - 0x0E, 0x0E, 0x0D, 0x0C, 0x0B, 0x08, 0x06, 0x04, 0x02, 0x01, 0x03, - 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0E, 0x0E, 0x0F, 0x10, 0x11, 0x12, - 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, - 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13}; - -/* direction: freq - contents : codewords - raw table: HuffCode2.m - built by : FH 00-02-04 */ - -const INT v_Huff_envelopeLevelC11F[63] = { - 0x000FFFF0, 0x000FFFF1, 0x000FFFF2, 0x000FFFF3, 0x000FFFF4, 0x000FFFF5, - 0x000FFFF6, 0x0003FFF3, 0x0007FFF5, 0x0007FFEE, 0x0007FFEF, 0x0007FFF6, - 0x0003FFF4, 0x0003FFF2, 0x000FFFF7, 0x0007FFF0, 0x0001FFF5, 0x0003FFF0, - 0x0001FFF4, 0x0000FFF7, 0x0000FFF6, 0x00007FF8, 0x00003FFB, 0x00000FFD, - 0x000007FD, 0x000003FD, 0x000001FD, 0x000000FD, 0x0000003E, 0x0000000E, - 0x00000002, 0x00000000, 0x00000006, 0x0000001E, 0x000000FC, 0x000001FC, - 0x000003FC, 0x000007FC, 0x00000FFC, 0x00001FFC, 0x00003FFA, 0x00007FF9, - 0x00007FFA, 0x0000FFF8, 0x0000FFF9, 0x0001FFF6, 0x0001FFF7, 0x0003FFF5, - 0x0003FFF6, 0x0003FFF1, 0x000FFFF8, 0x0007FFF1, 0x0007FFF2, 0x0007FFF3, - 0x000FFFF9, 0x0007FFF7, 0x0007FFF4, 0x000FFFFA, 0x000FFFFB, 0x000FFFFC, - 0x000FFFFD, 0x000FFFFE, 0x000FFFFF}; - -/* direction: freq - contents : codeword lengths - raw table: HuffCode2.m - built by : FH 00-02-04 */ - -const UCHAR v_Huff_envelopeLevelL11F[63] = { - 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x12, 0x13, 0x13, 0x13, - 0x13, 0x12, 0x12, 0x14, 0x13, 0x11, 0x12, 0x11, 0x10, 0x10, 0x0F, - 0x0E, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01, 0x03, - 0x05, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x0F, 0x10, - 0x10, 0x11, 0x11, 0x12, 0x12, 0x12, 0x14, 0x13, 0x13, 0x13, 0x14, - 0x13, 0x13, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14}; - -/*******************************************************************************/ -/* table : envelope balance, 3.0 dB */ -/* theor range : [-24,24], CODE_BOOK_SCF_LAV = 24 */ -/* implem range: same but mapped to [-12,12], CODE_BOOK_SCF_LAV_BALANCE11 = 12 - */ -/* raw stats : envelopeBalance_11 KK 00-02-03 */ -/*******************************************************************************/ - -/* direction: time - contents : codewords - raw table: HuffCode3C.m/envelopeBalance_11T.mat/v_nBhex - built by : FH 01-05-15 */ - -const INT bookSbrEnvBalanceC11T[25] = { - 0x00001FF2, 0x00001FF3, 0x00001FF4, 0x00001FF5, 0x00001FF6, - 0x00001FF7, 0x00001FF8, 0x00000FF8, 0x000000FE, 0x0000007E, - 0x0000000E, 0x00000006, 0x00000000, 0x00000002, 0x0000001E, - 0x0000003E, 0x000001FE, 0x00001FF9, 0x00001FFA, 0x00001FFB, - 0x00001FFC, 0x00001FFD, 0x00001FFE, 0x00003FFE, 0x00003FFF}; - -/* direction: time - contents : codeword lengths - raw table: HuffCode3C.m/envelopeBalance_11T.mat/v_nLhex - built by : FH 01-05-15 */ - -const UCHAR bookSbrEnvBalanceL11T[25] = { - 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0C, 0x08, - 0x07, 0x04, 0x03, 0x01, 0x02, 0x05, 0x06, 0x09, 0x0D, - 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0E, 0x0E}; - -/* direction: freq - contents : codewords - raw table: HuffCode3C.m/envelopeBalance_11F.mat/v_nBhex - built by : FH 01-05-15 */ - -const INT bookSbrEnvBalanceC11F[25] = { - 0x00001FF7, 0x00001FF8, 0x00001FF9, 0x00001FFA, 0x00001FFB, - 0x00003FF8, 0x00003FF9, 0x000007FC, 0x000000FE, 0x0000007E, - 0x0000000E, 0x00000002, 0x00000000, 0x00000006, 0x0000001E, - 0x0000003E, 0x000001FE, 0x00000FFA, 0x00001FF6, 0x00003FFA, - 0x00003FFB, 0x00003FFC, 0x00003FFD, 0x00003FFE, 0x00003FFF}; - -/* direction: freq - contents : codeword lengths - raw table: HuffCode3C.m/envelopeBalance_11F.mat/v_nLhex - built by : FH 01-05-15 */ - -const UCHAR bookSbrEnvBalanceL11F[25] = { - 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0E, 0x0E, 0x0B, 0x08, - 0x07, 0x04, 0x02, 0x01, 0x03, 0x05, 0x06, 0x09, 0x0C, - 0x0D, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E}; - -/*******************************************************************************/ -/* table : noise level, 3.0 dB */ -/* theor range : [-29,29], CODE_BOOK_SCF_LAV = 29 */ -/* implem range: [-31,31], CODE_BOOK_SCF_LAV11 = 31 */ -/* raw stats : noiseLevel_11 KK 00-02-03 */ -/*******************************************************************************/ - -/* direction: time - contents : codewords - raw table: HuffCode2.m - built by : FH 00-02-04 */ - -const INT v_Huff_NoiseLevelC11T[63] = { - 0x00001FCE, 0x00001FCF, 0x00001FD0, 0x00001FD1, 0x00001FD2, 0x00001FD3, - 0x00001FD4, 0x00001FD5, 0x00001FD6, 0x00001FD7, 0x00001FD8, 0x00001FD9, - 0x00001FDA, 0x00001FDB, 0x00001FDC, 0x00001FDD, 0x00001FDE, 0x00001FDF, - 0x00001FE0, 0x00001FE1, 0x00001FE2, 0x00001FE3, 0x00001FE4, 0x00001FE5, - 0x00001FE6, 0x00001FE7, 0x000007F2, 0x000000FD, 0x0000003E, 0x0000000E, - 0x00000006, 0x00000000, 0x00000002, 0x0000001E, 0x000000FC, 0x000003F8, - 0x00001FCC, 0x00001FE8, 0x00001FE9, 0x00001FEA, 0x00001FEB, 0x00001FEC, - 0x00001FCD, 0x00001FED, 0x00001FEE, 0x00001FEF, 0x00001FF0, 0x00001FF1, - 0x00001FF2, 0x00001FF3, 0x00001FF4, 0x00001FF5, 0x00001FF6, 0x00001FF7, - 0x00001FF8, 0x00001FF9, 0x00001FFA, 0x00001FFB, 0x00001FFC, 0x00001FFD, - 0x00001FFE, 0x00003FFE, 0x00003FFF}; - -/* direction: time - contents : codeword lengths - raw table: HuffCode2.m - built by : FH 00-02-04 */ - -const UCHAR v_Huff_NoiseLevelL11T[63] = { - 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, - 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, - 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, - 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, - 0x0000000D, 0x0000000D, 0x0000000B, 0x00000008, 0x00000006, 0x00000004, - 0x00000003, 0x00000001, 0x00000002, 0x00000005, 0x00000008, 0x0000000A, - 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, - 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, - 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, - 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, 0x0000000D, - 0x0000000D, 0x0000000E, 0x0000000E}; - -/*******************************************************************************/ -/* table : noise balance, 3.0 dB */ -/* theor range : [-24,24], CODE_BOOK_SCF_LAV = 24 */ -/* implem range: same but mapped to [-12,12], CODE_BOOK_SCF_LAV_BALANCE11 = 12 - */ -/* raw stats : noiseBalance_11 KK 00-02-03 */ -/*******************************************************************************/ - -/* direction: time - contents : codewords - raw table: HuffCode3C.m/noiseBalance_11.mat/v_nBhex - built by : FH 01-05-15 */ - -const INT bookSbrNoiseBalanceC11T[25] = { - 0x000000EC, 0x000000ED, 0x000000EE, 0x000000EF, 0x000000F0, - 0x000000F1, 0x000000F2, 0x000000F3, 0x000000F4, 0x000000F5, - 0x0000001C, 0x00000002, 0x00000000, 0x00000006, 0x0000003A, - 0x000000F6, 0x000000F7, 0x000000F8, 0x000000F9, 0x000000FA, - 0x000000FB, 0x000000FC, 0x000000FD, 0x000000FE, 0x000000FF}; - -/* direction: time - contents : codeword lengths - raw table: HuffCode3C.m/noiseBalance_11.mat/v_nLhex - built by : FH 01-05-15 */ - -const UCHAR bookSbrNoiseBalanceL11T[25] = { - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, - 0x08, 0x05, 0x02, 0x01, 0x03, 0x06, 0x08, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}; - -/* - tuningTable -*/ -const sbrTuningTable_t sbrTuningTable[] = { - /* Some of the low bitrates are commented out here, this is because the - encoder could lose frames at those bitrates and throw an error - because it has insufficient bits to encode for some test items. - */ - - /*** HE-AAC section ***/ - /* sf,sfsp,sf,sfsp,nnb,nfo,saml,SM,FS*/ - - /*** mono ***/ - - /* 8/16 kHz dual rate */ - {CODEC_AAC, 8000, 10000, 8000, 1, 7, 6, 11, 10, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 10000, 12000, 8000, 1, 11, 7, 13, 12, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 12000, 16001, 8000, 1, 14, 10, 13, 13, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 16000, 24000, 8000, 1, 14, 10, 14, 14, 2, 0, 3, SBR_MONO, 2}, - {CODEC_AAC, 24000, 32000, 8000, 1, 14, 10, 14, 14, 2, 0, 3, SBR_MONO, 2}, - {CODEC_AAC, 32000, 48001, 8000, 1, 14, 11, 15, 15, 2, 0, 3, SBR_MONO, 2}, - - /* 11/22 kHz dual rate */ - {CODEC_AAC, 8000, 10000, 11025, 1, 5, 4, 6, 6, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 10000, 12000, 11025, 1, 8, 5, 12, 9, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 12000, 16000, 11025, 1, 12, 8, 13, 8, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 16000, 20000, 11025, 1, 12, 8, 13, 8, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 20000, 24001, 11025, 1, 13, 9, 13, 8, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 24000, 32000, 11025, 1, 14, 10, 14, 9, 2, 0, 3, SBR_MONO, 2}, - {CODEC_AAC, 32000, 48000, 11025, 1, 15, 11, 15, 10, 2, 0, 3, SBR_MONO, 2}, - {CODEC_AAC, 48000, 64001, 11025, 1, 15, 11, 15, 10, 2, 0, 3, SBR_MONO, 1}, - - /* 12/24 kHz dual rate */ - {CODEC_AAC, 8000, 10000, 12000, 1, 4, 3, 6, 6, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 10000, 12000, 12000, 1, 7, 4, 11, 8, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 12000, 16000, 12000, 1, 11, 7, 12, 8, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 16000, 20000, 12000, 1, 11, 7, 12, 8, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 20000, 24001, 12000, 1, 12, 8, 12, 8, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 24000, 32000, 12000, 1, 13, 9, 13, 9, 2, 0, 3, SBR_MONO, 2}, - {CODEC_AAC, 32000, 48000, 12000, 1, 14, 10, 14, 10, 2, 0, 3, SBR_MONO, 2}, - {CODEC_AAC, 48000, 64001, 12000, 1, 14, 11, 15, 11, 2, 0, 3, SBR_MONO, 1}, - - /* 16/32 kHz dual rate */ - {CODEC_AAC, 8000, 10000, 16000, 1, 1, 1, 0, 0, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 10000, 12000, 16000, 1, 2, 1, 6, 0, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 12000, 16000, 16000, 1, 4, 2, 6, 0, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 16000, 18000, 16000, 1, 4, 2, 8, 3, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 18000, 22000, 16000, 1, 6, 5, 11, 7, 2, 0, 6, SBR_MONO, 2}, - {CODEC_AAC, 22000, 28000, 16000, 1, 10, 9, 12, 8, 2, 0, 6, SBR_MONO, 2}, - {CODEC_AAC, 28000, 36000, 16000, 1, 12, 12, 13, 13, 2, 0, 3, SBR_MONO, 2}, - {CODEC_AAC, 36000, 44000, 16000, 1, 14, 14, 13, 13, 2, 0, 3, SBR_MONO, 1}, - {CODEC_AAC, 44000, 64001, 16000, 1, 14, 14, 13, 13, 2, 0, 3, SBR_MONO, 1}, - - /* 22.05/44.1 kHz dual rate */ - /* { CODEC_AAC, 8000, 11369, 22050, 1, 1, 1, 1, 1, 1, 0, 6, - SBR_MONO, 3 }, */ - {CODEC_AAC, 11369, 16000, 22050, 1, 3, 1, 4, 4, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 16000, 18000, 22050, 1, 3, 1, 5, 4, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 18000, 22000, 22050, 1, 4, 4, 8, 5, 2, 0, 6, SBR_MONO, 2}, - {CODEC_AAC, 22000, 28000, 22050, 1, 7, 6, 8, 6, 2, 0, 6, SBR_MONO, 2}, - {CODEC_AAC, 28000, 36000, 22050, 1, 10, 10, 9, 9, 2, 0, 3, SBR_MONO, 2}, - {CODEC_AAC, 36000, 44000, 22050, 1, 11, 11, 10, 10, 2, 0, 3, SBR_MONO, 1}, - {CODEC_AAC, 44000, 64001, 22050, 1, 13, 13, 12, 12, 2, 0, 3, SBR_MONO, 1}, - - /* 24/48 kHz dual rate */ - /* { CODEC_AAC, 8000, 12000, 24000, 1, 1, 1, 1, 1, 1, 0, 6, - SBR_MONO, 3 }, */ - {CODEC_AAC, 12000, 16000, 24000, 1, 3, 1, 4, 4, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 16000, 18000, 24000, 1, 3, 1, 5, 4, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AAC, 18000, 22000, 24000, 1, 4, 3, 8, 5, 2, 0, 6, SBR_MONO, 2}, - {CODEC_AAC, 22000, 28000, 24000, 1, 7, 6, 8, 6, 2, 0, 6, SBR_MONO, 2}, - {CODEC_AAC, 28000, 36000, 24000, 1, 10, 10, 9, 9, 2, 0, 3, SBR_MONO, 2}, - {CODEC_AAC, 36000, 44000, 24000, 1, 11, 11, 10, 10, 2, 0, 3, SBR_MONO, 1}, - {CODEC_AAC, 44000, 64001, 24000, 1, 13, 13, 11, 11, 2, 0, 3, SBR_MONO, 1}, - - /* 32/64 kHz dual rate */ - {CODEC_AAC, 24000, 36000, 32000, 1, 4, 4, 4, 4, 2, 0, 3, SBR_MONO, 3}, - {CODEC_AAC, 36000, 60000, 32000, 1, 7, 7, 6, 6, 2, 0, 3, SBR_MONO, 2}, - {CODEC_AAC, 60000, 72000, 32000, 1, 9, 9, 8, 8, 2, 0, 3, SBR_MONO, 1}, - {CODEC_AAC, 72000, 100000, 32000, 1, 11, 11, 10, 10, 2, 0, 3, SBR_MONO, 1}, - {CODEC_AAC, 100000, 160001, 32000, 1, 13, 13, 11, 11, 2, 0, 3, SBR_MONO, 1}, - - /* 44.1/88.2 kHz dual rate */ - {CODEC_AAC, 24000, 36000, 44100, 1, 4, 4, 4, 4, 2, 0, 3, SBR_MONO, 3}, - {CODEC_AAC, 36000, 60000, 44100, 1, 7, 7, 6, 6, 2, 0, 3, SBR_MONO, 2}, - {CODEC_AAC, 60000, 72000, 44100, 1, 9, 9, 8, 8, 2, 0, 3, SBR_MONO, 1}, - {CODEC_AAC, 72000, 100000, 44100, 1, 11, 11, 10, 10, 2, 0, 3, SBR_MONO, 1}, - {CODEC_AAC, 100000, 160001, 44100, 1, 13, 13, 11, 11, 2, 0, 3, SBR_MONO, 1}, - - /* 48/96 kHz dual rate */ - {CODEC_AAC, 32000, 36000, 48000, 1, 4, 4, 9, 9, 2, 0, 3, SBR_MONO, 3}, - {CODEC_AAC, 36000, 60000, 48000, 1, 7, 7, 10, 10, 2, 0, 3, SBR_MONO, 2}, - {CODEC_AAC, 60000, 72000, 48000, 1, 9, 9, 10, 10, 2, 0, 3, SBR_MONO, 1}, - {CODEC_AAC, 72000, 100000, 48000, 1, 11, 11, 11, 11, 2, 0, 3, SBR_MONO, 1}, - {CODEC_AAC, 100000, 160001, 48000, 1, 13, 13, 11, 11, 2, 0, 3, SBR_MONO, 1}, - - /*** stereo ***/ - /* 08/16 kHz dual rate */ - {CODEC_AAC, 16000, 24000, 8000, 2, 6, 6, 9, 7, 1, 0, -3, SBR_SWITCH_LRC, 3}, - {CODEC_AAC, 24000, 28000, 8000, 2, 9, 9, 11, 9, 1, 0, -3, SBR_SWITCH_LRC, - 3}, - {CODEC_AAC, 28000, 36000, 8000, 2, 11, 9, 11, 9, 2, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AAC, 36000, 44000, 8000, 2, 13, 11, 13, 11, 2, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AAC, 44000, 52000, 8000, 2, 14, 12, 13, 12, 2, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AAC, 52000, 60000, 8000, 2, 14, 14, 13, 13, 3, 0, -3, SBR_SWITCH_LRC, - 1}, - {CODEC_AAC, 60000, 76000, 8000, 2, 14, 14, 13, 13, 3, 0, -3, SBR_LEFT_RIGHT, - 1}, - {CODEC_AAC, 76000, 128001, 8000, 2, 14, 14, 13, 13, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - - /* 11/22 kHz dual rate */ - {CODEC_AAC, 16000, 24000, 11025, 2, 7, 5, 9, 7, 1, 0, -3, SBR_SWITCH_LRC, - 3}, - {CODEC_AAC, 24000, 28000, 11025, 2, 10, 8, 10, 8, 1, 0, -3, SBR_SWITCH_LRC, - 3}, - {CODEC_AAC, 28000, 36000, 11025, 2, 12, 8, 12, 8, 2, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AAC, 36000, 44000, 11025, 2, 13, 9, 13, 9, 2, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AAC, 44000, 52000, 11025, 2, 14, 11, 13, 11, 2, 0, -3, - SBR_SWITCH_LRC, 2}, - {CODEC_AAC, 52000, 60000, 11025, 2, 15, 15, 13, 13, 3, 0, -3, - SBR_SWITCH_LRC, 1}, - {CODEC_AAC, 60000, 76000, 11025, 2, 15, 15, 13, 13, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - {CODEC_AAC, 76000, 128001, 11025, 2, 15, 15, 13, 13, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - - /* 12/24 kHz dual rate */ - {CODEC_AAC, 16000, 24000, 12000, 2, 6, 4, 9, 7, 1, 0, -3, SBR_SWITCH_LRC, - 3}, - {CODEC_AAC, 24000, 28000, 12000, 2, 9, 7, 10, 8, 1, 0, -3, SBR_SWITCH_LRC, - 3}, - {CODEC_AAC, 28000, 36000, 12000, 2, 11, 7, 12, 8, 2, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AAC, 36000, 44000, 12000, 2, 12, 9, 12, 9, 2, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AAC, 44000, 52000, 12000, 2, 13, 12, 13, 12, 2, 0, -3, - SBR_SWITCH_LRC, 2}, - {CODEC_AAC, 52000, 60000, 12000, 2, 14, 14, 13, 13, 3, 0, -3, - SBR_SWITCH_LRC, 1}, - {CODEC_AAC, 60000, 76000, 12000, 2, 14, 14, 13, 13, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - {CODEC_AAC, 76000, 128001, 12000, 2, 14, 14, 13, 13, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - - /* 16/32 kHz dual rate */ - {CODEC_AAC, 16000, 24000, 16000, 2, 4, 2, 1, 0, 1, 0, -3, SBR_SWITCH_LRC, - 3}, - {CODEC_AAC, 24000, 28000, 16000, 2, 8, 7, 10, 8, 1, 0, -3, SBR_SWITCH_LRC, - 3}, - {CODEC_AAC, 28000, 36000, 16000, 2, 10, 9, 12, 11, 2, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AAC, 36000, 44000, 16000, 2, 13, 13, 13, 13, 2, 0, -3, - SBR_SWITCH_LRC, 2}, - {CODEC_AAC, 44000, 52000, 16000, 2, 14, 14, 13, 13, 2, 0, -3, - SBR_SWITCH_LRC, 2}, - {CODEC_AAC, 52000, 60000, 16000, 2, 14, 14, 13, 13, 3, 0, -3, - SBR_SWITCH_LRC, 1}, - {CODEC_AAC, 60000, 76000, 16000, 2, 14, 14, 13, 13, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - {CODEC_AAC, 76000, 128001, 16000, 2, 14, 14, 13, 13, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - - /* 22.05/44.1 kHz dual rate */ - {CODEC_AAC, 16000, 24000, 22050, 2, 2, 1, 1, 0, 1, 0, -3, SBR_SWITCH_LRC, - 3}, - {CODEC_AAC, 24000, 28000, 22050, 2, 5, 4, 6, 5, 1, 0, -3, SBR_SWITCH_LRC, - 3}, - {CODEC_AAC, 28000, 32000, 22050, 2, 5, 4, 8, 7, 2, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AAC, 32000, 36000, 22050, 2, 7, 6, 8, 7, 2, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AAC, 36000, 44000, 22050, 2, 10, 10, 9, 9, 2, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AAC, 44000, 52000, 22050, 2, 12, 12, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AAC, 52000, 60000, 22050, 2, 13, 13, 10, 10, 3, 0, -3, - SBR_SWITCH_LRC, 1}, - {CODEC_AAC, 60000, 76000, 22050, 2, 14, 14, 12, 12, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - {CODEC_AAC, 76000, 128001, 22050, 2, 14, 14, 12, 12, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - - /* 24/48 kHz dual rate */ - {CODEC_AAC, 16000, 24000, 24000, 2, 2, 1, 1, 0, 1, 0, -3, SBR_SWITCH_LRC, - 3}, - {CODEC_AAC, 24000, 28000, 24000, 2, 5, 5, 6, 6, 1, 0, -3, SBR_SWITCH_LRC, - 3}, - {CODEC_AAC, 28000, 36000, 24000, 2, 7, 6, 8, 7, 2, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AAC, 36000, 44000, 24000, 2, 10, 10, 9, 9, 2, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AAC, 44000, 52000, 24000, 2, 12, 12, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AAC, 52000, 60000, 24000, 2, 13, 13, 10, 10, 3, 0, -3, - SBR_SWITCH_LRC, 1}, - {CODEC_AAC, 60000, 76000, 24000, 2, 14, 14, 12, 12, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - {CODEC_AAC, 76000, 128001, 24000, 2, 14, 14, 12, 12, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - - /* 32/64 kHz dual rate */ - {CODEC_AAC, 32000, 60000, 32000, 2, 4, 4, 4, 4, 2, 0, -3, SBR_SWITCH_LRC, - 3}, - {CODEC_AAC, 60000, 80000, 32000, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AAC, 80000, 112000, 32000, 2, 9, 9, 8, 8, 3, 0, -3, SBR_LEFT_RIGHT, - 1}, - {CODEC_AAC, 112000, 144000, 32000, 2, 11, 11, 10, 10, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - {CODEC_AAC, 144000, 256001, 32000, 2, 13, 13, 11, 11, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - - /* 44.1/88.2 kHz dual rate */ - {CODEC_AAC, 32000, 60000, 44100, 2, 4, 4, 4, 4, 2, 0, -3, SBR_SWITCH_LRC, - 3}, - {CODEC_AAC, 60000, 80000, 44100, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AAC, 80000, 112000, 44100, 2, 9, 9, 8, 8, 3, 0, -3, SBR_LEFT_RIGHT, - 1}, - {CODEC_AAC, 112000, 144000, 44100, 2, 11, 11, 10, 10, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - {CODEC_AAC, 144000, 256001, 44100, 2, 13, 13, 11, 11, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - - /* 48/96 kHz dual rate */ - {CODEC_AAC, 36000, 60000, 48000, 2, 4, 4, 9, 9, 2, 0, -3, SBR_SWITCH_LRC, - 3}, - {CODEC_AAC, 60000, 80000, 48000, 2, 7, 7, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AAC, 80000, 112000, 48000, 2, 9, 9, 10, 10, 3, 0, -3, SBR_LEFT_RIGHT, - 1}, - {CODEC_AAC, 112000, 144000, 48000, 2, 11, 11, 11, 11, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - {CODEC_AAC, 144000, 256001, 48000, 2, 13, 13, 11, 11, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - - /** AAC LOW DELAY SECTION **/ - - /* 24 kHz dual rate - 12kHz singlerate is not allowed (deactivated in - FDKsbrEnc_IsSbrSettingAvail()) */ - {CODEC_AACLD, 8000, 32000, 12000, 1, 1, 1, 0, 0, 1, 0, 6, SBR_MONO, 3}, - - /*** mono ***/ - /* 16/32 kHz dual rate */ - {CODEC_AACLD, 16000, 18000, 16000, 1, 4, 5, 9, 7, 1, 0, 6, SBR_MONO, 3}, - {CODEC_AACLD, 18000, 22000, 16000, 1, 7, 7, 12, 12, 1, 6, 9, SBR_MONO, 3}, - {CODEC_AACLD, 22000, 28000, 16000, 1, 6, 6, 9, 9, 2, 3, 6, SBR_MONO, 3}, - {CODEC_AACLD, 28000, 36000, 16000, 1, 8, 8, 12, 7, 2, 9, 12, SBR_MONO, 3}, - {CODEC_AACLD, 36000, 44000, 16000, 1, 10, 14, 12, 13, 2, 0, 3, SBR_MONO, 1}, - {CODEC_AACLD, 44000, 64001, 16000, 1, 11, 14, 13, 13, 2, 0, 3, SBR_MONO, 1}, - - /* 22.05/44.1 kHz dual rate */ - {CODEC_AACLD, 18000, 22000, 22050, 1, 4, 4, 5, 5, 2, 0, 6, SBR_MONO, 3}, - {CODEC_AACLD, 22000, 28000, 22050, 1, 5, 5, 6, 6, 2, 0, 6, SBR_MONO, 2}, - {CODEC_AACLD, 28000, 36000, 22050, 1, 7, 8, 8, 8, 2, 0, 3, SBR_MONO, 2}, - {CODEC_AACLD, 36000, 44000, 22050, 1, 9, 9, 9, 9, 2, 0, 3, SBR_MONO, 1}, - {CODEC_AACLD, 44000, 52000, 22050, 1, 12, 11, 11, 11, 2, 0, 3, SBR_MONO, 1}, - {CODEC_AACLD, 52000, 64001, 22050, 1, 13, 11, 11, 10, 2, 0, 3, SBR_MONO, 1}, - - /* 24/48 kHz dual rate */ - {CODEC_AACLD, 20000, 22000, 24000, 1, 3, 4, 8, 8, 2, 0, 6, SBR_MONO, 2}, - {CODEC_AACLD, 22000, 28000, 24000, 1, 3, 8, 8, 7, 2, 0, 3, SBR_MONO, 2}, - {CODEC_AACLD, 28000, 36000, 24000, 1, 4, 8, 8, 7, 2, 0, 3, SBR_MONO, 2}, - {CODEC_AACLD, 36000, 56000, 24000, 1, 8, 9, 9, 8, 2, 0, 3, SBR_MONO, 1}, - {CODEC_AACLD, 56000, 64001, 24000, 1, 13, 11, 11, 10, 2, 0, 3, SBR_MONO, 1}, - - /* 32/64 kHz dual rate */ - {CODEC_AACLD, 24000, 36000, 32000, 1, 4, 4, 4, 4, 2, 0, 3, SBR_MONO, 3}, - {CODEC_AACLD, 36000, 60000, 32000, 1, 7, 7, 6, 6, 2, 0, 3, SBR_MONO, 2}, - {CODEC_AACLD, 60000, 72000, 32000, 1, 9, 9, 8, 8, 2, 0, 3, SBR_MONO, 1}, - {CODEC_AACLD, 72000, 100000, 32000, 1, 11, 11, 10, 10, 2, 0, 3, SBR_MONO, - 1}, - {CODEC_AACLD, 100000, 160001, 32000, 1, 13, 13, 11, 11, 2, 0, 3, SBR_MONO, - 1}, - - /* 44/88 kHz dual rate */ - {CODEC_AACLD, 36000, 60000, 44100, 1, 8, 7, 6, 9, 2, 0, 3, SBR_MONO, 2}, - {CODEC_AACLD, 60000, 72000, 44100, 1, 9, 9, 10, 10, 2, 0, 3, SBR_MONO, 1}, - {CODEC_AACLD, 72000, 100000, 44100, 1, 11, 11, 11, 11, 2, 0, 3, SBR_MONO, - 1}, - {CODEC_AACLD, 100000, 160001, 44100, 1, 13, 13, 11, 11, 2, 0, 3, SBR_MONO, - 1}, - - /* 48/96 kHz dual rate */ /* 32 and 40kbps line tuned for dual-rate SBR - */ - {CODEC_AACLD, 36000, 60000, 48000, 1, 4, 7, 4, 4, 2, 0, 3, SBR_MONO, 3}, - {CODEC_AACLD, 60000, 72000, 48000, 1, 9, 9, 10, 10, 2, 0, 3, SBR_MONO, 1}, - {CODEC_AACLD, 72000, 100000, 48000, 1, 11, 11, 11, 11, 2, 0, 3, SBR_MONO, - 1}, - {CODEC_AACLD, 100000, 160001, 48000, 1, 13, 13, 11, 11, 2, 0, 3, SBR_MONO, - 1}, - - /*** stereo ***/ - /* 16/32 kHz dual rate */ - {CODEC_AACLD, 32000, 36000, 16000, 2, 10, 9, 12, 11, 2, 0, -3, - SBR_SWITCH_LRC, 2}, - {CODEC_AACLD, 36000, 44000, 16000, 2, 13, 13, 13, 13, 2, 0, -3, - SBR_SWITCH_LRC, 2}, - {CODEC_AACLD, 44000, 52000, 16000, 2, 10, 9, 11, 9, 2, 0, -3, - SBR_SWITCH_LRC, 2}, - {CODEC_AACLD, 52000, 60000, 16000, 2, 14, 14, 13, 13, 3, 0, -3, - SBR_SWITCH_LRC, 1}, - {CODEC_AACLD, 60000, 76000, 16000, 2, 14, 14, 13, 13, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - {CODEC_AACLD, 76000, 128001, 16000, 2, 14, 14, 13, 13, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - - /* 22.05/44.1 kHz dual rate */ - {CODEC_AACLD, 32000, 36000, 22050, 2, 5, 4, 7, 6, 2, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AACLD, 36000, 44000, 22050, 2, 5, 8, 8, 8, 2, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AACLD, 44000, 52000, 22050, 2, 7, 10, 8, 8, 3, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AACLD, 52000, 60000, 22050, 2, 9, 11, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, - 1}, - {CODEC_AACLD, 60000, 76000, 22050, 2, 10, 12, 10, 11, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - {CODEC_AACLD, 76000, 82000, 22050, 2, 12, 12, 11, 11, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - {CODEC_AACLD, 82000, 128001, 22050, 2, 13, 12, 11, 11, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - - /* 24/48 kHz dual rate */ - {CODEC_AACLD, 32000, 36000, 24000, 2, 5, 4, 7, 6, 2, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AACLD, 36000, 44000, 24000, 2, 4, 8, 8, 8, 2, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AACLD, 44000, 52000, 24000, 2, 6, 10, 8, 8, 3, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AACLD, 52000, 60000, 24000, 2, 9, 11, 9, 9, 3, 0, -3, SBR_SWITCH_LRC, - 1}, - {CODEC_AACLD, 60000, 76000, 24000, 2, 11, 12, 10, 11, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - {CODEC_AACLD, 76000, 88000, 24000, 2, 12, 13, 11, 11, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - {CODEC_AACLD, 88000, 128001, 24000, 2, 13, 13, 11, 11, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - - /* 32/64 kHz dual rate */ - {CODEC_AACLD, 60000, 80000, 32000, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AACLD, 80000, 112000, 32000, 2, 9, 9, 8, 8, 3, 0, -3, SBR_LEFT_RIGHT, - 1}, - {CODEC_AACLD, 112000, 144000, 32000, 2, 11, 11, 10, 10, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - {CODEC_AACLD, 144000, 256001, 32000, 2, 13, 13, 11, 11, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - - /* 44.1/88.2 kHz dual rate */ - {CODEC_AACLD, 60000, 80000, 44100, 2, 7, 7, 6, 6, 3, 0, -3, SBR_SWITCH_LRC, - 2}, - {CODEC_AACLD, 80000, 112000, 44100, 2, 10, 10, 8, 8, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - {CODEC_AACLD, 112000, 144000, 44100, 2, 12, 12, 10, 10, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - {CODEC_AACLD, 144000, 256001, 44100, 2, 13, 13, 11, 11, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - - /* 48/96 kHz dual rate */ - {CODEC_AACLD, 60000, 80000, 48000, 2, 7, 7, 10, 10, 2, 0, -3, - SBR_SWITCH_LRC, 2}, - {CODEC_AACLD, 80000, 112000, 48000, 2, 9, 9, 10, 10, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - {CODEC_AACLD, 112000, 144000, 48000, 2, 11, 11, 11, 11, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - {CODEC_AACLD, 144000, 176000, 48000, 2, 12, 12, 11, 11, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - {CODEC_AACLD, 176000, 256001, 48000, 2, 13, 13, 11, 11, 3, 0, -3, - SBR_LEFT_RIGHT, 1}, - -}; - -const int sbrTuningTableSize = - sizeof(sbrTuningTable) / sizeof(sbrTuningTable[0]); - -const psTuningTable_t psTuningTable[4] = { - {8000, 22000, PSENC_STEREO_BANDS_10, PSENC_NENV_1, - FL2FXCONST_DBL(3.0f / 4.0f)}, - {22000, 28000, PSENC_STEREO_BANDS_20, PSENC_NENV_1, - FL2FXCONST_DBL(2.0f / 4.0f)}, - {28000, 36000, PSENC_STEREO_BANDS_20, PSENC_NENV_2, - FL2FXCONST_DBL(1.5f / 4.0f)}, - {36000, 160001, PSENC_STEREO_BANDS_20, PSENC_NENV_4, - FL2FXCONST_DBL(1.1f / 4.0f)}, -}; - -//@} --- a/libSBRenc/src/sbrenc_rom.h +++ /dev/null @@ -1,145 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! -\file -\brief Declaration of constant tables -$Revision: 92790 $ -*/ -#ifndef SBRENC_ROM_H -#define SBRENC_ROM_H - -#include "sbr_def.h" -#include "sbr_encoder.h" - -#include "ps_main.h" - -/* - huffman tables -*/ -extern const INT v_Huff_envelopeLevelC10T[121]; -extern const UCHAR v_Huff_envelopeLevelL10T[121]; -extern const INT v_Huff_envelopeLevelC10F[121]; -extern const UCHAR v_Huff_envelopeLevelL10F[121]; -extern const INT bookSbrEnvBalanceC10T[49]; -extern const UCHAR bookSbrEnvBalanceL10T[49]; -extern const INT bookSbrEnvBalanceC10F[49]; -extern const UCHAR bookSbrEnvBalanceL10F[49]; -extern const INT v_Huff_envelopeLevelC11T[63]; -extern const UCHAR v_Huff_envelopeLevelL11T[63]; -extern const INT v_Huff_envelopeLevelC11F[63]; -extern const UCHAR v_Huff_envelopeLevelL11F[63]; -extern const INT bookSbrEnvBalanceC11T[25]; -extern const UCHAR bookSbrEnvBalanceL11T[25]; -extern const INT bookSbrEnvBalanceC11F[25]; -extern const UCHAR bookSbrEnvBalanceL11F[25]; -extern const INT v_Huff_NoiseLevelC11T[63]; -extern const UCHAR v_Huff_NoiseLevelL11T[63]; -extern const INT bookSbrNoiseBalanceC11T[25]; -extern const UCHAR bookSbrNoiseBalanceL11T[25]; - -extern const sbrTuningTable_t sbrTuningTable[]; -extern const int sbrTuningTableSize; - -extern const psTuningTable_t psTuningTable[4]; - -#endif --- a/libSBRenc/src/ton_corr.cpp +++ /dev/null @@ -1,891 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -#include "ton_corr.h" - -#include "sbrenc_ram.h" -#include "sbr_misc.h" -#include "genericStds.h" -#include "autocorr2nd.h" - -#define BAND_V_SIZE 32 -#define NUM_V_COMBINE \ - 8 /* Must be a divisor of 64 and fulfill the ASSERTs below */ - -/**************************************************************************/ -/*! - \brief Calculates the tonal to noise ration for different frequency bands - and time segments. - - The ratio between the predicted energy (tonal energy A) and the total - energy (A + B) is calculated. This is converted to the ratio between - the predicted energy (tonal energy A) and the non-predictable energy - (noise energy B). Hence the quota-matrix contains A/B = q/(1-q). - - The samples in nrgVector are scaled by 1.0/16.0 - The samples in pNrgVectorFreq are scaled by 1.0/2.0 - The samples in quotaMatrix are scaled by RELAXATION - - \return none. - -*/ -/**************************************************************************/ - -void FDKsbrEnc_CalculateTonalityQuotas( - HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */ - FIXP_DBL **RESTRICT - sourceBufferReal, /*!< The real part of the QMF-matrix. */ - FIXP_DBL **RESTRICT - sourceBufferImag, /*!< The imaginary part of the QMF-matrix. */ - INT usb, /*!< upper side band, highest + 1 QMF band in the SBR range. */ - INT qmfScale /*!< sclefactor of QMF subsamples */ -) { - INT i, k, r, r2, timeIndex, autoCorrScaling; - - INT startIndexMatrix = hTonCorr->startIndexMatrix; - INT totNoEst = hTonCorr->numberOfEstimates; - INT noEstPerFrame = hTonCorr->numberOfEstimatesPerFrame; - INT move = hTonCorr->move; - INT noQmfChannels = hTonCorr->noQmfChannels; /* Number of Bands */ - INT buffLen = hTonCorr->bufferLength; /* Number of Slots */ - INT stepSize = hTonCorr->stepSize; - INT *pBlockLength = hTonCorr->lpcLength; - INT **RESTRICT signMatrix = hTonCorr->signMatrix; - FIXP_DBL *RESTRICT nrgVector = hTonCorr->nrgVector; - FIXP_DBL **RESTRICT quotaMatrix = hTonCorr->quotaMatrix; - FIXP_DBL *RESTRICT pNrgVectorFreq = hTonCorr->nrgVectorFreq; - - FIXP_DBL *realBuf; - FIXP_DBL *imagBuf; - - FIXP_DBL alphar[2], alphai[2], fac; - - C_ALLOC_SCRATCH_START(ac, ACORR_COEFS, 1) - C_ALLOC_SCRATCH_START(realBufRef, FIXP_DBL, 2 * BAND_V_SIZE * NUM_V_COMBINE) - realBuf = realBufRef; - imagBuf = realBuf + BAND_V_SIZE * NUM_V_COMBINE; - - FDK_ASSERT(buffLen <= BAND_V_SIZE); - FDK_ASSERT(sizeof(FIXP_DBL) * NUM_V_COMBINE * BAND_V_SIZE * 2 < - (1024 * sizeof(FIXP_DBL) - sizeof(ACORR_COEFS))); - - /* - * Buffering of the quotaMatrix and the quotaMatrixTransp. - *********************************************************/ - for (i = 0; i < move; i++) { - FDKmemcpy(quotaMatrix[i], quotaMatrix[i + noEstPerFrame], - noQmfChannels * sizeof(FIXP_DBL)); - FDKmemcpy(signMatrix[i], signMatrix[i + noEstPerFrame], - noQmfChannels * sizeof(INT)); - } - - FDKmemmove(nrgVector, nrgVector + noEstPerFrame, move * sizeof(FIXP_DBL)); - FDKmemclear(nrgVector + startIndexMatrix, - (totNoEst - startIndexMatrix) * sizeof(FIXP_DBL)); - FDKmemclear(pNrgVectorFreq, noQmfChannels * sizeof(FIXP_DBL)); - - /* - * Calculate the quotas for the current time steps. - **************************************************/ - - for (r = 0; r < usb; r++) { - int blockLength; - - k = hTonCorr->nextSample; /* startSample */ - timeIndex = startIndexMatrix; - /* Copy as many as possible Band across all Slots at once */ - if (realBuf != realBufRef) { - realBuf -= BAND_V_SIZE; - imagBuf -= BAND_V_SIZE; - } else { - realBuf += BAND_V_SIZE * (NUM_V_COMBINE - 1); - imagBuf += BAND_V_SIZE * (NUM_V_COMBINE - 1); - - for (i = 0; i < buffLen; i++) { - int v; - FIXP_DBL *ptr; - ptr = realBuf + i; - for (v = 0; v < NUM_V_COMBINE; v++) { - ptr[0] = sourceBufferReal[i][r + v]; - ptr[0 + BAND_V_SIZE * NUM_V_COMBINE] = sourceBufferImag[i][r + v]; - ptr -= BAND_V_SIZE; - } - } - } - - blockLength = pBlockLength[0]; - - while (k <= buffLen - blockLength) { - autoCorrScaling = fixMin( - getScalefactor(&realBuf[k - LPC_ORDER], LPC_ORDER + blockLength), - getScalefactor(&imagBuf[k - LPC_ORDER], LPC_ORDER + blockLength)); - autoCorrScaling = fixMax(0, autoCorrScaling - 1); - - scaleValues(&realBuf[k - LPC_ORDER], LPC_ORDER + blockLength, - autoCorrScaling); - scaleValues(&imagBuf[k - LPC_ORDER], LPC_ORDER + blockLength, - autoCorrScaling); - - autoCorrScaling <<= 1; /* consider qmf buffer scaling twice */ - autoCorrScaling += - autoCorr2nd_cplx(ac, realBuf + k, imagBuf + k, blockLength); - - if (ac->det == FL2FXCONST_DBL(0.0f)) { - alphar[1] = alphai[1] = FL2FXCONST_DBL(0.0f); - - alphar[0] = (ac->r01r) >> 2; - alphai[0] = (ac->r01i) >> 2; - - fac = fMultDiv2(ac->r00r, ac->r11r) >> 1; - } else { - alphar[1] = (fMultDiv2(ac->r01r, ac->r12r) >> 1) - - (fMultDiv2(ac->r01i, ac->r12i) >> 1) - - (fMultDiv2(ac->r02r, ac->r11r) >> 1); - alphai[1] = (fMultDiv2(ac->r01i, ac->r12r) >> 1) + - (fMultDiv2(ac->r01r, ac->r12i) >> 1) - - (fMultDiv2(ac->r02i, ac->r11r) >> 1); - - alphar[0] = (fMultDiv2(ac->r01r, ac->det) >> (ac->det_scale + 1)) + - fMult(alphar[1], ac->r12r) + fMult(alphai[1], ac->r12i); - alphai[0] = (fMultDiv2(ac->r01i, ac->det) >> (ac->det_scale + 1)) + - fMult(alphai[1], ac->r12r) - fMult(alphar[1], ac->r12i); - - fac = fMultDiv2(ac->r00r, fMult(ac->det, ac->r11r)) >> - (ac->det_scale + 1); - } - - if (fac == FL2FXCONST_DBL(0.0f)) { - quotaMatrix[timeIndex][r] = FL2FXCONST_DBL(0.0f); - signMatrix[timeIndex][r] = 0; - } else { - /* quotaMatrix is scaled with the factor RELAXATION - parse RELAXATION in fractional part and shift factor: 1/(1/0.524288 * - 2^RELAXATION_SHIFT) */ - FIXP_DBL tmp, num, denom; - INT numShift, denomShift, commonShift; - INT sign; - - num = fMultDiv2(alphar[0], ac->r01r) + fMultDiv2(alphai[0], ac->r01i) - - fMultDiv2(alphar[1], fMult(ac->r02r, ac->r11r)) - - fMultDiv2(alphai[1], fMult(ac->r02i, ac->r11r)); - num = fixp_abs(num); - - denom = (fac >> 1) + - (fMultDiv2(fac, RELAXATION_FRACT) >> RELAXATION_SHIFT) - num; - denom = fixp_abs(denom); - - num = fMult(num, RELAXATION_FRACT); - - numShift = CountLeadingBits(num) - 2; - num = scaleValue(num, numShift); - - denomShift = CountLeadingBits(denom); - denom = (FIXP_DBL)denom << denomShift; - - if ((num > FL2FXCONST_DBL(0.0f)) && (denom != FL2FXCONST_DBL(0.0f))) { - commonShift = - fixMin(numShift - denomShift + RELAXATION_SHIFT, DFRACT_BITS - 1); - if (commonShift < 0) { - commonShift = -commonShift; - tmp = schur_div(num, denom, 16); - commonShift = fixMin(commonShift, CountLeadingBits(tmp)); - quotaMatrix[timeIndex][r] = tmp << commonShift; - } else { - quotaMatrix[timeIndex][r] = - schur_div(num, denom, 16) >> commonShift; - } - } else { - quotaMatrix[timeIndex][r] = FL2FXCONST_DBL(0.0f); - } - - if (ac->r11r != FL2FXCONST_DBL(0.0f)) { - if (((ac->r01r >= FL2FXCONST_DBL(0.0f)) && - (ac->r11r >= FL2FXCONST_DBL(0.0f))) || - ((ac->r01r < FL2FXCONST_DBL(0.0f)) && - (ac->r11r < FL2FXCONST_DBL(0.0f)))) { - sign = 1; - } else { - sign = -1; - } - } else { - sign = 1; - } - - if (sign < 0) { - r2 = r; /* (INT) pow(-1, band); */ - } else { - r2 = r + 1; /* (INT) pow(-1, band+1); */ - } - signMatrix[timeIndex][r] = 1 - 2 * (r2 & 0x1); - } - - nrgVector[timeIndex] += - ((ac->r00r) >> - fixMin(DFRACT_BITS - 1, - (2 * qmfScale + autoCorrScaling + SCALE_NRGVEC))); - /* pNrgVectorFreq[r] finally has to be divided by noEstPerFrame, replaced - * division by shifting with one */ - pNrgVectorFreq[r] = - pNrgVectorFreq[r] + - ((ac->r00r) >> - fixMin(DFRACT_BITS - 1, - (2 * qmfScale + autoCorrScaling + SCALE_NRGVEC))); - - blockLength = pBlockLength[1]; - k += stepSize; - timeIndex++; - } - } - - C_ALLOC_SCRATCH_END(realBufRef, FIXP_DBL, 2 * BAND_V_SIZE * NUM_V_COMBINE) - C_ALLOC_SCRATCH_END(ac, ACORR_COEFS, 1) -} - -/**************************************************************************/ -/*! - \brief Extracts the parameters required in the decoder to obtain the - correct tonal to noise ratio after SBR. - - Estimates the tonal to noise ratio of the original signal (using LPC). - Predicts the tonal to noise ration of the SBR signal (in the decoder) by - patching the tonal to noise ratio values similar to the patching of the - lowband in the decoder. Given the tonal to noise ratio of the original - and the SBR signal, it estimates the required amount of inverse filtering, - additional noise as well as any additional sines. - - \return none. - -*/ -/**************************************************************************/ -void FDKsbrEnc_TonCorrParamExtr( - HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */ - INVF_MODE *infVec, /*!< Vector where the inverse filtering levels will be - stored. */ - FIXP_DBL *noiseLevels, /*!< Vector where the noise levels will be stored. */ - INT *missingHarmonicFlag, /*!< Flag set to one or zero, dependent on if any - strong sines are missing.*/ - UCHAR *missingHarmonicsIndex, /*!< Vector indicating where sines are - missing. */ - UCHAR *envelopeCompensation, /*!< Vector to store compensation values for - the energies in. */ - const SBR_FRAME_INFO *frameInfo, /*!< Frame info struct, contains the time - and frequency grid of the current - frame.*/ - UCHAR *transientInfo, /*!< Transient info.*/ - UCHAR *freqBandTable, /*!< Frequency band tables for high-res.*/ - INT nSfb, /*!< Number of scalefactor bands for high-res. */ - XPOS_MODE xposType, /*!< Type of transposer used in the decoder.*/ - UINT sbrSyntaxFlags) { - INT band; - INT transientFlag = transientInfo[1]; /*!< Flag indicating if a transient is - present in the current frame. */ - INT transientPos = transientInfo[0]; /*!< Position of the transient.*/ - INT transientFrame, transientFrameInvfEst; - INVF_MODE *infVecPtr; - - /* Determine if this is a frame where a transient starts... - - The detection of noise-floor, missing harmonics and invf_est, is not in sync - for the non-buf-opt decoder such as AAC. Hence we need to keep track on the - transient in the present frame as well as in the next. - */ - transientFrame = 0; - if (hTonCorr->transientNextFrame) { /* The transient was detected in the - previous frame, but is actually */ - transientFrame = 1; - hTonCorr->transientNextFrame = 0; - - if (transientFlag) { - if (transientPos + hTonCorr->transientPosOffset >= - frameInfo->borders[frameInfo->nEnvelopes]) { - hTonCorr->transientNextFrame = 1; - } - } - } else { - if (transientFlag) { - if (transientPos + hTonCorr->transientPosOffset < - frameInfo->borders[frameInfo->nEnvelopes]) { - transientFrame = 1; - hTonCorr->transientNextFrame = 0; - } else { - hTonCorr->transientNextFrame = 1; - } - } - } - transientFrameInvfEst = transientFrame; - - /* - Estimate the required invese filtereing level. - */ - if (hTonCorr->switchInverseFilt) - FDKsbrEnc_qmfInverseFilteringDetector( - &hTonCorr->sbrInvFilt, hTonCorr->quotaMatrix, hTonCorr->nrgVector, - hTonCorr->indexVector, hTonCorr->frameStartIndexInvfEst, - hTonCorr->numberOfEstimatesPerFrame + hTonCorr->frameStartIndexInvfEst, - transientFrameInvfEst, infVec); - - /* - Detect what tones will be missing. - */ - if (xposType == XPOS_LC) { - FDKsbrEnc_SbrMissingHarmonicsDetectorQmf( - &hTonCorr->sbrMissingHarmonicsDetector, hTonCorr->quotaMatrix, - hTonCorr->signMatrix, hTonCorr->indexVector, frameInfo, transientInfo, - missingHarmonicFlag, missingHarmonicsIndex, freqBandTable, nSfb, - envelopeCompensation, hTonCorr->nrgVectorFreq); - } else { - *missingHarmonicFlag = 0; - FDKmemclear(missingHarmonicsIndex, nSfb * sizeof(UCHAR)); - } - - /* - Noise floor estimation - */ - - infVecPtr = hTonCorr->sbrInvFilt.prevInvfMode; - - FDKsbrEnc_sbrNoiseFloorEstimateQmf( - &hTonCorr->sbrNoiseFloorEstimate, frameInfo, noiseLevels, - hTonCorr->quotaMatrix, hTonCorr->indexVector, *missingHarmonicFlag, - hTonCorr->frameStartIndex, hTonCorr->numberOfEstimatesPerFrame, - transientFrame, infVecPtr, sbrSyntaxFlags); - - /* Store the invfVec data for the next frame...*/ - for (band = 0; band < hTonCorr->sbrInvFilt.noDetectorBands; band++) { - hTonCorr->sbrInvFilt.prevInvfMode[band] = infVec[band]; - } -} - -/**************************************************************************/ -/*! - \brief Searches for the closest match in the frequency master table. - - - - \return closest entry. - -*/ -/**************************************************************************/ -static INT findClosestEntry(INT goalSb, UCHAR *v_k_master, INT numMaster, - INT direction) { - INT index; - - if (goalSb <= v_k_master[0]) return v_k_master[0]; - - if (goalSb >= v_k_master[numMaster]) return v_k_master[numMaster]; - - if (direction) { - index = 0; - while (v_k_master[index] < goalSb) { - index++; - } - } else { - index = numMaster; - while (v_k_master[index] > goalSb) { - index--; - } - } - - return v_k_master[index]; -} - -/**************************************************************************/ -/*! - \brief resets the patch - - - - \return errorCode, noError if successful. - -*/ -/**************************************************************************/ -static INT resetPatch( - HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */ - INT xposctrl, /*!< Different patch modes. */ - INT highBandStartSb, /*!< Start band of the SBR range. */ - UCHAR *v_k_master, /*!< Master frequency table from which all other table - are derived.*/ - INT numMaster, /*!< Number of elements in the master table. */ - INT fs, /*!< Sampling frequency. */ - INT noChannels) /*!< Number of QMF-channels. */ -{ - INT patch, k, i; - INT targetStopBand; - - PATCH_PARAM *patchParam = hTonCorr->patchParam; - - INT sbGuard = hTonCorr->guard; - INT sourceStartBand; - INT patchDistance; - INT numBandsInPatch; - - INT lsb = - v_k_master[0]; /* Lowest subband related to the synthesis filterbank */ - INT usb = v_k_master[numMaster]; /* Stop subband related to the synthesis - filterbank */ - INT xoverOffset = - highBandStartSb - - v_k_master[0]; /* Calculate distance in subbands between k0 and kx */ - - INT goalSb; - - /* - * Initialize the patching parameter - */ - - if (xposctrl == 1) { - lsb += xoverOffset; - xoverOffset = 0; - } - - goalSb = (INT)((2 * noChannels * 16000 + (fs >> 1)) / fs); /* 16 kHz band */ - goalSb = findClosestEntry(goalSb, v_k_master, numMaster, - 1); /* Adapt region to master-table */ - - /* First patch */ - sourceStartBand = hTonCorr->shiftStartSb + xoverOffset; - targetStopBand = lsb + xoverOffset; - - /* even (odd) numbered channel must be patched to even (odd) numbered channel - */ - patch = 0; - while (targetStopBand < usb) { - /* To many patches */ - if (patch >= MAX_NUM_PATCHES) return (1); /*Number of patches to high */ - - patchParam[patch].guardStartBand = targetStopBand; - targetStopBand += sbGuard; - patchParam[patch].targetStartBand = targetStopBand; - - numBandsInPatch = - goalSb - targetStopBand; /* get the desired range of the patch */ - - if (numBandsInPatch >= lsb - sourceStartBand) { - /* desired number bands are not available -> patch whole source range */ - patchDistance = - targetStopBand - sourceStartBand; /* get the targetOffset */ - patchDistance = - patchDistance & ~1; /* rounding off odd numbers and make all even */ - numBandsInPatch = lsb - (targetStopBand - patchDistance); - numBandsInPatch = findClosestEntry(targetStopBand + numBandsInPatch, - v_k_master, numMaster, 0) - - targetStopBand; /* Adapt region to master-table */ - } - - /* desired number bands are available -> get the minimal even patching - * distance */ - patchDistance = - numBandsInPatch + targetStopBand - lsb; /* get minimal distance */ - patchDistance = (patchDistance + 1) & - ~1; /* rounding up odd numbers and make all even */ - - if (numBandsInPatch <= 0) { - patch--; - } else { - patchParam[patch].sourceStartBand = targetStopBand - patchDistance; - patchParam[patch].targetBandOffs = patchDistance; - patchParam[patch].numBandsInPatch = numBandsInPatch; - patchParam[patch].sourceStopBand = - patchParam[patch].sourceStartBand + numBandsInPatch; - - targetStopBand += patchParam[patch].numBandsInPatch; - } - - /* All patches but first */ - sourceStartBand = hTonCorr->shiftStartSb; - - /* Check if we are close to goalSb */ - if (fixp_abs(targetStopBand - goalSb) < 3) { - goalSb = usb; - } - - patch++; - } - - patch--; - - /* if highest patch contains less than three subband: skip it */ - if (patchParam[patch].numBandsInPatch < 3 && patch > 0) { - patch--; - } - - hTonCorr->noOfPatches = patch + 1; - - /* Assign the index-vector, so we know where to look for the high-band. - -1 represents a guard-band. */ - for (k = 0; k < hTonCorr->patchParam[0].guardStartBand; k++) - hTonCorr->indexVector[k] = k; - - for (i = 0; i < hTonCorr->noOfPatches; i++) { - INT sourceStart = hTonCorr->patchParam[i].sourceStartBand; - INT targetStart = hTonCorr->patchParam[i].targetStartBand; - INT numberOfBands = hTonCorr->patchParam[i].numBandsInPatch; - INT startGuardBand = hTonCorr->patchParam[i].guardStartBand; - - for (k = 0; k < (targetStart - startGuardBand); k++) - hTonCorr->indexVector[startGuardBand + k] = -1; - - for (k = 0; k < numberOfBands; k++) - hTonCorr->indexVector[targetStart + k] = sourceStart + k; - } - - return (0); -} - -/**************************************************************************/ -/*! - \brief Creates an instance of the tonality correction parameter module. - - The module includes modules for inverse filtering level estimation, - missing harmonics detection and noise floor level estimation. - - \return errorCode, noError if successful. -*/ -/**************************************************************************/ -INT FDKsbrEnc_CreateTonCorrParamExtr( - HANDLE_SBR_TON_CORR_EST - hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */ - INT chan) /*!< Channel index, needed for mem allocation */ -{ - INT i; - FIXP_DBL *quotaMatrix = GetRam_Sbr_quotaMatrix(chan); - INT *signMatrix = GetRam_Sbr_signMatrix(chan); - - if ((NULL == quotaMatrix) || (NULL == signMatrix)) { - goto bail; - } - - FDKmemclear(hTonCorr, sizeof(SBR_TON_CORR_EST)); - - for (i = 0; i < MAX_NO_OF_ESTIMATES; i++) { - hTonCorr->quotaMatrix[i] = quotaMatrix + (i * 64); - hTonCorr->signMatrix[i] = signMatrix + (i * 64); - } - - if (0 != FDKsbrEnc_CreateSbrMissingHarmonicsDetector( - &hTonCorr->sbrMissingHarmonicsDetector, chan)) { - goto bail; - } - - return 0; - -bail: - hTonCorr->quotaMatrix[0] = quotaMatrix; - hTonCorr->signMatrix[0] = signMatrix; - - FDKsbrEnc_DeleteTonCorrParamExtr(hTonCorr); - - return -1; -} - -/**************************************************************************/ -/*! - \brief Initialize an instance of the tonality correction parameter module. - - The module includes modules for inverse filtering level estimation, - missing harmonics detection and noise floor level estimation. - - \return errorCode, noError if successful. -*/ -/**************************************************************************/ -INT FDKsbrEnc_InitTonCorrParamExtr( - INT frameSize, /*!< Current SBR frame size. */ - HANDLE_SBR_TON_CORR_EST - hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */ - HANDLE_SBR_CONFIG_DATA - sbrCfg, /*!< Pointer to SBR configuration parameters. */ - INT timeSlots, /*!< Number of time-slots per frame */ - INT xposCtrl, /*!< Different patch modes. */ - INT ana_max_level, /*!< Maximum level of the adaptive noise. */ - INT noiseBands, /*!< Number of noise bands per octave. */ - INT noiseFloorOffset, /*!< Noise floor offset. */ - UINT useSpeechConfig) /*!< Speech or music tuning. */ -{ - INT nCols = sbrCfg->noQmfSlots; - INT fs = sbrCfg->sampleFreq; - INT noQmfChannels = sbrCfg->noQmfBands; - - INT highBandStartSb = sbrCfg->freqBandTable[LOW_RES][0]; - UCHAR *v_k_master = sbrCfg->v_k_master; - INT numMaster = sbrCfg->num_Master; - - UCHAR **freqBandTable = sbrCfg->freqBandTable; - INT *nSfb = sbrCfg->nSfb; - - INT i; - - /* - Reset the patching and allocate memory for the quota matrix. - Assuming parameters for the LPC analysis. - */ - if (sbrCfg->sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { - switch (timeSlots) { - case NUMBER_TIME_SLOTS_1920: - hTonCorr->lpcLength[0] = 8 - LPC_ORDER; - hTonCorr->lpcLength[1] = 7 - LPC_ORDER; - hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD; - hTonCorr->numberOfEstimatesPerFrame = 2; /* sbrCfg->noQmfSlots / 7 */ - hTonCorr->frameStartIndexInvfEst = 0; - hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; - break; - case NUMBER_TIME_SLOTS_2048: - hTonCorr->lpcLength[0] = 8 - LPC_ORDER; - hTonCorr->lpcLength[1] = 8 - LPC_ORDER; - hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LD; - hTonCorr->numberOfEstimatesPerFrame = 2; /* sbrCfg->noQmfSlots / 8 */ - hTonCorr->frameStartIndexInvfEst = 0; - hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_512LD; - break; - } - } else - switch (timeSlots) { - case NUMBER_TIME_SLOTS_2048: - hTonCorr->lpcLength[0] = 16 - LPC_ORDER; /* blockLength[0] */ - hTonCorr->lpcLength[1] = 16 - LPC_ORDER; /* blockLength[0] */ - hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LC; - hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 16; - hTonCorr->frameStartIndexInvfEst = 0; - hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_2048; - break; - case NUMBER_TIME_SLOTS_1920: - hTonCorr->lpcLength[0] = 15 - LPC_ORDER; /* blockLength[0] */ - hTonCorr->lpcLength[1] = 15 - LPC_ORDER; /* blockLength[0] */ - hTonCorr->numberOfEstimates = NO_OF_ESTIMATES_LC; - hTonCorr->numberOfEstimatesPerFrame = sbrCfg->noQmfSlots / 15; - hTonCorr->frameStartIndexInvfEst = 0; - hTonCorr->transientPosOffset = FRAME_MIDDLE_SLOT_1920; - break; - default: - return -1; - } - - hTonCorr->bufferLength = nCols; - hTonCorr->stepSize = - hTonCorr->lpcLength[0] + LPC_ORDER; /* stepSize[0] implicitly 0. */ - - hTonCorr->nextSample = LPC_ORDER; /* firstSample */ - hTonCorr->move = hTonCorr->numberOfEstimates - - hTonCorr->numberOfEstimatesPerFrame; /* Number of estimates - to move when - buffering.*/ - if (hTonCorr->move < 0) { - return -1; - } - hTonCorr->startIndexMatrix = - hTonCorr->numberOfEstimates - - hTonCorr->numberOfEstimatesPerFrame; /* Where to store the latest - estimations in the tonality - Matrix.*/ - hTonCorr->frameStartIndex = 0; /* Where in the tonality matrix the current - frame (to be sent to the decoder) starts. */ - hTonCorr->prevTransientFlag = 0; - hTonCorr->transientNextFrame = 0; - - hTonCorr->noQmfChannels = noQmfChannels; - - for (i = 0; i < hTonCorr->numberOfEstimates; i++) { - FDKmemclear(hTonCorr->quotaMatrix[i], sizeof(FIXP_DBL) * noQmfChannels); - FDKmemclear(hTonCorr->signMatrix[i], sizeof(INT) * noQmfChannels); - } - - /* Reset the patch.*/ - hTonCorr->guard = 0; - hTonCorr->shiftStartSb = 1; - - if (resetPatch(hTonCorr, xposCtrl, highBandStartSb, v_k_master, numMaster, fs, - noQmfChannels)) - return (1); - - if (FDKsbrEnc_InitSbrNoiseFloorEstimate( - &hTonCorr->sbrNoiseFloorEstimate, ana_max_level, freqBandTable[LO], - nSfb[LO], noiseBands, noiseFloorOffset, timeSlots, useSpeechConfig)) - return (1); - - if (FDKsbrEnc_initInvFiltDetector( - &hTonCorr->sbrInvFilt, - hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf, - hTonCorr->sbrNoiseFloorEstimate.noNoiseBands, useSpeechConfig)) - return (1); - - if (FDKsbrEnc_InitSbrMissingHarmonicsDetector( - &hTonCorr->sbrMissingHarmonicsDetector, fs, frameSize, nSfb[HI], - noQmfChannels, hTonCorr->numberOfEstimates, hTonCorr->move, - hTonCorr->numberOfEstimatesPerFrame, sbrCfg->sbrSyntaxFlags)) - return (1); - - return (0); -} - -/**************************************************************************/ -/*! - \brief resets tonality correction parameter module. - - - - \return errorCode, noError if successful. - -*/ -/**************************************************************************/ -INT FDKsbrEnc_ResetTonCorrParamExtr( - HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */ - INT xposctrl, /*!< Different patch modes. */ - INT highBandStartSb, /*!< Start band of the SBR range. */ - UCHAR *v_k_master, /*!< Master frequency table from which all other table - are derived.*/ - INT numMaster, /*!< Number of elements in the master table. */ - INT fs, /*!< Sampling frequency (of the SBR part). */ - UCHAR * - *freqBandTable, /*!< Frequency band table for low-res and high-res. */ - INT *nSfb, /*!< Number of frequency bands (hig-res and low-res). */ - INT noQmfChannels /*!< Number of QMF channels. */ -) { - /* Reset the patch.*/ - hTonCorr->guard = 0; - hTonCorr->shiftStartSb = 1; - - if (resetPatch(hTonCorr, xposctrl, highBandStartSb, v_k_master, numMaster, fs, - noQmfChannels)) - return (1); - - /* Reset the noise floor estimate.*/ - if (FDKsbrEnc_resetSbrNoiseFloorEstimate(&hTonCorr->sbrNoiseFloorEstimate, - freqBandTable[LO], nSfb[LO])) - return (1); - - /* - Reset the inveerse filtereing detector. - */ - if (FDKsbrEnc_resetInvFiltDetector( - &hTonCorr->sbrInvFilt, - hTonCorr->sbrNoiseFloorEstimate.freqBandTableQmf, - hTonCorr->sbrNoiseFloorEstimate.noNoiseBands)) - return (1); - /* Reset the missing harmonics detector. */ - if (FDKsbrEnc_ResetSbrMissingHarmonicsDetector( - &hTonCorr->sbrMissingHarmonicsDetector, nSfb[HI])) - return (1); - - return (0); -} - -/**************************************************************************/ -/*! - \brief Deletes the tonality correction paramtere module. - - - - \return none - -*/ -/**************************************************************************/ -void FDKsbrEnc_DeleteTonCorrParamExtr( - HANDLE_SBR_TON_CORR_EST hTonCorr) /*!< Handle to SBR_TON_CORR struct. */ -{ - if (hTonCorr) { - FreeRam_Sbr_quotaMatrix(hTonCorr->quotaMatrix); - - FreeRam_Sbr_signMatrix(hTonCorr->signMatrix); - - FDKsbrEnc_DeleteSbrMissingHarmonicsDetector( - &hTonCorr->sbrMissingHarmonicsDetector); - } -} --- a/libSBRenc/src/ton_corr.h +++ /dev/null @@ -1,258 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief General tonality correction detector module. -*/ -#ifndef TON_CORR_H -#define TON_CORR_H - -#include "sbr_encoder.h" -#include "mh_det.h" -#include "nf_est.h" -#include "invf_est.h" - -#define MAX_NUM_PATCHES 6 -#define SCALE_NRGVEC 4 - -/** parameter set for one single patch */ -typedef struct { - INT sourceStartBand; /*!< first band in lowbands where to take the samples - from */ - INT sourceStopBand; /*!< first band in lowbands which is not included in the - patch anymore */ - INT guardStartBand; /*!< first band in highbands to be filled with zeros in - order to reduce interferences between patches */ - INT targetStartBand; /*!< first band in highbands to be filled with whitened - lowband signal */ - INT targetBandOffs; /*!< difference between 'startTargetBand' and - 'startSourceBand' */ - INT numBandsInPatch; /*!< number of consecutive bands in this one patch */ -} PATCH_PARAM; - -typedef struct { - INT switchInverseFilt; /*!< Flag to enable dynamic adaption of invf. detection - */ - INT noQmfChannels; - INT bufferLength; /*!< Length of the r and i buffers. */ - INT stepSize; /*!< Stride for the lpc estimate. */ - INT numberOfEstimates; /*!< The total number of estiamtes, available in the - quotaMatrix.*/ - UINT numberOfEstimatesPerFrame; /*!< The number of estimates per frame - available in the quotaMatrix.*/ - INT lpcLength[2]; /*!< Segment length used for second order LPC analysis.*/ - INT nextSample; /*!< Where to start the LPC analysis of the current frame.*/ - INT move; /*!< How many estimates to move in the quotaMatrix, when buffering. - */ - INT frameStartIndex; /*!< The start index for the current frame in the r and i - buffers. */ - INT startIndexMatrix; /*!< The start index for the current frame in the - quotaMatrix. */ - INT frameStartIndexInvfEst; /*!< The start index of the inverse filtering, not - the same as the others, dependent on what - decoder is used (buffer opt, or no buffer opt). - */ - INT prevTransientFlag; /*!< The transisent flag (from the transient detector) - for the previous frame. */ - INT transientNextFrame; /*!< Flag to indicate that the transient will show up - in the next frame. */ - INT transientPosOffset; /*!< An offset value to match the transient pos as - calculated by the transient detector with the - actual position in the frame.*/ - - INT* signMatrix[MAX_NO_OF_ESTIMATES]; /*!< Matrix holding the sign of each - channe, i.e. indicating in what part - of a QMF channel a possible sine is. - */ - - FIXP_DBL* quotaMatrix[MAX_NO_OF_ESTIMATES]; /*!< Matrix holding the quota - values for all estimates, all - channels. */ - - FIXP_DBL nrgVector[MAX_NO_OF_ESTIMATES]; /*!< Vector holding the averaged - energies for every QMF band. */ - FIXP_DBL nrgVectorFreq[64]; /*!< Vector holding the averaged energies for - every QMF channel */ - - SCHAR indexVector[64]; /*!< Index vector poINTing to the correct lowband - channel, when indexing a highband channel, -1 - represents a guard band */ - PATCH_PARAM - patchParam[MAX_NUM_PATCHES]; /*!< new parameter set for patching */ - INT guard; /*!< number of guardbands between every patch */ - INT shiftStartSb; /*!< lowest subband of source range to be included in the - patches */ - INT noOfPatches; /*!< number of patches */ - - SBR_MISSING_HARMONICS_DETECTOR - sbrMissingHarmonicsDetector; /*!< SBR_MISSING_HARMONICS_DETECTOR struct. - */ - SBR_NOISE_FLOOR_ESTIMATE - sbrNoiseFloorEstimate; /*!< SBR_NOISE_FLOOR_ESTIMATE struct. */ - SBR_INV_FILT_EST sbrInvFilt; /*!< SBR_INV_FILT_EST struct. */ -} SBR_TON_CORR_EST; - -typedef SBR_TON_CORR_EST* HANDLE_SBR_TON_CORR_EST; - -void FDKsbrEnc_TonCorrParamExtr( - HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */ - INVF_MODE* infVec, /*!< Vector where the inverse filtering levels will be - stored. */ - FIXP_DBL* noiseLevels, /*!< Vector where the noise levels will be stored. */ - INT* missingHarmonicFlag, /*!< Flag set to one or zero, dependent on if any - strong sines are missing.*/ - UCHAR* missingHarmonicsIndex, /*!< Vector indicating where sines are - missing. */ - UCHAR* envelopeCompensation, /*!< Vector to store compensation values for - the energies in. */ - const SBR_FRAME_INFO* frameInfo, /*!< Frame info struct, contains the time - and frequency grid of the current - frame.*/ - UCHAR* transientInfo, /*!< Transient info.*/ - UCHAR* freqBandTable, /*!< Frequency band tables for high-res.*/ - INT nSfb, /*!< Number of scalefactor bands for high-res. */ - XPOS_MODE xposType, /*!< Type of transposer used in the decoder.*/ - UINT sbrSyntaxFlags); - -INT FDKsbrEnc_CreateTonCorrParamExtr( - HANDLE_SBR_TON_CORR_EST - hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */ - INT chan); /*!< Channel index, needed for mem allocation */ - -INT FDKsbrEnc_InitTonCorrParamExtr( - INT frameSize, /*!< Current SBR frame size. */ - HANDLE_SBR_TON_CORR_EST - hTonCorr, /*!< Pointer to handle to SBR_TON_CORR struct. */ - HANDLE_SBR_CONFIG_DATA - sbrCfg, /*!< Pointer to SBR configuration parameters. */ - INT timeSlots, /*!< Number of time-slots per frame */ - INT xposCtrl, /*!< Different patch modes. */ - INT ana_max_level, /*!< Maximum level of the adaptive noise. */ - INT noiseBands, /*!< Number of noise bands per octave. */ - INT noiseFloorOffset, /*!< Noise floor offset. */ - UINT useSpeechConfig /*!< Speech or music tuning. */ -); - -void FDKsbrEnc_DeleteTonCorrParamExtr( - HANDLE_SBR_TON_CORR_EST hTonCorr); /*!< Handle to SBR_TON_CORR struct. */ - -void FDKsbrEnc_CalculateTonalityQuotas( - HANDLE_SBR_TON_CORR_EST hTonCorr, FIXP_DBL** sourceBufferReal, - FIXP_DBL** sourceBufferImag, INT usb, - INT qmfScale /*!< sclefactor of QMF subsamples */ -); - -INT FDKsbrEnc_ResetTonCorrParamExtr( - HANDLE_SBR_TON_CORR_EST hTonCorr, /*!< Handle to SBR_TON_CORR struct. */ - INT xposctrl, /*!< Different patch modes. */ - INT highBandStartSb, /*!< Start band of the SBR range. */ - UCHAR* v_k_master, /*!< Master frequency table from which all other table - are derived.*/ - INT numMaster, /*!< Number of elements in the master table. */ - INT fs, /*!< Sampling frequency (of the SBR part). */ - UCHAR** - freqBandTable, /*!< Frequency band table for low-res and high-res. */ - INT* nSfb, /*!< Number of frequency bands (hig-res and low-res). */ - INT noQmfChannels /*!< Number of QMF channels. */ -); -#endif --- a/libSBRenc/src/tran_det.cpp +++ /dev/null @@ -1,1092 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): Tobias Chalupka - - Description: SBR encoder transient detector - -*******************************************************************************/ - -#include "tran_det.h" - -#include "fram_gen.h" -#include "sbrenc_ram.h" -#include "sbr_misc.h" - -#include "genericStds.h" - -#define NORM_QMF_ENERGY 9.31322574615479E-10 /* 2^-30 */ - -/* static FIXP_DBL ABS_THRES = fixMax( FL2FXCONST_DBL(1.28e5 * - * NORM_QMF_ENERGY), (FIXP_DBL)1) Minimum threshold for detecting changes */ -#define ABS_THRES ((FIXP_DBL)16) - -/******************************************************************************* - Functionname: spectralChange - ******************************************************************************* - \brief Calculates a measure for the spectral change within the frame - - The function says how good it would be to split the frame at the given border - position into 2 envelopes. - - The return value delta_sum is scaled with the factor 1/64 - - \return calculated value -*******************************************************************************/ -#define NRG_SHIFT 3 /* for energy summation */ - -static FIXP_DBL spectralChange( - FIXP_DBL Energies[NUMBER_TIME_SLOTS_2304][MAX_FREQ_COEFFS], - INT *scaleEnergies, FIXP_DBL EnergyTotal, INT nSfb, INT start, INT border, - INT YBufferWriteOffset, INT stop, INT *result_e) { - INT i, j; - INT len1, len2; - SCHAR energies_e_diff[NUMBER_TIME_SLOTS_2304], energies_e, energyTotal_e = 19, - energies_e_add; - SCHAR prevEnergies_e_diff, newEnergies_e_diff; - FIXP_DBL tmp0, tmp1; - FIXP_DBL delta, delta_sum; - INT accu_e, tmp_e; - - delta_sum = FL2FXCONST_DBL(0.0f); - *result_e = 0; - - len1 = border - start; - len2 = stop - border; - - /* prefer borders near the middle of the frame */ - FIXP_DBL pos_weight; - pos_weight = FL2FXCONST_DBL(0.5f) - (len1 * GetInvInt(len1 + len2)); - pos_weight = /*FL2FXCONST_DBL(1.0)*/ (FIXP_DBL)MAXVAL_DBL - - (fMult(pos_weight, pos_weight) << 2); - - /*** Calc scaling for energies ***/ - FDK_ASSERT(scaleEnergies[0] >= 0); - FDK_ASSERT(scaleEnergies[1] >= 0); - - energies_e = 19 - fMin(scaleEnergies[0], scaleEnergies[1]); - - /* limit shift for energy accumulation, energies_e can be -10 min. */ - if (energies_e < -10) { - energies_e_add = -10 - energies_e; - energies_e = -10; - } else if (energies_e > 17) { - energies_e_add = energies_e - 17; - energies_e = 17; - } else { - energies_e_add = 0; - } - - /* compensate scaling differences between scaleEnergies[0] and - * scaleEnergies[1] */ - prevEnergies_e_diff = scaleEnergies[0] - - fMin(scaleEnergies[0], scaleEnergies[1]) + - energies_e_add + NRG_SHIFT; - newEnergies_e_diff = scaleEnergies[1] - - fMin(scaleEnergies[0], scaleEnergies[1]) + - energies_e_add + NRG_SHIFT; - - prevEnergies_e_diff = fMin(prevEnergies_e_diff, DFRACT_BITS - 1); - newEnergies_e_diff = fMin(newEnergies_e_diff, DFRACT_BITS - 1); - - for (i = start; i < YBufferWriteOffset; i++) { - energies_e_diff[i] = prevEnergies_e_diff; - } - for (i = YBufferWriteOffset; i < stop; i++) { - energies_e_diff[i] = newEnergies_e_diff; - } - - /* Sum up energies of all QMF-timeslots for both halfs */ - FDK_ASSERT(len1 <= 8); /* otherwise an overflow is possible */ - FDK_ASSERT(len2 <= 8); /* otherwise an overflow is possible */ - - for (j = 0; j < nSfb; j++) { - FIXP_DBL accu1 = FL2FXCONST_DBL(0.f); - FIXP_DBL accu2 = FL2FXCONST_DBL(0.f); - accu_e = energies_e + 3; - - /* Sum up energies in first half */ - for (i = start; i < border; i++) { - accu1 += scaleValue(Energies[i][j], -energies_e_diff[i]); - } - - /* Sum up energies in second half */ - for (i = border; i < stop; i++) { - accu2 += scaleValue(Energies[i][j], -energies_e_diff[i]); - } - - /* Ensure certain energy to prevent division by zero and to prevent - * splitting for very low levels */ - accu1 = fMax(accu1, (FIXP_DBL)len1); - accu2 = fMax(accu2, (FIXP_DBL)len2); - -/* Energy change in current band */ -#define LN2 FL2FXCONST_DBL(0.6931471806f) /* ln(2) */ - tmp0 = fLog2(accu2, accu_e) - fLog2(accu1, accu_e); - tmp1 = fLog2((FIXP_DBL)len1, 31) - fLog2((FIXP_DBL)len2, 31); - delta = fMult(LN2, (tmp0 + tmp1)); - delta = (FIXP_DBL)fAbs(delta); - - /* Weighting with amplitude ratio of this band */ - accu_e++; /* scale at least one bit due to (accu1+accu2) */ - accu1 >>= 1; - accu2 >>= 1; - - if (accu_e & 1) { - accu_e++; /* for a defined square result exponent, the exponent has to be - even */ - accu1 >>= 1; - accu2 >>= 1; - } - - delta_sum += fMult(sqrtFixp(accu1 + accu2), delta); - *result_e = ((accu_e >> 1) + LD_DATA_SHIFT); - } - - if (energyTotal_e & 1) { - energyTotal_e += 1; /* for a defined square result exponent, the exponent - has to be even */ - EnergyTotal >>= 1; - } - - delta_sum = fMult(delta_sum, invSqrtNorm2(EnergyTotal, &tmp_e)); - *result_e = *result_e + (tmp_e - (energyTotal_e >> 1)); - - return fMult(delta_sum, pos_weight); -} - -/******************************************************************************* - Functionname: addLowbandEnergies - ******************************************************************************* - \brief Calculates total lowband energy - - The input values Energies[0] (low-band) are scaled by the factor - 2^(14-*scaleEnergies[0]) - The input values Energies[1] (high-band) are scaled by the factor - 2^(14-*scaleEnergies[1]) - - \return total energy in the lowband, scaled by the factor 2^19 -*******************************************************************************/ -static FIXP_DBL addLowbandEnergies(FIXP_DBL **Energies, int *scaleEnergies, - int YBufferWriteOffset, int nrgSzShift, - int tran_off, UCHAR *freqBandTable, - int slots) { - INT nrgTotal_e; - FIXP_DBL nrgTotal_m; - FIXP_DBL accu1 = FL2FXCONST_DBL(0.0f); - FIXP_DBL accu2 = FL2FXCONST_DBL(0.0f); - int tran_offdiv2 = tran_off >> nrgSzShift; - const int sc1 = - DFRACT_BITS - - fNormz((FIXP_DBL)fMax( - 1, (freqBandTable[0] * (YBufferWriteOffset - tran_offdiv2) - 1))); - const int sc2 = - DFRACT_BITS - - fNormz((FIXP_DBL)fMax( - 1, (freqBandTable[0] * - (tran_offdiv2 + (slots >> nrgSzShift) - YBufferWriteOffset) - - 1))); - int ts, k; - - /* Sum up lowband energy from one frame at offset tran_off */ - /* freqBandTable[LORES] has MAX_FREQ_COEFFS/2 +1 coeefs max. */ - for (ts = tran_offdiv2; ts < YBufferWriteOffset; ts++) { - for (k = 0; k < freqBandTable[0]; k++) { - accu1 += Energies[ts][k] >> sc1; - } - } - for (; ts < tran_offdiv2 + (slots >> nrgSzShift); ts++) { - for (k = 0; k < freqBandTable[0]; k++) { - accu2 += Energies[ts][k] >> sc2; - } - } - - nrgTotal_m = fAddNorm(accu1, (sc1 - 5) - scaleEnergies[0], accu2, - (sc2 - 5) - scaleEnergies[1], &nrgTotal_e); - nrgTotal_m = scaleValueSaturate(nrgTotal_m, nrgTotal_e); - - return (nrgTotal_m); -} - -/******************************************************************************* - Functionname: addHighbandEnergies - ******************************************************************************* - \brief Add highband energies - - Highband energies are mapped to an array with smaller dimension: - Its time resolution is only 1 SBR-timeslot and its frequency resolution - is 1 SBR-band. Therefore the data to be fed into the spectralChange - function is reduced. - - The values EnergiesM are scaled by the factor (2^19-scaleEnergies[0]) for - slots=YBufferWriteOffset. - - \return total energy in the highband, scaled by factor 2^19 -*******************************************************************************/ - -static FIXP_DBL addHighbandEnergies( - FIXP_DBL **RESTRICT Energies, /*!< input */ - INT *scaleEnergies, INT YBufferWriteOffset, - FIXP_DBL EnergiesM[NUMBER_TIME_SLOTS_2304] - [MAX_FREQ_COEFFS], /*!< Combined output */ - UCHAR *RESTRICT freqBandTable, INT nSfb, INT sbrSlots, INT timeStep) { - INT i, j, k, slotIn, slotOut, scale[2]; - INT li, ui; - FIXP_DBL nrgTotal; - FIXP_DBL accu = FL2FXCONST_DBL(0.0f); - - /* Combine QMF-timeslots to SBR-timeslots, - combine QMF-bands to SBR-bands, - combine Left and Right channel */ - for (slotOut = 0; slotOut < sbrSlots; slotOut++) { - /* Note: Below slotIn = slotOut and not slotIn = timeStep*slotOut - because the Energies[] time resolution is always the SBR slot resolution - regardless of the timeStep. */ - slotIn = slotOut; - - for (j = 0; j < nSfb; j++) { - accu = FL2FXCONST_DBL(0.0f); - - li = freqBandTable[j]; - ui = freqBandTable[j + 1]; - - for (k = li; k < ui; k++) { - for (i = 0; i < timeStep; i++) { - accu += Energies[slotIn][k] >> 5; - } - } - EnergiesM[slotOut][j] = accu; - } - } - - /* scale energies down before add up */ - scale[0] = fixMin(8, scaleEnergies[0]); - scale[1] = fixMin(8, scaleEnergies[1]); - - if ((scaleEnergies[0] - scale[0]) > (DFRACT_BITS - 1) || - (scaleEnergies[1] - scale[1]) > (DFRACT_BITS - 1)) - nrgTotal = FL2FXCONST_DBL(0.0f); - else { - /* Now add all energies */ - accu = FL2FXCONST_DBL(0.0f); - - for (slotOut = 0; slotOut < YBufferWriteOffset; slotOut++) { - for (j = 0; j < nSfb; j++) { - accu += (EnergiesM[slotOut][j] >> scale[0]); - } - } - nrgTotal = accu >> (scaleEnergies[0] - scale[0]); - - for (slotOut = YBufferWriteOffset; slotOut < sbrSlots; slotOut++) { - for (j = 0; j < nSfb; j++) { - accu += (EnergiesM[slotOut][j] >> scale[0]); - } - } - nrgTotal = fAddSaturate(nrgTotal, accu >> (scaleEnergies[1] - scale[1])); - } - - return (nrgTotal); -} - -/******************************************************************************* - Functionname: FDKsbrEnc_frameSplitter - ******************************************************************************* - \brief Decides if a FIXFIX-frame shall be splitted into 2 envelopes - - If no transient has been detected before, the frame can still be splitted - into 2 envelopes. -*******************************************************************************/ -void FDKsbrEnc_frameSplitter( - FIXP_DBL **Energies, INT *scaleEnergies, - HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector, UCHAR *freqBandTable, - UCHAR *tran_vector, int YBufferWriteOffset, int YBufferSzShift, int nSfb, - int timeStep, int no_cols, FIXP_DBL *tonality) { - if (tran_vector[1] == 0) /* no transient was detected */ - { - FIXP_DBL delta; - INT delta_e; - FIXP_DBL(*EnergiesM)[MAX_FREQ_COEFFS]; - FIXP_DBL EnergyTotal, newLowbandEnergy, newHighbandEnergy; - INT border; - INT sbrSlots = fMultI(GetInvInt(timeStep), no_cols); - C_ALLOC_SCRATCH_START(_EnergiesM, FIXP_DBL, - NUMBER_TIME_SLOTS_2304 * MAX_FREQ_COEFFS) - - FDK_ASSERT(sbrSlots * timeStep == no_cols); - - EnergiesM = (FIXP_DBL(*)[MAX_FREQ_COEFFS])_EnergiesM; - - /* - Get Lowband-energy over a range of 2 frames (Look half a frame back and - ahead). - */ - newLowbandEnergy = addLowbandEnergies( - Energies, scaleEnergies, YBufferWriteOffset, YBufferSzShift, - h_sbrTransientDetector->tran_off, freqBandTable, no_cols); - - newHighbandEnergy = - addHighbandEnergies(Energies, scaleEnergies, YBufferWriteOffset, - EnergiesM, freqBandTable, nSfb, sbrSlots, timeStep); - - { - /* prevLowBandEnergy: Corresponds to 1 frame, starting with half a frame - look-behind newLowbandEnergy: Corresponds to 1 frame, starting in the - middle of the current frame */ - EnergyTotal = (newLowbandEnergy >> 1) + - (h_sbrTransientDetector->prevLowBandEnergy >> - 1); /* mean of new and prev LB NRG */ - EnergyTotal = - fAddSaturate(EnergyTotal, newHighbandEnergy); /* Add HB NRG */ - /* The below border should specify the same position as the middle border - of a FIXFIX-frame with 2 envelopes. */ - border = (sbrSlots + 1) >> 1; - - if ((INT)EnergyTotal & 0xffffffe0 && - (scaleEnergies[0] < 32 || scaleEnergies[1] < 32)) /* i.e. > 31 */ { - delta = spectralChange(EnergiesM, scaleEnergies, EnergyTotal, nSfb, 0, - border, YBufferWriteOffset, sbrSlots, &delta_e); - } else { - delta = FL2FXCONST_DBL(0.0f); - delta_e = 0; - - /* set tonality to 0 when energy is very low, since the amplitude - resolution should then be low as well */ - *tonality = FL2FXCONST_DBL(0.0f); - } - - if (fIsLessThan(h_sbrTransientDetector->split_thr_m, - h_sbrTransientDetector->split_thr_e, delta, delta_e)) { - tran_vector[0] = 1; /* Set flag for splitting */ - } else { - tran_vector[0] = 0; - } - } - - /* Update prevLowBandEnergy */ - h_sbrTransientDetector->prevLowBandEnergy = newLowbandEnergy; - h_sbrTransientDetector->prevHighBandEnergy = newHighbandEnergy; - C_ALLOC_SCRATCH_END(_EnergiesM, FIXP_DBL, - NUMBER_TIME_SLOTS_2304 * MAX_FREQ_COEFFS) - } -} - -/* - * Calculate transient energy threshold for each QMF band - */ -static void calculateThresholds(FIXP_DBL **RESTRICT Energies, - INT *RESTRICT scaleEnergies, - FIXP_DBL *RESTRICT thresholds, - int YBufferWriteOffset, int YBufferSzShift, - int noCols, int noRows, int tran_off) { - FIXP_DBL mean_val, std_val, temp; - FIXP_DBL i_noCols; - FIXP_DBL i_noCols1; - FIXP_DBL accu, accu0, accu1; - int scaleFactor0, scaleFactor1, commonScale; - int i, j; - - i_noCols = GetInvInt(noCols + tran_off) << YBufferSzShift; - i_noCols1 = GetInvInt(noCols + tran_off - 1) << YBufferSzShift; - - /* calc minimum scale of energies of previous and current frame */ - commonScale = fixMin(scaleEnergies[0], scaleEnergies[1]); - - /* calc scalefactors to adapt energies to common scale */ - scaleFactor0 = fixMin((scaleEnergies[0] - commonScale), (DFRACT_BITS - 1)); - scaleFactor1 = fixMin((scaleEnergies[1] - commonScale), (DFRACT_BITS - 1)); - - FDK_ASSERT((scaleFactor0 >= 0) && (scaleFactor1 >= 0)); - - /* calculate standard deviation in every subband */ - for (i = 0; i < noRows; i++) { - int startEnergy = (tran_off >> YBufferSzShift); - int endEnergy = ((noCols >> YBufferSzShift) + tran_off); - int shift; - - /* calculate mean value over decimated energy values (downsampled by 2). */ - accu0 = accu1 = FL2FXCONST_DBL(0.0f); - - for (j = startEnergy; j < YBufferWriteOffset; j++) - accu0 = fMultAddDiv2(accu0, Energies[j][i], i_noCols); - for (; j < endEnergy; j++) - accu1 = fMultAddDiv2(accu1, Energies[j][i], i_noCols); - - mean_val = ((accu0 << 1) >> scaleFactor0) + - ((accu1 << 1) >> scaleFactor1); /* average */ - shift = fixMax( - 0, CountLeadingBits(mean_val) - - 6); /* -6 to keep room for accumulating upto N = 24 values */ - - /* calculate standard deviation */ - accu = FL2FXCONST_DBL(0.0f); - - /* summe { ((mean_val-nrg)^2) * i_noCols1 } */ - for (j = startEnergy; j < YBufferWriteOffset; j++) { - temp = ((FIXP_DBL)mean_val - ((FIXP_DBL)Energies[j][i] >> scaleFactor0)) - << shift; - temp = fPow2Div2(temp); - accu = fMultAddDiv2(accu, temp, i_noCols1); - } - for (; j < endEnergy; j++) { - temp = ((FIXP_DBL)mean_val - ((FIXP_DBL)Energies[j][i] >> scaleFactor1)) - << shift; - temp = fPow2Div2(temp); - accu = fMultAddDiv2(accu, temp, i_noCols1); - } - accu <<= 2; - std_val = sqrtFixp(accu) >> shift; /* standard deviation */ - - /* - Take new threshold as average of calculated standard deviation ratio - and old threshold if greater than absolute threshold - */ - temp = (commonScale <= (DFRACT_BITS - 1)) - ? fMult(FL2FXCONST_DBL(0.66f), thresholds[i]) + - (fMult(FL2FXCONST_DBL(0.34f), std_val) >> commonScale) - : (FIXP_DBL)0; - - thresholds[i] = fixMax(ABS_THRES, temp); - - FDK_ASSERT(commonScale >= 0); - } -} - -/* - * Calculate transient levels for each QMF time slot. - */ -static void extractTransientCandidates( - FIXP_DBL **RESTRICT Energies, INT *RESTRICT scaleEnergies, - FIXP_DBL *RESTRICT thresholds, FIXP_DBL *RESTRICT transients, - int YBufferWriteOffset, int YBufferSzShift, int noCols, int start_band, - int stop_band, int tran_off, int addPrevSamples) { - FIXP_DBL i_thres; - C_ALLOC_SCRATCH_START(EnergiesTemp, FIXP_DBL, 2 * 32) - int tmpScaleEnergies0, tmpScaleEnergies1; - int endCond; - int startEnerg, endEnerg; - int i, j, jIndex, jpBM; - - tmpScaleEnergies0 = scaleEnergies[0]; - tmpScaleEnergies1 = scaleEnergies[1]; - - /* Scale value for first energies, upto YBufferWriteOffset */ - tmpScaleEnergies0 = fixMin(tmpScaleEnergies0, MAX_SHIFT_DBL); - /* Scale value for first energies, from YBufferWriteOffset upwards */ - tmpScaleEnergies1 = fixMin(tmpScaleEnergies1, MAX_SHIFT_DBL); - - FDK_ASSERT((tmpScaleEnergies0 >= 0) && (tmpScaleEnergies1 >= 0)); - - /* Keep addPrevSamples extra previous transient candidates. */ - FDKmemmove(transients, transients + noCols - addPrevSamples, - (tran_off + addPrevSamples) * sizeof(FIXP_DBL)); - FDKmemclear(transients + tran_off + addPrevSamples, - noCols * sizeof(FIXP_DBL)); - - endCond = noCols; /* Amount of new transient values to be calculated. */ - startEnerg = (tran_off - 3) >> YBufferSzShift; /* >>YBufferSzShift because of - amount of energy values. -3 - because of neighbors being - watched. */ - endEnerg = - ((noCols + (YBufferWriteOffset << YBufferSzShift)) - 1) >> - YBufferSzShift; /* YBufferSzShift shifts because of half energy values. */ - - /* Compute differential values with two different weightings in every subband - */ - for (i = start_band; i < stop_band; i++) { - FIXP_DBL thres = thresholds[i]; - - if ((LONG)thresholds[i] >= 256) - i_thres = (LONG)((LONG)MAXVAL_DBL / ((((LONG)thresholds[i])) + 1)) - << (32 - 24); - else - i_thres = (LONG)MAXVAL_DBL; - - /* Copy one timeslot and de-scale and de-squish */ - if (YBufferSzShift == 1) { - for (j = startEnerg; j < YBufferWriteOffset; j++) { - FIXP_DBL tmp = Energies[j][i]; - EnergiesTemp[(j << 1) + 1] = EnergiesTemp[j << 1] = - tmp >> tmpScaleEnergies0; - } - for (; j <= endEnerg; j++) { - FIXP_DBL tmp = Energies[j][i]; - EnergiesTemp[(j << 1) + 1] = EnergiesTemp[j << 1] = - tmp >> tmpScaleEnergies1; - } - } else { - for (j = startEnerg; j < YBufferWriteOffset; j++) { - FIXP_DBL tmp = Energies[j][i]; - EnergiesTemp[j] = tmp >> tmpScaleEnergies0; - } - for (; j <= endEnerg; j++) { - FIXP_DBL tmp = Energies[j][i]; - EnergiesTemp[j] = tmp >> tmpScaleEnergies1; - } - } - - /* Detect peaks in energy values. */ - - jIndex = tran_off; - jpBM = jIndex + addPrevSamples; - - for (j = endCond; j--; jIndex++, jpBM++) { - FIXP_DBL delta, tran; - int d; - - delta = (FIXP_DBL)0; - tran = (FIXP_DBL)0; - - for (d = 1; d < 4; d++) { - delta += EnergiesTemp[jIndex + d]; /* R */ - delta -= EnergiesTemp[jIndex - d]; /* L */ - delta -= thres; - - if (delta > (FIXP_DBL)0) { - tran = fMultAddDiv2(tran, i_thres, delta); - } - } - transients[jpBM] += (tran << 1); - } - } - C_ALLOC_SCRATCH_END(EnergiesTemp, FIXP_DBL, 2 * 32) -} - -void FDKsbrEnc_transientDetect(HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTran, - FIXP_DBL **Energies, INT *scaleEnergies, - UCHAR *transient_info, int YBufferWriteOffset, - int YBufferSzShift, int timeStep, - int frameMiddleBorder) { - int no_cols = h_sbrTran->no_cols; - int qmfStartSample; - int addPrevSamples; - int timeStepShift = 0; - int i, cond; - - /* Where to start looking for transients in the transient candidate buffer */ - qmfStartSample = timeStep * frameMiddleBorder; - /* We need to look one value backwards in the transients, so we might need one - * more previous value. */ - addPrevSamples = (qmfStartSample > 0) ? 0 : 1; - - switch (timeStep) { - case 1: - timeStepShift = 0; - break; - case 2: - timeStepShift = 1; - break; - case 4: - timeStepShift = 2; - break; - } - - calculateThresholds(Energies, scaleEnergies, h_sbrTran->thresholds, - YBufferWriteOffset, YBufferSzShift, h_sbrTran->no_cols, - h_sbrTran->no_rows, h_sbrTran->tran_off); - - extractTransientCandidates( - Energies, scaleEnergies, h_sbrTran->thresholds, h_sbrTran->transients, - YBufferWriteOffset, YBufferSzShift, h_sbrTran->no_cols, 0, - h_sbrTran->no_rows, h_sbrTran->tran_off, addPrevSamples); - - transient_info[0] = 0; - transient_info[1] = 0; - transient_info[2] = 0; - - /* Offset by the amount of additional previous transient candidates being - * kept. */ - qmfStartSample += addPrevSamples; - - /* Check for transients in second granule (pick the last value of subsequent - * values) */ - for (i = qmfStartSample; i < qmfStartSample + no_cols; i++) { - cond = (h_sbrTran->transients[i] < - fMult(FL2FXCONST_DBL(0.9f), h_sbrTran->transients[i - 1])) && - (h_sbrTran->transients[i - 1] > h_sbrTran->tran_thr); - - if (cond) { - transient_info[0] = (i - qmfStartSample) >> timeStepShift; - transient_info[1] = 1; - break; - } - } - - if (h_sbrTran->frameShift != 0) { - /* transient prediction for LDSBR */ - /* Check for transients in first qmf-slots of second frame */ - for (i = qmfStartSample + no_cols; - i < qmfStartSample + no_cols + h_sbrTran->frameShift; i++) { - cond = (h_sbrTran->transients[i] < - fMult(FL2FXCONST_DBL(0.9f), h_sbrTran->transients[i - 1])) && - (h_sbrTran->transients[i - 1] > h_sbrTran->tran_thr); - - if (cond) { - int pos = (int)((i - qmfStartSample - no_cols) >> timeStepShift); - if ((pos < 3) && (transient_info[1] == 0)) { - transient_info[2] = 1; - } - break; - } - } - } -} - -int FDKsbrEnc_InitSbrTransientDetector( - HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector, - UINT sbrSyntaxFlags, /* SBR syntax flags derived from AOT. */ - INT frameSize, INT sampleFreq, sbrConfigurationPtr params, int tran_fc, - int no_cols, int no_rows, int YBufferWriteOffset, int YBufferSzShift, - int frameShift, int tran_off) { - INT totalBitrate = - params->codecSettings.standardBitrate * params->codecSettings.nChannels; - INT codecBitrate = params->codecSettings.bitRate; - FIXP_DBL bitrateFactor_m, framedur_fix; - INT bitrateFactor_e, tmp_e; - - FDKmemclear(h_sbrTransientDetector, sizeof(SBR_TRANSIENT_DETECTOR)); - - h_sbrTransientDetector->frameShift = frameShift; - h_sbrTransientDetector->tran_off = tran_off; - - if (codecBitrate) { - bitrateFactor_m = fDivNorm((FIXP_DBL)totalBitrate, - (FIXP_DBL)(codecBitrate << 2), &bitrateFactor_e); - bitrateFactor_e += 2; - } else { - bitrateFactor_m = FL2FXCONST_DBL(1.0 / 4.0); - bitrateFactor_e = 2; - } - - framedur_fix = fDivNorm(frameSize, sampleFreq); - - /* The longer the frames, the more often should the FIXFIX- - case transmit 2 envelopes instead of 1. - Frame durations below 10 ms produce the highest threshold - so that practically always only 1 env is transmitted. */ - FIXP_DBL tmp = framedur_fix - FL2FXCONST_DBL(0.010); - - tmp = fixMax(tmp, FL2FXCONST_DBL(0.0001)); - tmp = fDivNorm(FL2FXCONST_DBL(0.000075), fPow2(tmp), &tmp_e); - - bitrateFactor_e = (tmp_e + bitrateFactor_e); - - if (sbrSyntaxFlags & SBR_SYNTAX_LOW_DELAY) { - bitrateFactor_e--; /* divide by 2 */ - } - - FDK_ASSERT(no_cols <= 32); - FDK_ASSERT(no_rows <= 64); - - h_sbrTransientDetector->no_cols = no_cols; - h_sbrTransientDetector->tran_thr = - (FIXP_DBL)((params->tran_thr << (32 - 24 - 1)) / no_rows); - h_sbrTransientDetector->tran_fc = tran_fc; - h_sbrTransientDetector->split_thr_m = fMult(tmp, bitrateFactor_m); - h_sbrTransientDetector->split_thr_e = bitrateFactor_e; - h_sbrTransientDetector->no_rows = no_rows; - h_sbrTransientDetector->mode = params->tran_det_mode; - h_sbrTransientDetector->prevLowBandEnergy = FL2FXCONST_DBL(0.0f); - - return (0); -} - -#define ENERGY_SCALING_SIZE 32 - -INT FDKsbrEnc_InitSbrFastTransientDetector( - HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector, - const INT time_slots_per_frame, const INT bandwidth_qmf_slot, - const INT no_qmf_channels, const INT sbr_qmf_1st_band) { - int i; - int buff_size; - FIXP_DBL myExp; - FIXP_DBL myExpSlot; - - h_sbrFastTransientDetector->lookahead = TRAN_DET_LOOKAHEAD; - h_sbrFastTransientDetector->nTimeSlots = time_slots_per_frame; - - buff_size = h_sbrFastTransientDetector->nTimeSlots + - h_sbrFastTransientDetector->lookahead; - - for (i = 0; i < buff_size; i++) { - h_sbrFastTransientDetector->delta_energy[i] = FL2FXCONST_DBL(0.0f); - h_sbrFastTransientDetector->energy_timeSlots[i] = FL2FXCONST_DBL(0.0f); - h_sbrFastTransientDetector->lowpass_energy[i] = FL2FXCONST_DBL(0.0f); - h_sbrFastTransientDetector->transientCandidates[i] = 0; - } - - FDK_ASSERT(bandwidth_qmf_slot > 0.f); - h_sbrFastTransientDetector->stopBand = - fMin(TRAN_DET_STOP_FREQ / bandwidth_qmf_slot, no_qmf_channels); - h_sbrFastTransientDetector->startBand = - fMin(sbr_qmf_1st_band, - h_sbrFastTransientDetector->stopBand - TRAN_DET_MIN_QMFBANDS); - - FDK_ASSERT(h_sbrFastTransientDetector->startBand < no_qmf_channels); - FDK_ASSERT(h_sbrFastTransientDetector->startBand < - h_sbrFastTransientDetector->stopBand); - FDK_ASSERT(h_sbrFastTransientDetector->startBand > 1); - FDK_ASSERT(h_sbrFastTransientDetector->stopBand > 1); - - /* the energy weighting and adding up has a headroom of 6 Bits, - so up to 64 bands can be added without potential overflow. */ - FDK_ASSERT(h_sbrFastTransientDetector->stopBand - - h_sbrFastTransientDetector->startBand <= - 64); - -/* QMF_HP_dB_SLOPE_FIX says that we want a 20 dB per 16 kHz HP filter. - The following lines map this to the QMF bandwidth. */ -#define EXP_E 7 /* 64 (=64) multiplications max, max. allowed sum is 0.5 */ - myExp = fMultNorm(QMF_HP_dBd_SLOPE_FIX, 0, (FIXP_DBL)bandwidth_qmf_slot, - DFRACT_BITS - 1, EXP_E); - myExpSlot = myExp; - - for (i = 0; i < 64; i++) { - /* Calculate dBf over all qmf bands: - dBf = (10^(0.002266f/10*bw(slot)))^(band) = - = 2^(log2(10)*0.002266f/10*bw(slot)*band) = - = 2^(0.00075275f*bw(slot)*band) */ - - FIXP_DBL dBf_m; /* dBf mantissa */ - INT dBf_e; /* dBf exponent */ - INT tmp; - - INT dBf_int; /* dBf integer part */ - FIXP_DBL dBf_fract; /* dBf fractional part */ - - /* myExp*(i+1) = myExp_int - myExp_fract - myExp*(i+1) is split up here for better accuracy of CalcInvLdData(), - for its result can be split up into an integer and a fractional part */ - - /* Round up to next integer */ - FIXP_DBL myExp_int = - (myExpSlot & (FIXP_DBL)0xfe000000) + (FIXP_DBL)0x02000000; - - /* This is the fractional part that needs to be substracted */ - FIXP_DBL myExp_fract = myExp_int - myExpSlot; - - /* Calc integer part */ - dBf_int = CalcInvLdData(myExp_int); - /* The result needs to be re-scaled. The ld(myExp_int) had been scaled by - EXP_E, the CalcInvLdData expects the operand to be scaled by - LD_DATA_SHIFT. Therefore, the correctly scaled result is - dBf_int^(2^(EXP_E-LD_DATA_SHIFT)), which is dBf_int^2 */ - - if (dBf_int <= - 46340) { /* compare with maximum allowed value for signed integer - multiplication, 46340 = - (INT)floor(sqrt((double)(((UINT)1<<(DFRACT_BITS-1))-1))) */ - dBf_int *= dBf_int; - - /* Calc fractional part */ - dBf_fract = CalcInvLdData(-myExp_fract); - /* The result needs to be re-scaled. The ld(myExp_fract) had been scaled - by EXP_E, the CalcInvLdData expects the operand to be scaled by - LD_DATA_SHIFT. Therefore, the correctly scaled result is - dBf_fract^(2^(EXP_E-LD_DATA_SHIFT)), which is dBf_fract^2 */ - dBf_fract = fMultNorm(dBf_fract, dBf_fract, &tmp); - - /* Get worst case scaling of multiplication result */ - dBf_e = (DFRACT_BITS - 1 - tmp) - CountLeadingBits(dBf_int); - - /* Now multiply integer with fractional part of the result, thus resulting - in the overall accurate fractional result */ - dBf_m = fMultNorm(dBf_int, DFRACT_BITS - 1, dBf_fract, tmp, dBf_e); - - myExpSlot += myExp; - } else { - dBf_m = (FIXP_DBL)0; - dBf_e = 0; - } - - /* Keep the results */ - h_sbrFastTransientDetector->dBf_m[i] = dBf_m; - h_sbrFastTransientDetector->dBf_e[i] = dBf_e; - } - - /* Make sure that dBf is greater than 1.0 (because it should be a highpass) */ - /* ... */ - - return 0; -} - -void FDKsbrEnc_fastTransientDetect( - const HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector, - const FIXP_DBL *const *Energies, const int *const scaleEnergies, - const INT YBufferWriteOffset, UCHAR *const tran_vector) { - int timeSlot, band; - - FIXP_DBL max_delta_energy; /* helper to store maximum energy ratio */ - int max_delta_energy_scale; /* helper to store scale of maximum energy ratio - */ - int ind_max = 0; /* helper to store index of maximum energy ratio */ - int isTransientInFrame = 0; - - const int nTimeSlots = h_sbrFastTransientDetector->nTimeSlots; - const int lookahead = h_sbrFastTransientDetector->lookahead; - const int startBand = h_sbrFastTransientDetector->startBand; - const int stopBand = h_sbrFastTransientDetector->stopBand; - - int *transientCandidates = h_sbrFastTransientDetector->transientCandidates; - - FIXP_DBL *energy_timeSlots = h_sbrFastTransientDetector->energy_timeSlots; - int *energy_timeSlots_scale = - h_sbrFastTransientDetector->energy_timeSlots_scale; - - FIXP_DBL *delta_energy = h_sbrFastTransientDetector->delta_energy; - int *delta_energy_scale = h_sbrFastTransientDetector->delta_energy_scale; - - const FIXP_DBL thr = TRAN_DET_THRSHLD; - const INT thr_scale = TRAN_DET_THRSHLD_SCALE; - - /*reset transient info*/ - tran_vector[2] = 0; - - /* reset transient candidates */ - FDKmemclear(transientCandidates + lookahead, nTimeSlots * sizeof(int)); - - for (timeSlot = lookahead; timeSlot < nTimeSlots + lookahead; timeSlot++) { - int i, norm; - FIXP_DBL tmpE = FL2FXCONST_DBL(0.0f); - int headroomEnSlot = DFRACT_BITS - 1; - - FIXP_DBL smallNRG = FL2FXCONST_DBL(1e-2f); - FIXP_DBL denominator; - INT denominator_scale; - - /* determine minimum headroom of energy values for this timeslot */ - for (band = startBand; band < stopBand; band++) { - int tmp_headroom = fNormz(Energies[timeSlot][band]) - 1; - if (tmp_headroom < headroomEnSlot) { - headroomEnSlot = tmp_headroom; - } - } - - for (i = 0, band = startBand; band < stopBand; band++, i++) { - /* energy is weighted by weightingfactor stored in dBf_m array */ - /* dBf_m index runs from 0 to stopBand-startband */ - /* energy shifted by calculated headroom for maximum precision */ - FIXP_DBL weightedEnergy = - fMult(Energies[timeSlot][band] << headroomEnSlot, - h_sbrFastTransientDetector->dBf_m[i]); - - /* energy is added up */ - /* shift by 6 to have a headroom for maximum 64 additions */ - /* shift by dBf_e to handle weighting factor dependent scale factors */ - tmpE += - weightedEnergy >> (6 + (10 - h_sbrFastTransientDetector->dBf_e[i])); - } - - /* store calculated energy for timeslot */ - energy_timeSlots[timeSlot] = tmpE; - - /* calculate overall scale factor for energy of this timeslot */ - /* = original scale factor of energies - * (-scaleEnergies[0]+2*QMF_SCALE_OFFSET or - * -scaleEnergies[1]+2*QMF_SCALE_OFFSET */ - /* depending on YBufferWriteOffset) */ - /* + weighting factor scale (10) */ - /* + adding up scale factor ( 6) */ - /* - headroom of energy value (headroomEnSlot) */ - if (timeSlot < YBufferWriteOffset) { - energy_timeSlots_scale[timeSlot] = - (-scaleEnergies[0] + 2 * QMF_SCALE_OFFSET) + (10 + 6) - - headroomEnSlot; - } else { - energy_timeSlots_scale[timeSlot] = - (-scaleEnergies[1] + 2 * QMF_SCALE_OFFSET) + (10 + 6) - - headroomEnSlot; - } - - /* Add a small energy to the denominator, thus making the transient - detection energy-dependent. Loud transients are being detected, - silent ones not. */ - - /* make sure that smallNRG does not overflow */ - if (-energy_timeSlots_scale[timeSlot - 1] + 1 > 5) { - denominator = smallNRG; - denominator_scale = 0; - } else { - /* Leave an additional headroom of 1 bit for this addition. */ - smallNRG = - scaleValue(smallNRG, -(energy_timeSlots_scale[timeSlot - 1] + 1)); - denominator = (energy_timeSlots[timeSlot - 1] >> 1) + smallNRG; - denominator_scale = energy_timeSlots_scale[timeSlot - 1] + 1; - } - - delta_energy[timeSlot] = - fDivNorm(energy_timeSlots[timeSlot], denominator, &norm); - delta_energy_scale[timeSlot] = - energy_timeSlots_scale[timeSlot] - denominator_scale + norm; - } - - /*get transient candidates*/ - /* For every timeslot, check if delta(E) exceeds the threshold. If it did, - it could potentially be marked as a transient candidate. However, the 2 - slots before the current one must not be transients with an energy higher - than 1.4*E(current). If both aren't transients or if the energy of the - current timesolot is more than 1.4 times higher than the energy in the - last or the one before the last slot, it is marked as a transient.*/ - - FDK_ASSERT(lookahead >= 2); - for (timeSlot = lookahead; timeSlot < nTimeSlots + lookahead; timeSlot++) { - FIXP_DBL energy_cur_slot_weighted = - fMult(energy_timeSlots[timeSlot], FL2FXCONST_DBL(1.0f / 1.4f)); - if (!fIsLessThan(delta_energy[timeSlot], delta_energy_scale[timeSlot], thr, - thr_scale) && - (((transientCandidates[timeSlot - 2] == 0) && - (transientCandidates[timeSlot - 1] == 0)) || - !fIsLessThan(energy_cur_slot_weighted, - energy_timeSlots_scale[timeSlot], - energy_timeSlots[timeSlot - 1], - energy_timeSlots_scale[timeSlot - 1]) || - !fIsLessThan(energy_cur_slot_weighted, - energy_timeSlots_scale[timeSlot], - energy_timeSlots[timeSlot - 2], - energy_timeSlots_scale[timeSlot - 2]))) { - /* in case of strong transients, subsequent - * qmf slots might be recognized as transients. */ - transientCandidates[timeSlot] = 1; - } - } - - /*get transient with max energy*/ - max_delta_energy = FL2FXCONST_DBL(0.0f); - max_delta_energy_scale = 0; - ind_max = 0; - isTransientInFrame = 0; - for (timeSlot = 0; timeSlot < nTimeSlots; timeSlot++) { - int scale = fMax(delta_energy_scale[timeSlot], max_delta_energy_scale); - if (transientCandidates[timeSlot] && - ((delta_energy[timeSlot] >> (scale - delta_energy_scale[timeSlot])) > - (max_delta_energy >> (scale - max_delta_energy_scale)))) { - max_delta_energy = delta_energy[timeSlot]; - max_delta_energy_scale = scale; - ind_max = timeSlot; - isTransientInFrame = 1; - } - } - - /*from all transient candidates take the one with the biggest energy*/ - if (isTransientInFrame) { - tran_vector[0] = ind_max; - tran_vector[1] = 1; - } else { - /*reset transient info*/ - tran_vector[0] = tran_vector[1] = 0; - } - - /*check for transients in lookahead*/ - for (timeSlot = nTimeSlots; timeSlot < nTimeSlots + lookahead; timeSlot++) { - if (transientCandidates[timeSlot]) { - tran_vector[2] = 1; - } - } - - /*update buffers*/ - for (timeSlot = 0; timeSlot < lookahead; timeSlot++) { - transientCandidates[timeSlot] = transientCandidates[nTimeSlots + timeSlot]; - - /* fixpoint stuff */ - energy_timeSlots[timeSlot] = energy_timeSlots[nTimeSlots + timeSlot]; - energy_timeSlots_scale[timeSlot] = - energy_timeSlots_scale[nTimeSlots + timeSlot]; - - delta_energy[timeSlot] = delta_energy[nTimeSlots + timeSlot]; - delta_energy_scale[timeSlot] = delta_energy_scale[nTimeSlots + timeSlot]; - } -} --- a/libSBRenc/src/tran_det.h +++ /dev/null @@ -1,191 +0,0 @@ -/* ----------------------------------------------------------------------------- -Software License for The Fraunhofer FDK AAC Codec Library for Android - -© Copyright 1995 - 2018 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 ------------------------------------------------------------------------------ */ - -/**************************** SBR encoder library ****************************** - - Author(s): - - Description: - -*******************************************************************************/ - -/*! - \file - \brief Transient detector prototypes $Revision: 95111 $ -*/ -#ifndef TRAN_DET_H -#define TRAN_DET_H - -#include "sbr_encoder.h" -#include "sbr_def.h" - -typedef struct { - FIXP_DBL transients[32 + (32 / 2)]; - FIXP_DBL thresholds[64]; - FIXP_DBL tran_thr; /* Master threshold for transient signals */ - FIXP_DBL split_thr_m; /* Threshold for splitting FIXFIX-frames into 2 env */ - INT split_thr_e; /* Scale for splitting threshold */ - FIXP_DBL prevLowBandEnergy; /* Energy of low band */ - FIXP_DBL prevHighBandEnergy; /* Energy of high band */ - INT tran_fc; /* Number of lowband subbands to discard */ - INT no_cols; - INT no_rows; - INT mode; - - int frameShift; - int tran_off; /* Offset for reading energy values. */ -} SBR_TRANSIENT_DETECTOR; - -typedef SBR_TRANSIENT_DETECTOR *HANDLE_SBR_TRANSIENT_DETECTOR; - -#define TRAN_DET_LOOKAHEAD 2 -#define TRAN_DET_START_FREQ 4500 /*start frequency for transient detection*/ -#define TRAN_DET_STOP_FREQ 13500 /*stop frequency for transient detection*/ -#define TRAN_DET_MIN_QMFBANDS \ - 4 /* minimum qmf bands for transient detection \ - */ -#define QMF_HP_dBd_SLOPE_FIX \ - FL2FXCONST_DBL(0.00075275f) /* 0.002266f/10 * log2(10) */ -#define TRAN_DET_THRSHLD FL2FXCONST_DBL(5.0f / 8.0f) -#define TRAN_DET_THRSHLD_SCALE (3) - -typedef struct { - INT transientCandidates[32 + TRAN_DET_LOOKAHEAD]; - INT nTimeSlots; - INT lookahead; - INT startBand; - INT stopBand; - - FIXP_DBL dBf_m[64]; - INT dBf_e[64]; - - FIXP_DBL energy_timeSlots[32 + TRAN_DET_LOOKAHEAD]; - INT energy_timeSlots_scale[32 + TRAN_DET_LOOKAHEAD]; - - FIXP_DBL delta_energy[32 + TRAN_DET_LOOKAHEAD]; - INT delta_energy_scale[32 + TRAN_DET_LOOKAHEAD]; - - FIXP_DBL lowpass_energy[32 + TRAN_DET_LOOKAHEAD]; - INT lowpass_energy_scale[32 + TRAN_DET_LOOKAHEAD]; -} FAST_TRAN_DETECTOR; -typedef FAST_TRAN_DETECTOR *HANDLE_FAST_TRAN_DET; - -INT FDKsbrEnc_InitSbrFastTransientDetector( - HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector, - const INT time_slots_per_frame, const INT bandwidth_qmf_slot, - const INT no_qmf_channels, const INT sbr_qmf_1st_band); - -void FDKsbrEnc_fastTransientDetect( - const HANDLE_FAST_TRAN_DET h_sbrFastTransientDetector, - const FIXP_DBL *const *Energies, const int *const scaleEnergies, - const INT YBufferWriteOffset, UCHAR *const tran_vector); - -void FDKsbrEnc_transientDetect( - HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector, FIXP_DBL **Energies, - INT *scaleEnergies, UCHAR *tran_vector, int YBufferWriteOffset, - int YBufferSzShift, int timeStep, int frameMiddleBorder); - -int FDKsbrEnc_InitSbrTransientDetector( - HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector, - UINT sbrSyntaxFlags, /* SBR syntax flags derived from AOT. */ - INT frameSize, INT sampleFreq, sbrConfigurationPtr params, int tran_fc, - int no_cols, int no_rows, int YBufferWriteOffset, int YBufferSzShift, - int frameShift, int tran_off); - -void FDKsbrEnc_frameSplitter( - FIXP_DBL **Energies, INT *scaleEnergies, - HANDLE_SBR_TRANSIENT_DETECTOR h_sbrTransientDetector, UCHAR *freqBandTable, - UCHAR *tran_vector, int YBufferWriteOffset, int YBufferSzShift, int nSfb, - int timeStep, int no_cols, FIXP_DBL *tonality); -#endif