|
From 612384d1b1c44d03f0185ef50c8b53fcb5fccfc3 Mon Sep 17 00:00:00 2001
|
|
From: Wim Taymans <wtaymans@redhat.com>
|
|
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 <em>envelope</em> 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 <em>lowSubband</em> and <em>highSubband</em> 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 <em>_m</em> and <em>_e</em> 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 <em>hb_scale</em> 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:<br> \f$ gain
|
|
- = \sqrt{ \frac{nrgRef}{nrgEst} \cdot (1 - noiseRatio) } \hspace{2cm} noise =
|
|
- \sqrt{ nrgRef \cdot noiseRatio } \f$<br> where <em>noiseRatio</em> and
|
|
- <em>nrgRef</em> are extracted from the bitstream and <em>nrgEst</em> 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
|
|
-
|
|
- <br>
|
|
-*/
|
|
-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
|
|
-
|
|
- <h1>About the SBR data format:</h1>
|
|
-
|
|
- 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 <h2>The SBR_HEADER_ELEMENT</h2>
|
|
-
|
|
- 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 <h2>The SBR_STANDARD_ELEMENT</h2>
|
|
-
|
|
- 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<FL2FXCONST_DBL(0.015625f)>> 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; env<pBsData->noEnv; 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]<noSubSample for VAR_BORDERS by
|
|
- duplicating last PS parameters and incrementing noEnv */
|
|
- if (pBsData->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];
|
|
-
|
|
- /*!
|
|
- <h3> type 'A' rotation </h3>
|
|
- mixing procedure R_a, used in baseline version<br>
|
|
-
|
|
- Scale-factor vectors c1 and c2 are precalculated in initPsTables () and
|
|
- stored in scaleFactors[] and scaleFactorsFine[] = pScaleFactors []. From the
|
|
- linearized IID parameters (intensity differences), two scale factors are
|
|
- calculated. They are used to obtain the coefficients h11... h22.
|
|
- */
|
|
-
|
|
- /* ScaleR and ScaleL are scaled by 1 shift right */
|
|
-
|
|
- 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;
|
|
-
|
|
- /**********************************************************************************************/
|
|
- /*!
|
|
- <h2> Mapping </h2>
|
|
-
|
|
- The number of stereo bands that is actually used depends on the number of
|
|
- availble parameters for IID and ICC: <pre> nr. of IID para.| nr. of ICC para.
|
|
- | nr. of Stereo bands
|
|
- ----------------|------------------|-------------------
|
|
- 10,20 | 10,20 | 20
|
|
- 10,20 | 34 | 34
|
|
- 34 | 10,20 | 34
|
|
- 34 | 34 | 34
|
|
- </pre>
|
|
- In the case the number of parameters for IIS and ICC differs from the number
|
|
- of stereo bands, a mapping from the lower number to the higher number of
|
|
- parameters is applied. Index mapping of IID and ICC parameters is already done
|
|
- in psbitdec.cpp. Further mapping is not needed here in baseline version.
|
|
- **********************************************************************************************/
|
|
-
|
|
- /************************************************************************************************/
|
|
- /*!
|
|
- <h2> Mixing </h2>
|
|
-
|
|
- To generate the QMF subband signals for the subband samples n = n[e]+1 ,,,
|
|
- n_[e+1] the parameters at position n[e] and n[e+1] are required as well as the
|
|
- subband domain signals s_k(n) and d_k(n) for n = n[e]+1... n_[e+1]. n[e]
|
|
- represents the start position for envelope e. The border positions n[e] are
|
|
- handled in DecodePS().
|
|
-
|
|
- The stereo sub subband signals are constructed as:
|
|
- <pre>
|
|
- l_k(n) = H11(k,n) s_k(n) + H21(k,n) d_k(n)
|
|
- r_k(n) = H21(k,n) s_k(n) + H22(k,n) d_k(n)
|
|
- </pre>
|
|
- In order to obtain the matrices H11(k,n)... H22 (k,n), the vectors h11(b)...
|
|
- h22(b) need to be calculated first (b: parameter index). Depending on ICC mode
|
|
- either mixing procedure R_a or R_b is used for that. For both procedures, the
|
|
- parameters for parameter position n[e+1] is used.
|
|
- ************************************************************************************************/
|
|
-
|
|
- /************************************************************************************************/
|
|
- /*!
|
|
- <h2>Phase parameters </h2>
|
|
- With disabled phase parameters (which is the case in baseline version), the
|
|
- H-matrices are just calculated by:
|
|
-
|
|
- <pre>
|
|
- H11(k,n[e+1] = h11(b(k))
|
|
- (...)
|
|
- b(k): parameter index according to mapping table
|
|
- </pre>
|
|
-
|
|
- <h2>Processing of the samples in the sub subbands </h2>
|
|
- this loop includes the interpolation of the coefficients Hxx
|
|
- ************************************************************************************************/
|
|
-
|
|
- /******************************************************/
|
|
- /* 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.
|
|
-
|
|
-<pre>
|
|
-
|
|
- ------------- ---------- -------------
|
|
- | 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
|
|
-
|
|
-</pre>
|
|
-*/
|
|
-#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 <br>
|
|
- Dimension: (8) */
|
|
-C_ALLOC_MEM2(Ram_SbrDecElement, SBR_DECODER_ELEMENT, 1, (8))
|
|
-/*! SBR Decoder individual channel data <br>
|
|
- 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
|
|
- <br>
|
|
- Depending on the mode set by DONT_USE_CORE_WORKBUFFER, workbuffers are
|
|
- defined additionally to the CoreWorkbuffer.
|
|
- <br>
|
|
- The size of WorkBuffers is ((1024) / (32) * (4) / 2)*(64) = 2048.
|
|
- <br>
|
|
- 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. <br> WorkBuffer1 is
|
|
- reused in the AAC core (-> aacdecoder.cpp, aac_ram.cpp) <br>
|
|
-
|
|
- Use of WorkBuffers:
|
|
- <pre>
|
|
-
|
|
- -------------------------------------------------------------
|
|
- 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
|
|
-
|
|
- -------------------------------------------------------------
|
|
-
|
|
- </pre>
|
|
-
|
|
-*/
|
|
--- 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; i<INV_TABLE_SIZE; i++) {
|
|
- d = 0.5f / ( 0.5f+(double)(i+1)/(INV_TABLE_SIZE*2) ) ;
|
|
- invTable[i] = FL2FX_SGL(d);
|
|
- }
|
|
-*/
|
|
-const FIXP_SGL FDK_sbrDecoder_invTable[INV_TABLE_SIZE] = {
|
|
- 0x7f80, 0x7f01, 0x7e83, 0x7e07, 0x7d8b, 0x7d11, 0x7c97, 0x7c1e, 0x7ba6,
|
|
- 0x7b2f, 0x7ab9, 0x7a44, 0x79cf, 0x795c, 0x78e9, 0x7878, 0x7807, 0x7796,
|
|
- 0x7727, 0x76b9, 0x764b, 0x75de, 0x7572, 0x7506, 0x749c, 0x7432, 0x73c9,
|
|
- 0x7360, 0x72f9, 0x7292, 0x722c, 0x71c6, 0x7161, 0x70fd, 0x709a, 0x7037,
|
|
- 0x6fd5, 0x6f74, 0x6f13, 0x6eb3, 0x6e54, 0x6df5, 0x6d97, 0x6d39, 0x6cdc,
|
|
- 0x6c80, 0x6c24, 0x6bc9, 0x6b6f, 0x6b15, 0x6abc, 0x6a63, 0x6a0b, 0x69b3,
|
|
- 0x695c, 0x6906, 0x68b0, 0x685a, 0x6806, 0x67b1, 0x675e, 0x670a, 0x66b8,
|
|
- 0x6666, 0x6614, 0x65c3, 0x6572, 0x6522, 0x64d2, 0x6483, 0x6434, 0x63e6,
|
|
- 0x6399, 0x634b, 0x62fe, 0x62b2, 0x6266, 0x621b, 0x61d0, 0x6185, 0x613b,
|
|
- 0x60f2, 0x60a8, 0x6060, 0x6017, 0x5fcf, 0x5f88, 0x5f41, 0x5efa, 0x5eb4,
|
|
- 0x5e6e, 0x5e28, 0x5de3, 0x5d9f, 0x5d5a, 0x5d17, 0x5cd3, 0x5c90, 0x5c4d,
|
|
- 0x5c0b, 0x5bc9, 0x5b87, 0x5b46, 0x5b05, 0x5ac4, 0x5a84, 0x5a44, 0x5a05,
|
|
- 0x59c6, 0x5987, 0x5949, 0x590a, 0x58cd, 0x588f, 0x5852, 0x5815, 0x57d9,
|
|
- 0x579d, 0x5761, 0x5725, 0x56ea, 0x56af, 0x5675, 0x563b, 0x5601, 0x55c7,
|
|
- 0x558e, 0x5555, 0x551c, 0x54e3, 0x54ab, 0x5473, 0x543c, 0x5405, 0x53ce,
|
|
- 0x5397, 0x5360, 0x532a, 0x52f4, 0x52bf, 0x5289, 0x5254, 0x521f, 0x51eb,
|
|
- 0x51b7, 0x5183, 0x514f, 0x511b, 0x50e8, 0x50b5, 0x5082, 0x5050, 0x501d,
|
|
- 0x4feb, 0x4fba, 0x4f88, 0x4f57, 0x4f26, 0x4ef5, 0x4ec4, 0x4e94, 0x4e64,
|
|
- 0x4e34, 0x4e04, 0x4dd5, 0x4da6, 0x4d77, 0x4d48, 0x4d19, 0x4ceb, 0x4cbd,
|
|
- 0x4c8f, 0x4c61, 0x4c34, 0x4c07, 0x4bd9, 0x4bad, 0x4b80, 0x4b54, 0x4b27,
|
|
- 0x4afb, 0x4acf, 0x4aa4, 0x4a78, 0x4a4d, 0x4a22, 0x49f7, 0x49cd, 0x49a2,
|
|
- 0x4978, 0x494e, 0x4924, 0x48fa, 0x48d1, 0x48a7, 0x487e, 0x4855, 0x482d,
|
|
- 0x4804, 0x47dc, 0x47b3, 0x478b, 0x4763, 0x473c, 0x4714, 0x46ed, 0x46c5,
|
|
- 0x469e, 0x4677, 0x4651, 0x462a, 0x4604, 0x45de, 0x45b8, 0x4592, 0x456c,
|
|
- 0x4546, 0x4521, 0x44fc, 0x44d7, 0x44b2, 0x448d, 0x4468, 0x4444, 0x441f,
|
|
- 0x43fb, 0x43d7, 0x43b3, 0x4390, 0x436c, 0x4349, 0x4325, 0x4302, 0x42df,
|
|
- 0x42bc, 0x4299, 0x4277, 0x4254, 0x4232, 0x4210, 0x41ee, 0x41cc, 0x41aa,
|
|
- 0x4189, 0x4167, 0x4146, 0x4125, 0x4104, 0x40e3, 0x40c2, 0x40a1, 0x4081,
|
|
- 0x4060, 0x4040, 0x4020, 0x4000};
|
|
--- a/libSBRdec/src/sbr_rom.h
|
|
+++ /dev/null
|
|
@@ -1,216 +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 Declaration of constant tables
|
|
-*/
|
|
-#ifndef SBR_ROM_H
|
|
-#define SBR_ROM_H
|
|
-
|
|
-#include "sbrdecoder.h"
|
|
-#include "env_extr.h"
|
|
-#include "qmf.h"
|
|
-
|
|
-#define INV_INT_TABLE_SIZE 49
|
|
-#define SBR_NF_NO_RANDOM_VAL \
|
|
- 512 /*!< Size of random number array for noise floor */
|
|
-
|
|
-/*
|
|
- Frequency scales
|
|
-*/
|
|
-
|
|
-/* if defined(SBRDEC_RATIO_16_64_ENABLE) ((4) = 4) else ((4) = 2) */
|
|
-extern const UCHAR FDK_sbrDecoder_sbr_start_freq_16[(4) / 2][16];
|
|
-extern const UCHAR FDK_sbrDecoder_sbr_start_freq_22[(4) / 2][16];
|
|
-extern const UCHAR FDK_sbrDecoder_sbr_start_freq_24[(4) / 2][16];
|
|
-extern const UCHAR FDK_sbrDecoder_sbr_start_freq_32[(4) / 2][16];
|
|
-extern const UCHAR FDK_sbrDecoder_sbr_start_freq_40[(4) / 2][16];
|
|
-extern const UCHAR FDK_sbrDecoder_sbr_start_freq_44[(4) / 2][16];
|
|
-extern const UCHAR FDK_sbrDecoder_sbr_start_freq_48[(4) / 2][16];
|
|
-extern const UCHAR FDK_sbrDecoder_sbr_start_freq_64[(4) / 2][16];
|
|
-extern const UCHAR FDK_sbrDecoder_sbr_start_freq_88[(4) / 2][16];
|
|
-extern const UCHAR FDK_sbrDecoder_sbr_start_freq_192[16];
|
|
-extern const UCHAR FDK_sbrDecoder_sbr_start_freq_176[16];
|
|
-extern const UCHAR FDK_sbrDecoder_sbr_start_freq_128[16];
|
|
-
|
|
-/*
|
|
- Low-Power-Profile Transposer
|
|
-*/
|
|
-#define NUM_WHFACTOR_TABLE_ENTRIES 9
|
|
-extern const USHORT
|
|
- FDK_sbrDecoder_sbr_whFactorsIndex[NUM_WHFACTOR_TABLE_ENTRIES];
|
|
-extern const FIXP_DBL
|
|
- FDK_sbrDecoder_sbr_whFactorsTable[NUM_WHFACTOR_TABLE_ENTRIES][6];
|
|
-
|
|
-/*
|
|
- Envelope Adjustor
|
|
-*/
|
|
-extern const FIXP_SGL FDK_sbrDecoder_sbr_limGains_m[4];
|
|
-extern const UCHAR FDK_sbrDecoder_sbr_limGains_e[4];
|
|
-extern const FIXP_SGL FDK_sbrDecoder_sbr_limGainsPvc_m[4];
|
|
-extern const UCHAR FDK_sbrDecoder_sbr_limGainsPvc_e[4];
|
|
-extern const FIXP_SGL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4[4];
|
|
-extern const FIXP_DBL FDK_sbrDecoder_sbr_limiterBandsPerOctaveDiv4_DBL[4];
|
|
-extern const FIXP_SGL FDK_sbrDecoder_sbr_smoothFilter[4];
|
|
-extern const FIXP_SGL FDK_sbrDecoder_sbr_randomPhase[SBR_NF_NO_RANDOM_VAL][2];
|
|
-
|
|
-/*
|
|
- Envelope Extractor
|
|
-*/
|
|
-extern const int FDK_sbrDecoder_envelopeTable_8[8][5];
|
|
-extern const int FDK_sbrDecoder_envelopeTable_15[15][6];
|
|
-extern const int FDK_sbrDecoder_envelopeTable_16[16][6];
|
|
-extern const FRAME_INFO FDK_sbrDecoder_sbr_frame_info1_15;
|
|
-extern const FRAME_INFO FDK_sbrDecoder_sbr_frame_info2_15;
|
|
-extern const FRAME_INFO FDK_sbrDecoder_sbr_frame_info4_15;
|
|
-extern const FRAME_INFO FDK_sbrDecoder_sbr_frame_info8_15;
|
|
-extern const FRAME_INFO FDK_sbrDecoder_sbr_frame_info1_16;
|
|
-extern const FRAME_INFO FDK_sbrDecoder_sbr_frame_info2_16;
|
|
-extern const FRAME_INFO FDK_sbrDecoder_sbr_frame_info4_16;
|
|
-extern const FRAME_INFO FDK_sbrDecoder_sbr_frame_info8_16;
|
|
-
|
|
-extern const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvLevel10T[120][2];
|
|
-extern const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvLevel10F[120][2];
|
|
-extern const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvBalance10T[48][2];
|
|
-extern const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvBalance10F[48][2];
|
|
-extern const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvLevel11T[62][2];
|
|
-extern const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvLevel11F[62][2];
|
|
-extern const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvBalance11T[24][2];
|
|
-extern const SCHAR FDK_sbrDecoder_sbr_huffBook_EnvBalance11F[24][2];
|
|
-extern const SCHAR FDK_sbrDecoder_sbr_huffBook_NoiseLevel11T[62][2];
|
|
-extern const SCHAR FDK_sbrDecoder_sbr_huffBook_NoiseBalance11T[24][2];
|
|
-
|
|
-/*
|
|
- Parametric stereo
|
|
-*/
|
|
-
|
|
-/* FIX_BORDER can have 0, 1, 2, 4 envelops */
|
|
-extern const UCHAR FDK_sbrDecoder_aFixNoEnvDecode[4];
|
|
-
|
|
-/* IID & ICC Huffman codebooks */
|
|
-extern const SCHAR aBookPsIidTimeDecode[28][2];
|
|
-extern const SCHAR aBookPsIidFreqDecode[28][2];
|
|
-extern const SCHAR aBookPsIccTimeDecode[14][2];
|
|
-extern const SCHAR aBookPsIccFreqDecode[14][2];
|
|
-
|
|
-/* IID-fine Huffman codebooks */
|
|
-
|
|
-extern const SCHAR aBookPsIidFineTimeDecode[60][2];
|
|
-extern const SCHAR aBookPsIidFineFreqDecode[60][2];
|
|
-
|
|
-/* the values of the following 3 tables are shiftet right by 1 ! */
|
|
-extern const FIXP_DBL ScaleFactors[NO_IID_LEVELS];
|
|
-extern const FIXP_DBL ScaleFactorsFine[NO_IID_LEVELS_FINE];
|
|
-extern const FIXP_DBL Alphas[NO_ICC_LEVELS];
|
|
-
|
|
-extern const UCHAR bins2groupMap20[NO_IID_GROUPS];
|
|
-extern const UCHAR FDK_sbrDecoder_aNoIidBins[3];
|
|
-extern const UCHAR FDK_sbrDecoder_aNoIccBins[3];
|
|
-
|
|
-/* Lookup tables for some arithmetic functions */
|
|
-
|
|
-#define INV_TABLE_BITS 8
|
|
-#define INV_TABLE_SIZE (1 << INV_TABLE_BITS)
|
|
-extern const FIXP_SGL FDK_sbrDecoder_invTable[INV_TABLE_SIZE];
|
|
-
|
|
-#endif // SBR_ROM_H
|
|
--- a/libSBRdec/src/sbrdec_drc.cpp
|
|
+++ /dev/null
|
|
@@ -1,528 +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
|
|
-
|
|
-*******************************************************************************/
|
|
-
|
|
-#include "sbrdec_drc.h"
|
|
-
|
|
-/* DRC - Offset table for QMF interpolation. Shifted by one index position.
|
|
- The table defines the (short) window borders rounded to the nearest QMF
|
|
- timeslot. It has the size 16 because it is accessed with the
|
|
- drcInterpolationScheme that is read from the bitstream with 4 bit. */
|
|
-static const UCHAR winBorderToColMappingTab[2][16] = {
|
|
- /*-1, 0, 1, 2, 3, 4, 5, 6, 7, 8 */
|
|
- {0, 0, 4, 8, 12, 16, 20, 24, 28, 32, 32, 32, 32, 32, 32,
|
|
- 32}, /* 1024 framing */
|
|
- {0, 0, 4, 8, 11, 15, 19, 23, 26, 30, 30, 30, 30, 30, 30,
|
|
- 30} /* 960 framing */
|
|
-};
|
|
-
|
|
-/*!
|
|
- \brief Initialize DRC QMF factors
|
|
-
|
|
- \hDrcData Handle to DRC channel data.
|
|
-
|
|
- \return none
|
|
-*/
|
|
-void sbrDecoder_drcInitChannel(HANDLE_SBR_DRC_CHANNEL hDrcData) {
|
|
- int band;
|
|
-
|
|
- if (hDrcData == NULL) {
|
|
- return;
|
|
- }
|
|
-
|
|
- for (band = 0; band < (64); band++) {
|
|
- hDrcData->prevFact_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:
|
|
-
|
|
- <h2>Programming</h2>
|
|
-
|
|
- \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()
|
|
-
|
|
- <h2>Algorithmic details</h2>
|
|
- \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. <br>
|
|
- The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
|
|
-*/
|
|
-/************************************************************************/
|
|
-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. <br>
|
|
- The base for exponents is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
|
|
-
|
|
- 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. <br>
|
|
- The base for the exponent is 2. Example: \f$ a = a\_m * 2^{a\_e} \f$<br>
|
|
- 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<numberCols>> 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; i<totNoEst/2; i++) {
|
|
- for (i = 0; i < MAX_NO_OF_ESTIMATES / 2; i++) {
|
|
- FDKmemclear(hs->tonalityDiff[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. <br>
|
|
- 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) <br>
|
|
- Dimension #MAX_FREQ_COEFFS/2+1
|
|
-*/
|
|
-C_ALLOC_MEM2(Ram_Sbr_freqBandTableLO, UCHAR, (MAX_FREQ_COEFFS / 2 + 1), (8))
|
|
-
|
|
-/*! Frequency band table (high res) <br>
|
|
- Dimension #MAX_FREQ_COEFFS +1
|
|
-*/
|
|
-C_ALLOC_MEM2(Ram_Sbr_freqBandTableHI, UCHAR, (MAX_FREQ_COEFFS + 1), (8))
|
|
-
|
|
-/*! vk matser table <br>
|
|
- Dimension #MAX_FREQ_COEFFS +1
|
|
-*/
|
|
-C_ALLOC_MEM2(Ram_Sbr_v_k_master, UCHAR, (MAX_FREQ_COEFFS + 1), (8))
|
|
-
|
|
-/*
|
|
- Missing harmonics detection
|
|
-*/
|
|
-
|
|
-/*! sbr_detectionVectors <br>
|
|
- 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[ <br>
|
|
- Dimension #MAX_NUM_CHANNELS*#MAX_FREQ_COEFFS]
|
|
-*/
|
|
-C_ALLOC_MEM2(Ram_Sbr_prevEnvelopeCompensation, UCHAR, MAX_FREQ_COEFFS, (8))
|
|
-/*! sbr_guideScfb[ <br>
|
|
- Dimension #MAX_NUM_CHANNELS*#MAX_FREQ_COEFFS]
|
|
-*/
|
|
-C_ALLOC_MEM2(Ram_Sbr_guideScfb, UCHAR, MAX_FREQ_COEFFS, (8))
|
|
-
|
|
-/*! sbr_guideVectorDetected <br>
|
|
- 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 <br>
|
|
- 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<FIXP_DBL*>(
|
|
- reinterpret_cast<void*>(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<FIXP_DBL*>(reinterpret_cast<void*>(
|
|
- 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<FIXP_DBL*>(
|
|
- reinterpret_cast<void*>(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 and by the factor (2^19-scaleEnergies[1]) 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 <frameShift> 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
|