diff --git a/.gitignore b/.gitignore index a2f6a6b95f2848887c77031f45f10e0d72de0d35..7bddb459917192afb3babaa4010eee2213e81088 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ scripts/td_object_renderer/object_renderer_standalone/renderer_standalone.exe .DS_Store .vscode .cache +.idea *.log *.bak .\#* diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5d97bec1567f600abfaa8ffbc05e5bbd6daadfb7..4a7421142abdc243eb6cda18280b24d910cf251a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -413,7 +413,7 @@ renderer-asan: needs: ["build-codec-linux-cmake"] stage: test script: - - python3 ci/disable_ram_counting.py + - python3 ci/comment_defines.py -d RAM_COUNTING_TOOL -f lib_com/options.h - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=asan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true - cmake --build cmake-build -- -j - python3 -m pytest -q -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py @@ -437,7 +437,7 @@ renderer-msan: needs: ["build-codec-linux-cmake"] stage: test script: - - python3 ci/disable_ram_counting.py + - python3 ci/comment_defines.py -d RAM_COUNTING_TOOL -f lib_com/options.h - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=msan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true - cmake --build cmake-build -- -j - python3 -m pytest -q -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py @@ -732,6 +732,22 @@ selection-test-processing: when: on_failure expire_in: 1 week +lc3plus-ensure-no-code-changes: + extends: + - .test-job-linux + - .rules-merge-request + stage: validate + needs: [] + timeout: "5 minutes" + script: + # Replace code commited to repo with code downloaded from ETSI + - ./scripts/lc3plus_lib_setup/get_lc3plus.sh + + # Ensure git reports no changes + - modified_files=$(git status -s) + - if [[ $modified_files ]]; then printf 'LC3plus codebase was modified!\n\n'"$modified_files"'\n\n'; exit $EXIT_CODE_FAIL; fi + + # --------------------------------------------------------------- # Test jobs for main branch # --------------------------------------------------------------- diff --git a/CMakeLists.txt b/CMakeLists.txt index 8098dc1c6896db669b7b31edfd2717f703442fcf..7a6cc317caac3f4ae87a3b308a4e5205b1ec8619 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,9 +116,9 @@ file(GLOB libComSrcs "lib_com/*.c") file(GLOB libComHeaders "lib_com/*.h") add_library(lib_com ${libComSrcs} ${libComHeaders}) if(UNIX) - target_link_libraries(lib_com m) + target_link_libraries(lib_com PRIVATE m) endif() -target_include_directories(lib_com PUBLIC lib_com PRIVATE lib_enc lib_dec lib_rend lib_debug) +target_include_directories(lib_com PUBLIC lib_com PRIVATE lib_enc lib_dec lib_rend lib_debug lc3plus) file(GLOB libDebugSrcs "lib_debug/*.c") file(GLOB libDebugHeaders "lib_debug/*.h") @@ -130,14 +130,28 @@ file(GLOB libEncSrcs "lib_enc/*.c") file(GLOB libEncHeaders "lib_enc/*.h") add_library(lib_enc ${libEncSrcs} ${libEncHeaders}) target_link_libraries(lib_enc lib_com lib_debug) -target_include_directories(lib_enc PUBLIC lib_enc PRIVATE lib_dec lib_rend) +target_include_directories(lib_enc PUBLIC lib_enc PRIVATE lib_dec lib_rend lc3plus) + +file(GLOB libLC3plusSrcs "lc3plus/*.c") +file(GLOB libLC3plusHeaders "lc3plus/*.h") +file(GLOB libLC3plusFftSrcs "lc3plus/fft/*.c") +file(GLOB libLC3plusFftHeaders "lc3plus/fft/*.h") +add_library(lc3plus ${libLC3plusSrcs} ${libLC3plusFftSrcs} ${libLC3plusHeaders} ${libLC3plusFftHeaders}) +target_include_directories(lc3plus PUBLIC lc3plus PRIVATE lc3plus/fft ) +target_link_libraries(lc3plus lib_com) # For including options.h, which is needed for instrumentation to work correctly +if(WMOPS) + target_link_libraries(lc3plus lib_debug) +endif() +file(GLOB libCldfbTransCodecSrcs "lib_rend/ivas_cldfb_trans_codec/*.c") +file(GLOB libCldfbTransCodecHeaders "lib_rend/ivas_cldfb_trans_codec/*.h") file(GLOB libRendSrcs "lib_rend/*.c") file(GLOB libRendHeaders "lib_rend/*.h") -add_library(lib_rend ${libRendSrcs} ${libRendHeaders}) -target_link_libraries(lib_rend lib_dec lib_com lib_debug) # Todo refactor: This dependency on lib_dec should be removed. +add_library(lib_rend ${libRendSrcs} ${libCldfbTransCodecSrcs} ${libRendHeaders} ${libCldfbTransCodecHeaders}) +target_link_libraries(lib_rend lib_dec lib_com lib_debug lc3plus) # Todo refactor: This dependency on lib_dec should be removed. target_include_directories(lib_rend PUBLIC lib_rend PRIVATE lib_enc) + file(GLOB libDecSrcs "lib_dec/*.c") file(GLOB libDecHeaders "lib_dec/*.h") add_library(lib_dec ${libDecSrcs} ${libDecHeaders}) @@ -147,7 +161,13 @@ target_include_directories(lib_dec PUBLIC lib_dec lib_rend PRIVATE lib_enc) file(GLOB libUtilSrcs "lib_util/*.c") file(GLOB libUtilHeaders "lib_util/*.h") add_library(lib_util ${libUtilSrcs} ${libUtilHeaders}) -target_include_directories(lib_util PUBLIC lib_util PRIVATE lib_com lib_enc lib_dec lib_rend lib_debug) +target_include_directories(lib_util PUBLIC lib_util PRIVATE lib_com lib_enc lib_dec lib_rend lib_debug lc3plus) + +if(NOT WMOPS) + file(GLOB unitTestIvasLc3plusSrcs "scripts/split_rendering/lc3plus/*.c") + add_executable(ivas_lc3plus_unit_test ${unitTestIvasLc3plusSrcs}) + target_link_libraries(ivas_lc3plus_unit_test lib_rend lib_dec lib_util lib_com lib_debug) +endif() add_executable(IVAS_cod apps/encoder.c) target_link_libraries(IVAS_cod lib_enc lib_util) @@ -170,6 +190,9 @@ if(COPY_EXECUTABLES_FROM_BUILD_DIR) add_custom_command(TARGET IVAS_cod POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") add_custom_command(TARGET IVAS_dec POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") add_custom_command(TARGET IVAS_rend POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") + if (NOT WMOPS) + add_custom_command(TARGET ivas_lc3plus_unit_test POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/split_rendering/lc3plus") + endif() endif() # Allow creating packages for CMake install diff --git a/Makefile b/Makefile index 7f8874d3439cc1fb73096cd5af609880ba9b874a..d14ddfbd1b4afd69ae2f608d70dcae08794182aa 100644 --- a/Makefile +++ b/Makefile @@ -6,12 +6,13 @@ SRC_LIBDEBUG = lib_debug SRC_LIBDEC = lib_dec SRC_LIBENC = lib_enc SRC_LIBREND = lib_rend +SRC_LC3PLUS = lc3plus lc3plus/fft SRC_LIBUTIL = lib_util SRC_APP = apps BUILD = build OBJDIR = obj -SRC_DIRS = $(sort -u $(SRC_LIBCOM) $(SRC_LIBDEBUG) $(SRC_LIBDEC) $(SRC_LIBENC) $(SRC_LIBREND) $(SRC_LIBUTIL) $(SRC_APP)) +SRC_DIRS = $(sort -u $(SRC_LIBCOM) $(SRC_LIBDEBUG) $(SRC_LIBDEC) $(SRC_LIBENC) $(SRC_LIBREND) $(SRC_LC3PLUS) $(SRC_LIBUTIL) $(SRC_APP)) # Name of CLI binaries CLI_APIDEC ?= IVAS_dec @@ -22,6 +23,7 @@ LIB_LIBDEBUG ?= libivasdebug.a LIB_LIBDEC ?= libivasdec.a LIB_LIBENC ?= libivasenc.a LIB_LIBREND ?= libivasrend.a +LIB_LC3PLUS ?= liblc3plus.a LIB_LIBUTIL ?= libivasutil.a # Default tool settings @@ -118,6 +120,7 @@ SRCS_LIBDEBUG = $(foreach DIR,$(SRC_LIBDEBUG),$(patsubst $(DIR)/%,%,$(wildcard $ SRCS_LIBDEC = $(foreach DIR,$(SRC_LIBDEC),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) SRCS_LIBENC = $(foreach DIR,$(SRC_LIBENC),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) SRCS_LIBREND = $(foreach DIR,$(SRC_LIBREND),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) +SRCS_LC3PLUS = $(foreach DIR,$(SRC_LC3PLUS),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) SRCS_LIBUTIL = $(foreach DIR,$(SRC_LIBUTIL),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) OBJS_LIBCOM = $(addprefix $(OBJDIR)/,$(SRCS_LIBCOM:.c=.o)) @@ -125,13 +128,14 @@ OBJS_LIBDEBUG = $(addprefix $(OBJDIR)/,$(SRCS_LIBDEBUG:.c=.o)) OBJS_LIBDEC = $(addprefix $(OBJDIR)/,$(SRCS_LIBDEC:.c=.o)) OBJS_LIBENC = $(addprefix $(OBJDIR)/,$(SRCS_LIBENC:.c=.o)) OBJS_LIBREND = $(addprefix $(OBJDIR)/,$(SRCS_LIBREND:.c=.o)) +OBJS_LC3PLUS = $(addprefix $(OBJDIR)/,$(SRCS_LC3PLUS:.c=.o)) OBJS_LIBUTIL = $(addprefix $(OBJDIR)/,$(SRCS_LIBUTIL:.c=.o)) OBJS_CLI_APIDEC = $(OBJDIR)/decoder.o OBJS_CLI_APIENC = $(OBJDIR)/encoder.o OBJS_CLI_APPREND = $(OBJDIR)/renderer.o DEPS = $(addprefix $(OBJDIR)/,$(SRCS_LIBCOM:.c=.P) $(SRCS_LIBDEBUG:.c=.P) $(SRCS_LIBDEC:.c=.P) \ - $(SRCS_LIBENC:.c=.P) $(SRCS_LIBUTIL:.c=.P)) + $(SRCS_LIBENC:.c=.P) $(SRCS_LIBUTIL:.c=.P) $(SRCS_LIBREND:.c=.P) $(SRCS_LC3PLUS:.c=.P)) ############################################################################### @@ -157,25 +161,28 @@ $(LIB_LIBENC): $(OBJS_LIBENC) $(LIB_LIBREND): $(OBJS_LIBREND) $(QUIET_AR)$(AR) rcs $@ $^ +$(LIB_LC3PLUS): $(OBJS_LC3PLUS) + $(QUIET_AR)$(AR) rcs $@ $^ + $(LIB_LIBUTIL): $(OBJS_LIBUTIL) $(QUIET_AR)$(AR) rcs $@ $^ -$(CLI_APIENC): $(OBJS_CLI_APIENC) $(LIB_LIBENC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) +$(CLI_APIENC): $(OBJS_CLI_APIENC) $(LIB_LIBENC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LC3PLUS) $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIENC) -L. -livasenc -livascom -livasutil -livasdebug $(LDLIBS) -o $(CLI_APIENC) -$(CLI_APIDEC): $(OBJS_CLI_APIDEC) $(LIB_LIBDEC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) - $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIDEC) -L. -livasdec -livascom -livasutil -livasdebug $(LDLIBS) -o $(CLI_APIDEC) +$(CLI_APIDEC): $(OBJS_CLI_APIDEC) $(LIB_LIBDEC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LC3PLUS) + $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIDEC) -L. -livasdec -livascom -livasutil -livasdebug -llc3plus $(LDLIBS) -o $(CLI_APIDEC) -$(CLI_APIREND): $(OBJS_CLI_APPREND) $(LIB_LIBREND) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LIBDEC) - $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -livasdec -livasutil -livasdebug -livascom $(LDLIBS) -o $(CLI_APIREND) +$(CLI_APIREND): $(OBJS_CLI_APPREND) $(LIB_LIBREND) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LIBDEC) $(LIB_LC3PLUS) + $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -livasdec -livasutil -livasdebug -livascom -llc3plus $(LDLIBS) -o $(CLI_APIREND) -libs: $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBREND) $(LIB_LIBUTIL) +libs: $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBREND) $(LIB_LC3PLUS) $(LIB_LIBUTIL) clean: $(QUIET)$(RM) $(OBJS_LIBENC) $(OBJS_LIBDEC) $(DEPS) $(QUIET)$(RM) $(DEPS:.P=.d) $(QUIET)test ! -d $(OBJDIR) || rm -rf $(OBJDIR) - $(QUIET)$(RM) $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND) $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL) $(LIB_LIBREND) + $(QUIET)$(RM) $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND) $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL) $(LIB_LIBREND) $(LIB_LC3PLUS) $(OBJDIR)/%.o : %.c | $(OBJDIR) $(QUIET_CC)$(CC) $(CFLAGS) -c -MD -o $@ $< diff --git a/Workspace_msvc/LC3plus.vcxproj b/Workspace_msvc/LC3plus.vcxproj new file mode 100644 index 0000000000000000000000000000000000000000..a70c61e5a812e03801ad5970171ac0e413959484 --- /dev/null +++ b/Workspace_msvc/LC3plus.vcxproj @@ -0,0 +1,184 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {95030B82-70CD-4C6B-84D4-61096035BEA2} + Win32Proj + LC3_FL + 10.0.17763.0 + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + true + LC3plus + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\Obj\ + + + false + LC3plus + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\Obj\ + + + + + + Level3 + ..\lib_com;%(AdditionalIncludeDirectories) + Disabled + MultiThreadedDebug + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4305;4244;4996 + + + Console + true + + + + + Level3 + + + ..\lib_com;%(AdditionalIncludeDirectories) + MaxSpeed + MultiThreaded + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;4305;4996 + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/Workspace_msvc.sln b/Workspace_msvc/Workspace_msvc.sln index fbdb561ee2403a9fbcb65671157eafc4b8a21f88..1d8e08ac9fe62eb11c8a2747f22c01a7e9620e5c 100644 --- a/Workspace_msvc/Workspace_msvc.sln +++ b/Workspace_msvc/Workspace_msvc.sln @@ -20,6 +20,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "encoder", "encoder.vcxproj" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "renderer", "renderer.vcxproj", "{12B4C8A5-1E06-4E30-B443-D1F916F52B47}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LC3plus", "LC3plus.vcxproj", "{95030B82-70CD-4C6B-84D4-61096035BEA2}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{51160D4C-55C9-4C16-A792-D94507225746}" ProjectSection(SolutionItems) = preProject ..\.clang-format = ..\.clang-format @@ -87,6 +89,12 @@ Global {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Release|Win32.ActiveCfg = Release|Win32 {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Release|Win32.Build.0 = Release|Win32 {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Release|x64.ActiveCfg = Release|Win32 + {95030B82-70CD-4C6B-84D4-61096035BEA2}.Debug|Win32.ActiveCfg = Debug|Win32 + {95030B82-70CD-4C6B-84D4-61096035BEA2}.Debug|Win32.Build.0 = Debug|Win32 + {95030B82-70CD-4C6B-84D4-61096035BEA2}.Debug|x64.ActiveCfg = Debug|Win32 + {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|Win32.ActiveCfg = Release|Win32 + {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|Win32.Build.0 = Release|Win32 + {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 23aa2ae3f0b6722871f7f9d2c37b27e41f46862f..62f0c3b2098c60bad5fea5f09d00cff6f821f154 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -78,7 +78,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -109,7 +109,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) @@ -147,7 +147,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true diff --git a/Workspace_msvc/lib_debug.vcxproj b/Workspace_msvc/lib_debug.vcxproj index 3b648fae048920ae06aa709785d4b49d2e58d710..7a2fcecef1353bc4e7bf229c4e584957bb3e89b9 100644 --- a/Workspace_msvc/lib_debug.vcxproj +++ b/Workspace_msvc/lib_debug.vcxproj @@ -73,7 +73,7 @@ Disabled - ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) + ..\lib_util;..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) false @@ -97,7 +97,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) + ..\lib_util;..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) false @@ -124,7 +124,7 @@ AnySuitable false false - ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) + ..\lib_util;..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 80910aa5e713bfca913d57aa453a16cac1744f1d..645828db60765df626ab3d11925c76aaa9b345ae 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -89,7 +89,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -126,7 +126,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;..\lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) @@ -169,7 +169,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) true diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index 3378ac10f0ccb8b95616f87f6d225f38af30bb3d..6f88f77c4f760903c6b2a7cdbc2597ed4349c09e 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -89,7 +89,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -129,7 +129,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) @@ -176,7 +176,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index d1cda3290d9efd2128280b8dab8ddbe4e72272ac..6e3943249f2e64991a5cd27b6e6a09aa25ad2f33 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -89,7 +89,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -126,7 +126,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) @@ -169,7 +169,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) true @@ -199,8 +199,27 @@ + + + + + + + + + + + + + + + + + + + @@ -231,6 +250,8 @@ + + @@ -238,6 +259,9 @@ + + + @@ -248,6 +272,10 @@ {54509728-928b-44d9-a118-a6f92f08b34f} false + + {95030B82-70CD-4C6B-84D4-61096035BEA2} + false + diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index 9c68dbb36d26bb969bf1f470c4b4d85d104e7876..71723a07cbc7f13b0dc152081ea0ffe12fdc329e 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -73,7 +73,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;..\lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) false @@ -117,7 +117,7 @@ AnySuitable false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;..\lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) true @@ -159,6 +159,8 @@ + + @@ -184,8 +186,10 @@ + + diff --git a/Workspace_msvc/renderer.vcxproj b/Workspace_msvc/renderer.vcxproj index 94ad9f774e7bd050c4e940eb9a47911f18d783ef..eee6eed340c3d05398a8f668cde3c5748399d4fc 100644 --- a/Workspace_msvc/renderer.vcxproj +++ b/Workspace_msvc/renderer.vcxproj @@ -86,7 +86,7 @@ Disabled - ..\lib_com;..\lib_dec;..\lib_enc;..\lib_debug;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_dec;..\lib_enc;..\lib_debug;..\lib_util;..\lib_rend;..\lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) EnableFastChecks @@ -130,7 +130,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;..\lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) @@ -180,7 +180,7 @@ Neither false false - ..\lib_com;..\lib_dec;..\lib_enc;..\lib_debug;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_dec;..\lib_enc;..\lib_debug;..\lib_util;..\lib_rend;..\lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true diff --git a/Workspace_msvc/renderer_configs/split_renderer_config_384_3dof.txt b/Workspace_msvc/renderer_configs/split_renderer_config_384_3dof.txt new file mode 100644 index 0000000000000000000000000000000000000000..84f70f6d8adff513824cfb8fbbfc87f8d8763a03 --- /dev/null +++ b/Workspace_msvc/renderer_configs/split_renderer_config_384_3dof.txt @@ -0,0 +1,10 @@ +[SPLITREND] +BITRATE = 384000; +DOF = 3; +HQMODE = 0; + +[GENERAL] +RENDERER = CREND; + +[ROOMACOUSTICS] +REVERB = FALSE; diff --git a/Workspace_msvc/renderer_configs/split_renderer_config_384_3dof_hq.txt b/Workspace_msvc/renderer_configs/split_renderer_config_384_3dof_hq.txt new file mode 100644 index 0000000000000000000000000000000000000000..520ba5b8ae861957fc435e8423fd5b64134ba600 --- /dev/null +++ b/Workspace_msvc/renderer_configs/split_renderer_config_384_3dof_hq.txt @@ -0,0 +1,10 @@ +[SPLITREND] +BITRATE = 384000; +DOF = 3; +HQMODE = 1; + +[GENERAL] +RENDERER = CREND; + +[ROOMACOUSTICS] +REVERB = FALSE; diff --git a/Workspace_msvc/renderer_configs/split_renderer_config_512_2dof.txt b/Workspace_msvc/renderer_configs/split_renderer_config_512_2dof.txt new file mode 100644 index 0000000000000000000000000000000000000000..1a718cab03380efabe7af2022affd330d240a292 --- /dev/null +++ b/Workspace_msvc/renderer_configs/split_renderer_config_512_2dof.txt @@ -0,0 +1,10 @@ +[SPLITREND] +BITRATE = 512000; +DOF = 2; +HQMODE = 0; + +[GENERAL] +RENDERER = CREND; + +[ROOMACOUSTICS] +REVERB = FALSE; diff --git a/Workspace_msvc/renderer_configs/split_renderer_config_768_1dof.txt b/Workspace_msvc/renderer_configs/split_renderer_config_768_1dof.txt new file mode 100644 index 0000000000000000000000000000000000000000..31d94203ccfa51de0b455e4d6efdc94a9e825583 --- /dev/null +++ b/Workspace_msvc/renderer_configs/split_renderer_config_768_1dof.txt @@ -0,0 +1,10 @@ +[SPLITREND] +BITRATE = 768000; +DOF = 1; +HQMODE = 0; + +[GENERAL] +RENDERER = CREND; + +[ROOMACOUSTICS] +REVERB = FALSE; diff --git a/Workspace_msvc/renderer_configs/split_renderer_config_768_1dof_hoa_lc3plus.txt b/Workspace_msvc/renderer_configs/split_renderer_config_768_1dof_hoa_lc3plus.txt new file mode 100644 index 0000000000000000000000000000000000000000..498c6add9becc9f8b3821b290567827e8fc652c5 --- /dev/null +++ b/Workspace_msvc/renderer_configs/split_renderer_config_768_1dof_hoa_lc3plus.txt @@ -0,0 +1,11 @@ +[SPLITREND] +BITRATE = 768000; +DOF = 1; +HQMODE = 0; +CODEC = 1; + +[GENERAL] +RENDERER = CREND; + +[ROOMACOUSTICS] +REVERB = FALSE; diff --git a/Workspace_msvc/renderer_configs/split_renderer_config_768_2dof.txt b/Workspace_msvc/renderer_configs/split_renderer_config_768_2dof.txt new file mode 100644 index 0000000000000000000000000000000000000000..20488df35b2e941cb2d4fa754058ee80aeb1f3f1 --- /dev/null +++ b/Workspace_msvc/renderer_configs/split_renderer_config_768_2dof.txt @@ -0,0 +1,10 @@ +[SPLITREND] +BITRATE = 768000; +DOF = 2; +HQMODE = 0; + +[GENERAL] +RENDERER = CREND; + +[ROOMACOUSTICS] +REVERB = FALSE; diff --git a/Workspace_msvc/renderer_configs/split_renderer_config_fc_384_3dof.txt b/Workspace_msvc/renderer_configs/split_renderer_config_fc_384_3dof.txt new file mode 100644 index 0000000000000000000000000000000000000000..5fbf7f727640f143cc7325b716c2ca6125d68d8e --- /dev/null +++ b/Workspace_msvc/renderer_configs/split_renderer_config_fc_384_3dof.txt @@ -0,0 +1,10 @@ +[SPLITREND] +BITRATE = 384000; +DOF = 3; +HQMODE = 0; + +[GENERAL] +RENDERER = FASTCONV; + +[ROOMACOUSTICS] +REVERB = FALSE; diff --git a/Workspace_msvc/renderer_configs/split_renderer_config_fc_384_3dof_hq.txt b/Workspace_msvc/renderer_configs/split_renderer_config_fc_384_3dof_hq.txt new file mode 100644 index 0000000000000000000000000000000000000000..881f462661e998c6c5793310b01c0173523fec20 --- /dev/null +++ b/Workspace_msvc/renderer_configs/split_renderer_config_fc_384_3dof_hq.txt @@ -0,0 +1,10 @@ +[SPLITREND] +BITRATE = 384000; +DOF = 3; +HQMODE = 1; + +[GENERAL] +RENDERER = FASTCONV; + +[ROOMACOUSTICS] +REVERB = FALSE; \ No newline at end of file diff --git a/Workspace_msvc/renderer_configs/split_renderer_config_fc_512_2dof.txt b/Workspace_msvc/renderer_configs/split_renderer_config_fc_512_2dof.txt new file mode 100644 index 0000000000000000000000000000000000000000..3178a67e3297a50c8dd68b1c769a7891a0eb3555 --- /dev/null +++ b/Workspace_msvc/renderer_configs/split_renderer_config_fc_512_2dof.txt @@ -0,0 +1,10 @@ +[SPLITREND] +BITRATE = 512000; +DOF = 2; +HQMODE = 0; + +[GENERAL] +RENDERER = FASTCONV; + +[ROOMACOUSTICS] +REVERB = FALSE; diff --git a/Workspace_msvc/renderer_configs/split_renderer_config_fc_768_1dof.txt b/Workspace_msvc/renderer_configs/split_renderer_config_fc_768_1dof.txt new file mode 100644 index 0000000000000000000000000000000000000000..bd448d16b3c1a9d4f8e98840c9848894b7bfc2bc --- /dev/null +++ b/Workspace_msvc/renderer_configs/split_renderer_config_fc_768_1dof.txt @@ -0,0 +1,10 @@ +[SPLITREND] +BITRATE = 768000; +DOF = 1; +HQMODE = 0; + +[GENERAL] +RENDERER = FASTCONV; + +[ROOMACOUSTICS] +REVERB = FALSE; diff --git a/Workspace_msvc/renderer_configs/split_renderer_config_pcm_1dof.txt b/Workspace_msvc/renderer_configs/split_renderer_config_pcm_1dof.txt new file mode 100644 index 0000000000000000000000000000000000000000..d956b90ce66f87f1c68f553df439280228658003 --- /dev/null +++ b/Workspace_msvc/renderer_configs/split_renderer_config_pcm_1dof.txt @@ -0,0 +1,10 @@ +[SPLITREND] +BITRATE = 256000; +DOF = 1; +HQMODE = 0; + +[GENERAL] +RENDERER = CREND; + +[ROOMACOUSTICS] +REVERB = FALSE; diff --git a/Workspace_msvc/renderer_configs/split_renderer_config_pcm_2dof.txt b/Workspace_msvc/renderer_configs/split_renderer_config_pcm_2dof.txt new file mode 100644 index 0000000000000000000000000000000000000000..d8eb266458f8f7c09f491051c06f8403593ea991 --- /dev/null +++ b/Workspace_msvc/renderer_configs/split_renderer_config_pcm_2dof.txt @@ -0,0 +1,10 @@ +[SPLITREND] +BITRATE = 384000; +DOF = 2; +HQMODE = 0; + +[GENERAL] +RENDERER = CREND; + +[ROOMACOUSTICS] +REVERB = FALSE; diff --git a/Workspace_msvc/renderer_configs/split_renderer_config_pcm_3dof.txt b/Workspace_msvc/renderer_configs/split_renderer_config_pcm_3dof.txt new file mode 100644 index 0000000000000000000000000000000000000000..e8c9088862bdf564612907c4548dedb07c5a27a3 --- /dev/null +++ b/Workspace_msvc/renderer_configs/split_renderer_config_pcm_3dof.txt @@ -0,0 +1,10 @@ +[SPLITREND] +BITRATE = 512000; +DOF = 3; +HQMODE = 0; + +[GENERAL] +RENDERER = CREND; + +[ROOMACOUSTICS] +REVERB = FALSE; diff --git a/Workspace_msvc/renderer_configs/split_renderer_config_pcm_3dof_hq.txt b/Workspace_msvc/renderer_configs/split_renderer_config_pcm_3dof_hq.txt new file mode 100644 index 0000000000000000000000000000000000000000..6b33fc28cd850f700919931a160ea65607d55429 --- /dev/null +++ b/Workspace_msvc/renderer_configs/split_renderer_config_pcm_3dof_hq.txt @@ -0,0 +1,11 @@ +[SPLITREND] +BITRATE = 768000; +DOF = 3; +HQMODE = 1; +CODEC = 1; + +[GENERAL] +RENDERER = CREND; + +[ROOMACOUSTICS] +REVERB = FALSE; diff --git a/Workspace_msvc/sample_split_rend_script_ivas_enc_dec.py b/Workspace_msvc/sample_split_rend_script_ivas_enc_dec.py new file mode 100644 index 0000000000000000000000000000000000000000..7de05dba013f8f9f2406f2cabf3e0b1e57561405 --- /dev/null +++ b/Workspace_msvc/sample_split_rend_script_ivas_enc_dec.py @@ -0,0 +1,138 @@ +from scipy.io.wavfile import read, write +from scipy import signal +import subprocess +import numpy as np +import sys +import os + +## dimension of following 2 arrays should be same, that is for each file name there should be a tag +file_names = [ +'../scripts/testv/stv3OA48c.wav' +]; +file_tags = [ +'test_HOA3' +]; + +## dimension of following 3 arrays should be same, that is for each pre file there should be a post file and a tag +pre_hr_file_names = [ +'trajectories/pre-renderer_pose_files/pre_yaw20static.csv' +]; +post_hr_file_names = [ +'trajectories/post-renderer_pose_files/post_0static.csv' +]; +hr_file_tags = [ +'yaw20static' +]; + +renderers = [ +('fast_conv_768_1dof', 'renderer_configs/split_renderer_config_fc_768_1dof.txt', '0'), +('fast_conv_512_2dof', 'renderer_configs/split_renderer_config_fc_512_2dof.txt', '0'), +('fast_conv_384_3dof', 'renderer_configs/split_renderer_config_fc_384_3dof.txt', '0'), +('fast_conv_384_3dof_hq', 'renderer_configs/split_renderer_config_fc_384_3dof_hq.txt', '0')]; + + +split_rend_file_outs = ['recons_out_pos0.wav', + 'recons_out_pos1.wav', + 'recons_out_pos2.wav', + 'rotated_ref_pos0.wav', + 'rotated_ref_pos1.wav', + 'rotated_ref_pos2.wav', + 'rotated_ref_RefPos.wav', + 'split_rend_MD_bitrate.txt'] + +def check_and_makedir(dir_path): + if not os.path.exists(dir_path): + try: + os.makedirs(dir_path) + except OSError as e: + if e.errno != errno.EEXIST: + raise # raises the error again + + +def generate_split_rend_lis_items(file_dir, exe_dir, out_dir): + check_and_makedir(out_dir); + for idx in range(0, len(file_tags)): + for hr_idx in range(0, len(hr_file_tags)): + for rend in range(0, len(renderers)): + bitrate = '384000'; + filename = file_names[idx]; + file_in = os.path.join(file_dir, filename); + enc_exe = os.path.join(exe_dir, 'IVAS_cod.exe'); + dec_exe = os.path.join(exe_dir, 'IVAS_dec.exe'); + rend_exe = os.path.join(exe_dir, 'IVAS_rend.exe'); + file_pkt_name = '_'.join([file_tags[idx], bitrate, 'out.pkt']); + file_pkt = os.path.join(out_dir, file_pkt_name); + file_out_name = '_'.join([file_tags[idx], bitrate, renderers[rend][0], 'out.wav']); + file_out = os.path.join(out_dir, file_out_name); + bs_file_out_name = '_'.join([file_tags[idx], '_ivas_dec_out.pkt']); + bs_file_out = os.path.join(out_dir, bs_file_out_name); + + print(file_in) + print(file_pkt) + print(bs_file_out) + print(file_out) + + enc_cmd = [ + enc_exe, + '-sba', '3', + '-max_band', 'FB', + bitrate, + '48', + file_in, + file_pkt + ] + + hr_pre_file_name = pre_hr_file_names[hr_idx]; + hr_pre_file = os.path.join(file_dir, hr_pre_file_name); + hr_post_file_name = post_hr_file_names[hr_idx]; + hr_post_file = os.path.join(file_dir, hr_post_file_name); + + dec_cmd = [ + dec_exe, + '-RENDER_CONFIG', renderers[rend][1], + '-t', hr_pre_file, + 'BINAURAL_SPLIT_CLDFB', + '48', + file_pkt, + bs_file_out + ] + print(enc_cmd) + print(dec_cmd) + test_status = subprocess.call(enc_cmd, shell=False) + test_status = subprocess.call(dec_cmd, shell=False) + + post_rend_cmd = [ + rend_exe, + '-i', bs_file_out, + '-if', 'BINAURAL_SPLIT_CLDFB', + '-o', file_out, + '-of', 'BINAURAL', + '-fs', '48', + '-tf', hr_post_file, + ] + print(post_rend_cmd) + test_status = subprocess.call(post_rend_cmd, shell=False) + + if os.path.isfile(file_pkt): + os.remove(file_pkt) + + if os.path.exists(bs_file_out): + os.remove(bs_file_out); + + for fo in split_rend_file_outs: + file_old = os.path.join(os. getcwd(), fo); + file_out_name = '_'.join([file_tags[idx], hr_file_tags[hr_idx], fo]); + file_new = os.path.join(out_dir, file_out_name); + if os.path.exists(file_old): + os.rename(file_old, file_new); + + +def main(argv): + print('USAGE : python generate_split_rend_lis_items.py file_dir exe_dir out_dir') + if len(argv) < 3: + return print(len(argv)) + return generate_split_rend_lis_items(*argv[1:]) + + +if __name__ == "__main__": + sys.exit(main(sys.argv)) \ No newline at end of file diff --git a/Workspace_msvc/sample_split_rend_script_ivas_rend.py b/Workspace_msvc/sample_split_rend_script_ivas_rend.py new file mode 100644 index 0000000000000000000000000000000000000000..12ed4e09b308e6e6302acd115d65f95168afcab2 --- /dev/null +++ b/Workspace_msvc/sample_split_rend_script_ivas_rend.py @@ -0,0 +1,147 @@ +from scipy.io.wavfile import read, write +from scipy import signal +import subprocess +import numpy as np +import sys +import os + +## dimension of following 2 arrays should be same, that is for each file name there should be a tag +file_names = [ +'../scripts/testv/stv3OA48c.wav' +]; +file_tags = [ +'test_HOA3' +]; + +## dimension of following 3 arrays should be same, that is for each pre file there should be a post file and a tag +pre_hr_file_names = [ +'trajectories/pre-renderer_pose_files/pre_yaw20static.csv' +]; +post_hr_file_names = [ +'trajectories/post-renderer_pose_files/post_0static.csv' +]; +hr_file_tags = [ +'yaw20static' +]; + +renderers = [ +('crend_768_1dof', 'renderer_configs/split_renderer_config_768_1dof.txt', '0'), +('crend_pcm_1dof', 'renderer_configs/split_renderer_config_pcm_1dof.txt', '1'), +('fast_conv_768_1dof', 'renderer_configs/split_renderer_config_fc_768_1dof.txt', '0'), +('crend_512_2dof', 'renderer_configs/split_renderer_config_512_2dof.txt', '0'), +('crend_pcm_2dof', 'renderer_configs/split_renderer_config_pcm_2dof.txt', '1'), +('fast_conv_512_2dof', 'renderer_configs/split_renderer_config_fc_512_2dof.txt', '0'), +('crend_384_3dof', 'renderer_configs/split_renderer_config_384_3dof.txt', '0'), +('crend_pcm_3dof', 'renderer_configs/split_renderer_config_pcm_3dof.txt', '1'), +('fast_conv_384_3dof', 'renderer_configs/split_renderer_config_fc_384_3dof.txt', '0'), +('crend_384_3dof_hq', 'renderer_configs/split_renderer_config_384_3dof_hq.txt', '0'), +('crend_pcm_3dof_hq', 'renderer_configs/split_renderer_config_pcm_3dof_hq.txt', '1'), +('fast_conv_384_3dof_hq', 'renderer_configs/split_renderer_config_fc_384_3dof_hq.txt', '0')]; + +split_md_file_name = 'split_md.bin'; + +split_rend_file_outs = ['recons_out_pos0.wav', + 'recons_out_pos1.wav', + 'recons_out_pos2.wav', + 'rotated_ref_pos0.wav', + 'rotated_ref_pos1.wav', + 'rotated_ref_pos2.wav', + 'rotated_ref_RefPos.wav', + 'split_rend_MD_bitrate.txt'] + + +def check_and_makedir(dir_path): + if not os.path.exists(dir_path): + try: + os.makedirs(dir_path) + except OSError as e: + if e.errno != errno.EEXIST: + raise # raises the error again + + +def generate_split_rend_lis_items(file_dir, exe_dir, out_dir): + check_and_makedir(out_dir); + for idx in range(0, len(file_tags)): + for hr_idx in range(0, len(hr_file_tags)): + for rend in range(0, len(renderers)): + filename = file_names[idx]; + file_in = os.path.join(file_dir, filename); + rend_exe = os.path.join(exe_dir, 'IVAS_rend.exe'); + if renderers[rend][2] == '0': + bs_file_out_name = '_'.join([file_tags[idx], 'out.pkt']); + bs_file_out = os.path.join(out_dir, bs_file_out_name); + out_fmt = 'BINAURAL_SPLIT_CLDFB'; + else: + bs_file_out_name = '_'.join([file_tags[idx], 'out.wav']); + bs_file_out = os.path.join(out_dir, bs_file_out_name); + out_fmt = 'BINAURAL_SPLIT_PCM'; + md_out_arg = ['-om', split_md_file_name]; + md_in_arg = ['-im', split_md_file_name]; + file_out_name = '_'.join([file_tags[idx], renderers[rend][0], 'out.wav']); + file_out = os.path.join(out_dir, file_out_name); + + print(file_in) + print(bs_file_out) + print(file_out) + + hr_pre_file_name = pre_hr_file_names[hr_idx]; + hr_pre_file = os.path.join(file_dir, hr_pre_file_name); + hr_post_file_name = post_hr_file_names[hr_idx]; + hr_post_file = os.path.join(file_dir, hr_post_file_name); + + pre_rend_cmd = [ + rend_exe, + '-rc', renderers[rend][1], + md_out_arg[0], md_out_arg[1], + '-i', file_in, + '-if', 'HOA3', + '-o', bs_file_out, + '-of', out_fmt, + '-fs', '48', + '-tf', hr_pre_file, + ] + + + print(pre_rend_cmd) + test_status = subprocess.call(pre_rend_cmd, shell=False) + + + post_rend_cmd = [ + rend_exe, + md_in_arg[0], md_in_arg[1], + '-i', bs_file_out, + '-if', out_fmt, + '-o', file_out, + '-of', 'BINAURAL', + '-fs', '48', + '-tf', hr_post_file, + ] + + + print(post_rend_cmd) + test_status = subprocess.call(post_rend_cmd, shell=False) + + if os.path.exists(bs_file_out): + os.remove(bs_file_out); + + if os.path.exists(split_md_file_name): + os.remove(split_md_file_name); + + + for fo in split_rend_file_outs: + file_old = os.path.join(os. getcwd(), fo); + file_out_name = '_'.join([file_tags[idx], hr_file_tags[hr_idx], renderers[rend][0], fo]); + file_new = os.path.join(out_dir, file_out_name); + if os.path.exists(file_old): + os.rename(file_old, file_new); + + +def main(argv): + print('USAGE : python generate_split_rend_lis_items.py file_dir exe_dir out_dir') + if len(argv) < 3: + return print(len(argv)) + return generate_split_rend_lis_items(*argv[1:]) + + +if __name__ == "__main__": + sys.exit(main(sys.argv)) \ No newline at end of file diff --git a/Workspace_msvc/sample_split_rend_script_ivas_rend_ism.py b/Workspace_msvc/sample_split_rend_script_ivas_rend_ism.py new file mode 100644 index 0000000000000000000000000000000000000000..a6bd2c04a4c6497a9b35b5b9011d522a539fdde8 --- /dev/null +++ b/Workspace_msvc/sample_split_rend_script_ivas_rend_ism.py @@ -0,0 +1,151 @@ +from scipy.io.wavfile import read, write +from scipy import signal +import subprocess +import numpy as np +import sys +import os + +## dimension of following 2 arrays should be same, that is for each file name there should be a tag +file_names = [ +'../scripts/testv/stv4ISM48s.wav' +]; +ism_md_file_names = [ +'../scripts/testv/stvISM1.csv', +'../scripts/testv/stvISM2.csv', +'../scripts/testv/stvISM3.csv', +'../scripts/testv/stvISM4.csv' +]; +file_tags = [ +'test_ISM' +]; + +## dimension of following 3 arrays should be same, that is for each pre file there should be a post file and a tag +pre_hr_file_names = [ +'trajectories/pre-renderer_pose_files/pre_yaw20static.csv' +]; +post_hr_file_names = [ +'trajectories/post-renderer_pose_files/post_0static.csv' +]; +hr_file_tags = [ +'yaw20static' +]; + +renderers = [ +('crend_768_1dof', 'renderer_configs/split_renderer_config_768_1dof.txt', '0'), +('crend_pcm_1dof', 'renderer_configs/split_renderer_config_pcm_1dof.txt', '1'), +('crend_512_2dof', 'renderer_configs/split_renderer_config_512_2dof.txt', '0'), +('crend_pcm_2dof', 'renderer_configs/split_renderer_config_pcm_2dof.txt', '1'), +('crend_384_3dof', 'renderer_configs/split_renderer_config_384_3dof.txt', '0'), +('crend_pcm_3dof', 'renderer_configs/split_renderer_config_pcm_3dof.txt', '1'), +('crend_384_3dof_hq', 'renderer_configs/split_renderer_config_384_3dof_hq.txt', '0'), +('crend_pcm_3dof_hq', 'renderer_configs/split_renderer_config_pcm_3dof_hq.txt', '1'), +('crend_lc3plus_1dof', 'renderer_configs/split_renderer_config_768_1dof_hoa_lc3plus.txt', '0')]; + +split_md_file_name = 'split_md.bin'; + +split_rend_file_outs = ['recons_out_pos0.wav', + 'recons_out_pos1.wav', + 'recons_out_pos2.wav', + 'rotated_ref_pos0.wav', + 'rotated_ref_pos1.wav', + 'rotated_ref_pos2.wav', + 'rotated_ref_RefPos.wav', + 'split_rend_MD_bitrate.txt'] + + +def check_and_makedir(dir_path): + if not os.path.exists(dir_path): + try: + os.makedirs(dir_path) + except OSError as e: + if e.errno != errno.EEXIST: + raise # raises the error again + + +def generate_split_rend_lis_items(file_dir, exe_dir, out_dir): + check_and_makedir(out_dir); + for idx in range(0, len(file_tags)): + for hr_idx in range(0, len(hr_file_tags)): + for rend in range(0, len(renderers)): + filename = file_names[idx]; + file_in = os.path.join(file_dir, filename); + rend_exe = os.path.join(exe_dir, 'IVAS_rend.exe'); + if renderers[rend][2] == '0': + bs_file_out_name = '_'.join([file_tags[idx], 'out.pkt']); + bs_file_out = os.path.join(out_dir, bs_file_out_name); + out_fmt = 'BINAURAL_SPLIT_CLDFB'; + else: + bs_file_out_name = '_'.join([file_tags[idx], 'out.wav']); + bs_file_out = os.path.join(out_dir, bs_file_out_name); + out_fmt = 'BINAURAL_SPLIT_PCM'; + md_out_arg = ['-om', split_md_file_name]; + md_in_arg = ['-im', split_md_file_name]; + file_out_name = '_'.join([file_tags[idx], renderers[rend][0], 'out.wav']); + file_out = os.path.join(out_dir, file_out_name); + + print(file_in) + print(bs_file_out) + print(file_out) + + hr_pre_file_name = pre_hr_file_names[hr_idx]; + hr_pre_file = os.path.join(file_dir, hr_pre_file_name); + hr_post_file_name = post_hr_file_names[hr_idx]; + hr_post_file = os.path.join(file_dir, hr_post_file_name); + + pre_rend_cmd = [ + rend_exe, + '-rc', renderers[rend][1], + md_out_arg[0], md_out_arg[1], + '-i', file_in, + '-if', 'ISM4', + '-im', ism_md_file_names[0], ism_md_file_names[1], ism_md_file_names[2], ism_md_file_names[3], + '-o', bs_file_out, + '-of', out_fmt, + '-fs', '48', + '-tf', hr_pre_file, + ] + + + print(pre_rend_cmd) + test_status = subprocess.call(pre_rend_cmd, shell=False) + + + post_rend_cmd = [ + rend_exe, + md_in_arg[0], md_in_arg[1], + '-i', bs_file_out, + '-if', out_fmt, + '-o', file_out, + '-of', 'BINAURAL', + '-fs', '48', + '-tf', hr_post_file, + ] + + + print(post_rend_cmd) + test_status = subprocess.call(post_rend_cmd, shell=False) + + if os.path.exists(bs_file_out): + os.remove(bs_file_out); + + if os.path.exists(split_md_file_name): + os.remove(split_md_file_name); + + + for fo in split_rend_file_outs: + file_old = os.path.join(os. getcwd(), fo); + file_out_name = '_'.join([file_tags[idx], hr_file_tags[hr_idx], renderers[rend][0], fo]); + file_new = os.path.join(out_dir, file_out_name); + if os.path.exists(file_old): + os.rename(file_old, file_new); + + +def main(argv): + print('USAGE : python generate_split_rend_lis_items.py file_dir exe_dir out_dir') + if len(argv) < 3: + return print(len(argv)) + return generate_split_rend_lis_items(*argv[1:]) + + +if __name__ == "__main__": + sys.exit(main(sys.argv)) \ No newline at end of file diff --git a/Workspace_msvc/trajectories/post-renderer_pose_files/post_0static.csv b/Workspace_msvc/trajectories/post-renderer_pose_files/post_0static.csv new file mode 100644 index 0000000000000000000000000000000000000000..a292a3576cb618ab5e54ea2725829b0a714a880d --- /dev/null +++ b/Workspace_msvc/trajectories/post-renderer_pose_files/post_0static.csv @@ -0,0 +1,4 @@ +-3,0,0,0 +-3,0,0,0 +-3,0,0,0 +-3,0,0,0 diff --git a/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_pitch-20static.csv b/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_pitch-20static.csv new file mode 100644 index 0000000000000000000000000000000000000000..dab3c6940a8c9120f336d937d31a79571751717a --- /dev/null +++ b/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_pitch-20static.csv @@ -0,0 +1,4 @@ +-3,0,-20,0 +-3,0,-20,0 +-3,0,-20,0 +-3,0,-20,0 diff --git a/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_pitch20static.csv b/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_pitch20static.csv new file mode 100644 index 0000000000000000000000000000000000000000..ae6ac9cd9c01ae1f31eed8e587271798cf1783ee --- /dev/null +++ b/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_pitch20static.csv @@ -0,0 +1,4 @@ +-3,0,20,0 +-3,0,20,0 +-3,0,20,0 +-3,0,20,0 diff --git a/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_roll-20static.csv b/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_roll-20static.csv new file mode 100644 index 0000000000000000000000000000000000000000..5db0b1cab3cd39b4031c8a19addf2da94ad31fec --- /dev/null +++ b/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_roll-20static.csv @@ -0,0 +1,4 @@ +-3,0,0,-20 +-3,0,0,-20 +-3,0,0,-20 +-3,0,0,-20 diff --git a/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_roll20static.csv b/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_roll20static.csv new file mode 100644 index 0000000000000000000000000000000000000000..5bd8c2c4d9bc33270f0561d4dea903e4969953a9 --- /dev/null +++ b/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_roll20static.csv @@ -0,0 +1,4 @@ +-3,0,0,20 +-3,0,0,20 +-3,0,0,20 +-3,0,0,20 diff --git a/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_yaw-20pitch-20static.csv b/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_yaw-20pitch-20static.csv new file mode 100644 index 0000000000000000000000000000000000000000..e48c0a58f5dafd8ef4c181d36c6d345e5de7384c --- /dev/null +++ b/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_yaw-20pitch-20static.csv @@ -0,0 +1,4 @@ +-3,-20,-20,0 +-3,-20,-20,0 +-3,-20,-20,0 +-3,-20,-20,0 diff --git a/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_yaw-20static.csv b/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_yaw-20static.csv new file mode 100644 index 0000000000000000000000000000000000000000..6e446847a9dbde7ef74ff1ecc79c91bba46b7696 --- /dev/null +++ b/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_yaw-20static.csv @@ -0,0 +1,4 @@ +-3,-20,0,0 +-3,-20,0,0 +-3,-20,0,0 +-3,-20,0,0 diff --git a/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_yaw20pitch20static.csv b/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_yaw20pitch20static.csv new file mode 100644 index 0000000000000000000000000000000000000000..58788cc7dee341d398b93986a5f1f9db72010203 --- /dev/null +++ b/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_yaw20pitch20static.csv @@ -0,0 +1,4 @@ +-3,20,20,0 +-3,20,20,0 +-3,20,20,0 +-3,20,20,0 diff --git a/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_yaw20static.csv b/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_yaw20static.csv new file mode 100644 index 0000000000000000000000000000000000000000..2d674f971b1d6bdebc2cfe931196defdd159bcfd --- /dev/null +++ b/Workspace_msvc/trajectories/pre-renderer_pose_files/pre_yaw20static.csv @@ -0,0 +1,4 @@ +-3,20,0,0 +-3,20,0,0 +-3,20,0,0 +-3,20,0,0 diff --git a/apps/decoder.c b/apps/decoder.c index e210ebe95e7e431d4b3fa2684ee1594545e48831..939085acd155997e4c125b8a111b1467ad6d4ddc 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -33,6 +33,7 @@ #include #include #include +#include "assert.h" #include "options.h" #include "lib_dec.h" #include "cmdl_tools.h" @@ -54,6 +55,9 @@ #endif #include "wmc_auto.h" #include "render_config_reader.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "split_render_file_read_write.h" +#endif #include "hrtf_file_reader.h" @@ -70,10 +74,18 @@ static #define MIN_NUM_BITS_ACTIVE_FRAME 56 #define NUM_BITS_SID_IVAS_5K2 104 -#define MAX_FRAME_SIZE ( 48000 / 50 ) +#define NUM_FRAMES_PER_SEC 50 +#define MAX_FRAME_SIZE ( 48000 / NUM_FRAMES_PER_SEC ) #define MAX_NUM_OUTPUT_CHANNELS 16 #define MAX_OUTPUT_PCM_BUFFER_SIZE ( MAX_NUM_OUTPUT_CHANNELS * MAX_FRAME_SIZE ) - +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef SPLIT_REND_LC3PLUS +#define MAX_SPLIT_REND_BITRATE ( 1792000 ) /* TODO tmu: unify with SPLIT_REND_MAX_BRATE ?*/ +#else +#define MAX_SPLIT_REND_BITRATE ( 768000 ) +#endif +#define MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES ( ( ( (int32_t) MAX_SPLIT_REND_BITRATE / NUM_FRAMES_PER_SEC ) + 7 ) >> 3 ) +#endif #define IVAS_PUBLIC_ORIENT_TRK_NONE ( 0 ) #define IVAS_PUBLIC_ORIENT_TRK_REF ( 1 ) #define IVAS_PUBLIC_ORIENT_TRK_AVG ( 2 ) @@ -121,6 +133,9 @@ typedef struct float non_diegetic_pan_gain; bool renderConfigEnabled; char *renderConfigFilename; +#ifdef SPLIT_REND_WITH_HEAD_ROT + char *outputMdFilename; +#endif IVAS_DEC_COMPLEXITY_LEVEL complexityLevel; #ifdef DEBUGGING @@ -141,7 +156,6 @@ typedef struct uint16_t frontendFetchSizeMs; #endif #endif - } DecArguments; @@ -151,7 +165,13 @@ typedef struct static bool parseCmdlIVAS_dec( int16_t argc, char **argv, DecArguments *arg ); static void usage_dec( void ); -static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); + +static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, +#ifdef SPLIT_REND_WITH_HEAD_ROT + uint8_t *splitRendBitsBuf, +#endif + IVAS_DEC_HANDLE hIvasDec, + int16_t *pcmBuf ); static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, IVAS_DEC_HANDLE hIvasDec ); #ifdef DEBUGGING #ifdef VARIABLE_SPEED_DECODING @@ -185,6 +205,9 @@ int main( Vector3PairFileReader *referenceVectorReader = NULL; ivas_error error = IVAS_ERR_UNKNOWN; int16_t pcmBuf[MAX_OUTPUT_PCM_BUFFER_SIZE]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + uint8_t splitRendBitsBuf[MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES]; +#endif RenderConfigReader *renderConfigReader = NULL; #ifdef DEBUGGING int32_t noClipping; @@ -279,7 +302,11 @@ int main( if ( arg.enableHeadRotation ) { /* sanity check */ - if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM_IR && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM_REVERB ) + if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM_IR && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + && arg.outputFormat != IVAS_DEC_OUTPUT_SPLIT_BINAURAL_CLDFB && arg.outputFormat != IVAS_DEC_OUTPUT_SPLIT_BINAURAL_PCM +#endif + ) { fprintf( stderr, "\nError: Head-rotation file file cannot be used in this output configuration.\n\n" ); goto cleanup; @@ -379,7 +406,11 @@ int main( if ( arg.renderConfigEnabled ) { /* sanity check */ - if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM_IR && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM_REVERB ) + if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM_IR && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + && arg.outputFormat != IVAS_DEC_OUTPUT_SPLIT_BINAURAL_CLDFB && arg.outputFormat != IVAS_DEC_OUTPUT_SPLIT_BINAURAL_PCM +#endif + ) { fprintf( stderr, "\nError: Renderer configuration file cannot be used in this output configuration.\n\n" ); goto cleanup; @@ -395,8 +426,13 @@ int main( /*------------------------------------------------------------------------------------------* * Configure the decoder *------------------------------------------------------------------------------------------*/ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( arg.outputFormat == IVAS_DEC_OUTPUT_SPLIT_BINAURAL_CLDFB || arg.outputFormat == IVAS_DEC_OUTPUT_SPLIT_BINAURAL_PCM ) + { + arg.enableHeadRotation = true; + } +#endif if ( ( error = IVAS_DEC_Configure( hIvasDec, arg.output_Fs, arg.outputFormat, arg.customLsOutputEnabled, arg.hrtfReaderEnabled, arg.enableHeadRotation, arg.enableExternalOrientation, arg.orientation_tracking, arg.renderConfigEnabled, arg.Opt_non_diegetic_pan, arg.non_diegetic_pan_gain, arg.delayCompensationEnabled ) ) != IVAS_ERR_OK ) - { fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -543,11 +579,21 @@ int main( IVAS_RENDER_CONFIG_DATA renderConfig; /* sanity check */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM_IR && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM_REVERB && + arg.outputFormat != IVAS_DEC_OUTPUT_SPLIT_BINAURAL_CLDFB && + arg.outputFormat != IVAS_DEC_OUTPUT_SPLIT_BINAURAL_PCM ) + { + fprintf( stderr, "\nExternal Renderer Config is supported only when binaural output configurations is used as output OR when Split rendering mode is enabled. Exiting. \n" ); + exit( -1 ); + } +#else if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM_IR && arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM_REVERB ) { fprintf( stderr, "\nExternal Renderer Config is supported only for binaural output configurations. Exiting. \n\n" ); goto cleanup; } +#endif if ( ( error = IVAS_DEC_GetRenderConfig( hIvasDec, &renderConfig ) ) != IVAS_ERR_OK ) { @@ -651,7 +697,11 @@ int main( { error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, - refRotReader, referenceVectorReader, hIvasDec, pcmBuf ); + refRotReader, referenceVectorReader, +#ifdef SPLIT_REND_WITH_HEAD_ROT + splitRendBitsBuf, +#endif + hIvasDec, pcmBuf ); } if ( error == IVAS_ERR_OK || error == IVAS_ERR_END_OF_FILE ) @@ -803,6 +853,16 @@ static IVAS_DEC_AUDIO_CONFIG cmdline2config( { output_config = IVAS_DEC_OUTPUT_BINAURAL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + else if ( strcmp( argv_to_upper, "BINAURAL_SPLIT_CLDFB" ) == 0 ) + { + output_config = IVAS_DEC_OUTPUT_SPLIT_BINAURAL_CLDFB; + } + else if ( strcmp( argv_to_upper, "BINAURAL_SPLIT_PCM" ) == 0 ) + { + output_config = IVAS_DEC_OUTPUT_SPLIT_BINAURAL_PCM; + } +#endif else if ( strcmp( argv_to_upper, "BINAURAL_ROOM_IR" ) == 0 ) { output_config = IVAS_DEC_OUTPUT_BINAURAL_ROOM_IR; @@ -819,7 +879,6 @@ static IVAS_DEC_AUDIO_CONFIG cmdline2config( return output_config; } - /*---------------------------------------------------------------------* * parseCmdlIVAS_dec() * @@ -879,6 +938,10 @@ static bool parseCmdlIVAS_dec( arg->renderConfigEnabled = false; arg->renderConfigFilename = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + arg->outputMdFilename = NULL; +#endif + arg->inputFormat = IVAS_DEC_INPUT_FORMAT_G192; arg->Opt_non_diegetic_pan = 0; arg->non_diegetic_pan_gain = 0.f; @@ -1196,6 +1259,19 @@ static bool parseCmdlIVAS_dec( } i += 2; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + else if ( strcmp( argv_to_upper, "-OM" ) == 0 ) + { + arg->outputMdFilename = argv[i + 1]; + if ( arg->outputMdFilename[0] == '\0' ) + { + fprintf( stderr, "Error: output metadata file path not specified\n\n" ); + usage_dec(); + return false; + } + i += 2; + } +#endif else if ( strcmp( argv_to_upper, "-NON_DIEGETIC_PAN" ) == 0 ) { i++; @@ -1355,8 +1431,13 @@ static void usage_dec( void ) fprintf( stdout, "Mandatory parameters:\n" ); fprintf( stdout, "---------------------\n" ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + fprintf( stdout, "OutputConf : Output configuration: MONO, STEREO, 5_1, 7_1, 5_1_2, 5_1_4, 7_1_4, FOA,\n" ); + fprintf( stdout, " HOA2, HOA3, BINAURAL, BINAURAL_ROOM_IR, BINAURAL_ROOM_REVERB, BINAURAL_SPLIT_CLDFB, BINAURAL_SPLIT_PCM, EXT\n" ); +#else fprintf( stdout, "OutputConf : Output configuration: MONO, STEREO, 5_1, 7_1, 5_1_2, 5_1_4, 7_1_4, FOA,\n" ); fprintf( stdout, " HOA2, HOA3, BINAURAL, BINAURAL_ROOM_IR, BINAURAL_ROOM_REVERB, EXT\n" ); +#endif fprintf( stdout, " By default, channel order and loudspeaker positions are equal to the\n" ); fprintf( stdout, " encoder. For loudspeaker outputs, OutputConf can be a custom loudspeaker\n" ); fprintf( stdout, " layout file. See readme.txt for details.\n" ); @@ -1407,6 +1488,9 @@ static void usage_dec( void ) fprintf( stdout, "-rvf File : Reference vector specified by external trajectory file\n" ); fprintf( stdout, " works only in combination with '-otr ref_vec' and 'ref_vec_lev' modes\n" ); fprintf( stdout, "-render_config File : Renderer configuration File\n" ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + fprintf( stdout, "-om File : MD output file for BINAURAL_SPLIT_PCM output format\n" ); +#endif fprintf( stdout, "-non_diegetic_pan P : panning mono non-diegetic sound to stereo with paning P, -90<= P <=90,\n" ); fprintf( stdout, " left or l or 90->left, right or r or -90->right, center or c or 0->middle\n" ); fprintf( stdout, "-q : Quiet mode, no frame counter\n" ); @@ -1461,6 +1545,10 @@ static ivas_error initOnFirstGoodFrame( IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS], /* o : */ int16_t *pNumOutChannels, /* o : */ uint16_t *pNumObj /* o : */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + SplitFileReadWrite **hSplitRendFileReadWrite +#endif ) { ivas_error error = IVAS_ERR_UNKNOWN; @@ -1471,6 +1559,13 @@ static ivas_error initOnFirstGoodFrame( fprintf( stderr, "\nUnable to get delay of decoder: %s\n", ivas_error_to_string( error ) ); return error; } +#ifdef SPLIT_REND_CLDFB_ISM + if ( ( arg.outputFormat == IVAS_DEC_OUTPUT_SPLIT_BINAURAL_PCM ) || + ( arg.outputFormat == IVAS_DEC_OUTPUT_SPLIT_BINAURAL_CLDFB ) ) + { + pFullDelayNumSamples[0] = 0; + } +#endif if ( !arg.delayCompensationEnabled ) { @@ -1478,6 +1573,7 @@ static ivas_error initOnFirstGoodFrame( } *pRemainingDelayNumSamples = pFullDelayNumSamples[0]; + if ( ( error = IVAS_DEC_GetNumOutputChannels( hIvasDec, pNumOutChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in IVAS_DEC_GetNumOutputChannels, code: %d\n", error ); @@ -1492,11 +1588,45 @@ static ivas_error initOnFirstGoodFrame( return error; } - /* Open audio writer and write all previously skipped bad frames now that frame size is known */ - if ( ( error = AudioFileWriter_open( ppAfWriter, arg.outputWavFilename, arg.output_Fs, *pNumOutChannels ) ) != IVAS_ERR_OK ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( arg.outputFormat == IVAS_DEC_OUTPUT_SPLIT_BINAURAL_CLDFB ) { - fprintf( stderr, "\nUnable to open output file %s\n", arg.outputWavFilename ); - return error; + int16_t delayNumSamples_temp[3]; + int32_t delayTimeScale_temp; + IVAS_DEC_GetDelay( hIvasDec, delayNumSamples_temp, &delayTimeScale_temp ); + error = split_rend_writer_open( hSplitRendFileReadWrite, arg.outputWavFilename, delayNumSamples_temp[0], delayTimeScale_temp ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", arg.outputWavFilename ); + exit( -1 ); + } + *ppAfWriter = NULL; + } + else +#endif + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( arg.outputFormat == IVAS_DEC_OUTPUT_SPLIT_BINAURAL_PCM ) + { + int16_t delayNumSamples_temp[3]; + int32_t delayTimeScale_temp; + IVAS_DEC_GetDelay( hIvasDec, delayNumSamples_temp, &delayTimeScale_temp ); + assert( arg.outputMdFilename != NULL ); + error = split_rend_writer_open( hSplitRendFileReadWrite, arg.outputMdFilename, delayNumSamples_temp[0], delayTimeScale_temp ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", arg.outputWavFilename ); + exit( -1 ); + } + } +#endif + + /* Open audio writer and write all previously skipped bad frames now that frame size is known */ + if ( ( error = AudioFileWriter_open( ppAfWriter, arg.outputWavFilename, arg.output_Fs, *pNumOutChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to open output file %s\n", arg.outputWavFilename ); + return error; + } } int16_t *zeroBuf = malloc( pcmFrameSize * sizeof( int16_t ) ); @@ -1504,18 +1634,39 @@ static ivas_error initOnFirstGoodFrame( for ( int16_t i = 0; i < numInitialBadFrames; ++i ) { - if ( *pRemainingDelayNumSamples < numOutSamples ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( *hSplitRendFileReadWrite != NULL ) { - if ( ( error = AudioFileWriter_write( *ppAfWriter, zeroBuf, numOutSamples * *pNumOutChannels - ( *pRemainingDelayNumSamples * *pNumOutChannels ) ) ) != IVAS_ERR_OK ) + IVAS_SPLIT_REND_BITS splitRendBitsZero; + splitRendBitsZero.bits_written = 0; + splitRendBitsZero.bits_read = 0; + if ( split_rend_write_bitstream_to_file( *hSplitRendFileReadWrite, splitRendBitsZero.bits_buf, &splitRendBitsZero.bits_read, &splitRendBitsZero.bits_written +#ifdef SPLIT_REND_LC3PLUS + , + -1, IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE +#endif + ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nOutput audio file writer error\n" ); - return error; + fprintf( stderr, "\nUnable to write to bitstream file!\n" ); + exit( -1 ); } - *pRemainingDelayNumSamples = 0; } else +#endif { - *pRemainingDelayNumSamples -= numOutSamples; + if ( *pRemainingDelayNumSamples < numOutSamples ) + { + if ( ( error = AudioFileWriter_write( *ppAfWriter, zeroBuf, numOutSamples * *pNumOutChannels - ( *pRemainingDelayNumSamples * *pNumOutChannels ) ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + return error; + } + *pRemainingDelayNumSamples = 0; + } + else + { + *pRemainingDelayNumSamples -= numOutSamples; + } } } @@ -1617,6 +1768,9 @@ static ivas_error decodeG192( RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, +#ifdef SPLIT_REND_WITH_HEAD_ROT + uint8_t *splitRendBitsBuf, +#endif IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ) @@ -1642,6 +1796,11 @@ static ivas_error decodeG192( IVAS_DEC_BS_FORMAT bsFormat = IVAS_DEC_BS_UNKOWN; IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_BITS splitRendBits; + SplitFileReadWrite *hSplitRendFileReadWrite; +#endif + IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS]; for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) { @@ -1665,6 +1824,14 @@ static ivas_error decodeG192( reset_wmops(); #endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + splitRendBits.bits_buf = splitRendBitsBuf; + splitRendBits.bits_read = 0; + splitRendBits.bits_written = 0; + splitRendBits.buf_len = MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES; + hSplitRendFileReadWrite = NULL; +#endif + /*------------------------------------------------------------------------------------------* * Loop for every packet (frame) of bitstream data * - Read the bitstream packet @@ -1745,18 +1912,37 @@ static ivas_error decodeG192( if ( arg.enableHeadRotation ) { IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; - - for ( i = 0; i < IVAS_MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( headRotReader == NULL ) { - if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK ) + for ( i = 0; i < IVAS_MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { - fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), - RotationFileReader_getFilePath( headRotReader ) ); - goto cleanup; + Quaternions[i].w = -3.0f; + Quaternions[i].x = 0.0f; + Quaternions[i].y = 0.0f; + Quaternions[i].z = 0.0f; + } + } + else +#endif + { + for ( i = 0; i < IVAS_MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError %s while reading head orientation from %s\n", IVAS_DEC_GetErrorMessage( error ), + RotationFileReader_getFilePath( headRotReader ) ); + goto cleanup; + } } } - if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions, Pos ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions, Pos +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + DEFAULT_AXIS +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -1790,7 +1976,12 @@ static ivas_error decodeG192( } /* Run decoder for one frame (get rendered output) */ - if ( ( error = IVAS_DEC_GetSamples( hIvasDec, pcmBuf, &nOutSamples ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, pcmBuf, &nOutSamples +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + &splitRendBits +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError: could not get samples from decoder: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -1821,7 +2012,12 @@ static ivas_error decodeG192( &masaWriter, ismWriters, &nOutChannels, - &numObj ); + &numObj +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + &hSplitRendFileReadWrite +#endif + ); if ( error != IVAS_ERR_OK ) { goto cleanup; @@ -1836,18 +2032,51 @@ static ivas_error decodeG192( /* Write current frame */ if ( decodedGoodFrame ) { - if ( delayNumSamples < nOutSamples ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( hSplitRendFileReadWrite != NULL ) && ( arg.outputFormat == IVAS_DEC_OUTPUT_SPLIT_BINAURAL_CLDFB ) ) { - if ( ( error = AudioFileWriter_write( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK ) + if ( split_rend_write_bitstream_to_file( hSplitRendFileReadWrite, splitRendBits.bits_buf, &splitRendBits.bits_read, &splitRendBits.bits_written +#ifdef SPLIT_REND_LC3PLUS + , + splitRendBits.codec, splitRendBits.pose_correction +#endif + ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nOutput audio file writer error\n" ); - goto cleanup; + fprintf( stderr, "\nUnable to write to bitstream file!\n" ); + exit( -1 ); } - delayNumSamples = 0; } else +#endif { - delayNumSamples -= nOutSamples; +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( hSplitRendFileReadWrite != NULL ) && ( arg.outputFormat == IVAS_DEC_OUTPUT_SPLIT_BINAURAL_PCM ) ) + { + if ( split_rend_write_bitstream_to_file( hSplitRendFileReadWrite, splitRendBits.bits_buf, &splitRendBits.bits_read, &splitRendBits.bits_written +#ifdef SPLIT_REND_LC3PLUS + , + splitRendBits.codec, splitRendBits.pose_correction +#endif + ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to write to bitstream file!\n" ); + exit( -1 ); + } + } +#endif + if ( delayNumSamples < nOutSamples ) + { + if ( ( error = AudioFileWriter_write( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + goto cleanup; + } + delayNumSamples = 0; + } + else + { + delayNumSamples -= nOutSamples; + } } } @@ -1923,10 +2152,13 @@ static ivas_error decodeG192( memset( pcmBuf, 0, delayNumSamples_orig[0] * nOutChannels * sizeof( int16_t ) ); - if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK ) + if ( afWriter != NULL ) { - fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) ); - goto cleanup; + if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) ); + goto cleanup; + } } /*------------------------------------------------------------------------------------------* @@ -1968,8 +2200,16 @@ static ivas_error decodeG192( decodingFailed = false; /* This will stay set to true if cleanup is reached via a goto due to an error */ cleanup: - - AudioFileWriter_close( &afWriter ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( hSplitRendFileReadWrite != NULL ) + { + split_rend_reader_writer_close( &hSplitRendFileReadWrite ); + } + if ( afWriter != NULL ) +#endif + { + AudioFileWriter_close( &afWriter ); + } MasaFileWriter_close( &masaWriter ); for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; i++ ) { @@ -2354,6 +2594,10 @@ static ivas_error decodeVoIP( /* Once good frame decoded, catch up */ if ( decodedGoodFrame ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + + SplitFileReadWrite *hSplitRendFileReadWrite = NULL; +#endif error = initOnFirstGoodFrame( hIvasDec, arg, @@ -2367,7 +2611,12 @@ static ivas_error decodeVoIP( &masaWriter, ismWriters, &nOutChannels, - &numObj ); + &numObj +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + &hSplitRendFileReadWrite +#endif + ); if ( error != IVAS_ERR_OK ) { goto cleanup; @@ -2662,7 +2911,12 @@ static ivas_error decodeVariableSpeed( } } - if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions, Pos ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions, Pos +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + DEFAULT_AXIS +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -2776,6 +3030,10 @@ static ivas_error decodeVariableSpeed( /* Once good frame decoded, catch up */ if ( decodedGoodFrame ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + + SplitFileReadWrite *hSplitRendFileReadWrite = NULL; +#endif error = initOnFirstGoodFrame( hIvasDec, arg, @@ -2789,7 +3047,12 @@ static ivas_error decodeVariableSpeed( &masaWriter, ismWriters, &nOutChannels, - &numObj ); + &numObj +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + &hSplitRendFileReadWrite +#endif + ); if ( error != IVAS_ERR_OK ) { goto cleanup; @@ -2946,7 +3209,12 @@ static ivas_error decodeVariableSpeed( } } - if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions, Pos ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions, Pos +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + DEFAULT_AXIS +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; diff --git a/apps/renderer.c b/apps/renderer.c index 760065be91e705a12c149d81775f2e8da7178ff0..967f6ce946e049b652ab413e5bc2a80a20662c8a 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -31,6 +31,12 @@ *******************************************************************************************************/ #include "lib_rend.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "split_render_file_read_write.h" +#endif +#ifdef SPLIT_REND_PLC +#include "split_rend_bfi_file_reader.h" +#endif #include #include #include @@ -61,6 +67,10 @@ #define RENDERER_MAX_METADATA_LENGTH 8192 #define RENDERER_MAX_METADATA_LINE_LENGTH 1024 +#ifdef SPLIT_REND_CLDFB_HUFF_SAN_FIX +#define SPLIT_REND_BITS_BUFF_SIZE ( ( ( ( (int32_t) SPLIT_REND_MAX_BRATE / FRAMES_PER_SEC ) + 7 ) >> 3 ) + SPLIT_REND_ADDITIONAL_BYTES_TO_READ ) +#endif + #if !defined( DEBUGGING ) && !defined( WMOPS ) static #endif @@ -120,6 +130,10 @@ typedef struct IVAS_CUSTOM_LS_DATA inSetupCustom; RendererInput masaBuses[RENDERER_MAX_MASA_INPUTS]; uint16_t numMasaBuses; +#ifdef SPLIT_REND_WITH_HEAD_ROT + RendererInput binBuses[RENDERER_MAX_BIN_INPUTS]; + uint16_t numBinBuses; +#endif } InputConfig; typedef struct @@ -138,7 +152,13 @@ typedef struct OutputConfig outConfig; char inMetadataFilePaths[RENDERER_MAX_ISM_INPUTS][RENDERER_MAX_CLI_ARG_LENGTH]; int16_t numInMetadataFiles; +#ifdef SPLIT_REND_WITH_HEAD_ROT + char outMetadataFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; +#endif char headRotationFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; +#ifdef SPLIT_REND_PLC + char splitRendBFIFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; +#endif char referenceVectorFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; char referenceRotationFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; char externalOrientationFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; @@ -179,6 +199,12 @@ typedef enum CmdLnOptionId_inputMetadata, CmdLnOptionId_listFormats, CmdLnOptionId_inputGain, +#ifdef SPLIT_REND_WITH_HEAD_ROT + CmdLnOptionId_outputMetadata, +#endif +#ifdef SPLIT_REND_PLC + CmdLnOptionId_SplitRendBFIFile, +#endif CmdLnOptionId_referenceVectorFile, CmdLnOptionId_exteriorOrientationFile, } CmdLnOptionId; @@ -200,7 +226,11 @@ static const CmdLnParser_Option cliOptions[] = { .id = CmdLnOptionId_inputMetadata, .match = "input_metadata", .matchShort = "im", +#ifdef SPLIT_REND_WITH_HEAD_ROT + .description = "Space-separated list of path to metadata files for ISM or MASA inputs or BINAURAL_SPLIT_PCM input mode", +#else .description = "Space-separated list of path to metadata files for ISM or MASA inputs", +#endif }, { .id = CmdLnOptionId_outputFile, @@ -226,6 +256,22 @@ static const CmdLnParser_Option cliOptions[] = { .matchShort = "tf", .description = "Head rotation trajectory file for simulation of head tracking (only for binaural outputs)", }, +#ifdef SPLIT_REND_WITH_HEAD_ROT + { + .id = CmdLnOptionId_outputMetadata, + .match = "output_metadata", + .matchShort = "om", + .description = "coded metadata file for BINAURAL_SPLIT_PCM output mode", + }, +#endif +#ifdef SPLIT_REND_PLC + { + .id = CmdLnOptionId_SplitRendBFIFile, + .match = "post_rend_bfi_file", + .matchShort = "prbfi", + .description = "Split rendering option: bfi file", + }, +#endif { .id = CmdLnOptionId_refRotFile, .match = "reference_rotation_file", @@ -354,10 +400,21 @@ static void printSupportedAudioConfigs( void ); static IVAS_REND_AudioConfig parseAudioConfig( const char *configString ); -static void convertInputBuffer( const int16_t *intBuffer, const int16_t numIntSamplesPerChannel, const int16_t numFloatSamplesPerChannel, const int16_t numChannels, float *floatBuffer ); - -static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer ); +static void convertInputBuffer( const int16_t *intBuffer, const int16_t numIntSamplesPerChannel, const int16_t numFloatSamplesPerChannel, const int16_t numChannels, float *floatBuffer +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + const int16_t cldfb_in, + HANDLE_CLDFB_FILTER_BANK *cldfbAna +#endif +); +static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + const int16_t cldfb_in, + HANDLE_CLDFB_FILTER_BANK *cldfbSyn +#endif +); /*------------------------------------------------------------------------------------------* * Local functions @@ -383,7 +440,12 @@ static int16_t getTotalNumInChannels( IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS], IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS], IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS], - IVAS_REND_InputId masaIds[RENDERER_MAX_MASA_INPUTS] ) + IVAS_REND_InputId masaIds[RENDERER_MAX_MASA_INPUTS] +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + IVAS_REND_InputId splitBinIds[RENDERER_MAX_BIN_INPUTS] +#endif +) { int16_t totalNumInChannels = 0; int16_t i, numInputChannels; @@ -455,6 +517,24 @@ static int16_t getTotalNumInChannels( totalNumInChannels += numInputChannels; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + { + if ( splitBinIds[i] == 0 ) + { + /* Skip inactive inputs */ + continue; + } + + if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, splitBinIds[i], &numInputChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + totalNumInChannels += numInputChannels; + } +#endif + return totalNumInChannels; } @@ -463,7 +543,12 @@ static void setupWithSingleFormatInput( CmdlnArgs args, char *audioFilePath, IsmPositionProvider *positionProvider, - MasaFileReader **masaReaders ) + MasaFileReader **masaReaders +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + SplitFileReadWrite **hhSplitRendFileReadWrite +#endif +) { /* With single-format input, inputFilePath is the path to input audio file. */ strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX - 1 ); @@ -510,6 +595,22 @@ static void setupWithSingleFormatInput( } } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + else if ( args.inConfig.numBinBuses != 0 ) + { + *hhSplitRendFileReadWrite = NULL; + if ( args.inConfig.binBuses[0].audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + ivas_error error; + error = split_rend_reader_open( hhSplitRendFileReadWrite, args.inMetadataFilePaths[0] ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", args.inMetadataFilePaths[0] ); + exit( -1 ); + } + } + } +#endif } @@ -519,6 +620,106 @@ static float dBToLin( return powf( 10.0f, gain_dB / 20.0f ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT +static int16_t rend_openCldfb( + HANDLE_CLDFB_FILTER_BANK cldfbAna[MAX_INPUT_CHANNELS], + HANDLE_CLDFB_FILTER_BANK cldfbSyn[MAX_INPUT_CHANNELS], + const int16_t num_in_chs, + const int16_t num_out_chs, + const int32_t output_Fs ) +{ + int16_t n; + + for ( n = 0; n < num_in_chs; n++ ) + { + if ( openCldfb( &( cldfbAna[n] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) != IVAS_ERR_OK ) + { + return -1; + } + } + for ( ; n < MAX_INPUT_CHANNELS; n++ ) + { + cldfbAna[n] = NULL; + } + + for ( n = 0; n < num_out_chs; n++ ) + { + if ( openCldfb( &( cldfbSyn[n] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) != IVAS_ERR_OK ) + { + return -1; + } + } + for ( ; n < MAX_INPUT_CHANNELS; n++ ) + { + cldfbSyn[n] = NULL; + } + return 0; +} + +static void rend_closeCldfb( HANDLE_CLDFB_FILTER_BANK cldfbAna[MAX_INPUT_CHANNELS], HANDLE_CLDFB_FILTER_BANK cldfbSyn[MAX_INPUT_CHANNELS] ) +{ + int16_t n; + for ( n = 0; n < MAX_INPUT_CHANNELS; n++ ) + { + if ( cldfbAna[n] != NULL ) + { + deleteCldfb( &( cldfbAna[n] ) ); + cldfbAna[n] = NULL; + } + + if ( cldfbSyn[n] != NULL ) + { + deleteCldfb( &( cldfbSyn[n] ) ); + cldfbSyn[n] = NULL; + } + } + return; +} + +static int16_t get_cldfb_in_flag( IVAS_REND_AudioConfig audioConfig, IVAS_RENDER_CONFIG_DATA *renderConfig ) +{ + int16_t cldfb_in; + cldfb_in = 0; + if ( renderConfig->renderer_type_override == IVAS_RENDER_TYPE_OVERRIDE_FASTCONV ) + { +#ifdef DEBUGGING + cldfb_in = 1; +#endif + if ( audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) + { + cldfb_in = 1; + } + } + + return cldfb_in; +} + +static int16_t is_split_post_rend_mode( CmdlnArgs *args ) +{ + int16_t flag; + flag = 0; + if ( ( args->inConfig.numBinBuses > 0 ) && + ( ( args->inConfig.binBuses[0].audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) || ( args->inConfig.binBuses[0].audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) ) + { + flag = 1; + } + + return flag; +} + +static int16_t is_split_pre_rend_mode( CmdlnArgs *args ) +{ + int16_t flag; + flag = 0; + if ( ( args->outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) || + ( args->outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + flag = 1; + } + + return flag; +} +#endif /*------------------------------------------------------------------------------------------* * main() @@ -534,6 +735,14 @@ int main( RotFileReader *headRotReader = NULL; RotFileReader *externalOrientationFileReader = NULL; RotFileReader *referenceRotReader = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + HANDLE_CLDFB_FILTER_BANK cldfbAna[MAX_INPUT_CHANNELS]; + HANDLE_CLDFB_FILTER_BANK cldfbSyn[MAX_INPUT_CHANNELS]; + int16_t cldfb_in, CLDFBframeSize_smpls; +#endif +#ifdef SPLIT_REND_PLC + SplitRendBFIFileReader *splitRendBFIReader = NULL; +#endif Vector3PairFileReader *referenceVectorReader = NULL; hrtfFileReader *hrtfFileReader = NULL; IsmPositionProvider *positionProvider; @@ -547,12 +756,24 @@ int main( AudioFileWriter *audioWriter; int32_t inBufferSize; int32_t outBufferSize; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int32_t bitsBufferSize; +#endif int16_t *inpInt16Buffer; float *inFloatBuffer; int16_t *outInt16Buffer; float *outFloatBuffer; +#ifdef SPLIT_REND_WITH_HEAD_ROT + uint8_t *bitsBufferData; +#endif IVAS_REND_AudioBuffer inBuffer; IVAS_REND_AudioBuffer outBuffer; +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_REND_BitstreamBuffer bitsBuffer; + SplitFileReadWrite *hSplitRendFileReadWrite; + int16_t delayNumSamples_temp; + int32_t delayTimeScale_temp; +#endif int16_t numSamplesRead; int16_t delayNumSamples = -1; int16_t delayNumSamples_orig = 0; @@ -573,6 +794,9 @@ int main( hMasaMetadata[i] = NULL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + hSplitRendFileReadWrite = NULL; +#endif for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { lfeRoutingConfigs[i] = NULL; @@ -629,6 +853,13 @@ int main( } } +#ifdef SPLIT_REND_PLC + if ( !isEmptyString( args.splitRendBFIFilePath ) ) + { + convert_backslash( args.splitRendBFIFilePath ); + SplitRendBFIFileReader_open( args.splitRendBFIFilePath, &splitRendBFIReader ); + } +#endif if ( !isEmptyString( args.externalOrientationFilePath ) ) { if ( RotationFileReader_open( args.externalOrientationFilePath, &externalOrientationFileReader ) != IVAS_ERR_OK ) @@ -670,7 +901,12 @@ int main( else { /* With single-format input, all information is given on command line. */ - setupWithSingleFormatInput( args, audioFilePath, positionProvider, masaReaders ); + setupWithSingleFormatInput( args, audioFilePath, positionProvider, masaReaders +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + &hSplitRendFileReadWrite +#endif + ); } /* Check that there is allowed configuration for MASA format output */ @@ -691,14 +927,37 @@ int main( } } - if ( AudioFileReader_open( &audioReader, audioFilePath ) != IVAS_ERR_OK ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + /*if split renderer is running in post renderer mode*/ + if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) ) { - fprintf( stderr, "Error opening file: %s\n", audioFilePath ); - exit( -1 ); + error = split_rend_reader_open( &hSplitRendFileReadWrite, args.inputFilePath ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", args.inputFilePath ); + exit( -1 ); + } + audioReader = NULL; + } + else +#endif + { + if ( AudioFileReader_open( &audioReader, audioFilePath ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error opening file: %s\n", audioFilePath ); + exit( -1 ); + } } int32_t inFileSampleRate = 0; - error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate ); + if ( audioReader != NULL ) + { + error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate ); + } + else + { + inFileSampleRate = args.sampleRate; + } switch ( error ) { case IVAS_ERR_OK: @@ -727,18 +986,31 @@ int main( } int16_t inFileNumChannels = 0; - error = AudioFileReader_getNumChannels( audioReader, &inFileNumChannels ); - if ( error != IVAS_ERR_OK && error != IVAS_ERR_NUM_CHANNELS_UNKNOWN ) + if ( audioReader != NULL ) { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); + error = AudioFileReader_getNumChannels( audioReader, &inFileNumChannels ); + if ( error != IVAS_ERR_OK && error != IVAS_ERR_NUM_CHANNELS_UNKNOWN ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } } const int16_t frameSize_smpls = (int16_t) ( 20 * args.sampleRate / 1000 ); +#ifndef SPLIT_REND_WITH_HEAD_ROT +#ifdef SPLIT_REND_WITH_HEAD_ROT + const int16_t CLDFBframeSize_smpls = (int16_t) frameSize_smpls * 2; + cldfb_in = get_cldfb_in_flag( &args ); +#endif +#endif + IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS] = { 0 }; IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS] = { 0 }; IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS] = { 0 }; IVAS_REND_InputId masaIds[RENDERER_MAX_MASA_INPUTS] = { 0 }; +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_REND_InputId splitBinIds[RENDERER_MAX_BIN_INPUTS] = { 0 }; +#endif if ( ( error = IVAS_REND_Open( &hIvasRend, args.sampleRate, args.outConfig.audioConfig, args.nonDiegeticPan, args.nonDiegeticPanGain ) ) != IVAS_ERR_OK ) { @@ -753,20 +1025,34 @@ int main( exit( -1 ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + CLDFBframeSize_smpls = 0; + cldfb_in = 0; +#endif + if ( args.renderConfigFilePath[0] != '\0' ) { IVAS_RENDER_CONFIG_DATA renderConfig; /* sanity check */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL ) && ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_IR ) && ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) && !is_split_pre_rend_mode( &args ) ) + { + fprintf( stderr, "\nExternal Renderer Config is supported only when binaural output configurations is used as output OR when Split pre-rendering mode is enabled. Exiting. \n" ); + exit( -1 ); + } +#else if ( ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL ) && ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_IR ) && ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) { fprintf( stderr, "\nExternal Renderer Config is only supported for binaural output configurations. Exiting. \n" ); exit( -1 ); } +#endif + if ( ( error = IVAS_REND_GetRenderConfig( hIvasRend, &renderConfig ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed\n" ); + fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } @@ -783,9 +1069,16 @@ int main( if ( ( error = IVAS_REND_FeedRenderConfig( hIvasRend, renderConfig ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed\n" ); + fprintf( stderr, "\nIVAS_REND_FeedRenderConfig failed: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( !is_split_post_rend_mode( &args ) ) + { + CLDFBframeSize_smpls = frameSize_smpls * 2; + cldfb_in = get_cldfb_in_flag( args.outConfig.audioConfig, &renderConfig ); + } +#endif } if ( ( error = IVAS_REND_SetOrientationTrackingMode( hIvasRend, args.orientation_tracking ) ) != IVAS_ERR_OK ) @@ -946,6 +1239,23 @@ int main( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( i = 0; i < args.inConfig.numBinBuses; ++i ) + { + if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.binBuses[i].audioConfig, &splitBinIds[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = IVAS_REND_SetInputGain( hIvasRend, splitBinIds[i], args.inputGainGlobal * dBToLin( args.inConfig.binBuses[i].gain_dB ) ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } +#endif + for ( i = 0; i < args.inConfig.numMasaBuses; ++i ) { if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.masaBuses[i].audioConfig, &masaIds[i] ) ) != IVAS_ERR_OK ) @@ -961,7 +1271,12 @@ int main( } } - const int16_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds, masaIds ); + const int16_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds, masaIds +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + splitBinIds +#endif + ); if ( inFileNumChannels != 0 /* inFileNumChannels is 0 with raw PCM input */ && totalNumInChannels != inFileNumChannels ) { @@ -983,26 +1298,124 @@ int main( fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } - if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels ) != IVAS_ERR_OK ) + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( cldfb_in ) { - fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath ); - exit( -1 ); + rend_openCldfb( cldfbAna, cldfbSyn, totalNumInChannels, numOutChannels, args.sampleRate ); + } +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) + { + IVAS_REND_GetDelay( hIvasRend, &delayNumSamples_temp, &delayTimeScale_temp ); + error = split_rend_writer_open( &hSplitRendFileReadWrite, args.outputFilePath, delayNumSamples_temp, delayTimeScale_temp ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", args.outputFilePath ); + exit( -1 ); + } + audioWriter = NULL; } + else + { + if ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + IVAS_REND_GetDelay( hIvasRend, &delayNumSamples_temp, &delayTimeScale_temp ); + error = split_rend_writer_open( &hSplitRendFileReadWrite, args.outMetadataFilePath, delayNumSamples_temp, delayTimeScale_temp ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", args.outMetadataFilePath ); + exit( -1 ); + } + } +#endif + if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath ); + exit( -1 ); + } +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif inBufferSize = frameSize_smpls * totalNumInChannels; outBufferSize = frameSize_smpls * numOutChannels; +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( is_split_pre_rend_mode( &args ) || is_split_post_rend_mode( &args ) ) + { +#ifdef SPLIT_REND_CLDFB_HUFF_SAN_FIX + bitsBufferSize = SPLIT_REND_BITS_BUFF_SIZE; +#else + bitsBufferSize = (int32_t) SPLIT_REND_MAX_BRATE / FRAMES_PER_SEC; + bitsBufferSize = ( bitsBufferSize + 7 ) >> 3; +#endif +#ifdef SPLIT_REND_LC3PLUS_HBR_DBG + bitsBufferSize = ( SPLIT_REND_LC3PLUS_HBR * MAX_HEAD_ROT_POSES /* Max head poses */ * BINAURAL_CHANNELS /* Ech pose is 2 channels */ + 256000 /* Max metadata bitrate */ ) / FRAMES_PER_SEC / 8; +#endif + } + else + { + bitsBufferSize = 0; + } +#endif + inpInt16Buffer = malloc( inBufferSize * sizeof( int16_t ) ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( cldfb_in == 0 ) + { + inFloatBuffer = malloc( inBufferSize * sizeof( float ) ); + inBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; + outFloatBuffer = malloc( outBufferSize * sizeof( float ) ); + outBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; + } + else + { + inFloatBuffer = malloc( CLDFBframeSize_smpls * totalNumInChannels * sizeof( float ) ); + inBuffer.config.numSamplesPerChannel = (int16_t) CLDFBframeSize_smpls; + outFloatBuffer = malloc( CLDFBframeSize_smpls * totalNumInChannels * sizeof( float ) ); + outBuffer.config.numSamplesPerChannel = (int16_t) CLDFBframeSize_smpls; + } +#else + inBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; inFloatBuffer = malloc( inBufferSize * sizeof( float ) ); - outInt16Buffer = malloc( outBufferSize * sizeof( int16_t ) ); outFloatBuffer = malloc( outBufferSize * sizeof( float ) ); + outBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; +#endif + outInt16Buffer = malloc( outBufferSize * sizeof( int16_t ) ); - inBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; +#ifdef SPLIT_REND_WITH_HEAD_ROT + inBuffer.config.is_cldfb = cldfb_in; +#endif inBuffer.config.numChannels = (int16_t) totalNumInChannels; inBuffer.data = inFloatBuffer; - outBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; +#ifdef SPLIT_REND_WITH_HEAD_ROT + outBuffer.config.is_cldfb = cldfb_in; +#endif outBuffer.config.numChannels = (int16_t) numOutChannels; outBuffer.data = outFloatBuffer; + memset( outBuffer.data, 0, outBuffer.config.numSamplesPerChannel * outBuffer.config.numChannels * sizeof( float ) ); + + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( bitsBufferSize > 0 ) + { + bitsBufferData = malloc( bitsBufferSize * sizeof( uint8_t ) ); + } + else + { + bitsBufferData = NULL; + } + +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + bitsBuffer.bits = bitsBufferData; + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + bitsBuffer.config.bufLenInBytes = bitsBufferSize; +#endif #ifdef WMOPS reset_stack(); @@ -1024,11 +1437,40 @@ int main( int16_t num_in_channels; num_in_channels = inBuffer.config.numChannels; - /* Read the input data */ - if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + numSamplesRead = 0; + if ( ( hSplitRendFileReadWrite != NULL ) && is_split_post_rend_mode( &args ) ) { - fprintf( stderr, "\nError reading from file %s\n", audioFilePath ); - exit( -1 ); + ivas_error error_tmp; + numSamplesRead = (int16_t) inBufferSize; + error_tmp = split_rend_read_bits_from_file( hSplitRendFileReadWrite, bitsBuffer.bits, &bitsBuffer.config.bitsRead, &bitsBuffer.config.bitsWritten +#ifdef SPLIT_REND_LC3PLUS + , + &bitsBuffer.config.codec, &bitsBuffer.config.poseCorrection +#endif + ); + if ( error_tmp != IVAS_ERR_OK ) + { + if ( error_tmp == IVAS_ERR_END_OF_FILE ) + { + numSamplesRead = 0; + } + else + { + fprintf( stderr, "\nUnable to read from bitstream file!\n" ); + exit( -1 ); + } + } + } + if ( audioReader != NULL ) +#endif + { + /* Read the input data */ + if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError reading from file %s\n", audioFilePath ); + exit( -1 ); + } } if ( numSamplesRead == 0 ) @@ -1038,8 +1480,12 @@ int main( } /* Convert from int to float and from interleaved to packed */ - convertInputBuffer( inpInt16Buffer, numSamplesRead, frameSize_smpls, num_in_channels, inFloatBuffer ); - + convertInputBuffer( inpInt16Buffer, numSamplesRead, inBuffer.config.numSamplesPerChannel, num_in_channels, inFloatBuffer +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + inBuffer.config.is_cldfb, cldfbAna +#endif + ); ObjectPositionBuffer mtdBuffer; IsmPositionProvider_getNextFrame( positionProvider, &mtdBuffer ); @@ -1088,7 +1534,12 @@ int main( exit( -1 ); } } - if ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, quatBuffer, Pos ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, quatBuffer, Pos +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + DEFAULT_AXIS +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); @@ -1096,14 +1547,29 @@ int main( } else { - error = IVAS_REND_SetHeadRotation( hIvasRend, NULL, NULL ); + error = IVAS_REND_SetHeadRotation( hIvasRend, NULL, NULL +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + DEFAULT_AXIS +#endif + ); if ( error != IVAS_ERR_OK && error != IVAS_ERR_INVALID_OUTPUT_FORMAT ) + { fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } } +#ifdef SPLIT_REND_PLC + /* Read from split renderer bfi file if specified */ + if ( splitRendBFIReader != NULL ) + { + int16_t bfi; + SplitRendBFIFileReading( splitRendBFIReader, &bfi ); + IVAS_REND_SetSplitRendBFI( hIvasRend, bfi ); + } +#endif /* Read from external orientation file if specified */ if ( externalOrientationFileReader != NULL ) { @@ -1235,10 +1701,32 @@ int main( } } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( i = 0; i < args.inConfig.numBinBuses; ++i ) + { + if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, splitBinIds[i], &numChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.binBuses[i].inputChannelIndex, numChannels ); - if ( IVAS_REND_GetSamples( hIvasRend, outBuffer ) != IVAS_ERR_OK ) + if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, splitBinIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } +#endif + + if ( ( error = IVAS_REND_GetSamples( hIvasRend, outBuffer +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + &bitsBuffer +#endif + ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "Error in getting samples\n" ); + fprintf( stderr, "Error %s\n", ivas_error_to_string( error ) ); exit( -1 ); } @@ -1247,17 +1735,35 @@ int main( /* Convert from float to int and from packed to interleaved. * Values in outFloatBuffer are guaranteed to be within range INT16_MIN:INT16_MAX */ - convertOutputBuffer( outFloatBuffer, frameSize_smpls, num_out_channels, outInt16Buffer ); + convertOutputBuffer( outFloatBuffer, outBuffer.config.numSamplesPerChannel, num_out_channels, outInt16Buffer +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + cldfb_in, + cldfbSyn +#endif + ); if ( delayNumSamples == -1 ) { - if ( args.delayCompensationEnabled ) + if ( args.delayCompensationEnabled +#ifdef SPLIT_REND_WITH_HEAD_ROT + && !is_split_pre_rend_mode( &args ) +#endif + ) { if ( IVAS_REND_GetDelay( hIvasRend, &delayNumSamples, &delayTimeScale ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to get delay of renderer!\n" ); exit( -1 ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( is_split_post_rend_mode( &args ) && ( hSplitRendFileReadWrite != NULL ) ) + { + uint32_t pre_rend_delay_ns; + split_rend_read_pre_rend_delay_ns( hSplitRendFileReadWrite, &pre_rend_delay_ns ); + delayNumSamples += (int16_t) roundf( (float) pre_rend_delay_ns * delayTimeScale / 1000000000.f ); + } +#endif delayNumSamples_orig = delayNumSamples; } else @@ -1267,19 +1773,42 @@ int main( zeroPad = delayNumSamples; } - if ( delayNumSamples < outBufferSize ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( hSplitRendFileReadWrite != NULL ) && is_split_pre_rend_mode( &args ) ) { - if ( AudioFileWriter_write( audioWriter, &outInt16Buffer[delayNumSamples * num_out_channels], outBufferSize - ( delayNumSamples * num_out_channels ) ) != IVAS_ERR_OK ) + if ( split_rend_write_bitstream_to_file( hSplitRendFileReadWrite, bitsBuffer.bits, &bitsBuffer.config.bitsRead, &bitsBuffer.config.bitsWritten +#ifdef SPLIT_REND_LC3PLUS + , + bitsBuffer.config.codec, bitsBuffer.config.poseCorrection +#endif + ) != IVAS_ERR_OK ) { - fprintf( stderr, "Error writing audio file %s\n", args.outputFilePath ); + fprintf( stderr, "\nUnable to write to bitstream file!\n" ); exit( -1 ); } - delayNumSamples = 0; } - else + if ( audioWriter != NULL ) +#endif { - delayNumSamples -= (int16_t) outBufferSize; + if ( delayNumSamples < outBufferSize ) + { + if ( AudioFileWriter_write( audioWriter, &outInt16Buffer[delayNumSamples * num_out_channels], outBufferSize - ( delayNumSamples * num_out_channels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error writing audio file %s\n", args.outputFilePath ); + exit( -1 ); + } + delayNumSamples = 0; + } + else + { + delayNumSamples -= (int16_t) outBufferSize; + } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; +#endif + /* Write MASA metadata for MASA outputs */ if ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_MASA1 || args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_MASA2 ) @@ -1368,11 +1897,16 @@ int main( } /* add zeros at the end to have equal length of synthesized signals */ - memset( outInt16Buffer, 0, zeroPad * outBuffer.config.numChannels * sizeof( int16_t ) ); - if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, zeroPad * outBuffer.config.numChannels ) ) != IVAS_ERR_OK ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( audioWriter != NULL ) +#endif { - fprintf( stderr, "\nOutput audio file writer error\n" ); - exit( -1 ); + memset( outInt16Buffer, 0, zeroPad * outBuffer.config.numChannels * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, zeroPad * outBuffer.config.numChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + exit( -1 ); + } } if ( !args.quietModeEnabled && args.delayCompensationEnabled ) @@ -1399,10 +1933,41 @@ int main( free( inFloatBuffer ); free( outInt16Buffer ); free( outFloatBuffer ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( bitsBufferData != NULL ) + { + free( bitsBufferData ); + } +#endif for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { MasaFileReader_close( &masaReaders[i] ); } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( cldfb_in ) + { + rend_closeCldfb( cldfbAna, cldfbSyn ); + } +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( audioReader != NULL ) +#endif + { + AudioFileReader_close( &audioReader ); + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( hSplitRendFileReadWrite != NULL ) + { + split_rend_reader_writer_close( &hSplitRendFileReadWrite ); + } + if ( audioWriter != NULL ) +#endif + { + AudioFileWriter_close( &audioWriter ); + } for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { LfeRoutingConfig_close( lfeRoutingConfigs[i] ); @@ -1474,7 +2039,9 @@ static bool parseInConfig( inConfig->numAmbisonicsBuses = 0; inConfig->numMultiChannelBuses = 0; inConfig->numMasaBuses = 0; - +#ifdef SPLIT_REND_WITH_HEAD_ROT + inConfig->numBinBuses = 0; +#endif /* First check if input is being set to scene description file - this is not covered by parseAudioConfig(). */ strncpy( charBuf, inFormatStr, sizeof( charBuf ) - 1 ); charBuf[sizeof( charBuf ) - 1] = '\0'; @@ -1511,6 +2078,15 @@ static bool parseInConfig( inConfig->ambisonicsBuses[0].inputChannelIndex = 0; inConfig->ambisonicsBuses[0].gain_dB = 0.0f; break; +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB: + case IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + inConfig->numBinBuses = 1; + inConfig->binBuses[0].audioConfig = audioConfig; + inConfig->binBuses[0].inputChannelIndex = 0; + inConfig->binBuses[0].gain_dB = 0.0f; + break; +#endif case IVAS_REND_AUDIO_CONFIG_MASA1: case IVAS_REND_AUDIO_CONFIG_MASA2: inConfig->numMasaBuses = 1; @@ -1670,8 +2246,13 @@ static bool parseOrientationTracking( static IVAS_REND_AudioConfig parseAudioConfig( const char *configString ) { +#ifndef SPLIT_REND_WITH_HEAD_ROT char charBuf[21]; charBuf[20] = '\0'; +#else + char charBuf[25]; + charBuf[24] = '\0'; +#endif strncpy( charBuf, configString, sizeof( charBuf ) - 1 ); charBuf[sizeof( charBuf ) - 1] = '\0'; @@ -1748,6 +2329,16 @@ static IVAS_REND_AudioConfig parseAudioConfig( { return IVAS_REND_AUDIO_CONFIG_BINAURAL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( strcmp( charBuf, "BINAURAL_SPLIT_PCM" ) == 0 ) + { + return IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM; + } + if ( strcmp( charBuf, "BINAURAL_SPLIT_CLDFB" ) == 0 ) + { + return IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB; + } +#endif if ( strcmp( charBuf, "BINAURAL_ROOM_IR" ) == 0 ) { return IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_IR; @@ -1819,10 +2410,19 @@ static bool checkRequiredArgs( fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); missingRequiredArg = true; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + const bool singleInputSpecified = args.inConfig.numAudioObjects != 0 || + args.inConfig.numAmbisonicsBuses != 0 || + args.inConfig.numMultiChannelBuses != 0 || + args.inConfig.numMasaBuses != 0 || + args.inConfig.numBinBuses != 0; +#else const bool singleInputSpecified = args.inConfig.numAudioObjects != 0 || args.inConfig.numAmbisonicsBuses != 0 || args.inConfig.numMultiChannelBuses != 0 || args.inConfig.numMasaBuses != 0; +#endif + if ( !args.sceneDescriptionInput && !singleInputSpecified ) { /* Neither scene description input nor single-type input was specified on command line */ @@ -1878,6 +2478,12 @@ static CmdlnArgs defaultArgs( args.numInMetadataFiles = 0; clearString( args.headRotationFilePath ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + clearString( args.outMetadataFilePath ); +#endif +#ifdef SPLIT_REND_PLC + clearString( args.splitRendBFIFilePath ); +#endif clearString( args.referenceVectorFilePath ); clearString( args.referenceRotationFilePath ); clearString( args.customHrtfFilePath ); @@ -1960,6 +2566,18 @@ static void parseOption( assert( numOptionValues == 1 ); strncpy( args->headRotationFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); break; +#ifdef SPLIT_REND_WITH_HEAD_ROT + case CmdLnOptionId_outputMetadata: + assert( numOptionValues == 1 ); + strncpy( args->outMetadataFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); + break; +#endif +#ifdef SPLIT_REND_PLC + case CmdLnOptionId_SplitRendBFIFile: + assert( numOptionValues == 1 ); + strncpy( args->splitRendBFIFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); + break; +#endif case CmdLnOptionId_referenceVectorFile: assert( numOptionValues == 1 ); strncpy( args->referenceVectorFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); @@ -2910,6 +3528,10 @@ static void printSupportedAudioConfigs() "ISMx (input only)", "MASAx (input only)", "BINAURAL (output only)", +#ifdef SPLIT_REND_WITH_HEAD_ROT + "BINAURAL_SPLIT_PCM", + "BINAURAL_SPLIT_CLDFB", +#endif "BINAURAL_ROOM_IR (output only)", "BINAURAL_ROOM_REVERB (output only)", }; @@ -3003,26 +3625,72 @@ static void convertInputBuffer( const int16_t numIntSamplesPerChannel, const int16_t numFloatSamplesPerChannel, const int16_t numChannels, - float *floatBuffer ) + float *floatBuffer +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + const int16_t cldfb_in, + HANDLE_CLDFB_FILTER_BANK *cldfbAna +#endif +) { int16_t chnl, smpl, i; i = 0; - - for ( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( cldfb_in ) { - for ( chnl = 0; chnl < numChannels; ++chnl ) + int16_t slotIdx, numCldfbBands, numFloatPcmSamples; + float fIn[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + numFloatPcmSamples = numFloatSamplesPerChannel >> 1; + numCldfbBands = numFloatPcmSamples / CLDFB_NO_COL_MAX; + /* CLDFB Analysis*/ + assert( numIntSamplesPerChannel <= MAX_OUTPUT_CHANNELS * L_FRAME48k ); + for ( smpl = 0; smpl < numFloatPcmSamples; ++smpl ) { - if ( i < numIntSamplesPerChannel ) + for ( chnl = 0; chnl < numChannels; ++chnl ) { - floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = (float) intBuffer[i]; + if ( i < numIntSamplesPerChannel ) + { + fIn[chnl][smpl] = (float) intBuffer[i]; + } + else + { + fIn[chnl][smpl] = 0.f; + } + + ++i; } - else + } + for ( chnl = 0; chnl < numChannels; ++chnl ) + { + for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX; slotIdx++ ) { - floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = 0.f; + cldfbAnalysis_ts( &fIn[chnl][numCldfbBands * slotIdx], + &floatBuffer[( chnl * numFloatSamplesPerChannel ) + ( 2 * slotIdx * numCldfbBands )], + &floatBuffer[numCldfbBands + ( chnl * numFloatSamplesPerChannel ) + ( 2 * slotIdx * numCldfbBands )], + numCldfbBands, + cldfbAna[chnl] ); } + } + } + else +#endif + { + for ( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl ) + { + for ( chnl = 0; chnl < numChannels; ++chnl ) + { + if ( i < numIntSamplesPerChannel ) + { + floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = (float) intBuffer[i]; + } + else + { + floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = 0.f; + } - ++i; + ++i; + } } } @@ -3040,30 +3708,85 @@ static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, - int16_t *intBuffer ) + int16_t *intBuffer +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + const int16_t cldfb_in, + HANDLE_CLDFB_FILTER_BANK *cldfbSyn +#endif +) { int16_t chnl, smpl, i; float temp; i = 0; - for ( smpl = 0; smpl < numSamplesPerChannel; ++smpl ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( cldfb_in ) { + int16_t slotIdx, numCldfbBands, numPcmSamples, b; + float fIn[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float re[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float im[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + numPcmSamples = numSamplesPerChannel >> 1; + numCldfbBands = numPcmSamples / CLDFB_NO_COL_MAX; + /* CLDFB Synthesis*/ + for ( chnl = 0; chnl < numChannels; ++chnl ) + { + for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX; slotIdx++ ) + { + for ( b = 0; b < numCldfbBands; b++ ) + { + re[chnl][slotIdx][b] = floatBuffer[( chnl * numSamplesPerChannel ) + ( 2 * slotIdx * numCldfbBands ) + b]; + im[chnl][slotIdx][b] = floatBuffer[numCldfbBands + ( chnl * numSamplesPerChannel ) + ( 2 * slotIdx * numCldfbBands ) + b]; + } + } + } + + /* Implement CLDFB synthesis */ for ( chnl = 0; chnl < numChannels; ++chnl ) { - temp = floatBuffer[chnl * numSamplesPerChannel + smpl]; - temp = (float) floor( temp + 0.5f ); - if ( temp > MAX16B_FLT ) + float *RealBuffer[CLDFB_NO_COL_MAX]; + float *ImagBuffer[CLDFB_NO_COL_MAX]; + + for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX; slotIdx++ ) { - temp = MAX16B_FLT; + RealBuffer[slotIdx] = re[chnl][slotIdx]; + ImagBuffer[slotIdx] = im[chnl][slotIdx]; } - else if ( temp < MIN16B_FLT ) + + cldfbSynthesis( RealBuffer, ImagBuffer, &( fIn[chnl][0] ), numCldfbBands * CLDFB_NO_COL_MAX, cldfbSyn[chnl] ); + } + for ( smpl = 0; smpl < numPcmSamples; ++smpl ) + { + for ( chnl = 0; chnl < numChannels; ++chnl ) { - temp = MIN16B_FLT; + intBuffer[i] = (int16_t) roundf( fIn[chnl][smpl] ); + ++i; } - intBuffer[i] = (int16_t) temp; + } + } + else +#endif + { + for ( smpl = 0; smpl < numSamplesPerChannel; ++smpl ) + { + for ( chnl = 0; chnl < numChannels; ++chnl ) + { + temp = floatBuffer[chnl * numSamplesPerChannel + smpl]; + temp = (float) floor( temp + 0.5f ); + if ( temp > MAX16B_FLT ) + { + temp = MAX16B_FLT; + } + else if ( temp < MIN16B_FLT ) + { + temp = MIN16B_FLT; + } + intBuffer[i] = (int16_t) temp; - ++i; + ++i; + } } } diff --git a/ci/comment_defines.py b/ci/comment_defines.py new file mode 100755 index 0000000000000000000000000000000000000000..0b6e3457035e0dc93d930dbe046c18a8437c3e8c --- /dev/null +++ b/ci/comment_defines.py @@ -0,0 +1,47 @@ +import re +import argparse + + +def process_file(file_path: str, defines_re): + with open(file_path, "r", encoding="utf-8") as file: + lines = file.readlines() + + num_subbed = dict() + for name in defines_re.keys(): + num_subbed[name] = 0 + + for i, line in enumerate(lines): + for name, regex in defines_re.items(): + # Spaces are replaced with underscores to avoid matching on multiple runs + lines[i] = regex.sub(lambda x: f"/* {x.group(0).replace(' ', '_')} */", line) + + if lines[i] != line: + num_subbed[name] += 1 + + with open(file_path, "w", encoding="utf-8") as file: + file.writelines(lines) + + print(f"Processed {file_path}") + for name, num in num_subbed.items(): + print(f"{name} - {num} occurences commented") + print("") + + +def compile_define_re(define_name: str): + return re.compile(f"#define\\s+{define_name}") + + +def main(args): + defines_re = dict() + for define_name in args.defines: + defines_re[define_name] = compile_define_re(define_name) + + for file_path in args.files: + process_file(file_path, defines_re) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Comment out preprocessor defines in c/c++ files") + parser.add_argument("-f", "--files", nargs="+", required=True, type=str) + parser.add_argument("-d", "--defines", nargs="+", required=True, type=str) + main(parser.parse_args()) diff --git a/ci/disable_ram_counting.py b/ci/disable_ram_counting.py deleted file mode 100755 index 3c891535081528a249751eed987d88f589e55f9d..0000000000000000000000000000000000000000 --- a/ci/disable_ram_counting.py +++ /dev/null @@ -1,20 +0,0 @@ -import re -import os - -FILE_PATH = os.path.join(os.path.dirname(__file__), "..", "lib_com", "options.h") -RE_TO_COMMENT_OUT = re.compile(r"#define\s+RAM_COUNTING_TOOL") - - -def main(): - with open(FILE_PATH, "r", encoding="utf-8") as file: - lines = file.readlines() - - for i, line in enumerate(lines): - lines[i] = RE_TO_COMMENT_OUT.sub(lambda x: f"/* {x.group(0)} */", line) - - with open(FILE_PATH, "w", encoding="utf-8") as file: - file.writelines(lines) - - -if __name__ == "__main__": - main() diff --git a/lc3plus/adjust_global_gain.c b/lc3plus/adjust_global_gain.c new file mode 100644 index 0000000000000000000000000000000000000000..e7674dd7101b7079137738cd85e859562c1ed0ce --- /dev/null +++ b/lc3plus/adjust_global_gain.c @@ -0,0 +1,86 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +void processAdjustGlobalGain_fl(LC3_INT* gg_idx, LC3_INT gg_idx_min, LC3_INT gg_idx_off, LC3_FLOAT* gain, LC3_INT target, LC3_INT nBits, LC3_INT* gainChange, LC3_INT fs_idx + , LC3_INT16 hrmode, LC3_INT16 frame_dms + ) +{ + LC3_FLOAT delta = 0; + LC3_INT delta2 = 0; + LC3_INT gg_idx_inc; + LC3_INT factor; + + + if (frame_dms == 25) + { + if (target < 520) + { + factor = 3; + } else { + factor = 4; + } + } else if (frame_dms == 50) + { + factor = 2; + } else + { + factor = 1; + } + + if (nBits < gg_p1[fs_idx]) { + delta = (nBits + 48.0) / 16.0; + } else if (nBits < gg_p2[fs_idx]) { + delta = (nBits + gg_d[fs_idx]) * gg_c[fs_idx]; + } else if (nBits < gg_p3[fs_idx]) { + delta = nBits / 48.0; + } else { + delta = gg_p3[fs_idx] / 48.0; + } + + delta = round(delta); + delta2 = delta + 2; + + *gainChange = 0; + + if (*gg_idx == 255 && nBits > target) { + *gainChange = 1; + } + + if ((*gg_idx < 255 && nBits > target) || (*gg_idx > 0 && nBits < target - delta2)) { + if (hrmode) + { + if (nBits > target) { + gg_idx_inc = (int) factor * (((nBits - target)/ delta) + 1); + gg_idx_inc = MIN(gg_idx_inc, 10 * factor); + + *gg_idx += gg_idx_inc; + } + + *gg_idx = MIN(*gg_idx, 255); + } + else + { + if (nBits < target - delta2) { + *gg_idx = *gg_idx - 1; + } else if (*gg_idx == 254 || nBits < target + delta) { + *gg_idx = *gg_idx + 1; + } else { + *gg_idx = *gg_idx + 2; + } + } + + *gg_idx = MAX(*gg_idx, gg_idx_min - gg_idx_off); + *gain = LC3_POW(10, (LC3_FLOAT)(*gg_idx + gg_idx_off) / 28); + *gainChange = 1; + } +} diff --git a/lc3plus/al_fec_fl.c b/lc3plus/al_fec_fl.c new file mode 100644 index 0000000000000000000000000000000000000000..0cae36dade9bf580d3774b942dec6eb24b3cf62d --- /dev/null +++ b/lc3plus/al_fec_fl.c @@ -0,0 +1,2329 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "stdint.h" +#include +#include +#include + +#include "functions.h" + + +/* channel coder specific constants and macros */ +#define RS16_CW_LEN_MAX 15 + +#define FEC_N_MODES 4 +#define FEC_N_SYNDROMES_MAX 6 +#define FEC_N_ERR_POS_MAX 3 +#define FEC_N_ELP_COEFF_MAX 4 +#define FEC_N_ERR_SYMB_MAX 3 +#define FEC_N_MODE_DETECTION_CW 6 + +#define SYNDROME_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_SYNDROMES_MAX) +#define ELP_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_ELP_COEFF_MAX) +#define ERR_POS_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_ERR_POS_MAX) +#define ERR_SYMB_IDX(mode_index, cw_index) (((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) * FEC_N_ERR_SYMB_MAX) +#define DEG_ELP_IDX(mode_index, cw_index) ((mode_index)*FEC_N_MODE_DETECTION_CW + (cw_index)) + +#define FEC_TOTAL_SYNDROME_SIZE (FEC_N_SYNDROMES_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW) +#define FEC_TOTAL_ELP_SIZE (FEC_N_ELP_COEFF_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW) +#define FEC_TOTAL_ERR_POS_SIZE (FEC_N_ERR_POS_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW) +#define FEC_TOTAL_ERROR_SIZE (FEC_N_ERR_SYMB_MAX * FEC_N_MODES * FEC_N_MODE_DETECTION_CW) +#define FEC_TOTAL_DEG_ELP_SIZE (FEC_N_MODES * FEC_N_MODE_DETECTION_CW) + +#define ERROR_REPORT_BEC_MASK ((0x0FFF)>>1) +#define ERROR_REPORT_EP1_OK ((0x1000)>>1) +#define ERROR_REPORT_EP2_OK ((0x2000)>>1) +#define ERROR_REPORT_EP3_OK ((0x4000)>>1) +#define ERROR_REPORT_EP4_OK ((0x8000)>>1) +#define ERROR_REPORT_ALL_OK (ERROR_REPORT_EP1_OK | ERROR_REPORT_EP2_OK | ERROR_REPORT_EP3_OK | ERROR_REPORT_EP4_OK) + +/* debugging switches */ + +/* constants concerning mode detection */ +#define EP_RISK_THRESH_NS_M 21990 +#define EP_RISK_THRESH_NS_E -23 +#define EP_RISK_THRESH_OS_M 25166 +#define EP_RISK_THRESH_OS_E -10 + +#define SIMPLE_FLOAT_1_MANTISSA 16384 + +#define FEC_STATIC static + +/* DISCLAIMER: Strict instrumentation of GF16 arithmetic would have to take into account + * the initial conversion of the arguments from LC3_UINT8 to LC3_INT16 (one move16() per argument). + * Behind this is the assumption that one would store GF16 elements in LC3_INT16 for strict BASOP + * implementation. + */ +#define GF16_MUL(a, b) gf16_mult_table[(a) | (b << 4)] +#define GF16_MUL0(a, b) gf16_mult_table[(a) | (b)] +#define GF16_ADD(a, b) ((a) ^ (b)) + +/* tables for finite field arithmetic */ +/* tables for arithmetic in GF(16) * + * generator polynomial: 19 + * unit group generator (g): 2 + */ + +static const LC3_UINT8 gf16_mult_table[256] = { + /* gf16_mult_table[a | (b << 4)] contains the product of a and b in GF(16) */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 0, 2, 4, 6, 8, 10, 12, 14, 3, 1, 7, 5, 11, 9, 15, 13, 0, 3, 6, 5, 12, 15, 10, 9, 11, 8, + 13, 14, 7, 4, 1, 2, 0, 4, 8, 12, 3, 7, 11, 15, 6, 2, 14, 10, 5, 1, 13, 9, 0, 5, 10, 15, 7, 2, 13, + 8, 14, 11, 4, 1, 9, 12, 3, 6, 0, 6, 12, 10, 11, 13, 7, 1, 5, 3, 9, 15, 14, 8, 2, 4, 0, 7, 14, 9, + 15, 8, 1, 6, 13, 10, 3, 4, 2, 5, 12, 11, 0, 8, 3, 11, 6, 14, 5, 13, 12, 4, 15, 7, 10, 2, 9, 1, 0, + 9, 1, 8, 2, 11, 3, 10, 4, 13, 5, 12, 6, 15, 7, 14, 0, 10, 7, 13, 14, 4, 9, 3, 15, 5, 8, 2, 1, 11, + 6, 12, 0, 11, 5, 14, 10, 1, 15, 4, 7, 12, 2, 9, 13, 6, 8, 3, 0, 12, 11, 7, 5, 9, 14, 2, 10, 6, 1, + 13, 15, 3, 4, 8, 0, 13, 9, 4, 1, 12, 8, 5, 2, 15, 11, 6, 3, 14, 10, 7, 0, 14, 15, 1, 13, 3, 2, 12, + 9, 7, 6, 8, 4, 10, 11, 5, 0, 15, 13, 2, 9, 6, 4, 11, 1, 14, 12, 3, 8, 7, 5, 10, +}; + +static const LC3_UINT8 rs16_elp_deg2_table[256] = { + /* If the polynomial x^2 + ax + b has distinct non-zero roots z1 and z2 in GF(16), * + * then table entry a + 16*b contains log_g(z1) | log_g(z2) << 4, and otherwise it * + * contains 0. */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 0, 0, 0, 0, + 105, 195, 0, 210, 0, 225, 0, 180, 120, 0, 0, 121, 0, 16, 0, 211, 0, 0, 181, 0, 0, 106, + 196, 226, 0, 0, 0, 214, 64, 0, 199, 0, 0, 0, 0, 0, 49, 184, 0, 154, 0, 229, 0, 227, + 182, 0, 0, 32, 0, 0, 0, 197, 0, 0, 122, 0, 212, 152, 0, 203, 0, 158, 128, 0, 0, 0, + 98, 113, 218, 0, 0, 0, 53, 0, 0, 65, 0, 0, 185, 110, 215, 80, 0, 0, 200, 0, 50, 0, + 0, 0, 0, 130, 205, 115, 0, 0, 160, 190, 145, 0, 0, 0, 0, 0, 0, 100, 0, 0, 168, 198, + 0, 183, 33, 0, 0, 48, 228, 213, 0, 0, 0, 0, 0, 0, 0, 0, 164, 0, 179, 0, 224, 104, + 0, 194, 149, 0, 0, 209, 0, 0, 0, 189, 99, 84, 0, 129, 0, 0, 0, 144, 0, 0, 234, 114, + 0, 0, 82, 0, 0, 0, 0, 217, 202, 0, 112, 52, 232, 0, 97, 0, 0, 0, 126, 0, 81, 201, + 0, 36, 216, 186, 0, 0, 0, 96, 0, 0, 0, 0, 0, 88, 0, 0, 0, 103, 0, 148, 178, 0, + 208, 193, 0, 58, 0, 0, 0, 0, 0, 161, 206, 0, 116, 0, 101, 0, 0, 56, 146, 176, 0, 0, + 147, 162, 222, 0, 132, 0, 0, 0, 0, 0, 177, 117, 192, 0, +}; + +static const LC3_UINT16 rs16_elp_deg3_table[256] = { + /* If the polynomial x^3 + ax + b has distinct roots z1, z2 and z3 in GF(16), * + * then table entry a + 16*b contains z1) | z2 << 4 | z3 << 8, and otherwise it * + * contains 0. */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1889, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2977, 0, 0, 0, 0, 0, 3990, 1859, 0, + 0, 0, 0, 0, 0, 0, 3521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1874, 0, 3718, 0, 0, 0, + 0, 0, 0, 2433, 0, 0, 1619, 0, 0, 0, 0, 3495, 0, 0, 0, 0, 0, 0, 4065, 0, 0, 0, + 0, 0, 0, 3255, 0, 0, 0, 1602, 0, 3735, 0, 0, 0, 0, 3238, 801, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 3510, 0, 0, 0, 0, 1345, 3975, 0, 0, 0, 0, 0, 0, 0, 0, 3778, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2947, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3476, 0, 4005, 0, 3461, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3748, 0, 0, 2962, 0, 0, 0, 0, 4035, 0, 0, 4020, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3221, 0, 0, 0, 0, 0, 0, 2690, + 0, 0, 0, 3795, 0, 0, 0, 4050, 0, 0, 0, 0, 0, 3204, 3765, 0, 0, 0, 0, 0, 2707, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; + +static const LC3_UINT8 gf16_g_pow[16] = {1, 2, 4, 8, 3, 6, 12, 11, 5, 10, 7, 14, 15, 13, 9, 1}; +/* g_pow[i] contains g^i*/ + +static const LC3_UINT8 gf16_log_g[16] = {255, 0, 1, 4, 2, 8, 5, 10, 3, 14, 9, 7, 6, 13, 11, 12}; +/* log_g[n] contains contains the value i such that g^i = n for n=1, 2, ..., 15, log_g[0] is set to 255 */ + +static const LC3_UINT8 gf16_inv_table[16] = {255, 1, 9, 14, 13, 11, 7, 6, 15, 2, 12, 5, 10, 4, 3, 8}; +/* gf16_inv_table[n] contains the multiplicative inverse of n in GF(16) (1/0 is set to 255)*/ + +/* RS16 generating polynomials (from lowest to highest coefficient without leading 1)*/ + +static const LC3_UINT8 rs16_gp_d3[] = {8, 6}; +static const LC3_UINT8 rs16_gp_d5[] = {7, 8, 12, 13}; +static const LC3_UINT8 rs16_gp_d7[] = {12, 10, 12, 3, 9, 7}; + +/* FEC mode signaling polynomials */ + +#define EP_SIG_POLY_DEG 12 + +static const LC3_UINT8 sig_polys[4][15] = {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {7, 15, 5, 6, 14, 9, 1, 3, 12, 10, 13, 3, 2, 0, 0}, + {7, 11, 14, 1, 2, 3, 12, 11, 6, 15, 7, 6, 12, 0, 0}, + {6, 15, 12, 2, 9, 15, 2, 8, 12, 3, 10, 5, 4, 0, 0}}; + +static const LC3_UINT8 sig_poly_syndr[4][6] = { + {0, 0, 0, 0, 0, 0}, {0, 4, 5, 11, 5, 8}, {0, 5, 9, 0, 1, 7}, {0, 12, 5, 12, 9, 8}}; + +/* bit count table for error report (0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111) */ + +static const LC3_UINT8 rs16_bit_count_table[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; + +/* List of RS16 generators by Hamming distance */ + +static const LC3_UINT8 *const rs16_gp_by_hd[8] = {NULL, NULL, NULL, rs16_gp_d3, NULL, rs16_gp_d5, NULL, rs16_gp_d7}; + +/* fec config data */ + +static const LC3_UINT8 hamming_distance_by_mode0[] = {1, 3, 3, 5, 7}; +static const LC3_UINT8 hamming_distance_by_mode1[] = {1, 1, 3, 5, 7}; + +static const LC3_UINT8 crc1_bytes_by_mode0[] = {0, 3, 2, 2, 2}; +static const LC3_UINT8 crc1_bytes_by_mode1[] = {0, 3, 3, 3, 3}; +static const LC3_UINT8 crc2_bytes_by_mode[] = {0, 0, 2, 2, 2}; + +/* fec mode risk table */ +typedef struct +{ + LC3_UINT32 mantissa; + LC3_INT16 exponent; +} simple_float; + +static const simple_float risk_table_f[4][4] = {{{16384, 0}, {16384, 0}, {16384, 0}, {16384, 0}}, + {{16384, -8}, {26880, -1}, {16384, 0}, {16384, 0}}, + {{16384, -16}, {26880, -9}, {20475, -2}, {16384, 0}}, + {{16384, -24}, {26880, -17}, {20475, -10}, {19195, -4}}}; +/* bit error limits for slot size 40 */ +static LC3_INT16 const low_br_max_bit_errors_by_mode[] = {0, 0, 3, 9, 18}; + +/* +corresponding float values: + {1.f, 1.f, 1.f, 1.f}, + {0.00390625f, 0.820312f, 1.f, 1.f}, + {1.52588e-05f, 0.00320435f, 0.312424f, 1.f}, + {5.96046e-08f, 1.2517e-05f, 0.00122041f, 0.0732243f} +*/ + +/* internal encoder routines */ + +FEC_STATIC void fec_interleave_pack(LC3_UINT8 *out, LC3_UINT8 *in, LC3_INT16 n_nibbles, LC3_INT16 n_codewords); + +FEC_STATIC void rs16_enc(LC3_UINT8 *iobuf, LC3_INT16 codeword_length, LC3_INT16 hamming_distance, LC3_INT16 fec_mode, + LC3_INT16 signal_mode); + +/* internal decoder routines */ + +FEC_STATIC void fec_deinterleave_unpack(LC3_UINT8 *out, LC3_UINT8 *in, LC3_INT16 n_nibbles, LC3_INT16 n_codewords); + +FEC_STATIC LC3_INT16 fec_data_preproc(LC3_INT16 mode, LC3_INT16 epmr, LC3_UINT8 *iobuf, LC3_UINT8 *cw_buf, LC3_INT16 data_bytes, + LC3_INT16 slot_bytes, LC3_INT16 pc_split); + +FEC_STATIC void fec_data_postproc(LC3_INT16 mode, LC3PLUS_EpModeRequest *epmr, LC3_UINT8 *iobuf, LC3_INT16 data_bytes, LC3_UINT8 *cw_buf, + LC3_INT16 slot_bytes, LC3_INT16 pc_split, LC3_INT32 *bfi); + +FEC_STATIC LC3_INT32 rs16_detect_and_correct(LC3_UINT8 *iobuf, LC3_INT32 n_symb, LC3_INT32 n_codewords, LC3PLUS_EpModeRequest *epmr, LC3_INT16 *error_report, + LC3_INT32 *bfi, LC3_UINT8 *array_of_trust, LC3_INT32 ccc_flag_flag, LC3_INT16 *n_pccw); + +FEC_STATIC void rs16_calculate_six_syndromes(LC3_UINT8 *syndromes, LC3_UINT8 *cw, LC3_INT32 cw_poly_deg); + +FEC_STATIC void rs16_calculate_four_syndromes(LC3_UINT8 *syndromes, LC3_UINT8 *cw, LC3_INT32 cw_poly_deg); + +FEC_STATIC void rs16_calculate_two_syndromes(LC3_UINT8 *syndromes, LC3_UINT8 *cw, LC3_INT32 cw_poly_deg); + +FEC_STATIC LC3_INT8 rs16_calculate_elp(LC3_UINT8 *elp, LC3_UINT8 *syndromes, LC3_INT16 hamming_distance); + +FEC_STATIC LC3_INT16 rs16_factorize_elp(LC3_UINT8 *error_locations, LC3_UINT8 *elp, LC3_INT16 deg_elp, LC3_INT16 max_pos); + +FEC_STATIC void rs16_calculate_errors(LC3_UINT8 *errors, LC3_UINT8 *err_pos, LC3_UINT8 *syndromes, LC3_INT8 deg_elp, LC3_INT8 t); + +/* auxiliary routines */ + +FEC_STATIC LC3_INT16 crc1(LC3_UINT8 *data, LC3_INT16 data_size, LC3_INT16 epmr, LC3_UINT8 *hash_val, LC3_INT16 hash_size, LC3_INT16 check); + +FEC_STATIC LC3PLUS_EpModeRequest fec_estimate_epmr_from_cw0(LC3_UINT8 *cw0, LC3_INT8 *t, LC3_UINT8 *syndromes, LC3_UINT8 *elp, LC3_INT8 *deg_elp, + LC3_UINT8 *err_pos, LC3_UINT8 *err_symb, LC3_INT16 n_codewords, LC3_INT16 n_symb); + +FEC_STATIC void dw0_bitswap(LC3_UINT8 *dw0, LC3_INT16 mode, LC3_INT16 slot_bytes); + +FEC_STATIC LC3PLUS_EpModeRequest cw0_get_epmr(LC3_UINT8 *cw0, LC3_INT16 epmr_position); + +FEC_STATIC LC3PLUS_EpModeRequest dw0_get_epmr(LC3_UINT8 *dw0, LC3_INT16 mode, LC3_INT16 slot_size); + +FEC_STATIC LC3_INT16 crc2(LC3_UINT8 *data, LC3_INT16 data_size, LC3_UINT8 *hash_val, LC3_INT16 hash_size, LC3_INT16 check); + +FEC_STATIC simple_float simple_float_mul(simple_float op1, simple_float op2); + +FEC_STATIC LC3_INT16 simple_float_cmp(simple_float op1, simple_float op2); + +FEC_STATIC LC3_INT16 get_total_crc_size(LC3_INT16 slot_bytes, LC3_INT16 fec_mode, LC3_INT16 pc_split); + +FEC_STATIC LC3_INT16 get_n_codewords(LC3_INT16 slot_bytes); + +FEC_STATIC LC3_INT16 get_codeword_length(LC3_INT16 n_codewords, LC3_INT16 slot_nibbles, LC3_INT16 codeword_index); + + + +LC3_INT16 fec_get_n_pccw(LC3_INT16 slot_bytes, LC3_INT16 fec_mode, LC3_INT16 ccc_flag) +{ + LC3_INT16 n_pccw; + + if (fec_mode == 3) + { + n_pccw = (LC3_INT16) (0.080447761194030 * slot_bytes - 1.791044776119394 + 0.5); + } + else if (fec_mode == 4) + { + n_pccw = (LC3_INT16) (0.066492537313433 * slot_bytes - 1.970149253731338 + 0.5); + } + else + { + n_pccw = 0; + } + + if (ccc_flag == 1 || slot_bytes < 80) + { + n_pccw = 0; + } + + return n_pccw; +} + +FEC_STATIC LC3_INT16 get_total_crc_size(LC3_INT16 slot_bytes, LC3_INT16 fec_mode, LC3_INT16 pc_split) +{ + LC3_INT16 n_crc; + + n_crc = crc1_bytes_by_mode1[fec_mode]; + if (slot_bytes == 40) + { + n_crc = crc1_bytes_by_mode0[fec_mode]; + } + + if (pc_split > 0) + { + n_crc = n_crc + crc2_bytes_by_mode[fec_mode]; + } + + + + return n_crc; +} + +FEC_STATIC LC3_INT16 get_n_codewords(LC3_INT16 slot_bytes) +{ + return (2*slot_bytes + 14)/15; +} + +FEC_STATIC LC3_INT16 get_codeword_length(LC3_INT16 n_codewords, LC3_INT16 slot_nibbles, LC3_INT16 codeword_index) +{ + return (slot_nibbles - codeword_index - 1) / n_codewords + 1; +} + +/* Encoder */ + +LC3_INT16 fec_get_data_size(LC3_INT16 fec_mode, LC3_INT16 ccc_flag, LC3_INT16 slot_bytes) +/* not time critical */ +{ + LC3_INT16 n_codewords, payload_size; + + n_codewords = get_n_codewords(slot_bytes); + + assert(n_codewords == (2 * slot_bytes + RS16_CW_LEN_MAX - 1) / RS16_CW_LEN_MAX); + payload_size = slot_bytes; + + if (fec_mode > 0) + { + if (fec_mode == 1) + { + payload_size --; + } + else + { + payload_size -= (fec_mode - 1) * n_codewords; + } + if (slot_bytes == 40) + { + payload_size -= crc1_bytes_by_mode0[fec_mode]; + } + else + { + payload_size -= crc1_bytes_by_mode1[fec_mode]; + } + + if (ccc_flag == 0 && fec_mode > 2 && slot_bytes >= 80) + { + payload_size -= crc2_bytes_by_mode[fec_mode]; + } + } + + + + return payload_size; +} + +LC3_INT16 fec_get_n_pc(LC3_INT16 fec_mode, LC3_INT16 n_pccw, LC3_INT16 slot_bytes) +/* not time critical */ +{ + LC3_INT16 n_codewords, pc_split; + LC3_INT32 i; + + n_codewords = get_n_codewords(slot_bytes); + + assert(n_codewords == (2 * slot_bytes + RS16_CW_LEN_MAX - 1) / RS16_CW_LEN_MAX); + + pc_split = - 2*n_pccw*(fec_mode - 1); + + if (fec_mode == 1 || slot_bytes < 80) + { + pc_split = 0; + } + else + { + for (i = 0; i < n_pccw; i++) + { + pc_split += (2 * slot_bytes + i) / n_codewords; + } + } + + + + return pc_split; +} + +/* functions for EPMR handling */ +FEC_STATIC void dw0_bitswap(LC3_UINT8 *dw0, LC3_INT16 mode, LC3_INT16 slot_bytes) +/* swap epmr bits with bits that will be positioned at 30 and 32 in code word 0 */ +{ + LC3_UINT8 tmp; + LC3_INT32 ind0, ind1, position; + + position = get_codeword_length(get_n_codewords(slot_bytes), 2*slot_bytes, 0) - 1; + + if (slot_bytes == 40) + { + ind0 = 2*crc1_bytes_by_mode0[mode] - 1; + } + else + { + ind0 = 2*crc1_bytes_by_mode1[mode] - 1; + } + + ind1 = position - hamming_distance_by_mode0[mode] + 1; + + /* swap bits 2 and 3 of dw0[ind0] with bits 0 and 1 of dw0[ind1] */ + tmp = (dw0[ind0] >> 2) & 3; + dw0[ind0] = dw0[ind0] & 3; + dw0[ind0] = dw0[ind0] | ((dw0[ind1] & 3) << 2); + dw0[ind1] = dw0[ind1] & 12; + dw0[ind1] = dw0[ind1] | tmp; + + +} + +FEC_STATIC LC3PLUS_EpModeRequest cw0_get_epmr(LC3_UINT8 *cw0, LC3_INT16 position) +{ + return (LC3PLUS_EpModeRequest)(cw0[position] & 3); +} + +FEC_STATIC LC3PLUS_EpModeRequest dw0_get_epmr(LC3_UINT8 *dw0, LC3_INT16 mode, LC3_INT16 slot_size) +{ + LC3_INT32 ncrc1; + LC3PLUS_EpModeRequest epmr; + + ncrc1 = crc1_bytes_by_mode1[mode]; + + if (slot_size == 40) + { + ncrc1 = crc1_bytes_by_mode0[mode]; + } + + epmr = (LC3PLUS_EpModeRequest)(dw0[2 * ncrc1 - 1] >> 2); + + + + return epmr; +} + + +FEC_STATIC LC3_INT16 fec_data_preproc(LC3_INT16 mode, LC3_INT16 epmr, LC3_UINT8 *iobuf, LC3_UINT8 *cw_buf, LC3_INT16 data_bytes, + LC3_INT16 slot_bytes, LC3_INT16 pc_split) +{ + LC3_INT16 data_offset, n_crc1, n_crc2; + LC3_INT32 i, j; + + data_offset = 2*(slot_bytes - data_bytes); + + /* extract and reverse data*/ + j = 2*slot_bytes - 1; + for (i = 0; i < data_bytes; i++) + { + cw_buf[j--] = iobuf[i] & 15; + cw_buf[j--] = iobuf[i] >> 4; + } + + /* add crc hashes */ + if (slot_bytes == 40) + { + n_crc1 = crc1_bytes_by_mode0[mode]; + } + else + { + n_crc1 = crc1_bytes_by_mode1[mode]; + } + + if (pc_split > 0 && mode > 1) + { + n_crc2 = crc2_bytes_by_mode[mode]; + } + else + { + n_crc2 = 0; + } + + if (n_crc2) + { + crc2(cw_buf + data_offset + 2 * data_bytes - pc_split, pc_split, cw_buf + data_offset - 2 * n_crc2, n_crc2, 0); + } + if (n_crc1) + { + crc1(cw_buf + data_offset, 2 * data_bytes - pc_split, epmr, cw_buf + data_offset - 2 * (n_crc1 + n_crc2), n_crc1, + 0); + } + + data_offset -= 2* (n_crc1 + n_crc2); + + dw0_bitswap(cw_buf + data_offset, mode, slot_bytes); + + + + return data_offset; +} + +void fec_encoder(LC3_INT16 mode, LC3_INT16 epmr, LC3_UINT8 *iobuf, LC3_INT16 data_bytes, LC3_INT16 slot_bytes, LC3_INT16 n_pccw) +{ + LC3_INT16 n_codewords, codeword_length, hd, redundancy_nibbles, cw_offset, dw_offset, pc_split; + LC3_INT32 i, j; + LC3_UINT8 cw_buf[2 * FEC_SLOT_BYTES_MAX]; + + cw_offset = 0; + dw_offset = 0; + pc_split = 0; + + n_codewords = get_n_codewords(slot_bytes); + + /* some sanity checks */ + { + LC3_INT32 tmp = slot_bytes; + + assert((slot_bytes >= FEC_SLOT_BYTES_MIN && slot_bytes <= FEC_SLOT_BYTES_MAX) && + "fec_encoder: slot_bytes out of range"); + tmp -= mode == 1 ? 1 : n_codewords * (mode - 1); // reed solomon redundancy + tmp -= slot_bytes == 40 ? crc1_bytes_by_mode0[mode] : crc1_bytes_by_mode1[mode]; // crc1 + tmp -= (n_pccw > 0) && (mode > 1) ? crc2_bytes_by_mode[mode] : 0; // crc2 + assert(data_bytes == tmp && "fec_encoder: inconsistent payload size"); + assert(n_codewords - n_pccw >= 6); + } + + /* data preproc: re-ordering and hash extension */ + pc_split = fec_get_n_pc(mode, n_pccw, slot_bytes); + + dw_offset = fec_data_preproc(mode, epmr, iobuf, cw_buf, data_bytes, slot_bytes, pc_split); + + /* encoding of first data word*/ + hd = hamming_distance_by_mode0[mode]; + redundancy_nibbles = hd - 1; + codeword_length = get_codeword_length(n_codewords, 2 * slot_bytes, 0); + + assert(codeword_length == (2 * slot_bytes - 1) / n_codewords + 1); + + for (j = redundancy_nibbles; j < codeword_length; (j++, dw_offset++)) + { + cw_buf[j] = cw_buf[dw_offset]; + } + + rs16_enc(cw_buf, codeword_length, hd, mode, 1); + + cw_offset += codeword_length; + + /* encoding of remaining data words */ + hd = hamming_distance_by_mode1[mode]; + redundancy_nibbles = hd - 1; + + for (i = 1; i < n_codewords; i++) + { + codeword_length = get_codeword_length(n_codewords, 2*slot_bytes, i); + + for (j = redundancy_nibbles; j < codeword_length; (j++, dw_offset++)) + { + cw_buf[cw_offset + j] = cw_buf[dw_offset]; + } + + rs16_enc(cw_buf + cw_offset, codeword_length, hd, mode, i < 6); + + cw_offset += codeword_length; + } + + assert(cw_offset == 2 * slot_bytes && dw_offset == 2 * slot_bytes); + + fec_interleave_pack(iobuf, cw_buf, 2 * slot_bytes, n_codewords); + + +} + +FEC_STATIC void rs16_enc(LC3_UINT8 *iobuf, LC3_INT16 codeword_length, LC3_INT16 hamming_distance, LC3_INT16 fec_mode, + LC3_INT16 signal_mode) +/* expects (data polynomial) * x^(hamming_distance - 1) in iobuf */ +{ + LC3_UINT8 const *gp; + LC3_UINT8 shift_buffer[RS16_CW_LEN_MAX + 1], lc; + LC3_INT32 i, j, deg_gp; + + memset(shift_buffer, 0, sizeof(shift_buffer)); + gp = rs16_gp_by_hd[hamming_distance]; + deg_gp = hamming_distance - 1; + + if (hamming_distance > 1) + { + assert(codeword_length > deg_gp); + + /* initialize redundancy part to zero */ + memset(iobuf, 0, deg_gp); + + /* initialize shift_buffer */ + memmove(shift_buffer + 1, iobuf + codeword_length - deg_gp, deg_gp); + + /* calculate remainder */ + for (i = codeword_length - deg_gp - 1; i >= 0; i--) + { + shift_buffer[0] = iobuf[i]; + lc = shift_buffer[deg_gp] << 4; + + for (j = deg_gp - 1; j >= 0; j--) + { + shift_buffer[j + 1] = GF16_ADD(shift_buffer[j], GF16_MUL0(gp[j], lc)); + } + } + + /* add remainder to shifted data polynomial */ + for (i = 0; i < deg_gp; i++) + { + iobuf[i] = shift_buffer[i + 1]; + } + + /* add signaling polynomial */ + if (signal_mode) + { + assert(codeword_length > EP_SIG_POLY_DEG); + for (i = 0; i <= EP_SIG_POLY_DEG; i++) + { + iobuf[i] = GF16_ADD(iobuf[i], sig_polys[fec_mode - 1][i]); + } + } + } + + +} + +FEC_STATIC void fec_interleave_pack(LC3_UINT8 *out, LC3_UINT8 *in, LC3_INT16 n_nibbles, LC3_INT16 n_codewords) +{ + LC3_INT16 out_offset, cw_offset, codeword_length; + LC3_INT32 i, j; + + out_offset = 0; + cw_offset = 0; + + /* initialize output buffer to zero */ + memset(out, 0, n_nibbles >> 1); + + /* interleave and pack codewords */ + for (i = 0; i < n_codewords; i++) + { + codeword_length = get_codeword_length(n_codewords, n_nibbles, i); + + for (j = 0; j < codeword_length; j++) + { + out_offset = n_nibbles - 1 - j*n_codewords - i; + out[out_offset >> 1] |= in[cw_offset] << ((out_offset & 1) << 2); + cw_offset = cw_offset + 1; + } + } + + + assert(cw_offset == n_nibbles); +} + +/* Decoder */ +FEC_STATIC void fec_data_postproc(LC3_INT16 mode, LC3PLUS_EpModeRequest *epmr, LC3_UINT8 *obuf, LC3_INT16 data_bytes, LC3_UINT8 *cw_buf, + LC3_INT16 slot_bytes, LC3_INT16 pc_split, LC3_INT32 *bfi) +{ + LC3_INT16 i; + LC3_INT16 n_crc1, n_crc2; + LC3_INT16 cw_buf_len; + LC3PLUS_EpModeRequest tmp_epmr; + + n_crc1 = crc1_bytes_by_mode1[mode]; + if (slot_bytes == 40) + { + n_crc1 = crc1_bytes_by_mode0[mode]; + } + + n_crc2 = 0; + if (pc_split > 0) + { + n_crc2 = crc2_bytes_by_mode[mode]; + } + + assert(n_crc1 == (slot_bytes == 40 ? crc1_bytes_by_mode0[mode] : crc1_bytes_by_mode1[mode])); + assert(n_crc2 == ((pc_split > 0) && (mode > 1) ? crc2_bytes_by_mode[mode] : 0)); + + cw_buf_len = 2 * (data_bytes + n_crc1 + n_crc2); + + if ((mode - 1)) + { + /* reverse bit-swap */ + dw0_bitswap(cw_buf, mode, slot_bytes); + tmp_epmr = dw0_get_epmr(cw_buf, mode, slot_bytes); + + if (crc1(cw_buf + ((n_crc1 + n_crc2) << 1), ((data_bytes << 1) - pc_split), tmp_epmr, cw_buf, n_crc1, 1)) + { + *bfi = 1; + + return; + } + else + { + *epmr = tmp_epmr; + } + } + + if (pc_split > 0 && *bfi != 2) + { + if (crc2(cw_buf + (((data_bytes + (n_crc1 + n_crc2)) << 1) - pc_split), pc_split, + cw_buf + (n_crc1 << 1), n_crc2, 1)) + { + *bfi = 2; + } + } + + for (i = 0; i < data_bytes; i++) + { + obuf[i] = (LC3_UINT8)(cw_buf[cw_buf_len - 2 * i - 1] | (cw_buf[cw_buf_len - 2 * i - 2] << 4)); + } + + +} + +LC3_INT32 fec_decoder(LC3_UINT8 *iobuf, LC3_INT16 slot_bytes, LC3_INT32 *data_bytes, LC3PLUS_EpModeRequest *epmr, LC3_INT16 ccc_flag, LC3_INT16 *n_pccw, + LC3_INT32 *bfi, LC3_INT16 *be_bp_left, LC3_INT16 *be_bp_right, LC3_INT16 *n_pc, LC3_INT16 *m_fec) +{ + LC3_UINT8 cw_buf[2 * FEC_SLOT_BYTES_MAX]; + LC3_UINT8 array_of_trust[MAX_LEN]; + LC3_INT16 i, j; + LC3_INT16 cw_offset, dw_offset; + LC3_INT16 n_codewords, redundancy_nibbles, codeword_length; + LC3_INT16 mode, error_report; + LC3_INT16 n_crc; + LC3_INT16 first_bad_cw; + LC3_INT16 pc_split; + + UNUSED(n_crc); + + + if (*bfi == 1) + { + + return ERROR_REPORT_BEC_MASK; + } + + if (slot_bytes < FEC_SLOT_BYTES_MIN || slot_bytes > FEC_SLOT_BYTES_MAX) + { + *bfi = 1; + + return ERROR_REPORT_BEC_MASK; + } + + if (ccc_flag == 0) + { + *be_bp_left = -1; + *be_bp_right = -1; + } + + n_codewords = get_n_codewords(slot_bytes); + + /* extract and de-interleave nibbles */ + fec_deinterleave_unpack(cw_buf, iobuf, 2 * slot_bytes, n_codewords); + + /* mode detection and error correction */ + mode = rs16_detect_and_correct(cw_buf, 2 * slot_bytes, n_codewords, epmr, &error_report, bfi, array_of_trust, + ccc_flag, n_pccw); + + /* for normal slots the maximal number of bit errors is limited */ +#ifndef APPLY_MAX_ERRORS + if (slot_bytes == 40 && mode > 0) + { + if ((error_report & ERROR_REPORT_BEC_MASK) > low_br_max_bit_errors_by_mode[mode]) + { + error_report &= ERROR_REPORT_BEC_MASK; + mode = -1; + *bfi = 1; + } + else + { + if ((error_report & ERROR_REPORT_BEC_MASK) > low_br_max_bit_errors_by_mode[2]) + { + error_report &= ~ERROR_REPORT_EP2_OK; + } + if ((error_report & ERROR_REPORT_BEC_MASK) > low_br_max_bit_errors_by_mode[3]) + { + error_report &= ~ERROR_REPORT_EP3_OK; + } + } + } +#endif + + if (*bfi == 1) + { + *data_bytes = 0; + + + return error_report; + } + + /* initialization for decoding */ + *data_bytes = fec_get_data_size(mode, ccc_flag, slot_bytes); + pc_split = fec_get_n_pc(mode, *n_pccw, slot_bytes); + n_crc = get_total_crc_size(slot_bytes, mode, pc_split); + + /* decoding of first code word */ + redundancy_nibbles = hamming_distance_by_mode0[mode] - 1; + codeword_length = get_codeword_length(n_codewords, slot_bytes + slot_bytes, 0); + + dw_offset = 0; + cw_offset = 0; + + for (j = redundancy_nibbles; j < codeword_length; j++) + { + cw_buf[dw_offset++] = cw_buf[j]; + } + cw_offset = cw_offset + codeword_length; + + /* decoding of remaining code words */ + redundancy_nibbles = hamming_distance_by_mode1[mode] - 1; + + for (i = 1; i < n_codewords; i++) + { + codeword_length = get_codeword_length(n_codewords, slot_bytes + slot_bytes, i); + + for (j = redundancy_nibbles; j < codeword_length; j++) + { + cw_buf[dw_offset++] = cw_buf[j + cw_offset]; + } + + cw_offset = cw_offset + codeword_length; + } + + /* data postproc: hash validation and re-ordering */ + + fec_data_postproc(mode, epmr, iobuf, *data_bytes, cw_buf, slot_bytes, pc_split, bfi); + + if (*bfi == 1) + { + *data_bytes = 0; + + error_report &= ERROR_REPORT_BEC_MASK; + + + return error_report; + } + + if (*bfi == 2) + { + first_bad_cw = 0; + array_of_trust[*n_pccw] = 0; + while (array_of_trust[first_bad_cw] != 0) + { + first_bad_cw = first_bad_cw + 1; + } + if (first_bad_cw == *n_pccw) + { + /* this is the case when CRC failed */ + *be_bp_left = 0; + } + else + { + *be_bp_left = 4*fec_get_n_pc(mode, first_bad_cw, slot_bytes); + } + + for (i = *n_pccw - 1; i >= 0; i--) + { + if (!array_of_trust[i]) + { + break; + } + } + if (i < 0) + { + i = *n_pccw - 1; + } + *be_bp_right = 4*fec_get_n_pc(mode, i + 1, slot_bytes) - 1; + } + + if (ccc_flag == 0) + { + *n_pc = pc_split; + *m_fec = mode; + } + + + return error_report; +} + +FEC_STATIC void fec_deinterleave_unpack(LC3_UINT8 *out, LC3_UINT8 *in, LC3_INT16 n_nibbles, LC3_INT16 n_codewords) +{ + LC3_INT16 in_offset, out_offset, codeword_length; + LC3_INT32 i, j; + + in_offset = 0; + out_offset = 0; + + /* unpack nibbles in input buffer and deinterleave codewords */ + for (i = 0; i < n_codewords; i++) + { + codeword_length = get_codeword_length(n_codewords, n_nibbles, i); + for (j = 0; j < codeword_length; (j++, out_offset++)) + { + in_offset = n_nibbles - 1 - j*n_codewords - i; + out[out_offset] = (in[in_offset >> 1] >> ((in_offset & 1) << 2)) & 15; + } + } + + + assert(out_offset == n_nibbles); + +} + +FEC_STATIC LC3PLUS_EpModeRequest fec_estimate_epmr_from_cw0(LC3_UINT8 *cw0, LC3_INT8 *t, LC3_UINT8 *syndromes, LC3_UINT8 *elp, LC3_INT8 *deg_elp, + LC3_UINT8 *err_pos, LC3_UINT8 *err_symb, LC3_INT16 n_codewords, LC3_INT16 n_symb) +{ + LC3_INT32 epmr_lowest_risk_exp; + LC3_INT32 start, inc, i, n_candidates; + LC3_INT32 first_codeword_length; + LC3_INT32 mode_counter; + LC3PLUS_EpModeRequest epmr; + + epmr_lowest_risk_exp = 0; + first_codeword_length = get_codeword_length(n_codewords, n_symb, 0); + start = 2; + inc = 1; + n_candidates = 0; + + /* test if first code word decodes in mode 0 or 1 without error correction */ + if ((syndromes[SYNDROME_IDX(0, 0)] | syndromes[SYNDROME_IDX(0, 0) + 1]) == 0 || + (syndromes[SYNDROME_IDX(1, 0)] | syndromes[SYNDROME_IDX(1, 0) + 1]) == 0) + { + epmr_lowest_risk_exp = risk_table_f[1][0].exponent; + } + /* test if first code word decodes in mode 2 or 3 with lower risk */ + if (deg_elp[DEG_ELP_IDX(2, 0)] <= t[2]) + { + if (risk_table_f[2][deg_elp[DEG_ELP_IDX(2, 0)]].exponent <= -8) + { + n_candidates++; + start = 2; + } + } + + if (deg_elp[DEG_ELP_IDX(3, 0)] <= t[3]) + { + if (risk_table_f[3][deg_elp[DEG_ELP_IDX(3, 0)]].exponent <= -8) + { + n_candidates++; + start = 3; + } + } + + if (n_candidates > 1) + { + /* decide on order if mode 2 and 3 are considered */ + if (simple_float_cmp(risk_table_f[2][deg_elp[DEG_ELP_IDX(2, 0)]], risk_table_f[3][deg_elp[DEG_ELP_IDX(3, 0)]]) < + 0) + { + start = 2; + inc = 1; + } + else + { + start = 3; + inc = -1; + } + } + + for (mode_counter = start, i = 0; i < n_candidates; mode_counter += inc, i++) + { + if (risk_table_f[mode_counter][deg_elp[DEG_ELP_IDX(mode_counter, 0)]].exponent < epmr_lowest_risk_exp) + { + if (!rs16_factorize_elp(err_pos + ERR_POS_IDX(mode_counter, 0), elp + ELP_IDX(mode_counter, 0), + deg_elp[DEG_ELP_IDX(mode_counter, 0)], first_codeword_length - 1)) + { + /* code word is decodable with error correction */ + epmr_lowest_risk_exp = risk_table_f[mode_counter][deg_elp[DEG_ELP_IDX(mode_counter, 0)]].exponent; + + rs16_calculate_errors(err_symb + ERR_SYMB_IDX(mode_counter, 0), err_pos + ERR_POS_IDX(mode_counter, 0), + syndromes + SYNDROME_IDX(mode_counter, 0), deg_elp[DEG_ELP_IDX(mode_counter, 0)], + t[mode_counter]); + + for (i = 0; i < deg_elp[DEG_ELP_IDX(mode_counter, 0)]; i++) + { + cw0[err_pos[ERR_POS_IDX(mode_counter, 0) + i]] = GF16_ADD( + cw0[err_pos[ERR_POS_IDX(mode_counter, 0) + i]], err_symb[ERR_SYMB_IDX(mode_counter, 0) + i]); + } + break; + } + } + } + + epmr = cw0_get_epmr(cw0, first_codeword_length - 1); + + if (epmr_lowest_risk_exp > -16) + { + epmr += 4; + } + if (epmr_lowest_risk_exp > -8) + { + epmr += 4; + } + + + return epmr; +} + +FEC_STATIC LC3_INT32 rs16_detect_and_correct(LC3_UINT8 *iobuf, LC3_INT32 n_symb, LC3_INT32 n_codewords, LC3PLUS_EpModeRequest *epmr, LC3_INT16 *error_report, + LC3_INT32 *bfi, LC3_UINT8 *array_of_trust, LC3_INT32 ccc_flag, LC3_INT16 *n_pccw) +{ + + LC3_INT16 mode_broken[4]; + LC3_INT16 error_report_ep_ok[4]; + LC3_INT16 i, cw_counter, mode_counter, cw_offset; + LC3_INT16 codeword_length; + LC3_INT16 mode; + LC3_INT16 mode_candidates[4]; + LC3_INT16 n_mode_candidates; + LC3_INT16 broken_cw, n_broken_cw; + LC3_INT16 j, idx_min; + LC3_INT16 n_pccw0; + simple_float val_min_f; + LC3_INT16 tmp; + LC3_INT16 epmr_position; + simple_float dec_risk_f[FEC_N_MODES]; + simple_float risk_min_f; + simple_float ep_risk_thresh; + LC3_INT32 epmr_dec_fail_increment; + LC3_UINT8 const *hamming_distance; + LC3_UINT8 syndromes[FEC_TOTAL_SYNDROME_SIZE]; + LC3_UINT8 elp[FEC_TOTAL_ELP_SIZE]; + LC3_UINT8 err_pos[FEC_TOTAL_ERR_POS_SIZE]; + LC3_UINT8 err_symb[FEC_TOTAL_ERROR_SIZE]; + LC3_INT8 t[FEC_N_MODES]; + LC3_INT8 deg_elp[FEC_TOTAL_DEG_ELP_SIZE]; + LC3_UINT8 blacklist[FEC_N_MODES]; + LC3_INT32 rop; + + void (*syndr_calc[3])(LC3_UINT8 *, LC3_UINT8 *, LC3_INT32); + rop = 0; + + /* initialization */ + blacklist[0] = 0; + blacklist[1] = 0; + blacklist[2] = 0; + blacklist[3] = 0; + mode_broken[0] = 0; + mode_broken[1] = 0; + mode_broken[2] = 0; + mode_broken[3] = 0; + error_report_ep_ok[0] = ERROR_REPORT_EP1_OK; + error_report_ep_ok[1] = ERROR_REPORT_EP2_OK; + error_report_ep_ok[2] = ERROR_REPORT_EP3_OK; + error_report_ep_ok[3] = ERROR_REPORT_EP4_OK; + hamming_distance = &hamming_distance_by_mode0[1]; + mode = -1; + n_mode_candidates = 0; + risk_min_f.mantissa = SIMPLE_FLOAT_1_MANTISSA; + risk_min_f.exponent = 0; + + if (n_symb <= 80) + { + ep_risk_thresh.mantissa = EP_RISK_THRESH_NS_M; + ep_risk_thresh.exponent = EP_RISK_THRESH_NS_E; + } + else + { + ep_risk_thresh.mantissa = EP_RISK_THRESH_OS_M; + ep_risk_thresh.exponent = EP_RISK_THRESH_OS_E; + } + + syndr_calc[0] = &rs16_calculate_two_syndromes; + syndr_calc[1] = &rs16_calculate_four_syndromes; + syndr_calc[2] = &rs16_calculate_six_syndromes; + + for (i = 0; i < FEC_N_MODES; i++) + { + t[i] = (hamming_distance[i] -1)/2; + } + + *error_report = 0; + *bfi = 0; + + /* mode detection (stage 1) */ + codeword_length = get_codeword_length(n_codewords, n_symb, 0); + + epmr_position = codeword_length - 1; + + rs16_calculate_two_syndromes(syndromes + SYNDROME_IDX(0, 0), iobuf, codeword_length - 1); + + if ((syndromes[0 + SYNDROME_IDX(0, 0)] | syndromes[1 + SYNDROME_IDX(0, 0)]) == 0) + { + + /* data validation for fec mode 1 */ + *epmr = cw0_get_epmr(iobuf, epmr_position); + + dw0_bitswap(iobuf + 2, 1, n_symb / 2); + + if (!crc1(iobuf + 8, n_symb - 8, *epmr, iobuf + 2, 3, 1)) + { + *error_report |= ERROR_REPORT_ALL_OK; + mode = 0; + + + rop = mode + 1; + goto CLEANUP; + } + else + { + /* reverse bit swap */ + dw0_bitswap(iobuf + 2, 1, n_symb / 2); + + *epmr += 4; + } + } + + blacklist[0] = 1; + + /* mode detection (stage 2) */ + + /* calculate syndromes of code words 0 to 5 and modes 1 to 3 */ + cw_offset = 0; + + for (cw_counter = 0; cw_counter < 6; cw_counter++) + { + codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); + + rs16_calculate_six_syndromes(syndromes + SYNDROME_IDX(1, cw_counter), iobuf + cw_offset, + codeword_length - 1); + + cw_offset += codeword_length; + + for (mode_counter = FEC_N_MODES - 1; mode_counter >= 1; mode_counter--) + { + for (i = 0; i < hamming_distance[mode_counter] - 1; i++) + { + syndromes[SYNDROME_IDX(mode_counter, cw_counter) + i] = GF16_ADD( + syndromes[SYNDROME_IDX(1, cw_counter) + i], sig_poly_syndr[mode_counter][i]); + } + } + } + + /* check for valid code words */ + for (mode_counter = 1; mode_counter < FEC_N_MODES; mode_counter++) + { + n_broken_cw = 0; + for (cw_counter = 0; cw_counter < 6; cw_counter++) + { + broken_cw = 0; + for (i = 0; i < hamming_distance[mode_counter] - 1; i++) + { + broken_cw |= syndromes[SYNDROME_IDX(mode_counter, cw_counter) + i]; + } + if (broken_cw != 0) + { + n_broken_cw ++; + } + } + + if (n_broken_cw == 0) + { + mode = mode_counter; + cw_offset = 0; + + *epmr = cw0_get_epmr(iobuf, epmr_position); + + for (cw_counter = 0; cw_counter < 6; cw_counter++) + { + codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); + for (i = 0; i <= EP_SIG_POLY_DEG; i++) + { + iobuf[cw_offset + i] = GF16_ADD(iobuf[cw_offset + i], sig_polys[mode][i]); + } + cw_offset += codeword_length; + } + } + } + + if (mode < 0) /* mode hasn't been detected so far -> errors occurred in transmission */ + { + /* calculate error locator polynomials for code words 0 to 5 */ + for (mode_counter = 1; mode_counter < FEC_N_MODES; mode_counter++) + { + for (cw_counter = 0; cw_counter < 6; cw_counter++) + { + deg_elp[DEG_ELP_IDX(mode_counter, cw_counter)] = rs16_calculate_elp( + elp + ELP_IDX(mode_counter, cw_counter), syndromes + SYNDROME_IDX(mode_counter, cw_counter), + t[mode_counter]); + if (deg_elp[DEG_ELP_IDX(mode_counter, cw_counter)] > t[mode_counter]) + { + blacklist[mode_counter] = 1; + break; + } + } + } + + /* risk analysis for mode candidate selection */ + for (mode_counter = 1; mode_counter < FEC_N_MODES; mode_counter++) + { + dec_risk_f[mode_counter].mantissa = SIMPLE_FLOAT_1_MANTISSA; + dec_risk_f[mode_counter].exponent = 0; + + if (blacklist[mode_counter] == 0) + { + for (cw_counter = 0; cw_counter < 6; cw_counter++) + { + dec_risk_f[mode_counter] = simple_float_mul( + dec_risk_f[mode_counter], + risk_table_f[mode_counter][deg_elp[DEG_ELP_IDX(mode_counter, cw_counter)]]); + } + + if (simple_float_cmp(dec_risk_f[mode_counter], ep_risk_thresh) <= 0) + { + mode_candidates[n_mode_candidates++] = mode_counter; + } + + if (simple_float_cmp(dec_risk_f[mode_counter], risk_min_f) < 0) + { + risk_min_f = dec_risk_f[mode_counter]; + } + } + } + assert(n_mode_candidates <= 4); // suppress false gcc warning when OPTIM=3 + + /* sort mode candidates by risk */ + for (i = 0; i < n_mode_candidates; i++) + { + idx_min = i; + val_min_f = dec_risk_f[mode_candidates[i]]; + + for (j = i + 1; j < n_mode_candidates; j++) + { + if (simple_float_cmp(dec_risk_f[mode_candidates[j]], val_min_f) < 0) + { + val_min_f = dec_risk_f[mode_candidates[j]]; + idx_min = j; + } + } + + if (idx_min > i) + { + tmp = mode_candidates[i]; + mode_candidates[i] = mode_candidates[idx_min]; + mode_candidates[idx_min] = tmp; + } + } + + /* try out candidate modes */ + for (i = 0; i < n_mode_candidates; i++) + { + mode = mode_candidates[i]; + + for (cw_counter = 0; cw_counter < 6; cw_counter++) + { + codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); + + if (deg_elp[DEG_ELP_IDX(mode, cw_counter)]) + { + if (rs16_factorize_elp(err_pos + ERR_POS_IDX(mode, cw_counter), elp + ELP_IDX(mode, cw_counter), + deg_elp[DEG_ELP_IDX(mode, cw_counter)], codeword_length - 1)) + { + /* elp did not split into distinct linear factors or error position was out of range */ + mode = -1; + break; + } + } + } + if (mode > 0) + { + /* decodable mode with lowest risk has been found */ + break; + } + } + + if (mode < 0) + { + /* no decodable mode has been found */ + *error_report = ERROR_REPORT_BEC_MASK; + *bfi = 1; + mode = -1; + + *epmr = fec_estimate_epmr_from_cw0(iobuf, t, syndromes, elp, deg_elp, err_pos, err_symb, n_codewords, + n_symb); + + + rop = mode; + goto CLEANUP; + } + + /* perform error correction */ + cw_offset = 0; + *error_report = 0; + for (cw_counter = 0; cw_counter < 6; cw_counter++) + { + codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); + + if (deg_elp[DEG_ELP_IDX(mode, cw_counter)]) + { + rs16_calculate_errors( + err_symb + ERR_SYMB_IDX(mode, cw_counter), err_pos + ERR_POS_IDX(mode, cw_counter), + syndromes + SYNDROME_IDX(mode, cw_counter), deg_elp[DEG_ELP_IDX(mode, cw_counter)], t[mode]); + + /* correct errors and sum up number of corrected bits */ + for (i = 0; i < deg_elp[DEG_ELP_IDX(mode, cw_counter)]; i++) + { + iobuf[err_pos[ERR_POS_IDX(mode, cw_counter) + i] + cw_offset] = + GF16_ADD(iobuf[err_pos[ERR_POS_IDX(mode, cw_counter) + i] + cw_offset], + err_symb[ERR_SYMB_IDX(mode, cw_counter) + i]); + *error_report += rs16_bit_count_table[err_symb[ERR_SYMB_IDX(mode, cw_counter) + i]]; + } + + for (i = 0; i < mode; i ++) + { + if(deg_elp[DEG_ELP_IDX(mode, cw_counter)] > i) + { + mode_broken[i] = 1; + } + } + + } + + for (i = 0; i <= EP_SIG_POLY_DEG; i++) + { + iobuf[cw_offset + i] = GF16_ADD(iobuf[cw_offset + i], sig_polys[mode][i]); + } + cw_offset += codeword_length; + } + + /* set epmr according to risk value of cw0 */ + epmr_dec_fail_increment = 8; + + if (risk_table_f[mode][deg_elp[DEG_ELP_IDX(mode, 0)]].exponent <= -8) + { + epmr_dec_fail_increment -= 4; + } + if (risk_table_f[mode][deg_elp[DEG_ELP_IDX(mode, 0)]].exponent <= -16) + { + epmr_dec_fail_increment -= 4; + } + + *epmr = (LC3PLUS_EpModeRequest)(cw0_get_epmr(iobuf, epmr_position) + epmr_dec_fail_increment); + } + + /* mode has been successfully detected -> now check and try to correct remaining code words*/ + *n_pccw = fec_get_n_pccw(n_symb / 2, mode + 1, ccc_flag); + if (ccc_flag == 0) + { + n_pccw0 = fec_get_n_pccw(n_symb / 2, mode + 1, ccc_flag); + *n_pccw = n_pccw0; + } + else + { + n_pccw0 = 0; + } + + for (cw_counter = 6; cw_counter < n_codewords; cw_counter++) + { + /* usual error correction scheme: syndromes -> elp's, errors, etc. */ + codeword_length = get_codeword_length(n_codewords, n_symb, cw_counter); + array_of_trust[n_codewords - 1 - cw_counter] = 1; + + syndr_calc[t[mode] - 1](syndromes, iobuf + cw_offset, codeword_length -1); + + deg_elp[0] = rs16_calculate_elp(elp, syndromes, t[mode]); + + for (i = 0; i < mode; i ++) + { + if (deg_elp[0] > i) + { + mode_broken[i] = 1; + } + } + + if (deg_elp[0] > t[mode]) + { + for (i = 0; i < 4; i ++) + { + mode_broken[i] = 1; + } + cw_offset += codeword_length; + if (cw_counter < n_codewords - n_pccw0) + { + *error_report = ERROR_REPORT_BEC_MASK; + mode = -1; + *bfi = 1; + break; + } + else + { + *bfi = 2; + array_of_trust[n_codewords - 1 - cw_counter] = 0; + continue; + } + } + + if (deg_elp[0]) + { + if (rs16_factorize_elp(err_pos, elp, deg_elp[0], codeword_length - 1)) + { + cw_offset += codeword_length; + for (i = 0; i < 4; i ++) + { + mode_broken[i] = 1; + } + if (cw_counter < n_codewords - n_pccw0) + { + *error_report = ERROR_REPORT_BEC_MASK; + mode = -1; + *bfi = 1; + + break; + } + else + { + *bfi = 2; + array_of_trust[n_codewords - 1 - cw_counter] = 0; + continue; + } + } + + rs16_calculate_errors(err_symb, err_pos, syndromes, deg_elp[0], t[mode]); + + /* correct errors and sum up number of corrected bits */ + for (i = 0; i < deg_elp[0]; i++) + { + iobuf[err_pos[i] + cw_offset] = GF16_ADD(iobuf[err_pos[i] + cw_offset], err_symb[i]); + *error_report += rs16_bit_count_table[err_symb[i]]; + } + } + cw_offset += codeword_length; + if (risk_table_f[mode][deg_elp[0]].exponent > -16) + { + array_of_trust[n_codewords - 1 - cw_counter] = 0; + } + } + + *error_report &= ERROR_REPORT_BEC_MASK; + for (i = 0; i < 4; i ++) + { + if (!mode_broken[i]) + { + *error_report |= error_report_ep_ok[i]; + } + } + + if (mode >= 0) + { + rop = mode + 1; + } else { + rop = -1; + } + + + +CLEANUP: + return rop; +} + +FEC_STATIC void rs16_calculate_six_syndromes(LC3_UINT8 *syndromes, LC3_UINT8 *cw, LC3_INT32 cw_poly_deg) +{ + LC3_INT32 i; + LC3_UINT8 buffer[15]; + + assert(cw_poly_deg >= 12); + + for (i = 0; i <= cw_poly_deg; i++) + { + buffer[i] = cw[i]; + } + + syndromes[0] = buffer[0]; + syndromes[1] = buffer[0]; + syndromes[2] = buffer[0]; + syndromes[3] = buffer[0]; + syndromes[4] = buffer[0]; + syndromes[5] = buffer[0]; + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[1], 32)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[1], 64)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[1], 128)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[1], 48)); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[1], 96)); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[1], 192)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[2], 64)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[2], 48)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[2], 192)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[2], 80)); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[2], 112)); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[2], 240)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[3], 128)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[3], 192)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[3], 160)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[3], 240)); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[3], 16)); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[3], 128)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[4], 48)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[4], 80)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[4], 240)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[4], 32)); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[4], 96)); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[4], 160)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[5], 96)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[5], 112)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[5], 16)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[5], 96)); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[5], 112)); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[5], 16)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[6], 192)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[6], 240)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[6], 128)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[6], 160)); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[6], 16)); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[6], 192)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[7], 176)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[7], 144)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[7], 192)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[7], 208)); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[7], 96)); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[7], 240)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[8], 80)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[8], 32)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[8], 160)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[8], 64)); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[8], 112)); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[8], 128)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[9], 160)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[9], 128)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[9], 240)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[9], 192)); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[9], 16)); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[9], 160)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[10], 112)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[10], 96)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[10], 16)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[10], 112)); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[10], 96)); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[10], 16)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[11], 224)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[11], 176)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[11], 128)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[11], 144)); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[11], 112)); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[11], 192)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[12], 240)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[12], 160)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[12], 192)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[12], 128)); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[12], 16)); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[12], 240)); + + if (cw_poly_deg >= 13) + { + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[13], 208)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[13], 224)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[13], 160)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[13], 176)); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[13], 96)); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[13], 128)); + } + + if (cw_poly_deg >= 14) + { + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[14], 144)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[14], 208)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[14], 240)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[14], 224)); + syndromes[4] = GF16_ADD(syndromes[4], GF16_MUL0(buffer[14], 112)); + syndromes[5] = GF16_ADD(syndromes[5], GF16_MUL0(buffer[14], 160)); + } + + +} + +FEC_STATIC void rs16_calculate_four_syndromes(LC3_UINT8 *syndromes, LC3_UINT8 *cw, LC3_INT32 cw_poly_deg) +{ + LC3_INT32 i; + LC3_UINT8 buffer[15]; + + assert(cw_poly_deg >= 12); + + for (i = 0; i <= cw_poly_deg; i++) + { + buffer[i] = cw[i]; + } + + syndromes[0] = buffer[0]; + syndromes[1] = buffer[0]; + syndromes[2] = buffer[0]; + syndromes[3] = buffer[0]; + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[1], 32)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[1], 64)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[1], 128)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[1], 48)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[2], 64)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[2], 48)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[2], 192)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[2], 80)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[3], 128)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[3], 192)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[3], 160)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[3], 240)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[4], 48)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[4], 80)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[4], 240)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[4], 32)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[5], 96)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[5], 112)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[5], 16)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[5], 96)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[6], 192)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[6], 240)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[6], 128)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[6], 160)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[7], 176)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[7], 144)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[7], 192)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[7], 208)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[8], 80)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[8], 32)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[8], 160)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[8], 64)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[9], 160)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[9], 128)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[9], 240)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[9], 192)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[10], 112)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[10], 96)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[10], 16)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[10], 112)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[11], 224)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[11], 176)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[11], 128)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[11], 144)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[12], 240)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[12], 160)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[12], 192)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[12], 128)); + + if (cw_poly_deg >= 13) + { + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[13], 208)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[13], 224)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[13], 160)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[13], 176)); + } + + if (cw_poly_deg >= 14) + { + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[14], 144)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[14], 208)); + syndromes[2] = GF16_ADD(syndromes[2], GF16_MUL0(buffer[14], 240)); + syndromes[3] = GF16_ADD(syndromes[3], GF16_MUL0(buffer[14], 224)); + } + + +} + +FEC_STATIC void rs16_calculate_two_syndromes(LC3_UINT8 *syndromes, LC3_UINT8 *cw, LC3_INT32 cw_poly_deg) +{ + LC3_INT32 i; + LC3_UINT8 buffer[15]; + + assert(cw_poly_deg >= 12); + + for (i = 0; i <= cw_poly_deg; i++) + { + buffer[i] = cw[i]; + } + + syndromes[0] = buffer[0]; + syndromes[1] = buffer[0]; + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[1], 32)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[1], 64)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[2], 64)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[2], 48)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[3], 128)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[3], 192)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[4], 48)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[4], 80)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[5], 96)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[5], 112)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[6], 192)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[6], 240)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[7], 176)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[7], 144)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[8], 80)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[8], 32)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[9], 160)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[9], 128)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[10], 112)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[10], 96)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[11], 224)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[11], 176)); + + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[12], 240)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[12], 160)); + + if (cw_poly_deg >= 13) + { + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[13], 208)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[13], 224)); + } + + if (cw_poly_deg >= 14) + { + syndromes[0] = GF16_ADD(syndromes[0], GF16_MUL0(buffer[14], 144)); + syndromes[1] = GF16_ADD(syndromes[1], GF16_MUL0(buffer[14], 208)); + } + + +} + +FEC_STATIC LC3_INT8 rs16_calculate_elp(LC3_UINT8 *elp, LC3_UINT8 *syndromes, LC3_INT16 t) +/* calculates error locator polynomial vie Petterson's algorithm */ +{ + LC3_INT8 ret; + LC3_UINT8 det, det_inv, aux, all_s, *s; + LC3_UINT8 s22, s33, s44, s13, s14, s15; + LC3_UINT8 s23, s24, s25, s34, s35; + LC3_UINT8 a, b, c, d, e, f; + + ret = 0; + all_s = 0; + s = syndromes; + elp[0] = 1; + memset(elp + 1, 0, 3); + + switch (t) + { + case 3: + { + /* check for errors */ + all_s = s[0] | s[1] | s[2] | s[3] | s[4] | s[5]; + + if (all_s == 0) + { + break; + } + + /* assume 3 errors */ + s22 = GF16_MUL(s[1], s[1]); + s33 = GF16_MUL(s[2], s[2]); + s44 = GF16_MUL(s[3], s[3]); + s13 = GF16_MUL(s[0], s[2]); + + det = GF16_ADD(GF16_ADD(GF16_MUL(s13, s[4]), GF16_MUL(s44, s[0])), + GF16_ADD(GF16_MUL(s22, s[4]), GF16_MUL(s33, s[2]))); + + if (det) + { + det_inv = gf16_inv_table[det] << 4; + + s14 = GF16_MUL(s[0], s[3]); + s15 = GF16_MUL(s[0], s[4]); + + s23 = GF16_MUL(s[1], s[2]); + s24 = GF16_MUL(s[1], s[3]); + s25 = GF16_MUL(s[1], s[4]); + + s34 = GF16_MUL(s[2], s[3]); + s35 = GF16_MUL(s[2], s[4]); + + a = GF16_ADD(s35, s44) << 4; + b = GF16_ADD(s15, s33) << 4; + c = GF16_ADD(s13, s22) << 4; + d = GF16_ADD(s34, s25) << 4; + e = GF16_ADD(s23, s14) << 4; + f = GF16_ADD(s24, s33) << 4; + + aux = GF16_ADD(GF16_ADD(GF16_MUL0(a, s[3]), GF16_MUL0(d, s[4])), GF16_MUL0(f, s[5])); + elp[3] = GF16_MUL0(aux, det_inv); + + aux = GF16_ADD(GF16_ADD(GF16_MUL0(d, s[3]), GF16_MUL0(b, s[4])), GF16_MUL0(e, s[5])); + elp[2] = GF16_MUL0(aux, det_inv); + + aux = GF16_ADD(GF16_ADD(GF16_MUL0(f, s[3]), GF16_MUL0(e, s[4])), GF16_MUL0(c, s[5])); + elp[1] = GF16_MUL0(aux, det_inv); + + if (elp[3] == 0) + { + ret = t+1; + } + else + { + ret = 3; + } + break; + } + + /* assume two errors */ + det = GF16_ADD(GF16_MUL(syndromes[0], syndromes[2]), GF16_MUL(syndromes[1], syndromes[1])); + + if (det) + { + det_inv = gf16_inv_table[det] << 4; + + aux = GF16_ADD(GF16_MUL(syndromes[1], syndromes[2]), GF16_MUL(syndromes[0], syndromes[3])); + elp[1] = GF16_MUL0(aux, det_inv); + + aux = GF16_ADD(GF16_MUL(syndromes[2], syndromes[2]), GF16_MUL(syndromes[1], syndromes[3])); + elp[2] = GF16_MUL0(aux, det_inv); + + /* check remaining LSF relations */ + aux = GF16_ADD(GF16_ADD(GF16_MUL(elp[2], s[2]), GF16_MUL(elp[1], s[3])), s[4]) + | GF16_ADD(GF16_ADD(GF16_MUL(elp[2], s[3]), GF16_MUL(elp[1], s[4])), s[5]); + + aux |= elp[2] == 0; + + if (aux != 0) + { + ret = t + 1; + } + else + { + ret = 2; + } + break; + } + + /* assume one error */ + if (syndromes[0] != 0) + { + elp[1] = GF16_MUL(syndromes[1], gf16_inv_table[syndromes[0]]); + + /* check remaining LSF relations */ + aux = GF16_ADD(GF16_MUL(elp[1], s[1]), s[2]) + | GF16_ADD(GF16_MUL(elp[1], s[2]), s[3]) + | GF16_ADD(GF16_MUL(elp[1], s[3]), s[4]) + | GF16_ADD(GF16_MUL(elp[1], s[4]), s[5]); + + aux |= elp[1] == 0; + + if (aux != 0) + { + ret = t + 1; + } + else + { + ret = 1; + } + break; + } + + ret = t + 1; + break; + } + case 2: + { + all_s = s[0] | s[1] | s[2] | s[3]; + + if (all_s == 0) + { + break; + } + + /* assume two errors */ + det = GF16_ADD(GF16_MUL(syndromes[0], syndromes[2]), GF16_MUL(syndromes[1], syndromes[1])); + + if (det) + { + det_inv = gf16_inv_table[det] << 4; + + aux = GF16_ADD(GF16_MUL(syndromes[1], syndromes[2]), GF16_MUL(syndromes[0], syndromes[3])); + elp[1] = GF16_MUL0(aux, det_inv); + + aux = GF16_ADD(GF16_MUL(syndromes[2], syndromes[2]), GF16_MUL(syndromes[1], syndromes[3])); + elp[2] = GF16_MUL0(aux, det_inv); + + if (elp[2] == 0) + { + ret = t + 1; + } + else + { + ret = 2; + } + break; + } + + /* assume one error */ + if (syndromes[0] != 0) + { + elp[1] = GF16_MUL(syndromes[1], gf16_inv_table[syndromes[0]]); + + /* check remaining LSF relation */ + aux = GF16_ADD(GF16_MUL(elp[1], s[1]), s[2]) | GF16_ADD(GF16_MUL(elp[1], s[2]), s[3]); + aux |= elp[1] == 0; + + if (aux != 0) + { + ret = t + 1; + } + else + { + ret = 1; + } + break; + } + + ret = t + 1; + break; + } + case 1: + { + all_s = s[0] | s[1]; + + if (all_s == 0) + { + break; + } + + if (syndromes[0] != 0) + { + elp[1] = GF16_MUL(syndromes[1], gf16_inv_table[syndromes[0]]); + if (elp[1] == 0) + { + ret = t + 1; + } + else + { + ret = 1; + } + break; + } + + ret = t + 1; + break; + } + default: assert(0 && "calculating elp of this degree not implemented"); + } + + + return ret; +} + +FEC_STATIC LC3_INT16 rs16_factorize_elp(LC3_UINT8 *err_pos, LC3_UINT8 *elp, LC3_INT16 deg_elp, LC3_INT16 max_pos) +{ + LC3_UINT8 beta, gamma; + LC3_INT16 zeros, err_pos0, err_pos1, err_pos2, ret; + + beta = 0; + gamma = 0; + zeros = 0; + ret = 0; + + switch (deg_elp) + { + case 0: break; + + case 1: + err_pos0 = gf16_log_g[elp[1]]; + if (err_pos0 > max_pos) + { + ret = 1; + break; + } + + err_pos[0] = (LC3_UINT8)err_pos0; + break; + + case 2: + zeros = rs16_elp_deg2_table[elp[1] | (elp[2] << 4)]; + if (zeros == 0) + { + + return 1; + } + + err_pos0 = zeros & 15; + err_pos1 = (zeros >> 4) & 15; + + if (err_pos0 > max_pos || err_pos1 > max_pos) + { + ret = 1; + break; + } + + err_pos[0] = (LC3_UINT8)err_pos0; + err_pos[1] = (LC3_UINT8)err_pos1; + break; + + case 3: + /* beta = a*a + b, gamma = a*b + c */ + beta = GF16_ADD(GF16_MUL(elp[1], elp[1]), elp[2]); + gamma = GF16_ADD(GF16_MUL(elp[1], elp[2]), elp[3]); + zeros = rs16_elp_deg3_table[beta | gamma << 4]; + + if (zeros == 0) + /* elp does not split over GF(16) or has multiple zeros */ + { + ret = 1; + break; + } + + /* remove shift from zeros */ + err_pos0 = GF16_ADD(zeros & 15, elp[1]); + err_pos1 = GF16_ADD((zeros >> 4) & 15, elp[1]); + err_pos2 = GF16_ADD((zeros >> 8) & 15, elp[1]); + + if (err_pos0 == 0 || err_pos1 == 0 || err_pos2 == 0) + { + + return 1; + } + + err_pos0 = gf16_log_g[err_pos0]; + err_pos1 = gf16_log_g[err_pos1]; + err_pos2 = gf16_log_g[err_pos2]; + + if (err_pos0 > max_pos || err_pos1 > max_pos || err_pos2 > max_pos) + { + ret = 1; + break; + } + + err_pos[0] = (LC3_UINT8)err_pos0; + err_pos[1] = (LC3_UINT8)err_pos1; + err_pos[2] = (LC3_UINT8)err_pos2; + + break; + + default: assert(0 && "invalid degree in rs16_error_locator"); + } + + + return ret; +} + +FEC_STATIC void rs16_calculate_errors(LC3_UINT8 *err_symb, LC3_UINT8 *err_pos, LC3_UINT8 *syndromes, LC3_INT8 deg_elp, LC3_INT8 t) +{ + LC3_UINT8 det_inv; + LC3_UINT8 x0, x1, x2; + LC3_UINT8 x0sq, x1sq, x2sq; + LC3_UINT8 c0, c1, c2; + LC3_UINT8 s0, s1, s2; + LC3_UINT8 tmp; + + UNUSED(t); + + assert(deg_elp <= t); + + switch (deg_elp) + { + case 0: break; + + case 1: + err_symb[0] = GF16_MUL(gf16_g_pow[15 - err_pos[0]], syndromes[0]); + + break; + + case 2: + s0 = (LC3_UINT8) (syndromes[0] << 4); + s1 = (LC3_UINT8) (syndromes[1] << 4); + + x0 = gf16_g_pow[err_pos[0]]; + x1 = gf16_g_pow[err_pos[1]]; + + x0sq = GF16_MUL(x0, x0); + x1sq = GF16_MUL(x1, x1); + + tmp = GF16_ADD(GF16_MUL(x0sq, x1), GF16_MUL(x1sq, x0)); + det_inv = gf16_inv_table[tmp] << 4; + + tmp = GF16_ADD(GF16_MUL0(x1sq, s0), GF16_MUL0(x1, s1)); + err_symb[0] = GF16_MUL0(tmp, det_inv); + + tmp = GF16_ADD(GF16_MUL0(x0sq, s0), GF16_MUL0(x0, s1)); + err_symb[1] = GF16_MUL0(tmp, det_inv); + + break; + + case 3: + s0 = syndromes[0] << 4; + s1 = syndromes[1] << 4; + s2 = syndromes[2] << 4; + + x0 = gf16_g_pow[err_pos[0]]; + x1 = gf16_g_pow[err_pos[1]]; + x2 = gf16_g_pow[err_pos[2]]; + + x0sq = GF16_MUL(x0, x0); + x1sq = GF16_MUL(x1, x1); + x2sq = GF16_MUL(x2, x2); + + tmp = GF16_MUL(GF16_ADD(x1, x0), GF16_ADD(x2, x0)); + tmp = GF16_MUL(GF16_ADD(x2, x1), tmp); + det_inv = gf16_inv_table[tmp] << 4; + + c0 = GF16_ADD(GF16_MUL(x1, x2sq), GF16_MUL(x2, x1sq)); + c1 = GF16_ADD(x2sq, x1sq); + c2 = GF16_ADD(x2, x1); + + err_symb[0] = GF16_ADD(GF16_ADD(GF16_MUL0(c0, s0), GF16_MUL0(c1, s1)), GF16_MUL0(c2, s2)); + + c0 = GF16_ADD(GF16_MUL(x0, x2sq), GF16_MUL(x2, x0sq)); + c1 = GF16_ADD(x2sq, x0sq); + c2 = GF16_ADD(x2, x0); + + err_symb[1] = GF16_ADD(GF16_ADD(GF16_MUL0(c0, s0), GF16_MUL0(c1, s1)), GF16_MUL0(c2, s2)); + + c0 = GF16_ADD(GF16_MUL(x0, x1sq), GF16_MUL(x1, x0sq)); + c1 = GF16_ADD(x1sq, x0sq); + c2 = GF16_ADD(x1, x0); + + err_symb[2] = GF16_ADD(GF16_ADD(GF16_MUL0(c0, s0), GF16_MUL0(c1, s1)), GF16_MUL0(c2, s2)); + + tmp = GF16_MUL0(err_symb[0], det_inv); + err_symb[0] = GF16_MUL(tmp, gf16_inv_table[x0]); + + tmp = GF16_MUL0(err_symb[1], det_inv); + err_symb[1] = GF16_MUL(tmp, gf16_inv_table[x1]); + + tmp = GF16_MUL0(err_symb[2], det_inv); + err_symb[2] = GF16_MUL(tmp, gf16_inv_table[x2]); + + break; + + default: assert(0 && "method not implemented\n"); break; + } + + +} + +/* hash functions for data validation */ + +/* hamming distance 4 */ +static const LC3_UINT32 crc14_mask[16] = {0, 17989, 35978, 51919, 71956, 89937, 103838, 119771, + 143912, 160877, 179874, 194791, 207676, 224633, 239542, 254451}; + +/* hamming distance 4 */ +static const LC3_UINT32 crc22_mask[16] = {0, 4788009, 9576018, 14356859, 19152036, 23933837, 28713718, 33500639, + 33650273, 38304072, 43214899, 47867674, 52775621, 57427436, 62346391, 67001278}; + +FEC_STATIC LC3_INT16 crc1(LC3_UINT8 *data, LC3_INT16 data_size, LC3_INT16 epmr, LC3_UINT8 *hash_val, LC3_INT16 hash_size, LC3_INT16 check) +{ + LC3_UINT32 const *mask; + LC3_INT32 shift, i, fail; + LC3_UINT32 rem; + + fail = 0; + rem = 0; + + assert(hash_size > 0); + + switch (hash_size) + { + case 2: + shift = 14; + mask = crc14_mask; + break; + case 3: + shift = 22; + mask = crc22_mask; + break; + default: + shift = 0; + mask = 0; + assert(0 && "crc hash size not implemented"); + } + + /* data array contains 4-bit words */ + for (i = data_size - 1; i >= 0; i--) + { + rem = (rem << 4) ^ data[i]; + rem ^= mask[(rem >> shift) & 15]; + } + + rem = (rem << 4) ^ (epmr << 2); + rem ^= mask[(rem >> shift) & 15]; + + for (i = 0; i < 2 * hash_size - 1; i++) + { + rem <<= 4; + rem ^= mask[(rem >> shift) & 15]; + } + + rem ^= ((LC3_UINT32) epmr) << shift; + + if (check) + { + /* test hash value */ + for (i = 0; i < 2 * hash_size; i++) + { + fail |= hash_val[i] ^ ((rem >> (4*i)) & 15); + } + } + else + { + /* write hash value */ + for (i = 0; i < 2 * hash_size; i++) + { + hash_val[i] = (LC3_UINT8) ((rem >> (4*i)) & 15); + } + } + + + return fail; +} + +/* hamming distance = 4 */ +static const LC3_UINT32 crc16_mask[16] = {0, 107243, 190269, 214486, 289937, 380538, 428972, 469319, + 579874, 621513, 671263, 761076, 832947, 857944, 938638, 1044581}; + +FEC_STATIC LC3_INT16 crc2(LC3_UINT8 *data, LC3_INT16 data_size, LC3_UINT8 *hash_val, LC3_INT16 hash_size, LC3_INT16 check) +{ + LC3_UINT32 const *mask; + LC3_INT32 shift, i, fail; + LC3_UINT32 rem; + + fail = 0; + rem = 0; + + assert(hash_size > 0); + + switch (hash_size) + { + case 2: + shift = 16; + mask = crc16_mask; + break; + default: + shift = 0; + mask = 0; + assert(0 && "crc hash size not implemented"); + } + + /* data array contains 4-bit words */ + for (i = data_size - 1; i >= 0; i--) + { + rem = (rem << 4) ^ data[i]; + rem ^= mask[(rem >> shift) & 15]; + } + + for (i = 0; i < 2 * hash_size; i++) + { + rem <<= 4; + rem ^= mask[(rem >> shift) & 15]; + } + + if (check) + { + /* test hash value */ + for (i = 0; i < 2 * hash_size; i++) + { + fail |= hash_val[i] ^ ((rem >> (4*i)) & 15); + } + } + else + { + /* write hash value */ + for (i = 0; i < 2 * hash_size; i++) + { + hash_val[i] = (LC3_UINT8) ((rem >> (4*i)) & 15); + } + } + + + return fail; +} + +/* simple float implementation */ +FEC_STATIC simple_float simple_float_mul(simple_float op1, simple_float op2) +{ + simple_float rop; + LC3_INT32 aux; + + aux = (op1.mantissa * op2.mantissa) >> 14; + rop.exponent = op1.exponent + op2.exponent; + if (aux & 32768L) + { + aux >>= 1; + rop.exponent ++; + } + rop.mantissa = (LC3_INT16) aux; + + + return rop; +} + +/* Auxiliary */ + +FEC_STATIC LC3_INT16 simple_float_cmp(simple_float op1, simple_float op2) +/* returns 1 if op1 > op2, 0 if op1 = op2, and -1 if op1 < op2 */ +{ + LC3_INT16 rval; + LC3_INT16 mdiff; + LC3_INT16 ediff; + + rval = 0; + + ediff = op1.exponent - op2.exponent; + mdiff = (LC3_INT16) op1.mantissa - (LC3_INT16) op2.mantissa; + + if (ediff == 0) + { + if (mdiff > 0) + { + rval = 1; + } + if (mdiff < 0) + { + rval = -1; + } + } + else + { + if (ediff > 0) + { + rval = 1; + } + if (ediff < 0) + { + rval = -1; + } + } + + + return rval; +} + diff --git a/lc3plus/apply_global_gain.c b/lc3plus/apply_global_gain.c new file mode 100644 index 0000000000000000000000000000000000000000..c67432e2c3bebcc30da1912ea0c63813f3471d46 --- /dev/null +++ b/lc3plus/apply_global_gain.c @@ -0,0 +1,21 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +void processApplyGlobalGain_fl(LC3_FLOAT x[], LC3_INT xLen, LC3_INT global_gain_idx, LC3_INT global_gain_off) +{ + LC3_FLOAT gg = 0; + + gg = LC3_POW(10, (LC3_FLOAT)(global_gain_idx + global_gain_off) / 28); + + mult_const(x, gg, xLen); +} diff --git a/lc3plus/ari_codec.c b/lc3plus/ari_codec.c new file mode 100644 index 0000000000000000000000000000000000000000..80c75fcf0cebcf278e4522643ab460beb46cc5bf --- /dev/null +++ b/lc3plus/ari_codec.c @@ -0,0 +1,1122 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +static void ac_shift_fl(Encoder_State_fl* st); +static void ac_encode_fl(Encoder_State_fl* st, LC3_INT sym_freq, LC3_INT cum_freq); +static void tns_order_freq_enc(LC3_INT enable_lpc_weighting, LC3_INT order, LC3_INT* symfreq, LC3_INT* cumfreq); +static void tns_coef_freq_enc(LC3_INT k, LC3_INT idx, LC3_INT* symfreq, LC3_INT* cumfreq); +static void ac_freq_fl(LC3_INT pki, LC3_INT s, LC3_INT* symfreq, LC3_INT* cumfreq); +static void ac_finalize_fl(Encoder_State_fl* st); +static void write_uint_forward_fl(Encoder_State_fl* st, LC3_INT val, LC3_INT numbits); +static void ari_enc_init(Encoder_State_fl* st, LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_side); +static LC3_INT sign(LC3_INT x); +static void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit, LC3_INT *bp, Decoder_State_fl* st_fl, LC3_INT from_left); +static void ac_dec_init_fl(LC3_UINT8* ptr, LC3_INT* bp, Decoder_State_fl* st_fl, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side); +static void tns_order_freq(LC3_INT enable_lpc_weighting, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym); +static void tns_coef_freq(LC3_INT k, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym); +static LC3_INT ac_decode_fl(Decoder_State_fl* st, LC3_INT* sym_freq, LC3_INT* cum_freq, LC3_INT num_sym, LC3_UINT8* ptr, LC3_INT* bp, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side); +static void ac_freq(LC3_INT pki, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym); +static void findNonZero(LC3_INT* in, LC3_INT* out, LC3_INT len, LC3_INT* outLen); +static void pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side); +static void calculate_nfseed(LC3_INT *x, LC3_INT L_spec, LC3_INT *nf_seed); + +void calculate_nfseed(LC3_INT *x, LC3_INT L_spec, LC3_INT *nf_seed) +{ + LC3_INT k = 0; + + *nf_seed = 0; + + for (k = 0; k < L_spec; k++) { + *nf_seed = *nf_seed + (abs(x[k]) & 32767) * k; + } + *nf_seed = *nf_seed & 65535; + + if (*nf_seed >= 32768) { + *nf_seed = *nf_seed - 65536; + } +} + +static void pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT32 from_left, LC3_INT32 mask_side, LC3_INT32 *bp_side) +{ + LC3_INT32 bp_local, bp_side_local, offset; + + if (st_fl->pc_bytes > 0) + { + if (!from_left && mask_side != 1) + { + return; + } + + if (st_fl->pc_c_bp_side > 0 && *bp_side < 0) + { + assert(mask_side == 1); + assert(st_fl->pc_b_right != -1); + *bp_side = st_fl->pc_b_right; + return; + } + + bp_local = *bp; + bp_side_local = *bp_side; + + if (from_left) + { + if (mask_side == 1) + { + bp_side_local = bp_side_local + 1; + } + } else { + bp_local = bp_local - 1; + } + + if (st_fl->pc_b_right == -1) + { + offset = -1; + if (!st_fl->pc_enc) + { + offset = offset + st_fl->pc_bytes; + } + + if ((bp_side_local + offset - bp_local) == st_fl->pc_bytes) + { + st_fl->pc_b_left = bp_local + 1; + st_fl->pc_b_right = bp_side_local - 1; + + if (st_fl->pc_enc) + { + st_fl->pc_return = 1; + return; + } + } + } + + if (!st_fl->pc_enc && st_fl->pc_b_right > -1) + { + if (from_left && *bp == st_fl->pc_b_left) + { + *bp = 0; + st_fl->pc_c_bp = 1; + } + + if (!from_left && bp_side_local == st_fl->pc_b_right) + { + *bp_side = st_fl->pc_bytes - 1; + st_fl->pc_c_bp_side = 1; + } + + if (st_fl->pc_bfi == 2) + { + + if ((st_fl->pc_c_bp && (*bp + 1) >= st_fl->pc_be_bp_left) || (st_fl->pc_c_bp_side && (*bp_side + 1) <= st_fl->pc_be_bp_right)) + { + st_fl->pc_bbi = 2; + } else if ((st_fl->pc_c_bp && *bp >= 0) || (st_fl->pc_c_bp_side && *bp_side <= (st_fl->pc_bytes - 1))) + { + st_fl->pc_bbi = 1; + } + } + } + } + + return; +} + + +void ac_dec_init_fl(LC3_UINT8* ptr, LC3_INT* bp, Decoder_State_fl* st_fl, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side) +{ + LC3_INT i = 0; + + if (!st_fl->pc_enc) + { + *bp = *bp + st_fl->pc_bytes; + } + + st_fl->ac_low_fl = 0; + + st_fl->ac_range_fl = (LC3_UINT32)pow(2, 24) - (LC3_UINT32)1; + for (i = 0; i < 3; i++) { + pc_check_bytes(bp, st_fl, from_left, mask_side, bp_side); + + st_fl->ac_low_fl = (st_fl->ac_low_fl << 8) + (LC3_UINT32)ptr[*bp]; + *bp = *bp + 1; + } + + st_fl->BER_detect = 0; +} + +void tns_order_freq(LC3_INT enable_lpc_weighting, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym) +{ + LC3_INT i = 0, j = 0; + + *numsym = 8; + + j = 0; + for (i = 1; i < 9; i++) { + symfreq[j] = ari_tns_order_cf[enable_lpc_weighting][i]; + j++; + } + + for (i = 0; i < *numsym; i++) { + symfreq[i] -= ari_tns_order_cf[enable_lpc_weighting][i]; + } + + for (i = 0; i < *numsym; i++) { + cumfreq[i] = ari_tns_order_cf[enable_lpc_weighting][i]; + } +} + +/* Returns val */ +LC3_INT ac_decode_fl(Decoder_State_fl* st, LC3_INT* sym_freq, LC3_INT* cum_freq, LC3_INT num_sym, LC3_UINT8* ptr, LC3_INT* bp, LC3_INT from_left, LC3_INT mask_side, LC3_INT *bp_side) +{ + LC3_INT val = 0, tmp = 0; + + + tmp = st->ac_range_fl >> 10; + + if (st->ac_low_fl >= (LC3_UINT32)(tmp << 10)) { + st->BER_detect = 1; + } + + val = num_sym - 1; + + while (st->ac_low_fl < (LC3_UINT32)(tmp * cum_freq[val])) { + val--; + } + + st->ac_low_fl = st->ac_low_fl - tmp * cum_freq[val]; + st->ac_range_fl = tmp * sym_freq[val]; + + while (st->ac_range_fl < pow(2, 16)) { + st->ac_low_fl = st->ac_low_fl << 8; + st->ac_low_fl = ((LC3_INT)st->ac_low_fl) & ((LC3_INT)(pow(2, 24) - 1)); + + pc_check_bytes(bp, st, from_left, mask_side, bp_side); + + st->ac_low_fl = st->ac_low_fl + ptr[*bp]; + *bp = *bp + 1; + st->ac_range_fl = st->ac_range_fl << 8; + } + + return val; +} + +void tns_coef_freq(LC3_INT k, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym) +{ + LC3_INT i = 0, j = 0; + + *numsym = 18 - 1; + + j = 0; + for (i = 1; i <= *numsym; i++) { + symfreq[j] = ari_tns_freq_cf[k][i]; + j++; + } + + for (i = 0; i < *numsym; i++) { + symfreq[i] -= ari_tns_freq_cf[k][i]; + } + + for (i = 0; i < *numsym; i++) { + cumfreq[i] = ari_tns_freq_cf[k][i]; + } +} + +void ac_freq(LC3_INT pki, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym) +{ + LC3_INT i = 0, j = 0; + + *numsym = 18 - 1; + + j = 0; + for (i = 1; i <= *numsym; i++) { + symfreq[j] = ari_spec_cumfreq_fl[pki][i]; + j++; + } + + for (i = 0; i < *numsym; i++) { + symfreq[i] -= ari_spec_cumfreq_fl[pki][i]; + } + + for (i = 0; i < *numsym; i++) { + cumfreq[i] = ari_spec_cumfreq_fl[pki][i]; + } +} + +void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit, LC3_INT *bp, Decoder_State_fl* st_fl, LC3_INT from_left) +{ + *bit = 0; + + UNUSED(bp); + UNUSED(st_fl); + UNUSED(from_left); + + if (ptr[*bp_side] & *mask_side) { + *bit = 1; + } else { + *bit = 0; + } + + if (*mask_side == 128) { + *mask_side = 1; + *bp_side = *bp_side - 1; + } else { + *mask_side = *mask_side * 2; + } +} + +void findNonZero(LC3_INT* in, LC3_INT* out, LC3_INT len, LC3_INT* outLen) +{ + LC3_INT i = 0, j = 0; + + for (i = 0; i < len; i++) { + if (in[i] != 0) { + out[j] = i; + j++; + } + } + + *outLen = j; +} + +void processAriDecoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, LC3_INT L_spec, LC3_INT fs_idx, LC3_INT enable_lpc_weighting, + LC3_INT tns_numfilters, LC3_INT lsbMode, LC3_INT lastnz, LC3_INT* bfi, LC3_INT* tns_order, LC3_INT fac_ns_idx, + LC3_INT gg_idx, uint8_t * resBits, LC3_INT* x, LC3_INT* nf_seed, LC3_INT* tns_idx, LC3_INT* zero_frame, LC3_INT numbytes, + LC3_INT* nbits_residual, LC3_INT* residualPresent, LC3_INT frame_dms, + LC3_INT32 n_pc, LC3_INT32 be_bp_left, LC3_INT32 be_bp_right, LC3_INT32 enc, LC3_INT32 *b_left, LC3_INT32 *spec_inv_idx, + LC3_INT hrmode +) +{ + Decoder_State_fl st; + LC3_INT a = 0, b = 0, t = 0, bp = 0; + LC3_INT c = 0; + LC3_INT nbits_side = 0, extra_bits = 0; + LC3_UINT8* ptr = NULL; + LC3_INT n = 0, k = 0, lev = 0; + LC3_INT max_lev = 0, tmp = 0; + LC3_INT sym_freq[MAX_LEN] = {0}, cum_freq[MAX_LEN] = {0}, numsym = 0, bit = 0, lev1 = 0, pki = 0, sym = 0, + save_lev[MAX_LEN] = {0}, idx_len = 0, total_bits = 0, nbits_ari = 0, idx[MAX_LEN] = {0}, rateFlag = 0; + + total_bits = 8 * numbytes; + + memset(&st, 0, sizeof(st)); + + + st.pc_bytes = (n_pc + 1) >> 1; + st.pc_b_left = numbytes + 1; + st.pc_b_right = -1; + st.pc_enc = enc; + st.pc_bfi = *bfi; + st.pc_be_bp_left = floor(be_bp_left / 8); + st.pc_be_bp_right = floor(be_bp_right / 8) - 1; + *spec_inv_idx = L_spec + 1; + assert(st.pc_be_bp_right < st.pc_bytes || st.pc_bytes == 0); + + /* Rate flag */ + if (fs_idx != 5) + { + if (total_bits > (160 + fs_idx * 160)) { + rateFlag = 512; + } + } + + /* Init */ + c = 0; + t = 0; + bp = 0; + + *b_left = -1; + + ptr = bytes; + + /* Start Decoding */ + ac_dec_init_fl(ptr, &bp, &st, 1, mask_side, &bp_side); + + /* Decode TNS data */ + tmp = MAXLAG; + if (frame_dms == 25) + { + tmp /= 2; + } + if (frame_dms == 50) + { + tmp /= 2; + } + + /* Decode TNS data */ + for (n = 0; n < tns_numfilters; n++) { + + if (tns_order[n] > 0) { + tns_order_freq(enable_lpc_weighting, sym_freq, cum_freq, &numsym); + + tns_order[n] = ac_decode_fl(&st, sym_freq, cum_freq, numsym, ptr, &bp, 1, mask_side, &bp_side); + + if (st.pc_return) + { + *b_left = st.pc_b_left; + return; + } + + tns_order[n] = tns_order[n] + 1; + + if (tns_order[n] > tmp) + { + st.BER_detect = 1; + } + + if (st.pc_bbi == 1) + { + spec_inv_idx = 0; + } else if (st.pc_bbi == 2) + { + st.BER_detect = 1; + } + + for (k = 0; k < tns_order[n]; k++) { + if (bp_side < bp) + { + *bfi = 1; + return; + } + + tns_coef_freq(k, sym_freq, cum_freq, &numsym); + tns_idx[n * 8 + k] = ac_decode_fl(&st, sym_freq, cum_freq, numsym, ptr, &bp, 1, mask_side, &bp_side); + + if (st.pc_return) + { + *b_left = st.pc_b_left; + return; + } + + if (st.pc_bbi == 1) + { + spec_inv_idx = 0; + } else if (st.pc_bbi == 2) + { + st.BER_detect = 1; + } + } + } + } + + if (st.BER_detect > 0) { + *bfi = 1; + return; + } + + /* Spectral data */ + for (k = 0; k < lastnz; k = k + 2) { + /* Context */ + t = c + rateFlag; + + if (k > L_spec / 2) { + t = t + 256; + } + + /* Decode amplitude */ + x[k] = 0; + x[k + 1] = 0; + + if (hrmode == 1) { + max_lev = 13 + 8; + } else { + max_lev = 13; + } + + for (lev = 0; lev <= max_lev; lev++) { + lev1 = MIN(lev, 3); + pki = ari_spec_lookup_fl[t + lev1 * 1024]; + ac_freq(pki, sym_freq, cum_freq, &numsym); + sym = ac_decode_fl(&st, sym_freq, cum_freq, numsym, ptr, &bp, 1, mask_side, &bp_side); + + if (st.pc_return) + { + *b_left = st.pc_b_left; + return; + } + + if (st.pc_bbi == 1) + { + *spec_inv_idx = MIN(*spec_inv_idx, k); + } else if (st.pc_bbi == 2) + { + *spec_inv_idx = k; + x[k] = 0; + x[k + 1] = 0; + calculate_nfseed(x, k, nf_seed); + return; + } + + if (sym < 16) { + break; + } + + if (lsbMode == 0 || lev > 0) { + pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); + read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); + + if (st.pc_return) + { + *b_left = st.pc_b_left; + return; + } + + if (st.pc_bbi == 2) + { + *spec_inv_idx = k; + x[k] = 0; + x[k + 1] = 0; + calculate_nfseed(x, k, nf_seed); + return; + } + + x[k] = x[k] + (bit << lev); + pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); + read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); + + if (st.pc_return) + { + *b_left = st.pc_b_left; + return; + } + + if (st.pc_bbi == 2) + { + *spec_inv_idx = k; + x[k] = 0; + x[k + 1] = 0; + calculate_nfseed(x, k, nf_seed); + return; + } + + x[k + 1] = x[k + 1] + (bit << lev); + } + } + + if ((lev - 1) == 13 && sym == 16) + { + st.BER_detect = 1; + } + + if (hrmode == 0) { + lev = MIN(lev, 13); + } + + if (lsbMode == 1) { + save_lev[k] = lev; + } + + a = sym & 3; + b = sym >> 2; + + x[k] = x[k] + (a << lev); + x[k + 1] = x[k + 1] + (b << lev); + + /* Decode signs */ + if (x[k] > 0) { + pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); + read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); + + if (st.pc_return) + { + *b_left = st.pc_b_left; + return; + } + + if (st.pc_bbi == 2) + { + *spec_inv_idx = k; + x[k] = 0; + x[k + 1] = 0; + calculate_nfseed(x, k, nf_seed); + return; + } + + if (bit == 1) { + x[k] = -x[k]; + } + } + + if (x[k + 1] > 0) { + pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); + read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); + + if (st.pc_return) + { + *b_left = st.pc_b_left; + return; + } + + if (st.pc_bbi == 2) + { + *spec_inv_idx = k + 1; + x[k + 1] = 0; + calculate_nfseed(x, k, nf_seed); + return; + } + + if (bit == 1) { + x[k + 1] = -x[k + 1]; + } + } + + /* Context */ + lev1 = MIN(lev, 3); + if (lev1 <= 1) { + t = 1 + (a + b) * (lev1 + 1); + } else { + t = 12 + lev1; + } + + c = (c & 15) * 16 + t; + + if (((bp - bp_side) > 3 && (st.pc_c_bp == st.pc_c_bp_side))) { + + if ((0 < *spec_inv_idx) && (*spec_inv_idx < (L_spec + 1))) + { + *bfi = 2; + calculate_nfseed(x, k, nf_seed); + return; + } + + *bfi = 1; + return; + } + + if (st.BER_detect > 0) + { + if ((0 < *spec_inv_idx) && (*spec_inv_idx < (L_spec + 1))) + { + *bfi = 2; + calculate_nfseed(x, k, nf_seed); + return; + } + + *bfi = 1; + return; + } + } + + /* Residual bits */ + nbits_side = total_bits - (8 * bp_side + 8 - (31 - clz_func(mask_side))); + nbits_ari = (bp - 3) * 8; + extra_bits = 25 - (31 - clz_func(st.ac_range_fl)); + + if (enc == 0) + { + if (st.pc_c_bp == 0) + { + nbits_ari = (bp - st.pc_bytes - 3) * 8; + } else { + nbits_ari = (bp + st.pc_b_left - st.pc_bytes - 3) * 8; + } + + if (st.pc_c_bp_side != 0) + { + nbits_side = total_bits - 8 * (st.pc_b_left) + 8 * (st.pc_bytes - bp_side) - (8 - LC3_LOGTWO(mask_side)); + } + } + + + *nbits_residual = total_bits - (nbits_side + nbits_ari + extra_bits); + + if (*nbits_residual < 0) { + if ((0 < *spec_inv_idx) && (*spec_inv_idx < (L_spec + 1))) + { + *bfi = 2; + calculate_nfseed(x, k, nf_seed); + return; + } + + *bfi = 1; + return; + } + + if (lsbMode == 0) { + findNonZero(x, idx, L_spec, &idx_len); + if (hrmode) + { + idx_len *= EXT_RES_ITER_MAX; + } + *nbits_residual = MIN(*nbits_residual, idx_len); + *residualPresent = 1; + + memset(resBits, 0, MAX_RESBITS_LEN); + + for (k = 0; k < *nbits_residual; k++) { + pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); + read_bit_fl(ptr, &mask_side, &bp_side, &tmp, &bp, &st, 0); + + if (st.pc_return) + { + *b_left = st.pc_b_left; + return; + } + + if (st.pc_bbi == 2) + { + *bfi = 0; + memset(resBits, 0, sizeof(uint8_t) * (*nbits_residual)); + calculate_nfseed(x, k, nf_seed); + return; + } + + resBits[k >> 3] |= tmp << (k & 7); + } + } else { + for (k = 0; k < lastnz; k = k + 2) { + if (save_lev[k] > 0) { + if (*nbits_residual == 0) { + break; + } + + pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); + read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); + + if (st.pc_return) + { + *b_left = st.pc_b_left; + return; + } + + if (st.pc_bbi == 2) + { + *bfi = 0; + memset(resBits, 0, sizeof(LC3_INT32) * (*nbits_residual)); + calculate_nfseed(x, k, nf_seed); + return; + } + + *nbits_residual = *nbits_residual - 1; + + if (bit == 1) { + if (x[k] > 0) { + x[k] = x[k] + 1; + } else if (x[k] < 0) { + x[k] = x[k] - 1; + } else { + if (*nbits_residual == 0) { + break; + } + + pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); + read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); + + if (st.pc_return) + { + *b_left = st.pc_b_left; + return; + } + + if (st.pc_bbi == 2) + { + *bfi = 0; + memset(resBits, 0, sizeof(LC3_INT32) * (*nbits_residual)); + calculate_nfseed(x, k, nf_seed); + return; + } + + *nbits_residual = *nbits_residual - 1; + + if (bit == 0) { + x[k] = 1; + } else { + x[k] = -1; + } + } + } + + if (*nbits_residual == 0) { + break; + } + + pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); + read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); + + if (st.pc_return) + { + *b_left = st.pc_b_left; + return; + } + + if (st.pc_bbi == 2) + { + *bfi = 0; + memset(resBits, 0, sizeof(LC3_INT32) * (*nbits_residual)); + calculate_nfseed(x, k, nf_seed); + return; + } + + *nbits_residual = *nbits_residual - 1; + + if (bit == 1) { + if (x[k + 1] > 0) { + x[k + 1] = x[k + 1] + 1; + } else if (x[k + 1] < 0) { + x[k + 1] = x[k + 1] - 1; + } else { + if (*nbits_residual == 0) { + break; + } + + pc_check_bytes(&bp, &st, 0, mask_side, &bp_side); + read_bit_fl(ptr, &mask_side, &bp_side, &bit, &bp, &st, 0); + + if (st.pc_return) + { + *b_left = st.pc_b_left; + return; + } + + if (st.pc_bbi == 2) + { + *bfi = 0; + memset(resBits, 0, sizeof(LC3_INT32) * (*nbits_residual)); + calculate_nfseed(x, k, nf_seed); + return; + } + + *nbits_residual = *nbits_residual - 1; + + if (bit == 0) { + x[k + 1] = 1; + } else { + x[k + 1] = -1; + } + } + } + } + } + } + + /* Noise-filling seed */ + calculate_nfseed(x, L_spec, nf_seed); + + /* Zero frame flag */ + if (lastnz == 2 && x[0] == 0 && x[1] == 0 && gg_idx == 0 && fac_ns_idx == 7) { + *zero_frame = 1; + } else { + *zero_frame = 0; + } + + if (enc) + { + if (st.pc_bytes > 0) + { + if (st.pc_b_left > numbytes) + { + *b_left = bp_side - st.pc_bytes; + } + } + } + + if ((*bfi == 2) && (*spec_inv_idx == (L_spec + 1))) + { + *bfi = 0; + } + + *spec_inv_idx = *spec_inv_idx - 1; +} + +void ac_encode_fl(Encoder_State_fl* st, LC3_INT sym_freq, LC3_INT cum_freq) +{ + LC3_INT r = 0; + + r = st->range >> 10; + st->low = st->low + r * cum_freq; + + if ((st->low >> 24) == 1) { + st->carry = 1; + } + + st->low = (st->low) & ((LC3_INT)pow(2, 24) - 1); + st->range = r * sym_freq; + + while (st->range < (LC3_INT)pow(2, 16)) { + st->range = st->range << 8; + ac_shift_fl(st); + } +} + +void ac_shift_fl(Encoder_State_fl* st) +{ + if (st->low < 16711680 || st->carry == 1) { + if (st->cache >= 0) { + st->ptr[st->bp] = st->cache + st->carry; + st->bp = st->bp + 1; + } + + while (st->carry_count > 0) { + st->ptr[st->bp] = (st->carry + 255) & 255; + st->bp = st->bp + 1; + st->carry_count = st->carry_count - 1; + } + + st->cache = st->low >> 16; + st->carry = 0; + } else { + st->carry_count = st->carry_count + 1; + } + + st->low = st->low << 8; + st->low = (st->low) & ((LC3_INT)pow(2, 24) - 1); +} + +void tns_order_freq_enc(LC3_INT enable_lpc_weighting, LC3_INT order, LC3_INT* symfreq, LC3_INT* cumfreq) +{ + *symfreq = tns_freq_cf[enable_lpc_weighting][order] - tns_freq_cf[enable_lpc_weighting][order - 1]; + *cumfreq = tns_freq_cf[enable_lpc_weighting][order - 1]; +} + +void tns_coef_freq_enc(LC3_INT k, LC3_INT idx, LC3_INT* symfreq, LC3_INT* cumfreq) +{ + *symfreq = tns_cf[k][idx + 1] - tns_cf[k][idx]; + *cumfreq = tns_cf[k][idx]; +} + +void ac_freq_fl(LC3_INT pki, LC3_INT s, LC3_INT* symfreq, LC3_INT* cumfreq) +{ + *symfreq = ari_spec_cumfreq_fl[pki][s + 1] - ari_spec_cumfreq_fl[pki][s]; + *cumfreq = ari_spec_cumfreq_fl[pki][s]; +} + +void ac_finalize_fl(Encoder_State_fl* st) +{ + LC3_INT bits = 0, mask = 0, val = 0, over1 = 0, high = 0, over2 = 0, c = 0, b = 0; + + bits = 24 - floor(LC3_LOGTWO(st->range)); + mask = ((LC3_INT)pow(2, 24) - 1) >> bits; + val = st->low + mask; + over1 = val >> 24; + + val = (val) & ((LC3_INT)pow(2, 24) - 1); + high = st->low + st->range; + over2 = high >> 24; + high = high & ((LC3_INT)pow(2, 24) - 1); + val = val & (((LC3_INT)pow(2, 24) - 1) - mask); + + if (over1 == over2) { + if (val + mask >= high) { + bits = bits + 1; + mask = mask >> 1; + val = ((st->low + mask) & ((LC3_INT)pow(2, 24) - 1)) & (((LC3_INT)pow(2, 24) - 1) - mask); + } + + if (val < st->low) { + st->carry = 1; + } + } + + st->low = val; + + b = bits; + + if (bits > 8) { + for (; b >= 1; b = b - 8) { + ac_shift_fl(st); + } + } else { + ac_shift_fl(st); + } + + bits = b; + if (bits < 0) { + bits += 8; + } + + if (st->carry_count > 0) { + st->ptr[st->bp] = st->cache; + st->bp = st->bp + 1; + + for (c = st->carry_count; c >= 2; c--) { + st->ptr[st->bp] = 255; + st->bp = st->bp + 1; + } + + write_uint_forward_fl(st, 255 << (bits - 8), bits); + } else { + write_uint_forward_fl(st, st->cache, bits); + } +} + +void write_uint_forward_fl(Encoder_State_fl* st, LC3_INT val, LC3_INT numbits) +{ + LC3_INT k = 0, bit = 0, mask = 128; + + for (k = 0; k < numbits; k++) { + bit = val & mask; + + if (bit == 0) { + st->ptr[st->bp] = st->ptr[st->bp] & (255 - mask); + } else { + st->ptr[st->bp] = st->ptr[st->bp] | mask; + } + + mask = mask >> 1; + } +} + +void ari_enc_init(Encoder_State_fl* st, LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_side) +{ + st->ptr = bytes; + st->bp_side = bp_side; + st->mask_side = mask_side; + st->bp = 0; + st->low = 0; + st->range = (LC3_INT)pow(2, 24) - 1; + st->cache = -1; + st->carry = 0; + st->carry_count = 0; +} + +LC3_INT sign(LC3_INT x) +{ + if (x > 0) + return 1; + + if (x < 0) + return -1; + + return 0; +} + +void processAriEncoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, LC3_INT* x, LC3_INT* tns_order, LC3_INT tns_numfilters, + LC3_INT* tns_idx, LC3_INT lastnz, LC3_INT* codingdata, uint8_t* res_bits, LC3_INT resBitsLen, LC3_INT lsbMode, + LC3_INT nbbits, LC3_INT enable_lpc_weighting) +{ + LC3_INT total_bits = 0, cumfreq = 0, symfreq = 0, k = 0, i = 0, j = 0, lev = 0, lev1 = 0; + LC3_INT bit1 = 0, bit2 = 0, lsb1 = 0, lsb2 = 0, a = 0, b = 0, bit = 0, pki = 0, nbits_side = 0; + LC3_INT nbits_residual_enc = 0, nbits_ari = 0, lsbs[MAX_LEN] = {0}, lsbsLen = 0; + Encoder_State_fl st; + + ari_enc_init(&st, bytes, &bp_side, &mask_side); + + total_bits = nbbits; + + /* TNS data */ + for (i = 0; i < tns_numfilters; i++) { + if (tns_order[i] > 0) { + tns_order_freq_enc(enable_lpc_weighting, tns_order[i], &symfreq, &cumfreq); + ac_encode_fl(&st, symfreq, cumfreq); + + for (j = 0; j < tns_order[i]; j++) { + tns_coef_freq_enc(j, tns_idx[i * 8 + j], &symfreq, &cumfreq); + ac_encode_fl(&st, symfreq, cumfreq); + } + } + } + + /* Spectral data */ + for (k = 0; k < lastnz; k = k + 2) { + for (lev = 0; lev < codingdata[1]; lev++) { + lev1 = MIN(lev, 3); + pki = ari_spec_lookup_fl[codingdata[0] + lev1 * 1024]; + ac_freq_fl(pki, 16, &symfreq, &cumfreq); + + ac_encode_fl(&st, symfreq, cumfreq); + bit1 = (abs(x[k]) >> lev) & 1; + bit2 = (abs(x[k + 1]) >> lev) & 1; + + if (lsbMode == 1 && lev == 0) { + lsb1 = bit1; + lsb2 = bit2; + } else { + write_bit_backward_fl(st.ptr, st.bp_side, st.mask_side, bit1); + write_bit_backward_fl(st.ptr, st.bp_side, st.mask_side, bit2); + } + } + + lev1 = MIN(MAX(codingdata[1], 0), 3); + pki = ari_spec_lookup_fl[codingdata[0] + lev1 * 1024]; + + ac_freq_fl(pki, codingdata[2], &symfreq, &cumfreq); + ac_encode_fl(&st, symfreq, cumfreq); + + a = abs(x[k]); + b = abs(x[k + 1]); + + if (lsbMode == 1 && codingdata[1] > 0) { + a = a >> 1; + lsbs[lsbsLen] = lsb1; + lsbsLen++; + + if (a == 0 && x[k] != 0) { + bit = MAX(0, -sign(x[k])); + lsbs[lsbsLen] = bit; + lsbsLen++; + } + + b = b >> 1; + lsbs[lsbsLen] = lsb2; + lsbsLen++; + + if (b == 0 && x[k + 1] != 0) { + bit = MAX(0, -sign(x[k + 1])); + lsbs[lsbsLen] = bit; + lsbsLen++; + } + } + + if (a != 0) { + bit = MAX(0, -sign(x[k])); + write_bit_backward_fl(st.ptr, st.bp_side, st.mask_side, bit); + } + + if (b != 0) { + bit = MAX(0, -sign(x[k + 1])); + write_bit_backward_fl(st.ptr, st.bp_side, st.mask_side, bit); + } + + codingdata += 3; + } + + /* Residual bits */ + nbits_side = total_bits - (8 * (*(st.bp_side) + 1) + 8 - LC3_LOGTWO(*(st.mask_side))); + nbits_ari = (st.bp + 1) * 8 + 25 - floor(LC3_LOGTWO(st.range)); + + if (st.cache >= 0) { + nbits_ari = nbits_ari + 8; + } + + if (st.carry_count > 0) { + nbits_ari = nbits_ari + st.carry_count * 8; + } + + nbits_residual_enc = MAX(total_bits - (nbits_side + nbits_ari), 0); + /* the max operation avoids in very rare cases, that + * nbits_residual_enc becomes negative; having overwritten + * the last bit(s) of the side information is in this case + * assumed to be not critical, since no spectral data bits + * were written */ + + if (lsbMode == 0) { + nbits_residual_enc = MIN(nbits_residual_enc, resBitsLen); + for (k = 0; k < nbits_residual_enc; k++) { + if (res_bits[k >> 3] & (1 << (k & 7))) + { + write_bit_backward_fl(st.ptr, st.bp_side, st.mask_side, 1); + } + else + { + write_bit_backward_fl(st.ptr, st.bp_side, st.mask_side, 0); + } + } + } else { + nbits_residual_enc = MIN(nbits_residual_enc, lsbsLen); + + for (k = 0; k < nbits_residual_enc; k++) { + write_bit_backward_fl(st.ptr, st.bp_side, st.mask_side, lsbs[k]); + } + } + + ac_finalize_fl(&st); +} + diff --git a/lc3plus/attack_detector.c b/lc3plus/attack_detector.c new file mode 100644 index 0000000000000000000000000000000000000000..c9f7c0a94c0be6529592f96793969ff5b2edb5b4 --- /dev/null +++ b/lc3plus/attack_detector.c @@ -0,0 +1,105 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +void attack_detector_fl(LC3_FLOAT* in, LC3_INT frame_size, LC3_INT fs, LC3_INT* lastAttackPosition, LC3_FLOAT* accNrg, LC3_INT* attackFlag, + LC3_FLOAT* attdec_filter_mem, LC3_INT attackHandlingOn, LC3_INT attdec_nblocks, LC3_INT attdec_hangover_threshold) +{ + LC3_FLOAT f_sig[160] = {0}, block_nrg[4] = {0}, sum = 0, tmpEne = 0, *ptr = NULL, tmp[162] = {0}; + LC3_INT i = 0, j = 0, attackPosition = 0; + LC3_FLOAT mval = 0; + LC3_INT frame_size_16k = attdec_nblocks * 40; + + + ptr = &tmp[2]; + + + + if (attackHandlingOn) { + /* Decimate 96, 48 and 32 kHz signals to 16 kHz */ + if (fs == 96000) { + for (i = 0; i < frame_size;) { + ptr[j] = in[i] + in[i + 1] + in[i + 2] + in[i + 3] + in[i + 4] + in[i + 5]; + i = i + 6; + j++; + } + mval = 1e-5; + } else if (fs == 48000) { + j = 0; + for (i = 0; i < frame_size;) { + ptr[j] = (in[i] + in[i + 1] + in[i + 2]); + i = i + 3; + j++; + } + } else if (fs == 32000) { + j = 0; + for (i = 0; i < frame_size;) { + ptr[j] = (in[i] + in[i + 1]); + i = i + 2; + j++; + } + } else if (fs == 24000) { + j = 0; + for (i = 0; i < frame_size;) { + ptr[j] = (in[i] + (in[i + 1] + in[i + 2]) / 2.0); + i = i + 3; + j++; + } + } + + /* Filter */ + ptr[-2] = (LC3_FLOAT)attdec_filter_mem[0]; + ptr[-1] = (LC3_FLOAT)attdec_filter_mem[1]; + + attdec_filter_mem[0] = ptr[frame_size_16k - 2]; + attdec_filter_mem[1] = ptr[frame_size_16k - 1]; + + for (i = 159; i >= 0; i--) { + tmpEne = 0; + + tmpEne += ptr[i] * 0.375; + tmpEne += ptr[i - 1] * (-0.5); + tmpEne += ptr[i - 2] * (0.125); + + f_sig[i] = tmpEne; + } + + for (i = 0; i < attdec_nblocks; i++) { + sum = 0; + for (j = 0; j < 40; j++) { + sum += f_sig[j + i * 40] * f_sig[j + i * 40]; + } + + block_nrg[i] = sum; + } + + *attackFlag = 0; + attackPosition = -1; + + for (i = 0; i < attdec_nblocks; i++) { + tmpEne = block_nrg[i] / 8.5; + + if (tmpEne > MAX(*accNrg, mval)) { + *attackFlag = 1; + attackPosition = i + 1; + } + + *accNrg = MAX(block_nrg[i], 0.25 * (*accNrg)); + } + + if (*lastAttackPosition > attdec_hangover_threshold) { + *attackFlag = 1; + } + + *lastAttackPosition = attackPosition; + } +} diff --git a/lc3plus/clib.h b/lc3plus/clib.h new file mode 100644 index 0000000000000000000000000000000000000000..bd709278086b82b878ad95d1b7699ddfa4d7e0f2 --- /dev/null +++ b/lc3plus/clib.h @@ -0,0 +1,27 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#ifndef CLIB_H +#define CLIB_H + +#include +#include +#include +#include +#include +#include +#include +#ifndef _MSC_VER +#include "strings.h" +#else +#include +#endif + +#endif diff --git a/lc3plus/constants.c b/lc3plus/constants.c new file mode 100644 index 0000000000000000000000000000000000000000..8189761a04c12632f10a502e51f0479efbdc00fe --- /dev/null +++ b/lc3plus/constants.c @@ -0,0 +1,3803 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +/* DCT */ +#define ENTRY_DCT2_1 {0.353553, 0.000000} +#define ENTRY_DCT2_2 {0.351851, -0.034654} +#define ENTRY_DCT2_3 {0.346760, -0.068975} +#define ENTRY_DCT2_4 {0.338329, -0.102631} +#define ENTRY_DCT2_5 {0.326641, -0.135299} +#define ENTRY_DCT2_6 {0.311806, -0.166664} +#define ENTRY_DCT2_7 {0.293969, -0.196424} +#define ENTRY_DCT2_8 {0.273300, -0.224292} +#define ENTRY_DCT2_9 {0.250000, -0.250000} +#define ENTRY_DCT2_10 {0.224292, -0.273300} +#define ENTRY_DCT2_11 {0.196424, -0.293969} +#define ENTRY_DCT2_12 {0.166664, -0.311806} +#define ENTRY_DCT2_13 {0.135299, -0.326641} +#define ENTRY_DCT2_14 {0.102631, -0.338329} +#define ENTRY_DCT2_15 {0.068975, -0.346760} +#define ENTRY_DCT2_16 {0.034654, -0.351851} + +const Complex dct2_16[16] = { +ENTRY_DCT2_1, +ENTRY_DCT2_2, +ENTRY_DCT2_3, +ENTRY_DCT2_4, +ENTRY_DCT2_5, +ENTRY_DCT2_6, +ENTRY_DCT2_7, +ENTRY_DCT2_8, +ENTRY_DCT2_9, +ENTRY_DCT2_10, +ENTRY_DCT2_11, +ENTRY_DCT2_12, +ENTRY_DCT2_13, +ENTRY_DCT2_14, +ENTRY_DCT2_15, +ENTRY_DCT2_16 +}; + +const LC3_INT ari_tns_order_cf[2][9] = {{0, 3, 12, 35, 89, 200, 390, 658, 1024}, + {0, 14, 56, 156, 313, 494, 672, 839, 1024}}; + +const LC3_INT ari_tns_freq_cf[8][18] = { + {0, 1, 6, 21, 52, 106, 192, 289, 409, 568, 720, 831, 935, 994, 1016, 1022, 1023, 1024}, + {0, 1, 2, 3, 4, 17, 60, 154, 293, 466, 626, 780, 911, 989, 1016, 1022, 1023, 1024}, + {0, 1, 2, 3, 4, 13, 56, 162, 361, 578, 788, 929, 1003, 1020, 1021, 1022, 1023, 1024}, + {0, 1, 2, 3, 4, 6, 17, 66, 270, 555, 852, 972, 1011, 1020, 1021, 1022, 1023, 1024}, + {0, 1, 2, 3, 4, 5, 12, 54, 295, 636, 950, 1008, 1017, 1020, 1021, 1022, 1023, 1024}, + {0, 1, 2, 3, 4, 5, 6, 19, 224, 590, 967, 1014, 1019, 1020, 1021, 1022, 1023, 1024}, + {0, 1, 2, 3, 4, 5, 6, 19, 300, 630, 1001, 1018, 1019, 1020, 1021, 1022, 1023, 1024}, + {0, 1, 2, 3, 4, 5, 6, 11, 308, 309, 991, 1017, 1019, 1020, 1021, 1022, 1023, 1024}}; + +const LC3_INT ari_spec_lookup_fl[4096] = { + 0x01, 0x27, 0x07, 0x19, 0x16, 0x16, 0x1C, 0x16, 0x16, 0x16, 0x16, 0x1C, 0x1C, 0x1C, 0x22, 0x1F, 0x1F, 0x28, 0x2B, + 0x2E, 0x31, 0x34, 0x0E, 0x11, 0x24, 0x24, 0x24, 0x26, 0x00, 0x39, 0x26, 0x16, 0x00, 0x08, 0x09, 0x0B, 0x2F, 0x0E, + 0x0E, 0x11, 0x24, 0x24, 0x24, 0x26, 0x3B, 0x3B, 0x26, 0x16, 0x16, 0x1A, 0x2E, 0x1D, 0x1E, 0x20, 0x21, 0x23, 0x24, + 0x24, 0x24, 0x26, 0x00, 0x3B, 0x17, 0x16, 0x2E, 0x2E, 0x2D, 0x2F, 0x30, 0x32, 0x32, 0x12, 0x36, 0x36, 0x36, 0x26, + 0x3B, 0x3B, 0x3B, 0x16, 0x00, 0x3E, 0x3F, 0x03, 0x21, 0x02, 0x02, 0x3D, 0x14, 0x14, 0x14, 0x15, 0x3B, 0x3B, 0x27, + 0x1C, 0x1C, 0x3F, 0x3F, 0x03, 0x21, 0x02, 0x02, 0x3D, 0x26, 0x26, 0x26, 0x15, 0x3B, 0x3B, 0x27, 0x1C, 0x1C, 0x06, + 0x06, 0x06, 0x02, 0x12, 0x3D, 0x14, 0x15, 0x15, 0x15, 0x3B, 0x27, 0x27, 0x07, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x33, 0x33, 0x33, 0x35, 0x36, 0x14, 0x26, + 0x26, 0x39, 0x27, 0x27, 0x27, 0x07, 0x18, 0x22, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x38, 0x26, 0x39, 0x39, 0x3B, 0x07, 0x07, 0x07, 0x2A, + 0x2A, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x04, 0x04, 0x05, 0x15, 0x15, 0x3B, 0x07, 0x07, 0x07, 0x07, 0x19, 0x19, 0x19, 0x22, 0x04, 0x04, 0x04, 0x04, + 0x05, 0x17, 0x17, 0x27, 0x07, 0x07, 0x07, 0x2A, 0x19, 0x19, 0x16, 0x1F, 0x1F, 0x27, 0x27, 0x27, 0x27, 0x07, 0x07, + 0x2A, 0x00, 0x19, 0x16, 0x16, 0x16, 0x1C, 0x22, 0x1F, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, + 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x28, 0x08, 0x09, 0x31, 0x31, 0x34, 0x11, 0x11, 0x11, 0x04, 0x00, + 0x14, 0x11, 0x3C, 0x28, 0x28, 0x08, 0x2B, 0x1B, 0x31, 0x31, 0x0E, 0x11, 0x11, 0x11, 0x24, 0x2A, 0x2A, 0x11, 0x39, + 0x39, 0x28, 0x08, 0x1A, 0x1B, 0x31, 0x0C, 0x0E, 0x11, 0x11, 0x11, 0x24, 0x00, 0x26, 0x24, 0x01, 0x08, 0x08, 0x2B, + 0x09, 0x0B, 0x31, 0x0C, 0x0E, 0x0E, 0x21, 0x32, 0x32, 0x32, 0x3D, 0x24, 0x27, 0x08, 0x08, 0x2B, 0x2E, 0x31, 0x34, + 0x1E, 0x0E, 0x0E, 0x21, 0x32, 0x32, 0x32, 0x32, 0x12, 0x19, 0x08, 0x08, 0x2B, 0x2E, 0x31, 0x34, 0x1E, 0x0E, 0x0E, + 0x12, 0x05, 0x05, 0x05, 0x3D, 0x12, 0x17, 0x2B, 0x2B, 0x2B, 0x09, 0x31, 0x34, 0x03, 0x0E, 0x0E, 0x32, 0x32, 0x32, + 0x32, 0x3D, 0x11, 0x18, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, + 0x2B, 0x2B, 0x2B, 0x2B, 0x09, 0x0B, 0x34, 0x34, 0x0E, 0x0E, 0x11, 0x3D, 0x3D, 0x3D, 0x36, 0x11, 0x27, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2C, 0x1B, 0x1D, + 0x34, 0x30, 0x34, 0x34, 0x11, 0x11, 0x11, 0x11, 0x02, 0x11, 0x07, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, + 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x09, 0x1B, 0x1B, 0x0C, 0x34, 0x0E, 0x0E, 0x3A, 0x29, + 0x29, 0x29, 0x06, 0x11, 0x25, 0x09, 0x09, 0x09, 0x1B, 0x0B, 0x31, 0x0C, 0x34, 0x0E, 0x0E, 0x0E, 0x32, 0x00, 0x35, + 0x11, 0x1C, 0x34, 0x34, 0x31, 0x34, 0x0C, 0x34, 0x1E, 0x0E, 0x0E, 0x11, 0x02, 0x02, 0x02, 0x26, 0x26, 0x22, 0x1F, + 0x22, 0x22, 0x1F, 0x1F, 0x1F, 0x1F, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x1F, 0x13, 0x2C, 0x2C, 0x3E, 0x1E, + 0x20, 0x3A, 0x23, 0x24, 0x24, 0x26, 0x00, 0x3B, 0x07, 0x07, 0x27, 0x22, 0x22, 0x2D, 0x2F, 0x30, 0x21, 0x23, 0x23, + 0x24, 0x26, 0x26, 0x26, 0x3B, 0x07, 0x07, 0x27, 0x22, 0x22, 0x3E, 0x1E, 0x0F, 0x32, 0x35, 0x35, 0x36, 0x15, 0x15, + 0x15, 0x3B, 0x07, 0x07, 0x07, 0x22, 0x1E, 0x1E, 0x30, 0x21, 0x3A, 0x12, 0x12, 0x38, 0x17, 0x17, 0x17, 0x3B, 0x07, + 0x07, 0x18, 0x22, 0x22, 0x06, 0x06, 0x3A, 0x35, 0x36, 0x36, 0x15, 0x3B, 0x3B, 0x3B, 0x27, 0x07, 0x07, 0x2A, 0x22, + 0x06, 0x06, 0x21, 0x3A, 0x35, 0x36, 0x3D, 0x15, 0x3B, 0x3B, 0x3B, 0x27, 0x07, 0x07, 0x2A, 0x22, 0x22, 0x33, 0x33, + 0x35, 0x36, 0x38, 0x38, 0x39, 0x27, 0x27, 0x27, 0x07, 0x2A, 0x2A, 0x19, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x04, 0x04, 0x04, 0x05, 0x17, 0x17, 0x27, 0x07, + 0x07, 0x07, 0x2A, 0x19, 0x19, 0x16, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x05, 0x05, 0x05, 0x05, 0x39, 0x39, 0x27, 0x18, 0x18, 0x18, 0x2A, 0x16, 0x16, 0x1C, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x29, + 0x29, 0x29, 0x29, 0x27, 0x27, 0x07, 0x2A, 0x2A, 0x2A, 0x19, 0x1C, 0x1C, 0x1C, 0x1F, 0x1F, 0x29, 0x29, 0x29, 0x29, + 0x27, 0x27, 0x18, 0x19, 0x19, 0x19, 0x16, 0x1C, 0x1C, 0x22, 0x1F, 0x1F, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x1C, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1F, 0x13, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x0B, 0x2F, 0x20, 0x32, 0x12, 0x12, 0x14, 0x15, 0x15, 0x15, 0x27, + 0x3B, 0x22, 0x1A, 0x1A, 0x1B, 0x1D, 0x1E, 0x21, 0x32, 0x12, 0x12, 0x14, 0x39, 0x39, 0x39, 0x3B, 0x3B, 0x22, 0x1B, + 0x1B, 0x0B, 0x0C, 0x30, 0x32, 0x3A, 0x3D, 0x3D, 0x38, 0x39, 0x39, 0x39, 0x3B, 0x27, 0x22, 0x2D, 0x2D, 0x0C, 0x1E, + 0x20, 0x02, 0x02, 0x3D, 0x26, 0x26, 0x26, 0x39, 0x00, 0x3B, 0x27, 0x22, 0x3F, 0x3F, 0x03, 0x20, 0x3A, 0x12, 0x12, + 0x14, 0x15, 0x15, 0x15, 0x3B, 0x27, 0x27, 0x07, 0x1F, 0x1F, 0x03, 0x03, 0x21, 0x3A, 0x12, 0x12, 0x14, 0x15, 0x15, + 0x15, 0x3B, 0x07, 0x07, 0x07, 0x1F, 0x06, 0x06, 0x33, 0x33, 0x35, 0x36, 0x36, 0x26, 0x39, 0x39, 0x39, 0x27, 0x07, + 0x07, 0x2A, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x33, 0x35, 0x35, 0x36, 0x38, 0x38, 0x39, 0x3B, 0x3B, 0x3B, 0x07, 0x18, 0x18, 0x19, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x04, 0x04, 0x04, 0x36, 0x15, + 0x15, 0x39, 0x27, 0x27, 0x27, 0x07, 0x2A, 0x2A, 0x16, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x05, 0x05, 0x05, 0x05, 0x17, 0x17, 0x3B, 0x07, 0x07, 0x07, 0x2A, + 0x16, 0x16, 0x1C, 0x1F, 0x1F, 0x04, 0x04, 0x04, 0x05, 0x17, 0x17, 0x27, 0x18, 0x18, 0x18, 0x19, 0x1C, 0x1C, 0x22, + 0x1F, 0x1F, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x1C, 0x22, 0x22, 0x22, 0x1F, 0x1F, 0x1F, 0x1F, 0x13, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, + 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, + 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x3C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, + 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3C, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x10, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x10, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, + 0x3C, 0x10, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x25, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, + 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x13, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, + 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x3C, 0x3C, 0x3C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, + 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +const LC3_INT ari_spec_cumfreq_fl[64][18] = { + {0, 1, 2, 177, 225, 226, 227, 336, 372, 543, 652, 699, 719, 768, 804, 824, 834, 1024}, + {0, 18, 44, 61, 71, 98, 135, 159, 175, 197, 229, 251, 265, 282, 308, 328, 341, 1024}, + {0, 71, 163, 212, 237, 318, 420, 481, 514, 556, 613, 652, 675, 697, 727, 749, 764, 1024}, + {0, 160, 290, 336, 354, 475, 598, 653, 677, 722, 777, 808, 823, 842, 866, 881, 890, 1024}, + {0, 71, 144, 177, 195, 266, 342, 385, 411, 445, 489, 519, 539, 559, 586, 607, 622, 1024}, + {0, 48, 108, 140, 159, 217, 285, 327, 354, 385, 427, 457, 478, 497, 524, 545, 561, 1024}, + {0, 138, 247, 290, 308, 419, 531, 584, 609, 655, 710, 742, 759, 780, 807, 825, 836, 1024}, + {0, 16, 40, 62, 79, 103, 139, 170, 195, 215, 245, 270, 290, 305, 327, 346, 362, 1024}, + {0, 579, 729, 741, 743, 897, 970, 980, 982, 996, 1007, 1010, 1011, 1014, 1017, 1018, 1019, 1024}, + {0, 398, 582, 607, 612, 788, 902, 925, 931, 956, 979, 987, 990, 996, 1002, 1005, 1007, 1024}, + {0, 13, 34, 52, 63, 83, 112, 134, 149, 163, 183, 199, 211, 221, 235, 247, 257, 1024}, + {0, 281, 464, 501, 510, 681, 820, 857, 867, 902, 938, 953, 959, 968, 978, 984, 987, 1024}, + {0, 198, 362, 408, 421, 575, 722, 773, 789, 832, 881, 905, 915, 928, 944, 954, 959, 1024}, + {0, 1, 2, 95, 139, 140, 141, 213, 251, 337, 407, 450, 475, 515, 551, 576, 592, 1024}, + {0, 133, 274, 338, 366, 483, 605, 664, 691, 730, 778, 807, 822, 837, 857, 870, 878, 1024}, + {0, 128, 253, 302, 320, 443, 577, 636, 659, 708, 767, 799, 814, 833, 857, 872, 881, 1024}, + {0, 1, 2, 25, 42, 43, 44, 67, 85, 105, 126, 144, 159, 174, 191, 205, 217, 1024}, + {0, 70, 166, 229, 267, 356, 468, 533, 569, 606, 653, 685, 705, 722, 745, 762, 774, 1024}, + {0, 55, 130, 175, 200, 268, 358, 416, 449, 488, 542, 581, 606, 628, 659, 683, 699, 1024}, + {0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 1024}, + {0, 34, 85, 123, 147, 196, 265, 317, 352, 386, 433, 470, 497, 518, 549, 574, 593, 1024}, + {0, 30, 73, 105, 127, 170, 229, 274, 305, 335, 377, 411, 436, 455, 483, 506, 524, 1024}, + {0, 9, 24, 38, 51, 65, 87, 108, 126, 139, 159, 177, 193, 204, 221, 236, 250, 1024}, + {0, 30, 74, 105, 125, 166, 224, 266, 294, 322, 361, 391, 413, 431, 457, 478, 494, 1024}, + {0, 15, 38, 58, 73, 95, 128, 156, 178, 196, 222, 245, 263, 276, 296, 314, 329, 1024}, + {0, 11, 28, 44, 57, 74, 100, 123, 142, 157, 179, 199, 216, 228, 246, 262, 276, 1024}, + {0, 448, 619, 639, 643, 821, 926, 944, 948, 971, 991, 998, 1000, 1005, 1010, 1012, 1013, 1024}, + {0, 332, 520, 549, 555, 741, 874, 903, 910, 940, 970, 981, 985, 991, 998, 1002, 1004, 1024}, + {0, 8, 21, 34, 45, 58, 78, 96, 112, 124, 141, 157, 170, 180, 194, 207, 219, 1024}, + {0, 239, 415, 457, 468, 631, 776, 820, 833, 872, 914, 933, 940, 951, 964, 971, 975, 1024}, + {0, 165, 310, 359, 375, 513, 652, 707, 727, 774, 828, 856, 868, 884, 904, 916, 923, 1024}, + {0, 3, 8, 13, 18, 23, 30, 37, 44, 48, 55, 62, 68, 72, 78, 84, 90, 1024}, + {0, 115, 237, 289, 311, 422, 547, 608, 635, 680, 737, 771, 788, 807, 832, 849, 859, 1024}, + {0, 107, 221, 272, 293, 399, 521, 582, 610, 656, 714, 749, 767, 787, 813, 831, 842, 1024}, + {0, 6, 16, 26, 35, 45, 60, 75, 89, 98, 112, 125, 137, 145, 157, 168, 178, 1024}, + {0, 72, 160, 210, 236, 320, 422, 482, 514, 555, 608, 644, 665, 685, 712, 732, 745, 1024}, + {0, 45, 108, 153, 183, 244, 327, 385, 421, 455, 502, 536, 559, 578, 605, 626, 641, 1024}, + {0, 1, 2, 9, 16, 17, 18, 26, 34, 40, 48, 55, 62, 68, 75, 82, 88, 1024}, + {0, 29, 73, 108, 132, 174, 236, 284, 318, 348, 391, 426, 452, 471, 500, 524, 543, 1024}, + {0, 20, 51, 76, 93, 123, 166, 200, 225, 247, 279, 305, 326, 342, 365, 385, 401, 1024}, + {0, 742, 845, 850, 851, 959, 997, 1001, 1002, 1009, 1014, 1016, 1017, 1019, 1020, 1021, 1022, 1024}, + {0, 42, 94, 121, 137, 186, 244, 280, 303, 330, 366, 392, 410, 427, 451, 470, 484, 1024}, + {0, 13, 33, 51, 66, 85, 114, 140, 161, 178, 203, 225, 243, 256, 275, 292, 307, 1024}, + {0, 501, 670, 689, 693, 848, 936, 952, 956, 975, 991, 997, 999, 1004, 1008, 1010, 1011, 1024}, + {0, 445, 581, 603, 609, 767, 865, 888, 895, 926, 954, 964, 968, 977, 986, 991, 993, 1024}, + {0, 285, 442, 479, 489, 650, 779, 818, 830, 870, 912, 930, 937, 949, 963, 971, 975, 1024}, + {0, 349, 528, 561, 569, 731, 852, 883, 892, 923, 953, 965, 970, 978, 987, 992, 994, 1024}, + {0, 199, 355, 402, 417, 563, 700, 750, 767, 811, 860, 884, 894, 909, 926, 936, 942, 1024}, + {0, 141, 275, 325, 343, 471, 606, 664, 686, 734, 791, 822, 836, 854, 877, 891, 899, 1024}, + {0, 243, 437, 493, 510, 649, 775, 820, 836, 869, 905, 923, 931, 941, 953, 960, 964, 1024}, + {0, 91, 197, 248, 271, 370, 487, 550, 580, 625, 684, 721, 741, 761, 788, 807, 819, 1024}, + {0, 107, 201, 242, 262, 354, 451, 503, 531, 573, 626, 660, 680, 701, 730, 751, 765, 1024}, + {0, 168, 339, 407, 432, 553, 676, 731, 755, 789, 830, 854, 866, 879, 895, 906, 912, 1024}, + {0, 67, 147, 191, 214, 290, 384, 441, 472, 513, 567, 604, 627, 648, 678, 700, 715, 1024}, + {0, 46, 109, 148, 171, 229, 307, 359, 391, 427, 476, 513, 537, 558, 588, 612, 629, 1024}, + {0, 848, 918, 920, 921, 996, 1012, 1013, 1014, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024}, + {0, 36, 88, 123, 145, 193, 260, 308, 340, 372, 417, 452, 476, 496, 525, 548, 565, 1024}, + {0, 24, 61, 90, 110, 145, 196, 237, 266, 292, 330, 361, 385, 403, 430, 453, 471, 1024}, + {0, 85, 182, 230, 253, 344, 454, 515, 545, 590, 648, 685, 706, 727, 756, 776, 789, 1024}, + {0, 22, 55, 82, 102, 135, 183, 222, 252, 278, 315, 345, 368, 385, 410, 431, 448, 1024}, + {0, 1, 2, 56, 89, 90, 91, 140, 172, 221, 268, 303, 328, 358, 388, 412, 430, 1024}, + {0, 45, 109, 152, 177, 239, 320, 376, 411, 448, 499, 537, 563, 585, 616, 640, 658, 1024}, + {0, 247, 395, 433, 445, 599, 729, 771, 785, 829, 875, 896, 905, 920, 937, 946, 951, 1024}, + {0, 231, 367, 408, 423, 557, 676, 723, 742, 786, 835, 860, 872, 889, 909, 921, 928, 1024}}; + +const LC3_INT ari_spec_bits_fl[64][17] = { + {20480, 20480, 5220, 9042, 20480, 20480, 6619, 9892, 5289, 6619, 9105, 11629, 8982, 9892, 11629, 13677, 4977}, + {11940, 10854, 12109, 13677, 10742, 9812, 11090, 12288, 11348, 10240, 11348, 12683, 12109, 10854, 11629, 12902, + 1197}, + {7886, 7120, 8982, 10970, 7496, 6815, 8334, 10150, 9437, 8535, 9656, 11216, 11348, 10431, 11348, 12479, 4051}, + {5485, 6099, 9168, 11940, 6311, 6262, 8640, 11090, 9233, 8640, 10334, 12479, 11781, 11090, 12479, 13988, 6009}, + {7886, 7804, 10150, 11940, 7886, 7685, 9368, 10854, 10061, 9300, 10431, 11629, 11629, 10742, 11485, 12479, 2763}, + {9042, 8383, 10240, 11781, 8483, 8013, 9437, 10742, 10334, 9437, 10431, 11485, 11781, 10742, 11485, 12288, 2346}, + {5922, 6619, 9368, 11940, 6566, 6539, 8750, 10970, 9168, 8640, 10240, 12109, 11485, 10742, 11940, 13396, 5009}, + {12288, 11090, 11348, 12109, 11090, 9892, 10334, 10970, 11629, 10431, 10970, 11629, 12479, 11348, 11781, 12288, + 1289}, + {1685, 5676, 13138, 18432, 5598, 7804, 13677, 18432, 12683, 13396, 17234, 20480, 17234, 17234, 20480, 20480, 15725}, + {2793, 5072, 10970, 15725, 5204, 6487, 11216, 15186, 10970, 11216, 14336, 17234, 15186, 15186, 17234, 18432, 12109}, + {12902, 11485, 11940, 13396, 11629, 10531, 11348, 12479, 12683, 11629, 12288, 13138, 13677, 12683, 13138, 13677, + 854}, + {3821, 5088, 9812, 13988, 5289, 5901, 9812, 13677, 9976, 9892, 12479, 15186, 13988, 13677, 15186, 17234, 9812}, + {4856, 5412, 9168, 12902, 5598, 5736, 8863, 12288, 9368, 8982, 11090, 13677, 12902, 12288, 13677, 15725, 8147}, + {20480, 20480, 7088, 9300, 20480, 20480, 7844, 9733, 7320, 7928, 9368, 10970, 9581, 9892, 10970, 12288, 2550}, + {6031, 5859, 8192, 10635, 6410, 6286, 8433, 10742, 9656, 9042, 10531, 12479, 12479, 11629, 12902, 14336, 5756}, + {6144, 6215, 8982, 11940, 6262, 6009, 8433, 11216, 8982, 8433, 10240, 12479, 11781, 11090, 12479, 13988, 5817}, + {20480, 20480, 11216, 12109, 20480, 20480, 11216, 11940, 11629, 11485, 11940, 12479, 12479, 12109, 12683, 13138, + 704}, + {7928, 6994, 8239, 9733, 7218, 6539, 8147, 9892, 9812, 9105, 10240, 11629, 12109, 11216, 12109, 13138, 4167}, + {8640, 7724, 9233, 10970, 8013, 7185, 8483, 10150, 9656, 8694, 9656, 10970, 11348, 10334, 11090, 12288, 3391}, + {20480, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, + 91}, + {10061, 8863, 9733, 11090, 8982, 7970, 8806, 9976, 10061, 9105, 9812, 10742, 11485, 10334, 10970, 11781, 2557}, + {10431, 9368, 10240, 11348, 9368, 8433, 9233, 10334, 10431, 9437, 10061, 10970, 11781, 10635, 11216, 11940, 2119}, + {13988, 12479, 12683, 12902, 12683, 11348, 11485, 11940, 12902, 11629, 11940, 12288, 13396, 12109, 12479, 12683, + 828}, + {10431, 9300, 10334, 11629, 9508, 8483, 9437, 10635, 10635, 9656, 10431, 11348, 11940, 10854, 11485, 12288, 1946}, + {12479, 11216, 11629, 12479, 11348, 10150, 10635, 11348, 11940, 10854, 11216, 11940, 12902, 11629, 11940, 12479, + 1146}, + {13396, 12109, 12288, 12902, 12109, 10854, 11216, 11781, 12479, 11348, 11629, 12109, 13138, 11940, 12288, 12683, + 928}, + {2443, 5289, 11629, 16384, 5170, 6730, 11940, 16384, 11216, 11629, 14731, 18432, 15725, 15725, 18432, 20480, 13396}, + {3328, 5009, 10531, 15186, 5040, 6031, 10531, 14731, 10431, 10431, 13396, 16384, 15186, 14731, 16384, 18432, 11629}, + {14336, 12902, 12902, 13396, 12902, 11629, 11940, 12288, 13138, 12109, 12288, 12902, 13677, 12683, 12902, 13138, + 711}, + {4300, 5204, 9437, 13396, 5430, 5776, 9300, 12902, 9656, 9437, 11781, 14731, 13396, 12902, 14731, 16384, 8982}, + {5394, 5776, 8982, 12288, 5922, 5901, 8640, 11629, 9105, 8694, 10635, 13138, 12288, 11629, 13138, 14731, 6844}, + {17234, 15725, 15725, 15725, 15725, 14731, 14731, 14731, 16384, 14731, 14731, 15186, 16384, 15186, 15186, 15186, + 272}, + {6461, 6286, 8806, 11348, 6566, 6215, 8334, 10742, 9233, 8535, 10061, 12109, 11781, 10970, 12109, 13677, 5394}, + {6674, 6487, 8863, 11485, 6702, 6286, 8334, 10635, 9168, 8483, 9976, 11940, 11629, 10854, 11940, 13396, 5105}, + {15186, 13677, 13677, 13988, 13677, 12479, 12479, 12683, 13988, 12683, 12902, 13138, 14336, 13138, 13396, 13677, + 565}, + {7844, 7252, 8922, 10854, 7389, 6815, 8383, 10240, 9508, 8750, 9892, 11485, 11629, 10742, 11629, 12902, 3842}, + {9233, 8239, 9233, 10431, 8334, 7424, 8483, 9892, 10061, 9105, 10061, 11216, 11781, 10742, 11485, 12479, 2906}, + {20480, 20480, 14731, 14731, 20480, 20480, 14336, 14336, 15186, 14336, 14731, 14731, 15186, 14731, 14731, 15186, + 266}, + {10531, 9300, 9976, 11090, 9437, 8286, 9042, 10061, 10431, 9368, 9976, 10854, 11781, 10531, 11090, 11781, 2233}, + {11629, 10334, 10970, 12109, 10431, 9368, 10061, 10970, 11348, 10240, 10854, 11485, 12288, 11216, 11629, 12288, + 1469}, + {952, 6787, 15725, 20480, 6646, 9733, 16384, 20480, 14731, 15725, 18432, 20480, 18432, 20480, 20480, 20480, 18432}, + {9437, 8806, 10742, 12288, 8982, 8483, 9892, 11216, 10742, 9892, 10854, 11940, 12109, 11090, 11781, 12683, 1891}, + {12902, 11629, 11940, 12479, 11781, 10531, 10854, 11485, 12109, 10970, 11348, 11940, 12902, 11781, 12109, 12479, + 1054}, + {2113, 5323, 11781, 16384, 5579, 7252, 12288, 16384, 11781, 12288, 15186, 18432, 15725, 16384, 18432, 20480, 12902}, + {2463, 5965, 11348, 15186, 5522, 6934, 11216, 14731, 10334, 10635, 13677, 16384, 13988, 13988, 15725, 18432, 10334}, + {3779, 5541, 9812, 13677, 5467, 6122, 9656, 13138, 9581, 9437, 11940, 14731, 13138, 12683, 14336, 16384, 8982}, + {3181, 5154, 10150, 14336, 5448, 6311, 10334, 13988, 10334, 10431, 13138, 15725, 14336, 13988, 15725, 18432, 10431}, + {4841, 5560, 9105, 12479, 5756, 5944, 8922, 12109, 9300, 8982, 11090, 13677, 12479, 12109, 13677, 15186, 7460}, + {5859, 6009, 8922, 11940, 6144, 5987, 8483, 11348, 9042, 8535, 10334, 12683, 11940, 11216, 12683, 14336, 6215}, + {4250, 4916, 8587, 12109, 5901, 6191, 9233, 12288, 10150, 9892, 11940, 14336, 13677, 13138, 14731, 16384, 8383}, + {7153, 6702, 8863, 11216, 6904, 6410, 8239, 10431, 9233, 8433, 9812, 11629, 11629, 10742, 11781, 13138, 4753}, + {6674, 7057, 9508, 11629, 7120, 6964, 8806, 10635, 9437, 8750, 10061, 11629, 11485, 10531, 11485, 12683, 4062}, + {5341, 5289, 8013, 10970, 6311, 6262, 8640, 11090, 10061, 9508, 11090, 13138, 12902, 12288, 13396, 15186, 6539}, + {8057, 7533, 9300, 11216, 7685, 7057, 8535, 10334, 9508, 8694, 9812, 11216, 11485, 10431, 11348, 12479, 3541}, + {9168, 8239, 9656, 11216, 8483, 7608, 8806, 10240, 9892, 8982, 9812, 11090, 11485, 10431, 11090, 12109, 2815}, + {558, 7928, 18432, 20480, 7724, 12288, 20480, 20480, 18432, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480}, + {9892, 8806, 9976, 11348, 9042, 8057, 9042, 10240, 10240, 9233, 9976, 11090, 11629, 10531, 11216, 12109, 2371}, + {11090, 9812, 10531, 11629, 9976, 8863, 9508, 10531, 10854, 9733, 10334, 11090, 11940, 10742, 11216, 11940, 1821}, + {7354, 6964, 9042, 11216, 7153, 6592, 8334, 10431, 9233, 8483, 9812, 11485, 11485, 10531, 11629, 12902, 4349}, + {11348, 10150, 10742, 11629, 10150, 9042, 9656, 10431, 10854, 9812, 10431, 11216, 12109, 10970, 11485, 12109, 1700}, + {20480, 20480, 8694, 10150, 20480, 20480, 8982, 10240, 8982, 9105, 9976, 10970, 10431, 10431, 11090, 11940, 1610}, + {9233, 8192, 9368, 10970, 8286, 7496, 8587, 9976, 9812, 8863, 9733, 10854, 11348, 10334, 11090, 11940, 3040}, + {4202, 5716, 9733, 13138, 5598, 6099, 9437, 12683, 9300, 9168, 11485, 13988, 12479, 12109, 13988, 15725, 7804}, + {4400, 5965, 9508, 12479, 6009, 6360, 9105, 11781, 9300, 8982, 10970, 13138, 12109, 11629, 13138, 14731, 6994}}; + +const LC3_FLOAT sns_LFCB[8][32] = { + {2.26283365592678, 2.94516479191376, -2.18610707009979, 0.693688236528920, -1.29752132315296, 0.914652037830672, + -2.51428812578962, -0.922188404812385, 0.790322288369266, 1.44775580178724, 0.793354526417474, 2.72425347385034, + -0.530830198375400, 1.68728410845006, -2.95183272801858, 0.101878342785628, 2.68254575498426, 4.82697923680403, + 0.0878419936470335, 1.39102308204326, 0.384585893889182, 1.93227399441719, 0.175080462899884, -1.18817020250556, + 2.53322203327061, 3.99889837485606, 0.507902593186381, 3.16856825107569, 1.89414766731764, 0.948880604517188, + -1.88026757045628, 0.246375746277129}, + {0.813311269061339, 2.41143317956679, -1.97152135675228, 0.955609857158220, -0.740369057177853, + 1.74293043435257, -2.89175271384373, 0.632495141440552, 0.628401261876199, 2.72399951674952, + 0.0143931185523454, 2.95947572404824, -0.212690682812164, 2.43614509237656, -1.59393496773345, + 0.589857324228917, 1.32738010899420, 3.11947804492488, -0.569586840238501, 1.98146479199466, + -0.160588785536510, 3.01030180412057, -0.750522832248985, 0.366792873662636, 2.11274642695908, + 4.07901751451956, 1.58838449789527, 3.25853458159407, 1.25108694609232, 2.13239439249982, + -1.26431072758705, 0.955621773393099}, + {-0.530193494871436, 0.960455106400727, -1.78718619681006, 0.575230787038733, -0.345372483642106, + 1.90906626859986, -2.00450666759434, 1.08736431254641, 0.393117923540450, 2.31083268737528, + -0.567834844729679, 1.84953559268461, 0.00576613628377097, 2.33019429078225, -0.109918772878022, + 0.619047646793466, 0.130185273804048, 1.39513671385178, -1.14506015668811, 1.11265796388770, + -0.539366809557710, 3.06543893826204, -1.03943893342231, 1.30957830409096, 1.26288411502064, + 2.82285661102496, 1.72899023869209, 2.42230591328599, 0.590451210720628, 2.72345350344278, + 0.311424976968699, 1.52046776741766}, + {-1.35664835903442, -0.443226488076917, -1.91865895685577, -0.114603419462889, -0.313285696247940, + 1.54408483842665, -0.750912273903127, 0.608628624535820, 0.480007710866901, 0.935051269566529, + -0.654760467916745, 0.563284922322364, 0.424871484383745, 1.77983777835091, 0.388609072919257, + 1.26731313851796, -0.338533088511347, 0.250295315918722, -1.66968488172598, -0.220107509420743, + -0.529309078789857, 2.50110160870008, -1.13577508937648, 1.68330687280491, 0.761513512430427, + 1.72607212849580, 1.00692230241726, 1.79446077643261, 0.608358583293714, 2.76986076866588, + 1.83670210306430, 1.97647400419457}, + {-1.59952176563196, -1.22913612425590, -1.79399121836596, -0.646050637436029, -0.402977242824477, + 1.09344960761455, 0.441202104904691, 0.131174567547348, 0.447815138050143, -0.274743911383688, + -0.479458998475743, 0.139917088125072, 0.473128952158668, 1.44411295390082, 0.512932649517584, + 2.41961047769804, -0.368219235899667, -0.393613839379793, -1.84534417603682, -0.774965611552366, + 0.190433547437932, 1.93089592978934, -1.04197903837494, 1.25100924225127, 0.522117937976170, + 0.647144377348619, 0.377121231816382, 1.52177910653089, 0.878171010011082, 2.54286973254946, + 2.25634191839874, 1.94043867177462}, + {-1.44098768430095, -1.55590039118170, -1.35738404257288, -0.952351370449625, -0.372020853465227, + 0.647479549518278, 1.20190987601009, -0.296149157743752, 0.209734214552234, -0.902077696828602, + -0.173894661902889, 0.359641093366222, 0.858894199321281, 1.51995177009730, 0.628112597063497, + 2.25174252572187, -0.191689946715961, -0.643458173054701, -1.56468027328802, -0.594063874149117, + 2.56062918106522, 0.572153810961837, -0.0152060098993382, 0.942375751628615, 0.118680069757121, + -0.331148521217238, 0.476370766899498, 1.17196706537602, 1.11912510950950, 2.02046263825019, + 2.04818998463474, 2.23375847282686}, + {-1.14381648305821, -1.49688655952376, -0.705444279353869, -1.07405247226150, -0.0783414177323738, + 0.0361790752449642, 1.32742857257290, -0.207013516525629, 0.00656691996428021, -0.940681511945404, + 0.0680162705515438, 0.689461354774589, 1.19111160854435, 1.47199393750425, 0.822621796430634, + 0.526537030991201, -0.154782377153908, -0.642570736856943, -1.11746759076420, 0.136937680628923, + 2.81896398245248, -0.811741794081091, 2.07048391716707, 0.826250483374133, -0.452346827507370, + -0.884042570848749, 1.08754740372170, 0.489394596980695, 1.01857661550342, 0.830045859400910, + 2.19526837458568, 1.98835977758407}, + {-0.755203767909064, -1.11689986501469, -0.0478172944777711, -0.758087707094905, 0.0970441303992295, + -0.297092807178889, 1.22049081140984, 0.134924916642080, -0.0861242342061857, -0.633697038974310, + 0.295125948369794, 0.639790176833105, 0.996189669638358, 0.977682473891761, 0.875891424655081, + -0.396591513227999, -0.234207177774392, -0.723193223444072, -0.533981663366786, 0.818242891264338, + 0.656670875696161, -1.17641810861903, 3.42948918081689, 0.439952741120956, -0.700352426161103, + -1.12697340645478, 1.08756266099221, -0.0622795715718769, 0.620453891011724, -0.0275569173888263, + 2.02659613836619, 1.27232672554701}}; + +const LC3_FLOAT sns_HFCB[8][32] = { + {0.232028419124465, -1.29503936673618, 0.139285716045803, -0.316513102185725, 0.879518405226496, + -0.296701922455375, 0.340981100469697, -1.41229759077597, -0.228839511827379, -1.07148628544449, + -0.590988511188051, -0.848434098836164, 1.14069145562382, -0.376283237967464, 0.665004120598402, + -0.826265953982679, 1.41008326832173, 0.361386817574348, 0.437469239330329, 0.648100318996503, + 1.11919833091304, 0.141847497087176, 0.504046955390252, -0.501076050479357, 3.74970982709642, + -1.15258990980549, 1.02827246422140, 0.128831971707817, 1.34033030334757, 2.13843105419313, + 0.564830487355396, -0.422460547586087}, + {-1.00890270604455, -1.79929965384339, -0.258185126171752, -0.477747657209805, 0.298340096007189, + -0.975004919174553, 0.268899788946055, -1.48522119349852, -0.333719069784662, -1.41767015456261, + -0.0711737758537628, -0.583226810708889, 0.964016892398293, 0.0425675462096105, 1.09790764690795, + -0.671181232766603, 0.754441907835468, -0.0219991705427826, 0.305440419605961, 0.682299133640680, + 1.23465532536005, -0.110660070633151, 0.826982162959097, -0.325678006081417, 1.52342611847045, + -1.10800885906241, 1.09770519389828, 0.689439395264878, 1.38996825067789, 4.24711267303104, + 1.59184977958743, 0.326149625049801}, + {-2.14223502789471, -1.88703147531519, -0.650804572670110, -0.551162075879755, -0.915386396405710, + -1.35857500246993, 0.0563335684828033, -1.18603579834700, -0.809321359324656, -1.54891762265441, + 0.345719522947313, 0.0900423688142873, 0.381461205984798, 0.516547696592306, 1.38342667112079, + -0.228495592779472, -1.30550584958631, -0.579368833633824, -0.00738786566478374, 0.253247464332976, + 0.589170238085318, -0.282824592543629, 1.11981236291828, 0.0280798194947077, -0.457715661897855, + -0.562615116512472, 0.768645545764776, 1.12346905009575, 1.04467921708883, 2.89734109830439, + 2.39771699015146, 1.39171313342261}, + {-2.37533813570664, -1.80991659687332, -1.06815731781969, -0.484788283381197, -2.20645974739762, + -0.983721105837444, 0.0499114046826685, -0.625001634441352, -1.63587876923797, -1.45296062475530, + 0.300549460996251, 0.845025007556886, -0.482849340608998, 0.251716881864630, 1.34327358628285, + 0.518980852551937, -1.87133711350971, -0.879427960941070, -0.495649854710252, 0.0735842143788469, + -1.37192459653166, -0.00659813474614194, 1.17914044332734, 0.262054554763133, -0.798711008243192, + -0.220562123765675, 0.206081977740766, 1.30934523106594, 0.635822746244367, 0.932730658026815, + 3.03697343600704, 2.23146614636474}, + {-2.23041933049655, -1.76340038479206, -1.61928741524302, -0.238388394455814, -2.74142180959951, + -0.652956939100809, -0.0954130727414369, 0.153902497468304, -1.88486397330982, -1.03182970062270, + -1.11865218295857, 1.06572384501716, -1.81632721260589, -0.216179967524303, 0.822978836855922, + 1.36721896340278, -1.24008685156305, -0.850685023408119, -0.806651271118393, 0.314216709389010, + -2.37095707241577, 0.285929279627216, 1.07987429197260, 0.360590806085767, -0.386819329309100, + -0.349842880336644, -0.342805735091998, 1.35511964713935, -0.274733755518482, -0.292822249729810, + 2.66424350337151, 2.61179442169688}, + {-2.17595881223696, -1.83418428467950, -2.18762566441756, -0.143024507285504, -2.86139074276891, + -0.989986992921811, -0.760166146083885, 0.576386497810755, -1.64496691316356, -0.690642640272584, + -2.44089151148049, 0.737582999377756, -2.80279512728555, -0.534074091124504, 0.215876798515679, + 2.18023038253092, -1.26712924866274, -0.779397050155816, -1.22431891984401, 0.234729880923679, + -2.00779782682360, 0.0460445529952971, 0.697536239067500, 0.635623722053700, -0.375901062231203, + -0.753432770250495, -0.754939404625340, 1.42311381470799, -1.54923372430695, -0.810404296853182, + 1.39304485032606, 2.66540340196570}, + {-2.29065913541000, -1.80480980687405, -2.63757586939054, 0.0683186673649074, -2.88841597105271, + -1.61467224598900, -2.32758120177007, 0.795092603798871, -1.40515778046612, -0.428843804532171, + -2.22854732450735, 0.256590452459912, -3.23385724833864, -0.640786096262196, -0.404925753080293, + 2.53596092750107, -2.03670813003907, -0.732182927291826, -1.70157770043181, 0.144600134479837, + -1.66688540224395, -0.602596415577886, -0.912548817371081, 0.959012467178154, -0.657836899930538, + -0.988596593396384, -1.04196177632000, 1.15706449190905, -2.44239710278007, -0.788868098756483, + 0.403834023595745, 2.40103554105707}, + {-2.53286397979846, -1.73679545317401, -2.97897749575096, 0.0883061717288066, -2.95182608262521, + -2.40712302385116, -3.77155485385656, 0.596564632144913, -1.46666471326146, -0.494960215408874, + -1.89509228210853, -0.491963359762378, -3.45908714491473, -0.869745032374135, -1.07025605870523, + 2.20121098860036, -2.89685162242381, -0.888348514821255, -2.24491913755611, -0.0682120178880174, + -1.92631846258406, -2.26568728632575, -3.57684747062773, 1.30745156688653, -1.28163964243603, + -1.28790471791471, -1.50335652955529, 0.406319437516838, -3.02457606944550, -0.935353148761338, + -0.656270971328114, 1.75920379670881}}; + +const LC3_INT pvq_enc_A[16][11] = {{0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + {0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19}, + {0, 1, 5, 13, 25, 41, 61, 85, 113, 145, 181}, + {0, 1, 7, 25, 63, 129, 231, 377, 575, 833, 1159}, + {0, 1, 9, 41, 129, 321, 681, 1289, 2241, 3649, 5641}, + {0, 1, 11, 61, 231, 681, 1683, 3653, 7183, 13073, 22363}, + {0, 1, 13, 85, 377, 1289, 3653, 8989, 19825, 40081, 75517}, + {0, 1, 15, 113, 575, 2241, 7183, 19825, 48639, 108545, 224143}, + {0, 1, 17, 145, 833, 3649, 13073, 40081, 108545, 265729, 598417}, + {0, 1, 19, 181, 1159, 5641, 22363, 75517, 224143, 598417, 1462563}, + {0, 1, 21, 221, 1561, 8361, 36365, 134245, 433905, 1256465, 3317445}, + {0, 1, 23, 265, 2047, 11969, 56695, 227305, 795455, 2485825, 7059735}, + {0, 1, 25, 313, 2625, 16641, 85305, 369305, 1392065, 4673345, 14218905}, + {0, 1, 27, 365, 3303, 22569, 124515, 579125, 2340495, 8405905, 27298155}, + {0, 1, 29, 421, 4089, 29961, 177045, 880685, 3800305, 14546705, 50250765}, + {0, 1, 31, 481, 4991, 39041, 246047, 1303777, 5984767, 24331777, 89129247}}; + +const LC3_FLOAT lp_scale_factors[6] = {1, 1, 0.6666666666666666, .5, 0.3333333333333333, 0.16666666666666666}; + + +/* 12.8 kHz resampler */ +const LC3_FLOAT highpass50_filt_b[3] = {0.9827947082978771, -1.965589416595754, 0.9827947082978771}; +const LC3_FLOAT highpass50_filt_a[3] = {1, -1.9652933726226904, 0.9658854605688177}; + +const LC3_INT32 resamp_params[][4] = { + {24, 5, 0, 15}, + {12, 10, 1, 3}, + {8, 15, 1, 7}, + {6, 20, 2, 3}, + {4, 30, 3, 3}, + {2, 60, 7, 1} +}; + + +const LC3_FLOAT lp_filter_8[240] = {0.0065408750, 0.0127360141, -0.0320970677, -0.1382038444, 0.8005587459, -0.1382038444, -0.0320970677, 0.0127360141, 0.0065408750, 0.0000000000, 0.0064595463, 0.0084537705, -0.0391003005, -0.1198658869, 0.7945935130, -0.1519452035, -0.0230523963, 0.0167804975, 0.0063002659, -0.0002451667, 0.0060938913, 0.0041435249, -0.0439039879, -0.0980933905, 0.7768620253, -0.1600013375, -0.0122310519, 0.0203715712, 0.0057131811, -0.0005356151, 0.0054914863, 0.0000000000, -0.0464562289, -0.0740769655, 0.7478516698, -0.1614013463, 0.0000000000, 0.0232978407, 0.0047708568, -0.0008596397, 0.0047065411, -0.0038048958, -0.0468063876, -0.0489920303, 0.7083564401, -0.1553338468, 0.0131809860, 0.0253629088, 0.0034824028, -0.0012012133, 0.0037965439, -0.0071282135, -0.0450960808, -0.0239577144, 0.6594504118, -0.1411849856, 0.0267735831, 0.0263961889, 0.0018761361, -0.0015404741, 0.0028190494, -0.0098603060, -0.0415467210, -0.0000000000, 0.6024519205, -0.1185704023, 0.0401797108, 0.0262632743, -0.0000000000, -0.0018545259, 0.0018287648, -0.0119272992, -0.0364444591, 0.0219798349, 0.5388799906, -0.0873604342, 0.0527642742, 0.0248753466, -0.0020790326, -0.0021185349, 0.0008750616, -0.0132916924, -0.0301232301, 0.0412303619, 0.4704038501, -0.0476967618, 0.0638811216, 0.0221970305, -0.0042766319, -0.0023070835, 0.0000000000, -0.0139512215, -0.0229468606, 0.0571681485, 0.3987891078, 0.0000000000, 0.0729012638, 0.0182522610, -0.0064938627, -0.0023957258, -0.0007630716, -0.0139361415, -0.0152910165, 0.0693885013, 0.3258404732, 0.0550325289, 0.0792422444, 0.0131276902, -0.0086209681, -0.0023626641, -0.0013903243, -0.0133052040, -0.0075258445, 0.0776687115, 0.2533447146, 0.1164389849, 0.0823974460, 0.0069732964, -0.0105420630, -0.0021904600, -0.0018676731, -0.0121405739, -0.0000000000, 0.0819641128, 0.1830149740, 0.1830149740, 0.0819641128, -0.0000000000, -0.0121405739, -0.0018676731, -0.0021904600, -0.0105420630, 0.0069732964, 0.0823974460, 0.1164389849, 0.2533447146, 0.0776687115, -0.0075258445, -0.0133052040, -0.0013903243, -0.0023626641, -0.0086209681, 0.0131276902, 0.0792422444, 0.0550325289, 0.3258404732, 0.0693885013, -0.0152910165, -0.0139361415, -0.0007630716, -0.0023957258, -0.0064938627, 0.0182522610, 0.0729012638, 0.0000000000, 0.3987891078, 0.0571681485, -0.0229468606, -0.0139512215, 0.0000000000, -0.0023070835, -0.0042766319, 0.0221970305, 0.0638811216, -0.0476967618, 0.4704038501, 0.0412303619, -0.0301232301, -0.0132916924, 0.0008750616, -0.0021185349, -0.0020790326, 0.0248753466, 0.0527642742, -0.0873604342, 0.5388799906, 0.0219798349, -0.0364444591, -0.0119272992, 0.0018287648, -0.0018545259, -0.0000000000, 0.0262632743, 0.0401797108, -0.1185704023, 0.6024519205, -0.0000000000, -0.0415467210, -0.0098603060, 0.0028190494, -0.0015404741, 0.0018761361, 0.0263961889, 0.0267735831, -0.1411849856, 0.6594504118, -0.0239577144, -0.0450960808, -0.0071282135, 0.0037965439, -0.0012012133, 0.0034824028, 0.0253629088, 0.0131809860, -0.1553338468, 0.7083564401, -0.0489920303, -0.0468063876, -0.0038048958, 0.0047065411, -0.0008596397, 0.0047708568, 0.0232978407, 0.0000000000, -0.1614013463, 0.7478516698, -0.0740769655, -0.0464562289, 0.0000000000, 0.0054914863, -0.0005356151, 0.0057131811, 0.0203715712, -0.0122310519, -0.1600013375, 0.7768620253, -0.0980933905, -0.0439039879, 0.0041435249, 0.0060938913, -0.0002451667, 0.0063002659, 0.0167804975, -0.0230523963, -0.1519452035, 0.7945935130, -0.1198658869, -0.0391003005, 0.0084537705, 0.0064595463}; + +const LC3_FLOAT lp_filter_16[240] = { +-0.0018676731, 0.0065408750, -0.0121405739, 0.0127360141, -0.0000000000, -0.0320970677, 0.0819641128, -0.1382038444, 0.1830149740, 0.8005587459, 0.1830149740, -0.1382038444, 0.0819641128, -0.0320970677, -0.0000000000, 0.0127360141, -0.0121405739, 0.0065408750, -0.0018676731, 0.0000000000, -0.0021904600, 0.0064595463, -0.0105420630, 0.0084537705, 0.0069732964, -0.0391003005, 0.0823974460, -0.1198658869, 0.1164389849, 0.7945935130, 0.2533447146, -0.1519452035, 0.0776687115, -0.0230523963, -0.0075258445, 0.0167804975, -0.0133052040, 0.0063002659, -0.0013903243, -0.0002451667, -0.0023626641, 0.0060938913, -0.0086209681, 0.0041435249, 0.0131276902, -0.0439039879, 0.0792422444, -0.0980933905, 0.0550325289, 0.7768620253, 0.3258404732, -0.1600013375, 0.0693885013, -0.0122310519, -0.0152910165, 0.0203715712, -0.0139361415, 0.0057131811, -0.0007630716, -0.0005356151, -0.0023957258, 0.0054914863, -0.0064938627, 0.0000000000, 0.0182522610, -0.0464562289, 0.0729012638, -0.0740769655, 0.0000000000, 0.7478516698, 0.3987891078, -0.1614013463, 0.0571681485, 0.0000000000, -0.0229468606, 0.0232978407, -0.0139512215, 0.0047708568, 0.0000000000, -0.0008596397, -0.0023070835, 0.0047065411, -0.0042766319, -0.0038048958, 0.0221970305, -0.0468063876, 0.0638811216, -0.0489920303, -0.0476967618, 0.7083564401, 0.4704038501, -0.1553338468, 0.0412303619, 0.0131809860, -0.0301232301, 0.0253629088, -0.0132916924, 0.0034824028, 0.0008750616, -0.0012012133, -0.0021185349, 0.0037965439, -0.0020790326, -0.0071282135, 0.0248753466, -0.0450960808, 0.0527642742, -0.0239577144, -0.0873604342, 0.6594504118, 0.5388799906, -0.1411849856, 0.0219798349, 0.0267735831, -0.0364444591, 0.0263961889, -0.0119272992, 0.0018761361, 0.0018287648, -0.0015404741, -0.0018545259, 0.0028190494, -0.0000000000, -0.0098603060, 0.0262632743, -0.0415467210, 0.0401797108, -0.0000000000, -0.1185704023, 0.6024519205, 0.6024519205, -0.1185704023, -0.0000000000, 0.0401797108, -0.0415467210, 0.0262632743, -0.0098603060, -0.0000000000, 0.0028190494, -0.0018545259, -0.0015404741, 0.0018287648, 0.0018761361, -0.0119272992, 0.0263961889, -0.0364444591, 0.0267735831, 0.0219798349, -0.1411849856, 0.5388799906, 0.6594504118, -0.0873604342, -0.0239577144, 0.0527642742, -0.0450960808, 0.0248753466, -0.0071282135, -0.0020790326, 0.0037965439, -0.0021185349, -0.0012012133, 0.0008750616, 0.0034824028, -0.0132916924, 0.0253629088, -0.0301232301, 0.0131809860, 0.0412303619, -0.1553338468, 0.4704038501, 0.7083564401, -0.0476967618, -0.0489920303, 0.0638811216, -0.0468063876, 0.0221970305, -0.0038048958, -0.0042766319, 0.0047065411, -0.0023070835, -0.0008596397, 0.0000000000, 0.0047708568, -0.0139512215, 0.0232978407, -0.0229468606, 0.0000000000, 0.0571681485, -0.1614013463, 0.3987891078, 0.7478516698, 0.0000000000, -0.0740769655, 0.0729012638, -0.0464562289, 0.0182522610, 0.0000000000, -0.0064938627, 0.0054914863, -0.0023957258, -0.0005356151, -0.0007630716, 0.0057131811, -0.0139361415, 0.0203715712, -0.0152910165, -0.0122310519, 0.0693885013, -0.1600013375, 0.3258404732, 0.7768620253, 0.0550325289, -0.0980933905, 0.0792422444, -0.0439039879, 0.0131276902, 0.0041435249, -0.0086209681, 0.0060938913, -0.0023626641, -0.0002451667, -0.0013903243, 0.0063002659, -0.0133052040, 0.0167804975, -0.0075258445, -0.0230523963, 0.0776687115, -0.1519452035, 0.2533447146, 0.7945935130, 0.1164389849, -0.1198658869, 0.0823974460, -0.0391003005, 0.0069732964, 0.0084537705, -0.0105420630, 0.0064595463, -0.0021904600 +}; + +const LC3_FLOAT lp_filter_24[240] = { +-0.0015380557, 0.0005833744, 0.0043605831, -0.0028510878, -0.0088611282, 0.0084906761, 0.0147980200, -0.0200821534, -0.0213980451, 0.0425874144, 0.0274869073, -0.0921358988, -0.0317978412, 0.3136025667, 0.5337058306, 0.3136025667, -0.0317978412, -0.0921358988, 0.0274869073, 0.0425874144, -0.0213980451, -0.0200821534, 0.0147980200, 0.0084906761, -0.0088611282, -0.0028510878, 0.0043605831, 0.0005833744, -0.0015380557, 0.0000000000, -0.0014123565, 0.0000000000, 0.0043063643, -0.0013860217, -0.0093008140, 0.0056358469, 0.0165835638, -0.0152979074, -0.0260668676, 0.0351761840, 0.0381121002, -0.0799105912, -0.0582402907, 0.2658593953, 0.5297290087, 0.3592533171, 0.0000000000, -0.1012968048, 0.0146532226, 0.0486008413, -0.0153682642, -0.0242963061, 0.0121681746, 0.0111869983, -0.0079515325, -0.0043292418, 0.0042001773, 0.0012191766, -0.0015971506, -0.0001634445, -0.0012363506, -0.0005087144, 0.0040625944, -0.0000000000, -0.0092907613, 0.0027623500, 0.0175088495, -0.0101940110, -0.0292693246, 0.0267864745, 0.0462590009, -0.0653955936, -0.0790469348, 0.2172269821, 0.5179080367, 0.4016346335, 0.0366883539, -0.1066675633, -0.0000000000, 0.0528281629, -0.0081540346, -0.0276978146, 0.0087517938, 0.0135810468, -0.0065735374, -0.0057473122, 0.0038087873, 0.0018793662, -0.0015751094, -0.0003570767, -0.0010269828, -0.0009268829, 0.0036609909, 0.0012507574, -0.0088701360, 0.0000000000, 0.0175974593, -0.0050172298, -0.0309708193, 0.0178490561, 0.0517791398, -0.0493846424, -0.0941233262, 0.1688964665, 0.4985677898, 0.4396336079, 0.0776259899, -0.1076008976, -0.0159718096, 0.0549316332, 0.0000000000, -0.0300640538, 0.0046488643, 0.0155318938, -0.0047521424, -0.0070280419, 0.0031805711, 0.0025310293, -0.0014603067, -0.0005730931, -0.0008008089, -0.0012451154, 0.0031376940, 0.0023216018, -0.0080937156, -0.0025365972, 0.0169086065, -0.0000000000, -0.0312042590, 0.0087873237, 0.0546427406, -0.0326613523, -0.1035559028, 0.1220099851, 0.4722376168, 0.4722376168, 0.1220099851, -0.1035559028, -0.0326613523, 0.0546427406, 0.0087873237, -0.0312042590, -0.0000000000, 0.0169086065, -0.0025365972, -0.0080937156, 0.0023216018, 0.0031376940, -0.0012451154, -0.0008008089, -0.0005730931, -0.0014603067, 0.0025310293, 0.0031805711, -0.0070280419, -0.0047521424, 0.0155318938, 0.0046488643, -0.0300640538, 0.0000000000, 0.0549316332, -0.0159718096, -0.1076008976, 0.0776259899, 0.4396336079, 0.4985677898, 0.1688964665, -0.0941233262, -0.0493846424, 0.0517791398, 0.0178490561, -0.0309708193, -0.0050172298, 0.0175974593, 0.0000000000, -0.0088701360, 0.0012507574, 0.0036609909, -0.0009268829, -0.0010269828, -0.0003570767, -0.0015751094, 0.0018793662, 0.0038087873, -0.0057473122, -0.0065735374, 0.0135810468, 0.0087517938, -0.0276978146, -0.0081540346, 0.0528281629, -0.0000000000, -0.1066675633, 0.0366883539, 0.4016346335, 0.5179080367, 0.2172269821, -0.0790469348, -0.0653955936, 0.0462590009, 0.0267864745, -0.0292693246, -0.0101940110, 0.0175088495, 0.0027623500, -0.0092907613, -0.0000000000, 0.0040625944, -0.0005087144, -0.0012363506, -0.0001634445, -0.0015971506, 0.0012191766, 0.0042001773, -0.0043292418, -0.0079515325, 0.0111869983, 0.0121681746, -0.0242963061, -0.0153682642, 0.0486008413, 0.0146532226, -0.1012968048, 0.0000000000, 0.3592533171, 0.5297290087, 0.2658593953, -0.0582402907, -0.0799105912, 0.0381121002, 0.0351761840, -0.0260668676, -0.0152979074, 0.0165835638, 0.0056358469, -0.0093008140, -0.0013860217, 0.0043063643, 0.0000000000, -0.0014123565 +}; + +const LC3_FLOAT lp_filter_32[240] = { +-0.0009272629, -0.0009338366, 0.0014095247, 0.0032704375, -0.0000000000, -0.0060702870, -0.0049301530, 0.0063680070, 0.0131316371, -0.0000000000, -0.0207733605, -0.0160485338, 0.0200898554, 0.0409820564, -0.0000000000, -0.0691019222, -0.0592852011, 0.0915074870, 0.3012259603, 0.4002793729, 0.3012259603, 0.0915074870, -0.0592852011, -0.0691019222, -0.0000000000, 0.0409820564, 0.0200898554, -0.0160485338, -0.0207733605, -0.0000000000, 0.0131316371, 0.0063680070, -0.0049301530, -0.0060702870, -0.0000000000, 0.0032704375, 0.0014095247, -0.0009338366, -0.0009272629, 0.0000000000, -0.0007702371, -0.0010952300, 0.0009143824, 0.0032297731, 0.0009380680, -0.0052710315, -0.0059636496, 0.0042268853, 0.0131980944, 0.0034866482, -0.0182222296, -0.0195501503, 0.0133867916, 0.0411987230, 0.0109899174, -0.0599329434, -0.0705924928, 0.0582194924, 0.2694399953, 0.3972967565, 0.3297252059, 0.1266723573, -0.0436802171, -0.0759726018, -0.0119788572, 0.0388343558, 0.0263821371, -0.0115261981, -0.0225480404, -0.0037629222, 0.0124376733, 0.0083902488, -0.0035641068, -0.0066526020, -0.0010395163, 0.0031501330, 0.0018982720, -0.0006951622, -0.0010592674, -0.0001225834, -0.0006006067, -0.0011813320, 0.0004375308, 0.0030469457, 0.0017412014, -0.0043104840, -0.0066458462, 0.0020717625, 0.0126814544, 0.0065638451, -0.0150616150, -0.0219519939, 0.0065904930, 0.0396211222, 0.0206151810, -0.0490466952, -0.0776669234, 0.0275162645, 0.2352019250, 0.3884310126, 0.3541782200, 0.1629202366, -0.0238483809, -0.0800006688, -0.0244960152, 0.0346942507, 0.0319405608, -0.0061155260, -0.0234031938, -0.0076455083, 0.0110985152, 0.0101857856, -0.0019024479, -0.0069680708, -0.0021383159, 0.0028565906, 0.0023532705, -0.0003815358, -0.0011535417, -0.0002678075, -0.0004298199, -0.0011978629, 0.0000000000, 0.0027457431, 0.0023854284, -0.0032469314, -0.0069756107, 0.0000000000, 0.0116489204, 0.0091261305, -0.0114734303, -0.0232281145, 0.0000000000, 0.0364506319, 0.0285840742, -0.0370384827, -0.0807006732, 0.0000000000, 0.1993945539, 0.3739258349, 0.3739258349, 0.1993945539, 0.0000000000, -0.0807006732, -0.0370384827, 0.0285840742, 0.0364506319, 0.0000000000, -0.0232281145, -0.0114734303, 0.0091261305, 0.0116489204, 0.0000000000, -0.0069756107, -0.0032469314, 0.0023854284, 0.0027457431, 0.0000000000, -0.0011978629, -0.0004298199, -0.0002678075, -0.0011535417, -0.0003815358, 0.0023532705, 0.0028565906, -0.0021383159, -0.0069680708, -0.0019024479, 0.0101857856, 0.0110985152, -0.0076455083, -0.0234031938, -0.0061155260, 0.0319405608, 0.0346942507, -0.0244960152, -0.0800006688, -0.0238483809, 0.1629202366, 0.3541782200, 0.3884310126, 0.2352019250, 0.0275162645, -0.0776669234, -0.0490466952, 0.0206151810, 0.0396211222, 0.0065904930, -0.0219519939, -0.0150616150, 0.0065638451, 0.0126814544, 0.0020717625, -0.0066458462, -0.0043104840, 0.0017412014, 0.0030469457, 0.0004375308, -0.0011813320, -0.0006006067, -0.0001225834, -0.0010592674, -0.0006951622, 0.0018982720, 0.0031501330, -0.0010395163, -0.0066526020, -0.0035641068, 0.0083902488, 0.0124376733, -0.0037629222, -0.0225480404, -0.0115261981, 0.0263821371, 0.0388343558, -0.0119788572, -0.0759726018, -0.0436802171, 0.1266723573, 0.3297252059, 0.3972967565, 0.2694399953, 0.0582194924, -0.0705924928, -0.0599329434, 0.0109899174, 0.0411987230, 0.0133867916, -0.0195501503, -0.0182222296, 0.0034866482, 0.0131980944, 0.0042268853, -0.0059636496, -0.0052710315, 0.0009380680, 0.0032297731, 0.0009143824, -0.0010952300, -0.0007702371 +}; + +const LC3_FLOAT lp_filter_48[240] = { +-0.0004004044, -0.0007690279, -0.0006225577, 0.0002916872, 0.0015688470, 0.0021802916, 0.0011608009, -0.0014255439, -0.0040468578, -0.0044305641, -0.0012682986, 0.0042453380, 0.0084543033, 0.0073990100, -0.0000000000, -0.0100410767, -0.0156021295, -0.0106990226, 0.0043936619, 0.0212937072, 0.0273213703, 0.0137434537, -0.0163306762, -0.0460679494, -0.0517779514, -0.0158989206, 0.0610049926, 0.1568012834, 0.2361188084, 0.2668529153, 0.2361188084, 0.1568012834, 0.0610049926, -0.0158989206, -0.0517779514, -0.0460679494, -0.0163306762, 0.0137434537, 0.0273213703, 0.0212937072, 0.0043936619, -0.0106990226, -0.0156021295, -0.0100410767, -0.0000000000, 0.0073990100, 0.0084543033, 0.0042453380, -0.0012682986, -0.0044305641, -0.0040468578, -0.0014255439, 0.0011608009, 0.0021802916, 0.0015688470, 0.0002916872, -0.0006225577, -0.0007690279, -0.0004004044, 0.0000000000, -0.0002865466, -0.0007061783, -0.0007301533, 0.0000000000, 0.0012655146, 0.0021531822, 0.0015902856, -0.0006930109, -0.0035140209, -0.0046504070, -0.0023760712, 0.0028179234, 0.0077659469, 0.0082917819, 0.0023244321, -0.0076489537, -0.0150320269, -0.0130334338, 0.0000000000, 0.0175880920, 0.0274658166, 0.0190560501, -0.0079859048, -0.0399552956, -0.0538004488, -0.0291201454, 0.0388129950, 0.1329296976, 0.2198168039, 0.2648645043, 0.2492838949, 0.1796266586, 0.0844482332, 0.0000000000, -0.0470616631, -0.0506484024, -0.0246923212, 0.0073266113, 0.0258895699, 0.0243004207, 0.0089245280, -0.0076841321, -0.0154854096, -0.0121481530, -0.0025086149, 0.0060840873, 0.0087987296, 0.0055934992, 0.0000000000, -0.0039757662, -0.0044350680, -0.0021646209, 0.0006253787, 0.0021000886, 0.0018304954, 0.0006095883, -0.0004634415, -0.0007985753, -0.0005134914, -0.0000817222, -0.0001785384, -0.0006181753, -0.0007875547, -0.0002543572, 0.0009396831, 0.0020312972, 0.0019043937, -0.0000000000, -0.0028736561, -0.0046453807, -0.0032867687, 0.0013811750, 0.0067905234, 0.0087544248, 0.0043758969, -0.0050970055, -0.0138489073, -0.0146346623, -0.0040770173, 0.0133932373, 0.0264140815, 0.0231295004, -0.0000000000, -0.0326977968, -0.0533337817, -0.0395234674, 0.0183441769, 0.1086134911, 0.2008173168, 0.2589540184, 0.2589540184, 0.2008173168, 0.1086134911, 0.0183441769, -0.0395234674, -0.0533337817, -0.0326977968, -0.0000000000, 0.0231295004, 0.0264140815, 0.0133932373, -0.0040770173, -0.0146346623, -0.0138489073, -0.0050970055, 0.0043758969, 0.0087544248, 0.0067905234, 0.0013811750, -0.0032867687, -0.0046453807, -0.0028736561, -0.0000000000, 0.0019043937, 0.0020312972, 0.0009396831, -0.0002543572, -0.0007875547, -0.0006181753, -0.0001785384, -0.0000817222, -0.0005134914, -0.0007985753, -0.0004634415, 0.0006095883, 0.0018304954, 0.0021000886, 0.0006253787, -0.0021646209, -0.0044350680, -0.0039757662, 0.0000000000, 0.0055934992, 0.0087987296, 0.0060840873, -0.0025086149, -0.0121481530, -0.0154854096, -0.0076841321, 0.0089245280, 0.0243004207, 0.0258895699, 0.0073266113, -0.0246923212, -0.0506484024, -0.0470616631, 0.0000000000, 0.0844482332, 0.1796266586, 0.2492838949, 0.2648645043, 0.2198168039, 0.1329296976, 0.0388129950, -0.0291201454, -0.0538004488, -0.0399552956, -0.0079859048, 0.0190560501, 0.0274658166, 0.0175880920, 0.0000000000, -0.0130334338, -0.0150320269, -0.0076489537, 0.0023244321, 0.0082917819, 0.0077659469, 0.0028179234, -0.0023760712, -0.0046504070, -0.0035140209, -0.0006930109, 0.0015902856, 0.0021531822, 0.0012655146, 0.0000000000, -0.0007301533, -0.0007061783, -0.0002865466 +}; + +const LC3_FLOAT lp_filter_96[240] = { +-0.0000892692, -0.0002002022, -0.0003090877, -0.0003845139, -0.0003937774, -0.0003112789, -0.0001271786, 0.0001458436, 0.0004698416, 0.0007844235, 0.0010156486, 0.0010901458, 0.0009521968, 0.0005804005, -0.0000000000, -0.0007127720, -0.0014368281, -0.0020234289, -0.0023226903, -0.0022152821, -0.0016433843, -0.0006341493, 0.0006905875, 0.0021226690, 0.0033952617, 0.0042271516, 0.0043772124, 0.0036995050, 0.0021879484, -0.0000000000, -0.0025485028, -0.0050205383, -0.0069244537, -0.0078010648, -0.0073173312, -0.0053495113, -0.0020385087, 0.0021968309, 0.0066966186, 0.0106468536, 0.0132070407, 0.0136606852, 0.0115647502, 0.0068717268, -0.0000000000, -0.0081653381, -0.0163488984, -0.0230339747, -0.0266668908, -0.0258889757, -0.0197617337, -0.0079494603, 0.0091720885, 0.0305024963, 0.0543067455, 0.0784006417, 0.1004086584, 0.1180594042, 0.1294770092, 0.1334264576, 0.1294770092, 0.1180594042, 0.1004086584, 0.0784006417, 0.0543067455, 0.0305024963, 0.0091720885, -0.0079494603, -0.0197617337, -0.0258889757, -0.0266668908, -0.0230339747, -0.0163488984, -0.0081653381, -0.0000000000, 0.0068717268, 0.0115647502, 0.0136606852, 0.0132070407, 0.0106468536, 0.0066966186, 0.0021968309, -0.0020385087, -0.0053495113, -0.0073173312, -0.0078010648, -0.0069244537, -0.0050205383, -0.0025485028, -0.0000000000, 0.0021879484, 0.0036995050, 0.0043772124, 0.0042271516, 0.0033952617, 0.0021226690, 0.0006905875, -0.0006341493, -0.0016433843, -0.0022152821, -0.0023226903, -0.0020234289, -0.0014368281, -0.0007127720, -0.0000000000, 0.0005804005, 0.0009521968, 0.0010901458, 0.0010156486, 0.0007844235, 0.0004698416, 0.0001458436, -0.0001271786, -0.0003112789, -0.0003937774, -0.0003845139, -0.0003090877, -0.0002002022, -0.0000892692, 0.0000000000, -0.0000408611, -0.0001432733, -0.0002567457, -0.0003530891, -0.0003992876, -0.0003650767, -0.0002317207, 0.0000000000, 0.0003047941, 0.0006327573, 0.0009152477, 0.0010765911, 0.0010500443, 0.0007951428, 0.0003126893, -0.0003465054, -0.0010823105, -0.0017570105, -0.0022175340, -0.0023252035, -0.0019878831, -0.0011880356, 0.0000000000, 0.0014089617, 0.0027967496, 0.0038829735, 0.0043993648, 0.0041458909, 0.0030420437, 0.0011622161, -0.0012543075, -0.0038244769, -0.0060740765, -0.0075160135, -0.0077427048, -0.0065167169, -0.0038420660, 0.0000000000, 0.0044622640, 0.0087940460, 0.0121502103, 0.0137329083, 0.0129447849, 0.0095280251, 0.0036633057, -0.0039929524, -0.0123461606, -0.0199776478, -0.0253242012, -0.0269002244, -0.0235308316, -0.0145600727, 0.0000000000, 0.0194064975, 0.0422241166, 0.0664648488, 0.0898133293, 0.1099084020, 0.1246419474, 0.1324322522, 0.1324322522, 0.1246419474, 0.1099084020, 0.0898133293, 0.0664648488, 0.0422241166, 0.0194064975, 0.0000000000, -0.0145600727, -0.0235308316, -0.0269002244, -0.0253242012, -0.0199776478, -0.0123461606, -0.0039929524, 0.0036633057, 0.0095280251, 0.0129447849, 0.0137329083, 0.0121502103, 0.0087940460, 0.0044622640, 0.0000000000, -0.0038420660, -0.0065167169, -0.0077427048, -0.0075160135, -0.0060740765, -0.0038244769, -0.0012543075, 0.0011622161, 0.0030420437, 0.0041458909, 0.0043993648, 0.0038829735, 0.0027967496, 0.0014089617, 0.0000000000, -0.0011880356, -0.0019878831, -0.0023252035, -0.0022175340, -0.0017570105, -0.0010823105, -0.0003465054, 0.0003126893, 0.0007951428, 0.0010500443, 0.0010765911, 0.0009152477, 0.0006327573, 0.0003047941, 0.0000000000, -0.0002317207, -0.0003650767, -0.0003992876, -0.0003530891, -0.0002567457, -0.0001432733, -0.0000408611 +}; + +const LC3_FLOAT *lp_filter[] = {lp_filter_8, lp_filter_16, lp_filter_24, lp_filter_32, lp_filter_48, lp_filter_96}; + +const LC3_INT up_fac[6] = {24, 12, 8, 6, 4, 2}; + +/* TNS */ +const LC3_INT huff_bits_tns[8][17] = { + {20480, 15725, 12479, 10334, 8694, 7320, 6964, 6335, 5504, 5637, 6566, 6758, 8433, 11348, 15186, 20480, 20480}, + {20480, 20480, 20480, 20480, 12902, 9368, 7057, 5901, 5254, 5485, 5598, 6076, 7608, 10742, 15186, 20480, 20480}, + {20480, 20480, 20480, 20480, 13988, 9368, 6702, 4841, 4585, 4682, 5859, 7764, 12109, 20480, 20480, 20480, 20480}, + {20480, 20480, 20480, 20480, 18432, 13396, 8982, 4767, 3779, 3658, 6335, 9656, 13988, 20480, 20480, 20480, 20480}, + {20480, 20480, 20480, 20480, 20480, 14731, 9437, 4275, 3249, 3493, 8483, 13988, 17234, 20480, 20480, 20480, 20480}, + {20480, 20480, 20480, 20480, 20480, 20480, 12902, 4753, 3040, 2953, 9105, 15725, 20480, 20480, 20480, 20480, 20480}, + {20480, 20480, 20480, 20480, 20480, 20480, 12902, 3821, 3346, 3000, 12109, 20480, 20480, 20480, 20480, 20480, + 20480}, + {20480, 20480, 20480, 20480, 20480, 20480, 15725, 3658, 20480, 1201, 10854, 18432, 20480, 20480, 20480, 20480, + 20480}}; + +const LC3_INT order1_tns[8] = {17234, 13988, 11216, 8694, 6566, 4977, 3961, 3040}; +const LC3_INT order2_tns[8] = {12683, 9437, 6874, 5541, 5121, 5170, 5359, 5056}; + +const LC3_FLOAT lagw_tns[9] = {1, + 0.998028026020383, + 0.992135405511397, + 0.982391584470799, + 0.968910791191297, + 0.951849807369274, + 0.931404933402306, + 0.907808229996959, + 0.881323136669471}; + +const LC3_FLOAT quants_pts_tns[17] = { -0.995727539062500, -0.961822509765625, -0.895172119140625, + -0.798004150390625, -0.673706054687500, -0.526428222656250, + -0.361236572265625, -0.183746337890625, 0.000000000000000, + 0.183746337890625, 0.361236572265625, 0.526428222656250, + 0.673706054687500, 0.798004150390625, 0.895172119140625, + 0.961822509765625, 0.995727539062500}; + +const LC3_FLOAT quants_thr_tns[18] = {-1, + -0.982973099683902, + -0.932472229404356, + -0.850217135729614, + -0.739008917220659, + -0.602634636379256, + -0.445738355776538, + -0.273662990072083, + -0.0922683594633020, + 0.0922683594633020, + 0.273662990072083, + 0.445738355776538, + 0.602634636379256, + 0.739008917220659, + 0.850217135729614, + 0.932472229404356, + 0.982973099683902, + 1}; + +/* SNS */ +const LC3_FLOAT sns_vq_far_adj_gains_fl[8] = {1.05859375000000, 1.23706054687500, 1.43920898437500, 1.98950195312500, + 2.49877929687500, 3.13110351562500, 4.11816406250000, 4.85400390625000}; + +const LC3_FLOAT sns_vq_near_adj_gains_fl[4] = {1.73315429687500, 2.22949218750000, 2.74731445312500, 3.61523437500000}; + +const LC3_FLOAT sns_vq_reg_lf_adj_gains_fl[4] = {1.52465820312500, 3.67260742187500, 4.36059570312500, + 5.13037109375000}; + +const LC3_FLOAT q_g_sns[6] = {2.17651367187500, 2.94287109375000, 1.52465820312500, + 3.67260742187500, 4.36059570312500, 5.13037109375000}; + +const LC3_FLOAT sns_vq_reg_adj_gains_fl[2] = {2.17651367187500, 2.94287109375000}; + +/* First element in each row is multiplied with norm2 = 1 / sqrt(2) */ +const LC3_FLOAT idct_lookup[M][M] = { + {0.707106781186547, 0.995184726672197, 0.980785280403230, 0.956940335732209, 0.923879532511287, 0.881921264348355, 0.831469612302545, 0.773010453362737, 0.707106781186548, 0.634393284163646, 0.555570233019602, 0.471396736825998, 0.382683432365090, 0.290284677254462, 0.195090322016128, 0.0980171403295608}, + {0.707106781186547, 0.956940335732209, 0.831469612302545, 0.634393284163646, 0.382683432365090, 0.0980171403295608, -0.195090322016128, -0.471396736825998, -0.707106781186548, -0.881921264348355, -0.980785280403230, -0.995184726672197, -0.923879532511287, -0.773010453362737, -0.555570233019602, -0.290284677254462}, + {0.707106781186547, 0.881921264348355, 0.555570233019602, 0.0980171403295608, -0.382683432365090, -0.773010453362737, -0.980785280403230, -0.956940335732209, -0.707106781186548, -0.290284677254462, 0.195090322016128, 0.634393284163646, 0.923879532511287, 0.995184726672197, 0.831469612302546, 0.471396736825998}, + {0.707106781186547, 0.773010453362737, 0.195090322016128, -0.471396736825998, -0.923879532511287, -0.956940335732209, -0.555570233019602, 0.0980171403295601, 0.707106781186547, 0.995184726672197, 0.831469612302546, 0.290284677254463, -0.382683432365090, -0.881921264348355, -0.980785280403231, -0.634393284163645}, + {0.707106781186547, 0.634393284163646, -0.195090322016128, -0.881921264348355, -0.923879532511287, -0.290284677254462, 0.555570233019602, 0.995184726672197, 0.707106781186548, -0.0980171403295600, -0.831469612302545, -0.956940335732209, -0.382683432365091, 0.471396736825997, 0.980785280403230, 0.773010453362738}, + {0.707106781186547, 0.471396736825998, -0.555570233019602, -0.995184726672197, -0.382683432365090, 0.634393284163645, 0.980785280403231, 0.290284677254463, -0.707106781186547, -0.956940335732209, -0.195090322016130, 0.773010453362736, 0.923879532511287, 0.0980171403295626, -0.831469612302544, -0.881921264348356}, + {0.707106781186547, 0.290284677254462, -0.831469612302545, -0.773010453362737, 0.382683432365090, 0.995184726672197, 0.195090322016128, -0.881921264348356, -0.707106781186547, 0.471396736825997, 0.980785280403230, 0.0980171403295591, -0.923879532511287, -0.634393284163646, 0.555570233019604, 0.956940335732208}, + {0.707106781186547, 0.0980171403295608, -0.980785280403230, -0.290284677254463, 0.923879532511287, 0.471396736825998, -0.831469612302544, -0.634393284163647, 0.707106781186547, 0.773010453362738, -0.555570233019602, -0.881921264348356, 0.382683432365086, 0.956940335732209, -0.195090322016125, -0.995184726672197}, + {0.707106781186547, -0.0980171403295607, -0.980785280403230, 0.290284677254463, 0.923879532511287, -0.471396736825998, -0.831469612302545, 0.634393284163646, 0.707106781186547, -0.773010453362737, -0.555570233019603, 0.881921264348356, 0.382683432365088, -0.956940335732209, -0.195090322016127, 0.995184726672197}, + {0.707106781186547, -0.290284677254462, -0.831469612302546, 0.773010453362737, 0.382683432365090, -0.995184726672197, 0.195090322016127, 0.881921264348356, -0.707106781186547, -0.471396736825998, 0.980785280403230, -0.0980171403295577, -0.923879532511288, 0.634393284163644, 0.555570233019606, -0.956940335732208}, + {0.707106781186547, -0.471396736825998, -0.555570233019602, 0.995184726672197, -0.382683432365090, -0.634393284163645, 0.980785280403230, -0.290284677254463, -0.707106781186547, 0.956940335732209, -0.195090322016129, -0.773010453362737, 0.923879532511287, -0.0980171403295610, -0.831469612302545, 0.881921264348355}, + {0.707106781186547, -0.634393284163645, -0.195090322016129, 0.881921264348355, -0.923879532511286, 0.290284677254461, 0.555570233019603, -0.995184726672197, 0.707106781186547, 0.0980171403295628, -0.831469612302547, 0.956940335732208, -0.382683432365089, -0.471396736825999, 0.980785280403231, -0.773010453362733}, + {0.707106781186547, -0.773010453362737, 0.195090322016128, 0.471396736825998, -0.923879532511287, 0.956940335732209, -0.555570233019602, -0.0980171403295592, 0.707106781186548, -0.995184726672197, 0.831469612302546, -0.290284677254462, -0.382683432365091, 0.881921264348355, -0.980785280403231, 0.634393284163644}, + {0.707106781186547, -0.881921264348355, 0.555570233019602, -0.0980171403295600, -0.382683432365091, 0.773010453362738, -0.980785280403231, 0.956940335732208, -0.707106781186546, 0.290284677254462, 0.195090322016130, -0.634393284163649, 0.923879532511288, -0.995184726672197, 0.831469612302542, -0.471396736825993}, + {0.707106781186547, -0.956940335732209, 0.831469612302545, -0.634393284163645, 0.382683432365090, -0.0980171403295615, -0.195090322016130, 0.471396736825998, -0.707106781186548, 0.881921264348355, -0.980785280403230, 0.995184726672197, -0.923879532511285, 0.773010453362735, -0.555570233019601, 0.290284677254462}, + {0.707106781186547, -0.995184726672197, 0.980785280403230, -0.956940335732209, 0.923879532511286, -0.881921264348355, 0.831469612302544, -0.773010453362736, 0.707106781186546, -0.634393284163644, 0.555570233019601, -0.471396736825994, 0.382683432365086, -0.290284677254458, 0.195090322016124, -0.0980171403295567} +}; + +const LC3_FLOAT sns_dec_gains[4][8] = { + {2.17651367187500, 2.94287109375000, 0, 0, 0, 0, 0, 0}, + {1.52465820312500, 3.67260742187500, 4.36059570312500, 5.13037109375000, 0, 0, 0, 0}, + {1.73315429687500, 2.22949218750000, 2.74731445312500, 3.61523437500000, 0, 0, 0, 0}, + {1.05859375000000, 1.23706054687500, 1.43920898437500, 1.98950195312500, 2.49877929687500, 3.13110351562500, + 4.11816406250000, 4.85400390625000}}; + +/* Global Gain */ +const LC3_INT gg_p1[6] = {80, 230, 380, 530, 680, 830}; +const LC3_INT gg_p2[6] = {500, 1025, 1550, 2075, 2600, 3125}; +const LC3_INT gg_p3[6] = {850, 1700, 2550, 3400, 4250, 5100}; + +const LC3_FLOAT gg_c[6] = {0.00575396825396825, 0.00500524109014675, 0.00473646723646723, + 0.00459816612729234, 0.00451388888888889, 0.004457153231663}; +const LC3_FLOAT gg_d[6] = {1310.34482758621, 3241.36125654450, 5267.66917293233, + 7326.39296187684, 9400.00000000000, 11481.67006109979}; + +/* Olpa */ +const LC3_FLOAT olpa_down2[5] = {0.1236796411180537, 0.2353512128364889, 0.2819382920909148, 0.2353512128364889, + 0.1236796411180537}; + +const LC3_FLOAT olpa_acw[98] = {1.0, + 0.994845360824742, + 0.989690721649485, + 0.984536082474227, + 0.979381443298969, + 0.974226804123711, + 0.969072164948454, + 0.963917525773196, + 0.958762886597938, + 0.953608247422680, + 0.948453608247423, + 0.943298969072165, + 0.938144329896907, + 0.932989690721650, + 0.927835051546392, + 0.922680412371134, + 0.917525773195876, + 0.912371134020619, + 0.907216494845361, + 0.902061855670103, + 0.896907216494845, + 0.891752577319588, + 0.886597938144330, + 0.881443298969072, + 0.876288659793814, + 0.871134020618557, + 0.865979381443299, + 0.860824742268041, + 0.855670103092784, + 0.850515463917526, + 0.845360824742268, + 0.840206185567010, + 0.835051546391753, + 0.829896907216495, + 0.824742268041237, + 0.819587628865979, + 0.814432989690722, + 0.809278350515464, + 0.804123711340206, + 0.798969072164949, + 0.793814432989691, + 0.788659793814433, + 0.783505154639175, + 0.778350515463918, + 0.773195876288660, + 0.768041237113402, + 0.762886597938144, + 0.757731958762887, + 0.752577319587629, + 0.747422680412371, + 0.742268041237113, + 0.737113402061856, + 0.731958762886598, + 0.726804123711340, + 0.721649484536083, + 0.716494845360825, + 0.711340206185567, + 0.706185567010309, + 0.701030927835052, + 0.695876288659794, + 0.690721649484536, + 0.685567010309278, + 0.680412371134021, + 0.675257731958763, + 0.670103092783505, + 0.664948453608247, + 0.659793814432990, + 0.654639175257732, + 0.649484536082474, + 0.644329896907216, + 0.639175257731959, + 0.634020618556701, + 0.628865979381443, + 0.623711340206186, + 0.618556701030928, + 0.613402061855670, + 0.608247422680412, + 0.603092783505155, + 0.597938144329897, + 0.592783505154639, + 0.587628865979382, + 0.582474226804124, + 0.577319587628866, + 0.572164948453608, + 0.567010309278351, + 0.561855670103093, + 0.556701030927835, + 0.551546391752577, + 0.546391752577320, + 0.541237113402062, + 0.536082474226804, + 0.530927835051546, + 0.525773195876289, + 0.520618556701031, + 0.515463917525773, + 0.510309278350515, + 0.505154639175258, + 0.500000000000000}; + +/* LTPF */ +const LC3_FLOAT conf_tilt_filter_16[4][3] = {{6.023618207009578e-01, 4.197609261363617e-01, -1.883424527883687e-02}, + {5.994768582584314e-01, 4.197609261363620e-01, -1.594928283631041e-02}, + {5.967764663733787e-01, 4.197609261363617e-01, -1.324889095125780e-02}, + {5.942410120098895e-01, 4.197609261363618e-01, -1.071343658776831e-02}}; + +const LC3_FLOAT conf_tilt_filter_24[4][5] = {{3.989695588963494e-01, 5.142508607708275e-01, 1.004382966157454e-01, + -1.278893956818042e-02, -1.572280075461383e-03}, + {3.948634911286333e-01, 5.123819208048688e-01, 1.043194926386267e-01, + -1.091999960222166e-02, -1.347408330627317e-03}, + {3.909844475885914e-01, 5.106053522688359e-01, 1.079832524685944e-01, + -9.143431066188848e-03, -1.132124620551895e-03}, + {3.873093888199928e-01, 5.089122083363975e-01, 1.114517380217371e-01, + -7.450287133750717e-03, -9.255514050963111e-04}}; + +const LC3_FLOAT conf_tilt_filter_32[4][7] = { + {2.982379446702096e-01, 4.652809203721290e-01, 2.105997428614279e-01, 3.766780380806063e-02, -1.015696155796564e-02, + -2.535880996101096e-03, -3.182946168719958e-04}, + {2.943834154510240e-01, 4.619294002718798e-01, 2.129465770091844e-01, 4.066175002688857e-02, -8.693272297010050e-03, + -2.178307114679820e-03, -2.742888063983188e-04}, + {2.907439213122688e-01, 4.587461910960279e-01, 2.151456974108970e-01, 4.350104772529774e-02, -7.295495347716925e-03, + -1.834395637237086e-03, -2.316920186482416e-04}, + {2.872975852589158e-01, 4.557148886861379e-01, 2.172126950911401e-01, 4.620088878229615e-02, -5.957463802125952e-03, + -1.502934284345198e-03, -1.903851911308866e-04}}; + +const LC3_FLOAT conf_tilt_filter_48[4][11] = { + {1.981363739883217e-01, 3.524494903964904e-01, 2.513695269649414e-01, 1.424146237314458e-01, 5.704731023952599e-02, + 9.293366241586384e-03, -7.226025368953745e-03, -3.172679890356356e-03, -1.121835963567014e-03, + -2.902957238400140e-04, -4.270815593769240e-05}, + {1.950709426598375e-01, 3.484660408341632e-01, 2.509988459466574e-01, 1.441167412482088e-01, 5.928947317677285e-02, + 1.108923827452231e-02, -6.192908108653504e-03, -2.726705509251737e-03, -9.667125826217151e-04, + -2.508100923165204e-04, -3.699938766131869e-05}, + {1.921810055196015e-01, 3.446945561091513e-01, 2.506220094626024e-01, 1.457102447664837e-01, 6.141132133664525e-02, + 1.279941396562798e-02, -5.203721087886321e-03, -2.297324511109085e-03, -8.165608133217555e-04, + -2.123855748277408e-04, -3.141271330981649e-05}, + {1.894485314175868e-01, 3.411139251108252e-01, 2.502406876894361e-01, 1.472065631098081e-01, 6.342477229539051e-02, + 1.443203434150312e-02, -4.254449144657098e-03, -1.883081472613493e-03, -6.709619060722140e-04, + -1.749363341966872e-04, -2.593864735284285e-05}}; + +const LC3_FLOAT conf_inter_filter_16[4][4] = { + {2.098804630681809e-01, 5.835275754221211e-01, 2.098804630681809e-01, 0.000000000000000e+00}, + {1.069991860896389e-01, 5.500750019177116e-01, 3.356906254147840e-01, 6.698858366939680e-03}, + {3.967114782344967e-02, 4.592209296082350e-01, 4.592209296082350e-01, 3.967114782344967e-02}, + {6.698858366939680e-03, 3.356906254147840e-01, 5.500750019177116e-01, 1.069991860896389e-01}}; + +const LC3_FLOAT conf_inter_filter_24[4][6] = {{6.322231627323796e-02, 2.507309606013235e-01, 3.713909428901578e-01, + 2.507309606013235e-01, 6.322231627323796e-02, 0.000000000000000e+00}, + {3.459272174099855e-02, 1.986515602645028e-01, 3.626411726581452e-01, + 2.986750548992179e-01, 1.013092873505928e-01, 4.263543712369752e-03}, + {1.535746784963907e-02, 1.474344878058222e-01, 3.374259553990717e-01, + 3.374259553990717e-01, 1.474344878058222e-01, 1.535746784963907e-02}, + {4.263543712369752e-03, 1.013092873505928e-01, 2.986750548992179e-01, + 3.626411726581452e-01, 1.986515602645028e-01, 3.459272174099855e-02}}; + +const LC3_FLOAT conf_inter_filter_32[4][8] = { + {2.900401878228730e-02, 1.129857420560927e-01, 2.212024028097570e-01, 2.723909472446145e-01, 2.212024028097570e-01, + 1.129857420560927e-01, 2.900401878228730e-02, 0.000000000000000e+00}, + {1.703153418385261e-02, 8.722503785537784e-02, 1.961407762232199e-01, 2.689237982237257e-01, 2.424999102756389e-01, + 1.405773364650031e-01, 4.474877169485788e-02, 3.127030243100724e-03}, + {8.563673748488349e-03, 6.426222944493845e-02, 1.687676705918012e-01, 2.587445937795505e-01, 2.587445937795505e-01, + 1.687676705918012e-01, 6.426222944493845e-02, 8.563673748488349e-03}, + {3.127030243100724e-03, 4.474877169485788e-02, 1.405773364650031e-01, 2.424999102756389e-01, 2.689237982237257e-01, + 1.961407762232199e-01, 8.722503785537784e-02, 1.703153418385261e-02}}; + +const LC3_FLOAT conf_inter_filter_48[4][12] = { + {1.082359386659387e-02, 3.608969221303979e-02, 7.676401468099964e-02, 1.241530577501703e-01, 1.627596438300696e-01, + 1.776771417779109e-01, 1.627596438300696e-01, 1.241530577501703e-01, 7.676401468099964e-02, 3.608969221303979e-02, + 1.082359386659387e-02, 0.000000000000000e+00}, + {7.041404930459358e-03, 2.819702319820420e-02, 6.547044935127551e-02, 1.124647986743299e-01, 1.548418956489015e-01, + 1.767122381341857e-01, 1.691507213057663e-01, 1.352901577989766e-01, 8.851425011427483e-02, 4.499353848562444e-02, + 1.557613714732002e-02, 2.039721956502016e-03}, + {4.146998467444788e-03, 2.135757310741917e-02, 5.482735584552816e-02, 1.004971444643720e-01, 1.456060342830002e-01, + 1.738439838565869e-01, 1.738439838565869e-01, 1.456060342830002e-01, 1.004971444643720e-01, 5.482735584552816e-02, + 2.135757310741917e-02, 4.146998467444788e-03}, + {2.039721956502016e-03, 1.557613714732002e-02, 4.499353848562444e-02, 8.851425011427483e-02, 1.352901577989766e-01, + 1.691507213057663e-01, 1.767122381341857e-01, 1.548418956489015e-01, 1.124647986743299e-01, 6.547044935127551e-02, + 2.819702319820420e-02, 7.041404930459358e-03}}; + +const LC3_FLOAT inter4_1[33] = {0, + -2.874561161519444e-03, + -3.001251025861499e-03, + +2.745471654059321e-03, + +1.535727698935322e-02, + +2.868234046665657e-02, + +2.950385026557377e-02, + +4.598334491135473e-03, + -4.729632459043440e-02, + -1.058359163062837e-01, + -1.303050213607112e-01, + -7.544046357555201e-02, + +8.357885725250529e-02, + +3.301825710764459e-01, + +6.032970076366158e-01, + +8.174886856243178e-01, + +8.986382851273982e-01, + +8.174886856243178e-01, + +6.032970076366158e-01, + +3.301825710764459e-01, + +8.357885725250529e-02, + -7.544046357555201e-02, + -1.303050213607112e-01, + -1.058359163062837e-01, + -4.729632459043440e-02, + +4.598334491135473e-03, + +2.950385026557377e-02, + +2.868234046665657e-02, + +1.535727698935322e-02, + +2.745471654059321e-03, + -3.001251025861499e-03, + -2.874561161519444e-03, + 0}; + +const LC3_FLOAT enc_inter_filter[4][4] = { + {+2.098804630681809e-01, +5.835275754221211e-01, +2.098804630681809e-01, 0}, + {+1.069991860896389e-01, +5.500750019177116e-01, +3.356906254147840e-01, +6.698858366939680e-03}, + {+3.967114782344967e-02, +4.592209296082350e-01, +4.592209296082350e-01, +3.967114782344967e-02}, + {+6.698858366939680e-03, +3.356906254147840e-01, +5.500750019177116e-01, +1.069991860896389e-01}}; + +/* Bandwidth Detector */ +const LC3_INT threshold_quiet[4] = {20, 10, 10, 10}; +const LC3_INT threshold_brickwall[4] = {15, 23, 20, 20}; +const LC3_INT brickwall_dist[4] = {4, 4, 3, 1}; +const LC3_INT BW_warp_idx_start_16k[4] = {53, 0, 0, 0}; +const LC3_INT BW_warp_idx_stop_16k[4] = {63, 0, 0, 0}; +const LC3_INT BW_warp_idx_start_24k[4] = {47, 59, 0, 0}; +const LC3_INT BW_warp_idx_stop_24k[4] = {56, 63, 0, 0}; +const LC3_INT BW_warp_idx_start_32k[4] = {44, 54, 60, 0}; +const LC3_INT BW_warp_idx_stop_32k[4] = {52, 59, 63, 0}; +const LC3_INT BW_warp_idx_start_48k[4] = {41, 51, 57, 61}; +const LC3_INT BW_warp_idx_stop_48k[4] = {49, 55, 60, 63}; +const LC3_INT* BW_warp_idx_start_all[4] = {BW_warp_idx_start_16k, BW_warp_idx_start_24k, BW_warp_idx_start_32k, + BW_warp_idx_start_48k}; +const LC3_INT* BW_warp_idx_stop_all[4] = {BW_warp_idx_stop_16k, BW_warp_idx_stop_24k, BW_warp_idx_stop_32k, + BW_warp_idx_stop_48k}; + +const LC3_INT BW_warp_idx_start_16k_2_5ms[4] = {24, 0, 0, 0}; +const LC3_INT BW_warp_idx_stop_16k_2_5ms[4] = {34, 0, 0, 0}; +const LC3_INT BW_warp_idx_start_24k_2_5ms[4] = {24, 35, 0, 0}; +const LC3_INT BW_warp_idx_stop_24k_2_5ms[4] = {32, 39, 0, 0}; +const LC3_INT BW_warp_idx_start_32k_2_5ms[4] = {24, 33, 39, 0}; +const LC3_INT BW_warp_idx_stop_32k_2_5ms[4] = {31, 38, 42, 0}; +const LC3_INT BW_warp_idx_start_48k_2_5ms[4] = {22, 31, 37, 41}; +const LC3_INT BW_warp_idx_stop_48k_2_5ms[4] = {29, 35, 40, 43}; + +const LC3_INT* BW_warp_idx_start_all_2_5ms[4] = {BW_warp_idx_start_16k_2_5ms, BW_warp_idx_start_24k_2_5ms, + BW_warp_idx_start_32k_2_5ms, BW_warp_idx_start_48k_2_5ms}; +const LC3_INT* BW_warp_idx_stop_all_2_5ms[4] = {BW_warp_idx_stop_16k_2_5ms, BW_warp_idx_stop_24k_2_5ms, + BW_warp_idx_stop_32k_2_5ms, BW_warp_idx_stop_48k_2_5ms}; + +const LC3_INT bands_number_2_5ms_HR[6] = {20, 35, 40, 43, 45, 49}; + +const LC3_INT bands_number_2_5ms[5] = {20, 35, 40, 43, 44}; + + +const LC3_INT BW_warp_idx_start_16k_5ms[4] = {39, 0, 0, 0}; +const LC3_INT BW_warp_idx_stop_16k_5ms[4] = {49, 0, 0, 0}; +const LC3_INT BW_warp_idx_start_24k_5ms[4] = {35, 47, 0, 0}; +const LC3_INT BW_warp_idx_stop_24k_5ms[4] = {44, 51, 0, 0}; +const LC3_INT BW_warp_idx_start_32k_5ms[4] = {34, 44, 50, 0}; +const LC3_INT BW_warp_idx_stop_32k_5ms[4] = {42, 49, 53, 0}; +const LC3_INT BW_warp_idx_start_48k_5ms[4] = {32, 42, 48, 52}; +const LC3_INT BW_warp_idx_stop_48k_5ms[4] = {40, 46, 51, 54}; + +const LC3_INT* BW_warp_idx_start_all_5ms[4] = {BW_warp_idx_start_16k_5ms, BW_warp_idx_start_24k_5ms, + BW_warp_idx_start_32k_5ms, BW_warp_idx_start_48k_5ms}; +const LC3_INT* BW_warp_idx_stop_all_5ms[4] = {BW_warp_idx_stop_16k_5ms, BW_warp_idx_stop_24k_5ms, + BW_warp_idx_stop_32k_5ms, BW_warp_idx_stop_48k_5ms}; + +const LC3_INT bands_number_5ms[6] = {39, 50, 52, 54, 55, 58}; + + +const LC3_INT BW_cutoff_bin_all[MAX_BW_BANDS_NUMBER] = {80, 160, 240, 320, 400, 400}; +const LC3_INT BW_cutoff_bits_all[MAX_BW_BANDS_NUMBER] = {0, 1, 2, 2, 3, 0}; + +const LC3_INT BW_cutoff_bin_all_5ms[MAX_BW_BANDS_NUMBER] = {40, 80, 120, 160, 200, 200}; +const LC3_INT BW_cutoff_bin_all_2_5ms[MAX_BW_BANDS_NUMBER] = {20, 40, 60, 80, 100, 100}; + +/* Arithmetic coding */ +const LC3_INT tns_cf[8][18] = {{0, 1, 6, 21, 52, 106, 192, 289, 409, 568, 720, 831, 935, 994, 1016, 1022, 1023, 1024}, + {0, 1, 2, 3, 4, 17, 60, 154, 293, 466, 626, 780, 911, 989, 1016, 1022, 1023, 1024}, + {0, 1, 2, 3, 4, 13, 56, 162, 361, 578, 788, 929, 1003, 1020, 1021, 1022, 1023, 1024}, + {0, 1, 2, 3, 4, 6, 17, 66, 270, 555, 852, 972, 1011, 1020, 1021, 1022, 1023, 1024}, + {0, 1, 2, 3, 4, 5, 12, 54, 295, 636, 950, 1008, 1017, 1020, 1021, 1022, 1023, 1024}, + {0, 1, 2, 3, 4, 5, 6, 19, 224, 590, 967, 1014, 1019, 1020, 1021, 1022, 1023, 1024}, + {0, 1, 2, 3, 4, 5, 6, 19, 300, 630, 1001, 1018, 1019, 1020, 1021, 1022, 1023, 1024}, + {0, 1, 2, 3, 4, 5, 6, 11, 308, 309, 991, 1017, 1019, 1020, 1021, 1022, 1023, 1024}}; + +const LC3_INT tns_freq_cf[2][9] = {{0, 3, 12, 35, 89, 200, 390, 658, 1024}, {0, 14, 56, 156, 313, 494, 672, 839, 1024}}; + +/* MDCT Windows */ + + +const LC3_FLOAT MDCT_WINDOW_80_2_5ms[40] = { + 6.737914289329320e-03, 2.732289618100209e-02, 6.163560962361236e-02, 1.119125037883055e-01, 1.787053464784875e-01, + 2.607525136824537e-01, 3.549776504187033e-01, 4.567696724165073e-01, 5.605239559005871e-01, 6.603665285212146e-01, + 7.509434386216048e-01, 8.281382099997300e-01, 8.895849967038094e-01, 9.348747871791264e-01, 9.654056798094166e-01, + 9.839026370225886e-01, 9.937180643904148e-01, 9.980987183772584e-01, 9.996266599807562e-01, 9.999772999978698e-01, + 9.999772999978698e-01, 9.996266599807562e-01, 9.980987183772584e-01, 9.937180643904148e-01, 9.839026370225886e-01, + 9.654056798094166e-01, 9.348747871791264e-01, 8.895849967038094e-01, 8.281382099997300e-01, 7.509434386216048e-01, + 6.603665285212146e-01, 5.605239559005871e-01, 4.567696724165073e-01, 3.549776504187033e-01, 2.607525136824537e-01, + 1.787053464784875e-01, 1.119125037883055e-01, 6.163560962361236e-02, 2.732289618100209e-02, 6.737914289329320e-03}; + +const LC3_FLOAT MDCT_WINDOW_160_2_5ms[80] = { + 4.764416154578566e-03, 1.204636278996989e-02, 2.226396539371650e-02, 3.580223111285056e-02, 5.299054649961241e-02, + 7.408518398076024e-02, 9.925385917916330e-02, 1.285631180041137e-01, 1.619692437449073e-01, 1.993132407013812e-01, + 2.403202823615340e-01, 2.846038181323611e-01, 3.316743228466244e-01, 3.809524578920635e-01, 4.317862022264749e-01, + 4.834713159013930e-01, 5.352743274612082e-01, 5.864570980113353e-01, 6.363019156559162e-01, 6.841360194558924e-01, + 7.293544453028629e-01, 7.714401286766273e-01, 8.099802912368443e-01, 8.446782786131956e-01, 8.753602039735273e-01, + 9.019759839191052e-01, 9.245946272967390e-01, 9.433939492938426e-01, 9.586452246292587e-01, 9.706936498636800e-01, + 9.799358305935717e-01, 9.867958066797319e-01, 9.917013283691115e-01, 9.950621445106043e-01, 9.972519167765670e-01, + 9.985950139980033e-01, 9.993588946156141e-01, 9.997521272020117e-01, 9.999274399392850e-01, 9.999886501049429e-01, + 9.999886501049429e-01, 9.999274399392850e-01, 9.997521272020117e-01, 9.993588946156141e-01, 9.985950139980033e-01, + 9.972519167765670e-01, 9.950621445106043e-01, 9.917013283691115e-01, 9.867958066797319e-01, 9.799358305935717e-01, + 9.706936498636800e-01, 9.586452246292587e-01, 9.433939492938426e-01, 9.245946272967390e-01, 9.019759839191052e-01, + 8.753602039735273e-01, 8.446782786131956e-01, 8.099802912368443e-01, 7.714401286766273e-01, 7.293544453028629e-01, + 6.841360194558924e-01, 6.363019156559162e-01, 5.864570980113353e-01, 5.352743274612082e-01, 4.834713159013930e-01, + 4.317862022264749e-01, 3.809524578920635e-01, 3.316743228466244e-01, 2.846038181323611e-01, 2.403202823615340e-01, + 1.993132407013812e-01, 1.619692437449073e-01, 1.285631180041137e-01, 9.925385917916330e-02, 7.408518398076024e-02, + 5.299054649961241e-02, 3.580223111285056e-02, 2.226396539371650e-02, 1.204636278996989e-02, 4.764416154578566e-03}; + +const LC3_FLOAT MDCT_WINDOW_240_2_5ms[120] = { + 3.890134207235998e-03, 8.202595078385781e-03, 1.370235555340779e-02, 2.052968531182845e-02, 2.880307728389693e-02, + 3.862785141889536e-02, 5.009569719921809e-02, 6.328296540190831e-02, 7.824881086160715e-02, 9.503346510857243e-02, + 1.136567491769230e-01, 1.341168883357315e-01, 1.563896708020576e-01, 1.804279808512455e-01, 2.061617274373514e-01, + 2.334981807379911e-01, 2.623227204239969e-01, 2.924999908279060e-01, 3.238754496100354e-01, 3.562772881250116e-01, + 3.895186936283779e-01, 4.234004158919065e-01, 4.577135938730904e-01, 4.922427919542673e-01, 5.267691900603833e-01, + 5.610738677940736e-01, 5.949411196851041e-01, 6.281617368097510e-01, 6.605361894447956e-01, 6.918776461105686e-01, + 7.220147663396499e-01, 7.507942077785026e-01, 7.780827927721814e-01, 8.037692853722609e-01, 8.277657367145603e-01, + 8.500083649018569e-01, 8.704579448595252e-01, 8.890996940634835e-01, 9.059426515086708e-01, 9.210185597011833e-01, + 9.343802726761132e-01, 9.460997268469628e-01, 9.562655255553633e-01, 9.649802020504638e-01, 9.723572386690237e-01, + 9.785179314351103e-01, 9.835881982445411e-01, 9.876954342642392e-01, 9.909655192099981e-01, 9.935200769821082e-01, + 9.954740782709803e-01, 9.969338611957889e-01, 9.979956243841658e-01, 9.987444223234112e-01, 9.992536660401901e-01, + 9.995851053006831e-01, 9.997892438014110e-01, 9.999061183192590e-01, 9.999663581511030e-01, 9.999924333992981e-01, + 9.999924333992981e-01, 9.999663581511030e-01, 9.999061183192590e-01, 9.997892438014110e-01, 9.995851053006831e-01, + 9.992536660401901e-01, 9.987444223234112e-01, 9.979956243841658e-01, 9.969338611957889e-01, 9.954740782709803e-01, + 9.935200769821082e-01, 9.909655192099981e-01, 9.876954342642392e-01, 9.835881982445411e-01, 9.785179314351103e-01, + 9.723572386690237e-01, 9.649802020504638e-01, 9.562655255553633e-01, 9.460997268469628e-01, 9.343802726761132e-01, + 9.210185597011833e-01, 9.059426515086708e-01, 8.890996940634835e-01, 8.704579448595252e-01, 8.500083649018569e-01, + 8.277657367145603e-01, 8.037692853722609e-01, 7.780827927721814e-01, 7.507942077785026e-01, 7.220147663396499e-01, + 6.918776461105686e-01, 6.605361894447956e-01, 6.281617368097510e-01, 5.949411196851041e-01, 5.610738677940736e-01, + 5.267691900603833e-01, 4.922427919542673e-01, 4.577135938730904e-01, 4.234004158919065e-01, 3.895186936283779e-01, + 3.562772881250116e-01, 3.238754496100354e-01, 2.924999908279060e-01, 2.623227204239969e-01, 2.334981807379911e-01, + 2.061617274373514e-01, 1.804279808512455e-01, 1.563896708020576e-01, 1.341168883357315e-01, 1.136567491769230e-01, + 9.503346510857243e-02, 7.824881086160715e-02, 6.328296540190831e-02, 5.009569719921809e-02, 3.862785141889536e-02, + 2.880307728389693e-02, 2.052968531182845e-02, 1.370235555340779e-02, 8.202595078385781e-03, 3.890134207235998e-03}; + +const LC3_FLOAT MDCT_WINDOW_320_2_5ms[160] = { + 3.368958353152859e-03, 6.455557414799749e-03, 1.014308076237845e-02, 1.452126850237346e-02, 1.965076732239952e-02, + 2.558352795411825e-02, 3.236628529621430e-02, 4.004117865352276e-02, 4.864564178753818e-02, 5.821207082124419e-02, + 6.876742903793599e-02, 8.033284980531531e-02, 9.292326595333501e-02, 1.065470811378728e-01, 1.212058930254449e-01, + 1.368942751980506e-01, 1.535996228917228e-01, 1.713020663983868e-01, 1.899744548998832e-01, 2.095824125414741e-01, + 2.300844676343023e-01, 2.514322549787097e-01, 2.735707904154788e-01, 2.964388158404272e-01, 3.199692120640840e-01, + 3.440894760693133e-01, 3.687222584236977e-01, 3.937859558486231e-01, 4.191953532416662e-01, 4.448623088011174e-01, + 4.706964753188311e-01, 4.966060501969578e-01, 5.224985463116437e-01, 5.482815754977786e-01, 5.738636361677886e-01, + 5.991548964078475e-01, 6.240679638193776e-01, 6.485186333941402e-01, 6.724266048285701e-01, 6.957161608975563e-01, + 7.183167988192716e-01, 7.401638069500036e-01, 7.611987796499656e-01, 7.813700637561797e-01, 8.006331307849442e-01, + 8.189508697622124e-01, 8.362937964433754e-01, 8.526401756322647e-01, 8.679760543400818e-01, 8.822952046352904e-01, + 8.955989762210201e-01, 9.078960600314304e-01, 9.192021654545784e-01, 9.295396151552272e-01, 9.389368628711653e-01, + 9.474279409702298e-01, 9.550518459555614e-01, 9.618518714601797e-01, 9.678748995383242e-01, 9.731706621931426e-01, + 9.777909860257944e-01, 9.817890335940264e-01, 9.852185554726640e-01, 9.881331670617683e-01, 9.905856638463937e-01, + 9.926273880444285e-01, 9.943076583739057e-01, 9.956732730391862e-01, 9.967680940129237e-01, 9.976327183405286e-01, + 9.983042396036903e-01, 9.988160999578843e-01, 9.991980304284215e-01, 9.994760745391177e-01, 9.996726879821318e-01, + 9.998069050289865e-01, 9.998945608218308e-01, 9.999485576331654e-01, 9.999791626721350e-01, 9.999943250437048e-01, + 9.999943250437048e-01, 9.999791626721350e-01, 9.999485576331654e-01, 9.998945608218308e-01, 9.998069050289865e-01, + 9.996726879821318e-01, 9.994760745391177e-01, 9.991980304284215e-01, 9.988160999578843e-01, 9.983042396036903e-01, + 9.976327183405286e-01, 9.967680940129237e-01, 9.956732730391862e-01, 9.943076583739057e-01, 9.926273880444285e-01, + 9.905856638463937e-01, 9.881331670617683e-01, 9.852185554726640e-01, 9.817890335940264e-01, 9.777909860257944e-01, + 9.731706621931426e-01, 9.678748995383242e-01, 9.618518714601797e-01, 9.550518459555614e-01, 9.474279409702298e-01, + 9.389368628711653e-01, 9.295396151552272e-01, 9.192021654545784e-01, 9.078960600314304e-01, 8.955989762210201e-01, + 8.822952046352904e-01, 8.679760543400818e-01, 8.526401756322647e-01, 8.362937964433754e-01, 8.189508697622124e-01, + 8.006331307849442e-01, 7.813700637561797e-01, 7.611987796499656e-01, 7.401638069500036e-01, 7.183167988192716e-01, + 6.957161608975563e-01, 6.724266048285701e-01, 6.485186333941402e-01, 6.240679638193776e-01, 5.991548964078475e-01, + 5.738636361677886e-01, 5.482815754977786e-01, 5.224985463116437e-01, 4.966060501969578e-01, 4.706964753188311e-01, + 4.448623088011174e-01, 4.191953532416662e-01, 3.937859558486231e-01, 3.687222584236977e-01, 3.440894760693133e-01, + 3.199692120640840e-01, 2.964388158404272e-01, 2.735707904154788e-01, 2.514322549787097e-01, 2.300844676343023e-01, + 2.095824125414741e-01, 1.899744548998832e-01, 1.713020663983868e-01, 1.535996228917228e-01, 1.368942751980506e-01, + 1.212058930254449e-01, 1.065470811378728e-01, 9.292326595333501e-02, 8.033284980531531e-02, 6.876742903793599e-02, + 5.821207082124419e-02, 4.864564178753818e-02, 4.004117865352276e-02, 3.236628529621430e-02, 2.558352795411825e-02, + 1.965076732239952e-02, 1.452126850237346e-02, 1.014308076237845e-02, 6.455557414799749e-03, 3.368958353152859e-03}; + +const LC3_FLOAT MDCT_WINDOW_480_2_5ms[240] = { + 2.750746382614873e-03, 4.775245154322467e-03, 6.991265476184880e-03, 9.470118155887091e-03, 1.224415763156159e-02, + 1.533559472880042e-02, 1.876266772162453e-02, 2.254154337372088e-02, 2.668701415521377e-02, 3.121277069249126e-02, + 3.613150075407039e-02, 4.145491000214293e-02, 4.719370517091751e-02, 5.335755875796826e-02, 5.995506493224793e-02, + 6.699369195627566e-02, 7.447973421347953e-02, 8.241826576309315e-02, 9.081309669365416e-02, 9.966673316465058e-02, + 1.089803417907089e-01, 1.187537188695662e-01, 1.289852648491186e-01, 1.396719643506733e-01, 1.508093720039881e-01, + 1.623916042982366e-01, 1.744113376077630e-01, 1.868598125100347e-01, 1.997268444741311e-01, 2.130008409605561e-01, + 2.266688249366323e-01, 2.407164647759538e-01, 2.551281104752023e-01, 2.698868360870567e-01, 2.849744882339612e-01, + 3.003717405342550e-01, 3.160581537396951e-01, 3.320122413518523e-01, 3.482115404543554e-01, 3.646326874686314e-01, + 3.812514985127824e-01, 3.980430540166849e-01, 4.149817872214252e-01, 4.320415761679195e-01, 4.491958387581356e-01, + 4.664176304528364e-01, 4.836797441523142e-01, 5.009548117912680e-01, 5.182154071658814e-01, 5.354341495003542e-01, + 5.525838072516958e-01, 5.696374016455559e-01, 5.865683094322820e-01, 6.033503643513004e-01, 6.199579567933325e-01, + 6.363661311538971e-01, 6.525506803780192e-01, 6.684882372050696e-01, 6.841563616341746e-01, 6.995336241446708e-01, + 7.145996842225878e-01, 7.293353637631239e-01, 7.437227149404935e-01, 7.577450821603423e-01, 7.713871577361272e-01, + 7.846350309593857e-01, 7.974762302646725e-01, 8.098997582230498e-01, 8.218961191333729e-01, 8.334573390181531e-01, + 8.445769778704795e-01, 8.552501340402698e-01, 8.654734406919574e-01, 8.752450543115063e-01, 8.845646352883213e-01, + 8.934333206470277e-01, 9.018536890551258e-01, 9.098297182849719e-01, 9.173667353621834e-01, 9.244713596871228e-01, + 9.311514394712620e-01, 9.374159818855259e-01, 9.432750773727245e-01, 9.487398186303003e-01, 9.538222148222497e-01, + 9.585351016294561e-01, 9.628920477950361e-01, 9.669072588647543e-01, 9.705954788611818e-01, 9.739718906630962e-01, + 9.770520158876372e-01, 9.798516150909821e-01, 9.823865891128170e-01, 9.846728823898172e-01, 9.867263890529354e-01, + 9.885628626019504e-01, 9.901978299180545e-01, 9.916465103310770e-01, 9.929237404023775e-01, 9.940439050178721e-01, + 9.950208753087979e-01, 9.958679538316859e-01, 9.965978273449145e-01, 9.972225274187749e-01, 9.977533990110320e-01, + 9.982010770325636e-01, 9.985754708200026e-01, 9.988857563266385e-01, 9.991403757414241e-01, 9.993470441509588e-01, + 9.995127627727911e-01, 9.996438382121301e-01, 9.997459071295719e-01, 9.998239656559388e-01, 9.998824028526124e-01, + 9.999250374922579e-01, 9.999551574256286e-01, 9.999755608048836e-01, 9.999885984518604e-01, 9.999962166900126e-01, + 9.999962166900126e-01, 9.999885984518604e-01, 9.999755608048836e-01, 9.999551574256286e-01, 9.999250374922579e-01, + 9.998824028526124e-01, 9.998239656559388e-01, 9.997459071295719e-01, 9.996438382121301e-01, 9.995127627727911e-01, + 9.993470441509588e-01, 9.991403757414241e-01, 9.988857563266385e-01, 9.985754708200026e-01, 9.982010770325636e-01, + 9.977533990110320e-01, 9.972225274187749e-01, 9.965978273449145e-01, 9.958679538316859e-01, 9.950208753087979e-01, + 9.940439050178721e-01, 9.929237404023775e-01, 9.916465103310770e-01, 9.901978299180545e-01, 9.885628626019504e-01, + 9.867263890529354e-01, 9.846728823898172e-01, 9.823865891128170e-01, 9.798516150909821e-01, 9.770520158876372e-01, + 9.739718906630962e-01, 9.705954788611818e-01, 9.669072588647543e-01, 9.628920477950361e-01, 9.585351016294561e-01, + 9.538222148222497e-01, 9.487398186303003e-01, 9.432750773727245e-01, 9.374159818855259e-01, 9.311514394712620e-01, + 9.244713596871228e-01, 9.173667353621834e-01, 9.098297182849719e-01, 9.018536890551258e-01, 8.934333206470277e-01, + 8.845646352883213e-01, 8.752450543115063e-01, 8.654734406919574e-01, 8.552501340402698e-01, 8.445769778704795e-01, + 8.334573390181531e-01, 8.218961191333729e-01, 8.098997582230498e-01, 7.974762302646725e-01, 7.846350309593857e-01, + 7.713871577361272e-01, 7.577450821603423e-01, 7.437227149404935e-01, 7.293353637631239e-01, 7.145996842225878e-01, + 6.995336241446708e-01, 6.841563616341746e-01, 6.684882372050696e-01, 6.525506803780192e-01, 6.363661311538971e-01, + 6.199579567933325e-01, 6.033503643513004e-01, 5.865683094322820e-01, 5.696374016455559e-01, 5.525838072516958e-01, + 5.354341495003542e-01, 5.182154071658814e-01, 5.009548117912680e-01, 4.836797441523142e-01, 4.664176304528364e-01, + 4.491958387581356e-01, 4.320415761679195e-01, 4.149817872214252e-01, 3.980430540166849e-01, 3.812514985127824e-01, + 3.646326874686314e-01, 3.482115404543554e-01, 3.320122413518523e-01, 3.160581537396951e-01, 3.003717405342550e-01, + 2.849744882339612e-01, 2.698868360870567e-01, 2.551281104752023e-01, 2.407164647759538e-01, 2.266688249366323e-01, + 2.130008409605561e-01, 1.997268444741311e-01, 1.868598125100347e-01, 1.744113376077630e-01, 1.623916042982366e-01, + 1.508093720039881e-01, 1.396719643506733e-01, 1.289852648491186e-01, 1.187537188695662e-01, 1.089803417907089e-01, + 9.966673316465058e-02, 9.081309669365416e-02, 8.241826576309315e-02, 7.447973421347953e-02, 6.699369195627566e-02, + 5.995506493224793e-02, 5.335755875796826e-02, 4.719370517091751e-02, 4.145491000214293e-02, 3.613150075407039e-02, + 3.121277069249126e-02, 2.668701415521377e-02, 2.254154337372088e-02, 1.876266772162453e-02, 1.533559472880042e-02, + 1.224415763156159e-02, 9.470118155887091e-03, 6.991265476184880e-03, 4.775245154322467e-03, 2.750746382614873e-03}; + +const LC3_FLOAT MDCT_WINDOW_80[160] = { + -7.078546706512391e-04, -2.098197727900724e-03, -4.525198076002370e-03, -8.233976327300612e-03, + -1.337713096257934e-02, -1.999721557401502e-02, -2.800909464274782e-02, -3.721502082245055e-02, + -4.731768261606175e-02, -5.794654834034055e-02, -6.867606753531441e-02, -7.904647440788692e-02, + -8.859705468085925e-02, -9.688303623049199e-02, -1.034961241263523e-01, -1.080766457616878e-01, + -1.103242262600913e-01, -1.099809851424550e-01, -1.068172142230882e-01, -1.006190418791648e-01, + -9.116452506492527e-02, -7.820617483254730e-02, -6.146688124166948e-02, -4.063362855701623e-02, + -1.536329520788766e-02, 1.470155068746303e-02, 4.989736509080558e-02, 9.050369257152079e-02, + 1.366911019414417e-01, 1.884686389218322e-01, 2.456456803467095e-01, 3.077789078889820e-01, + 3.741642373060188e-01, 4.438114799213576e-01, 5.154735456539700e-01, 5.876661722564289e-01, + 6.587619767809000e-01, 7.270576699841359e-01, 7.908752989295335e-01, 8.486643364959733e-01, + 8.991320235484349e-01, 9.413348145272842e-01, 9.747634827941575e-01, 9.994114730415857e-01, + 1.015760373791603e+00, 1.024736164069697e+00, 1.027634294456205e+00, 1.025991493983836e+00, + 1.021427210603284e+00, 1.015439859549357e+00, 1.009366925499550e+00, 1.003508162416449e+00, + 9.988898206257559e-01, 9.953133902427869e-01, 9.925943919208190e-01, 9.905771957917731e-01, + 9.891371616557014e-01, 9.881790747212391e-01, 9.876249269174586e-01, 9.874056275509585e-01, + 9.874524849192456e-01, 9.876951134084213e-01, 9.880640617030884e-01, 9.884926873551375e-01, + 9.889230031022089e-01, 9.893074965384659e-01, 9.896146331889107e-01, 9.898319269347060e-01, + 9.899693102025342e-01, 9.900603352632121e-01, 9.901575015155720e-01, 9.903255289051605e-01, + 9.906303787150326e-01, 9.911298894709990e-01, 9.918665491182922e-01, 9.928619727154252e-01, + 9.941156069136238e-01, 9.956033775539884e-01, 9.972793109558521e-01, 9.990784840729244e-01, + 1.000922365901945e+00, 1.002728111386909e+00, 1.004416038098237e+00, 1.005919224127911e+00, + 1.007189345025525e+00, 1.008200146369426e+00, 1.008949493525753e+00, 1.009458241425143e+00, + 1.009768980817384e+00, 1.009940336228694e+00, 1.010039453539107e+00, 1.010132323996401e+00, + 1.010272524848519e+00, 1.010494354532353e+00, 1.010808068774316e+00, 1.011201071127927e+00, + 1.011641272406023e+00, 1.012080125934687e+00, 1.012458183122033e+00, 1.012706955800289e+00, + 1.012755013843985e+00, 1.012530134411619e+00, 1.011962331100864e+00, 1.010982135506986e+00, + 1.009512438049510e+00, 1.007460860286395e+00, 1.004708677491086e+00, 1.001111413242302e+00, + 9.965041017623596e-01, 9.907199995730845e-01, 9.823765865983288e-01, 9.708821747608998e-01, + 9.546732976073705e-01, 9.321553861564006e-01, 9.018003682081348e-01, 8.623984077953557e-01, + 8.132817365236141e-01, 7.544551974836834e-01, 6.866580716267418e-01, 6.113488038789190e-01, + 5.306181649316597e-01, 4.471309850999502e-01, 3.639114681156236e-01, 2.841647033392408e-01, + 2.110209448747969e-01, 1.472287968327703e-01, 9.482665349502291e-02, 5.482436608328477e-02, + 2.701461405056264e-02, 9.996743588367519e-03, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; + +const LC3_FLOAT MDCT_WINDOW_160[320] = { + -4.619898752628163e-04, -9.747166718929050e-04, -1.664473096973725e-03, -2.597106916737789e-03, + -3.806285163352241e-03, -5.324608721716763e-03, -7.175885277771099e-03, -9.382480860899108e-03, + -1.195270300743193e-02, -1.489528159506296e-02, -1.820666399965468e-02, -2.187570925786862e-02, + -2.588471937157619e-02, -3.020862738245264e-02, -3.481597793538342e-02, -3.967067992672979e-02, + -4.472698045914417e-02, -4.994225863256500e-02, -5.526334794593565e-02, -6.063717235243996e-02, + -6.600961519440657e-02, -7.131966266443390e-02, -7.651178225890490e-02, -8.152964005319532e-02, + -8.631137544905677e-02, -9.080411291245728e-02, -9.495377758870335e-02, -9.870736514214426e-02, + -1.020202684361974e-01, -1.048438825017798e-01, -1.071382314127799e-01, -1.088690135027248e-01, + -1.099969655786929e-01, -1.104898474883336e-01, -1.103225838568563e-01, -1.094621746650760e-01, + -1.078834293141886e-01, -1.055612509762041e-01, -1.024650162703341e-01, -9.857014566194629e-02, + -9.384684920715425e-02, -8.826309993000785e-02, -8.178792716809512e-02, -7.438785600211463e-02, + -6.602189797715241e-02, -5.665655641133161e-02, -4.624456893420224e-02, -3.474585776145929e-02, + -2.211581608120528e-02, -8.310425696208936e-03, 6.717697635290676e-03, 2.300642061077823e-02, + 4.060106462625085e-02, 5.953239090915557e-02, 7.983354189816511e-02, 1.015233140203748e-01, + 1.246171387327525e-01, 1.491152519299797e-01, 1.750067399059861e-01, 2.022699854906251e-01, + 2.308655379767671e-01, 2.607365124918583e-01, 2.918144694729168e-01, 3.240095704645023e-01, + 3.572175180786021e-01, 3.913146885756875e-01, 4.261571642320424e-01, 4.615925445090212e-01, + 4.974471592901086e-01, 5.335326819631583e-01, 5.696546730080154e-01, 6.056083823929643e-01, + 6.411830842823245e-01, 6.761653499550255e-01, 7.103400549562944e-01, 7.434943718765665e-01, + 7.754281892901473e-01, 8.059437233154637e-01, 8.348589373399948e-01, 8.620108336276733e-01, + 8.872599706865123e-01, 9.104863121445679e-01, 9.315962496426278e-01, 9.505220861927248e-01, + 9.672366712325431e-01, 9.817397501303696e-01, 9.940557180662704e-01, 1.004247514102417e+00, + 1.012407428282884e+00, 1.018650990561848e+00, 1.023118841384460e+00, 1.025972450969440e+00, + 1.027397523939210e+00, 1.027585830688143e+00, 1.026738673647482e+00, 1.025061777648234e+00, + 1.022756514615106e+00, 1.020009139549275e+00, 1.016996499560845e+00, 1.013915946100629e+00, + 1.011044869639164e+00, 1.007773858455400e+00, 1.004848753962734e+00, 1.002245009135684e+00, + 9.999393169239009e-01, 9.979055415627330e-01, 9.961203379971326e-01, 9.945597525471822e-01, + 9.932031606606762e-01, 9.920297273323891e-01, 9.910230654424902e-01, 9.901668953434221e-01, + 9.894488374513719e-01, 9.888556356037892e-01, 9.883778520531268e-01, 9.880051626345804e-01, + 9.877295459610343e-01, 9.875412739766566e-01, 9.874329809802893e-01, 9.873949921033299e-01, + 9.874197049003676e-01, 9.874973205882319e-01, 9.876201238703241e-01, 9.877781920433015e-01, + 9.879637979933339e-01, 9.881678007807095e-01, 9.883835200189653e-01, 9.886022219397892e-01, + 9.888182771263505e-01, 9.890247977602895e-01, 9.892178658748239e-01, 9.893923680007577e-01, + 9.895463342815009e-01, 9.896772011542693e-01, 9.897859195209235e-01, 9.898725363809847e-01, + 9.899410789223559e-01, 9.899945557067980e-01, 9.900394023736973e-01, 9.900814722948890e-01, + 9.901293790312005e-01, 9.901902265696609e-01, 9.902734448815004e-01, 9.903862280081246e-01, + 9.905379830873822e-01, 9.907348826312993e-01, 9.909842592301273e-01, 9.912905118607647e-01, + 9.916586940166509e-01, 9.920906151219310e-01, 9.925887208794144e-01, 9.931516528513824e-01, + 9.937790866568735e-01, 9.944668184371617e-01, 9.952116634297566e-01, 9.960068616185641e-01, + 9.968461329825753e-01, 9.977203369515556e-01, 9.986213520769593e-01, 9.995382582242990e-01, + 1.000461955079660e+00, 1.001380551217109e+00, 1.002284871786226e+00, 1.003163845364970e+00, + 1.004009147462043e+00, 1.004811375053364e+00, 1.005563968008037e+00, 1.006259855360867e+00, + 1.006895570408563e+00, 1.007466616298057e+00, 1.007972441990187e+00, 1.008411468616852e+00, + 1.008786009787269e+00, 1.009097763850333e+00, 1.009351762546296e+00, 1.009552401900961e+00, + 1.009707093778162e+00, 1.009822090220407e+00, 1.009906958448099e+00, 1.009969021400474e+00, + 1.010017890428877e+00, 1.010060809299530e+00, 1.010106564965965e+00, 1.010161131093372e+00, + 1.010231078494249e+00, 1.010319484524512e+00, 1.010430470494512e+00, 1.010564099281000e+00, + 1.010721360243234e+00, 1.010899655674578e+00, 1.011096993993037e+00, 1.011308167670753e+00, + 1.011529185153809e+00, 1.011753008569803e+00, 1.011973876511603e+00, 1.012182837094955e+00, + 1.012373028737774e+00, 1.012535058602453e+00, 1.012660975529858e+00, 1.012740575296603e+00, + 1.012765922449960e+00, 1.012726958954961e+00, 1.012615904116265e+00, 1.012422888521601e+00, + 1.012140460211194e+00, 1.011758810583150e+00, 1.011269960947744e+00, 1.010663676735228e+00, + 1.009930754807923e+00, 1.009058249873833e+00, 1.008034308295421e+00, 1.006843352506855e+00, + 1.005470005637052e+00, 1.003894772403371e+00, 1.002098854400575e+00, 1.000060686758758e+00, + 9.977600196406868e-01, 9.951746430061121e-01, 9.922861082472264e-01, 9.890757868707590e-01, + 9.847362453480265e-01, 9.798613526271561e-01, 9.741378617337759e-01, 9.673331975559332e-01, + 9.592539757044516e-01, 9.496984081652284e-01, 9.384634163826711e-01, 9.253567968750328e-01, + 9.101986790930605e-01, 8.928338316495705e-01, 8.731437835983047e-01, 8.510420440685049e-01, + 8.264839911291133e-01, 7.994681492797084e-01, 7.700431275216928e-01, 7.383028603058783e-01, + 7.043814340356083e-01, 6.684616478236647e-01, 6.307755329382612e-01, 5.915799587176216e-01, + 5.511703155400274e-01, 5.098915423728179e-01, 4.681017110047964e-01, 4.261772971493010e-01, + 3.845172335531009e-01, 3.435228672445613e-01, 3.036004651973099e-01, 2.651434678028531e-01, + 2.285283969438072e-01, 1.941021906320984e-01, 1.621735416384830e-01, 1.330015240938615e-01, + 1.067840430193724e-01, 8.365057236623041e-02, 6.365188111381356e-02, 4.676538412257621e-02, + 3.288072750732215e-02, 2.183057564646270e-02, 1.336381425803019e-02, 6.758124889697787e-03, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; + +const LC3_FLOAT MDCT_WINDOW_240[480] = { + -3.613496418928369e-04, -7.078546706512391e-04, -1.074443637110903e-03, -1.533478537964509e-03, + -2.098197727900724e-03, -2.778420871815740e-03, -3.584129920673041e-03, -4.525198076002370e-03, + -5.609327243712055e-03, -6.843234536105624e-03, -8.233976327300612e-03, -9.785314755557023e-03, + -1.149880303071551e-02, -1.337713096257934e-02, -1.542181679511618e-02, -1.762979910961727e-02, + -1.999721557401502e-02, -2.252080561390149e-02, -2.519406300389030e-02, -2.800909464274782e-02, + -3.095765092956728e-02, -3.402996266948349e-02, -3.721502082245055e-02, -4.050053247568393e-02, + -4.387219218706189e-02, -4.731768261606175e-02, -5.082325342672667e-02, -5.437166635159518e-02, + -5.794654834034055e-02, -6.153426201732499e-02, -6.511708163113709e-02, -6.867606753531441e-02, + -7.219447805250771e-02, -7.565695975592170e-02, -7.904647440788692e-02, -8.234442557322251e-02, + -8.553324579905185e-02, -8.859705468085925e-02, -9.152091100798199e-02, -9.428847446755965e-02, + -9.688303623049198e-02, -9.929123258537813e-02, -1.015008467688577e-01, -1.034961241263523e-01, + -1.052637003544443e-01, -1.067939984687745e-01, -1.080766457616878e-01, -1.090997300590506e-01, + -1.098524491515805e-01, -1.103242262600913e-01, -1.105084619148789e-01, -1.103977408741932e-01, + -1.099809851424550e-01, -1.092492774392824e-01, -1.081974227416502e-01, -1.068172142230882e-01, + -1.050995803285455e-01, -1.030360111111103e-01, -1.006190418791648e-01, -9.784120023411771e-02, + -9.469304216883027e-02, -9.116452506492527e-02, -8.724644532866996e-02, -8.293043914044632e-02, + -7.820617483254730e-02, -7.306142427456862e-02, -6.748468182105991e-02, -6.146688124166948e-02, + -5.499497258200362e-02, -4.805444424454820e-02, -4.063362855701623e-02, -3.272045590229335e-02, + -2.430122582451853e-02, -1.536329520788766e-02, -5.891434269890659e-03, 4.126595858583295e-03, + 1.470155068746303e-02, 2.584738191459814e-02, 3.757652772246801e-02, 4.989736509080558e-02, + 6.282034030592902e-02, 7.635397728566121e-02, 9.050369257152079e-02, 1.052747118478660e-01, + 1.206703467513333e-01, 1.366911019414417e-01, 1.533343890681390e-01, 1.705954709184399e-01, + 1.884686389218322e-01, 2.069449962574092e-01, 2.260093000067393e-01, 2.456456803467095e-01, + 2.658346019332584e-01, 2.865543814049772e-01, 3.077789078889820e-01, 3.294769437072290e-01, + 3.516171481750350e-01, 3.741642373060188e-01, 3.970739591211551e-01, 4.203043046885219e-01, + 4.438114799213576e-01, 4.675442291623012e-01, 4.914498631045615e-01, 5.154735456539700e-01, + 5.395557644293222e-01, 5.636399817032525e-01, 5.876661722564289e-01, 6.115695310143157e-01, + 6.352890592874099e-01, 6.587619767809000e-01, 6.819230974423550e-01, 7.047092819314779e-01, + 7.270576699841359e-01, 7.489068963384272e-01, 7.701990187606995e-01, 7.908752989295335e-01, + 8.108788692151807e-01, 8.301579139160681e-01, 8.486643364959733e-01, 8.663548164329093e-01, + 8.831896853053627e-01, 8.991320235484349e-01, 9.141540563656075e-01, 9.282282546151819e-01, + 9.413348145272842e-01, 9.534619388400459e-01, 9.646048250501910e-01, 9.747634827941575e-01, + 9.839435385219192e-01, 9.921529097154242e-01, 9.994114730415857e-01, 1.005746084650236e+00, + 1.011183971347815e+00, 1.015760373791603e+00, 1.019515072412387e+00, 1.022490937034641e+00, + 1.024736164069697e+00, 1.026304095700693e+00, 1.027250978292214e+00, 1.027634294456205e+00, + 1.027511063644843e+00, 1.026942795115598e+00, 1.025991493983836e+00, 1.024716149969084e+00, + 1.023175976163407e+00, 1.021427210603284e+00, 1.019521566634239e+00, 1.017510118327508e+00, + 1.015439859549357e+00, 1.013460916839174e+00, 1.011654901040475e+00, 1.009366925499550e+00, + 1.007263182132894e+00, 1.005313192386866e+00, 1.003508162416449e+00, 1.001840787319378e+00, + 1.000303927234380e+00, 9.988898206257559e-01, 9.975915283480670e-01, 9.964015284765968e-01, + 9.953133902427869e-01, 9.943201078053212e-01, 9.934158959186011e-01, 9.925943919208190e-01, + 9.918510277326026e-01, 9.911797988363887e-01, 9.905771957917731e-01, 9.900381047643838e-01, + 9.895594394179152e-01, 9.891371616557014e-01, 9.887684373604154e-01, 9.884497924570929e-01, + 9.881790747212391e-01, 9.879528358230726e-01, 9.877691368590689e-01, 9.876249269174586e-01, + 9.875179947346887e-01, 9.874458127312921e-01, 9.874056275509585e-01, 9.873951115886979e-01, + 9.874115368168944e-01, 9.874524849192456e-01, 9.875149888347144e-01, 9.875968894760857e-01, + 9.876951134084213e-01, 9.878075819424549e-01, 9.879311998177238e-01, 9.880640617030884e-01, + 9.882032571565917e-01, 9.883471084085503e-01, 9.884926873551375e-01, 9.886386592120545e-01, + 9.887825578295630e-01, 9.889230031022089e-01, 9.890581715933395e-01, 9.891867674284610e-01, + 9.893074965384659e-01, 9.894196399062921e-01, 9.895220757174378e-01, 9.896146331889107e-01, + 9.896970346678272e-01, 9.897692596535289e-01, 9.898319269347060e-01, 9.898852572653667e-01, + 9.899307640365727e-01, 9.899693102025343e-01, 9.900025692522435e-01, 9.900321562263099e-01, + 9.900603352632121e-01, 9.900889812894406e-01, 9.901206586012907e-01, 9.901575015155720e-01, + 9.902023946214220e-01, 9.902575406142213e-01, 9.903255289051605e-01, 9.904087914462694e-01, + 9.905096491583045e-01, 9.906303787150326e-01, 9.907727108894024e-01, 9.909387444078919e-01, + 9.911298894709990e-01, 9.913476318763218e-01, 9.915928560402563e-01, 9.918665491182922e-01, + 9.921691315380984e-01, 9.925010851461232e-01, 9.928619727154252e-01, 9.932519181564613e-01, + 9.936700207375173e-01, 9.941156069136238e-01, 9.945873147903244e-01, 9.950837402063278e-01, + 9.956033775539884e-01, 9.961439922621166e-01, 9.967034533921340e-01, 9.972793109558521e-01, + 9.978690858367024e-01, 9.984697087896268e-01, 9.990784840729244e-01, 9.996919011206490e-01, + 1.000308193833526e+00, 1.000922365901945e+00, 1.001532636590676e+00, 1.002135464655177e+00, + 1.002728111386909e+00, 1.003307449770187e+00, 1.003870934089686e+00, 1.004416038098237e+00, + 1.004940548815171e+00, 1.005442141810160e+00, 1.005919224127911e+00, 1.006370303149314e+00, + 1.006793927824538e+00, 1.007189345025525e+00, 1.007555573455895e+00, 1.007892674961336e+00, + 1.008200146369426e+00, 1.008478423284851e+00, 1.008727884997619e+00, 1.008949493525753e+00, + 1.009144112734761e+00, 1.009313224929575e+00, 1.009458241425143e+00, 1.009581280555682e+00, + 1.009684090687164e+00, 1.009768980817384e+00, 1.009838308708799e+00, 1.009894548257807e+00, + 1.009940336228694e+00, 1.009977916643680e+00, 1.010010230290263e+00, 1.010039453539107e+00, + 1.010068202038694e+00, 1.010098388689342e+00, 1.010132323996401e+00, 1.010171656775640e+00, + 1.010218096148412e+00, 1.010272524848519e+00, 1.010336490294771e+00, 1.010410221483215e+00, + 1.010494354532353e+00, 1.010588873699422e+00, 1.010693501186928e+00, 1.010808068774316e+00, + 1.010931436739342e+00, 1.011062876503041e+00, 1.011201071127927e+00, 1.011344700694417e+00, + 1.011491904228184e+00, 1.011641272406023e+00, 1.011790282474963e+00, 1.011937567254485e+00, + 1.012080125934687e+00, 1.012216235487353e+00, 1.012342907951334e+00, 1.012458183122033e+00, + 1.012558879696851e+00, 1.012642857380847e+00, 1.012706955800289e+00, 1.012748952907404e+00, + 1.012765799894453e+00, 1.012755013843985e+00, 1.012713798678211e+00, 1.012639775003457e+00, + 1.012530134411619e+00, 1.012382309473470e+00, 1.012194068117524e+00, 1.011962331100864e+00, + 1.011685173724601e+00, 1.011359143572147e+00, 1.010982135506986e+00, 1.010550715971368e+00, + 1.010062133151922e+00, 1.009512438049510e+00, 1.008898689394160e+00, 1.008215923600973e+00, + 1.007460860286395e+00, 1.006627741823389e+00, 1.005712337656749e+00, 1.004708677491086e+00, + 1.003611467285588e+00, 1.002414286392268e+00, 1.001111413242302e+00, 9.996961651093181e-01, + 9.981625949525345e-01, 9.965041017623596e-01, 9.947148884277037e-01, 9.927891912841345e-01, + 9.907199995730845e-01, 9.884793707533194e-01, 9.855347660016696e-01, 9.823765865983286e-01, + 9.789747333404933e-01, 9.751623811486372e-01, 9.708821747608998e-01, 9.660805524695870e-01, + 9.606976399184645e-01, 9.546732976073706e-01, 9.479479345282376e-01, 9.404609052933396e-01, + 9.321553861564006e-01, 9.229775478442888e-01, 9.128745354570823e-01, 9.018003682081348e-01, + 8.897163275605041e-01, 8.765908974996186e-01, 8.623984077953557e-01, 8.471200801854385e-01, + 8.307479727020245e-01, 8.132817365236141e-01, 7.947291447585267e-01, 7.751108841891807e-01, + 7.544551974836834e-01, 7.327963552921717e-01, 7.101790843209148e-01, 6.866580716267418e-01, + 6.622962432368731e-01, 6.371684119604742e-01, 6.113488038789190e-01, 5.849206604934815e-01, + 5.579747428663487e-01, 5.306181649316717e-01, 5.029523957059122e-01, 4.750868825511614e-01, + 4.471309850999535e-01, 4.192049917945288e-01, 3.914252910998820e-01, 3.639114681156252e-01, + 3.367837772954476e-01, 3.101627843160973e-01, 2.841647033392418e-01, 2.589033711808454e-01, + 2.344880603710975e-01, 2.110209448747974e-01, 1.885997642296488e-01, 1.673100807904834e-01, + 1.472287968327706e-01, 1.284223074167396e-01, 1.109422548710344e-01, 9.482665349502306e-02, + 8.009914366829558e-02, 6.676765847398403e-02, 5.482436608328485e-02, 4.424588851571281e-02, + 3.499361000717621e-02, 2.701461405056267e-02, 2.024370180670145e-02, 1.460796755137538e-02, + 9.996743588367531e-03, 5.305235098871444e-03, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; + +const LC3_FLOAT MDCT_WINDOW_320[640] = { + -3.021153494057143e-04, -5.867737487939294e-04, -8.366504004139796e-04, -1.126635355725494e-03, + -1.470492941694331e-03, -1.873473391018495e-03, -2.339292362082021e-03, -2.872008069419264e-03, + -3.476256385086407e-03, -4.155963816705528e-03, -4.914563787665504e-03, -5.755172503953251e-03, + -6.680623380533122e-03, -7.693816924650567e-03, -8.796760749750191e-03, -9.990503073705982e-03, + -1.127574117138621e-02, -1.265334152129685e-02, -1.412438986522702e-02, -1.568889620430290e-02, + -1.734512089366117e-02, -1.909097368362797e-02, -2.092546711168754e-02, -2.284684792818856e-02, + -2.485207716234951e-02, -2.693746704328349e-02, -2.909952486193999e-02, -3.133504629493832e-02, + -3.363960728361352e-02, -3.600820974457969e-02, -3.843601741746971e-02, -4.091746034850161e-02, + -4.344654894948344e-02, -4.601786724624048e-02, -4.862598509282497e-02, -5.126474204655663e-02, + -5.392644753556616e-02, -5.660384311081047e-02, -5.929116747072080e-02, -6.198268202511926e-02, + -6.467025548071184e-02, -6.734542216184526e-02, -7.000099017198280e-02, -7.263057011354321e-02, + -7.522784961377151e-02, -7.778525942347714e-02, -8.029480247839878e-02, -8.274924535373614e-02, + -8.514125464087215e-02, -8.746379123238275e-02, -8.971069341834263e-02, -9.187564084638347e-02, + -9.395176975347193e-02, -9.593137735886889e-02, -9.780843257659243e-02, -9.957851303827886e-02, + -1.012361165314596e-01, -1.027741036495644e-01, -1.041861222641119e-01, -1.054680247057000e-01, + -1.066160875985523e-01, -1.076255384835563e-01, -1.084912299471198e-01, -1.092087422379003e-01, + -1.097736146613313e-01, -1.101808861640070e-01, -1.104271876052675e-01, -1.105108362290460e-01, + -1.104281465492726e-01, -1.101739218186236e-01, -1.097437360338336e-01, -1.091353125572511e-01, + -1.083467335729228e-01, -1.073739938306107e-01, -1.062130155324388e-01, -1.048606145834788e-01, + -1.033132401525343e-01, -1.015673163469357e-01, -9.962005506126154e-02, -9.746803229469267e-02, + -9.510723623306666e-02, -9.253303383231506e-02, -8.974125216128212e-02, -8.672877689119252e-02, + -8.349213839083708e-02, -8.002639902061687e-02, -7.632679536516856e-02, -7.238806162166744e-02, + -6.820576796149519e-02, -6.377611429172260e-02, -5.909386001558149e-02, -5.415316322402774e-02, + -4.894812724598650e-02, -4.347347112195197e-02, -3.772461300253332e-02, -3.169587609244436e-02, + -2.538179830690266e-02, -1.877689096555516e-02, -1.187461378850388e-02, -4.669099247423082e-03, + 2.844096748870385e-03, 1.066976124794342e-02, 1.881355950582949e-02, 2.728156010437695e-02, + 3.607810469851272e-02, 4.520702759803914e-02, 5.467238802204326e-02, 6.447866054615346e-02, + 7.462862199422061e-02, 8.512490568723846e-02, 9.596983987496970e-02, 1.071650779014335e-01, + 1.187115850305241e-01, 1.306101067250375e-01, 1.428596447589721e-01, 1.554584725339102e-01, + 1.684041609371527e-01, 1.816947894623263e-01, 1.953273880886783e-01, 2.092963206850239e-01, + 2.235945635254679e-01, 2.382160219461597e-01, 2.531529721334063e-01, 2.683961570569586e-01, + 2.839361392493072e-01, 2.997624255177811e-01, 3.158619077906196e-01, 3.322210551086769e-01, + 3.488264676990591e-01, 3.656640377499646e-01, 3.827152968157059e-01, 3.999611859760947e-01, + 4.173843265025887e-01, 4.349669624916473e-01, 4.526876397402144e-01, 4.705242008503956e-01, + 4.884539254831315e-01, 5.064545550235134e-01, 5.245006748662190e-01, 5.425674372882107e-01, + 5.606312044701524e-01, 5.786672646386708e-01, 5.966477035050948e-01, 6.145458904162185e-01, + 6.323361944662236e-01, 6.499926319211774e-01, 6.674874032292857e-01, 6.847932667399612e-01, + 7.018835463513400e-01, 7.187322544823347e-01, 7.353128213893310e-01, 7.516001985652684e-01, + 7.675699252273948e-01, 7.831974571624924e-01, 7.984583859818390e-01, 8.133295347030278e-01, + 8.277892271515950e-01, 8.418178561101360e-01, 8.553961300139363e-01, 8.685068980898102e-01, + 8.811334436653052e-01, 8.932596784799233e-01, 9.048748835980528e-01, 9.159657608120536e-01, + 9.265215299450000e-01, 9.365339988633418e-01, 9.459977028429117e-01, 9.549088408436811e-01, + 9.632658122557368e-01, 9.710688896122810e-01, 9.783204156360773e-01, 9.850226760127131e-01, + 9.911792082081333e-01, 9.967989944502682e-01, 1.001894024615659e+00, 1.006474342231823e+00, + 1.010552057109195e+00, 1.014142538208007e+00, 1.017262593268930e+00, 1.019928842669923e+00, + 1.022159867011177e+00, 1.023976320927187e+00, 1.025400734608122e+00, 1.026455340400072e+00, + 1.027164510654160e+00, 1.027552729180790e+00, 1.027644462380432e+00, 1.027463246660797e+00, + 1.027035903410657e+00, 1.026389068000259e+00, 1.025548201799728e+00, 1.024537134749709e+00, + 1.023380803775376e+00, 1.022103695693341e+00, 1.020728359657958e+00, 1.019275334687329e+00, + 1.017765178792830e+00, 1.016217355867531e+00, 1.014665311686846e+00, 1.013249071090664e+00, + 1.011948006992127e+00, 1.010189090179223e+00, 1.008557961167850e+00, 1.007011287608451e+00, + 1.005548764575910e+00, 1.004168417268956e+00, 1.002867268893035e+00, 1.001641769115897e+00, + 1.000489068954641e+00, 9.994060799749374e-01, 9.983898865406841e-01, 9.974370849972721e-01, + 9.965444836911705e-01, 9.957098545943852e-01, 9.949302413030897e-01, 9.942024045863540e-01, + 9.935241604969254e-01, 9.928930430130044e-01, 9.923068103443909e-01, 9.917633778190438e-01, + 9.912597642374404e-01, 9.907954498484041e-01, 9.903677893656558e-01, 9.899751611066148e-01, + 9.896160337369861e-01, 9.892890160408989e-01, 9.889928511129679e-01, 9.887260333430423e-01, + 9.884868721088945e-01, 9.882751039537586e-01, 9.880892168751595e-01, 9.879277114724612e-01, + 9.877898261218510e-01, 9.876743442038471e-01, 9.875807496078497e-01, 9.875072021876561e-01, + 9.874529447589979e-01, 9.874169741527905e-01, 9.873984685207834e-01, 9.873958301311858e-01, + 9.874080027710336e-01, 9.874343401290739e-01, 9.874736235387018e-01, 9.875243137719285e-01, + 9.875856201221135e-01, 9.876563785063032e-01, 9.877358921155149e-01, 9.878225576787804e-01, + 9.879150968481590e-01, 9.880132731565830e-01, 9.881156946084619e-01, 9.882211314188272e-01, + 9.883289032519310e-01, 9.884378310018685e-01, 9.885476787868710e-01, 9.886568414746639e-01, + 9.887645868459630e-01, 9.888708540445242e-01, 9.889744320992592e-01, 9.890747269455915e-01, + 9.891710038703801e-01, 9.892631024032380e-01, 9.893507219573624e-01, 9.894330645494204e-01, + 9.895096919388534e-01, 9.895810813422480e-01, 9.896467469067676e-01, 9.897067365020641e-01, + 9.897606930400666e-01, 9.898094478563998e-01, 9.898530133261707e-01, 9.898914705684924e-01, + 9.899254194103574e-01, 9.899554202030650e-01, 9.899824494486951e-01, 9.900065116928948e-01, + 9.900284805353695e-01, 9.900497484789281e-01, 9.900709561632662e-01, 9.900928358611601e-01, + 9.901163920607219e-01, 9.901427479709606e-01, 9.901734275350572e-01, 9.902087332329851e-01, + 9.902498637985275e-01, 9.902983686695558e-01, 9.903548501470234e-01, 9.904205084933333e-01, + 9.904959297726740e-01, 9.905825150202904e-01, 9.906812569810133e-01, 9.907922087340426e-01, + 9.909165464981378e-01, 9.910550740962871e-01, 9.912084614290896e-01, 9.913768610980639e-01, + 9.915605826937839e-01, 9.917604214872976e-01, 9.919767175562684e-01, 9.922091101818779e-01, + 9.924579135466506e-01, 9.927231225056266e-01, 9.930049538427406e-01, 9.933027281437943e-01, + 9.936161084869942e-01, 9.939453714404443e-01, 9.942895145656371e-01, 9.946481676207727e-01, + 9.950203031067961e-01, 9.954058173659507e-01, 9.958038713694317e-01, 9.962130271017117e-01, + 9.966324689957675e-01, 9.970615306490058e-01, 9.974990583293081e-01, 9.979437430375855e-01, + 9.983940572002874e-01, 9.988493116887893e-01, 9.993083430214909e-01, 9.997689221333534e-01, + 1.000231131275969e+00, 1.000692135698996e+00, 1.001152013920163e+00, 1.001608526000461e+00, + 1.002060493867275e+00, 1.002507212061815e+00, 1.002947129400411e+00, 1.003378909587027e+00, + 1.003801368578070e+00, 1.004213810320699e+00, 1.004615386562846e+00, 1.005004618375781e+00, + 1.005380628601598e+00, 1.005743282364652e+00, 1.006091510392348e+00, 1.006424907424988e+00, + 1.006742427727669e+00, 1.007044321511378e+00, 1.007330218597112e+00, 1.007599401798709e+00, + 1.007852064386603e+00, 1.008088176165563e+00, 1.008308033204578e+00, 1.008511247273756e+00, + 1.008698144207627e+00, 1.008869515256392e+00, 1.009025659761512e+00, 1.009166718967367e+00, + 1.009293362609020e+00, 1.009406398832440e+00, 1.009507017171120e+00, 1.009595264293017e+00, + 1.009672145744679e+00, 1.009739084785160e+00, 1.009796675060142e+00, 1.009846137382005e+00, + 1.009888083631667e+00, 1.009924092276850e+00, 1.009955384765721e+00, 1.009982268770147e+00, + 1.010006298177305e+00, 1.010028618428735e+00, 1.010050254076988e+00, 1.010071952131355e+00, + 1.010094366238073e+00, 1.010118917317053e+00, 1.010146497096682e+00, 1.010177110711677e+00, + 1.010211755260102e+00, 1.010251003469427e+00, 1.010295468653759e+00, 1.010345234996637e+00, + 1.010400316698172e+00, 1.010461564316351e+00, 1.010528615445659e+00, 1.010601521285347e+00, + 1.010679788081867e+00, 1.010763905869062e+00, 1.010853429760676e+00, 1.010947547074519e+00, + 1.011045953108263e+00, 1.011148486293359e+00, 1.011254397791134e+00, 1.011363082075863e+00, + 1.011473302008831e+00, 1.011584996312149e+00, 1.011697416504599e+00, 1.011808919793469e+00, + 1.011919264025716e+00, 1.012027240794153e+00, 1.012132151631041e+00, 1.012232734564333e+00, + 1.012327560477901e+00, 1.012416383754384e+00, 1.012497890726292e+00, 1.012570434021054e+00, + 1.012633295255708e+00, 1.012685277016726e+00, 1.012725564992284e+00, 1.012752577651415e+00, + 1.012765062889864e+00, 1.012762356719162e+00, 1.012743376077777e+00, 1.012706484200181e+00, + 1.012650842226435e+00, 1.012575427778520e+00, 1.012479473490919e+00, 1.012361105121003e+00, + 1.012219809594718e+00, 1.012054359992419e+00, 1.011864000215460e+00, 1.011647223869087e+00, + 1.011402518267713e+00, 1.011129654652857e+00, 1.010826951260377e+00, 1.010492924436361e+00, + 1.010126353960416e+00, 1.009725892479312e+00, 1.009290060983833e+00, 1.008817301052548e+00, + 1.008305027555130e+00, 1.007752833675443e+00, 1.007157827358150e+00, 1.006518049344503e+00, + 1.005831403532018e+00, 1.005095592119373e+00, 1.004308630055050e+00, 1.003467498305776e+00, + 1.002569500413888e+00, 1.001612710105563e+00, 1.000594272975683e+00, 9.995111701168786e-01, + 9.983609218719522e-01, 9.971409288327860e-01, 9.958488863050556e-01, 9.944818543153893e-01, + 9.930375282832211e-01, 9.915146560759479e-01, 9.899136802423638e-01, 9.881930623810997e-01, + 9.859422591203311e-01, 9.835667898378924e-01, 9.811423034808365e-01, 9.785214441250228e-01, + 9.756636036109838e-01, 9.725453442532574e-01, 9.691456634185092e-01, 9.654406178310209e-01, + 9.614043615076308e-01, 9.570113065179300e-01, 9.522367669696690e-01, 9.470548839544214e-01, + 9.414403740008491e-01, 9.353691612846549e-01, 9.288190093977164e-01, 9.217662887169115e-01, + 9.141896283466009e-01, 9.060694681113471e-01, 8.973891675497357e-01, 8.881332000806269e-01, + 8.782893885841422e-01, 8.678469565343039e-01, 8.567970644671067e-01, 8.451334654019180e-01, + 8.328542805780399e-01, 8.199594783897041e-01, 8.064511006873497e-01, 7.923346478686025e-01, + 7.776204488292163e-01, 7.623206183595970e-01, 7.464486491227057e-01, 7.300205729992958e-01, + 7.130567383226717e-01, 6.955805444755916e-01, 6.776173229836567e-01, 6.591955305148172e-01, + 6.403486426892321e-01, 6.211072197441818e-01, 6.015049275244730e-01, 5.815787608870452e-01, + 5.613674511156324e-01, 5.409188627354076e-01, 5.202736834971303e-01, 4.994780733459294e-01, + 4.785774177949064e-01, 4.576172599874928e-01, 4.366490208265804e-01, 4.157221460415995e-01, + 3.948856590950757e-01, 3.741903189229770e-01, 3.536868899553974e-01, 3.334260017756462e-01, + 3.134586473252229e-01, 2.938337904395871e-01, 2.745992637590817e-01, 2.558030636168172e-01, + 2.374902188466697e-01, 2.197036032185785e-01, 2.024855415115456e-01, 1.858749915117319e-01, + 1.699067802117410e-01, 1.546132267478873e-01, 1.400238206749695e-01, 1.261637395672913e-01, + 1.130534434072719e-01, 1.007084973747940e-01, 8.914024389873081e-02, 7.835612100141792e-02, + 6.835821233920988e-02, 5.914211536028976e-02, 5.069893012340832e-02, 4.301717763585550e-02, + 3.608020726673359e-02, 2.986316337017630e-02, 2.433722657129812e-02, 1.947675241971700e-02, + 1.525710171255895e-02, 1.163787492636240e-02, 8.433087782643718e-03, 4.449668997344735e-03, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; + +const LC3_FLOAT MDCT_WINDOW_480[960] = { + -2.353032150516754e-04, -4.619898752628163e-04, -6.262931535610879e-04, -7.929180432976445e-04, + -9.747166718929050e-04, -1.180256894474562e-03, -1.409209039594871e-03, -1.664473096973725e-03, + -1.946591608170231e-03, -2.257081732588478e-03, -2.597106916737789e-03, -2.967607624839524e-03, + -3.370454877988472e-03, -3.806285163352241e-03, -4.276873767639064e-03, -4.782469904501813e-03, + -5.324608721716763e-03, -5.903403814095400e-03, -6.520419726599805e-03, -7.175885277771099e-03, + -7.871422820642307e-03, -8.606586039759667e-03, -9.382480860899108e-03, -1.019827182163307e-02, + -1.105520547739066e-02, -1.195270300743193e-02, -1.289205910303846e-02, -1.387263484323160e-02, + -1.489528159506296e-02, -1.595856621933800e-02, -1.706288556735433e-02, -1.820666399965468e-02, + -1.939065975232718e-02, -2.061355417582714e-02, -2.187570925786862e-02, -2.317526315266411e-02, + -2.451227449041489e-02, -2.588471937157619e-02, -2.729263737090799e-02, -2.873390902713615e-02, + -3.020862738245264e-02, -3.171440372994384e-02, -3.325098858986303e-02, -3.481597793538342e-02, + -3.640892406933019e-02, -3.802742318209150e-02, -3.967067992672979e-02, -4.133575417353826e-02, + -4.302203371734278e-02, -4.472698045914417e-02, -4.645022292934329e-02, -4.818891490266687e-02, + -4.994225863256500e-02, -5.170690802826666e-02, -5.348162036097223e-02, -5.526334794593565e-02, + -5.705123152423822e-02, -5.884271749745559e-02, -6.063717235243996e-02, -6.243104027829089e-02, + -6.422303545004304e-02, -6.600961519440657e-02, -6.778962269634495e-02, -6.955996868581379e-02, + -7.131966266443390e-02, -7.306581273272733e-02, -7.479758913001458e-02, -7.651178225890490e-02, + -7.820711420768856e-02, -7.988010693411644e-02, -8.152964005319532e-02, -8.315237353264004e-02, + -8.474728946770714e-02, -8.631137544905677e-02, -8.784374452959058e-02, -8.934164364321417e-02, + -9.080411291245728e-02, -9.222795761428432e-02, -9.361232867223340e-02, -9.495377758870335e-02, + -9.625155313139856e-02, -9.750284620437569e-02, -9.870736514214426e-02, -9.986271288271026e-02, + -1.009680221406219e-01, -1.020202684361974e-01, -1.030183804850491e-01, -1.039596356759290e-01, + -1.048438825017798e-01, -1.056686838192766e-01, -1.064342821660323e-01, -1.071382314127799e-01, + -1.077799961121537e-01, -1.083570625865931e-01, -1.088690135027248e-01, -1.093135588677235e-01, + -1.096903559498340e-01, -1.099969655786929e-01, -1.102332261219973e-01, -1.103972812085189e-01, + -1.104898474883336e-01, -1.105086416532167e-01, -1.104537426996073e-01, -1.103225838568563e-01, + -1.101145827722143e-01, -1.098276928170364e-01, -1.094621746650760e-01, -1.090163960055733e-01, + -1.084908852561722e-01, -1.078834293141886e-01, -1.071937180231978e-01, -1.064196358069465e-01, + -1.055612509762041e-01, -1.046162812518618e-01, -1.035849043557610e-01, -1.024650162703341e-01, + -1.012568997532046e-01, -9.995864571932928e-02, -9.857014566194627e-02, -9.708911135857967e-02, + -9.551545820689084e-02, -9.384684920715425e-02, -9.208300062891550e-02, -9.022171021406450e-02, + -8.826309993000785e-02, -8.620493821803937e-02, -8.404742152815330e-02, -8.178792716809512e-02, + -7.942625026703617e-02, -7.695980775819990e-02, -7.438785600211463e-02, -7.170797002873608e-02, + -6.891994783815969e-02, -6.602189797715241e-02, -6.301349420724424e-02, -5.989191912667712e-02, + -5.665655641133161e-02, -5.330406164482222e-02, -4.983427241976235e-02, -4.624456893420224e-02, + -4.253455686336916e-02, -3.870195772538443e-02, -3.474585776145929e-02, -3.066341518682682e-02, + -2.645425077642105e-02, -2.211581608120528e-02, -1.764740541599136e-02, -1.304581363895818e-02, + -8.310425696208936e-03, -3.438268661133170e-03, 1.570315476576933e-03, 6.717697635290676e-03, + 1.200477020244778e-02, 1.743398319747869e-02, 2.300642061077823e-02, 2.872481423270595e-02, + 3.458896350634671e-02, 4.060106462625085e-02, 4.676102915752826e-02, 5.307133911821893e-02, + 5.953239090915557e-02, 6.614647812869151e-02, 7.291293184312803e-02, 7.983354189816511e-02, + 8.690807412770696e-02, 9.413813765275064e-02, 1.015233140203748e-01, 1.090651518336202e-01, + 1.167626546016197e-01, 1.246171387327525e-01, 1.326272948938113e-01, 1.407938190608664e-01, + 1.491152519299797e-01, 1.575921408388593e-01, 1.662224799248571e-01, 1.750067399059861e-01, + 1.839431938620024e-01, 1.930318183054904e-01, 2.022699854906251e-01, 2.116567430906184e-01, + 2.211888523410642e-01, 2.308655379767671e-01, 2.406837992341654e-01, 2.506420640291662e-01, + 2.607365124918583e-01, 2.709659073501196e-01, 2.813259021832532e-01, 2.918144694729168e-01, + 3.024270279840051e-01, 3.131603499997996e-01, 3.240095704645023e-01, 3.349719592361666e-01, + 3.460422935204829e-01, 3.572175180786021e-01, 3.684915649120530e-01, 3.798595119591716e-01, + 3.913146885756875e-01, 4.028532873867052e-01, 4.144688328137527e-01, 4.261571642320424e-01, + 4.379113897565727e-01, 4.497256320417501e-01, 4.615925445090212e-01, 4.735067030065239e-01, + 4.854600184866710e-01, 4.974471592901086e-01, 5.094597228333853e-01, 5.214909841729947e-01, + 5.335326819631583e-01, 5.455789811615239e-01, 5.576217157959890e-01, 5.696546730080154e-01, + 5.816685576268035e-01, 5.936560624526468e-01, 6.056083823929643e-01, 6.175192060085208e-01, + 6.293796611336280e-01, 6.411830842823245e-01, 6.529203544876097e-01, 6.645840786371451e-01, + 6.761653499550255e-01, 6.876573952173626e-01, 6.990511539119996e-01, 7.103400549562944e-01, + 7.215149331458728e-01, 7.325691772738999e-01, 7.434943718765665e-01, 7.542846327442048e-01, + 7.649313654540612e-01, 7.754281892901473e-01, 7.857670170752049e-01, 7.959414651061612e-01, + 8.059437233154637e-01, 8.157687070715176e-01, 8.254086223972127e-01, 8.348589373399948e-01, + 8.441125827416620e-01, 8.531651194538425e-01, 8.620108336276733e-01, 8.706456337542150e-01, + 8.790631561061171e-01, 8.872599706865123e-01, 8.952313288619367e-01, 9.029751680353524e-01, + 9.104863121445679e-01, 9.177625550620636e-01, 9.247997426966093e-01, 9.315962496426278e-01, + 9.381494858921667e-01, 9.444588390359354e-01, 9.505220861927248e-01, 9.563402921286364e-01, + 9.619114522936701e-01, 9.672366712325431e-01, 9.723156637834687e-01, 9.771501187120180e-01, + 9.817397501303696e-01, 9.860865871353246e-01, 9.901906380163595e-01, 9.940557180662704e-01, + 9.976842395284637e-01, 1.001080961257010e+00, 1.004247514102417e+00, 1.007188578458507e+00, + 1.009906654565108e+00, 1.012407428282884e+00, 1.014694702432600e+00, 1.016774659209400e+00, + 1.018650990561848e+00, 1.020330464463111e+00, 1.021817328911793e+00, 1.023118841384460e+00, + 1.024240262467000e+00, 1.025189721888128e+00, 1.025972450969440e+00, 1.026596938589443e+00, + 1.027069179375841e+00, 1.027397523939210e+00, 1.027587902203109e+00, 1.027648951922701e+00, + 1.027585830688143e+00, 1.027408519661012e+00, 1.027122986826984e+00, 1.026738673647482e+00, + 1.026261663878092e+00, 1.025701002415063e+00, 1.025061777648234e+00, 1.024353980976701e+00, + 1.023582385618774e+00, 1.022756514615106e+00, 1.021880604350422e+00, 1.020963871317665e+00, + 1.020009139549275e+00, 1.019027285501251e+00, 1.018019442784231e+00, 1.016996499560845e+00, + 1.015957433206324e+00, 1.014923441259795e+00, 1.013915946100629e+00, 1.013047565149327e+00, + 1.012216130365610e+00, 1.011044869639164e+00, 1.009914592130044e+00, 1.008824888092573e+00, + 1.007773858455400e+00, 1.006761700412993e+00, 1.005786648810854e+00, 1.004848753962734e+00, + 1.003946083413733e+00, 1.003078846506546e+00, 1.002245009135684e+00, 1.001444733905817e+00, + 1.000676188436651e+00, 9.999393169239009e-01, 9.992320848298057e-01, 9.985548127155425e-01, + 9.979055415627330e-01, 9.972842679758880e-01, 9.966890948441745e-01, 9.961203379971326e-01, + 9.955761256313581e-01, 9.950565724564597e-01, 9.945597525471822e-01, 9.940860378486615e-01, + 9.936337788972491e-01, 9.932031606606759e-01, 9.927921871265732e-01, 9.924015177880798e-01, + 9.920297273323891e-01, 9.916767775088281e-01, 9.913408767719142e-01, 9.910230654424902e-01, + 9.907216425865902e-01, 9.904366799536263e-01, 9.901668953434221e-01, 9.899131011580791e-01, + 9.896735637374597e-01, 9.894488374513719e-01, 9.892374835404283e-01, 9.890401927796704e-01, + 9.888556356037892e-01, 9.886843467692753e-01, 9.885247606051014e-01, 9.883778520531268e-01, + 9.882423270582524e-01, 9.881185638915363e-01, 9.880051626345804e-01, 9.879032023766432e-01, + 9.878111744348976e-01, 9.877295459610343e-01, 9.876571983429736e-01, 9.875949843246187e-01, + 9.875412739766566e-01, 9.874969061399389e-01, 9.874606249127551e-01, 9.874329809802893e-01, + 9.874126414437681e-01, 9.874004750404033e-01, 9.873949921033299e-01, 9.873969162747074e-01, + 9.874049060317581e-01, 9.874197049003676e-01, 9.874399717110517e-01, 9.874663281231737e-01, + 9.874973205882319e-01, 9.875338926695315e-01, 9.875746535410983e-01, 9.876201238703241e-01, + 9.876689801932402e-01, 9.877221556193183e-01, 9.877781920433015e-01, 9.878376489591358e-01, + 9.878991990245439e-01, 9.879637979933339e-01, 9.880300303653743e-01, 9.880984675859855e-01, + 9.881678007807095e-01, 9.882390300097154e-01, 9.883107693992456e-01, 9.883835200189653e-01, + 9.884560159878955e-01, 9.885294200392185e-01, 9.886022219397892e-01, 9.886749404176028e-01, + 9.887466261142505e-01, 9.888182771263505e-01, 9.888882480852147e-01, 9.889574384705896e-01, + 9.890247977602895e-01, 9.890911247701029e-01, 9.891551701556196e-01, 9.892178658748239e-01, + 9.892779555818088e-01, 9.893365186903538e-01, 9.893923680007577e-01, 9.894462830852175e-01, + 9.894972124952000e-01, 9.895463342815009e-01, 9.895923617530382e-01, 9.896362652966239e-01, + 9.896772011542693e-01, 9.897162195263046e-01, 9.897520286480039e-01, 9.897859195209235e-01, + 9.898170267411330e-01, 9.898462068764986e-01, 9.898725363809847e-01, 9.898975138787787e-01, + 9.899200050208486e-01, 9.899410789223559e-01, 9.899600605054418e-01, 9.899782261038060e-01, + 9.899945557067980e-01, 9.900103500807507e-01, 9.900248320990181e-01, 9.900394023736973e-01, + 9.900532105829365e-01, 9.900674746047259e-01, 9.900814722948890e-01, 9.900966926051257e-01, + 9.901122448734595e-01, 9.901293790312005e-01, 9.901474648912307e-01, 9.901680598867444e-01, + 9.901902265696609e-01, 9.902151896501201e-01, 9.902424418296485e-01, 9.902734448815004e-01, + 9.903071270768942e-01, 9.903448913950654e-01, 9.903862280081246e-01, 9.904324484666853e-01, + 9.904825650601110e-01, 9.905379830873822e-01, 9.905980602136440e-01, 9.906640366554630e-01, + 9.907348826312993e-01, 9.908120376822228e-01, 9.908947858311721e-01, 9.909842592301273e-01, + 9.910795247770178e-01, 9.911819240108124e-01, 9.912905118607647e-01, 9.914064705361564e-01, + 9.915288011543961e-01, 9.916586940166509e-01, 9.917952720685562e-01, 9.919396217291009e-01, + 9.920906151219310e-01, 9.922495028313456e-01, 9.924152398352751e-01, 9.925887208794144e-01, + 9.927688708468421e-01, 9.929569112537944e-01, 9.931516528513824e-01, 9.933539244159140e-01, + 9.935626893131695e-01, 9.937790866568735e-01, 9.940016434044485e-01, 9.942312024833810e-01, + 9.944668184371617e-01, 9.947093441694513e-01, 9.949572854565533e-01, 9.952116634297566e-01, + 9.954712635321227e-01, 9.957367951478069e-01, 9.960068616185641e-01, 9.962823025614079e-01, + 9.965617986382630e-01, 9.968461329825753e-01, 9.971338271912752e-01, 9.974256691222113e-01, + 9.977203369515556e-01, 9.980185087055744e-01, 9.983185871761977e-01, 9.986213520769593e-01, + 9.989255426466267e-01, 9.992317314100975e-01, 9.995382582242990e-01, 9.998461160718275e-01, + 1.000153907612080e+00, 1.000461955079660e+00, 1.000768859280338e+00, 1.001075613053728e+00, + 1.001380551217109e+00, 1.001684244734497e+00, 1.001985425397567e+00, 1.002284871786226e+00, + 1.002580975161843e+00, 1.002874411368430e+00, 1.003163845364970e+00, 1.003450063374329e+00, + 1.003731570287893e+00, 1.004009147462043e+00, 1.004281457582935e+00, 1.004549339226336e+00, + 1.004811375053364e+00, 1.005068272394360e+00, 1.005318795748286e+00, 1.005563968008037e+00, + 1.005802269635282e+00, 1.006034554002353e+00, 1.006259855360867e+00, 1.006479018139540e+00, + 1.006690541428116e+00, 1.006895570408563e+00, 1.007093045696527e+00, 1.007283799246233e+00, + 1.007466616298057e+00, 1.007642728426847e+00, 1.007811036585595e+00, 1.007972441990187e+00, + 1.008125875904472e+00, 1.008272602383284e+00, 1.008411468616852e+00, 1.008543573152632e+00, + 1.008668018334797e+00, 1.008786009787269e+00, 1.008896526233555e+00, 1.009000766336071e+00, + 1.009097763850333e+00, 1.009188880897370e+00, 1.009273163797313e+00, 1.009351762546296e+00, + 1.009423944949143e+00, 1.009491175244507e+00, 1.009552401900961e+00, 1.009608886895764e+00, + 1.009659973830751e+00, 1.009707093778162e+00, 1.009749238562067e+00, 1.009787744284661e+00, + 1.009822090220407e+00, 1.009853706282597e+00, 1.009881498943010e+00, 1.009906958448099e+00, + 1.009929567021562e+00, 1.009950573483366e+00, 1.009969021400474e+00, 1.009986499185054e+00, + 1.010002363879044e+00, 1.010017890428877e+00, 1.010032170180360e+00, 1.010046722045583e+00, + 1.010060809299530e+00, 1.010075674445289e+00, 1.010090449982098e+00, 1.010106564965965e+00, + 1.010123226584120e+00, 1.010141762173145e+00, 1.010161131093372e+00, 1.010182635897876e+00, + 1.010205587931660e+00, 1.010231078494249e+00, 1.010257950227988e+00, 1.010287732968580e+00, + 1.010319484524512e+00, 1.010354079663767e+00, 1.010390635488037e+00, 1.010430470494512e+00, + 1.010472266495074e+00, 1.010517096381509e+00, 1.010564099281000e+00, 1.010614266894512e+00, + 1.010666285876455e+00, 1.010721360243234e+00, 1.010778416755264e+00, 1.010838252644461e+00, + 1.010899655674578e+00, 1.010963729626641e+00, 1.011029191301694e+00, 1.011096993993037e+00, + 1.011165861239173e+00, 1.011236610341260e+00, 1.011308167670753e+00, 1.011381453638912e+00, + 1.011454785713102e+00, 1.011529185153809e+00, 1.011603680910505e+00, 1.011678803938046e+00, + 1.011753008569803e+00, 1.011827484797985e+00, 1.011900936547881e+00, 1.011973876511603e+00, + 1.012044885003304e+00, 1.012114985644919e+00, 1.012182837094955e+00, 1.012249023976742e+00, + 1.012312095063070e+00, 1.012373028737774e+00, 1.012430463679316e+00, 1.012484972246822e+00, + 1.012535058602453e+00, 1.012581678169188e+00, 1.012623472898504e+00, 1.012660975529858e+00, + 1.012692758750213e+00, 1.012719789201144e+00, 1.012740575296603e+00, 1.012755753887085e+00, + 1.012763948841204e+00, 1.012765922449960e+00, 1.012760298661069e+00, 1.012747819936584e+00, + 1.012726958954961e+00, 1.012698607692183e+00, 1.012661400539405e+00, 1.012615904116265e+00, + 1.012560833005713e+00, 1.012497050269805e+00, 1.012422888521601e+00, 1.012339226241367e+00, + 1.012244921966297e+00, 1.012140460211194e+00, 1.012024302085441e+00, 1.011897560567707e+00, + 1.011758810583150e+00, 1.011608449127642e+00, 1.011445162723270e+00, 1.011269960947744e+00, + 1.011081255645969e+00, 1.010879608424312e+00, 1.010663676735228e+00, 1.010434184200640e+00, + 1.010189681124657e+00, 1.009930754807923e+00, 1.009655660215271e+00, 1.009365251564694e+00, + 1.009058249873833e+00, 1.008734758578989e+00, 1.008393079963091e+00, 1.008034308295421e+00, + 1.007656661215973e+00, 1.007260142622887e+00, 1.006843352506855e+00, 1.006407009542103e+00, + 1.005949145170711e+00, 1.005470005637052e+00, 1.004967986424467e+00, 1.004443531995945e+00, + 1.003894772403371e+00, 1.003321903663793e+00, 1.002723127308148e+00, 1.002098854400575e+00, + 1.001447278873483e+00, 1.000768505317086e+00, 1.000060686758758e+00, 9.993242684851855e-01, + 9.985573503390627e-01, 9.977600196406868e-01, 9.969306036935497e-01, 9.960694269553644e-01, + 9.951746430061121e-01, 9.942466438407230e-01, 9.932837131068657e-01, 9.922861082472264e-01, + 9.912523092989319e-01, 9.901827419790691e-01, 9.890757868707590e-01, 9.879313024174022e-01, + 9.863553220272523e-01, 9.847362453480265e-01, 9.831750948772566e-01, 9.815583336011345e-01, + 9.798613526271561e-01, 9.780617486993630e-01, 9.761574317374303e-01, 9.741378617337759e-01, + 9.719990112065752e-01, 9.697327413658168e-01, 9.673331975559332e-01, 9.647915124057732e-01, + 9.621011497566145e-01, 9.592539757044516e-01, 9.562427177295731e-01, 9.530600909726344e-01, + 9.496984081652284e-01, 9.461498120176854e-01, 9.424071613625743e-01, 9.384634163826711e-01, + 9.343112966094085e-01, 9.299449872197452e-01, 9.253567968750328e-01, 9.205404627076625e-01, + 9.154896280575360e-01, 9.101986790930605e-01, 9.046620597741508e-01, 8.988755194372424e-01, + 8.928338316495705e-01, 8.865337190368053e-01, 8.799712722567934e-01, 8.731437835983047e-01, + 8.660476534563131e-01, 8.586812520174252e-01, 8.510420440685049e-01, 8.431297226886574e-01, + 8.349435141989714e-01, 8.264839911291133e-01, 8.177505366573690e-01, 8.087449817124315e-01, + 7.994681492797084e-01, 7.899235162194718e-01, 7.801137731566502e-01, 7.700431275216928e-01, + 7.597145736971065e-01, 7.491330971820804e-01, 7.383028603058783e-01, 7.272298755824693e-01, + 7.159201919962611e-01, 7.043814340356083e-01, 6.926196927377140e-01, 6.806438831866077e-01, + 6.684616478236647e-01, 6.560830137986515e-01, 6.435179268559957e-01, 6.307755329382612e-01, + 6.178641647786525e-01, 6.047954625702541e-01, 5.915799587176216e-01, 5.782289366005894e-01, + 5.647535885752191e-01, 5.511703155400274e-01, 5.374905090437071e-01, 5.237263500445715e-01, + 5.098915423728255e-01, 4.960008074926423e-01, 4.820662943337458e-01, 4.681017110048007e-01, + 4.541216995958746e-01, 4.401421815729068e-01, 4.261772971493010e-01, 4.122417888542512e-01, + 3.983499612526493e-01, 3.845172335531009e-01, 3.707583717376236e-01, 3.570886786795506e-01, + 3.435228672445627e-01, 3.300763764703638e-01, 3.167640325043893e-01, 3.036004651973109e-01, + 2.905996158436682e-01, 2.777758503744847e-01, 2.651434678028531e-01, 2.527161881181577e-01, + 2.405069849650012e-01, 2.285283969438072e-01, 2.167933432162879e-01, 2.053139897833021e-01, + 1.941021906320988e-01, 1.831680872008943e-01, 1.725221947208913e-01, 1.621735416384834e-01, + 1.521320683467849e-01, 1.424052801149985e-01, 1.330015240938615e-01, 1.239260664828526e-01, + 1.151858295527293e-01, 1.067840430193724e-01, 9.872637505002878e-02, 9.101379000888035e-02, + 8.365057236623055e-02, 7.663508305536153e-02, 6.997033405748826e-02, 6.365188111381365e-02, + 5.768176015814392e-02, 5.205244216987966e-02, 4.676538412257621e-02, 4.180950541438362e-02, + 3.718640251368464e-02, 3.288072750732215e-02, 2.889548499582958e-02, 2.520980565928884e-02, + 2.183057564646272e-02, 1.872896194002638e-02, 1.592127815153420e-02, 1.336381425803020e-02, + 1.108558877807282e-02, 8.943474189364638e-03, 6.758124889697787e-03, 3.504438130619497e-03, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; + +const LC3_FLOAT MDCT_WINDOW_80_5ms[80] = { + 9.959086585790517e-04, 3.819056787237678e-03, 9.540832613229890e-03, 1.921659800166160e-02, 3.382719081038548e-02, + 5.424831667522354e-02, 8.120777668775610e-02, 1.152171887125930e-01, 1.564942331034909e-01, 2.049363422022628e-01, + 2.601166575816199e-01, 3.212814164616093e-01, 3.873472997948746e-01, 4.569497078592333e-01, 5.285192958868393e-01, + 6.003522489375573e-01, 6.706896380227332e-01, 7.378044458510402e-01, 8.000925313431716e-01, 8.561409184410547e-01, + 9.048272294524792e-01, 9.453685031730190e-01, 9.773507430600533e-01, 1.000800872826561e+00, 1.016171590112097e+00, + 1.024315247630982e+00, 1.026415431432931e+00, 1.023858366571912e+00, 1.018135705524407e+00, 1.010794822557756e+00, + 1.003406509762925e+00, 9.967831265986109e-01, 9.920995520917141e-01, 9.892206942816891e-01, 9.879658322200813e-01, + 9.881273531631907e-01, 9.894805541465801e-01, 9.917849916000535e-01, 9.947847580943504e-01, 9.982119669301160e-01, + 1.001791235858836e+00, 1.005242583245485e+00, 1.008283053756130e+00, 1.010631281038659e+00, 1.012015300253356e+00, + 1.012180753005270e+00, 1.010896765282633e+00, 1.007963362035220e+00, 1.003227255072391e+00, 9.966050551498514e-01, + 9.868284225039941e-01, 9.731250287581631e-01, 9.540636479502398e-01, 9.283864275822276e-01, 8.950916858157935e-01, + 8.534769362643825e-01, 8.032090930429980e-01, 7.444735201251689e-01, 6.780787033699449e-01, 6.053970453856138e-01, + 5.282077505750667e-01, 4.486552956056635e-01, 3.691875990296312e-01, 2.924566408966777e-01, 2.210718537110463e-01, + 1.573148583944309e-01, 1.030525757797768e-01, 5.982732244758054e-02, 2.871831923385133e-02, 9.683884928956490e-03, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; + +const LC3_FLOAT MDCT_WINDOW_160_5ms[160] = { + 6.143388180964179e-04, 1.489582832987000e-03, 2.884104959764029e-03, 4.934298832466617e-03, 7.779130464154915e-03, + 1.154910606525086e-02, 1.637155619860352e-02, 2.237116158648752e-02, 2.966159685753317e-02, 3.835663329277230e-02, + 4.855610986150206e-02, 6.035055738891727e-02, 7.382288203064732e-02, 8.903563687211119e-02, 1.060356225286319e-01, + 1.248534855777947e-01, 1.454931890869180e-01, 1.679435556337752e-01, 1.921728622634411e-01, 2.181238261985594e-01, + 2.457259744642953e-01, 2.748839432649996e-01, 3.054824712370942e-01, 3.373873799614014e-01, 3.704415932452488e-01, + 4.044749630814483e-01, 4.393004362003260e-01, 4.747225454237193e-01, 5.105341492548225e-01, 5.465201916422433e-01, + 5.824658100332457e-01, 6.181452662624718e-01, 6.533411462740817e-01, 6.878367295965062e-01, 7.214176027060971e-01, + 7.538887973483771e-01, 7.850546571907628e-01, 8.147397447696774e-01, 8.427819363777799e-01, 8.690376742017057e-01, + 8.933935477349644e-01, 9.157483563218768e-01, 9.360270196617569e-01, 9.541731142261065e-01, 9.701635474343885e-01, + 9.840036439809510e-01, 9.957199420334376e-01, 1.005374268639838e+00, 1.013046655758663e+00, 1.018843380560658e+00, + 1.022896948293643e+00, 1.025355286710874e+00, 1.026382881625701e+00, 1.026155530733488e+00, 1.024853974580724e+00, + 1.022664602721801e+00, 1.019779396547454e+00, 1.016391686789653e+00, 1.012697033320358e+00, 1.008885191761748e+00, + 1.005378742804807e+00, 1.001563778373068e+00, 9.982531564931281e-01, 9.954346644968789e-01, 9.930950268060122e-01, + 9.912170911359961e-01, 9.897805192546195e-01, 9.887624937408933e-01, 9.881383235740961e-01, 9.878819413827574e-01, + 9.879662130250981e-01, 9.883630508181326e-01, 9.890434070785485e-01, 9.899772316163624e-01, 9.911334564321237e-01, + 9.924800441092685e-01, 9.939841207305906e-01, 9.956121471675398e-01, 9.973300590248015e-01, 9.991033633647473e-01, + 1.000897441314013e+00, 1.002677088643863e+00, 1.004407190937699e+00, 1.006052289109999e+00, 1.007576934100958e+00, + 1.008945862447015e+00, 1.010124241309341e+00, 1.011077969726137e+00, 1.011773962181442e+00, 1.012180362866919e+00, + 1.012266707295288e+00, 1.012004064757857e+00, 1.011365223023975e+00, 1.010324996851905e+00, 1.008860731864438e+00, + 1.006952983357691e+00, 1.004586273379809e+00, 1.001749900308864e+00, 9.984386632116344e-01, 9.946500332901397e-01, + 9.895756853352172e-01, 9.838303127859196e-01, 9.769999155793757e-01, 9.689141159310996e-01, 9.594038121639412e-01, + 9.483086322505029e-01, 9.354860218216989e-01, 9.208101305030523e-01, 9.041732260327581e-01, 8.854882249661838e-01, + 8.646864947605046e-01, 8.417237467711145e-01, 8.165875713256009e-01, 7.892986353718001e-01, 7.599171886893816e-01, + 7.285474515411827e-01, 6.953282935906302e-01, 6.604334017809461e-01, 6.240661431421666e-01, 5.864461424698465e-01, + 5.478160663871147e-01, 5.084499758302218e-01, 4.686361426418982e-01, 4.286789889246253e-01, 3.889032719013045e-01, + 3.496431418636314e-01, 3.112360816586544e-01, 2.740128472224535e-01, 2.382847225401666e-01, 2.043379825955252e-01, + 1.724305860483632e-01, 1.427939789949265e-01, 1.156385879569741e-01, 9.115821766571995e-02, 6.952749039054593e-02, + 5.088975408628225e-02, 3.533430192568954e-02, 2.286680405144430e-02, 1.338005016725895e-02, 6.640506529168652e-03, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; + +const LC3_FLOAT MDCT_WINDOW_240_5ms[240] = { + 5.087227626168386e-04, 9.959086585790517e-04, 1.682208006328800e-03, 2.609697259047744e-03, 3.819056787237678e-03, + 5.349319592933909e-03, 7.243906383895192e-03, 9.540832613229890e-03, 1.227637642543709e-02, 1.548950238899404e-02, + 1.921659800166160e-02, 2.349369619441617e-02, 2.835199581667961e-02, 3.382719081038548e-02, 3.994939538719628e-02, + 4.674775238543380e-02, 5.424831667522354e-02, 6.247770776443612e-02, 7.145835917501348e-02, 8.120777668775610e-02, + 9.174400412319896e-02, 1.030764959637497e-01, 1.152171887125930e-01, 1.281665713944242e-01, 1.419264381068653e-01, + 1.564942331034909e-01, 1.718593189799504e-01, 1.880134254543744e-01, 2.049363422022628e-01, 2.226123055761096e-01, + 2.410151242797736e-01, 2.601166575816199e-01, 2.798871008989962e-01, 3.002880135563586e-01, 3.212814164616093e-01, + 3.428208463088390e-01, 3.648596557863134e-01, 3.873472997948746e-01, 4.102294951869188e-01, 4.334494534591082e-01, + 4.569497078592333e-01, 4.806696403251166e-01, 5.045473815014847e-01, 5.285192958868393e-01, 5.525196099932443e-01, + 5.764872452085427e-01, 6.003522489375573e-01, 6.240509872809882e-01, 6.475182586093196e-01, 6.706896380227332e-01, + 6.935029068990036e-01, 7.158927516396895e-01, 7.378044458510402e-01, 7.591787241845952e-01, 7.799586608897265e-01, + 8.000925313431716e-01, 8.195318652294690e-01, 8.382288957404715e-01, 8.561409184410547e-01, 8.732316951214179e-01, + 8.894702022170831e-01, 9.048272294524792e-01, 9.192736375782965e-01, 9.327940405054362e-01, 9.453685031730190e-01, + 9.569883933538136e-01, 9.676486424195593e-01, 9.773507430600533e-01, 9.861027831072527e-01, 9.939122412655677e-01, + 1.000800872826561e+00, 1.006787811971719e+00, 1.011901269172423e+00, 1.016171590112097e+00, 1.019636414864842e+00, + 1.022336613864005e+00, 1.024315247630982e+00, 1.025621299895396e+00, 1.026303439275662e+00, 1.026415431432931e+00, + 1.026007933174836e+00, 1.025137435167917e+00, 1.023858366571912e+00, 1.022226936424625e+00, 1.020300550334848e+00, + 1.018135705524407e+00, 1.015792146756340e+00, 1.013325966774524e+00, 1.010794822557756e+00, 1.008265131568879e+00, + 1.006046874304407e+00, 1.003406509762925e+00, 1.000977398831985e+00, 9.987704535700208e-01, 9.967831265986109e-01, + 9.950118905889862e-01, 9.934523971504882e-01, 9.920995520917141e-01, 9.909475998606236e-01, 9.899902426925508e-01, + 9.892206942816891e-01, 9.886318043013834e-01, 9.882160904669929e-01, 9.879658322200813e-01, 9.878730767519871e-01, + 9.879296932443894e-01, 9.881273531631907e-01, 9.884575535474619e-01, 9.889115869213529e-01, 9.894805541465801e-01, + 9.901553455166457e-01, 9.909266562913843e-01, 9.917849916000535e-01, 9.927206838643636e-01, 9.937239208721489e-01, + 9.947847580943504e-01, 9.958931493776203e-01, 9.970389567617592e-01, 9.982119669301160e-01, 9.994020338838508e-01, + 1.000598323893564e+00, 1.001791235858836e+00, 1.002969837054169e+00, 1.004123786397111e+00, 1.005242583245485e+00, + 1.006315717067918e+00, 1.007332693127034e+00, 1.008283053756130e+00, 1.009156423082384e+00, 1.009942535308151e+00, + 1.010631281038659e+00, 1.011212744622770e+00, 1.011677230257499e+00, 1.012015300253356e+00, 1.012217779097186e+00, + 1.012275790821109e+00, 1.012180753005270e+00, 1.011924425888915e+00, 1.011498917644724e+00, 1.010896765282633e+00, + 1.010110965619444e+00, 1.009135094671655e+00, 1.007963362035220e+00, 1.006590756505588e+00, 1.005013115379014e+00, + 1.003227255072391e+00, 1.001231060075500e+00, 9.990235555436858e-01, 9.966050551498514e-01, 9.939894706113089e-01, + 9.904539200261149e-01, 9.868284225039941e-01, 9.827716736909488e-01, 9.782206672373213e-01, 9.731250287581631e-01, + 9.674323528812744e-01, 9.610947043524248e-01, 9.540636479502398e-01, 9.462952991190324e-01, 9.377489107516087e-01, + 9.283864275822276e-01, 9.181762606422500e-01, 9.070861558801854e-01, 8.950916858157935e-01, 8.821696237804294e-01, + 8.683025287048570e-01, 8.534769362643825e-01, 8.376852006833730e-01, 8.209275259764013e-01, 8.032090930429980e-01, + 7.845450482523652e-01, 7.649554851899686e-01, 7.444735201251689e-01, 7.231348066419057e-01, 7.009860555207412e-01, + 6.780787033699450e-01, 6.544686506489734e-01, 6.302212149502727e-01, 6.053970453856138e-01, 5.800715766089168e-01, + 5.543129276657669e-01, 5.282077505750727e-01, 5.018369724442092e-01, 4.752902962082383e-01, 4.486552956056652e-01, + 4.220281118338883e-01, 3.955057965950340e-01, 3.691875990296320e-01, 3.431732847389720e-01, 3.175633015043183e-01, + 2.924566408966782e-01, 2.679463783886042e-01, 2.441231331518492e-01, 2.210718537110466e-01, 1.988719153219592e-01, + 1.775967625327044e-01, 1.573148583944310e-01, 1.380903364946733e-01, 1.199837497591550e-01, 1.030525757797769e-01, + 8.735085011789188e-02, 7.292811584897502e-02, 5.982732244758056e-02, 4.808178837444506e-02, 3.771135297837851e-02, + 2.871831923385135e-02, 2.108352028641225e-02, 1.476289412849005e-02, 9.683884928956495e-03, 5.642168789286858e-03, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; + +const LC3_FLOAT MDCT_WINDOW_320_5ms[320] = { + 4.595886345493055e-04, 7.919323614002698e-04, 1.227927169310031e-03, 1.783653266717233e-03, 2.479549413444207e-03, + 3.329799454594261e-03, 4.353535478916468e-03, 5.564965156664018e-03, 6.986108359341676e-03, 8.629882322202329e-03, + 1.051343406844975e-02, 1.265082642578719e-02, 1.506090447446532e-02, 1.775591229287213e-02, 2.075475983187825e-02, + 2.406813715401559e-02, 2.771207863541604e-02, 3.169933248543932e-02, 3.604609640533871e-02, 4.076128638095439e-02, + 4.586038120884381e-02, 5.135136676471998e-02, 5.724780220726930e-02, 6.355854744461048e-02, 7.029450733434550e-02, + 7.745987198268531e-02, 8.506635369887924e-02, 9.311641620512773e-02, 1.016162955027316e-01, 1.105690806271684e-01, + 1.199789286645804e-01, 1.298417294090302e-01, 1.401623800497866e-01, 1.509371564593891e-01, 1.621632295622287e-01, + 1.738354123649302e-01, 1.859520359191026e-01, 1.985008828937603e-01, 2.114778554475382e-01, 2.248732557074316e-01, + 2.386763947872762e-01, 2.528729453658238e-01, 2.674547009618951e-01, 2.824031465430401e-01, 2.977050145264297e-01, + 3.133419120661713e-01, 3.292976696294886e-01, 3.455490160824131e-01, 3.620795045342974e-01, 3.788648665671841e-01, + 3.958851576591690e-01, 4.131143794748322e-01, 4.305308301005456e-01, 4.481076715576617e-01, 4.658227790464821e-01, + 4.836466393241829e-01, 5.015564851667653e-01, 5.195228071176610e-01, 5.375197039843709e-01, 5.555183841040963e-01, + 5.734957812557457e-01, 5.914186654649489e-01, 6.092622887527459e-01, 6.269981160888640e-01, 6.446002007776794e-01, + 6.620384583071039e-01, 6.792906550106088e-01, 6.963256426589250e-01, 7.131194393772130e-01, 7.296469905863920e-01, + 7.458864594794676e-01, 7.618094719403713e-01, 7.773958448163656e-01, 7.926208751337592e-01, 8.074666387233143e-01, + 8.219101564897180e-01, 8.359343163788637e-01, 8.495180470826319e-01, 8.626485837105826e-01, 8.753083234662220e-01, + 8.874884715160425e-01, 8.991737724042251e-01, 9.103527429187326e-01, 9.210144133066616e-01, 9.311556192776946e-01, + 9.407644740241826e-01, 9.498382236872068e-01, 9.583732599601223e-01, 9.663690412284377e-01, 9.738235617865406e-01, + 9.807442506043361e-01, 9.871297972052695e-01, 9.929872268444632e-01, 9.983241398929388e-01, 1.003150760219063e+00, + 1.007473713377193e+00, 1.011309151636166e+00, 1.014666681083198e+00, 1.017563337333301e+00, 1.020014681326785e+00, + 1.022039872150903e+00, 1.023654257342442e+00, 1.024881624147540e+00, 1.025739288978437e+00, 1.026250709375593e+00, + 1.026436666375082e+00, 1.026320857404224e+00, 1.025922917798664e+00, 1.025269979527211e+00, 1.024382188798244e+00, + 1.023284940887058e+00, 1.022000829220643e+00, 1.020555973231408e+00, 1.018971390778550e+00, 1.017275179369116e+00, + 1.015489129111694e+00, 1.013639356938881e+00, 1.011747750709711e+00, 1.009840844244693e+00, 1.007939764480188e+00, + 1.006407400915498e+00, 1.004374825095777e+00, 1.002469814737132e+00, 1.000689073754539e+00, 9.990346001249977e-01, + 9.975024904153303e-01, 9.960941547576162e-01, 9.948051243621099e-01, 9.936362728142866e-01, 9.925826537087717e-01, + 9.916447007525191e-01, 9.908170758245324e-01, 9.900998445795673e-01, 9.894873685512386e-01, 9.889794323427195e-01, + 9.885701787626714e-01, 9.882591911282058e-01, 9.880404423341358e-01, 9.879133688360181e-01, 9.878718098237022e-01, + 9.879150762106034e-01, 9.880368938846610e-01, 9.882364564839506e-01, 9.885073687439192e-01, 9.888487088987707e-01, + 9.892539488627546e-01, 9.897220412447528e-01, 9.902463287269285e-01, 9.908256340476208e-01, 9.914531811725067e-01, + 9.921276814881759e-01, 9.928422499725458e-01, 9.935955098307742e-01, 9.943804814776256e-01, 9.951957244449919e-01, + 9.960341878404958e-01, 9.968943831870675e-01, 9.977692009836100e-01, 9.986571134591464e-01, 9.995509738170480e-01, + 1.000449227898040e+00, 1.001344692310058e+00, 1.002235786606954e+00, 1.003115291715261e+00, 1.003981602446902e+00, + 1.004827468041713e+00, 1.005651275972376e+00, 1.006445772052972e+00, 1.007209352772459e+00, 1.007934783656087e+00, + 1.008620496650569e+00, 1.009259314290145e+00, 1.009849742422788e+00, 1.010384692193296e+00, 1.010862783160582e+00, + 1.011277044709547e+00, 1.011626247430694e+00, 1.011903571699736e+00, 1.012107954864219e+00, 1.012232755709885e+00, + 1.012277089047072e+00, 1.012234505114778e+00, 1.012104319978655e+00, 1.011880293122688e+00, 1.011561972516341e+00, + 1.011143373963981e+00, 1.010624321020038e+00, 1.009999148545101e+00, 1.009268031808824e+00, 1.008425698479647e+00, + 1.007472774447058e+00, 1.006404483571931e+00, 1.005222003295591e+00, 1.003921160689206e+00, 1.002503762756151e+00, + 1.000966332772540e+00, 9.993114007411373e-01, 9.975362702189898e-01, 9.956442306333592e-01, 9.936333924912825e-01, + 9.908677480361242e-01, 9.882326326262749e-01, 9.853620567056602e-01, 9.822305093671991e-01, 9.788185853162172e-01, + 9.751026333215268e-01, 9.710631852370086e-01, 9.666759668947944e-01, 9.619242192293307e-01, 9.567841986369235e-01, + 9.512394303101863e-01, 9.452700238623795e-01, 9.388615698236068e-01, 9.319946435581106e-01, 9.246592033932568e-01, + 9.168383396399868e-01, 9.085218034087421e-01, 8.996967011299613e-01, 8.903562054918268e-01, 8.804877931535187e-01, + 8.700884209228057e-01, 8.591492134848259e-01, 8.476686394755906e-01, 8.356428970797861e-01, 8.230753889817990e-01, + 8.099649296155544e-01, 7.963204506324437e-01, 7.821460539775005e-01, 7.674541821769616e-01, 7.522563457568547e-01, + 7.365702052057368e-01, 7.204090552899627e-01, 7.037975107157410e-01, 6.867542812151157e-01, 6.693041888771051e-01, + 6.514710959179395e-01, 6.332854832820911e-01, 6.147685389896460e-01, 5.959553778639692e-01, 5.768737955463938e-01, + 5.575534287167304e-01, 5.380320138068979e-01, 5.183454027643563e-01, 4.985259415650634e-01, 4.786156067459849e-01, + 4.586473038370941e-01, 4.386643656872842e-01, 4.187046888325280e-01, 3.988123056192917e-01, 3.790262923635886e-01, + 3.593914828698096e-01, 3.399474132903109e-01, 3.207392420889753e-01, 3.018061113177048e-01, 2.831905952786929e-01, + 2.649288369241889e-01, 2.470608550624402e-01, 2.296201119084317e-01, 2.126433716126151e-01, 1.961601816145380e-01, + 1.802035203864437e-01, 1.647996883470626e-01, 1.499787548077656e-01, 1.357643522991611e-01, 1.221842534547464e-01, + 1.092601994264172e-01, 9.701788451015501e-02, 8.547680283183663e-02, 7.465976378295235e-02, 6.458254322751883e-02, + 5.526281189874138e-02, 4.670976978373095e-02, 3.893244425578719e-02, 3.192976013776996e-02, 2.569810636390756e-02, + 2.022259265088492e-02, 1.548317776486452e-02, 1.144924909653903e-02, 8.076482660383199e-03, 5.300044080947794e-03, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; + +const LC3_FLOAT MDCT_WINDOW_480_5ms[480] = { + 4.090106504820579e-04, 6.143388180964179e-04, 8.571759876954877e-04, 1.147015057857495e-03, 1.489582832987000e-03, + 1.889770382231583e-03, 2.353000800169909e-03, 2.884104959764029e-03, 3.488213786635855e-03, 4.170040431489613e-03, + 4.934298832466617e-03, 5.787076505403503e-03, 6.733811743137561e-03, 7.779130464154915e-03, 8.927044958757816e-03, + 1.018202888968871e-02, 1.154910606525086e-02, 1.303349217699797e-02, 1.463951288465963e-02, 1.637155619860352e-02, + 1.823455383898077e-02, 2.023309488998589e-02, 2.237116158648752e-02, 2.465237348403478e-02, 2.708101935270475e-02, + 2.966159685753317e-02, 3.239884850877327e-02, 3.529601774976465e-02, 3.835663329277230e-02, 4.158447932459513e-02, + 4.498322421745353e-02, 4.855610986150206e-02, 5.230596475016741e-02, 5.623624576084146e-02, 6.035055738891727e-02, + 6.465186317477950e-02, 6.914195749790462e-02, 7.382288203064732e-02, 7.869709331995660e-02, 8.376761638427657e-02, + 8.903563687211118e-02, 9.450199243028472e-02, 1.001680193006426e-01, 1.060356225286319e-01, 1.121060220821844e-01, + 1.183788547045326e-01, 1.248534855777947e-01, 1.315302847610869e-01, 1.384103079528939e-01, 1.454931890869180e-01, + 1.527772946853750e-01, 1.602608842337125e-01, 1.679435556337752e-01, 1.758245615079801e-01, 1.839020119821303e-01, + 1.921728622634411e-01, 2.006344295681524e-01, 2.092853879977170e-01, 2.181238261985594e-01, 2.271462264407930e-01, + 2.363479205237173e-01, 2.457259744642953e-01, 2.552771551741124e-01, 2.649981094228982e-01, 2.748839432649996e-01, + 2.849296444030153e-01, 2.951306505827265e-01, 3.054824712370942e-01, 3.159799638238941e-01, 3.266169794538543e-01, + 3.373873799614014e-01, 3.482855915638277e-01, 3.593057693987583e-01, 3.704415932452488e-01, 3.816862385160692e-01, + 3.930329782788047e-01, 4.044749630814483e-01, 4.160051103939122e-01, 4.276159595085598e-01, 4.393004362003260e-01, + 4.510516333434032e-01, 4.628616046119925e-01, 4.747225454237193e-01, 4.866266705542529e-01, 4.985664508456704e-01, + 5.105341492548225e-01, 5.225212793188740e-01, 5.345190505841265e-01, 5.465201916422433e-01, 5.585172769552711e-01, + 5.705021536899105e-01, 5.824658100332457e-01, 5.943991720381216e-01, 6.062948176207270e-01, 6.181452662624718e-01, + 6.299422016714543e-01, 6.416768736044914e-01, 6.533411462740817e-01, 6.649277540000037e-01, 6.764292700223311e-01, + 6.878367295965062e-01, 6.991421467689277e-01, 7.103379606632721e-01, 7.214176027060971e-01, 7.323746102405828e-01, + 7.432008025932804e-01, 7.538887973483771e-01, 7.644315495717613e-01, 7.748223151443820e-01, 7.850546571907628e-01, + 7.951223518167163e-01, 8.050193862201107e-01, 8.147397447696774e-01, 8.242774413707643e-01, 8.336267114335371e-01, + 8.427819363777799e-01, 8.517386186427548e-01, 8.604920874939698e-01, 8.690376742017057e-01, 8.773720451249032e-01, + 8.854927938913381e-01, 8.933935477349644e-01, 9.010727088526728e-01, 9.085249398881980e-01, 9.157483563218768e-01, + 9.227413839712016e-01, 9.295017469413066e-01, 9.360270196617569e-01, 9.423143052164881e-01, 9.483629792665091e-01, + 9.541731142261065e-01, 9.597438382130120e-01, 9.650738394220176e-01, 9.701635474343885e-01, 9.750143364412617e-01, + 9.796277191617885e-01, 9.840036439809510e-01, 9.881426772731259e-01, 9.920470446911211e-01, 9.957199420334376e-01, + 9.991640812275709e-01, 1.002381307710643e+00, 1.005374268639838e+00, 1.008146718214831e+00, 1.010703123647275e+00, + 1.013046655758663e+00, 1.015181271161417e+00, 1.017111643578857e+00, 1.018843380560658e+00, 1.020381713994816e+00, + 1.021731101971518e+00, 1.022896948293643e+00, 1.023885455671576e+00, 1.024702974608899e+00, 1.025355286710874e+00, + 1.025848243050604e+00, 1.026188366261215e+00, 1.026382881625701e+00, 1.026438102255574e+00, 1.026360125820994e+00, + 1.026155530733488e+00, 1.025831456886557e+00, 1.025395432284244e+00, 1.024853974580724e+00, 1.024213482124578e+00, + 1.023481184943025e+00, 1.022664602721801e+00, 1.021770903480975e+00, 1.020806917660529e+00, 1.019779396547454e+00, + 1.018695995335235e+00, 1.017564416918053e+00, 1.016391686789653e+00, 1.015184918030332e+00, 1.013950835315021e+00, + 1.012697033320358e+00, 1.011430749860716e+00, 1.010158346781076e+00, 1.008885191761748e+00, 1.007592718305943e+00, + 1.006805603478092e+00, 1.005378742804807e+00, 1.004049051787112e+00, 1.002778356298787e+00, 1.001563778373068e+00, + 1.000404915291105e+00, 9.993014844615166e-01, 9.982531564931281e-01, 9.972595460676951e-01, 9.963202131848272e-01, + 9.954346644968789e-01, 9.946023543844607e-01, 9.938226881029791e-01, 9.930950268060122e-01, 9.924186919309267e-01, + 9.917929657090736e-01, 9.912170911359961e-01, 9.906902760441473e-01, 9.902117003786811e-01, 9.897805192546193e-01, + 9.893958602389157e-01, 9.890568243690241e-01, 9.887624937408933e-01, 9.885119364350415e-01, 9.883042028597552e-01, + 9.881383235740961e-01, 9.880133161159576e-01, 9.879281898513085e-01, 9.878819413827574e-01, 9.878735508484809e-01, + 9.879019873841568e-01, 9.879662130250981e-01, 9.880651778500144e-01, 9.881978162133899e-01, 9.883630508181326e-01, + 9.885597957603544e-01, 9.887869526128024e-01, 9.890434070785485e-01, 9.893280319166613e-01, 9.896396899060125e-01, + 9.899772316163624e-01, 9.903394929409673e-01, 9.907252968668226e-01, 9.911334564321237e-01, 9.915627747807666e-01, + 9.920120436855326e-01, 9.924800441092685e-01, 9.929655482846576e-01, 9.934673212537685e-01, 9.939841207305906e-01, + 9.945146969322154e-01, 9.950577931942117e-01, 9.956121471675398e-01, 9.961764915534302e-01, 9.967495543671935e-01, + 9.973300590248015e-01, 9.979167245036720e-01, 9.985082643417953e-01, 9.991033633647473e-01, 9.997003478609010e-01, + 1.000299741957418e+00, 1.000897441314013e+00, 1.001493964257960e+00, 1.002087624593489e+00, 1.002677088643863e+00, + 1.003261045483858e+00, 1.003838183774652e+00, 1.004407190937699e+00, 1.004966753528881e+00, 1.005515557572658e+00, + 1.006052289109999e+00, 1.006575635258931e+00, 1.007084285781611e+00, 1.007576934100958e+00, 1.008052277555815e+00, + 1.008509017718116e+00, 1.008945862447015e+00, 1.009361528531177e+00, 1.009754742820913e+00, 1.010124241309341e+00, + 1.010468769795370e+00, 1.010787087537248e+00, 1.011077969726137e+00, 1.011340205650538e+00, 1.011572597114216e+00, + 1.011773962181442e+00, 1.011943138906979e+00, 1.012078982659783e+00, 1.012180362866919e+00, 1.012246166897464e+00, + 1.012275305013586e+00, 1.012266707295288e+00, 1.012219319453278e+00, 1.012132107622966e+00, 1.012004064757857e+00, + 1.011834207632025e+00, 1.011621572933544e+00, 1.011365223023975e+00, 1.011064253702468e+00, 1.010717792733157e+00, + 1.010324996851905e+00, 1.009885057526159e+00, 1.009397209381147e+00, 1.008860731864438e+00, 1.008274947065247e+00, + 1.007639223374887e+00, 1.006952983357691e+00, 1.006215708265639e+00, 1.005426938305289e+00, 1.004586273379809e+00, + 1.003693377657581e+00, 1.002747984657666e+00, 1.001749900308864e+00, 1.000699003803502e+00, 9.995952485989262e-01, + 9.984386632116344e-01, 9.972293415774932e-01, 9.959672769174924e-01, 9.946500332901397e-01, 9.932403996813470e-01, + 9.912511516117244e-01, 9.895756853352172e-01, 9.877713214760662e-01, 9.858577479051078e-01, 9.838303127859196e-01, + 9.816822625580078e-01, 9.794074486605805e-01, 9.769999155793757e-01, 9.744528356359687e-01, 9.717597500340699e-01, + 9.689141159310996e-01, 9.659101618500662e-01, 9.627421831412876e-01, 9.594038121639412e-01, 9.558889978382734e-01, + 9.521922434090249e-01, 9.483086322505029e-01, 9.442332539187503e-01, 9.399607238929982e-01, 9.354860218216989e-01, + 9.308052967663477e-01, 9.259146970284931e-01, 9.208101305030523e-01, 9.154873597416558e-01, 9.099426066529104e-01, + 9.041732260327581e-01, 8.981763729936715e-01, 8.919490241013392e-01, 8.854882249661838e-01, 8.787919436722827e-01, + 8.718585835568161e-01, 8.646864947605047e-01, 8.572738135700366e-01, 8.496195859658071e-01, 8.417237467711145e-01, + 8.335862715770727e-01, 8.252074428838668e-01, 8.165875713256009e-01, 8.077280370477699e-01, 7.986311592191131e-01, + 7.892986353718001e-01, 7.797330954210866e-01, 7.699379531983687e-01, 7.599171886893816e-01, 7.496758423734833e-01, + 7.392176841476761e-01, 7.285474515411827e-01, 7.176714478163359e-01, 7.065962311464494e-01, 6.953282935906302e-01, + 6.838739059112046e-01, 6.722395305539791e-01, 6.604334017809461e-01, 6.484643596235256e-01, 6.363395004626368e-01, + 6.240661431421666e-01, 6.116530334821534e-01, 5.991098644638286e-01, 5.864461424698465e-01, 5.736694851703749e-01, + 5.607881029948401e-01, 5.478160663871271e-01, 5.347619788897301e-01, 5.216365147692703e-01, 5.084499758302256e-01, + 4.952135086430446e-01, 4.819387562519412e-01, 4.686361426419003e-01, 4.553170769563941e-01, 4.419939954454178e-01, + 4.286789889246267e-01, 4.153837786572842e-01, 4.021211063103491e-01, 3.889032719013054e-01, 3.757425439137077e-01, + 3.626515183776310e-01, 3.496431418636322e-01, 3.367290822653354e-01, 3.239228075238623e-01, 3.112360816586549e-01, + 2.986807941537710e-01, 2.862694673284843e-01, 2.740128472224539e-01, 2.619228330079575e-01, 2.500098438708934e-01, + 2.382847225401669e-01, 2.267578490199104e-01, 2.154390996938547e-01, 2.043379825955254e-01, 1.934636765792024e-01, + 1.828250319214460e-01, 1.724305860483634e-01, 1.622886348529314e-01, 1.524071880359812e-01, 1.427939789949266e-01, + 1.334565845242183e-01, 1.244023922999665e-01, 1.156385879569742e-01, 1.071721547807196e-01, 9.900985872728905e-02, + 9.115821766572002e-02, 8.362344855837105e-02, 7.641140367416376e-02, 6.952749039054598e-02, 6.297656454790079e-02, + 5.676284244020858e-02, 5.088975408628229e-02, 4.535983304624439e-02, 4.017457306236873e-02, 3.533430192568957e-02, + 3.083806062123772e-02, 2.668355420358626e-02, 2.286680405144430e-02, 1.938236337675363e-02, 1.622312720409645e-02, + 1.338005016725895e-02, 1.084218595595746e-02, 8.596753980908744e-03, 6.640506529168652e-03, 5.172703110468352e-03, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; + + +const LC3_FLOAT MDCT_HRA_WINDOW_480_2_5ms[240] = { + 1.928875250471185e-07, 1.268623078914631e-06, 3.736943081685792e-06, 8.649386473419844e-06, 1.752499879209154e-05, + 3.251004192297566e-05, 5.654995150945631e-05, 9.358653414327445e-05, 1.487809853781833e-04, 2.287619057346095e-04, + 3.418963835622074e-04, 4.985810015573861e-04, 7.115482671394238e-04, 9.961824750040105e-04, 1.370837415765066e-03, + 1.857146703383843e-03, 2.480315886706181e-03, 3.269384042869696e-03, 4.257441351253188e-03, 5.481788360538607e-03, + 6.984022437256788e-03, 8.810037359146468e-03, 1.100992329671028e-02, 1.363775656493463e-02, 1.675127150559057e-02, + 2.041141057401967e-02, 2.468175295733717e-02, 2.962782656580052e-02, 3.531631267855188e-02, 4.181415652877682e-02, + 4.918760034374654e-02, 5.750115754515065e-02, 6.681654781077175e-02, 7.719161248813326e-02, 8.867922857347045e-02, + 1.013262374019720e-01, 1.151724017179353e-01, 1.302494023407827e-01, 1.465798836473051e-01, 1.641765559275968e-01, + 1.830413626142431e-01, 2.031647215674081e-01, 2.245248520040451e-01, 2.470872021104946e-01, 2.708039965464759e-01, + 2.956139274737775e-01, 3.214420168557505e-01, 3.481996809305596e-01, 3.757850292873181e-01, 4.040834302177654e-01, + 4.329683704138883e-01, 4.623026302356333e-01, 4.919397855296871e-01, 5.217260335074649e-01, 5.515023240298861e-01, + 5.811067597335228e-01, 6.103772100633116e-01, 6.391540670154212e-01, 6.672830559207561e-01, 6.946180045149623e-01, + 7.210234691482331e-01, 7.463771190956836e-01, 7.705717887049389e-01, 7.935171220325148e-01, 8.151407544921331e-01, + 8.353889991744725e-01, 8.542270299166949e-01, 8.716385768842180e-01, 8.876251715716619e-01, 9.022049953400274e-01, + 9.154113980197115e-01, 9.272911604251438e-01, 9.379025770646191e-01, 9.473134335138002e-01, 9.555989477431630e-01, + 9.628397371519567e-01, 9.691198641470655e-01, 9.745250036731624e-01, 9.791407668194774e-01, 9.830512059497915e-01, + 9.863375189657285e-01, 9.890769633791019e-01, 9.913419847656554e-01, 9.931995587544050e-01, 9.947107408108303e-01, + 9.959304135675596e-01, 9.969072172806543e-01, 9.976836451676292e-01, 9.982962820245519e-01, 9.987761617973335e-01, + 9.991492178976376e-01, 9.994367991905715e-01, 9.996562248627440e-01, 9.998213528339476e-01, 9.999431389208511e-01, + 1.000030167405588e+00, 1.000089137729581e+00, 1.000125296398298e+00, 1.000142807515464e+00, 1.000145059370791e+00, + 1.000134907956303e+00, 1.000114861040898e+00, 1.000087208438067e+00, 1.000054105383460e+00, 1.000017616583971e+00, + 9.999797286315710e-01, 9.999423382309206e-01, 9.999072232012880e-01, 9.998760025910959e-01, 9.998500915686289e-01, + 9.998306560737898e-01, 9.998185715517388e-01, 9.998143894342878e-01, 9.998183143680869e-01, 9.998301944838478e-01, + 9.998495262367371e-01, 9.998754745167079e-01, 9.999069078401956e-01, 9.999424475239904e-01, 9.999805288598742e-01, + 1.000019471519221e+00, 1.000057555786879e+00, 1.000093100812805e+00, 1.000124540917058e+00, 1.000150496102128e+00, + 1.000169833298924e+00, 1.000181715452526e+00, 1.000185636273393e+00, 1.000181439257840e+00, 1.000169320335504e+00, + 1.000149814156658e+00, 1.000123764529774e+00, 1.000092279821119e+00, 1.000056674215966e+00, 1.000018395617911e+00, + 9.999789406480724e-01, 9.999397567326687e-01, 9.999021306794866e-01, 9.998670624939285e-01, 9.998351225350340e-01, + 9.998062895304436e-01, 9.997797665333356e-01, 9.997537716957203e-01, 9.997253008334399e-01, 9.996898592447866e-01, + 9.996411611766667e-01, 9.995707967428177e-01, 9.994678679836200e-01, 9.993185980679096e-01, 9.991059202780914e-01, + 9.988090562524252e-01, 9.984030958127336e-01, 9.978585933978946e-01, 9.971411984750603e-01, 9.962113391583908e-01, + 9.950239795154223e-01, 9.935284716160412e-01, 9.916685232530794e-01, 9.893823014422549e-01, 9.866026903106617e-01, + 9.832577198181265e-01, 9.792711789106039e-01, 9.745634231307387e-01, 9.690523823244767e-01, 9.626547687789766e-01, + 9.552874798038419e-01, 9.468691813614447e-01, 9.373220508813107e-01, 9.265736480032657e-01, 9.145588719963409e-01, + 9.012219545005915e-01, 8.865184267401519e-01, 8.704169923325978e-01, 8.529012312555665e-01, 8.339710584198038e-01, + 8.136438625110305e-01, 7.919552579077074e-01, 7.689593947581650e-01, 7.447287893964823e-01, 7.193536583208960e-01, + 6.929407625549489e-01, 6.656117935585394e-01, 6.375013549431151e-01, 6.087546140984144e-01, 5.795247127727363e-01, + 5.499700344866872e-01, 5.202514288725478e-01, 4.905294887819369e-01, 4.609619660928919e-01, 4.317013978660552e-01, + 4.028929974356116e-01, 3.746728468420245e-01, 3.471664092737412e-01, 3.204873641715565e-01, 2.947367542923338e-01, + 2.700024238683050e-01, 2.463587202023185e-01, 2.238664274584689e-01, 2.025729006480214e-01, 1.825123693148748e-01, + 1.637063835467572e-01, 1.461643790086412e-01, 1.298843420747792e-01, 1.148535602600838e-01, 1.010494465619472e-01, + 8.844042869400506e-02, 7.698689534753124e-02, 6.664219153548699e-02, 5.735365389394342e-02, 4.906367480666277e-02, + 4.171078175510523e-02, 3.523071580898128e-02, 2.955749109487545e-02, 2.462441579169607e-02, 2.036505497804320e-02, + 1.671411663728698e-02, 1.360824429995981e-02, 1.098670301702559e-02, 8.791949345648940e-03, 6.970080454492374e-03, + 5.471161958930394e-03, 4.249438341364304e-03, 3.263433520599239e-03, 2.475952111493295e-03, 1.853994056678125e-03, + 1.368596596909542e-03, 9.946180283333026e-04, 7.104774789034889e-04, 4.978641589703932e-04, 3.414283510010364e-04, + 2.284649445606105e-04, 1.485987233730432e-04, 9.347897725317759e-05, 5.648942347847280e-05, 3.247793542861785e-05, + 1.750922386335714e-05, 8.642407336226362e-06, 3.734302301245202e-06, 1.267861256795911e-06, 1.927766981311251e-07}; + +const LC3_FLOAT MDCT_HRA_WINDOW_960_2_5ms[480] = { + 1.363353492760669e-07, 4.577676005269251e-07, 9.975675168391671e-07, 1.840776229085288e-06, 3.092248230077047e-06, + 4.880943708557620e-06, 7.363817805099883e-06, 1.073000750387602e-05, 1.520538607055496e-05, 2.105750528134522e-05, + 2.860093592119667e-05, 3.820301288710557e-05, 5.028998805188179e-05, 6.535359090391442e-05, 8.395799364585048e-05, + 1.067471738361778e-04, 1.344526637637966e-04, 1.679016715435404e-04, 2.080255544044134e-04, 2.558686198117505e-04, + 3.125972249248099e-04, 3.795091394541575e-04, 4.580431312676675e-04, 5.497887281277575e-04, 6.564961027629782e-04, + 7.800860221325537e-04, 9.226597952927381e-04, 1.086509147791288e-03, 1.274125944085974e-03, 1.488211673202887e-03, + 1.731686606830910e-03, 2.007698533412427e-03, 2.319630966669840e-03, 2.671110722544265e-03, 3.066014754864068e-03, + 3.508476137357141e-03, 4.002889078021606e-03, 4.553912851519276e-03, 5.166474536289647e-03, 5.845770445618693e-03, + 6.597266146035767e-03, 7.426694962226363e-03, 8.340054875180547e-03, 9.343603729551937e-03, 1.044385267714563e-02, + 1.164755779600632e-02, 1.296170983861615e-02, 1.439352207806304e-02, 1.595041623748902e-02, 1.764000650541313e-02, + 1.947008165734806e-02, 2.144858532216432e-02, 2.358359444954804e-02, 2.588329605228426e-02, 2.835596231360897e-02, + 3.100992416515645e-02, 3.385354345474830e-02, 3.689518383513415e-02, 4.014318051454780e-02, 4.360580901740066e-02, + 4.729125310846769e-02, 5.120757203648361e-02, 5.536266725318061e-02, 5.976424876157179e-02, 6.441980124289254e-02, + 6.933655010531084e-02, 7.452142758961615e-02, 7.998103905796611e-02, 8.572162958181787e-02, 9.174905093483054e-02, + 9.806872908624656e-02, 1.046856322804917e-01, 1.116042397799019e-01, 1.188285113399959e-01, 1.263618574809210e-01, + 1.342071106149135e-01, 1.423664970880752e-01, 1.508416101956496e-01, 1.596333842333865e-01, 1.687420696535257e-01, + 1.781672094023636e-01, 1.879076165271377e-01, 1.979613531528743e-01, 2.083257109445936e-01, 2.189971931864894e-01, + 2.299714986269890e-01, 2.412435072564368e-01, 2.528072682020181e-01, 2.646559899418406e-01, 2.767820330562002e-01, + 2.891769057483280e-01, 3.018312623786579e-01, 3.147349052652145e-01, 3.278767900074122e-01, 3.412450345907444e-01, + 3.548269325249284e-01, 3.686089702575019e-01, 3.825768490881926e-01, 3.967155117862224e-01, 4.110091740828488e-01, + 4.254413611747417e-01, 4.399949493303511e-01, 4.546522126414323e-01, 4.693948749058132e-01, 4.842041665659120e-01, + 4.990608865612834e-01, 5.139454688835927e-01, 5.288380535501122e-01, 5.437185616384643e-01, 5.585667739524391e-01, + 5.733624128178846e-01, 5.880852264406471e-01, 6.027150751969793e-01, 6.172320191724501e-01, 6.316164062197546e-01, + 6.458489597703579e-01, 6.599108656108541e-01, 6.737838568232726e-01, 6.874502960899853e-01, 7.008932545787268e-01, + 7.140965866515435e-01, 7.270449996828834e-01, 7.397241183258171e-01, 7.521205426304834e-01, 7.642218994939656e-01, + 7.760168870042503e-01, 7.874953113309442e-01, 7.986481159099932e-01, 8.094674027667472e-01, 8.199464459192338e-01, + 8.300796968994718e-01, 8.398627825231116e-01, 8.492924951249206e-01, 8.583667755581161e-01, 8.670846893280041e-01, + 8.754463962937875e-01, 8.834531144261093e-01, 8.911070781514043e-01, 8.984114918473676e-01, 9.053704790768982e-01, + 9.119890281611266e-01, 9.182729346961321e-01, 9.242287416134559e-01, 9.298636773723805e-01, 9.351855928531210e-01, + 9.402028974955879e-01, 9.449244951992589e-01, 9.493597204669394e-01, 9.535182752397909e-01, 9.574101668338553e-01, + 9.610456473502188e-01, 9.644351548926832e-01, 9.675892568889318e-01, 9.705185957742447e-01, 9.732338372611643e-01, + 9.757456213845153e-01, 9.780645164789403e-01, 9.802009762158145e-01, 9.821652997980082e-01, 9.839675953844861e-01, + 9.856177467920233e-01, 9.871253834983186e-01, 9.884998539492639e-01, 9.897502021530162e-01, 9.908851475245483e-01, + 9.919130679264989e-01, 9.928419858351684e-01, 9.936795575444219e-01, 9.944330653049196e-01, 9.951094122815642e-01, + 9.957151201982998e-01, 9.962563295265126e-01, 9.967388020613602e-01, 9.971679257195168e-01, 9.975487213822326e-01, + 9.978858515994010e-01, 9.981836309637017e-01, 9.984460379589807e-01, 9.986767280839717e-01, 9.988790480513948e-01, + 9.990560508634377e-01, 9.992105115676724e-01, 9.993449435025852e-01, 9.994616148490124e-01, 9.995625653127808e-01, + 9.996496227746003e-01, 9.997244197555017e-01, 9.997884095596641e-01, 9.998428819710351e-01, 9.998889783954170e-01, + 9.999277063554146e-01, 9.999599532614691e-01, 9.999864993978808e-01, 1.000008030077971e+00, 1.000025146937107e+00, + 1.000038378346013e+00, 1.000048188939381e+00, 1.000054988266291e+00, 1.000059138579006e+00, 1.000060961785582e+00, + 1.000060745599070e+00, 1.000058748922255e+00, 1.000055206511563e+00, 1.000050332967367e+00, 1.000044326100310e+00, + 1.000037369724671e+00, 1.000029635930232e+00, 1.000021286883873e+00, 1.000012476211096e+00, 1.000003350006250e+00, + 9.999940475182815e-01, 9.999847015566445e-01, 9.999754386595657e-01, 9.999663790642979e-01, 9.999576365163719e-01, + 9.999493179522237e-01, 9.999415230869807e-01, 9.999343439366570e-01, 9.999278643015735e-01, 9.999221592354568e-01, + 9.999172945224162e-01, 9.999133261818468e-01, 9.999103000191805e-01, 9.999082512384065e-01, 9.999072041302636e-01, + 9.999071718480597e-01, 9.999081562811047e-01, 9.999101480338050e-01, 9.999131265164656e-01, 9.999170601519115e-01, + 9.999219066999991e-01, 9.999276137001288e-01, 9.999341190298563e-01, 9.999413515757679e-01, 9.999492320108540e-01, + 9.999576736708096e-01, 9.999665835199758e-01, 9.999758631960602e-01, 9.999854101213793e-01, 9.999951186671812e-01, + 1.000004881356628e+00, 1.000014590091279e+00, 1.000024137385544e+00, 1.000033417593335e+00, 1.000042328111225e+00, + 1.000050770542848e+00, 1.000058651809861e+00, 1.000065885195634e+00, 1.000072391308898e+00, 1.000078098955774e+00, + 1.000082945909961e+00, 1.000086879572280e+00, 1.000089857512229e+00, 1.000091847885646e+00, 1.000092829723974e+00, + 1.000092793091916e+00, 1.000091739111420e+00, 1.000089679850895e+00, 1.000086638079347e+00, 1.000082646885623e+00, + 1.000077749163242e+00, 1.000071996961268e+00, 1.000065450701385e+00, 1.000058178260741e+00, 1.000050253919262e+00, + 1.000041757168942e+00, 1.000032771381191e+00, 1.000023382326608e+00, 1.000013676539597e+00, 1.000003739518099e+00, + 9.999936537463840e-01, 9.999834965263427e-01, 9.999733376002018e-01, 9.999632365449369e-01, 9.999532399160947e-01, + 9.999433781162252e-01, 9.999336619607787e-01, 9.999240789122246e-01, 9.999145889513631e-01, 9.999051200534473e-01, + 9.998955632358651e-01, 9.998857671439174e-01, 9.998755321416521e-01, 9.998646038760159e-01, 9.998526662846789e-01, + 9.998393340210341e-01, 9.998241442739438e-01, 9.998065479650342e-01, 9.997859003125656e-01, 9.997614507583039e-01, + 9.997323322622099e-01, 9.996975499792088e-01, 9.996559693426429e-01, 9.996063035901801e-01, 9.995471007797664e-01, + 9.994767303555520e-01, 9.993933693363640e-01, 9.992949882120472e-01, 9.991793366456373e-01, 9.990439290916592e-01, + 9.988860304525888e-01, 9.987026419065322e-01, 9.984904870492169e-01, 9.982459985022988e-01, 9.979653051476074e-01, + 9.976442201531890e-01, 9.972782299617136e-01, 9.968624844150069e-01, 9.963917881900651e-01, 9.958605937219481e-01, + 9.952629957874448e-01, 9.945927279204203e-01, 9.938431608253206e-01, 9.930073029495663e-01, 9.920778033684794e-01, + 9.910469571281373e-01, 9.899067131820748e-01, 9.886486850471784e-01, 9.872641642923781e-01, 9.857441369608847e-01, + 9.840793030126235e-01, 9.822600988582102e-01, 9.802767230390885e-01, 9.781191650903150e-01, 9.757772376026793e-01, + 9.732406114793927e-01, 9.704988543592059e-01, 9.675414721525257e-01, 9.643579536097365e-01, 9.609378178114939e-01, + 9.572706644392005e-01, 9.533462266503443e-01, 9.491544263479285e-01, 9.446854315961644e-01, 9.399297158962095e-01, + 9.348781189964488e-01, 9.295219088721776e-01, 9.238528444701966e-01, 9.178632387754598e-01, 9.115460217204322e-01, + 9.048948024240450e-01, 8.979039302171362e-01, 8.905685538859580e-01, 8.828846785458305e-01, 8.748492195442639e-01, + 8.664600527878369e-01, 8.577160608906681e-01, 8.486171745551603e-01, 8.391644086184020e-01, 8.293598922305367e-01, + 8.192068926746530e-01, 8.087098323911928e-01, 7.978742988330544e-01, 7.867070468498287e-01, 7.752159933798504e-01, + 7.634102043158196e-01, 7.512998735020282e-01, 7.388962939169839e-01, 7.262118211926384e-01, 7.132598297183557e-01, + 7.000546616722335e-01, 6.866115694122957e-01, 6.729466517435032e-01, 6.590767846515775e-01, 6.450195471597746e-01, + 6.307931430185830e-01, 6.164163189797930e-01, 6.019082804348481e-01, 5.872886052124403e-01, 5.725771563319307e-01, + 5.577939944978301e-01, 5.429592910967905e-01, 5.280932424234555e-01, 5.132159858162120e-01, 4.983475183298941e-01, + 4.835076185113182e-01, 4.687157717768828e-01, 4.539910998210603e-01, 4.393522944120604e-01, 4.248175558579833e-01, + 4.104045363548025e-01, 3.961302883579846e-01, 3.820112180536255e-01, 3.680630439436816e-01, 3.543007605040334e-01, + 3.407386068243548e-01, 3.273900400954695e-01, 3.142677137733552e-01, 3.013834602191723e-01, 2.887482775916394e-01, + 2.763723207514489e-01, 2.642648959268686e-01, 2.524344588847748e-01, 2.408886163515173e-01, 2.296341304326797e-01, + 2.186769257893048e-01, 2.080220993398264e-01, 1.976739322711464e-01, 1.876359041583237e-01, 1.779107090095517e-01, + 1.685002730708834e-01, 1.594057742429125e-01, 1.506276629788181e-01, 1.421656845493104e-01, 1.340189025746913e-01, + 1.261857237370651e-01, 1.186639235964411e-01, 1.114506734428340e-01, 1.045425681223503e-01, 9.793565477860058e-02, + 9.162546245161339e-02, 8.560703247484407e-02, 7.987494960705163e-02, 7.442337382999228e-02, 6.924607273536325e-02, + 6.433645441557491e-02, 5.968760076313909e-02, 5.529230107316437e-02, 5.114308583308901e-02, 4.723226057381158e-02, + 4.355193964722984e-02, 4.009407978727676e-02, 3.685051330522059e-02, 3.381298076557955e-02, 3.097316298675063e-02, + 2.832271221053797e-02, 2.585328228730008e-02, 2.355655772843824e-02, 2.142428148537503e-02, 1.944828132389286e-02, + 1.762049467453352e-02, 1.593299185344667e-02, 1.437799756332653e-02, 1.294791060055676e-02, 1.163532171204003e-02, + 1.043302956305446e-02, 9.334054795489547e-03, 8.331652173617308e-03, 7.419320831822072e-03, 6.590812655146027e-03, + 5.840138838848342e-03, 5.161574687206487e-03, 4.549662724337389e-03, 3.999214200759286e-03, 3.505309088672846e-03, + 3.063294666478038e-03, 2.668782798866110e-03, 2.317646022975776e-03, 2.006012553652158e-03, 1.730260321894845e-03, + 1.487010160247016e-03, 1.273118247295162e-03, 1.085667920762688e-03, 9.219609650399310e-04, 7.795084745479000e-04, + 6.560213892304477e-04, 5.494007928508220e-04, 4.577280587661532e-04, 3.792549215895880e-04, 3.123935467349105e-04, + 2.557066633705375e-04, 2.078978198736850e-04, 1.678018145436083e-04, 1.343753481649133e-04, 1.066879390562912e-04, + 8.391313553401788e-05, 6.532005529093359e-05, 5.026527605947520e-05, 3.818509710338716e-05, 2.858818657228189e-05, + 2.104862555598476e-05, 1.519935578579325e-05, 1.072603433419925e-05, 7.361295334616452e-06, 4.879415604699819e-06, + 3.091377877253446e-06, 1.840321200267112e-06, 9.973582966273186e-07, 4.576899867970956e-07, 1.363156993327630e-07}; + +const LC3_FLOAT MDCT_HRA_WINDOW_480_5ms[480] = { + 9.752475122178133e-08, 6.413568706385488e-07, 1.888722582859778e-06, 4.370037451432268e-06, 8.850535239285388e-06, + 1.640976145163547e-05, 2.852654713353143e-05, 4.717577700625728e-05, 7.493695610161539e-05, 1.151138634046934e-04, + 1.718640547726665e-04, 2.503364524287818e-04, 3.568147253529307e-04, 4.988636346654247e-04, 6.854750052598100e-04, + 9.272095051506971e-04, 1.236329983123574e-03, 1.626921748932395e-03, 2.114994893578391e-03, 2.718563554424897e-03, + 3.457696944351759e-03, 4.354536997897421e-03, 5.433277651003014e-03, 6.720101073517573e-03, 8.243066622086374e-03, + 1.003194888027514e-02, 1.211802190514137e-02, 1.453378770448280e-02, 1.731264802301458e-02, 2.048851971150478e-02, + 2.409539527917081e-02, 2.816685167069475e-02, 3.273551184443837e-02, 3.783246533188810e-02, 4.348665559839211e-02, + 4.972424366422929e-02, 5.656795903921283e-02, 6.403645052356303e-02, 7.214365077720192e-02, 8.089816969852329e-02, + 9.030273251800713e-02, 1.003536790358444e-01, 1.110405405506510e-01, 1.223457106767086e-01, 1.342442253757111e-01, + 1.467036660932157e-01, 1.596841978637899e-01, 1.731387516273307e-01, 1.870133568030685e-01, 2.012476264477750e-01, + 2.157753931632489e-01, 2.305254894308376e-01, 2.454226613848142e-01, 2.603886003668338e-01, 2.753430721265570e-01, + 2.902051194568206e-01, 3.048943105839568e-01, 3.193320029709852e-01, 3.334425905036104e-01, 3.471547014476447e-01, + 3.604024000326147e-01, 3.731263195417857e-01, 3.852742256277580e-01, 3.968020335005454e-01, 4.076742901287472e-01, + 4.178645650568324e-01, 4.273556452755667e-01, 4.361395400809099e-01, 4.442173028452789e-01, 4.515986821559811e-01, + 4.583016198658067e-01, 4.643516178635941e-01, 4.697809986240601e-01, 4.746280867221525e-01, 4.789363394414859e-01, + 4.827534543679447e-01, 4.861304804889396e-01, 4.891209569144257e-01, 4.917801000389275e-01, 4.941640559535466e-01, + 4.963292304037445e-01, 4.983317038070890e-01, 5.002267340435251e-01, 5.020683451596181e-01, 5.039089960260009e-01, + 5.057993195650324e-01, 5.077879205925190e-01, 5.099212187075181e-01, 5.122433220684072e-01, 5.147959182947806e-01, + 5.176181700509677e-01, 5.207466049576202e-01, 5.242149921562288e-01, 5.280542009005510e-01, 5.322920397381714e-01, + 5.369530779485470e-01, 5.420584537149585e-01, 5.476256758552612e-01, 5.536684276931489e-01, 5.601963827419005e-01, + 5.672150422730262e-01, 5.747256045798048e-01, 5.827248748908062e-01, 5.912052235447917e-01, 6.001545983308831e-01, + 6.095565949599409e-01, 6.193905875944715e-01, 6.296319193412947e-01, 6.402521506992933e-01, 6.512193622254838e-01, + 6.624985061836945e-01, 6.740518006968909e-01, 6.858391589448801e-01, 6.978186452298805e-01, 7.099469492625143e-01, + 7.221798697869513e-01, 7.344727986533678e-01, 7.467811966479000e-01, 7.590610527959840e-01, 7.712693194564819e-01, + 7.833643163120154e-01, 7.953060973228134e-01, 8.070567758283893e-01, 8.185808042273020e-01, 8.298452060049231e-01, + 8.408197592685507e-01, 8.514771323358515e-01, 8.617929732481214e-01, 8.717459562819760e-01, 8.813177895502246e-01, + 8.904931885580764e-01, 8.992598210679454e-01, 9.076082287937692e-01, 9.155317312832600e-01, 9.230263168675006e-01, + 9.300905248019673e-01, 9.367253217576155e-01, 9.429339747337118e-01, 9.487219213595656e-01, 9.540966375393273e-01, + 9.590675015747306e-01, 9.636456533576906e-01, 9.678438470101040e-01, 9.716762954761368e-01, 9.751585060165801e-01, + 9.783071062524560e-01, 9.811396612648455e-01, 9.836744831733611e-01, 9.859304354792453e-01, 9.879267351759304e-01, + 9.896827561287711e-01, 9.912178374656364e-01, 9.925511006920656e-01, 9.937012789694025e-01, 9.946865615154821e-01, + 9.955244554643670e-01, 9.962316668199601e-01, 9.968240014222112e-01, 9.973162861697706e-01, 9.977223101520583e-01, + 9.980547848638137e-01, 9.983253223174189e-01, 9.985444296291865e-01, 9.987215185204544e-01, 9.988649281201196e-01, + 9.989819594562657e-01, 9.990789200557365e-01, 9.991611771110095e-01, 9.992332177094652e-01, 9.992987146446982e-01, + 9.993605963440879e-01, 9.994211194587087e-01, 9.994819426820254e-01, 9.995442004050701e-01, 9.996085748889234e-01, + 9.996753657478641e-01, 9.997445556919270e-01, 9.998158716802928e-01, 9.998888409489480e-01, 9.999628437059447e-01, + 1.000037122530308e+00, 1.000110932111342e+00, 1.000183434550577e+00, 1.000253775458271e+00, 1.000321131235573e+00, + 1.000384720523657e+00, 1.000443814718821e+00, 1.000497747347372e+00, 1.000545922137548e+00, 1.000587819673348e+00, + 1.000623002564305e+00, 1.000651119113520e+00, 1.000671905511154e+00, 1.000685186620367e+00, 1.000690875455855e+00, + 1.000688971480779e+00, 1.000679557865722e+00, 1.000662797863287e+00, 1.000638930454792e+00, 1.000608265421794e+00, + 1.000571177986086e+00, 1.000528103148456e+00, 1.000479529839953e+00, 1.000425994980975e+00, 1.000368077524065e+00, + 1.000306392536921e+00, 1.000241585363485e+00, 1.000174325883803e+00, 1.000105302878071e+00, 1.000035218487335e+00, + 9.999647827529677e-01, 9.998947082094627e-01, 9.998257045004189e-01, 9.997584729859116e-01, 9.996937013107159e-01, + 9.996320579071534e-01, 9.995741864134795e-01, 9.995206999987033e-01, 9.994721755972762e-01, 9.994291480719714e-01, + 9.993921043401182e-01, 9.993614775166697e-01, 9.993376411467469e-01, 9.993209036195655e-01, 9.993115028741053e-01, + 9.993096015235072e-01, 9.993152825388751e-01, 9.993285456427281e-01, 9.993493045667127e-01, 9.993773853262324e-01, + 9.994125256556279e-01, 9.994543757308175e-01, 9.995025002817920e-01, 9.995563821653024e-01, 9.996154274293025e-01, + 9.996789718565903e-01, 9.997462889273712e-01, 9.998165990914856e-01, 9.998890801932255e-01, 9.999628788477228e-01, + 1.000037122530308e+00, 1.000110932111343e+00, 1.000183434550578e+00, 1.000253775458273e+00, 1.000321131235574e+00, + 1.000384720523658e+00, 1.000443814718822e+00, 1.000497747347373e+00, 1.000545922137550e+00, 1.000587819673349e+00, + 1.000623002564306e+00, 1.000651119113521e+00, 1.000671905511155e+00, 1.000685186620368e+00, 1.000690875455855e+00, + 1.000688971480779e+00, 1.000679557865721e+00, 1.000662797863286e+00, 1.000638930454791e+00, 1.000608265421792e+00, + 1.000571177986083e+00, 1.000528103148453e+00, 1.000479529839950e+00, 1.000425994980971e+00, 1.000368077524061e+00, + 1.000306392536917e+00, 1.000241585363480e+00, 1.000174325883798e+00, 1.000105302878066e+00, 1.000035218487330e+00, + 9.999647827529627e-01, 9.998947082094576e-01, 9.998257045004140e-01, 9.997584729859067e-01, 9.996937013107114e-01, + 9.996320579071492e-01, 9.995741864134757e-01, 9.995206999987001e-01, 9.994721755972732e-01, 9.994291480719688e-01, + 9.993921043401160e-01, 9.993614775166682e-01, 9.993376411467459e-01, 9.993209036195649e-01, 9.993115028741050e-01, + 9.993096015235075e-01, 9.993152825388757e-01, 9.993285456427290e-01, 9.993493045667138e-01, 9.993773853262338e-01, + 9.994125256556294e-01, 9.994543757308189e-01, 9.995025002817937e-01, 9.995563821653038e-01, 9.996154274293039e-01, + 9.996789718565914e-01, 9.997462889273723e-01, 9.998165990914865e-01, 9.998890801932260e-01, 9.999628788477231e-01, + 1.000037087385911e+00, 1.000110692813570e+00, 1.000182706868929e+00, 1.000252041323928e+00, 1.000317522732163e+00, + 1.000377862440740e+00, 1.000431621330905e+00, 1.000477167056245e+00, 1.000512623941274e+00, 1.000535816073234e+00, + 1.000544204364164e+00, 1.000534818530052e+00, 1.000504185023504e+00, 1.000448251960702e+00, 1.000362312003691e+00, + 1.000240924003935e+00, 1.000077833997232e+00, 9.998658958833085e-01, 9.995969918486358e-01, 9.992619523233789e-01, + 9.988504750288640e-01, 9.983510424973004e-01, 9.977508373579080e-01, 9.970356547108338e-01, 9.961898110802319e-01, + 9.951960497774461e-01, 9.940354430376489e-01, 9.926872920341389e-01, 9.911290268265915e-01, 9.893361094467528e-01, + 9.872819446267991e-01, 9.849378040627681e-01, 9.822727714796871e-01, 9.792537170020328e-01, 9.758453102910697e-01, + 9.720100824436398e-01, 9.677085466217928e-01, 9.628993866974633e-01, 9.575397217975740e-01, 9.515854525300023e-01, + 9.449916919338839e-01, 9.377132809663818e-01, 9.297053848015243e-01, 9.209241625967119e-01, 9.113274999097554e-01, + 9.008757898394824e-01, 8.895327463959180e-01, 8.772662317107712e-01, 8.640490775465693e-01, 8.498598811668777e-01, + 8.346837559540076e-01, 8.185130181287622e-01, 8.013477924378186e-01, 7.831965216140859e-01, 7.640763666675557e-01, + 7.440134875182273e-01, 7.230431960387166e-01, 7.012099761451619e-01, 6.785673680876833e-01, 6.551777164863924e-01, + 6.311117838899523e-01, 6.064482336696789e-01, 5.812729878873076e-01, 5.556784673902739e-01, 5.297627228142773e-01, + 5.036284664469868e-01, 4.773820160836825e-01, 4.511321631520609e-01, 4.249889785709717e-01, 3.990625711023555e-01, + 3.734618144045748e-01, 3.482930606136814e-01, 3.236588600361913e-01, 2.996567083459001e-01, 2.763778443910257e-01, + 2.539061231327225e-01, 2.323169891052670e-01, 2.116765758470110e-01, 1.920409557494601e-01, 1.734555625129627e-01, + 1.559548047768156e-01, 1.395618845278644e-01, 1.242888277448971e-01, 1.101367277067382e-01, 9.709619389909366e-02, + 8.514799199591219e-02, 7.426385348588532e-02, 6.440742764829473e-02, 5.553534414838273e-02, 4.759835178173250e-02, + 4.054249795560948e-02, 3.431031430250281e-02, 2.884197618951215e-02, 2.407640752522409e-02, 1.995230681955070e-02, + 1.640907554818694e-02, 1.338763515624311e-02, 1.083112419588716e-02, 8.685471885106049e-03, 6.899848624541457e-03, + 5.426997611391803e-03, 4.223454598964128e-03, 3.249665071710221e-03, 2.470009678121166e-03, 1.852749750240329e-03, + 1.369905213535462e-03, 9.970772330834560e-04, 7.132276282050243e-04, 5.004264891539459e-04, 3.435786103798425e-04, + 2.301383718361825e-04, 1.498216022111699e-04, 9.432178886435202e-05, 5.703679621983551e-05, 3.281105011319028e-05, + 1.769696765784037e-05, 8.738278469978569e-06, 3.776770390150926e-06, 1.282520060393973e-06, 1.950213832061108e-07, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; + +const LC3_FLOAT MDCT_HRA_WINDOW_960_5ms[960] = { + 6.895487963711672e-08, 2.315162529310440e-07, 5.044776791712418e-07, 9.307951082662299e-07, 1.563406927329763e-06, + 2.467387587537570e-06, 3.721891688909285e-06, 5.422241751611354e-06, 7.682193559629735e-06, 1.063638764371401e-05, + 1.444299034054517e-05, 1.928652559405143e-05, 2.538089690430043e-05, 3.297259712577839e-05, 4.234410206521111e-05, + 5.381744200626993e-05, 6.775794339454556e-05, 8.457813095885401e-05, 1.047417785352287e-04, 1.287680948104183e-04, + 1.572360281259058e-04, 1.907886723956216e-04, 2.301377541053808e-04, 2.760681782947526e-04, 3.294426093879363e-04, + 3.912060607548454e-04, 4.623904649625926e-04, 5.441191948366056e-04, 6.376115037051945e-04, 7.441868515669874e-04, + 8.652690824124538e-04, 1.002390416563642e-03, 1.157195220684898e-03, 1.331443517075892e-03, 1.527014193000520e-03, + 1.745907870144461e-03, 1.990249393843025e-03, 2.262289901491620e-03, 2.564408429555132e-03, 2.899113018840483e-03, + 3.269041278198808e-03, 3.676960367589013e-03, 4.125766362471570e-03, 4.618482962817473e-03, 5.158259511618939e-03, + 5.748368289680850e-03, 6.392201055659471e-03, 7.093264802800713e-03, 7.855176706615627e-03, 8.681658240816716e-03, + 9.576528442223354e-03, 1.054369630902618e-02, 1.158715232077375e-02, 1.271095907270489e-02, 1.391924102158781e-02, + 1.521617334503430e-02, 1.660596992132020e-02, 1.809287044204954e-02, 1.968112667553175e-02, 2.137498790448110e-02, + 2.317868556757386e-02, 2.509641714048705e-02, 2.713232929826755e-02, 2.929050040721149e-02, 3.157492240084053e-02, + 3.398948210100576e-02, 3.653794205159846e-02, 3.922392093875195e-02, 4.205087367774323e-02, 4.502207125299418e-02, + 4.814058040358271e-02, 5.140924325245049e-02, 5.483065698298122e-02, 5.840715367176064e-02, 6.214078039106200e-02, + 6.603327969885861e-02, 7.008607063789310e-02, 7.430023036845897e-02, 7.867647656201358e-02, 8.321515068447660e-02, + 8.791620229900704e-02, 9.277917451814051e-02, 9.780319073433394e-02, 1.029869427561657e-01, 1.083286804746118e-01, + 1.138262031799212e-01, 1.194768526446087e-01, 1.252775080819347e-01, 1.312245830819321e-01, 1.373140246185531e-01, + 1.435413142118472e-01, 1.499014713182564e-01, 1.563890590101503e-01, 1.629981919926660e-01, 1.697225469918130e-01, + 1.765553755327395e-01, 1.834895191111025e-01, 1.905174267437600e-01, 1.976311748676255e-01, 2.048224895376239e-01, + 2.120827708564311e-01, 2.194031195502149e-01, 2.267743655861134e-01, 2.341870987088808e-01, 2.416317007561807e-01, + 2.490983795946414e-01, 2.565772045021951e-01, 2.640581428066213e-01, 2.715310975758094e-01, 2.789859461422405e-01, + 2.864125792327671e-01, 2.938009404650995e-01, 3.011410659646723e-01, 3.084231238498945e-01, 3.156374533302977e-01, + 3.227746031609007e-01, 3.298253691972654e-01, 3.367808307992519e-01, 3.436323858374391e-01, 3.503717840645000e-01, + 3.569912187918766e-01, 3.634832564154323e-01, 3.698408960767766e-01, 3.760576237679591e-01, 3.821274200069671e-01, + 3.880447807855012e-01, 3.938047354128900e-01, 3.994028614671444e-01, 4.048352968090768e-01, 4.100987486186185e-01, + 4.151904994338012e-01, 4.201084101968628e-01, 4.248509203362432e-01, 4.294170449371775e-01, 4.338063690767977e-01, + 4.380190394218450e-01, 4.420557532080190e-01, 4.459177447394188e-01, 4.496067695642793e-01, 4.531250864990879e-01, + 4.564754376870322e-01, 4.596610268884718e-01, 4.626854962106256e-01, 4.655529014908880e-01, 4.682676865530477e-01, + 4.708346565582213e-01, 4.732589506724937e-01, 4.755460142711474e-01, 4.777015708950234e-01, 4.797315941680489e-01, + 4.816422798764418e-01, 4.834400183996339e-01, 4.851313676707616e-01, 4.867230268307342e-01, 4.882218107246894e-01, + 4.896346253731921e-01, 4.909684445331096e-01, 4.922302874448856e-01, 4.934271978441982e-01, 4.945662242969564e-01, + 4.956544018975119e-01, 4.966987353511036e-01, 4.977061834431282e-01, 4.986836448801200e-01, 4.996379454705324e-01, + 5.005758265977741e-01, 5.015039349236500e-01, 5.024288132476197e-01, 5.033568924361829e-01, 5.042944843274677e-01, + 5.052477755087517e-01, 5.062228218592734e-01, 5.072255437473754e-01, 5.082617217696771e-01, 5.093369929206453e-01, + 5.104568470835084e-01, 5.116266237378464e-01, 5.128515087852868e-01, 5.141365314023457e-01, 5.154865608384481e-01, + 5.169063030872989e-01, 5.184002973708743e-01, 5.199729123871391e-01, 5.216283422849100e-01, 5.233706023418981e-01, + 5.252035243345977e-01, 5.271307516011422e-01, 5.291557338103311e-01, 5.312817214614957e-01, 5.335117601505942e-01, + 5.358486846476969e-01, 5.382951128397399e-01, 5.408534395999681e-01, 5.435258306517384e-01, 5.463142164993156e-01, + 5.492202865018518e-01, 5.522454831689516e-01, 5.553909967570894e-01, 5.586577602456578e-01, 5.620464447697334e-01, + 5.655574555837481e-01, 5.691909286262941e-01, 5.729467277513715e-01, 5.768244426856284e-01, 5.808233877646608e-01, + 5.849426014943921e-01, 5.891808469760642e-01, 5.935366132255452e-01, 5.980081174096790e-01, 6.025933080143371e-01, + 6.072898689508155e-01, 6.120952245993402e-01, 6.170065457808297e-01, 6.220207566407007e-01, 6.271345424215810e-01, + 6.323443580952387e-01, 6.376464378179791e-01, 6.430368051681870e-01, 6.485112841196261e-01, 6.540655106995645e-01, + 6.596949452767820e-01, 6.653948854210106e-01, 6.711604792723804e-01, 6.769867393569574e-01, 6.828685567824609e-01, + 6.888007157467320e-01, 6.947779082904570e-01, 7.007947492250285e-01, 7.068457911662456e-01, 7.129255396047764e-01, + 7.190284679449507e-01, 7.251490324444848e-01, 7.312816869891655e-01, 7.374208976383266e-01, 7.435611568791312e-01, + 7.496969975302182e-01, 7.558230062381704e-01, 7.619338365135002e-01, 7.680242212564293e-01, 7.740889847266266e-01, + 7.801230539152502e-01, 7.861214692821104e-01, 7.920793948254449e-01, 7.979921274567765e-01, 8.038551056583576e-01, + 8.096639174059964e-01, 8.154143073453887e-01, 8.211021832154612e-01, 8.267236215176270e-01, 8.322748724351863e-01, + 8.377523640123131e-01, 8.431527056071227e-01, 8.484726906381246e-01, 8.537092986478724e-01, 8.588596967118024e-01, + 8.639212402239919e-01, 8.688914730948750e-01, 8.737681273987250e-01, 8.785491225109360e-01, 8.832325637767802e-01, + 8.878167407543193e-01, 8.923001250745454e-01, 8.966813679615423e-01, 9.009592974545819e-01, 9.051329153725320e-01, + 9.092013940588521e-01, 9.131640729428008e-01, 9.170204549493250e-01, 9.207702027865553e-01, 9.244131351359152e-01, + 9.279492227657136e-01, 9.313785845847777e-01, 9.347014836483568e-01, 9.379183231242151e-01, 9.410296422227417e-01, + 9.440361120910473e-01, 9.469385316675432e-01, 9.497378234904927e-01, 9.524350294515523e-01, 9.550313064834267e-01, + 9.575279221695473e-01, 9.599262502631155e-01, 9.622277661029504e-01, 9.644340419143761e-01, 9.665467419847689e-01, + 9.685676177053684e-01, 9.704985024734301e-01, 9.723413064517235e-01, 9.740980111855780e-01, 9.757706640811671e-01, + 9.773613727522825e-01, 9.788722992464219e-01, 9.803056541645230e-01, 9.816636906919504e-01, 9.829486985613498e-01, + 9.841629979706453e-01, 9.853089334816367e-01, 9.863888679264271e-01, 9.874051763501168e-01, 9.883602400189044e-01, + 9.892564405229114e-01, 9.900961540026917e-01, 9.908817455275554e-01, 9.916155636525488e-01, 9.922999351792323e-01, + 9.929371601433686e-01, 9.935295070502858e-01, 9.940792083761523e-01, 9.945884563506685e-01, 9.950593990338927e-01, + 9.954941366970841e-01, 9.958947185146307e-01, 9.962631395714290e-01, 9.966013381874510e-01, 9.969111935588407e-01, + 9.971945237126117e-01, 9.974530837700109e-01, 9.976885645118487e-01, 9.979025912375212e-01, 9.980967229081705e-01, + 9.982724515633580e-01, 9.984312019997783e-01, 9.985743316998982e-01, 9.987031309979628e-01, 9.988188234704969e-01, + 9.989225665382725e-01, 9.990154522666818e-01, 9.990985083514453e-01, 9.991726992767055e-01, 9.992389276326772e-01, + 9.992980355801597e-01, 9.993508064493677e-01, 9.993979664606926e-01, 9.994401865550964e-01, 9.994780843219823e-01, + 9.995122260124369e-01, 9.995431286258258e-01, 9.995712620577665e-01, 9.995970512975859e-01, 9.996208786634017e-01, + 9.996430860630976e-01, 9.996639772695648e-01, 9.996838201987696e-01, 9.997028491794524e-01, 9.997212672035590e-01, + 9.997392481469061e-01, 9.997569389500512e-01, 9.997744617498990e-01, 9.997919159532207e-01, 9.998093802440068e-01, + 9.998269145173621e-01, 9.998445617335565e-01, 9.998623496867628e-01, 9.998802926840086e-01, 9.998983931308962e-01, + 9.999166430217568e-01, 9.999350253331990e-01, 9.999535153223720e-01, 9.999720817407219e-01, 9.999906880869937e-01, + 1.000009287384094e+00, 1.000027834887701e+00, 1.000046300263356e+00, 1.000064628855653e+00, 1.000082766500416e+00, + 1.000100659718907e+00, 1.000118255908114e+00, 1.000135503526064e+00, 1.000152352271145e+00, 1.000168753254485e+00, + 1.000184659164501e+00, 1.000200024422812e+00, 1.000214805330795e+00, 1.000228960206152e+00, 1.000242449508936e+00, + 1.000255235956603e+00, 1.000267284627736e+00, 1.000278563054190e+00, 1.000289041301502e+00, 1.000298692037510e+00, + 1.000307490589210e+00, 1.000315414987954e+00, 1.000322446003211e+00, 1.000328567165139e+00, 1.000333764776314e+00, + 1.000338027913029e+00, 1.000341348416600e+00, 1.000343720875191e+00, 1.000345142596687e+00, 1.000345613573201e+00, + 1.000345136437780e+00, 1.000343716413940e+00, 1.000341361258634e+00, 1.000338081199265e+00, 1.000333888865364e+00, + 1.000328799215526e+00, 1.000322829460192e+00, 1.000315998980821e+00, 1.000308329246033e+00, 1.000299843725172e+00, + 1.000290567799819e+00, 1.000280528673668e+00, 1.000269755281177e+00, 1.000258278195373e+00, 1.000246129535135e+00, + 1.000233342872247e+00, 1.000219953138478e+00, 1.000205996532915e+00, 1.000191510429709e+00, 1.000176533286394e+00, + 1.000161104552890e+00, 1.000145264581248e+00, 1.000129054536203e+00, 1.000112516306544e+00, 1.000095692417284e+00, + 1.000078625942615e+00, 1.000061360419570e+00, 1.000043939762341e+00, 1.000026408177143e+00, 1.000008810077537e+00, + 9.999911900000854e-01, 9.999735925202352e-01, 9.999560621682817e-01, 9.999386433453050e-01, 9.999213802389432e-01, + 9.999043167388835e-01, 9.998874963519558e-01, 9.998709621167259e-01, 9.998547565174905e-01, 9.998389213976104e-01, + 9.998234978721111e-01, 9.998085262395175e-01, 9.997940458929213e-01, 9.997800952302701e-01, 9.997667115639504e-01, + 9.997539310297094e-01, 9.997417884950316e-01, 9.997303174671138e-01, 9.997195500006013e-01, 9.997095166053042e-01, + 9.997002461541395e-01, 9.996917657915899e-01, 9.996841008429919e-01, 9.996772747250358e-01, 9.996713088578647e-01, + 9.996662225792015e-01, 9.996620330610038e-01, 9.996587552291110e-01, 9.996564016864400e-01, 9.996549826402822e-01, + 9.996545058342721e-01, 9.996549764856241e-01, 9.996563972282545e-01, 9.996587680623811e-01, 9.996620863112294e-01, + 9.996663465854424e-01, 9.996715407557830e-01, 9.996776579346981e-01, 9.996846844672899e-01, 9.996926039321870e-01, + 9.997013971527812e-01, 9.997110422192300e-01, 9.997215145215743e-01, 9.997327867942448e-01, 9.997448291721661e-01, + 9.997576092585791e-01, 9.997710922046226e-01, 9.997852408006243e-01, 9.998000155789548e-01, 9.998153749282088e-01, + 9.998312752183693e-01, 9.998476709365326e-01, 9.998645148326526e-01, 9.998817580746910e-01, 9.998993504124509e-01, + 9.999172403493095e-01, 9.999353753209654e-01, 9.999537018802583e-01, 9.999721658870582e-01, 9.999907127021609e-01, + 1.000009287384094e+00, 1.000027834887701e+00, 1.000046300263357e+00, 1.000064628855654e+00, 1.000082766500417e+00, + 1.000100659718908e+00, 1.000118255908115e+00, 1.000135503526065e+00, 1.000152352271146e+00, 1.000168753254487e+00, + 1.000184659164503e+00, 1.000200024422814e+00, 1.000214805330797e+00, 1.000228960206154e+00, 1.000242449508937e+00, + 1.000255235956604e+00, 1.000267284627737e+00, 1.000278563054191e+00, 1.000289041301503e+00, 1.000298692037512e+00, + 1.000307490589211e+00, 1.000315414987955e+00, 1.000322446003212e+00, 1.000328567165140e+00, 1.000333764776315e+00, + 1.000338027913030e+00, 1.000341348416601e+00, 1.000343720875191e+00, 1.000345142596688e+00, 1.000345613573201e+00, + 1.000345136437780e+00, 1.000343716413940e+00, 1.000341361258634e+00, 1.000338081199264e+00, 1.000333888865363e+00, + 1.000328799215525e+00, 1.000322829460191e+00, 1.000315998980820e+00, 1.000308329246031e+00, 1.000299843725170e+00, + 1.000290567799817e+00, 1.000280528673665e+00, 1.000269755281174e+00, 1.000258278195370e+00, 1.000246129535132e+00, + 1.000233342872243e+00, 1.000219953138474e+00, 1.000205996532911e+00, 1.000191510429705e+00, 1.000176533286390e+00, + 1.000161104552886e+00, 1.000145264581243e+00, 1.000129054536198e+00, 1.000112516306539e+00, 1.000095692417279e+00, + 1.000078625942610e+00, 1.000061360419565e+00, 1.000043939762336e+00, 1.000026408177138e+00, 1.000008810077532e+00, + 9.999911900000801e-01, 9.999735925202301e-01, 9.999560621682765e-01, 9.999386433453000e-01, 9.999213802389382e-01, + 9.999043167388785e-01, 9.998874963519510e-01, 9.998709621167211e-01, 9.998547565174859e-01, 9.998389213976059e-01, + 9.998234978721068e-01, 9.998085262395136e-01, 9.997940458929174e-01, 9.997800952302665e-01, 9.997667115639468e-01, + 9.997539310297062e-01, 9.997417884950285e-01, 9.997303174671109e-01, 9.997195500005988e-01, 9.997095166053018e-01, + 9.997002461541374e-01, 9.996917657915880e-01, 9.996841008429901e-01, 9.996772747250343e-01, 9.996713088578635e-01, + 9.996662225792006e-01, 9.996620330610030e-01, 9.996587552291103e-01, 9.996564016864398e-01, 9.996549826402821e-01, + 9.996545058342721e-01, 9.996549764856244e-01, 9.996563972282549e-01, 9.996587680623816e-01, 9.996620863112300e-01, + 9.996663465854433e-01, 9.996715407557840e-01, 9.996776579346992e-01, 9.996846844672912e-01, 9.996926039321883e-01, + 9.997013971527825e-01, 9.997110422192316e-01, 9.997215145215756e-01, 9.997327867942462e-01, 9.997448291721677e-01, + 9.997576092585806e-01, 9.997710922046239e-01, 9.997852408006256e-01, 9.998000155789563e-01, 9.998153749282102e-01, + 9.998312752183705e-01, 9.998476709365336e-01, 9.998645148326535e-01, 9.998817580746918e-01, 9.998993504124516e-01, + 9.999172403493102e-01, 9.999353753209660e-01, 9.999537018802587e-01, 9.999721658870584e-01, 9.999907127021610e-01, + 1.000009262768464e+00, 1.000027750736626e+00, 1.000046113687940e+00, 1.000064278821780e+00, 1.000082169071538e+00, + 1.000099702238537e+00, 1.000116790156982e+00, 1.000133337763978e+00, 1.000149242061725e+00, 1.000164390968527e+00, + 1.000178662057694e+00, 1.000191921184823e+00, 1.000204021005123e+00, 1.000214799383556e+00, 1.000224077701589e+00, + 1.000231659065357e+00, 1.000237326420850e+00, 1.000240840582544e+00, 1.000241938182520e+00, 1.000240329547572e+00, + 1.000235696512191e+00, 1.000227690175467e+00, 1.000215928609961e+00, 1.000199994530463e+00, 1.000179432930259e+00, + 1.000153748692032e+00, 1.000122404179984e+00, 1.000084816818973e+00, 1.000040356665695e+00, 9.999883439759534e-01, + 9.999280467710976e-01, 9.998586784056549e-01, 9.997793951371076e-01, 9.996892936976876e-01, 9.995874088670188e-01, + 9.994727110434261e-01, 9.993441038107910e-01, 9.992004214970033e-01, 9.990404267193601e-01, 9.988628079116455e-01, + 9.986661768272946e-01, 9.984490660128014e-01, 9.982099262455740e-01, 9.979471239307242e-01, 9.976589384518300e-01, + 9.973435594715599e-01, 9.969990841792483e-01, 9.966235144840385e-01, 9.962147541541155e-01, 9.957706059048574e-01, + 9.952887684414411e-01, 9.947668334645193e-01, 9.942022826511501e-01, 9.935924846270409e-01, 9.929346919504907e-01, + 9.922260381330554e-01, 9.914635347268980e-01, 9.906440685140006e-01, 9.897643988377397e-01, 9.888211551228012e-01, + 9.878108346347950e-01, 9.867298005362246e-01, 9.855742803004703e-01, 9.843403645500459e-01, 9.830240063894612e-01, + 9.816210213063771e-01, 9.801270877173017e-01, 9.785377482356147e-01, 9.768484117402024e-01, 9.750543563222487e-01, + 9.731507331856758e-01, 9.711325715733536e-01, 9.689947847863860e-01, 9.667321773575633e-01, 9.643394534324848e-01, + 9.618112264029069e-01, 9.591420298267040e-01, 9.563263296575538e-01, 9.533585377951747e-01, 9.502330269539270e-01, + 9.469441468339291e-01, 9.434862415648529e-01, 9.398536683783788e-01, 9.360408174512334e-01, 9.320421328469384e-01, + 9.278521344711611e-01, 9.234654409430395e-01, 9.188767932732427e-01, 9.140810792290244e-01, 9.090733582572249e-01, + 9.038488868282046e-01, 8.984031440571518e-01, 8.927318574541139e-01, 8.868310286504967e-01, 8.806969589476717e-01, + 8.743262745326578e-01, 8.677159512065934e-01, 8.608633384737868e-01, 8.537661828424618e-01, 8.464226501927783e-01, + 8.388313470732423e-01, 8.309913407930509e-01, 8.229021781851953e-01, 8.145639029231079e-01, 8.059770712821837e-01, + 7.971427662465509e-01, 7.880626098708469e-01, 7.787387738164395e-01, 7.691739879913762e-01, 7.593715472332762e-01, + 7.493353159843403e-01, 7.390697309175267e-01, 7.285798014827035e-01, 7.178711083511555e-01, 7.069497997461519e-01, + 6.958225856563154e-01, 6.844967299372567e-01, 6.729800403152869e-01, 6.612808563149986e-01, 6.494080351400781e-01, + 6.373709355438772e-01, 6.251793997330287e-01, 6.128437333537300e-01, 6.003746836162993e-01, 5.877834156192006e-01, + 5.750814869390165e-01, 5.622808205578382e-01, 5.493936762043069e-01, 5.364326201891255e-01, 5.234104938203454e-01, + 5.103403804881693e-01, 4.972355715134865e-01, 4.841095308589323e-01, 4.709758588060189e-01, 4.578482547068641e-01, + 4.447404789243264e-01, 4.316663140799624e-01, 4.186395257351866e-01, 4.056738226373441e-01, 3.927828166690819e-01, + 3.799799826463771e-01, 3.672786181177968e-01, 3.546918033248968e-01, 3.422323614910038e-01, 3.299128196128071e-01, + 3.177453699359932e-01, 3.057418323024091e-01, 2.939136175616680e-01, 2.822716922444745e-01, 2.708265446979701e-01, + 2.595881528848133e-01, 2.485659540472639e-01, 2.377688164349652e-01, 2.272050132902212e-01, 2.168821992771410e-01, + 2.068073895309444e-01, 1.969869414909128e-01, 1.874265396648929e-01, 1.781311834549869e-01, 1.691051781531976e-01, + 1.603521291925451e-01, 1.518749397137918e-01, 1.436758114807520e-01, 1.357562491485994e-01, 1.281170678600890e-01, + 1.207584041146470e-01, 1.136797298253828e-01, 1.068798694497608e-01, 1.003570200514591e-01, 9.410877412434678e-02, + 8.813214498499827e-02, 8.242359451816077e-02, 7.697906304046008e-02, 7.179400103167609e-02, 6.686340247035585e-02, + 6.218183950151154e-02, 5.774349815872721e-02, 5.354221486116098e-02, 4.957151340757950e-02, 4.582464219454362e-02, + 4.229461139394613e-02, 3.897422983601720e-02, 3.585614135733534e-02, 3.293286038897012e-02, 3.019680657726779e-02, + 2.764033824859545e-02, 2.525578454921406e-02, 2.303547611198478e-02, 2.097177412248857e-02, 1.905709767802756e-02, + 1.728394935359176e-02, 1.564493890895436e-02, 1.413280509038132e-02, 1.274043549881785e-02, 1.146088451369467e-02, + 1.028738927756386e-02, 9.213383761543762e-03, 8.232510944970423e-03, 7.338633154694566e-03, 6.525840620123105e-03, + 5.788458309403464e-03, 5.121051120120478e-03, 4.518427504569718e-03, 3.975641615147556e-03, 3.487994059724770e-03, + 3.051031360120983e-03, 2.660544209048234e-03, 2.312564622222088e-03, 2.003362082825875e-03, 1.729438775235064e-03, + 1.487524003938835e-03, 1.274567892006584e-03, 1.087734451306357e-03, 9.243941140548951e-04, 7.821158122256320e-04, + 6.586586879186365e-04, 5.519635140582476e-04, 4.601439007796695e-04, 3.814773586413279e-04, 3.143962853984603e-04, + 2.574789385355991e-04, 2.094404511189233e-04, 1.691239438292752e-04, 1.354917813061114e-04, 1.076170162029800e-04, + 8.467505965565773e-05, 6.593561222250244e-05, 5.075488479887568e-05, 3.856813455801580e-05, 2.888253665201353e-05, + 2.127040823889544e-05, 1.536279740228267e-05, 1.084344570939908e-05, 7.443129506680882e-06, 4.934381529209004e-06, + 3.126590786650604e-06, 1.861474073153740e-06, 1.008902130957542e-06, 4.630128105556161e-07, 1.379047824504878e-07, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; + +const LC3_FLOAT MDCT_HRA_WINDOW_480_10ms[960] = { + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 9.423411645757145e-08, 6.198383813913816e-07, 1.826038044753334e-06, 4.227415544684874e-06, 8.568221371240009e-06, + 1.590138306691229e-05, 2.767384916372097e-05, 4.582461489197476e-05, 7.289566442148343e-05, 1.121553337189409e-04, + 1.677330226576781e-04, 2.447635817250988e-04, 3.495390594774230e-04, 4.896648355656373e-04, 6.742165007916612e-04, + 9.138932038423809e-04, 1.221162590096684e-03, 1.610391938745493e-03, 2.097959688543948e-03, 2.702341257534836e-03, + 3.444162934209273e-03, 4.346217670272292e-03, 5.433436858058855e-03, 6.732812643305091e-03, 8.273266014983896e-03, + 1.008545682987358e-02, 1.220153306437313e-02, 1.465481792555360e-02, 1.747943497487382e-02, 2.070987309036685e-02, + 2.438049487743156e-02, 2.852499398840518e-02, 3.317580867440409e-02, 3.836350071222914e-02, 4.411611056397528e-02, + 5.045850117560903e-02, 5.741170414223051e-02, 6.499228300404947e-02, 7.321172913556540e-02, 8.207590600577601e-02, + 9.158455748369454e-02, 1.017308953166495e-01, 1.125012799073065e-01, 1.238750070616895e-01, 1.358242114920720e-01, + 1.483138955678087e-01, 1.613020891609740e-01, 1.747401434927874e-01, 1.885731587242474e-01, 2.027405417335493e-01, + 2.171766871750067e-01, 2.318117716158385e-01, 2.465726473968904e-01, 2.613838199586506e-01, 2.761684898079396e-01, + 2.908496381590925e-01, 3.053511336415384e-01, 3.195988363856895e-01, 3.335216753280081e-01, 3.470526747443392e-01, + 3.601299968134419e-01, 3.726979341699064e-01, 3.847073300820699e-01, 3.961165192918680e-01, 4.068917464693262e-01, + 4.170075357150957e-01, 4.264469007050540e-01, 4.352013996719531e-01, 4.432710380854631e-01, 4.506640257151909e-01, + 4.573963985795680e-01, 4.634915197715306e-01, 4.689794761564862e-01, 4.738963903364035e-01, 4.782836689638748e-01, + 4.821872093925473e-01, 4.856565867140006e-01, 4.887442424370954e-01, 4.915046944332492e-01, 4.939937853618382e-01, + 4.962679837116828e-01, 4.983837480011794e-01, 5.003969607669508e-01, 5.023624349677376e-01, 5.043334915837460e-01, + 5.063616037481589e-01, 5.084960999306821e-01, 5.107839166820760e-01, 5.132693903594975e-01, 5.159940771247666e-01, + 5.189965912996581e-01, 5.223124537547313e-01, 5.259739442166247e-01, 5.300099539725758e-01, 5.344458381774531e-01, + 5.393032695777062e-01, 5.446000977350559e-01, 5.503502195833738e-01, 5.565634682679432e-01, 5.632455276465002e-01, + 5.703978795909497e-01, 5.780177903898996e-01, 5.860983412324646e-01, 5.946285060985402e-01, 6.035932785464501e-01, + 6.129738470263359e-01, 6.227478165890419e-01, 6.328894733093686e-01, 6.433700864704220e-01, 6.541582425999274e-01, + 6.652202048172945e-01, 6.765202906248624e-01, 6.880212612236103e-01, 6.996847156078869e-01, 7.114714830467992e-01, + 7.233420080447298e-01, 7.352567224482216e-01, 7.471763999968595e-01, 7.590624892758133e-01, 7.708774216994878e-01, + 7.825848918282421e-01, 7.941501079877761e-01, 8.055400118211323e-01, 8.167234660553659e-01, 8.276714104070468e-01, + 8.383569861788307e-01, 8.487556307051457e-01, 8.588451433758131e-01, 8.686057254837016e-01, 8.780199965830640e-01, + 8.870729903819699e-01, 8.957521333967015e-01, 9.040472096414102e-01, 9.119503144919421e-01, 9.194558005383104e-01, + 9.265602177306744e-01, 9.332622494524668e-01, 9.395626453655078e-01, 9.454641510291475e-01, 9.509714334776073e-01, + 9.560910012334918e-01, 9.608311167251793e-01, 9.652016988316350e-01, 9.692142133449947e-01, 9.728815495300325e-01, + 9.762178816434048e-01, 9.792385151909874e-01, 9.819597187561544e-01, 9.843985433157453e-01, 9.865726319613708e-01, + 9.885000237614154e-01, 9.901989560579394e-01, 9.916876697497727e-01, 9.929842220610799e-01, 9.941063109595989e-01, + 9.950711148231832e-01, 9.958951502269355e-01, 9.965941499123417e-01, 9.971829621771531e-01, 9.976754721515079e-01, + 9.980845447462318e-01, 9.984219884986877e-01, 9.986985391068631e-01, 9.989238611254968e-01, 9.991065660804971e-01, + 9.992542451163898e-01, 9.993735142030505e-01, 9.994700698738658e-01, 9.995487534360048e-01, 9.996136215806155e-01, + 9.996680213292980e-01, 9.997146672907700e-01, 9.997557192777461e-01, 9.997928584573587e-01, 9.998273603841155e-01, + 9.998601634925650e-01, 9.998919319028886e-01, 9.999231117133845e-01, 9.999539803782231e-01, 9.999846913144619e-01, + 1.000015271687402e+00, 1.000045768313827e+00, 1.000076123719886e+00, 1.000106243781657e+00, 1.000136035347070e+00, + 1.000165406619359e+00, 1.000194267530612e+00, 1.000222530102796e+00, 1.000250108793741e+00, 1.000276920825814e+00, + 1.000302886495191e+00, 1.000327929459891e+00, 1.000351977005012e+00, 1.000374960283849e+00, 1.000396814533868e+00, + 1.000417479266803e+00, 1.000436898432418e+00, 1.000455020555724e+00, 1.000471798847772e+00, 1.000487191290310e+00, + 1.000501160694917e+00, 1.000513674737357e+00, 1.000524705968167e+00, 1.000534231800605e+00, 1.000542234477265e+00, + 1.000548701016775e+00, 1.000553623142091e+00, 1.000556997191966e+00, 1.000558824017243e+00, 1.000559108863603e+00, + 1.000557861242456e+00, 1.000555094791586e+00, 1.000550827127188e+00, 1.000545079688822e+00, 1.000537877578802e+00, + 1.000529249397403e+00, 1.000519227075235e+00, 1.000507845704000e+00, 1.000495143366764e+00, 1.000481160968755e+00, + 1.000465942069620e+00, 1.000449532717920e+00, 1.000431981288574e+00, 1.000413338323831e+00, 1.000393656378250e+00, + 1.000372989868060e+00, 1.000351394925194e+00, 1.000328929256167e+00, 1.000305652005906e+00, 1.000281623626542e+00, + 1.000256905751110e+00, 1.000231561072014e+00, 1.000205653224064e+00, 1.000179246671831e+00, 1.000152406601017e+00, + 1.000125198813461e+00, 1.000097689625410e+00, 1.000069945768613e+00, 1.000042034293768e+00, 1.000014022475844e+00, + 9.999859777207831e-01, 9.999579674730398e-01, 9.999300591234549e-01, 9.999023199169207e-01, 9.998748168593201e-01, + 9.998476166232155e-01, 9.998207854517803e-01, 9.997943890604891e-01, 9.997684925361024e-01, 9.997431602325028e-01, + 9.997184556629950e-01, 9.996944413886967e-01, 9.996711789027117e-01, 9.996487285098250e-01, 9.996271492015102e-01, + 9.996064985261154e-01, 9.995868324541498e-01, 9.995682052386838e-01, 9.995506692709443e-01, 9.995342749312822e-01, + 9.995190704357798e-01, 9.995051016788571e-01, 9.994924120723486e-01, 9.994810423816121e-01, 9.994710305593550e-01, + 9.994624115779566e-01, 9.994552172611834e-01, 9.994494761163015e-01, 9.994452131676952e-01, 9.994424497931953e-01, + 9.994412035644367e-01, 9.994414880926250e-01, 9.994433128811957e-01, 9.994466831869019e-01, 9.994515998909221e-01, + 9.994580593816230e-01, 9.994660534506217e-01, 9.994755692038015e-01, 9.994865889889091e-01, 9.994990903413156e-01, + 9.995130459494618e-01, 9.995284236414108e-01, 9.995451863938154e-01, 9.995632923644638e-01, 9.995826949494031e-01, + 9.996033428654485e-01, 9.996251802586674e-01, 9.996481468392096e-01, 9.996721780425870e-01, 9.996972052172600e-01, + 9.997231558380996e-01, 9.997499537450264e-01, 9.997775194058337e-01, 9.998057702019313e-01, 9.998346207354666e-01, + 9.998639831560286e-01, 9.998937675048852e-01, 9.999238820744936e-01, 9.999542337808154e-01, 9.999847285458191e-01, + 1.000015271687393e+00, 1.000045768313818e+00, 1.000076123719878e+00, 1.000106243781648e+00, 1.000136035347061e+00, + 1.000165406619350e+00, 1.000194267530604e+00, 1.000222530102788e+00, 1.000250108793733e+00, 1.000276920825807e+00, + 1.000302886495184e+00, 1.000327929459883e+00, 1.000351977005006e+00, 1.000374960283843e+00, 1.000396814533862e+00, + 1.000417479266798e+00, 1.000436898432413e+00, 1.000455020555719e+00, 1.000471798847767e+00, 1.000487191290306e+00, + 1.000501160694914e+00, 1.000513674737354e+00, 1.000524705968165e+00, 1.000534231800603e+00, 1.000542234477263e+00, + 1.000548701016774e+00, 1.000553623142090e+00, 1.000556997191965e+00, 1.000558824017242e+00, 1.000559108863603e+00, + 1.000557861242456e+00, 1.000555094791587e+00, 1.000550827127188e+00, 1.000545079688823e+00, 1.000537877578803e+00, + 1.000529249397404e+00, 1.000519227075236e+00, 1.000507845704002e+00, 1.000495143366766e+00, 1.000481160968757e+00, + 1.000465942069622e+00, 1.000449532717922e+00, 1.000431981288576e+00, 1.000413338323833e+00, 1.000393656378252e+00, + 1.000372989868062e+00, 1.000351394925196e+00, 1.000328929256169e+00, 1.000305652005908e+00, 1.000281623626544e+00, + 1.000256905751112e+00, 1.000231561072016e+00, 1.000205653224065e+00, 1.000179246671832e+00, 1.000152406601018e+00, + 1.000125198813462e+00, 1.000097689625411e+00, 1.000069945768614e+00, 1.000042034293768e+00, 1.000014022475844e+00, + 9.999859777207829e-01, 9.999579674730393e-01, 9.999300591234543e-01, 9.999023199169199e-01, 9.998748168593190e-01, + 9.998476166232144e-01, 9.998207854517789e-01, 9.997943890604876e-01, 9.997684925361007e-01, 9.997431602325010e-01, + 9.997184556629931e-01, 9.996944413886946e-01, 9.996711789027095e-01, 9.996487285098227e-01, 9.996271492015080e-01, + 9.996064985261129e-01, 9.995868324541474e-01, 9.995682052386815e-01, 9.995506692709419e-01, 9.995342749312801e-01, + 9.995190704357777e-01, 9.995051016788550e-01, 9.994924120723468e-01, 9.994810423816103e-01, 9.994710305593536e-01, + 9.994624115779553e-01, 9.994552172611824e-01, 9.994494761163009e-01, 9.994452131676944e-01, 9.994424497931950e-01, + 9.994412035644368e-01, 9.994414880926255e-01, 9.994433128811966e-01, 9.994466831869030e-01, 9.994515998909239e-01, + 9.994580593816250e-01, 9.994660534506239e-01, 9.994755692038041e-01, 9.994865889889122e-01, 9.994990903413189e-01, + 9.995130459494656e-01, 9.995284236414153e-01, 9.995451863938203e-01, 9.995632923644688e-01, 9.995826949494085e-01, + 9.996033428654543e-01, 9.996251802586735e-01, 9.996481468392161e-01, 9.996721780425940e-01, 9.996972052172670e-01, + 9.997231558381070e-01, 9.997499537450341e-01, 9.997775194058416e-01, 9.998057702019393e-01, 9.998346207354748e-01, + 9.998639831560371e-01, 9.998937675048939e-01, 9.999238820745020e-01, 9.999542337808240e-01, 9.999847285458278e-01, + 1.000015271687402e+00, 1.000045768313827e+00, 1.000076123719886e+00, 1.000106243781657e+00, 1.000136035347070e+00, + 1.000165406619359e+00, 1.000194267530612e+00, 1.000222530102796e+00, 1.000250108793741e+00, 1.000276920825814e+00, + 1.000302886495191e+00, 1.000327929459890e+00, 1.000351977005012e+00, 1.000374960283849e+00, 1.000396814533868e+00, + 1.000417479266803e+00, 1.000436898432418e+00, 1.000455020555724e+00, 1.000471798847772e+00, 1.000487191290310e+00, + 1.000501160694917e+00, 1.000513674737357e+00, 1.000524705968167e+00, 1.000534231800605e+00, 1.000542234477265e+00, + 1.000548701016775e+00, 1.000553623142091e+00, 1.000556997191966e+00, 1.000558824017243e+00, 1.000559108863603e+00, + 1.000557861242456e+00, 1.000555094791586e+00, 1.000550827127188e+00, 1.000545079688822e+00, 1.000537877578802e+00, + 1.000529249397403e+00, 1.000519227075234e+00, 1.000507845704000e+00, 1.000495143366764e+00, 1.000481160968755e+00, + 1.000465942069620e+00, 1.000449532717920e+00, 1.000431981288574e+00, 1.000413338323831e+00, 1.000393656378250e+00, + 1.000372989868060e+00, 1.000351394925194e+00, 1.000328929256167e+00, 1.000305652005906e+00, 1.000281623626542e+00, + 1.000256905751111e+00, 1.000231561072014e+00, 1.000205653224064e+00, 1.000179246671831e+00, 1.000152406601017e+00, + 1.000125198813461e+00, 1.000097689625410e+00, 1.000069945768614e+00, 1.000042034293768e+00, 1.000014022475844e+00, + 9.999859777207832e-01, 9.999579674730399e-01, 9.999300591234550e-01, 9.999023199169208e-01, 9.998748168593202e-01, + 9.998476166232156e-01, 9.998207854517805e-01, 9.997943890604892e-01, 9.997684925361026e-01, 9.997431602325029e-01, + 9.997184556629951e-01, 9.996944413886968e-01, 9.996711789027117e-01, 9.996487285098250e-01, 9.996271492015103e-01, + 9.996064985261155e-01, 9.995868324541498e-01, 9.995682052386839e-01, 9.995506692709443e-01, 9.995342749312823e-01, + 9.995190704357798e-01, 9.995051016788571e-01, 9.994924120723486e-01, 9.994810423816120e-01, 9.994710305593552e-01, + 9.994624115779566e-01, 9.994552172611834e-01, 9.994494761163015e-01, 9.994452131676951e-01, 9.994424497931953e-01, + 9.994412035644367e-01, 9.994414880926250e-01, 9.994433128811958e-01, 9.994466831869019e-01, 9.994515998909221e-01, + 9.994580593816230e-01, 9.994660534506217e-01, 9.994755692038015e-01, 9.994865889889089e-01, 9.994990903413155e-01, + 9.995130459494618e-01, 9.995284236414110e-01, 9.995451863938154e-01, 9.995632923644640e-01, 9.995826949494031e-01, + 9.996033428654485e-01, 9.996251802586674e-01, 9.996481468392096e-01, 9.996721780425870e-01, 9.996972052172600e-01, + 9.997231558380997e-01, 9.997499537450264e-01, 9.997775194058337e-01, 9.998057702019313e-01, 9.998346207354665e-01, + 9.998639831560286e-01, 9.998937675048852e-01, 9.999238820744936e-01, 9.999542337808154e-01, 9.999847285458191e-01, + 1.000015234454879e+00, 1.000045514887559e+00, 1.000075353237462e+00, 1.000104407768116e+00, 1.000132214556229e+00, + 1.000158143563050e+00, 1.000181349852841e+00, 1.000200717764093e+00, 1.000214798354899e+00, 1.000221740822748e+00, + 1.000219218852980e+00, 1.000204353032496e+00, 1.000173630567007e+00, 1.000122823551604e+00, 1.000046906963284e+00, + 9.999399773758973e-01, 9.997951731574873e-01, 9.996045966188434e-01, 9.993592382687311e-01, 9.990489030278769e-01, + 9.986621379953039e-01, 9.981861611823875e-01, 9.976067905662288e-01, 9.969083728962124e-01, 9.960737119427251e-01, + 9.950839963248127e-01, 9.939187277034516e-01, 9.925556509742455e-01, 9.909706891139552e-01, 9.891378864826104e-01, + 9.870293655848442e-01, 9.846153034530920e-01, 9.818639348132027e-01, 9.787415898998961e-01, 9.752127750773143e-01, + 9.712403041791187e-01, 9.667854876397981e-01, 9.618083850218845e-01, 9.562681244917907e-01, 9.501232902622440e-01, + 9.433323761603356e-01, 9.358543004959359e-01, 9.276489745130293e-01, 9.186779141170132e-01, 9.089048824643602e-01, + 8.982965495078461e-01, 8.868231537804969e-01, 8.744591515805539e-01, 8.611838392360764e-01, 8.469819351830896e-01, + 8.318441100567543e-01, 8.157674547284579e-01, 7.987558780821055e-01, 7.808204281831013e-01, 7.619795322485697e-01, + 7.422591523986999e-01, 7.216928555056540e-01, 7.003217965330363e-01, 6.781946155731466e-01, 6.553672493579565e-01, + 6.319026583753357e-01, 6.078704709095413e-01, 5.833465453994711e-01, 5.584124525334641e-01, 5.331548785464441e-01, + 5.076649513306994e-01, 4.820374912962984e-01, 4.563701895024020e-01, 4.307627165039317e-01, 4.053157666856800e-01, + 3.801300446346412e-01, 3.553052023472212e-01, 3.309387387548210e-01, 3.071248760994941e-01, 2.839534309593199e-01, + 2.615087010038701e-01, 2.398683915856861e-01, 2.191026087292818e-01, 1.992729466284019e-01, 1.804316980820018e-01, + 1.626212151220100e-01, 1.458734442426148e-01, 1.302096560997370e-01, 1.156403834405376e-01, 1.021655736434582e-01, + 8.977495404596501e-02, 7.844859976518601e-02, 6.815768558157265e-02, 5.886539624579484e-02, 5.052796378898961e-02, + 4.309579643342800e-02, 3.651466171052548e-02, 3.072688641085486e-02, 2.567253786455677e-02, 2.129055449466347e-02, + 1.751979822585132e-02, 1.430000675209340e-02, 1.157262945800897e-02, 9.281536579910191e-03, 7.373596677207363e-03, + 5.799122432483531e-03, 4.512189056010577e-03, 3.470833055336534e-03, 2.637141819806632e-03, 1.977246386436426e-03, + 1.461230953040205e-03, 1.062973263413438e-03, 7.599299954798238e-04, 5.328808285940163e-04, 3.656440417062249e-04, + 2.447753867250028e-04, 1.592606718286519e-04, 1.002110509628055e-04, 6.056851356108083e-05, 3.482755929907460e-05, + 1.877757338165862e-05, 9.269020516017977e-06, 4.005234147116555e-06, 1.359891615054068e-06, 2.067694412143206e-07, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; + +const LC3_FLOAT MDCT_HRA_WINDOW_960_10ms[1920] = { + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 6.663107991278473e-08, 2.237239208214098e-07, 4.875418283123564e-07, 8.996727135884617e-07, 1.511418282137696e-06, + 2.385908181307981e-06, 3.600021534325060e-06, 5.246458929559746e-06, 7.435999429480928e-06, 1.029995277226023e-05, + 1.399281202683861e-05, 1.869510977726803e-05, 2.461647918005920e-05, 3.199891951615131e-05, 4.112026404149671e-05, + 5.229784600131515e-05, 6.589235661010597e-05, 8.231188661821365e-05, 1.020161407958678e-04, 1.255208122795613e-04, + 1.534021012578998e-04, 1.863013599410517e-04, 2.249298431778123e-04, 2.700735414768832e-04, 3.225980705756125e-04, + 3.834535891028970e-04, 4.536797133272969e-04, 5.344103954917697e-04, 6.268787298389575e-04, 7.324216481524320e-04, + 8.524844645071808e-04, 9.886252269645022e-04, 1.142518832190136e-03, 1.315960857447457e-03, 1.510871063146860e-03, + 1.729296518144556e-03, 1.973414299303950e-03, 2.245533716484770e-03, 2.548098014131402e-03, 2.883685501012940e-03, + 3.255010060441685e-03, 3.664920994479873e-03, 4.116402157249738e-03, 4.612570334499312e-03, 5.156672829053223e-03, + 5.752084214696966e-03, 6.402302224405338e-03, 7.110942742626702e-03, 7.881733875566514e-03, 8.718509078064964e-03, + 9.625199320718177e-03, 1.060582428632988e-02, 1.166448259057781e-02, 1.280534102790626e-02, 1.403262285008227e-02, + 1.535059509154052e-02, 1.676355496255211e-02, 1.827581533833950e-02, 1.989168937947954e-02, 2.161547432623578e-02, + 2.345143451678970e-02, 2.540378368664082e-02, 2.747666661366220e-02, 2.967414018037076e-02, 3.200015393184128e-02, + 3.445853021429810e-02, 3.705294398569962e-02, 3.978690239552551e-02, 4.266372423642605e-02, 4.568651937534197e-02, + 4.885816827608890e-02, 5.218130172917755e-02, 5.565828090775238e-02, 5.929117787093344e-02, 6.308175663749782e-02, + 6.703145495369379e-02, 7.114136687902073e-02, 7.541222631299167e-02, 7.984439158421140e-02, 8.443783122053150e-02, + 8.919211101557852e-02, 9.410638250258946e-02, 9.917937294123873e-02, 1.044093769170137e-01, 1.097942496457128e-01, + 1.153314020678296e-01, 1.210177978089837e-01, 1.268499520732061e-01, 1.328239325258333e-01, 1.389353622120686e-01, + 1.451794245459895e-01, 1.515508703929904e-01, 1.580440272564225e-01, 1.646528105666080e-01, 1.713707370575420e-01, + 1.781909402035578e-01, 1.851061876750831e-01, 1.921089007594860e-01, 1.991911756799545e-01, 2.063448067325118e-01, + 2.135613111487021e-01, 2.208319555793100e-01, 2.281477840827779e-01, 2.354996474908733e-01, 2.428782340136974e-01, + 2.502741009364257e-01, 2.576777072513037e-01, 2.650794470604564e-01, 2.724696835780986e-01, 2.798387835547953e-01, + 2.871771519416024e-01, 2.944752666082350e-01, 3.017237129269402e-01, 3.089132180325088e-01, 3.160346845688595e-01, + 3.230792237339257e-01, 3.300381874371329e-01, 3.369031993875939e-01, 3.436661849362722e-01, 3.503193995017128e-01, + 3.568555192112148e-01, 3.632675601002685e-01, 3.695489358061075e-01, 3.756935099828519e-01, 3.816956001322418e-01, + 3.875499962002574e-01, 3.932519766094684e-01, 3.987973219750102e-01, 4.041823264714043e-01, 4.094038068104935e-01, + 4.144591088030795e-01, 4.193461114921915e-01, 4.240632288619702e-01, 4.286094091423471e-01, 4.329841317457969e-01, + 4.371874018882834e-01, 4.412197429619175e-01, 4.450821867417134e-01, 4.487762615229755e-01, 4.523039782991779e-01, + 4.556678151025579e-01, 4.588706996409412e-01, 4.619159903744011e-01, 4.648074561841559e-01, 4.675492547935124e-01, + 4.701459101065887e-01, 4.726022886349306e-01, 4.749235751849055e-01, 4.771152479798792e-01, 4.791830533906173e-01, + 4.811329804451050e-01, 4.829712352850382e-01, 4.847042157306455e-01, 4.863384861083030e-01, 4.878807524866530e-01, + 4.893378384567565e-01, 4.907166615802867e-01, 4.920242106170628e-01, 4.932675236294833e-01, 4.944536670468351e-01, + 4.955897157572258e-01, 4.966827342792363e-01, 4.977397590495528e-01, 4.987677818470457e-01, 4.997737343582849e-01, + 5.007644738745453e-01, 5.017467700962179e-01, 5.027272930074345e-01, 5.037126017718407e-01, 5.047091345900308e-01, + 5.057231994503223e-01, 5.067609656974670e-01, 5.078284563386384e-01, 5.089315410026908e-01, 5.100759294672467e-01, + 5.112671656686335e-01, 5.125106221119896e-01, 5.138114946028988e-01, 5.151747972275419e-01, 5.166053575154047e-01, + 5.181078117268841e-01, 5.196866002174090e-01, 5.213459628397580e-01, 5.230899343568223e-01, 5.249223398478975e-01, + 5.268467901024086e-01, 5.288666770055838e-01, 5.309851689306879e-01, 5.332052061618728e-01, 5.355294963802417e-01, + 5.379605102532377e-01, 5.405004771737987e-01, 5.431513812007881e-01, 5.459149572559273e-01, 5.487926876348163e-01, + 5.517857988905945e-01, 5.548952591484511e-01, 5.581217759075547e-01, 5.614657943841375e-01, 5.649274964455743e-01, + 5.685068001804389e-01, 5.722033601438381e-01, 5.760165683110121e-01, 5.799455557653441e-01, 5.839891951397580e-01, + 5.881461038230944e-01, 5.924146479356704e-01, 5.967929470708762e-01, 6.012788797925822e-01, 6.058700898713546e-01, + 6.105639932361040e-01, 6.153577856119751e-01, 6.202484508099709e-01, 6.252327696291247e-01, 6.303073293279928e-01, + 6.354685336188206e-01, 6.407126131349797e-01, 6.460356363201389e-01, 6.514335206861067e-01, 6.569020443853303e-01, + 6.624368580436263e-01, 6.680334967987880e-01, 6.736873924912369e-01, 6.793938859538112e-01, 6.851482393490396e-01, + 6.909456485038137e-01, 6.967812551932001e-01, 7.026501593271524e-01, 7.085474309960862e-01, 7.144681223336159e-01, + 7.204072791571976e-01, 7.263599523499238e-01, 7.323212089493037e-01, 7.382861429114533e-01, 7.442498855217515e-01, + 7.502076154256456e-01, 7.561545682559222e-01, 7.620860458353852e-01, 7.679974249364871e-01, 7.738841655820752e-01, + 7.797418188739772e-01, 7.855660343387494e-01, 7.913525667824293e-01, 7.970972826487233e-01, 8.027961658775241e-01, + 8.084453232632074e-01, 8.140409893145931e-01, 8.195795306209357e-01, 8.250574497306905e-01, 8.304713885521608e-01, + 8.358181312874381e-01, 8.410946069132281e-01, 8.462978912242891e-01, 8.514252084571686e-01, 8.564739325137894e-01, + 8.614415878060635e-01, 8.663258497442113e-01, 8.711245448926651e-01, 8.758356508184248e-01, 8.804572956574126e-01, + 8.849877574247438e-01, 8.894254630948657e-01, 8.937689874771898e-01, 8.980170519121489e-01, 9.021685228115252e-01, + 9.062224100654551e-01, 9.101778653366538e-01, 9.140341802602550e-01, 9.177907845650995e-01, 9.214472441295430e-01, + 9.250032589817625e-01, 9.284586612513364e-01, 9.318134130755062e-01, 9.350676044601444e-01, 9.382214510920930e-01, + 9.412752920963378e-01, 9.442295877284584e-01, 9.470849169901138e-01, 9.498419751530142e-01, 9.525015711749794e-01, + 9.550646249903935e-01, 9.575321646566392e-01, 9.599053233380030e-01, 9.621853361091064e-01, 9.643735365611265e-01, + 9.664713531959190e-01, 9.684803055955929e-01, 9.704020003580881e-01, 9.722381267927611e-01, 9.739904523738324e-01, + 9.756608179536774e-01, 9.772511327422573e-01, 9.787633690633392e-01, 9.801995569024828e-01, 9.815617782659093e-01, + 9.828521613732500e-01, 9.840728747106564e-01, 9.852261209738314e-01, 9.863141309330354e-01, 9.873391572540936e-01, + 9.883034683107520e-01, 9.892093420244598e-01, 9.900590597677280e-01, 9.908549003667192e-01, 9.915991342376211e-01, + 9.922940176897662e-01, 9.929417874263897e-01, 9.935446552714569e-01, 9.941048031482164e-01, 9.946243783321176e-01, + 9.951054889975415e-01, 9.955502000745265e-01, 9.959605294283782e-01, 9.963384443718103e-01, 9.966858585161255e-01, + 9.970046289649677e-01, 9.972965538513794e-01, 9.975633702163375e-01, 9.978067522246161e-01, 9.980283097117545e-01, + 9.982295870540839e-01, 9.984120623522111e-01, 9.985771469170162e-01, 9.987261850461071e-01, 9.988604540777616e-01, + 9.989811647086401e-01, 9.990894615609515e-01, 9.991864239842999e-01, 9.992730670770456e-01, 9.993503429117423e-01, + 9.994191419489804e-01, 9.994802946237851e-01, 9.995345730885834e-01, 9.995826930966561e-01, 9.996253160099111e-01, + 9.996630509147824e-01, 9.996964568300586e-01, 9.997260449905023e-01, 9.997522811902100e-01, 9.997755881698448e-01, + 9.997963480321130e-01, 9.998149046701891e-01, 9.998315661942099e-01, 9.998466073415005e-01, 9.998602718567984e-01, + 9.998727748295070e-01, 9.998843049758280e-01, 9.998950268545727e-01, 9.999050830064863e-01, 9.999145960080379e-01, + 9.999236704318017e-01, 9.999323947068164e-01, 9.999408428735685e-01, 9.999490762295546e-01, 9.999571448627051e-01, + 9.999650890712967e-01, 9.999729406705412e-01, 9.999807241886484e-01, 9.999884579652744e-01, 9.999961552850937e-01, + 1.000003818641721e+00, 1.000011453001950e+00, 1.000019078522643e+00, 1.000026689281996e+00, 1.000034279373492e+00, + 1.000041842912049e+00, 1.000049374040126e+00, 1.000056866933785e+00, 1.000064315808680e+00, 1.000071714925990e+00, + 1.000079058598250e+00, 1.000086341195099e+00, 1.000093557148926e+00, 1.000100700960395e+00, 1.000107767203853e+00, + 1.000114750532603e+00, 1.000121645684037e+00, 1.000128447484626e+00, 1.000135150854742e+00, 1.000141750813332e+00, + 1.000148242482408e+00, 1.000154621091371e+00, 1.000160881981147e+00, 1.000167020608141e+00, 1.000173032547996e+00, + 1.000178913499161e+00, 1.000184659286256e+00, 1.000190265863238e+00, 1.000195729316362e+00, 1.000201045866939e+00, + 1.000206211873884e+00, 1.000211223836059e+00, 1.000216078394407e+00, 1.000220772333881e+00, 1.000225302585160e+00, + 1.000229666226172e+00, 1.000233860483401e+00, 1.000237882733002e+00, 1.000241730501714e+00, 1.000245401467578e+00, + 1.000248893460465e+00, 1.000252204462412e+00, 1.000255332607784e+00, 1.000258276183243e+00, 1.000261033627556e+00, + 1.000263603531226e+00, 1.000265984635963e+00, 1.000268175833992e+00, 1.000270176167217e+00, 1.000271984826231e+00, + 1.000273601149186e+00, 1.000275024620537e+00, 1.000276254869646e+00, 1.000277291669272e+00, 1.000278134933949e+00, + 1.000278784718248e+00, 1.000279241214938e+00, 1.000279504753058e+00, 1.000279575795894e+00, 1.000279454938873e+00, + 1.000279142907386e+00, 1.000278640554535e+00, 1.000277948858822e+00, 1.000277068921773e+00, 1.000276001965517e+00, + 1.000274749330316e+00, 1.000273312472054e+00, 1.000271692959694e+00, 1.000269892472703e+00, 1.000267912798451e+00, + 1.000265755829598e+00, 1.000263423561457e+00, 1.000260918089352e+00, 1.000258241605975e+00, 1.000255396398729e+00, + 1.000252384847089e+00, 1.000249209419954e+00, 1.000245872673023e+00, 1.000242377246174e+00, 1.000238725860863e+00, + 1.000234921317548e+00, 1.000230966493118e+00, 1.000226864338370e+00, 1.000222617875491e+00, 1.000218230195586e+00, + 1.000213704456221e+00, 1.000209043879012e+00, 1.000204251747240e+00, 1.000199331403501e+00, 1.000194286247397e+00, + 1.000189119733258e+00, 1.000183835367906e+00, 1.000178436708454e+00, 1.000172927360150e+00, 1.000167310974248e+00, + 1.000161591245930e+00, 1.000155771912258e+00, 1.000149856750174e+00, 1.000143849574523e+00, 1.000137754236130e+00, + 1.000131574619904e+00, 1.000125314642979e+00, 1.000118978252895e+00, 1.000112569425805e+00, 1.000106092164726e+00, + 1.000099550497809e+00, 1.000092948476653e+00, 1.000086290174636e+00, 1.000079579685283e+00, 1.000072821120651e+00, + 1.000066018609750e+00, 1.000059176296973e+00, 1.000052298340563e+00, 1.000045388911081e+00, 1.000038452189909e+00, + 1.000031492367753e+00, 1.000024513643172e+00, 1.000017520221111e+00, 1.000010516311443e+00, 1.000003506127529e+00, + 9.999964938847642e-01, 9.999894837991481e-01, 9.999824800858419e-01, 9.999754869577321e-01, 9.999685086239848e-01, + 9.999615492886049e-01, 9.999546131489783e-01, 9.999477043944101e-01, 9.999408272046536e-01, 9.999339857484195e-01, + 9.999271841818784e-01, 9.999204266471391e-01, 9.999137172707154e-01, 9.999070601619628e-01, 9.999004594115060e-01, + 9.998939190896278e-01, 9.998874432446441e-01, 9.998810359012452e-01, 9.998747010588128e-01, 9.998684426896991e-01, + 9.998622647374855e-01, 9.998561711152009e-01, 9.998501657035072e-01, 9.998442523488513e-01, 9.998384348615825e-01, + 9.998327170140316e-01, 9.998271025385516e-01, 9.998215951255243e-01, 9.998161984213253e-01, 9.998109160262525e-01, + 9.998057514924167e-01, 9.998007083215891e-01, 9.997957899630165e-01, 9.997909998111978e-01, 9.997863412036158e-01, + 9.997818174184411e-01, 9.997774316721972e-01, 9.997731871173844e-01, 9.997690868400847e-01, 9.997651338575159e-01, + 9.997613311155714e-01, 9.997576814863203e-01, 9.997541877654884e-01, 9.997508526699078e-01, 9.997476788349500e-01, + 9.997446688119369e-01, 9.997418250655351e-01, 9.997391499711387e-01, 9.997366458122413e-01, 9.997343147777986e-01, + 9.997321589595916e-01, 9.997301803495896e-01, 9.997283808373202e-01, 9.997267622072430e-01, 9.997253261361446e-01, + 9.997240741905490e-01, 9.997230078241506e-01, 9.997221283752786e-01, 9.997214370643954e-01, 9.997209349916318e-01, + 9.997206231343719e-01, 9.997205023448855e-01, 9.997205733480192e-01, 9.997208367389500e-01, 9.997212929810099e-01, + 9.997219424035818e-01, 9.997227852000825e-01, 9.997238214260301e-01, 9.997250509972079e-01, 9.997264736879267e-01, + 9.997280891294001e-01, 9.997298968082279e-01, 9.997318960650045e-01, 9.997340860930513e-01, 9.997364659372833e-01, + 9.997390344932165e-01, 9.997417905061193e-01, 9.997447325703145e-01, 9.997478591286405e-01, 9.997511684720751e-01, + 9.997546587395272e-01, 9.997583279177997e-01, 9.997621738417346e-01, 9.997661941945379e-01, 9.997703865082921e-01, + 9.997747481646607e-01, 9.997792763957842e-01, 9.997839682853786e-01, 9.997888207700281e-01, 9.997938306406862e-01, + 9.997989945443773e-01, 9.998043089861064e-01, 9.998097703309746e-01, 9.998153748065003e-01, 9.998211185051531e-01, + 9.998269973870870e-01, 9.998330072830846e-01, 9.998391438977015e-01, 9.998454028126147e-01, 9.998517794901678e-01, + 9.998582692771129e-01, 9.998648674085433e-01, 9.998715690120116e-01, 9.998783691118356e-01, 9.998852626335712e-01, + 9.998922444086656e-01, 9.998993091792668e-01, 9.999064516031954e-01, 9.999136662590592e-01, 9.999209476515181e-01, + 9.999282902166716e-01, 9.999356883275767e-01, 9.999431362998797e-01, 9.999506283975492e-01, 9.999581588387069e-01, + 9.999657218015428e-01, 9.999733114303027e-01, 9.999809218413399e-01, 9.999885471292198e-01, 9.999961813728609e-01, + 1.000003818641712e+00, 1.000011453001941e+00, 1.000019078522634e+00, 1.000026689281987e+00, 1.000034279373484e+00, + 1.000041842912040e+00, 1.000049374040118e+00, 1.000056866933776e+00, 1.000064315808672e+00, 1.000071714925982e+00, + 1.000079058598242e+00, 1.000086341195091e+00, 1.000093557148918e+00, 1.000100700960387e+00, 1.000107767203845e+00, + 1.000114750532595e+00, 1.000121645684029e+00, 1.000128447484618e+00, 1.000135150854734e+00, 1.000141750813325e+00, + 1.000148242482401e+00, 1.000154621091364e+00, 1.000160881981140e+00, 1.000167020608134e+00, 1.000173032547989e+00, + 1.000178913499155e+00, 1.000184659286250e+00, 1.000190265863232e+00, 1.000195729316356e+00, 1.000201045866933e+00, + 1.000206211873878e+00, 1.000211223836054e+00, 1.000216078394402e+00, 1.000220772333876e+00, 1.000225302585155e+00, + 1.000229666226167e+00, 1.000233860483396e+00, 1.000237882732998e+00, 1.000241730501710e+00, 1.000245401467574e+00, + 1.000248893460461e+00, 1.000252204462409e+00, 1.000255332607781e+00, 1.000258276183240e+00, 1.000261033627553e+00, + 1.000263603531224e+00, 1.000265984635960e+00, 1.000268175833990e+00, 1.000270176167215e+00, 1.000271984826229e+00, + 1.000273601149185e+00, 1.000275024620536e+00, 1.000276254869644e+00, 1.000277291669271e+00, 1.000278134933948e+00, + 1.000278784718247e+00, 1.000279241214938e+00, 1.000279504753058e+00, 1.000279575795894e+00, 1.000279454938873e+00, + 1.000279142907386e+00, 1.000278640554536e+00, 1.000277948858822e+00, 1.000277068921773e+00, 1.000276001965517e+00, + 1.000274749330316e+00, 1.000273312472055e+00, 1.000271692959695e+00, 1.000269892472704e+00, 1.000267912798453e+00, + 1.000265755829599e+00, 1.000263423561458e+00, 1.000260918089354e+00, 1.000258241605976e+00, 1.000255396398731e+00, + 1.000252384847091e+00, 1.000249209419956e+00, 1.000245872673025e+00, 1.000242377246176e+00, 1.000238725860866e+00, + 1.000234921317550e+00, 1.000230966493120e+00, 1.000226864338372e+00, 1.000222617875493e+00, 1.000218230195589e+00, + 1.000213704456224e+00, 1.000209043879015e+00, 1.000204251747242e+00, 1.000199331403503e+00, 1.000194286247399e+00, + 1.000189119733260e+00, 1.000183835367908e+00, 1.000178436708457e+00, 1.000172927360152e+00, 1.000167310974250e+00, + 1.000161591245932e+00, 1.000155771912260e+00, 1.000149856750176e+00, 1.000143849574525e+00, 1.000137754236132e+00, + 1.000131574619906e+00, 1.000125314642981e+00, 1.000118978252897e+00, 1.000112569425807e+00, 1.000106092164727e+00, + 1.000099550497811e+00, 1.000092948476655e+00, 1.000086290174638e+00, 1.000079579685284e+00, 1.000072821120652e+00, + 1.000066018609751e+00, 1.000059176296974e+00, 1.000052298340564e+00, 1.000045388911082e+00, 1.000038452189910e+00, + 1.000031492367754e+00, 1.000024513643172e+00, 1.000017520221111e+00, 1.000010516311444e+00, 1.000003506127529e+00, + 9.999964938847641e-01, 9.999894837991480e-01, 9.999824800858417e-01, 9.999754869577318e-01, 9.999685086239841e-01, + 9.999615492886044e-01, 9.999546131489776e-01, 9.999477043944092e-01, 9.999408272046527e-01, 9.999339857484185e-01, + 9.999271841818773e-01, 9.999204266471379e-01, 9.999137172707140e-01, 9.999070601619615e-01, 9.999004594115044e-01, + 9.998939190896263e-01, 9.998874432446425e-01, 9.998810359012436e-01, 9.998747010588109e-01, 9.998684426896972e-01, + 9.998622647374836e-01, 9.998561711151988e-01, 9.998501657035050e-01, 9.998442523488493e-01, 9.998384348615804e-01, + 9.998327170140294e-01, 9.998271025385493e-01, 9.998215951255222e-01, 9.998161984213230e-01, 9.998109160262503e-01, + 9.998057514924145e-01, 9.998007083215869e-01, 9.997957899630143e-01, 9.997909998111957e-01, 9.997863412036135e-01, + 9.997818174184390e-01, 9.997774316721950e-01, 9.997731871173822e-01, 9.997690868400825e-01, 9.997651338575136e-01, + 9.997613311155693e-01, 9.997576814863183e-01, 9.997541877654863e-01, 9.997508526699059e-01, 9.997476788349481e-01, + 9.997446688119350e-01, 9.997418250655334e-01, 9.997391499711371e-01, 9.997366458122399e-01, 9.997343147777973e-01, + 9.997321589595902e-01, 9.997301803495884e-01, 9.997283808373191e-01, 9.997267622072419e-01, 9.997253261361438e-01, + 9.997240741905483e-01, 9.997230078241500e-01, 9.997221283752783e-01, 9.997214370643952e-01, 9.997209349916318e-01, + 9.997206231343722e-01, 9.997205023448859e-01, 9.997205733480196e-01, 9.997208367389504e-01, 9.997212929810105e-01, + 9.997219424035826e-01, 9.997227852000836e-01, 9.997238214260314e-01, 9.997250509972092e-01, 9.997264736879284e-01, + 9.997280891294021e-01, 9.997298968082300e-01, 9.997318960650067e-01, 9.997340860930538e-01, 9.997364659372859e-01, + 9.997390344932195e-01, 9.997417905061224e-01, 9.997447325703176e-01, 9.997478591286439e-01, 9.997511684720787e-01, + 9.997546587395311e-01, 9.997583279178037e-01, 9.997621738417388e-01, 9.997661941945423e-01, 9.997703865082966e-01, + 9.997747481646656e-01, 9.997792763957892e-01, 9.997839682853837e-01, 9.997888207700335e-01, 9.997938306406916e-01, + 9.997989945443829e-01, 9.998043089861125e-01, 9.998097703309806e-01, 9.998153748065066e-01, 9.998211185051595e-01, + 9.998269973870937e-01, 9.998330072830913e-01, 9.998391438977084e-01, 9.998454028126217e-01, 9.998517794901752e-01, + 9.998582692771203e-01, 9.998648674085506e-01, 9.998715690120191e-01, 9.998783691118432e-01, 9.998852626335790e-01, + 9.998922444086736e-01, 9.998993091792749e-01, 9.999064516032034e-01, 9.999136662590675e-01, 9.999209476515264e-01, + 9.999282902166798e-01, 9.999356883275852e-01, 9.999431362998885e-01, 9.999506283975580e-01, 9.999581588387155e-01, + 9.999657218015514e-01, 9.999733114303114e-01, 9.999809218413486e-01, 9.999885471292286e-01, 9.999961813728698e-01, + 1.000003818641721e+00, 1.000011453001950e+00, 1.000019078522643e+00, 1.000026689281996e+00, 1.000034279373492e+00, + 1.000041842912049e+00, 1.000049374040126e+00, 1.000056866933785e+00, 1.000064315808680e+00, 1.000071714925990e+00, + 1.000079058598250e+00, 1.000086341195099e+00, 1.000093557148926e+00, 1.000100700960395e+00, 1.000107767203853e+00, + 1.000114750532602e+00, 1.000121645684037e+00, 1.000128447484626e+00, 1.000135150854742e+00, 1.000141750813332e+00, + 1.000148242482408e+00, 1.000154621091371e+00, 1.000160881981147e+00, 1.000167020608141e+00, 1.000173032547996e+00, + 1.000178913499161e+00, 1.000184659286256e+00, 1.000190265863238e+00, 1.000195729316362e+00, 1.000201045866939e+00, + 1.000206211873884e+00, 1.000211223836059e+00, 1.000216078394407e+00, 1.000220772333881e+00, 1.000225302585160e+00, + 1.000229666226172e+00, 1.000233860483401e+00, 1.000237882733002e+00, 1.000241730501714e+00, 1.000245401467578e+00, + 1.000248893460465e+00, 1.000252204462412e+00, 1.000255332607784e+00, 1.000258276183243e+00, 1.000261033627556e+00, + 1.000263603531226e+00, 1.000265984635963e+00, 1.000268175833992e+00, 1.000270176167217e+00, 1.000271984826231e+00, + 1.000273601149187e+00, 1.000275024620537e+00, 1.000276254869646e+00, 1.000277291669272e+00, 1.000278134933949e+00, + 1.000278784718248e+00, 1.000279241214938e+00, 1.000279504753058e+00, 1.000279575795894e+00, 1.000279454938873e+00, + 1.000279142907386e+00, 1.000278640554535e+00, 1.000277948858822e+00, 1.000277068921773e+00, 1.000276001965517e+00, + 1.000274749330316e+00, 1.000273312472054e+00, 1.000271692959694e+00, 1.000269892472703e+00, 1.000267912798451e+00, + 1.000265755829598e+00, 1.000263423561457e+00, 1.000260918089352e+00, 1.000258241605975e+00, 1.000255396398729e+00, + 1.000252384847089e+00, 1.000249209419954e+00, 1.000245872673023e+00, 1.000242377246174e+00, 1.000238725860863e+00, + 1.000234921317548e+00, 1.000230966493118e+00, 1.000226864338370e+00, 1.000222617875491e+00, 1.000218230195586e+00, + 1.000213704456221e+00, 1.000209043879013e+00, 1.000204251747240e+00, 1.000199331403501e+00, 1.000194286247397e+00, + 1.000189119733258e+00, 1.000183835367906e+00, 1.000178436708454e+00, 1.000172927360150e+00, 1.000167310974248e+00, + 1.000161591245930e+00, 1.000155771912258e+00, 1.000149856750174e+00, 1.000143849574523e+00, 1.000137754236130e+00, + 1.000131574619904e+00, 1.000125314642979e+00, 1.000118978252895e+00, 1.000112569425805e+00, 1.000106092164726e+00, + 1.000099550497809e+00, 1.000092948476653e+00, 1.000086290174636e+00, 1.000079579685283e+00, 1.000072821120651e+00, + 1.000066018609750e+00, 1.000059176296973e+00, 1.000052298340563e+00, 1.000045388911081e+00, 1.000038452189909e+00, + 1.000031492367753e+00, 1.000024513643172e+00, 1.000017520221111e+00, 1.000010516311443e+00, 1.000003506127529e+00, + 9.999964938847643e-01, 9.999894837991482e-01, 9.999824800858421e-01, 9.999754869577322e-01, 9.999685086239848e-01, + 9.999615492886050e-01, 9.999546131489783e-01, 9.999477043944101e-01, 9.999408272046536e-01, 9.999339857484195e-01, + 9.999271841818784e-01, 9.999204266471392e-01, 9.999137172707154e-01, 9.999070601619630e-01, 9.999004594115060e-01, + 9.998939190896279e-01, 9.998874432446442e-01, 9.998810359012452e-01, 9.998747010588128e-01, 9.998684426896991e-01, + 9.998622647374856e-01, 9.998561711152009e-01, 9.998501657035073e-01, 9.998442523488514e-01, 9.998384348615826e-01, + 9.998327170140316e-01, 9.998271025385517e-01, 9.998215951255245e-01, 9.998161984213253e-01, 9.998109160262525e-01, + 9.998057514924167e-01, 9.998007083215890e-01, 9.997957899630168e-01, 9.997909998111979e-01, 9.997863412036158e-01, + 9.997818174184412e-01, 9.997774316721972e-01, 9.997731871173845e-01, 9.997690868400848e-01, 9.997651338575160e-01, + 9.997613311155714e-01, 9.997576814863203e-01, 9.997541877654884e-01, 9.997508526699078e-01, 9.997476788349500e-01, + 9.997446688119369e-01, 9.997418250655351e-01, 9.997391499711387e-01, 9.997366458122413e-01, 9.997343147777986e-01, + 9.997321589595916e-01, 9.997301803495896e-01, 9.997283808373202e-01, 9.997267622072429e-01, 9.997253261361446e-01, + 9.997240741905490e-01, 9.997230078241506e-01, 9.997221283752786e-01, 9.997214370643954e-01, 9.997209349916318e-01, + 9.997206231343720e-01, 9.997205023448855e-01, 9.997205733480192e-01, 9.997208367389500e-01, 9.997212929810099e-01, + 9.997219424035817e-01, 9.997227852000825e-01, 9.997238214260302e-01, 9.997250509972079e-01, 9.997264736879269e-01, + 9.997280891294001e-01, 9.997298968082279e-01, 9.997318960650045e-01, 9.997340860930511e-01, 9.997364659372833e-01, + 9.997390344932165e-01, 9.997417905061193e-01, 9.997447325703143e-01, 9.997478591286405e-01, 9.997511684720751e-01, + 9.997546587395272e-01, 9.997583279177997e-01, 9.997621738417345e-01, 9.997661941945379e-01, 9.997703865082921e-01, + 9.997747481646605e-01, 9.997792763957843e-01, 9.997839682853786e-01, 9.997888207700281e-01, 9.997938306406862e-01, + 9.997989945443773e-01, 9.998043089861064e-01, 9.998097703309746e-01, 9.998153748065003e-01, 9.998211185051530e-01, + 9.998269973870870e-01, 9.998330072830846e-01, 9.998391438977015e-01, 9.998454028126147e-01, 9.998517794901678e-01, + 9.998582692771129e-01, 9.998648674085431e-01, 9.998715690120116e-01, 9.998783691118356e-01, 9.998852626335712e-01, + 9.998922444086656e-01, 9.998993091792668e-01, 9.999064516031954e-01, 9.999136662590593e-01, 9.999209476515181e-01, + 9.999282902166716e-01, 9.999356883275767e-01, 9.999431362998797e-01, 9.999506283975492e-01, 9.999581588387069e-01, + 9.999657218015426e-01, 9.999733114303028e-01, 9.999809218413399e-01, 9.999885471292198e-01, 9.999961813728609e-01, + 1.000003792553732e+00, 1.000011363835885e+00, 1.000018880862106e+00, 1.000026318501453e+00, 1.000033646597102e+00, + 1.000040828844329e+00, 1.000047821703262e+00, 1.000054573213544e+00, 1.000061021697840e+00, 1.000067094351168e+00, + 1.000072705715621e+00, 1.000077756041457e+00, 1.000082129536869e+00, 1.000085692509860e+00, 1.000088291406840e+00, + 1.000089750753633e+00, 1.000089871005573e+00, 1.000088426314299e+00, 1.000085162219593e+00, 1.000079793275302e+00, + 1.000072000618805e+00, 1.000061429493851e+00, 1.000047686736686e+00, 1.000030338235356e+00, 1.000008906371822e+00, + 9.999828674561138e-01, 9.999516491611377e-01, 9.999146279660260e-01, 9.998711266149775e-01, 9.998204115975446e-01, + 9.997616906551822e-01, 9.996941103176716e-01, 9.996167534717882e-01, 9.995286369633262e-01, 9.994287092323502e-01, + 9.993158479803570e-01, 9.991888578669340e-01, 9.990464682325365e-01, 9.988873308431691e-01, 9.987100176521666e-01, + 9.985130185738464e-01, 9.982947392636853e-01, 9.980534988998219e-01, 9.977875279611558e-01, 9.974949659981255e-01, + 9.971738593934303e-01, 9.968221591115168e-01, 9.964377184376065e-01, 9.960182907094022e-01, 9.955615270473709e-01, + 9.950649740926601e-01, 9.945260717652322e-01, 9.939421510586981e-01, 9.933104318925129e-01, 9.926280210466711e-01, + 9.918919102086680e-01, 9.910989741672799e-01, 9.902459691925082e-01, 9.893295316457497e-01, 9.883461768687914e-01, + 9.872922984044433e-01, 9.861641676054160e-01, 9.849579336912377e-01, 9.836696243155244e-01, 9.822951467075759e-01, + 9.808302894530008e-01, 9.792707249777252e-01, 9.776120127982821e-01, 9.758496035985741e-01, 9.739788441893990e-01, + 9.719949834018297e-01, 9.698931789591444e-01, 9.676685053644012e-01, 9.653159628320954e-01, 9.628304872826687e-01, + 9.602069614081798e-01, 9.574402268063275e-01, 9.545250971684157e-01, 9.514563724950412e-01, 9.482288543014010e-01, + 9.448373617624480e-01, 9.412767487368542e-01, 9.375419215980740e-01, 9.336278577909594e-01, 9.295296250234834e-01, + 9.252424009953755e-01, 9.207614935589523e-01, 9.160823612022024e-01, 9.112006337403594e-01, 9.061121330997502e-01, + 9.008128940766279e-01, 8.952991849539681e-01, 8.895675278607562e-01, 8.836147187609806e-01, 8.774378469633509e-01, + 8.710343140474714e-01, 8.644018521077256e-01, 8.575385412223282e-01, 8.504428260617042e-01, 8.431135315574496e-01, + 8.355498775604459e-01, 8.277514924241404e-01, 8.197184254564199e-01, 8.114511581907922e-01, 8.029506144346715e-01, + 7.942181690593274e-01, 7.852556555024425e-01, 7.760653719601955e-01, 7.666500862512726e-01, 7.570130393401874e-01, + 7.471579475117688e-01, 7.370890031926083e-01, 7.268108744186758e-01, 7.163287029512231e-01, 7.056481010455187e-01, + 6.947751468789124e-01, 6.837163786462801e-01, 6.724787873320510e-01, 6.610698081688499e-01, 6.494973107933384e-01, + 6.377695881101478e-01, 6.258953438749761e-01, 6.138836790079482e-01, 6.017440766483936e-01, 5.894863859622419e-01, + 5.771208047134243e-01, 5.646578606110257e-01, 5.521083914445795e-01, 5.394835240208723e-01, 5.267946519170417e-01, + 5.140534120666679e-01, 5.012716601980810e-01, 4.884614451472596e-01, 4.756349820716255e-01, 4.628046245957236e-01, + 4.499828359253513e-01, 4.371821589731387e-01, 4.244151855459629e-01, 4.116945246528834e-01, 3.990327700015137e-01, + 3.864424667608565e-01, 3.739360776795802e-01, 3.615259486603844e-01, 3.492242739034092e-01, 3.370430607443994e-01, + 3.249940943263768e-01, 3.130889022566745e-01, 3.013387194140940e-01, 2.897544530833894e-01, 2.783466486059465e-01, + 2.671254557460968e-01, 2.561005959816459e-01, 2.452813309345670e-01, 2.346764321630724e-01, 2.242941525391207e-01, + 2.141421994355449e-01, 2.042277099441413e-01, 1.945572283400477e-01, 1.851366859983997e-01, 1.759713839565222e-01, + 1.670659782987828e-01, 1.584244685217862e-01, 1.500501890149949e-01, 1.419458037663698e-01, 1.341133043745716e-01, + 1.265540114190599e-01, 1.192685792075560e-01, 1.122570038873269e-01, 1.055186348731866e-01, 9.905218951159138e-02, + 9.285577086735504e-02, 8.692688848791834e-02, 8.126248197036480e-02, 7.585894712900819e-02, 7.071216453687493e-02, + 6.581753019316379e-02, 6.116998805112477e-02, 5.676406412698673e-02, 5.259390190074066e-02, 4.865329871379729e-02, + 4.493574286675733e-02, 4.143445112264064e-02, 3.814240632671975e-02, 3.505239486333388e-02, 3.215704368240290e-02, + 2.944885664345253e-02, 2.692024994241165e-02, 2.456358640583462e-02, 2.237120845811709e-02, 2.033546958929542e-02, + 1.844876417374586e-02, 1.670355551314538e-02, 1.509240200007160e-02, 1.360798132128038e-02, 1.224311264172586e-02, + 1.099077673153155e-02, 9.844134018179273e-03, 8.796540564986736e-03, 7.841561994366898e-03, 6.972985390308479e-03, + 6.184829228925801e-03, 5.471351398766137e-03, 4.827055383826915e-03, 4.246694691940794e-03, 3.725275619368065e-03, + 3.258058449144477e-03, 2.840557186031939e-03, 2.468537934882437e-03, 2.138016031933214e-03, 1.845252040089026e-03, + 1.586746719704406e-03, 1.359235085846040e-03, 1.159679661583578e-03, 9.852630346169412e-04, 8.333798215882749e-04, + 7.016281408336979e-04, 5.878006901877478e-04, 4.898755218427234e-04, 4.060066012630820e-04, 3.345142318353532e-04, + 2.738754213664553e-04, 2.227142607936653e-04, 1.797923795997266e-04, 1.439995364945199e-04, 1.143443979841680e-04, + 8.994555154915584e-05, 7.002279434068894e-05, 5.388873262066439e-05, 4.094072165278127e-05, 3.065317043363458e-05, + 2.257023056170620e-05, 1.629888370183569e-05, 1.150243752713366e-05, 7.894435705240934e-06, 5.232983386684600e-06, + 3.315485520548709e-06, 1.973790197100917e-06, 1.069718110365652e-06, 4.909053882102472e-07, 1.462097501755241e-07, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, + 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00, 0.000000000000000e+00}; + + + +const LC3_FLOAT* MDCT_WINS_10ms[2][6] = { + {MDCT_WINDOW_80, MDCT_WINDOW_160, MDCT_WINDOW_240, MDCT_WINDOW_320, MDCT_WINDOW_480, NULL}, + {NULL, NULL, NULL, NULL, MDCT_HRA_WINDOW_480_10ms, MDCT_HRA_WINDOW_960_10ms}}; +const LC3_INT MDCT_la_zeroes[6] = {30, 60, 90, 120, 180, 360}; + + +const LC3_FLOAT* MDCT_WINS_2_5ms[2][6] = { + {MDCT_WINDOW_80_2_5ms, MDCT_WINDOW_160_2_5ms, MDCT_WINDOW_240_2_5ms, MDCT_WINDOW_320_2_5ms, MDCT_WINDOW_480_2_5ms, + NULL}, + {NULL, NULL, NULL, NULL, MDCT_HRA_WINDOW_480_2_5ms, MDCT_HRA_WINDOW_960_2_5ms}}; +const LC3_INT MDCT_la_zeroes_2_5ms[6] = {0, 0, 0, 0, 0, 0}; + +const LC3_FLOAT* MDCT_WINS_5ms[2][6] = { + {MDCT_WINDOW_80_5ms, MDCT_WINDOW_160_5ms, MDCT_WINDOW_240_5ms, MDCT_WINDOW_320_5ms, MDCT_WINDOW_480_5ms, NULL}, + {NULL, NULL, NULL, NULL, MDCT_HRA_WINDOW_480_5ms, MDCT_HRA_WINDOW_960_5ms}}; +const LC3_INT MDCT_la_zeroes_5ms[6] = {10, 20, 30, 40, 60, 120}; + +const LC3_INT MDCT_WINDOWS_LENGTHS_10ms[6] = {160, 320, 480, 640, 960, 1920}; /* Last 960 dummy */ + +const LC3_INT MDCT_WINDOWS_LENGTHS_2_5ms[6] = {40, 80, 120, 160, 240, 480}; + + +const LC3_INT MDCT_WINDOWS_LENGTHS_5ms[6] = {80, 160, 240, 320, 480, 960}; + +/* Per band energy */ +const LC3_INT ACC_COEFF_PER_BAND_8[65] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 51, + 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 80}; + +const LC3_INT ACC_COEFF_PER_BAND_16[65] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 32, 34, 36, 38, + 40, 42, 44, 46, 48, 50, 52, 55, 58, 61, 64, 67, 70, 73, 76, 80, 84, + 88, 92, 96, 101, 106, 111, 116, 121, 127, 133, 139, 146, 153, 160}; + +const LC3_INT ACC_COEFF_PER_BAND_24[65] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 46, 49, 52, 55, 58, 61, 64, 68, 72, 76, + 80, 85, 90, 95, 100, 106, 112, 118, 125, 132, 139, 147, 155, 164, 173, 183, 193, 204, 215, 227, 240}; + +const LC3_INT ACC_COEFF_PER_BAND_32[65] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 22, + 24, 26, 28, 30, 32, 34, 36, 38, 41, 44, 47, 50, 53, 56, 60, 64, 68, 72, 76, 81, 86, 91, + 97, 103, 109, 116, 123, 131, 139, 148, 157, 166, 176, 187, 199, 211, 224, 238, 252, 268, 284, 302, 320}; + +const LC3_INT ACC_COEFF_PER_BAND_48[65] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, + 26, 28, 30, 32, 34, 36, 39, 42, 45, 48, 51, 55, 59, 63, 67, 71, 76, 81, 86, 92, 98, 105, + 112, 119, 127, 135, 144, 154, 164, 175, 186, 198, 211, 225, 240, 256, 273, 291, 310, 330, 352, 375, 400}; + +const LC3_INT ACC_COEFF_PER_BAND_8_2_5ms[21] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + +const LC3_INT ACC_COEFF_PER_BAND_16_2_5ms[36] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 32, 34, 36, 38, 40}; + +const LC3_INT ACC_COEFF_PER_BAND_24_2_5ms[41] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 28, + 30, 32, 34, 36, 38, 40, 42, 44, 47, 50, 53, 56, 60}; + +const LC3_INT ACC_COEFF_PER_BAND_32_2_5ms[44] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 28, 30, 32, 34, + 36, 38, 40, 43, 46, 49, 52, 55, 59, 63, 67, 71, 75, 80}; + +const LC3_INT ACC_COEFF_PER_BAND_48_2_5ms[45] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 23, 25, 27, 29, 31, 33, 35, 37, + 40, 43, 46, 49, 52, 56, 60, 64, 68, 72, 77, 82, 87, 93, 100}; + +const LC3_INT ACC_COEFF_PER_BAND_48_2_5ms_HR[46] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 40, 43, 46, + 49, 53, 57, 61, 65, 69, 74, 79, 85, 91, 97, 104, 112, 120}; +const LC3_INT ACC_COEFF_PER_BAND_96_2_5ms_HR[50] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 22, 24, 26, 28, 30, 32, + 35, 38, 41, 45, 49, 53, 57, 62, 67, 73, 79, 85, 92, 100, 108, 117, 127, 137, 149, 161, 174, 189, 204, 221, 240}; + + +const LC3_INT ACC_COEFF_PER_BAND_8_5ms[40] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 40}; + +const LC3_INT ACC_COEFF_PER_BAND_16_5ms[51] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 34, 36, + 38, 40, 42, 44, 46, 48, 50, 52, 54, 57, 60, 63, 66, 69, 72, 76, 80}; + +const LC3_INT ACC_COEFF_PER_BAND_24_5ms[53] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 26, 28, + 30, 32, 34, 36, 38, 40, 42, 44, 47, 50, 53, 56, 59, 62, 65, 69, 73, 77, 81, 86, 91, 96, 101, 107, 113, 120}; + +const LC3_INT ACC_COEFF_PER_BAND_32_5ms[55] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 26, 28, 30, 32, + 34, 36, 38, 40, 42, 45, 48, 51, 54, 57, 61, 65, 69, 73, + 78, 83, 88, 93, 99, 105, 112, 119, 126, 134, 142, 151, 160}; +const LC3_INT ACC_COEFF_PER_BAND_48_5ms_HR[56] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 21, 23, 25, 27, 29, 31, 33, 35, + 38, 41, 44, 47, 50, 54, 58, 62, 66, 71, 76, 81, 87, 93, + 100, 107, 114, 122, 131, 140, 149, 160, 171, 183, 196, 209, 224, 240}; +const LC3_INT ACC_COEFF_PER_BAND_48_5ms[56] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 23, 25, 27, 29, 31, 33, + 35, 37, 40, 43, 46, 49, 52, 55, 59, 63, 67, 72, 77, 82, + 87, 93, 99, 105, 112, 120, 128, 136, 145, 155, 165, 176, 187, 200}; +const LC3_INT ACC_COEFF_PER_BAND_96_5ms_HR[59] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 21, + 23, 25, 27, 29, 31, 34, 37, 40, 44, 48, 52, 56, 61, 66, 71, 77, 83, 90, 98, 106, + 115, 124, 135, 146, 158, 171, 185, 200, 217, 235, 254, 275, 298, 323, 349, 378, 409, 443, 480}; + + +const LC3_INT ACC_COEFF_PER_BAND_48_HR[65] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19, 21, 23, 25, + 27, 29, 31, 33, 36, 39, 42, 45, 48, 51, 55, 59, 63, 67, 72, 77, 83, 89, 95, 101, 108, 116, + 124, 133, 142, 152, 163, 174, 187, 200, 214, 229, 244, 262, 280, 299, 320, 343, 367, 392, 419, 449, 480}; + +const LC3_INT ACC_COEFF_PER_BAND_96_HR[65] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 33, 36, 39, 42, 46, 50, 54, 59, 64, 69, 75, 82, 89, 96, 104, 113, 122, 132, 143, 155, 168, 181, 196, 213, 230, 249, 270, 292, 316, 342, 371, 401, 434, 470, 509, 551, 596, 646, 699, 757, 819, 887, 960}; + +const LC3_INT* ACC_COEFF_PER_BAND_HR[6] = {NULL, NULL, NULL, NULL, ACC_COEFF_PER_BAND_48_HR, ACC_COEFF_PER_BAND_96_HR}; + +const LC3_INT* ACC_COEFF_PER_BAND[6] = {ACC_COEFF_PER_BAND_8, ACC_COEFF_PER_BAND_16, ACC_COEFF_PER_BAND_24, + ACC_COEFF_PER_BAND_32, ACC_COEFF_PER_BAND_48, NULL}; + +const LC3_INT* ACC_COEFF_PER_BAND_2_5ms_HR[6] = { + NULL, NULL, NULL, NULL, ACC_COEFF_PER_BAND_48_2_5ms_HR, ACC_COEFF_PER_BAND_96_2_5ms_HR}; + +const LC3_INT* ACC_COEFF_PER_BAND_2_5ms[5] = {ACC_COEFF_PER_BAND_8_2_5ms, ACC_COEFF_PER_BAND_16_2_5ms, + ACC_COEFF_PER_BAND_24_2_5ms, ACC_COEFF_PER_BAND_32_2_5ms, + ACC_COEFF_PER_BAND_48_2_5ms}; + + +const LC3_INT* ACC_COEFF_PER_BAND_5ms_HR[6] = { + NULL, NULL, NULL, NULL, ACC_COEFF_PER_BAND_48_5ms_HR, ACC_COEFF_PER_BAND_96_5ms_HR}; + +const LC3_INT* ACC_COEFF_PER_BAND_5ms[5] = {ACC_COEFF_PER_BAND_8_5ms, ACC_COEFF_PER_BAND_16_5ms, + ACC_COEFF_PER_BAND_24_5ms, ACC_COEFF_PER_BAND_32_5ms, + ACC_COEFF_PER_BAND_48_5ms}; + +/* Near Nyquist detector */ +const LC3_INT NN_thresh = 30; + + +const LC3_INT32 xavg_N_grp[5] = { 4, 5, 6, 7, 8 }; + + +const LC3_INT32 gwlpr[MAX_LGW+1] = { 1, 3*QUOT_LPR_LTR, 5*QUOT_LPR_LTR, 9*QUOT_LPR_LTR, 17*QUOT_LPR_LTR, 33*QUOT_LPR_LTR, 49*QUOT_LPR_LTR, 65*QUOT_LPR_LTR, 81*QUOT_LPR_LTR, 97*QUOT_LPR_LTR}; + + +const LC3_FLOAT PhECU_whr16ms_NB[128]={ +8.000000000000002e-02, 8.393536376804722e-02, 9.567411990702857e-02, 1.150154150448081e-01, 1.416283142591582e-01, +1.750574634660318e-01, 2.147308806541882e-01, 2.599697426559885e-01, 3.099999999999999e-01, 3.639656211120587e-01, +4.209432392528405e-01, 4.799579515787762e-01, 5.400000000000000e-01, 6.000420484212237e-01, 6.590567607471596e-01, +7.160343788879413e-01, 7.699999999999999e-01, 8.200302573440115e-01, 8.652691193458119e-01, 9.049425365339682e-01, +9.383716857408418e-01, 9.649845849551919e-01, 9.843258800929715e-01, 9.960646362319528e-01, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +9.960646362319528e-01, 9.843258800929715e-01, 9.649845849551919e-01, 9.383716857408418e-01, 9.049425365339682e-01, +8.652691193458119e-01, 8.200302573440115e-01, 7.699999999999999e-01, 7.160343788879413e-01, 6.590567607471596e-01, +6.000420484212237e-01, 5.400000000000000e-01, 4.799579515787762e-01, 4.209432392528405e-01, 3.639656211120587e-01, +3.099999999999999e-01, 2.599697426559885e-01, 2.147308806541882e-01, 1.750574634660318e-01, 1.416283142591582e-01, +1.150154150448081e-01, 9.567411990702857e-02, 8.393536376804722e-02 +}; +const LC3_FLOAT PhECU_whr16ms_WB[256]={ +8.000000000000002e-02, 8.098489531024239e-02, 8.393536376804722e-02, 8.883877101451404e-02, 9.567411990702857e-02, +1.044121404322514e-01, 1.150154150448081e-01, 1.274385388949634e-01, 1.416283142591582e-01, 1.575239783408292e-01, +1.750574634660318e-01, 1.941536885596704e-01, 2.147308806541882e-01, 2.367009250539683e-01, 2.599697426559885e-01, +2.844376928109830e-01, 3.099999999999999e-01, 3.365472024992595e-01, 3.639656211120587e-01, 3.921378459605457e-01, +4.209432392528405e-01, 4.502584518725810e-01, 4.799579515787762e-01, 5.099145605541342e-01, 5.400000000000000e-01, +5.700854394458659e-01, 6.000420484212237e-01, 6.297415481274190e-01, 6.590567607471596e-01, 6.878621540394543e-01, +7.160343788879413e-01, 7.434527975007406e-01, 7.699999999999999e-01, 7.955623071890170e-01, 8.200302573440115e-01, +8.432990749460317e-01, 8.652691193458119e-01, 8.858463114403297e-01, 9.049425365339682e-01, 9.224760216591710e-01, +9.383716857408418e-01, 9.525614611050366e-01, 9.649845849551919e-01, 9.755878595677486e-01, 9.843258800929715e-01, +9.911612289854861e-01, 9.960646362319528e-01, 9.990151046897577e-01, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 9.990151046897577e-01, +9.960646362319528e-01, 9.911612289854861e-01, 9.843258800929715e-01, 9.755878595677486e-01, 9.649845849551919e-01, +9.525614611050366e-01, 9.383716857408418e-01, 9.224760216591710e-01, 9.049425365339682e-01, 8.858463114403297e-01, +8.652691193458119e-01, 8.432990749460317e-01, 8.200302573440115e-01, 7.955623071890170e-01, 7.699999999999999e-01, +7.434527975007406e-01, 7.160343788879413e-01, 6.878621540394543e-01, 6.590567607471596e-01, 6.297415481274190e-01, +6.000420484212237e-01, 5.700854394458659e-01, 5.400000000000000e-01, 5.099145605541342e-01, 4.799579515787762e-01, +4.502584518725810e-01, 4.209432392528405e-01, 3.921378459605457e-01, 3.639656211120587e-01, 3.365472024992595e-01, +3.099999999999999e-01, 2.844376928109830e-01, 2.599697426559885e-01, 2.367009250539683e-01, 2.147308806541882e-01, +1.941536885596704e-01, 1.750574634660318e-01, 1.575239783408292e-01, 1.416283142591582e-01, 1.274385388949634e-01, +1.150154150448081e-01, 1.044121404322514e-01, 9.567411990702857e-02, 8.883877101451404e-02, 8.393536376804722e-02, +8.098489531024239e-02 +}; +const LC3_FLOAT PhECU_whr16ms_SSWB[384]={ +8.000000000000002e-02, 8.043781807234540e-02, 8.175043887779704e-02, 8.393536376804722e-02, 8.698843361438435e-02, +9.090383672483066e-02, 9.567411990702857e-02, 1.012902026558156e-01, 1.077413944384821e-01, 1.150154150448081e-01, +1.230984179631410e-01, 1.319750167380180e-01, 1.416283142591582e-01, 1.520399349260726e-01, 1.631900596270638e-01, +1.750574634660318e-01, 1.876195561652702e-01, 2.008524250673430e-01, 2.147308806541882e-01, 2.292285044967963e-01, +2.443176995441919e-01, 2.599697426559885e-01, 2.761548392785189e-01, 2.928421801604610e-01, 3.099999999999999e-01, +3.275956379118843e-01, 3.455955995992783e-01, 3.639656211120587e-01, 3.826707340701924e-01, 4.016753322280344e-01, +4.209432392528405e-01, 4.404377775884727e-01, 4.601218382732121e-01, 4.799579515787762e-01, 4.999083583360772e-01, +5.199350818119455e-01, 5.400000000000000e-01, 5.600649181880546e-01, 5.800916416639228e-01, 6.000420484212237e-01, +6.198781617267880e-01, 6.395622224115274e-01, 6.590567607471596e-01, 6.783246677719657e-01, 6.973292659298076e-01, +7.160343788879413e-01, 7.344044004007217e-01, 7.524043620881156e-01, 7.699999999999999e-01, 7.871578198395390e-01, +8.038451607214812e-01, 8.200302573440115e-01, 8.356823004558082e-01, 8.507714955032037e-01, 8.652691193458119e-01, +8.791475749326572e-01, 8.923804438347298e-01, 9.049425365339682e-01, 9.168099403729364e-01, 9.279600650739274e-01, +9.383716857408418e-01, 9.480249832619820e-01, 9.569015820368590e-01, 9.649845849551919e-01, 9.722586055615179e-01, +9.787097973441844e-01, 9.843258800929715e-01, 9.890961632751694e-01, 9.930115663856157e-01, 9.960646362319528e-01, +9.982495611222031e-01, 9.995621819276547e-01, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 9.995621819276547e-01, 9.982495611222031e-01, +9.960646362319528e-01, 9.930115663856157e-01, 9.890961632751694e-01, 9.843258800929715e-01, 9.787097973441844e-01, +9.722586055615179e-01, 9.649845849551919e-01, 9.569015820368590e-01, 9.480249832619820e-01, 9.383716857408418e-01, +9.279600650739274e-01, 9.168099403729364e-01, 9.049425365339682e-01, 8.923804438347298e-01, 8.791475749326572e-01, +8.652691193458119e-01, 8.507714955032037e-01, 8.356823004558082e-01, 8.200302573440115e-01, 8.038451607214812e-01, +7.871578198395390e-01, 7.699999999999999e-01, 7.524043620881156e-01, 7.344044004007217e-01, 7.160343788879413e-01, +6.973292659298076e-01, 6.783246677719657e-01, 6.590567607471596e-01, 6.395622224115274e-01, 6.198781617267880e-01, +6.000420484212237e-01, 5.800916416639228e-01, 5.600649181880546e-01, 5.400000000000000e-01, 5.199350818119455e-01, +4.999083583360772e-01, 4.799579515787762e-01, 4.601218382732121e-01, 4.404377775884727e-01, 4.209432392528405e-01, +4.016753322280344e-01, 3.826707340701924e-01, 3.639656211120587e-01, 3.455955995992783e-01, 3.275956379118843e-01, +3.099999999999999e-01, 2.928421801604610e-01, 2.761548392785189e-01, 2.599697426559885e-01, 2.443176995441919e-01, +2.292285044967963e-01, 2.147308806541882e-01, 2.008524250673430e-01, 1.876195561652702e-01, 1.750574634660318e-01, +1.631900596270638e-01, 1.520399349260726e-01, 1.416283142591582e-01, 1.319750167380180e-01, 1.230984179631410e-01, +1.150154150448081e-01, 1.077413944384821e-01, 1.012902026558156e-01, 9.567411990702857e-02, 9.090383672483066e-02, +8.698843361438435e-02, 8.393536376804722e-02, 8.175043887779704e-02, 8.043781807234540e-02 +}; +const LC3_FLOAT PhECU_whr16ms_SWB[512]={ +8.000000000000002e-02, 8.024628976087178e-02, 8.098489531024239e-02, 8.221502573078943e-02, 8.393536376804722e-02, +8.614406724095569e-02, 8.883877101451404e-02, 9.201658953242653e-02, 9.567411990702857e-02, 9.980744556318394e-02, +1.044121404322514e-01, 1.094832736916302e-01, 1.150154150448081e-01, 1.210026405362591e-01, 1.274385388949634e-01, +1.343162183997567e-01, 1.416283142591582e-01, 1.493669964977737e-01, 1.575239783408292e-01, 1.660905250878570e-01, +1.750574634660318e-01, 1.844151914531410e-01, 1.941536885596704e-01, 2.042625265589956e-01, 2.147308806541882e-01, +2.255475410694793e-01, 2.367009250539683e-01, 2.481790892847231e-01, 2.599697426559885e-01, 2.720602594408110e-01, +2.844376928109830e-01, 2.970887887008307e-01, 3.099999999999999e-01, 3.231575010600410e-01, 3.365472024992595e-01, +3.501547662899784e-01, 3.639656211120587e-01, 3.779649779562326e-01, 3.921378459605457e-01, 4.064690484629473e-01, +4.209432392528405e-01, 4.355449190041883e-01, 4.502584518725810e-01, 4.650680822384892e-01, 4.799579515787762e-01, +4.949121154484021e-01, 5.099145605541342e-01, 5.249492219019830e-01, 5.400000000000000e-01, 5.550507780980171e-01, +5.700854394458659e-01, 5.850878845515979e-01, 6.000420484212237e-01, 6.149319177615109e-01, 6.297415481274190e-01, +6.444550809958116e-01, 6.590567607471596e-01, 6.735309515370527e-01, 6.878621540394543e-01, 7.020350220437674e-01, +7.160343788879413e-01, 7.298452337100215e-01, 7.434527975007406e-01, 7.568424989399589e-01, 7.699999999999999e-01, +7.829112112991693e-01, 7.955623071890170e-01, 8.079397405591890e-01, 8.200302573440115e-01, 8.318209107152770e-01, +8.432990749460317e-01, 8.544524589305209e-01, 8.652691193458119e-01, 8.757374734410044e-01, 8.858463114403297e-01, +8.955848085468591e-01, 9.049425365339682e-01, 9.139094749121430e-01, 9.224760216591710e-01, 9.306330035022263e-01, +9.383716857408418e-01, 9.456837816002432e-01, 9.525614611050366e-01, 9.589973594637410e-01, 9.649845849551919e-01, +9.705167263083698e-01, 9.755878595677486e-01, 9.801925544368162e-01, 9.843258800929715e-01, 9.879834104675735e-01, +9.911612289854861e-01, 9.938559327590444e-01, 9.960646362319528e-01, 9.977849742692106e-01, 9.990151046897577e-01, +9.997537102391283e-01, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 9.997537102391283e-01, 9.990151046897577e-01, 9.977849742692106e-01, +9.960646362319528e-01, 9.938559327590444e-01, 9.911612289854861e-01, 9.879834104675735e-01, 9.843258800929715e-01, +9.801925544368162e-01, 9.755878595677486e-01, 9.705167263083698e-01, 9.649845849551919e-01, 9.589973594637410e-01, +9.525614611050366e-01, 9.456837816002432e-01, 9.383716857408418e-01, 9.306330035022263e-01, 9.224760216591710e-01, +9.139094749121430e-01, 9.049425365339682e-01, 8.955848085468591e-01, 8.858463114403297e-01, 8.757374734410044e-01, +8.652691193458119e-01, 8.544524589305209e-01, 8.432990749460317e-01, 8.318209107152770e-01, 8.200302573440115e-01, +8.079397405591890e-01, 7.955623071890170e-01, 7.829112112991693e-01, 7.699999999999999e-01, 7.568424989399589e-01, +7.434527975007406e-01, 7.298452337100215e-01, 7.160343788879413e-01, 7.020350220437674e-01, 6.878621540394543e-01, +6.735309515370527e-01, 6.590567607471596e-01, 6.444550809958116e-01, 6.297415481274190e-01, 6.149319177615109e-01, +6.000420484212237e-01, 5.850878845515979e-01, 5.700854394458659e-01, 5.550507780980171e-01, 5.400000000000000e-01, +5.249492219019830e-01, 5.099145605541342e-01, 4.949121154484021e-01, 4.799579515787762e-01, 4.650680822384892e-01, +4.502584518725810e-01, 4.355449190041883e-01, 4.209432392528405e-01, 4.064690484629473e-01, 3.921378459605457e-01, +3.779649779562326e-01, 3.639656211120587e-01, 3.501547662899784e-01, 3.365472024992595e-01, 3.231575010600410e-01, +3.099999999999999e-01, 2.970887887008307e-01, 2.844376928109830e-01, 2.720602594408110e-01, 2.599697426559885e-01, +2.481790892847231e-01, 2.367009250539683e-01, 2.255475410694793e-01, 2.147308806541882e-01, 2.042625265589956e-01, +1.941536885596704e-01, 1.844151914531410e-01, 1.750574634660318e-01, 1.660905250878570e-01, 1.575239783408292e-01, +1.493669964977737e-01, 1.416283142591582e-01, 1.343162183997567e-01, 1.274385388949634e-01, 1.210026405362591e-01, +1.150154150448081e-01, 1.094832736916302e-01, 1.044121404322514e-01, 9.980744556318394e-02, 9.567411990702857e-02, +9.201658953242653e-02, 8.883877101451404e-02, 8.614406724095569e-02, 8.393536376804722e-02, 8.221502573078943e-02, +8.098489531024239e-02, 8.024628976087178e-02 +}; +const LC3_FLOAT PhECU_whr16ms_FB[768]={ +8.000000000000002e-02, 8.010946754324183e-02, 8.043781807234540e-02, 8.098489531024239e-02, 8.175043887779704e-02, +8.273408441773300e-02, 8.393536376804722e-02, 8.535370518483010e-02, 8.698843361438435e-02, 8.883877101451404e-02, +9.090383672483066e-02, 9.318264788589975e-02, 9.567411990702857e-02, 9.837706698247278e-02, 1.012902026558156e-01, +1.044121404322514e-01, 1.077413944384821e-01, 1.112763801299127e-01, 1.150154150448081e-01, 1.189567196050543e-01, +1.230984179631410e-01, 1.274385388949634e-01, 1.319750167380180e-01, 1.367056923745465e-01, 1.416283142591582e-01, +1.467405394904446e-01, 1.520399349260726e-01, 1.575239783408292e-01, 1.631900596270638e-01, 1.690354820369581e-01, +1.750574634660318e-01, 1.812531377772744e-01, 1.876195561652702e-01, 1.941536885596704e-01, 2.008524250673430e-01, +2.077125774525124e-01, 2.147308806541882e-01, 2.219039943401561e-01, 2.292285044967963e-01, 2.367009250539683e-01, +2.443176995441919e-01, 2.520752027953329e-01, 2.599697426559885e-01, 2.679975617527521e-01, 2.761548392785189e-01, +2.844376928109830e-01, 2.928421801604610e-01, 3.013643012461601e-01, 3.099999999999999e-01, 3.187451662970817e-01, +3.275956379118843e-01, 3.365472024992595e-01, 3.455955995992783e-01, 3.547365226649809e-01, 3.639656211120587e-01, +3.732785023894972e-01, 3.826707340701924e-01, 3.921378459605457e-01, 4.016753322280344e-01, 4.112786535457436e-01, +4.209432392528405e-01, 4.306644895299604e-01, 4.404377775884727e-01, 4.502584518725810e-01, 4.601218382732121e-01, +4.700232423526383e-01, 4.799579515787762e-01, 4.899212375680964e-01, 4.999083583360772e-01, 5.099145605541342e-01, +5.199350818119455e-01, 5.299651528841020e-01, 5.400000000000000e-01, 5.500348471158981e-01, 5.600649181880546e-01, +5.700854394458659e-01, 5.800916416639228e-01, 5.900787624319037e-01, 6.000420484212237e-01, 6.099767576473617e-01, +6.198781617267880e-01, 6.297415481274190e-01, 6.395622224115274e-01, 6.493355104700396e-01, 6.590567607471596e-01, +6.687213464542564e-01, 6.783246677719657e-01, 6.878621540394543e-01, 6.973292659298076e-01, 7.067214976105027e-01, +7.160343788879413e-01, 7.252634773350191e-01, 7.344044004007217e-01, 7.434527975007406e-01, 7.524043620881156e-01, +7.612548337029182e-01, 7.699999999999999e-01, 7.786356987538400e-01, 7.871578198395390e-01, 7.955623071890170e-01, +8.038451607214812e-01, 8.120024382472478e-01, 8.200302573440115e-01, 8.279247972046673e-01, 8.356823004558082e-01, +8.432990749460317e-01, 8.507714955032037e-01, 8.580960056598439e-01, 8.652691193458119e-01, 8.722874225474876e-01, +8.791475749326572e-01, 8.858463114403297e-01, 8.923804438347298e-01, 8.987468622227257e-01, 9.049425365339682e-01, +9.109645179630421e-01, 9.168099403729364e-01, 9.224760216591710e-01, 9.279600650739274e-01, 9.332594605095554e-01, +9.383716857408418e-01, 9.432943076254536e-01, 9.480249832619820e-01, 9.525614611050366e-01, 9.569015820368590e-01, +9.610432803949458e-01, 9.649845849551919e-01, 9.687236198700873e-01, 9.722586055615179e-01, 9.755878595677486e-01, +9.787097973441844e-01, 9.816229330175272e-01, 9.843258800929715e-01, 9.868173521141004e-01, 9.890961632751694e-01, +9.911612289854861e-01, 9.930115663856157e-01, 9.946462948151700e-01, 9.960646362319528e-01, 9.972659155822671e-01, +9.982495611222031e-01, 9.990151046897577e-01, 9.995621819276547e-01, 9.998905324567582e-01, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, 1.000000000000000e+00, +9.998905324567582e-01, 9.995621819276547e-01, 9.990151046897577e-01, 9.982495611222031e-01, 9.972659155822671e-01, +9.960646362319528e-01, 9.946462948151700e-01, 9.930115663856157e-01, 9.911612289854861e-01, 9.890961632751694e-01, +9.868173521141004e-01, 9.843258800929715e-01, 9.816229330175272e-01, 9.787097973441844e-01, 9.755878595677486e-01, +9.722586055615179e-01, 9.687236198700873e-01, 9.649845849551919e-01, 9.610432803949458e-01, 9.569015820368590e-01, +9.525614611050366e-01, 9.480249832619820e-01, 9.432943076254536e-01, 9.383716857408418e-01, 9.332594605095554e-01, +9.279600650739274e-01, 9.224760216591710e-01, 9.168099403729364e-01, 9.109645179630421e-01, 9.049425365339682e-01, +8.987468622227257e-01, 8.923804438347298e-01, 8.858463114403297e-01, 8.791475749326572e-01, 8.722874225474876e-01, +8.652691193458119e-01, 8.580960056598439e-01, 8.507714955032037e-01, 8.432990749460317e-01, 8.356823004558082e-01, +8.279247972046673e-01, 8.200302573440115e-01, 8.120024382472478e-01, 8.038451607214812e-01, 7.955623071890170e-01, +7.871578198395390e-01, 7.786356987538400e-01, 7.699999999999999e-01, 7.612548337029182e-01, 7.524043620881156e-01, +7.434527975007406e-01, 7.344044004007217e-01, 7.252634773350191e-01, 7.160343788879413e-01, 7.067214976105027e-01, +6.973292659298076e-01, 6.878621540394543e-01, 6.783246677719657e-01, 6.687213464542564e-01, 6.590567607471596e-01, +6.493355104700396e-01, 6.395622224115274e-01, 6.297415481274190e-01, 6.198781617267880e-01, 6.099767576473617e-01, +6.000420484212237e-01, 5.900787624319037e-01, 5.800916416639228e-01, 5.700854394458659e-01, 5.600649181880546e-01, +5.500348471158981e-01, 5.400000000000000e-01, 5.299651528841020e-01, 5.199350818119455e-01, 5.099145605541342e-01, +4.999083583360772e-01, 4.899212375680964e-01, 4.799579515787762e-01, 4.700232423526383e-01, 4.601218382732121e-01, +4.502584518725810e-01, 4.404377775884727e-01, 4.306644895299604e-01, 4.209432392528405e-01, 4.112786535457436e-01, +4.016753322280344e-01, 3.921378459605457e-01, 3.826707340701924e-01, 3.732785023894972e-01, 3.639656211120587e-01, +3.547365226649809e-01, 3.455955995992783e-01, 3.365472024992595e-01, 3.275956379118843e-01, 3.187451662970817e-01, +3.099999999999999e-01, 3.013643012461601e-01, 2.928421801604610e-01, 2.844376928109830e-01, 2.761548392785189e-01, +2.679975617527521e-01, 2.599697426559885e-01, 2.520752027953329e-01, 2.443176995441919e-01, 2.367009250539683e-01, +2.292285044967963e-01, 2.219039943401561e-01, 2.147308806541882e-01, 2.077125774525124e-01, 2.008524250673430e-01, +1.941536885596704e-01, 1.876195561652702e-01, 1.812531377772744e-01, 1.750574634660318e-01, 1.690354820369581e-01, +1.631900596270638e-01, 1.575239783408292e-01, 1.520399349260726e-01, 1.467405394904446e-01, 1.416283142591582e-01, +1.367056923745465e-01, 1.319750167380180e-01, 1.274385388949634e-01, 1.230984179631410e-01, 1.189567196050543e-01, +1.150154150448081e-01, 1.112763801299127e-01, 1.077413944384821e-01, 1.044121404322514e-01, 1.012902026558156e-01, +9.837706698247278e-02, 9.567411990702857e-02, 9.318264788589975e-02, 9.090383672483066e-02, 8.883877101451404e-02, +8.698843361438435e-02, 8.535370518483010e-02, 8.393536376804722e-02, 8.273408441773300e-02, 8.175043887779704e-02, +8.098489531024239e-02, 8.043781807234540e-02, 8.010946754324183e-02 +}; + +const LC3_FLOAT* PhECU_whr16ms_wins[5] = { + PhECU_whr16ms_NB,PhECU_whr16ms_WB,PhECU_whr16ms_SSWB,PhECU_whr16ms_SWB, PhECU_whr16ms_FB +}; + + +const LC3_FLOAT hannOla_8k[28 / 2 + 1] = { + 0.0000000000, 0.0125360439, 0.0495155660, 0.1090842588, 0.1882550991, 0.2830581304, 0.3887395330, 0.5000000000, 0.6112604670, 0.7169418696, 0.8117449009, 0.8909157412, 0.9504844340, + 0.9874639561, 1.0000000000 }; + +const LC3_FLOAT hannOla_16k[56 / 2 + 1] = { + 0.0000000000, 0.0031438951, 0.0125360439, 0.0280583348, 0.0495155660, 0.0766379004, 0.1090842588, 0.1464466094, 0.1882550991, 0.2339839617, 0.2830581304, 0.3348604690, 0.3887395330, + 0.4440177619, 0.5000000000, 0.5559822381, 0.6112604670, 0.6651395310, 0.7169418696, 0.7660160383, 0.8117449009, 0.8535533906, 0.8909157412, 0.9233620996, 0.9504844340, 0.9719416652, + 0.9874639561, 0.9968561049, 1.0000000000 }; + +const LC3_FLOAT hannOla_24k[84 / 2 + 1] = { + 0.0000000000, 0.0013981014, 0.0055845869, 0.0125360439, 0.0222135971, 0.0345631257, 0.0495155660, 0.0669872981, 0.0868806128, 0.1090842588, 0.1334740641, 0.1599136311, 0.1882550991, + 0.2183399710, 0.2500000000, 0.2830581304, 0.3173294878, 0.3526224128, 0.3887395330, 0.4254788669, 0.4626349532, 0.5000000000, 0.5373650468, 0.5745211331, 0.6112604670, 0.6473775872, + 0.6826705122, 0.7169418696, 0.7500000000, 0.7816600290, 0.8117449009, 0.8400863689, 0.8665259359, 0.8909157412, 0.9131193872, 0.9330127019, 0.9504844340, 0.9654368743, 0.9777864029, + 0.9874639561, 0.9944154131, 0.9986018986, 1.0000000000 }; + +const LC3_FLOAT hannOla_32k[112 / 2 + 1] = { + 0.0000000000, 0.0007865925, 0.0031438951, 0.0070644907, 0.0125360439, 0.0195413390, 0.0280583348, 0.0380602337, 0.0495155660, 0.0623882890, 0.0766379004, 0.0922195655, 0.1090842588, + 0.1271789176, 0.1464466094, 0.1668267110, 0.1882550991, 0.2106643519, 0.2339839617, 0.2581405564, 0.2830581304, 0.3086582838, 0.3348604690, 0.3615822443, 0.3887395330, 0.4162468883, + 0.4440177619, 0.4719647764, 0.5000000000, 0.5280352236, 0.5559822381, 0.5837531117, 0.6112604670, 0.6384177557, 0.6651395310, 0.6913417162, 0.7169418696, 0.7418594436, 0.7660160383, + 0.7893356481, 0.8117449009, 0.8331732890, 0.8535533906, 0.8728210824, 0.8909157412, 0.9077804345, 0.9233620996, 0.9376117110, 0.9504844340, 0.9619397663, 0.9719416652, 0.9804586610, + 0.9874639561, 0.9929355093, 0.9968561049, 0.9992134075, 1.0000000000 }; + +const LC3_FLOAT hannOla_48k[168 / 2 + 1] = { + 0.0000000000, 0.0003496476, 0.0013981014, 0.0031438951, 0.0055845869, 0.0087167634, 0.0125360439, 0.0170370869, 0.0222135971, 0.0280583348, 0.0345631257, 0.0417188721, 0.0495155660, + 0.0579423032, 0.0669872981, 0.0766379004, 0.0868806128, 0.0977011101, 0.1090842588, 0.1210141384, 0.1334740641, 0.1464466094, 0.1599136311, 0.1738562944, 0.1882550991, 0.2030899072, + 0.2183399710, 0.2339839617, 0.2500000000, 0.2663656859, 0.2830581304, 0.3000539878, 0.3173294878, 0.3348604690, 0.3526224128, 0.3705904774, 0.3887395330, 0.4070441964, 0.4254788669, + 0.4440177619, 0.4626349532, 0.4813044029, 0.5000000000, 0.5186955971, 0.5373650468, 0.5559822381, 0.5745211331, 0.5929558036, 0.6112604670, 0.6294095226, 0.6473775872, 0.6651395310, + 0.6826705122, 0.6999460122, 0.7169418696, 0.7336343141, 0.7500000000, 0.7660160383, 0.7816600290, 0.7969100928, 0.8117449009, 0.8261437056, 0.8400863689, 0.8535533906, 0.8665259359, + 0.8789858616, 0.8909157412, 0.9022988899, 0.9131193872, 0.9233620996, 0.9330127019, 0.9420576968, 0.9504844340, 0.9582811279, 0.9654368743, 0.9719416652, 0.9777864029, 0.9829629131, + 0.9874639561, 0.9912832366, 0.9944154131, 0.9968561049, 0.9986018986, 0.9996503524, 1.0000000000 }; + +const LC3_FLOAT *hannOla_wins[5] = { hannOla_8k, hannOla_16k, hannOla_24k, hannOla_32k, hannOla_48k }; + +const LC3_FLOAT plc_tdc_lpc_8[17] = {1, 0.998890285693703, 0.995568526105076, 0.990056789412169, 0.982391584470799, 0.972623458066693, 0.960816439805232, 0.947047343167065, 0.931404933402306, 0.913988974871173, 0.894909172128633, 0.874284020464791, 0.852239582727672, 0.828908210053904, 0.804427224606163, 0.778937582561901, 0.752582535420797}; + +const LC3_FLOAT plc_tdc_lpc_16[17] = {1, 0.999722455898711, 0.998890285693703, 0.997504874399492, 0.995568526105076, 0.993084457588532, 0.990056789412169, 0.986490534532745, 0.982391584470799, 0.977766693092529, 0.972623458066693, 0.966970300067793, 0.960816439805232, 0.954171872966123, 0.947047343167065, 0.939454313017299, 0.931404933402306}; + +const LC3_FLOAT plc_tdc_lpc_24[17] = {1, 0.999876637554759, 0.999506641521283, 0.998890285693703, 0.998028026020383, 0.996920500041823, 0.995568526105076, 0.993973102356048, 0.992135405511397, 0.990056789412169, 0.987738783361644, 0.985183090250255, 0.982391584470799, 0.979366309627507, 0.976109476042902, 0.972623458066693, 0.968910791191297}; + +const LC3_FLOAT plc_tdc_lpc_32[17] = {1, 0.999930606751878, 0.999722455898711, 0.999375634094057, 0.998890285693703, 0.998266612655538, 0.997504874399492, 0.996605387627705, 0.995568526105076, 0.994394720400431, 0.993084457588532, 0.991638280913245, 0.990056789412169, 0.988340637503103, 0.986490534532745, 0.984507244288062, 0.982391584470799}; + +const LC3_FLOAT plc_tdc_lpc_48[17] = {1, 0.999969157961872, 0.999876637554759, 0.999722455898711, 0.999506641521283, 0.999229234348730, 0.998890285693703, 0.998489858239427, 0.998028026020383, 0.997504874399492, 0.996920500041823, 0.996275010884819, 0.995568526105076, 0.994801176081669, 0.993973102356048, 0.993084457588532, 0.992135405511397}; + +const LC3_FLOAT plc_tdc_lpc_96[17] = {1, 0.999992289401289, 0.999969157961872, 0.999930606751878, 0.999876637554759, 0.999807252867157, 0.999722455898711, 0.999622250571809, 0.999506641521283, 0.999375634094057, 0.999229234348730, 0.999067449055113, 0.998890285693703, 0.998697752455111, 0.998489858239427, 0.998266612655538, 0.998028026020383}; + +const LC3_FLOAT *plc_tdc_lpc_all[6] = {plc_tdc_lpc_8, plc_tdc_lpc_16, plc_tdc_lpc_24, plc_tdc_lpc_32, plc_tdc_lpc_48, plc_tdc_lpc_96}; + +const LC3_FLOAT plc_tdc_lpc_8_25ms[9] = {1, 0.998890285693703, 0.995568526105076, 0.990056789412169, 0.982391584470799, 0.972623458066693, 0.960816439805232, 0.947047343167065, 0.931404933402306}; + +const LC3_FLOAT plc_preemph_fac[] = {0.62, 0.72, 0.82, 0.92, 0.92, 0.92}; + +const LC3_INT ACC_COEFF_PER_BAND_PLC_8_10ms[81] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80}; +const LC3_INT ACC_COEFF_PER_BAND_PLC_16_10ms[81] = { + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, + 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, + 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, + 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160}; +const LC3_INT ACC_COEFF_PER_BAND_PLC_24_10ms[81] = { + 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, + 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99, 102, 105, 108, 111, 114, 117, 120, 123, + 126, 129, 132, 135, 138, 141, 144, 147, 150, 153, 156, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, + 189, 192, 195, 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, 240}; +const LC3_INT ACC_COEFF_PER_BAND_PLC_32_10ms[81] = { + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, + 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, + 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, + 252, 256, 260, 264, 268, 272, 276, 280, 284, 288, 292, 296, 300, 304, 308, 312, 316, 320}; +const LC3_INT ACC_COEFF_PER_BAND_PLC_48_10ms[81] = { + 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96, 102, 108, 114, 120, + 126, 132, 138, 144, 150, 156, 162, 168, 174, 180, 186, 192, 198, 204, 210, 216, 222, 228, 234, 240, 246, + 252, 258, 264, 270, 276, 282, 288, 294, 300, 306, 312, 318, 324, 330, 336, 342, 348, 354, 360, 366, 372, + 378, 384, 390, 396 , 402, 408, 414, 420, 426, 432, 438, 444, 450, 456, 462, 468, 474, 480}; +const LC3_INT ACC_COEFF_PER_BAND_PLC_96_10ms[81] = { + 0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 168, 180, 192, 204, 216, 228, 240, + 252, 264, 276, 288, 300, 312, 324, 336, 348, 360, 372, 384, 396, 408, 420, 432, 444, 456, 468, 480, 492, + 504, 516, 528, 540, 552, 564, 576, 588, 600, 612, 624, 636, 648, 660, 672, 684, 696, 708, 720, 732, 744, + 756, 768, 780, 792, 804, 816, 828, 840, 852, 864, 876, 888, 900, 912, 924, 936, 948, 960}; + +const LC3_INT* ACC_COEFF_PER_BAND_PLC[] = { + ACC_COEFF_PER_BAND_PLC_8_10ms, ACC_COEFF_PER_BAND_PLC_16_10ms, ACC_COEFF_PER_BAND_PLC_24_10ms, + ACC_COEFF_PER_BAND_PLC_32_10ms, ACC_COEFF_PER_BAND_PLC_48_10ms, ACC_COEFF_PER_BAND_PLC_96_10ms}; + +const LC3_INT ACC_COEFF_PER_BAND_PLC_8_2_5ms[21] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; + +const LC3_INT ACC_COEFF_PER_BAND_PLC_16_2_5ms[41] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40}; + +const LC3_INT ACC_COEFF_PER_BAND_PLC_24_2_5ms[61] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60}; + +const LC3_INT ACC_COEFF_PER_BAND_PLC_32_2_5ms[81] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80}; + +const LC3_INT ACC_COEFF_PER_BAND_PLC_48_2_5ms[61] = { + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, + 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, + 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120}; + +const LC3_INT ACC_COEFF_PER_BAND_PLC_96_2_5ms[81] = { + 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, + 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99, 102, 105, 108, 111, 114, 117, 120, 123, + 126, 129, 132, 135, 138, 141, 144, 147, 150, 153, 156, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, + 189, 192, 195, 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, 240}; + +const LC3_INT* ACC_COEFF_PER_BAND_PLC_2_5ms[] = { + ACC_COEFF_PER_BAND_PLC_8_2_5ms, ACC_COEFF_PER_BAND_PLC_16_2_5ms, ACC_COEFF_PER_BAND_PLC_24_2_5ms, + ACC_COEFF_PER_BAND_PLC_32_2_5ms, ACC_COEFF_PER_BAND_PLC_48_2_5ms, ACC_COEFF_PER_BAND_PLC_96_2_5ms}; + +const LC3_INT ACC_COEFF_PER_BAND_PLC_8_5ms[41] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40}; + +const LC3_INT ACC_COEFF_PER_BAND_PLC_16_5ms[81] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80}; + +const LC3_INT ACC_COEFF_PER_BAND_PLC_24_5ms[41] = {0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, + 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, + 84, 87, 90, 93, 96, 99, 102, 105, 108, 111, 114, 117, 120}; + +const LC3_INT ACC_COEFF_PER_BAND_PLC_32_5ms[81] = { + 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, + 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, + 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, + 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160}; + +const LC3_INT ACC_COEFF_PER_BAND_PLC_48_5ms[81] = { + 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, + 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99, 102, 105, 108, 111, 114, 117, 120, 123, + 126, 129, 132, 135, 138, 141, 144, 147, 150, 153, 156, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, + 189, 192, 195, 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, 240}; + +const LC3_INT ACC_COEFF_PER_BAND_PLC_96_5ms[81] = { + 0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96, 102, 108, 114, 120, + 126, 132, 138, 144, 150, 156, 162, 168, 174, 180, 186, 192, 198, 204, 210, 216, 222, 228, 234, 240, 246, + 252, 258, 264, 270, 276, 282, 288, 294, 300, 306, 312, 318, 324, 330, 336, 342, 348, 354, 360, 366, 372, + 378, 384, 390, 396, 402, 408, 414, 420, 426, 432, 438, 444, 450, 456, 462, 468, 474, 480}; + +const LC3_INT* ACC_COEFF_PER_BAND_PLC_5ms[] = { + ACC_COEFF_PER_BAND_PLC_8_5ms, ACC_COEFF_PER_BAND_PLC_16_5ms, ACC_COEFF_PER_BAND_PLC_24_5ms, + ACC_COEFF_PER_BAND_PLC_32_5ms, ACC_COEFF_PER_BAND_PLC_48_5ms, ACC_COEFF_PER_BAND_PLC_96_5ms}; + +const LC3_INT32 mdct_grp_bins[10] = { 4, 14, 24, 44, 84, 164, 244, 324, 404, 484 }; + diff --git a/lc3plus/constants.h b/lc3plus/constants.h new file mode 100644 index 0000000000000000000000000000000000000000..c0c9e286e55c72bd40851c91fe7229e22d9ef261 --- /dev/null +++ b/lc3plus/constants.h @@ -0,0 +1,203 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#ifndef CONSTANTS_H +#define CONSTANTS_H + +#include "defines.h" +#include "structs.h" + +/* DCT */ +extern const Complex dct2_16[16]; + +/* Ari coder */ +extern const LC3_INT ari_tns_order_cf[2][9]; +extern const LC3_INT ari_tns_freq_cf[8][18]; +extern const LC3_INT ari_spec_lookup_fl[4096]; +extern const LC3_INT ari_spec_cumfreq_fl[64][18]; +extern const LC3_INT ari_spec_bits_fl[64][17]; + +/* SNS */ +extern const LC3_FLOAT sns_LFCB[8][32]; +extern const LC3_FLOAT sns_HFCB[8][32]; +extern const LC3_INT pvq_enc_A[16][11]; +extern const LC3_FLOAT idct_lookup[M][M]; + +/* 12.8 kHz resampler */ +extern const LC3_FLOAT lp_scale_factors[6]; + +extern const LC3_INT32 resamp_params[][4]; +extern const LC3_FLOAT *lp_filter[6]; +extern const LC3_FLOAT highpass50_filt_b[3]; +extern const LC3_FLOAT highpass50_filt_a[3]; +extern const LC3_INT up_fac[6]; + +/* TNS */ +extern const LC3_FLOAT quants_pts_tns[17]; +extern const LC3_INT huff_bits_tns[8][17]; +extern const LC3_INT order1_tns[8]; +extern const LC3_INT order2_tns[8]; +extern const LC3_FLOAT lagw_tns[9]; +extern const LC3_FLOAT quants_pts_tns[17]; +extern const LC3_FLOAT quants_thr_tns[18]; + +/* SNS */ +extern const LC3_FLOAT sns_vq_far_adj_gains_fl[8]; +extern const LC3_FLOAT sns_vq_near_adj_gains_fl[4]; +extern const LC3_FLOAT sns_vq_reg_lf_adj_gains_fl[4]; +extern const LC3_FLOAT q_g_sns[6]; +extern const LC3_FLOAT sns_vq_reg_adj_gains_fl[2]; +extern const LC3_FLOAT sns_dec_gains[4][8]; + +/* Global Gain */ +extern const LC3_INT gg_p1[6]; +extern const LC3_INT gg_p2[6]; +extern const LC3_INT gg_p3[6]; +extern const LC3_FLOAT gg_c[6]; +extern const LC3_FLOAT gg_d[6]; + +/* Olpa */ +extern const LC3_FLOAT olpa_down2[5]; +extern const LC3_FLOAT olpa_acw[98]; + +/* LTPF */ +extern const LC3_FLOAT conf_inter_filter_48[4][12]; +extern const LC3_FLOAT conf_inter_filter_32[4][8]; +extern const LC3_FLOAT conf_inter_filter_24[4][6]; +extern const LC3_FLOAT conf_inter_filter_16[4][4]; +extern const LC3_FLOAT conf_tilt_filter_48[4][11]; +extern const LC3_FLOAT conf_tilt_filter_32[4][7]; +extern const LC3_FLOAT conf_tilt_filter_24[4][5]; +extern const LC3_FLOAT conf_tilt_filter_16[4][3]; +extern const LC3_FLOAT inter4_1[33]; +extern const LC3_FLOAT enc_inter_filter[4][4]; + +/* Bandwidth Detector */ +extern const LC3_INT threshold_quiet[4]; +extern const LC3_INT threshold_brickwall[4]; +extern const LC3_INT brickwall_dist[4]; +extern const LC3_INT BW_warp_idx_start_16k[4]; +extern const LC3_INT BW_warp_idx_stop_16k[4]; +extern const LC3_INT BW_warp_idx_start_24k[4]; +extern const LC3_INT BW_warp_idx_stop_24k[4]; +extern const LC3_INT BW_warp_idx_start_32k[4]; +extern const LC3_INT BW_warp_idx_stop_32k[4]; +extern const LC3_INT BW_warp_idx_start_48k[4]; +extern const LC3_INT BW_warp_idx_stop_48k[4]; +extern const LC3_INT* BW_warp_idx_start_all[4]; +extern const LC3_INT* BW_warp_idx_stop_all[4]; + +extern const LC3_INT BW_warp_idx_start_16k_2_5ms[4]; +extern const LC3_INT BW_warp_idx_stop_16k_2_5ms[4]; +extern const LC3_INT BW_warp_idx_start_24k_2_5ms[4]; +extern const LC3_INT BW_warp_idx_stop_24k_2_5ms[4]; +extern const LC3_INT BW_warp_idx_start_32k_2_5ms[4]; +extern const LC3_INT BW_warp_idx_stop_32k_2_5ms[4]; +extern const LC3_INT BW_warp_idx_start_48k_2_5ms[4]; +extern const LC3_INT BW_warp_idx_stop_48k_2_5ms[4]; +extern const LC3_INT* BW_warp_idx_start_all_2_5ms[4]; +extern const LC3_INT* BW_warp_idx_stop_all_2_5ms[4]; +extern const LC3_INT BW_cutoff_bin_all_2_5ms_HR[MAX_BW_BANDS_NUMBER]; +extern const LC3_INT bands_number_2_5ms_HR[6]; + +extern const LC3_INT BW_cutoff_bin_all_2_5ms[MAX_BW_BANDS_NUMBER]; +extern const LC3_INT bands_number_2_5ms[5]; + + +extern const LC3_INT BW_warp_idx_start_16k_5ms[4]; +extern const LC3_INT BW_warp_idx_stop_16k_5ms[4]; +extern const LC3_INT BW_warp_idx_start_24k_5ms[4]; +extern const LC3_INT BW_warp_idx_stop_24k_5ms[4]; +extern const LC3_INT BW_warp_idx_start_32k_5ms[4]; +extern const LC3_INT BW_warp_idx_stop_32k_5ms[4]; +extern const LC3_INT BW_warp_idx_start_48k_5ms[4]; +extern const LC3_INT BW_warp_idx_stop_48k_5ms[4]; +extern const LC3_INT* BW_warp_idx_start_all_5ms[4]; +extern const LC3_INT* BW_warp_idx_stop_all_5ms[4]; +extern const LC3_INT BW_cutoff_bin_all_5ms[MAX_BW_BANDS_NUMBER]; +extern const LC3_INT bands_number_5ms[6]; +extern const LC3_INT BW_cutoff_bin_all_HR[MAX_BW_BANDS_NUMBER]; +extern const LC3_INT BW_cutoff_bin_all_5ms_HR[MAX_BW_BANDS_NUMBER]; +extern const LC3_INT BW_cutoff_bin_all[MAX_BW_BANDS_NUMBER]; +extern const LC3_INT BW_cutoff_bits_all[MAX_BW_BANDS_NUMBER]; + +/* Arithmetic coding */ +extern const LC3_INT tns_cf[8][18]; +extern const LC3_INT tns_freq_cf[2][9]; + +/* MDCT Windows */ +extern const LC3_FLOAT MDCT_WINDOW_80[160]; +extern const LC3_FLOAT MDCT_WINDOW_160[320]; +extern const LC3_FLOAT MDCT_WINDOW_240[480]; +extern const LC3_FLOAT MDCT_WINDOW_320[640]; +extern const LC3_FLOAT MDCT_WINDOW_480[960]; +extern const LC3_FLOAT MDCT_WINDOW_960[1920]; +extern const LC3_FLOAT* MDCT_WINS_10ms[2][6]; +extern const LC3_INT MDCT_la_zeroes[6]; + +extern const LC3_FLOAT MDCT_WINDOW_80_2_5ms[40]; +extern const LC3_FLOAT MDCT_WINDOW_160_2_5ms[80]; +extern const LC3_FLOAT MDCT_WINDOW_240_2_5ms[120]; +extern const LC3_FLOAT MDCT_WINDOW_320_2_5ms[160]; +extern const LC3_FLOAT MDCT_WINDOW_480_2_5ms[240]; +extern const LC3_FLOAT* MDCT_WINS_2_5ms[2][6]; +extern const LC3_INT MDCT_la_zeroes_2_5ms[6]; + + +extern const LC3_FLOAT MDCT_WINDOW_80_5ms[80]; +extern const LC3_FLOAT MDCT_WINDOW_160_5ms[160]; +extern const LC3_FLOAT MDCT_WINDOW_240_5ms[240]; +extern const LC3_FLOAT MDCT_WINDOW_320_5ms[320]; +extern const LC3_FLOAT MDCT_WINDOW_480_5ms[480]; +extern const LC3_FLOAT* MDCT_WINS_5ms[2][6]; +extern const LC3_INT MDCT_la_zeroes_5ms[6]; + +extern const LC3_INT MDCT_WINDOWS_LENGTHS_10ms[6]; + +extern const LC3_INT MDCT_WINDOWS_LENGTHS_2_5ms[6]; + + +extern const LC3_INT MDCT_WINDOWS_LENGTHS_5ms[6]; + +/* Per band energy */ +extern const LC3_INT* ACC_COEFF_PER_BAND[6]; +extern const LC3_INT* ACC_COEFF_PER_BAND_HR[6]; + +extern const LC3_INT* ACC_COEFF_PER_BAND_2_5ms_HR[6]; +extern const LC3_INT* ACC_COEFF_PER_BAND_2_5ms[5]; + + +extern const LC3_INT* ACC_COEFF_PER_BAND_5ms_HR[6]; +extern const LC3_INT* ACC_COEFF_PER_BAND_5ms[5]; + +/* Near Nyquist detector */ +extern const LC3_INT NN_thresh; + + +extern const LC3_INT32 xavg_N_grp[5]; +extern const LC3_FLOAT *hannOla_wins[5]; +extern const LC3_INT32 gwlpr[MAX_LGW+1]; +extern const LC3_INT32 mdct_grp_bins[10]; +extern const LC3_FLOAT* PhECU_whr16ms_wins[5]; + +extern const LC3_FLOAT plc_preemph_fac[]; +extern const LC3_INT* ACC_COEFF_PER_BAND_PLC[]; +extern const LC3_INT* ACC_COEFF_PER_BAND_PLC_2_5ms[]; +extern const LC3_INT* ACC_COEFF_PER_BAND_PLC_5ms[]; +extern const LC3_FLOAT *plc_tdc_lpc_all[6]; +extern const LC3_FLOAT plc_tdc_lpc_8[17]; +extern const LC3_FLOAT plc_tdc_lpc_16[17]; +extern const LC3_FLOAT plc_tdc_lpc_24[17]; +extern const LC3_FLOAT plc_tdc_lpc_32[17]; +extern const LC3_FLOAT plc_tdc_lpc_48[17]; +extern const LC3_FLOAT plc_tdc_lpc_96[17]; +extern const LC3_FLOAT plc_tdc_lpc_8_25ms[9]; + +#endif diff --git a/lc3plus/cutoff_bandwidth.c b/lc3plus/cutoff_bandwidth.c new file mode 100644 index 0000000000000000000000000000000000000000..642b2afda2ef1848f5b232a4caf9d0770db6ef57 --- /dev/null +++ b/lc3plus/cutoff_bandwidth.c @@ -0,0 +1,27 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +void process_cutoff_bandwidth(LC3_FLOAT *d_fl, LC3_INT len, LC3_INT bw_bin) +{ + LC3_INT i = 0; + + if (len > bw_bin){ + for (i = -1; i < 3; i++) { + d_fl[bw_bin + i] = d_fl[bw_bin + i] * LC3_POW(2, -(i + 2)); + } + + for (i = bw_bin + 3; i < len; i++) { + d_fl[i] = 0; + } + } +} diff --git a/lc3plus/dct4.c b/lc3plus/dct4.c new file mode 100644 index 0000000000000000000000000000000000000000..8fd5784b287477aeffd3ee987e81527f755f2163 --- /dev/null +++ b/lc3plus/dct4.c @@ -0,0 +1,95 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +void dct2_init(Dct2* dct, int length) +{ + assert(length <= MAX_LEN); + dct->length = length; + fft_init(&dct->fft, length); +} + +void dct2_free(Dct2* dct) +{ + if (dct) { + fft_free(&dct->fft); + memset(dct, 0, sizeof(*dct)); + } +} + +void dct2_apply(Dct2* dct, const LC3_FLOAT* input, LC3_FLOAT* output) +{ + Complex tmp1[MAX_LEN]; + Complex tmp2[MAX_LEN]; + int i = 0; + const int len = dct->length; + assert(input != output); + + for (i = 0; i < len / 2; i++) { + tmp1[i] = cmplx(input[i * 2], 0); + tmp1[len - i - 1] = cmplx(input[i * 2 + 1], 0); + } + + fft_apply(&dct->fft, tmp1, tmp2); + + for (i = 0; i < len; i++) { + output[i] = cmul(tmp2[i], dct2_16[i]).r; + } + output[0] /= (LC3_FLOAT)1.414213562373095; /* SQRT(2) */ +} + + +void dct4_init(Dct4* dct, int length) +{ + int i = 0; + assert(length <= MAX_LEN); + dct->length = length; + dct->twid1 = calloc(sizeof(*dct->twid1), length / 2); + dct->twid2 = calloc(sizeof(*dct->twid2), length / 2); + for (i = 0; i < length / 2; i++) { + dct->twid1[i] = cexpi(-(LC3_FLOAT)M_PI * (i + (LC3_FLOAT)0.25) / length); + dct->twid2[i] = cexpi(-(LC3_FLOAT)M_PI * i / length); + } + fft_init(&dct->fft, length / 2); +} + +void dct4_free(Dct4* dct) +{ + if (dct) { + free(dct->twid1); + free(dct->twid2); + fft_free(&dct->fft); + memset(dct, 0, sizeof(*dct)); + } +} + +void dct4_apply(Dct4* dct, const LC3_FLOAT* input, LC3_FLOAT* output) +{ + Complex tmp2[MAX_LEN / 2]; + int i = 0; + Complex* tmp1 = (Complex*)output; + const int len = dct->length; + const LC3_FLOAT norm = (LC3_FLOAT)1.0 / LC3_SQRT((LC3_FLOAT)(len >> 1)); + assert(input != output); + + for (i = 0; i < len / 2; i++) { + tmp1[i] = cmul(cmplx(input[i * 2], input[len - i * 2 - 1]), dct->twid1[i]); + } + + fft_apply(&dct->fft, tmp1, tmp2); + + for (i = 0; i < len / 2; i++) { + Complex t = cmul(tmp2[i], dct->twid2[i]); + output[i * 2] = t.r * norm; + output[len - i * 2 - 1] = -t.i * norm; + } +} diff --git a/lc3plus/dec_entropy.c b/lc3plus/dec_entropy.c new file mode 100644 index 0000000000000000000000000000000000000000..d8512a1068b49c042f627936fa46b0b3df21339b --- /dev/null +++ b/lc3plus/dec_entropy.c @@ -0,0 +1,277 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +static void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit); +static void read_uint_fl(LC3_INT nbits, LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* val); + +void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit) +{ + if (ptr[*bp_side] & *mask_side) { + *bit = 1; + } else { + *bit = 0; + } + + if (*mask_side == 128) { + *mask_side = 1; + *bp_side = *bp_side - 1; + } else { + *mask_side = *mask_side * 2; + } +} + +void read_uint_fl(LC3_INT nbits, LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* val) +{ + LC3_INT bit = 0, i = 0; + + read_bit_fl(ptr, mask_side, bp_side, val); + + for (i = 1; i < nbits; i++) { + read_bit_fl(ptr, mask_side, bp_side, &bit); + *val = *val + (bit << i); + } +} + +#ifdef ENABLE_PADDING +LC3_INT paddingDec_fl(LC3_UINT8* bytes, LC3_INT nbbits, LC3_INT L_spec, LC3_INT bw_cutoff_bits, LC3_INT ep_enabled, LC3_INT* total_padding, LC3_INT *np_zero) +{ + LC3_INT lastnz_threshold; + LC3_INT val, padding_len_bits, padding_len; + LC3_INT bp_side; + LC3_INT mask_side; + LC3_UINT8* ptr = bytes; + + LC3_INT nbbytes = nbbits >> 3; + LC3_INT lastnz; + LC3_INT bw_cutoff_idx; + LC3_INT nbits = ceil(LC3_LOGTWO(L_spec / 2)); + + if (nbits > nbbits) + { + return 1; + } + + *np_zero = 0; + + *total_padding = 0; + + bp_side = (nbbits - 1) >> 3; + mask_side = 1 << (8 - (nbbits - (bp_side << 3))); + + if (bp_side < 19 || bp_side >= LC3PLUS_MAX_BYTES) { + return 1; + } + + ptr = bytes; + + if (bw_cutoff_bits > 0) { + read_uint_fl(bw_cutoff_bits, ptr, &mask_side, &bp_side, &bw_cutoff_idx); + } + + read_uint_fl(nbits, ptr, &mask_side, &bp_side, &lastnz); + + lastnz_threshold = (1 << nbits) - 1 - 1; + + while (lastnz == lastnz_threshold) { + padding_len_bits = 16 - nbits - bw_cutoff_bits - 4; + + /*Read padding length*/ + read_uint_fl(padding_len_bits, ptr, &mask_side, &bp_side, &padding_len); + + /* Read 4 reserved bits */ + read_uint_fl(4, ptr, &mask_side, &bp_side, &val); + + if (ep_enabled == 0) + { + /* Discard padding length bytes */ + bp_side = bp_side - padding_len; + *total_padding = *total_padding + padding_len + 2; + } + else + { + *total_padding = *total_padding + 2; + *np_zero = *np_zero + padding_len; + } + + /* check if minimum payload size is reached */ + if ((nbbytes - (*total_padding + *np_zero)) < 20) { + return 1; + } + + /* Read bandwidth bits */ + if (bw_cutoff_bits > 0) { + read_uint_fl(bw_cutoff_bits, ptr, &mask_side, &bp_side, &bw_cutoff_idx); + } + + read_uint_fl(nbits, ptr, &mask_side, &bp_side, &lastnz); + } + + if (ep_enabled != 0) + { + *total_padding = *total_padding + *np_zero; + } + + return 0; +} +#endif + +void processDecoderEntropy_fl(LC3_UINT8* bytes, LC3_INT numbytes, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT N, LC3_INT fs_idx, + LC3_INT bw_cutoff_bits, LC3_INT* bfi, LC3_INT* gg_idx, LC3_INT* scf_idx, LC3_INT* fac_ns_idx, + LC3_INT* tns_numfilters, LC3_INT* tns_order, LC3_INT* ltpf_idx, LC3_INT* bw_cutoff_idx, LC3_INT* lastnz, + LC3_INT* lsbMode, LC3_INT frame_dms) +{ + + LC3_INT plc_trigger_bw = 0, plc_trigger_last_nz = 0, plc_trigger_SNS1 = 0, plc_trigger_SNS2 = 0, tmp = 0, bit = 0, + submodeMSB = 0, i = 0, ltpf_tmp[3] = {0}, ind = 0, submodeLSB = 0, bp_side_local = 0, mask_side_local = 0; + LC3_UINT8* ptr; + LC3_INT gainMSBbits[4] = {1, 1, 2, 2}; + + *bp_side = -1; + bp_side_local = numbytes - 1; /* Matlab offset by 1 */ + mask_side_local = 1; + *mask_side = -1; + ptr = bytes; + *lsbMode = -1; + *lastnz = -1; + + plc_trigger_bw = 1; /* Bandwidth */ + plc_trigger_last_nz = 1; /* Last non-zero tuple */ + plc_trigger_SNS1 = 1; /* SNS-VQ 2nd stage MPVQ data (24-25 bits) */ + plc_trigger_SNS2 = 1; /* SNS-VQ 2nd stage MPVQ data (24-25 bits) */ + + + + /* Bandwidth */ + if (bw_cutoff_bits > 0) { + read_uint_fl(bw_cutoff_bits, ptr, &mask_side_local, &bp_side_local, bw_cutoff_idx); + + if (fs_idx < *bw_cutoff_idx) { + *bfi = plc_trigger_bw; + + if (*bfi) { + return; + } + } + } else { + *bw_cutoff_idx = fs_idx; + } + + /* Number of TNS filters */ + if (*bw_cutoff_idx < 3 || frame_dms == 25) { + *tns_numfilters = 1; + } else { + *tns_numfilters = 2; + } + + /* Last non-zero tuple */ + read_uint_fl(ceil(LC3_LOGTWO(N / 2)), ptr, &mask_side_local, &bp_side_local, lastnz); + *lastnz = (*lastnz + 1) * 2; + + if (*lastnz > N) { + *bfi = plc_trigger_last_nz; + if (*bfi) { + return; + } + } + + /* LSB mode bit */ + read_bit_fl(ptr, &mask_side_local, &bp_side_local, lsbMode); + + /* Global gain */ + read_uint_fl(8, ptr, &mask_side_local, &bp_side_local, gg_idx); + + /* TNS activation flag */ + for (i = 0; i < *tns_numfilters; i++) { + read_bit_fl(ptr, &mask_side_local, &bp_side_local, &bit); + tns_order[i] = bit; + } + + /* LTPF activation flag */ + read_bit_fl(ptr, &mask_side_local, &bp_side_local, <pf_tmp[0]); + + /* SNS-VQ 1st stage */ + read_uint_fl(5, ptr, &mask_side_local, &bp_side_local, &scf_idx[0]); + read_uint_fl(5, ptr, &mask_side_local, &bp_side_local, &scf_idx[1]); + + /* SNS-VQ 2nd stage side-info (3-4 bits) */ + read_bit_fl(ptr, &mask_side_local, &bp_side_local, &submodeMSB); + scf_idx[2] = submodeMSB * 2; + + read_uint_fl(gainMSBbits[scf_idx[2]], ptr, &mask_side_local, &bp_side_local, &scf_idx[3]); + read_bit_fl(ptr, &mask_side_local, &bp_side_local, &scf_idx[4]); + + /* SNS-VQ 2nd stage MPVQ data (24-25 bits) */ + if (submodeMSB == 0) { + read_uint_fl(25, ptr, &mask_side_local, &bp_side_local, &tmp); + if (tmp >= 33460056) { + *bfi = plc_trigger_SNS1; + if (*bfi) { + return; + } + } + + ind = floor(tmp / 2390004); + scf_idx[5] = tmp - ind * 2390004; + + if (ind < 2) { + submodeLSB = 1; + scf_idx[3] = scf_idx[3] * 2 + ind; + scf_idx[6] = -2; + } else { + submodeLSB = 0; + scf_idx[6] = ind - 2; + } + + } else { + read_uint_fl(24, ptr, &mask_side_local, &bp_side_local, &tmp); + + if (tmp >= 16708096) { + *bfi = plc_trigger_SNS2; + if (*bfi) { + return; + } + } + + if (tmp >= 15158272) { + submodeLSB = 1; + scf_idx[3] = scf_idx[3] * 2 + ((tmp - 15158272) & 1); + scf_idx[5] = floor((tmp - 15158272) / 2); + scf_idx[6] = -2; + } else { + submodeLSB = 0; + scf_idx[5] = tmp; + scf_idx[6] = -1; + } + } + + scf_idx[2] = scf_idx[2] + submodeLSB; + + /* LTPF data */ + if (ltpf_tmp[0] == 1) { + read_bit_fl(ptr, &mask_side_local, &bp_side_local, <pf_tmp[1]); + read_uint_fl(9, ptr, &mask_side_local, &bp_side_local, <pf_tmp[2]); + } else { + ltpf_tmp[1] = 0; + ltpf_tmp[2] = 0; + } + + for (i = 0; i < 3; i++) { + ltpf_idx[i] = ltpf_tmp[i]; + } + + /* Noise factor */ + read_uint_fl(3, ptr, &mask_side_local, &bp_side_local, fac_ns_idx); + + *bp_side = bp_side_local; + *mask_side = mask_side_local; +} diff --git a/lc3plus/dec_lc3_fl.c b/lc3plus/dec_lc3_fl.c new file mode 100644 index 0000000000000000000000000000000000000000..88c528b0f639178567a55b87a2084a20cc9b8864 --- /dev/null +++ b/lc3plus/dec_lc3_fl.c @@ -0,0 +1,365 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + + +static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs_in, void* s_out, int bps, int bfi_ext) +{ + DecSetup* h_DecSetup; + LC3_INT mask_side = 0, bp_side = 0, bfi = 0, gg_idx = 0, fac_ns_idx = 0, tns_numfilters = 0, bw_cutoff_idx = 0, + lastnz = 0, lsbMode = 0, nf_seed = 0, zero_frame = 0, residualPresent = 0, nbits_residual = 0, bitsRead = 0, + i = 0, tns_order[2] = {0}, sqQdec[MAX_LEN] = {0}; + LC3_INT b_left; + LC3_FLOAT stab_fac = 0; + + h_DecSetup = decoder->channel_setup[channel]; + + memset(h_DecSetup->tns_idx, 0, sizeof(*h_DecSetup->tns_idx) * TNS_NUMFILTERS_MAX * MAXLAG); + + bfi = bfi_ext; + + decoder->rframe = 0; + if (bfi == 3) + { + bfi = 2; + decoder->rframe = 1; + } + + /* Entropy decoding */ + if (bfi != 1) { + processDecoderEntropy_fl(bs_in, h_DecSetup->targetBytes, &mask_side, &bp_side, decoder->yLen, decoder->fs_idx, + decoder->BW_cutoff_bits, &bfi, &gg_idx, h_DecSetup->scf_idx, &fac_ns_idx, + &tns_numfilters, tns_order, h_DecSetup->ltpf_param, &bw_cutoff_idx, &lastnz, &lsbMode, decoder->frame_dms + ); + h_DecSetup->BW_cutoff_idx_nf = bw_cutoff_idx; + } + + /* Arithmetic decoding */ + if (bfi != 1) { + processAriDecoder_fl(bs_in, bp_side, mask_side, decoder->yLen, decoder->fs_idx, + h_DecSetup->enable_lpc_weighting, tns_numfilters, lsbMode, lastnz, &bfi, tns_order, fac_ns_idx, gg_idx, h_DecSetup->resBits, + sqQdec, &nf_seed, h_DecSetup->tns_idx, &zero_frame, h_DecSetup->targetBytes, &nbits_residual, &residualPresent, decoder->frame_dms, + decoder->n_pc, decoder->be_bp_left, decoder->be_bp_right, 0, &b_left, &h_DecSetup->spec_inv_idx, + decoder->hrmode + ); + + if (decoder->rframe == 1 && zero_frame == 0 && bfi != 1) + { + LC3_INT32 max_bw_stopband = BW_cutoff_bin_all[bw_cutoff_idx]; + bfi = 2; + switch (decoder->frame_dms) + { +# ifdef ENABLE_025_DMS_MODE + case 25: + max_bw_stopband = max_bw_stopband >> 2; + break; +# endif +# ifdef ENABLE_050_DMS_MODE + case 50: + max_bw_stopband = max_bw_stopband >> 1; + break; +# endif +# ifdef ENABLE_075_DMS_MODE + case 75: + max_bw_stopband = 3 * (max_bw_stopband >> 2); + break; +# endif + case 100: + break; + } + + h_DecSetup->spec_inv_idx = MAX(lastnz, max_bw_stopband); + } + + /* Cast from int to float */ + for (i = 0; i < decoder->yLen; i++) { + h_DecSetup->sqQdec_fl[i] = (LC3_FLOAT)sqQdec[i]; + } + } + + if (bfi != 1) + { + /* SNS Quantize Decoder */ + process_snsQuantizesScf_Dec(h_DecSetup->scf_idx, h_DecSetup->scf_q); + } + if (h_DecSetup->PlcAdvSetup) + { + processPlcComputeStabFacMain_fl(h_DecSetup->scf_q, h_DecSetup->PlcAdvSetup->scf_q_old, h_DecSetup->PlcAdvSetup->scf_q_old_old, bfi, h_DecSetup->PlcSetup.prevBfi, + h_DecSetup->PlcSetup.prevprevBfi, &h_DecSetup->PlcAdvSetup->stabFac); + } + + if ( bfi != 1 ) + { + stab_fac = 1; + if (h_DecSetup->PlcAdvSetup) + { + stab_fac = h_DecSetup->PlcAdvSetup->stabFac; + } + + /* Partial Concealment */ + processPcMain_fl(&bfi, decoder, h_DecSetup->sqQdec_fl, h_DecSetup, h_DecSetup->ltpf_param[0], stab_fac, gg_idx, h_DecSetup->quantizedGainOff, + fac_ns_idx, &h_DecSetup->statePC, h_DecSetup->spec_inv_idx, decoder->yLen); + } + + /* Decoding only if no bit error detected */ + if (bfi != 1) { + /* Residual decoding */ + if (residualPresent) { + processResidualDecoding_fl(&bitsRead, h_DecSetup->sqQdec_fl, decoder->yLen, h_DecSetup->resBits, + nbits_residual + , decoder->hrmode + ); + } + + + /* Noise filling */ + if (zero_frame == 0) { + processNoiseFilling_fl(h_DecSetup->sqQdec_fl, nf_seed, fac_ns_idx, decoder->cutoffBins[h_DecSetup->BW_cutoff_idx_nf], decoder->frame_dms, h_DecSetup->prev_fac_ns, h_DecSetup->spec_inv_idx); + } + + /* Application of global gain */ + processApplyGlobalGain_fl(h_DecSetup->sqQdec_fl, decoder->yLen, gg_idx, h_DecSetup->quantizedGainOff); + + /* TNS decoder */ + processTnsDecoder_fl(h_DecSetup->sqQdec_fl, h_DecSetup->tns_idx, tns_order, tns_numfilters, + decoder->cutoffBins[bw_cutoff_idx], h_DecSetup->N_red_tns, h_DecSetup->fs_red_tns); + + /* SNS interpolation */ + processSnsInterpolateScf_fl(h_DecSetup->scf_q, 0, decoder->bands_number, h_DecSetup->int_scf); + + /* MDCT shaping */ + processMdctShaping_fl(h_DecSetup->sqQdec_fl, h_DecSetup->int_scf, decoder->bands_offset, decoder->bands_number); + } + + /* PLC */ + processPlcMain_fl(h_DecSetup->sqQdec_fl, h_DecSetup->x_fl, decoder, h_DecSetup, bfi, h_DecSetup->PlcAdvSetup, &h_DecSetup->PlcSetup, + decoder->plcMeth, h_DecSetup->ltpf_mem_pitch, h_DecSetup->ltpf_mem_pitch_fr, decoder->tilt, decoder->bands_offset, + decoder->bands_number, decoder->bands_offsetPLC, decoder->n_bandsPLC, decoder->hrmode, &h_DecSetup->statePC); + + processPlcDampingScramblingMain_fl(&h_DecSetup->PlcNsSetup.seed, + &h_DecSetup->statePC.seed, h_DecSetup->statePC.ns_nbLostCmpt_pc, + h_DecSetup->PlcSetup.nbLostCmpt, &h_DecSetup->PlcAdvSetup->stabFac, + &h_DecSetup->PlcAdvSetup->cum_fading_slow, &h_DecSetup->PlcAdvSetup->cum_fading_fast, + h_DecSetup->PlcSetup.q_d_prev, h_DecSetup->sqQdec_fl, h_DecSetup->spec_inv_idx, decoder->yLen, bfi, + decoder->frame_dms, h_DecSetup->concealMethod, h_DecSetup->ltpf_mem_pitch, h_DecSetup->ltpf_param[0], + &h_DecSetup->PlcAdvSetup->cum_fflcAtten); + + /* IMDCT */ + if (h_DecSetup->concealMethod == 4 || bfi != 1 ) + { + ProcessingIMDCT_fl(h_DecSetup->sqQdec_fl, decoder->frame_length, decoder->imdct_win, decoder->imdct_winLen, decoder->imdct_laZeros, + h_DecSetup->imdct_mem, h_DecSetup->x_fl, &h_DecSetup->dct4structImdct); + } + + processPlcUpdate_fl(h_DecSetup->PlcAdvSetup + , decoder->frame_length, h_DecSetup->x_fl, h_DecSetup->scf_q, + &h_DecSetup->PlcSetup.nbLostCmpt, &h_DecSetup->PlcNsSetup.cum_alpha, bfi, &h_DecSetup->PlcSetup.prevBfi, &h_DecSetup->PlcSetup.prevprevBfi); + + /* LTPF decoder */ + process_ltpf_decoder_fl(h_DecSetup->x_fl, decoder->frame_length, h_DecSetup->x_fl, decoder->fs, + h_DecSetup->ltpf_mem_x, h_DecSetup->ltpf_mem_y, &h_DecSetup->ltpf_mem_pitch, + &h_DecSetup->ltpf_mem_pitch_fr, &h_DecSetup->ltpf_mem_gain, &h_DecSetup->ltpf_mem_beta_idx, + bfi, h_DecSetup->ltpf_param, h_DecSetup->ltpf_param_mem, h_DecSetup->ltpf_conf_beta_idx, + h_DecSetup->ltpf_conf_beta, h_DecSetup->concealMethod, h_DecSetup->alpha + , &h_DecSetup->ltpf_mem_active + ); + + { + /* Round, scale and copy output to output buffer */ + if (bps == 16) { + for (i = 0; i < decoder->frame_length; i++) { + LC3_FLOAT tmp = round(h_DecSetup->x_fl[i]); + ((int16_t*)s_out)[i] = (int16_t)fmaxf(fminf(tmp, 32767), -32768); + } + } else { + for (i = 0; i < decoder->frame_length; i++) { + LC3_FLOAT tmp = round(LC3_CONST_POW_2_23 * LC3_CONST_POW_2_M15 * h_DecSetup->x_fl[i]); + ((int32_t*)s_out)[i] = (int32_t)fmaxf(fminf(tmp, LC3_CONST_POW_2_23_RED), LC3_CONST_POW_2_23_NEG); + } + } + } + return bfi; +} + +LC3PLUS_Error Dec_LC3PLUS_fl(LC3PLUS_Dec* decoder, uint8_t* input, LC3_INT32 num_bytes, void** output, LC3_INT32 bps, LC3_INT32 bfi_ext) +{ + LC3_INT32 ch, bfi, lc3_num_bytes; + LC3PLUS_Error err; + LC3_INT32 fec_num_bytes; + LC3_INT32 lc3_channel_num_bytes; + LC3_INT32 channel_bfi, out_bfi; + LC3PLUS_EpModeRequest channel_epmr; + + bfi = bfi_ext; + lc3_num_bytes = 0; + err = LC3PLUS_OK; + + if (bfi == 0) + { + bfi = !num_bytes; + } + + if (decoder->ep_enabled) + { + decoder->combined_channel_coding = decoder->channels > 1 && num_bytes <= 160; + + if (decoder->combined_channel_coding) + { + fec_num_bytes = num_bytes; + + decoder->error_report = + fec_decoder(input, fec_num_bytes, &lc3_num_bytes, (LC3PLUS_EpModeRequest*)&decoder->epmr, decoder->combined_channel_coding, + &decoder->n_pccw, &bfi, &decoder->be_bp_left, &decoder->be_bp_right, &decoder->n_pc, &decoder->m_fec); + + for (ch = 0; ch < decoder->channels; ch++) + { + lc3_channel_num_bytes = lc3_num_bytes / decoder->channels + (ch < (lc3_num_bytes % decoder->channels)); + + + if (bfi != 1 && lc3_channel_num_bytes != decoder->channel_setup[ch]->last_size) + { + err = update_dec_bitrate(decoder, ch, lc3_channel_num_bytes); + if (err) + { + bfi = 1; + decoder->last_error = err; + } + else + { + decoder->channel_setup[ch]->last_size = lc3_channel_num_bytes; + } + } + + bfi = Dec_LC3PLUS_Channel_fl(decoder, ch, input, output[ch], bps, bfi); + input += decoder->channel_setup[ch]->targetBytes; + } + } + else + { + decoder->epmr = LC3PLUS_EPMR_HIGH_NC; + out_bfi = 0; + + for (ch = 0; ch < decoder->channels; ch++) + { + fec_num_bytes = num_bytes / decoder->channels + (ch < (num_bytes % decoder->channels)); + + channel_bfi = bfi; + + decoder->error_report = fec_decoder(input, fec_num_bytes, &lc3_num_bytes, &channel_epmr, + decoder->combined_channel_coding, &decoder->n_pccw, &channel_bfi, + &decoder->be_bp_left, &decoder->be_bp_right, &decoder->n_pc, &decoder->m_fec); + + decoder->epmr = MIN((LC3PLUS_EpModeRequest) decoder->epmr, channel_epmr); + + +#ifdef ENABLE_PADDING + if (channel_bfi != 1) + { + LC3_INT32 padding_len = 0, np_zero = 0; + + if (paddingDec_fl(input, (lc3_num_bytes << 3), decoder->yLen, decoder->BW_cutoff_bits, decoder->ep_enabled, &padding_len, &np_zero)) + { + channel_bfi = 1; + } + + input = input + np_zero; + decoder->n_pc = MAX(decoder->n_pc - (2 * np_zero), 0); + + if (channel_bfi == 2) + { + if (decoder->be_bp_right < (8 * np_zero)) + { + channel_bfi = 0; + decoder->be_bp_left = -1; + decoder->be_bp_right = -1; + } + else + { + decoder->be_bp_right = decoder->be_bp_right - (8 * np_zero); + decoder->be_bp_left = MAX(decoder->be_bp_left - (8 * np_zero), 0); + } + } + lc3_num_bytes = lc3_num_bytes - padding_len; + } +#endif + + if (channel_bfi != 1 && lc3_num_bytes != decoder->channel_setup[ch]->last_size) + { + err = update_dec_bitrate(decoder, ch, lc3_num_bytes); + if (err) + { + channel_bfi = 1; + decoder->last_error = err; + } + else + { + decoder->channel_setup[ch]->last_size = lc3_num_bytes; + } + } + + channel_bfi = Dec_LC3PLUS_Channel_fl(decoder, ch, input, output[ch], bps, channel_bfi); + + out_bfi |= channel_bfi; + input += fec_num_bytes; + } + + bfi = out_bfi & 1; + } + } + else + { + for (ch = 0; ch < decoder->channels; ch++) + { + lc3_num_bytes = num_bytes / decoder->channels + (ch < (num_bytes % decoder->channels)); + +#ifdef ENABLE_PADDING + if (bfi != 1) + { + LC3_INT32 padding_len = 0, np_zero = 0; + + if (paddingDec_fl(input, (lc3_num_bytes << 3), decoder->yLen, decoder->BW_cutoff_bits, decoder->ep_enabled, &padding_len, &np_zero)) + { + bfi = 1; + decoder->last_error = LC3PLUS_PADDING_ERROR; + } + + lc3_num_bytes = lc3_num_bytes - padding_len; + if (lc3_num_bytes < 20 || lc3_num_bytes > LC3PLUS_MAX_BYTES) + { + bfi = 1; /* mark frame as broken if frame size is below the minimum of 20 bytes or above the maximum of LC3PLUS_MAX_BYTES */ + decoder->last_error = FRAMESIZE_ERROR; + } + } +#endif + + if (bfi != 1 && lc3_num_bytes != decoder->channel_setup[ch]->last_size) + { + err = update_dec_bitrate(decoder, ch, lc3_num_bytes); + if (err) + { + bfi = 1; + decoder->last_error = err; + } + else + { + decoder->channel_setup[ch]->last_size = lc3_num_bytes; + } + } + + bfi = Dec_LC3PLUS_Channel_fl(decoder, ch, input, output[ch], bps, bfi); + input += decoder->channel_setup[ch]->targetBytes; + } + } + + if (decoder->last_error == LC3PLUS_OK && bfi) decoder->last_error = LC3PLUS_DECODE_ERROR; + return bfi == 1 ? LC3PLUS_DECODE_ERROR : LC3PLUS_OK; +} diff --git a/lc3plus/defines.h b/lc3plus/defines.h new file mode 100644 index 0000000000000000000000000000000000000000..d978fa4e15e73671ee23cb4eedad8eb9b681ba01 --- /dev/null +++ b/lc3plus/defines.h @@ -0,0 +1,238 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#ifndef DEFINES_H +#define DEFINES_H + +#include "stdint.h" + + +typedef float LC3_FLOAT; +typedef int32_t LC3_INT; +typedef int16_t LC3_INT16; +typedef uint16_t LC3_UINT16; +typedef short LC3_SHORT; +typedef uint8_t LC3_UINT8; +typedef int8_t LC3_INT8; +typedef uint32_t LC3_UINT32; + +/* Release defines */ +// #define ENABLE_2_5MS_MODE +#define ENABLE_5MS_MODE +#define ENABLE_10_MS_MODE +#define ENABLE_ADVANCED_PLC_FL +#define ENABLE_ADVANCED_PLC_FL_DEFAULT +#define ENABLE_BW_CONTROLLER +//#define ENABLE_HR_MODE_FL +#define ENABLE_PADDING +#define ENABLE_RFRAME_FL +#define ENABLE_PLC +/* flags */ +#define ENABLE_PLC_MODE_FLAG +#define ENABLE_BANDWIDTH_FLAG +#define ENABLE_EP_MODE_FLAG +#define ENABLE_FRAME_MS_FLAG +#define ENABLE_HR_MODE_FL_FLAG + +#ifndef NO_POST_REL_CHANGES +/* Post-release non-bitexact changes */ + +#endif /* NO_POST_REL_CHANGES */ + +/* Precision Defines */ +#define LC3_FABS(x) (fabsf(x)) +#define LC3_POW(x, y) (powf(x, y)) +#define LC3_LOGTEN(x) (log10f(x)) +#define LC3_LOGTWO(x) (log2f(x)) +# define LC3_COS(x) (cos(x)) +# define LC3_SIN(x) (sin(x)) +#define LC3_SQRT(x) (sqrtf(x)) +#define LC3_EXP(x) (expf(x)) + +# define MAX_BR 320000 /* 400 * 800 */ +# define MIN_BR_100DMS 16000 /* 20 * 800 * 100/100 */ +# define MIN_BR_025DMS 64000 /* 20 * 800 * 100/ 25 */ +# define MIN_BR_050DMS 32000 /* 20 * 800 * 100/ 50 */ +# define MAX_BR_050DMS_NB 260800 /* 163 * 800 * 100/ 50 */ +# define MAX_BR_100DMS_NB 114400 /* for 100ms at 8kHz */ + +# define MAX_BR_100DMS_WB 221600 /* for 100ms at 16kHz */ +# define MAX_BR_100DMS_SSWB 314400 /* for 100ms at 24kHz */ + +typedef int32_t LC3_INT32; + +# if defined(__xtensa__) +# define ALIGNMENT_BALLOC 4 +# define ALIGNMENT_BALLOC_RED 3 +# else +# define ALIGNMENT_BALLOC 8 +# define ALIGNMENT_BALLOC_RED 7 +# endif + +# define PLC2_FADEOUT_IN_MS 30 +# define PHECU_FRES 62.5 +# define PHECU_C_JACOB 1.1429 +# define MAX_LGW 9 /* LGW48K + 1 !! */ +# define QUOT_LPR_LTR 4 +# define MAX_PLC_LPROT ((512 * 48) / 32) +# define MAX_PLC_NPLOCS ((MAX_PLC_LPROT / 4) + 1) +# define MAX_PLC_LMSPEC ((MAX_PLC_LPROT / 2) + 1) +# define MAX_PLC_LMEM (400) /* "only" up to 20kHz (400 MDCT bins at 10 ms) at 48 kHz supported by PhEcu */ + +# define POS_ONE_Q15 (32767.0 / 32768.0) +# define PHECU_LTOT_MIN_MAN 1 /* lowest possible mantissa energy value */ +# define PHECU_LTOT_MIN_EXP -61 /* L_tot = PHECU_LTOT_MIN_MAN*2^(PHECU_LTOT_MIN_EXP-31) */ +# define PHECU_LTOT_MIN +# define PHECU_GRP_SHAPE_INIT 0 /* BASOP Q15 */ +# define PHECU_ENV_STAB_LOCAL POS_ONE_Q15 +# define PHECU_DELTA_CORR 5 +# define PHECU_PFIND_SENS 0.93 +# define PHECU_LA 0 + +# define LC3_ROUND(x) (roundf(x)) +# define LC3_FLOOR(x) (floorf(x)) + +# define LC3_CONST_POW_2_16 65536 +# define LC3_CONST_POW_2_M16 1.525878906250000e-05 +# define LC3_CONST_POW_2_100 1.267650600228229e+30 + +# define MAX_LEN_PCM_PLC (MAX_PITCH + MAX_LEN) +# define MAX_PITCH CEILING((MAX_PITCH_12K8 * MAX_LEN * 100), 12800) +# define TDC_L_FIR_HP 11 +# define PLC3_HPBLENDTHROTTLE 30 /* higher numbers increase throttled blending from hp filtered to unfiltered uv excitation (0 is no throttle) */ + +# define PLC_FADEOUT_IN_MS 60 /* fade-out to zero in ms for TD-PLC and NS, minimum value is 20 */ +# define PLC4_TRANSIT_START_IN_MS 20 /* begin of transition time for noise substitution for voiced signals */ +# define PLC4_TRANSIT_END_IN_MS PLC_FADEOUT_IN_MS /* end of transition time for noise substitution */ +# define PLC34_ATTEN_FAC_100 0.5000 /* attenuation factor for NS and TDC @ 10 ms*/ +# define PLC34_ATTEN_FAC_050 0.7071 /* attenuation factor for NS and TDC @ 5.0 ms*/ +# define PLC34_ATTEN_FAC_025 0.8409 /* attenuation factor for NS and TDC @ 2.5 ms*/ + +# define FEC_SLOT_BYTES_MIN 40 +# define FEC_SLOT_BYTES_MAX 400 + + +# define LC3_CONST_POW_2_M15 3.051757812500000e-05 +# define LC3_CONST_POW_2_23 8388608 +# define LC3_CONST_POW_2_23_NEG -8388608 +# define LC3_CONST_POW_2_23_RED 8388607 + +# define LC3_CONST_POW_2_100 1.267650600228229e+30 + +/* G192 bitstream writing/reading */ +#define G192_REDUNDANCY_FRAME 0x6B22 +#define G192_GOOD_FRAME 0x6B21 +#define G192_BAD_FRAME 0x6B20 +#define G192_ZERO 0x007F +#define G192_ONE 0x0081 +#define READ_G192FER /* Allow C executable to also read G192 formatted FER files */ + +# define LC3_EPS (1.1e-7f) + +#define M_PI 3.14159265358979323846 + +/* FUNCTION MACROS */ +#define CEILING(x, y) (((x) + (y)-1) / (y)) +#define FRAME2FS_IDX(x) (x / 100) /* 80 -> 0, 160 -> 1, 240 -> 2, 320 -> 3, 480 -> 4*/ +#define FS2FS_IDX(x) \ + (x / 10000) /* 8000 -> 0, 16000 -> 1, 24000 -> 2, 32000 -> 3, 48000 -> 4 \ + */ +#define UNUSED(x) (void)(x) /* silence unused parameter warning */ +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define STATIC_ASSERTS(cond, s) typedef char assert_##s[(cond) ? 1 : -1] +#define STATIC_ASSERTI(cond, i) STATIC_ASSERTS(cond, i) +#define STATIC_ASSERT(cond) STATIC_ASSERTI(cond, __LINE__) + +/* For dynamic memory calculations */ +#define CODEC_FS(fs) ((fs) == 44100 ? 48000 : (fs)) +#define DYN_MAX_LEN(fs) MAX(CODEC_FS(fs) / 100, 160) +# define DYN_MAX_LEN_EXT(fs) MAX(CODEC_FS(fs) / 100, 160) /* extension to length 160 for NB(fs=8000) */ +#define DYN_MAX_MDCT_LEN(fs) (DYN_MAX_LEN(fs) - (180 * DYN_MAX_LEN(fs) / 480)) + +/* OPTIONS */ + +#define MAX_SR 96000 +#define EXT_RES_ITER_MAX 20 +#define MAX_BW_BANDS_NUMBER 6 +#define MAX_LEN MAX_SR/100 /* = 10ms at 96kHz */ +#define MAX_RESBITS 5000 +#define MAX_RESBITS_LEN ((MAX_RESBITS + 7)/8) + +#define MAX_CHANNELS 2 +#define MIN_NBYTES 20 /* 100dms: 16 kbps at !=44.1kHz, 14.7kbps at 44.1kHz + 50dms: 32 kbps at !=44.1kHz, 29.4kbps at 44.1kHz + 25dms: 64 kbps at !=44.1kHz, 58.8kbps at 44.1kHz */ +#define MAX_NBYTES_025 100 /* any dms: 320 kbps at !=44.1kHz, 294 kbps at 44.1kHz */ +#define MAX_NBYTES_050 200 /* any dms: 320 kbps at !=44.1kHz, 294 kbps at 44.1kHz */ +#define MAX_NBYTES_100 400 /* any dms: 320 kbps at !=44.1kHz, 294 kbps at 44.1kHz */ + +#ifdef ENABLE_HR_MODE_FL +# define MIN_BR_25MS_48KHZ_HR ((int)172800/3200/2)*3200 +# define MIN_BR_25MS_96KHZ_HR ((int)198400/3200/2)*3200 +# define MIN_BR_50MS_48KHZ_HR ((int)148800/1600/2)*1600 +# define MIN_BR_50MS_96KHZ_HR ((int)174400/1600/2)*1600 +# define MIN_BR_100MS_48KHZ_HR ((int)124800/800/2)*800 +# define MIN_BR_100MS_96KHZ_HR ((int)149600/800/2)*800 +#endif /* ENABLE_HR_MODE */ +#define MAX_NBYTES2 625 +#define BYTESBUFSIZE (MAX_NBYTES2 * MAX_CHANNELS) +#define MAX_BW_BIN 400 +#if MAX_BW_BIN > MAX_LEN +# define MAX_BW MAX_LEN +#else +# define MAX_BW MAX_BW_BIN +#endif + +# ifdef ENABLE_HR_MODE_FL +# define MAX_BW_HR 960 +# endif + +/* SCF */ +#define M 16 +#define MAX_BANDS_NUMBER 64 +#define MAX_BANDS_NUMBER_PLC 80 +#define PVQ_MAX_VEC_SIZE M + +/* PVQ VQ setup */ +#define SCF_MAX_PARAM \ + 7 /* (L+H) + submode_MSB +gain+(Ia_leads+Ia_mpvq)+(Ib_joint_mpvq), \ + submode-LSB */ + +/* RESIDUAL CODING */ +#define NPRM_RESQ 5 * MAX_LEN + +/* MDCT */ +#define MDCT_MEM_LEN_MAX (MAX_LEN - ((180 * MAX_LEN) / 480)) + +/* TNS */ +#define TNS_NUMFILTERS_MAX 2 +#define MAXLAG 8 + +/* OLPA/LTPF */ +#define LEN_12K8 128 +#define LEN_6K4 64 +#define MIN_PITCH_6K4 17 +#define MAX_PITCH_6K4 114 +#define RANGE_PITCH_6K4 98 +#define MIN_PITCH_12K8 32 +#define MAX_PITCH_12K8 228 +#define RES2_PITCH_12K8 157 +#define RES4_PITCH_12K8 127 +#define LTPF_MEMIN_LEN (MAX_PITCH_12K8 + 4) + +/* Advanced PLC */ + + + +/* some configurations leave empty translation units. */ +extern int fix_empty_translation_unit_warning; + +#endif diff --git a/lc3plus/detect_cutoff_warped.c b/lc3plus/detect_cutoff_warped.c new file mode 100644 index 0000000000000000000000000000000000000000..9392867208e6d9270092e5789153a267c68f13e8 --- /dev/null +++ b/lc3plus/detect_cutoff_warped.c @@ -0,0 +1,84 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +void processDetectCutoffWarped_fl(LC3_FLOAT* d2, LC3_INT fs_idx, LC3_INT frame_dms, LC3_INT* bw_idx) +{ + const LC3_INT *warp_idx_start = NULL, *warp_idx_stop = NULL; + LC3_INT counter = 0, brickwall = 0, i = 0, stop = 0, dist = 0; + LC3_FLOAT d2_mean = 0, d2_sum = 0, e_diff = 0, thr = 0; + const LC3_INT *bw_dist = NULL; + + warp_idx_start = BW_warp_idx_start_all[fs_idx - 1]; + warp_idx_stop = BW_warp_idx_stop_all[fs_idx - 1]; + + switch (frame_dms) + { + case 25: + warp_idx_start = BW_warp_idx_start_all_2_5ms[fs_idx - 1]; + warp_idx_stop = BW_warp_idx_stop_all_2_5ms[fs_idx - 1]; + bw_dist = brickwall_dist; + break; + case 50: + warp_idx_start = BW_warp_idx_start_all_5ms[fs_idx - 1]; + warp_idx_stop = BW_warp_idx_stop_all_5ms[fs_idx - 1]; + bw_dist = brickwall_dist; + break; + case 100: + warp_idx_start = BW_warp_idx_start_all[fs_idx - 1]; + warp_idx_stop = BW_warp_idx_stop_all[fs_idx - 1]; + bw_dist = brickwall_dist; + break; + } + + counter = fs_idx; + + d2_sum = sum_vec(&d2[warp_idx_start[counter - 1]], warp_idx_stop[counter - 1] - warp_idx_start[counter - 1] + 1); + + d2_mean = d2_sum / (warp_idx_stop[counter - 1] - warp_idx_start[counter - 1] + 1); + + while (d2_mean < threshold_quiet[counter - 1]) { + d2_sum = 0; + counter--; + if (counter == 0) { + break; + } + + /* calculate mean energy per band */ + d2_sum = + sum_vec(&d2[warp_idx_start[counter - 1]], warp_idx_stop[counter - 1] - warp_idx_start[counter - 1] + 1); + + d2_mean = d2_sum / (warp_idx_stop[counter - 1] - warp_idx_start[counter - 1] + 1); + } + + *bw_idx = counter; + + /* check if energy difference between bands is present */ + if (*bw_idx < fs_idx) { + thr = (LC3_FLOAT)threshold_brickwall[counter]; + stop = warp_idx_start[counter]; + dist = bw_dist[counter]; + + for (i = stop; i >= stop - dist; i--) { + e_diff = 10.0 * LC3_LOGTEN(d2[i - dist + 1] + FLT_EPSILON) - 10.0 * LC3_LOGTEN(d2[i + 1] + FLT_EPSILON); + + if (e_diff > thr) { + brickwall = 1; + break; + } + } + + if (brickwall == 0) { + *bw_idx = fs_idx; + } + } +} diff --git a/lc3plus/enc_entropy.c b/lc3plus/enc_entropy.c new file mode 100644 index 0000000000000000000000000000000000000000..a7ff8cd70006ea601d7ffa0b579989a3258ba9f7 --- /dev/null +++ b/lc3plus/enc_entropy.c @@ -0,0 +1,126 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +void processEncoderEntropy_fl(LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT numbytes, LC3_INT bw_cutoff_bits, + LC3_INT bw_cutoff_idx, LC3_INT lastnz, LC3_INT N, LC3_INT lsbMode, LC3_INT gg_idx, LC3_INT num_tns_filters, + LC3_INT* tns_order, LC3_INT* ltpf_idx, LC3_INT* scf_idx, LC3_INT fac_ns_idx + , LC3_INT bfi_ext, LC3_INT fs_idx + ) +{ + LC3_UINT8* ptr; + LC3_INT i = 0, submodeMSB = 0, submodeLSB = 0, tmp = 0, gainMSB = 0, gainLSB = 0; + LC3_INT gainMSBbits[4] = {1, 1, 2, 2}, gainLSBbits[4] = {0, 1, 0, 1}; + + LC3_INT16 lastnzTrigger[5] = {63, 127, 127, 255, 255}; + + *bp_side = numbytes - 1; + *mask_side = 1; + ptr = bytes; + + /* Bandwidth */ + if (bw_cutoff_bits > 0) { + write_uint_backward_fl(ptr, bp_side, mask_side, bw_cutoff_idx, bw_cutoff_bits); + } + + /* Last non zero touple */ + if (bfi_ext == 1) { + write_uint_backward_fl(ptr, bp_side, mask_side, lastnzTrigger[fs_idx], ceil(LC3_LOGTWO(N >> 1))); + } + else + { + write_uint_backward_fl(ptr, bp_side, mask_side, lastnz / 2 - 1, ceil(LC3_LOGTWO(N / 2))); + } + + /* LSB mode bit */ + write_bit_backward_fl(ptr, bp_side, mask_side, lsbMode); + + /* Global gain */ + write_uint_backward_fl(ptr, bp_side, mask_side, gg_idx, 8); + + /* TNS activation flag */ + for (i = 0; i < num_tns_filters; i++) { + write_bit_backward_fl(ptr, bp_side, mask_side, MIN(1, tns_order[i])); + } + + /* LTPF activation flag */ + write_bit_backward_fl(ptr, bp_side, mask_side, ltpf_idx[0]); + + /* SNS-VQ 1st stage */ + write_uint_backward_fl(ptr, bp_side, mask_side, scf_idx[0], 5); + write_uint_backward_fl(ptr, bp_side, mask_side, scf_idx[1], 5); + + /* SNS-VQ 2nd stage side-info (3-4 bits) */ + submodeMSB = scf_idx[2] / 2; + submodeLSB = scf_idx[2] & 1; + write_bit_backward_fl(ptr, bp_side, mask_side, submodeMSB); + gainMSB = scf_idx[3] >> (gainLSBbits[scf_idx[2]]); + gainLSB = scf_idx[3] & 1; + write_uint_backward_fl(ptr, bp_side, mask_side, gainMSB, gainMSBbits[scf_idx[2]]); + write_bit_backward_fl(ptr, bp_side, mask_side, scf_idx[4]); + + /* SNS-VQ 2nd stage MPVQ data (24-25 bits) */ + if (submodeMSB == 0) { + if (submodeLSB == 0) { + tmp = scf_idx[6] + 2; + } else { + tmp = gainLSB; + } + + tmp = tmp * 2390004 + scf_idx[5]; + write_uint_backward_fl(ptr, bp_side, mask_side, tmp, 25); + } else { + tmp = scf_idx[5]; + + if (submodeLSB != 0) { + tmp = 2 * tmp + gainLSB + 15158272; + } + + write_uint_backward_fl(ptr, bp_side, mask_side, tmp, 24); + } + + /* LTPF data */ + if (ltpf_idx[0] == 1) { + write_uint_backward_fl(ptr, bp_side, mask_side, ltpf_idx[1], 1); + write_uint_backward_fl(ptr, bp_side, mask_side, ltpf_idx[2], 9); + } + + /* Noise factor */ + write_uint_backward_fl(ptr, bp_side, mask_side, fac_ns_idx, 3); +} + +void write_uint_backward_fl(LC3_UINT8* ptr, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT val, LC3_INT numbits) +{ + LC3_INT k = 0, bit = 0; + + for (k = 0; k < numbits; k++) { + bit = val & 1; + write_bit_backward_fl(ptr, bp_side, mask_side, bit); + val = val / 2; + } +} + +void write_bit_backward_fl(LC3_UINT8* ptr, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT bit) +{ + if (bit == 0) { + ptr[*bp_side] = ptr[*bp_side] & (255 - *mask_side); + } else { + ptr[*bp_side] = ptr[*bp_side] | *mask_side; + } + + if (*mask_side == 128) { + *mask_side = 1; + *bp_side = *bp_side - 1; + } else { + *mask_side = *mask_side * 2; + } +} diff --git a/lc3plus/enc_lc3_fl.c b/lc3plus/enc_lc3_fl.c new file mode 100644 index 0000000000000000000000000000000000000000..c89f7244ca8e03bc7593d0a49ebc873f14981c8c --- /dev/null +++ b/lc3plus/enc_lc3_fl.c @@ -0,0 +1,270 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s_in, uint8_t* bytes, int bps +, LC3_INT32 bfi_ext +) +{ + EncSetup* h_EncSetup; + + LC3_INT s_12k8_len = 0, T0_out = 0, ltpfBits = 0, BW_cutoff_idx = 0, tns_numfilters = 0, quantizedGain = 0, + quantizedGainMin = 0, nbits = 0, nbits2 = 0, lastnz = 0, lsbMode = 0, gainChange = 0, bp_side = 0, + mask_side = 0, fac_ns_idx = 0, numResBits = 0, tns_order[2] = {0}, i = 0; + LC3_FLOAT normcorr = 0, gain = 0; + + + LC3_FLOAT d_fl[MAX_LEN] = {0}; + LC3_INT q_d[MAX_LEN] = {0}; + LC3_INT indexes[TNS_NUMFILTERS_MAX * MAXLAG] = {0}; + + h_EncSetup = encoder->channel_setup[channel]; + memset(bytes, 0, sizeof(uint8_t) * h_EncSetup->targetBytes); + + if (bps == 24) { + for (i = 0; i < encoder->frame_length; i++) { + int32_t tmp = ((int32_t*)s_in)[i]; + + if (tmp >= 0) + { + tmp = tmp & 0x007fffff; + } + else + { + tmp = tmp | (int32_t)0xff800000; + } + + h_EncSetup->s_in_scaled[i] = ((LC3_FLOAT) tmp / (float) LC3_POW(2, 8)); + } + } else if (bps == 16) { + for (i = 0; i < encoder->frame_length; i++) { + h_EncSetup->s_in_scaled[i] = (LC3_FLOAT)((int16_t*)s_in)[i]; + } + } + + /* MDCT */ + processMdct_fl(h_EncSetup->s_in_scaled, d_fl, &h_EncSetup->mdctStruct); + + /* 12.8 kHz resampler */ + process_resamp12k8_fl(h_EncSetup->s_in_scaled, encoder->frame_length, h_EncSetup->r12k8_mem_in, + encoder->r12k8_mem_in_len, h_EncSetup->r12k8_mem_50, h_EncSetup->r12k8_mem_out, + encoder->r12k8_mem_out_len, h_EncSetup->s_12k8, &s_12k8_len, encoder->fs_idx, + encoder->frame_dms, encoder->fs); + + /* Pitch estimation */ + processOlpa_fl(h_EncSetup->s_12k8, h_EncSetup->olpa_mem_s12k8, h_EncSetup->olpa_mem_s6k4, + &h_EncSetup->olpa_mem_pitch, &T0_out, &normcorr, s_12k8_len, encoder->frame_dms); + + /* LTPF encoder */ + process_ltpf_coder_fl(h_EncSetup->s_12k8, s_12k8_len + 1, h_EncSetup->ltpf_enable, T0_out, normcorr, + encoder->frame_dms, h_EncSetup->ltpf_mem_in, encoder->ltpf_mem_in_len, + &h_EncSetup->ltpf_mem_normcorr, &h_EncSetup->ltpf_mem_ltpf_on, + &h_EncSetup->ltpf_mem_pitch, h_EncSetup->ltpf_param, &h_EncSetup->ltpf_mem_mem_normcorr, + <pfBits); + + /* Attack detector */ + attack_detector_fl(h_EncSetup->s_in_scaled, encoder->frame_length, encoder->fs, &h_EncSetup->attdec_position, + &h_EncSetup->attdec_acc_energy, &h_EncSetup->attdec_detected, h_EncSetup->attdec_filter_mem, + h_EncSetup->attack_handling, encoder->attdec_nblocks, encoder->attdec_hangover_thresh); + + /* Per-band energy */ + processPerBandEnergy_fl(encoder->bands_number, encoder->bands_offset, encoder->hrmode, encoder->frame_dms, h_EncSetup->ener, d_fl); + /* Near Nyquist detector */ + processNearNyquistdetector_fl(&encoder->near_nyquist_flag, encoder->fs_idx, encoder->near_nyquist_index, encoder->bands_number, h_EncSetup->ener); + + /* Disable LTPF if nyquist detector triggers or -lfe mode is active*/ + if (encoder->near_nyquist_flag != 0 || h_EncSetup->lfe == 1) + { + h_EncSetup->ltpf_mem_ltpf_on = 0; + h_EncSetup->ltpf_param[1] = 0; + } + + /* Bandwidth cut-off detection */ + if (h_EncSetup->lfe == 0) { + /* No BW Cutoff for 8 kHz and 96 kHz. No detection if bandwidth controller is active */ + if (encoder->fs_idx > 0 && encoder->hrmode == 0 && encoder->bw_ctrl_active == 0) { + processDetectCutoffWarped_fl(h_EncSetup->ener, encoder->fs_idx, encoder->frame_dms, &BW_cutoff_idx); + } else { + BW_cutoff_idx = encoder->fs_idx; + } + } else { + BW_cutoff_idx = 0; + } + + processSnsComputeScf_fl(h_EncSetup->ener, encoder->tilt, encoder->bands_number, h_EncSetup->scf, + h_EncSetup->attdec_detected, encoder->sns_damping, encoder->attdec_damping); + + /* SNS Quantizer */ + process_snsQuantizesScf_Enc(h_EncSetup->scf, h_EncSetup->L_scf_idx, h_EncSetup->scf_q, h_EncSetup->dct2StructSNS); + + /* SNS Interpolation */ + processSnsInterpolateScf_fl(h_EncSetup->scf_q, 1, encoder->bands_number, h_EncSetup->int_scf); + + /* MDCT shaping */ + processMdctShaping_fl(d_fl, h_EncSetup->int_scf, encoder->bands_offset, encoder->bands_number); + + /* Bandwidth controller */ + if (encoder->bandwidth < encoder->fs / 2) { + process_cutoff_bandwidth(d_fl, encoder->yLen, encoder->bw_ctrl_cutoff_bin); + BW_cutoff_idx = MIN(BW_cutoff_idx, encoder->bw_index); + } + + /* TNS encoder */ + if (h_EncSetup->lfe == 0) + { + processTnsCoder_fl(d_fl, BW_cutoff_idx, encoder->cutoffBins[BW_cutoff_idx], encoder->fs, encoder->frame_length, + encoder->frame_dms, h_EncSetup->total_bits, tns_order, indexes, &tns_numfilters, + &(h_EncSetup->tns_bits) + , encoder->near_nyquist_flag + ); + } + else + { + tns_numfilters = 1; + tns_order[0] = 0; + h_EncSetup->tns_bits = tns_numfilters; + } + /* Global Gain Estimation */ + h_EncSetup->targetBitsQuant = h_EncSetup->targetBitsInit - (h_EncSetup->tns_bits + ltpfBits); + + if (h_EncSetup->targetBitsQuant < 0 && ltpfBits > 1) + { + /* Disable LTPF */ + h_EncSetup->ltpf_mem_ltpf_on = 0; + h_EncSetup->ltpf_param[1] = 0; + ltpfBits = 1; + h_EncSetup->targetBitsQuant = h_EncSetup->targetBitsInit - (h_EncSetup->tns_bits + ltpfBits); + } + + processEstimateGlobalGain_fl(d_fl, encoder->yLen, h_EncSetup->targetBitsQuant, &gain, &quantizedGain, + &quantizedGainMin, h_EncSetup->quantizedGainOff, &h_EncSetup->targetBitsOff, + &h_EncSetup->mem_targetBits, h_EncSetup->mem_specBits + , encoder->hrmode, h_EncSetup->regBits, encoder->frame_ms + + ); + + /* 1. Quantization */ + processQuantizeSpec_fl(d_fl, gain, q_d, encoder->yLen, h_EncSetup->total_bits, &nbits, &nbits2, encoder->fs, + &lastnz, h_EncSetup->codingdata, &lsbMode, -1, h_EncSetup->targetBitsQuant, encoder->hrmode + ); + + h_EncSetup->mem_specBits = nbits; + + /* Global Gain Adjustment */ + processAdjustGlobalGain_fl(&quantizedGain, quantizedGainMin, h_EncSetup->quantizedGainOff, &gain, + h_EncSetup->targetBitsQuant, h_EncSetup->mem_specBits, &gainChange, encoder->fs_idx + , encoder->hrmode, encoder->frame_dms + ); + + /* 2. Quantization */ + if (gainChange) { + processQuantizeSpec_fl(d_fl, gain, q_d, encoder->yLen, h_EncSetup->total_bits, &nbits, &nbits2, encoder->fs, + &lastnz, + h_EncSetup->codingdata, + &lsbMode, 0, h_EncSetup->targetBitsQuant + , encoder->hrmode + ); + } + + /* Noise factor */ + if (h_EncSetup->lfe == 0) + { + processNoiseFactor_fl(&fac_ns_idx, d_fl, q_d, gain, encoder->cutoffBins[BW_cutoff_idx], encoder->frame_dms, + h_EncSetup->targetBytes + ); + } + else + { + fac_ns_idx = 7; + } + /* Residual Coding */ + if (lsbMode == 0) { + processResidualCoding_fl(d_fl, q_d, gain, encoder->yLen, h_EncSetup->targetBitsQuant, nbits2, + h_EncSetup->resBits, &numResBits + , encoder->hrmode + ); + } else { + numResBits = 0; + } + + /* Entropy encoding */ + processEncoderEntropy_fl(bytes, &bp_side, &mask_side, h_EncSetup->targetBytes, encoder->BW_cutoff_bits, + BW_cutoff_idx, lastnz, encoder->yLen, lsbMode, quantizedGain, tns_numfilters, tns_order, + h_EncSetup->ltpf_param, h_EncSetup->L_scf_idx, fac_ns_idx + , bfi_ext, encoder->fs_idx + ); + + /* Artithmetic encoding */ + processAriEncoder_fl(bytes, bp_side, mask_side, q_d, tns_order, tns_numfilters, indexes, lastnz, + h_EncSetup->codingdata, + h_EncSetup->resBits, numResBits, lsbMode, h_EncSetup->targetBitsAri, + h_EncSetup->enable_lpc_weighting); + + if (encoder->combined_channel_coding == 0 && h_EncSetup->n_pc > 0) + { + LC3_INT32 xbuf[MAX_LEN] = {0}, nf_seed, tns_idx[M], zero_frame, nbits_residual, residualPresent, b_left, spec_inv_idx; + + memset(h_EncSetup->resBits, 0, sizeof(*(h_EncSetup->resBits)) * MAX_RESBITS_LEN); + + processAriDecoder_fl(bytes, bp_side, mask_side, encoder->yLen, encoder->fs_idx, h_EncSetup->enable_lpc_weighting, + tns_numfilters, lsbMode, lastnz, &bfi_ext, tns_order, fac_ns_idx, quantizedGain, + h_EncSetup->resBits, xbuf, &nf_seed, tns_idx, &zero_frame, h_EncSetup->targetBytes, &nbits_residual, + &residualPresent, encoder->frame_dms, h_EncSetup->n_pc, 0, h_EncSetup->total_bits >> 3, 1, &b_left, + &spec_inv_idx, encoder->hrmode); + + processReorderBitstream_fl(bytes, h_EncSetup->n_pccw, h_EncSetup->n_pc, b_left, h_EncSetup->targetBytes); + } + +} + +int Enc_LC3PLUS_fl(LC3PLUS_Enc* encoder, void** input, uint8_t* output, int bps +, LC3_INT32 bfi_ext +) +{ + int ch = 0, output_size = 0; + uint8_t* lc3buf = output; + + LC3_INT32 totalBytes; + LC3_INT32 output_size2, input_size; + + totalBytes = encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in); + + for (ch = 0; ch < encoder->channels; ch++) + { + Enc_LC3PLUS_Channel_fl(encoder, ch, input[ch], lc3buf, bps, bfi_ext); + if (encoder->epmode && encoder->combined_channel_coding == 0) + { + output_size2 = totalBytes / encoder->channels + (ch < (totalBytes % encoder->channels)); + + fec_encoder(encoder->epmode, encoder->epmr, lc3buf, encoder->channel_setup[ch]->targetBytes, output_size2, + encoder->channel_setup[ch]->n_pccw); + + lc3buf += output_size2; + output_size += output_size2; + } + else + { + lc3buf += encoder->channel_setup[ch]->targetBytes; + output_size += encoder->channel_setup[ch]->targetBytes; + } + } + + if (encoder->epmode > 0 && encoder->combined_channel_coding) + { + input_size = output_size; + output_size = encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in); + + fec_encoder(encoder->epmode, encoder->epmr, output, input_size, output_size, encoder->channel_setup[0]->n_pccw); + } + + return output_size; +} diff --git a/lc3plus/estimate_global_gain.c b/lc3plus/estimate_global_gain.c new file mode 100644 index 0000000000000000000000000000000000000000..df9b1f5f238f39cfe0c41ae58c398b8746a970df --- /dev/null +++ b/lc3plus/estimate_global_gain.c @@ -0,0 +1,128 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + + +void processEstimateGlobalGain_fl(LC3_FLOAT x[], LC3_INT lg, LC3_INT nbitsSQ, LC3_FLOAT* gain, LC3_INT* quantizedGain, + LC3_INT* quantizedGainMin, LC3_INT quantizedGainOff, LC3_FLOAT* targetBitsOff, + LC3_INT* old_targetBits, LC3_INT old_specBits + , LC3_INT hrmode , LC3_INT regBits, LC3_FLOAT frame_ms +) +{ + + LC3_INT i = 0, N = 0, offset = 0, j = 0, iszero = 0; + LC3_FLOAT g_min = 0, x_max = 0, tmp = 0, ind = 0, ind_min = 0, target = 0, fac = 0, ener = 0; + LC3_FLOAT en[MAX_LEN / 4] = {0}; + LC3_FLOAT reg_val = 4.656612873077393e-10; + + if (*old_targetBits < 0) { + *targetBitsOff = 0; + } else { + tmp = MIN(40, MAX(-40, *targetBitsOff + *old_targetBits - old_specBits)); + *targetBitsOff = 0.8 * *targetBitsOff + 0.2 * tmp; + } + + *old_targetBits = nbitsSQ; + nbitsSQ = nbitsSQ + round(*targetBitsOff); + + x_max = array_max_abs(x, lg); + + if (hrmode && regBits > 0) + { + LC3_FLOAT M0 = 1e-5, M1 = 1e-5, rB_offset; + LC3_FLOAT thresh = 2*frame_ms; + for (i = 0; i < lg; i++) + { + M0 += fabs(x[i]); + M1 += i*fabs(x[i]); + } + + rB_offset = 8 * (1 - MIN(M1/M0, thresh) / thresh); + reg_val = x_max * LC3_POW(2,-regBits - rB_offset); + } + + if (x_max < LC3_EPS) + { + ind_min = quantizedGainOff; + ind = 0; + *old_targetBits = -1; + } else { + if (hrmode == 1) { + g_min = x_max / (32768 * 256 - 2); + } else { + g_min = x_max / (32767 - 0.375); + } + /* Prevent positive rounding errors from LC3_LOGTEN function */ + ind_min = 28.0 * LC3_LOGTEN(g_min); + + ind_min = ceil(ind_min + LC3_FABS(ind_min) * LC3_EPS); + + assert(LC3_POW(10, ind_min / 28.0) >= g_min); + assert(ind_min <= (255 + quantizedGainOff)); + + N = lg; + + j = 0; + for (i = 0; i < N; i = i + 4) { + tmp = x[i] * x[i]; + tmp += x[i + 1] * x[i + 1]; + tmp += x[i + 2] * x[i + 2]; + tmp += x[i + 3] * x[i + 3]; + en[j] = (28.0 / 20.0) * (7 + 10.0 * LC3_LOGTEN(tmp + reg_val)); + j++; + } + + target = (28.0 / 20.0) * (1.4) * nbitsSQ; + fac = 256; + offset = 255 + quantizedGainOff; + + for (i = 0; i < 8; i++) { + fac = fac * 0.5; + offset = offset - fac; + ener = 0; + iszero = 1; + + for (j = N / 4 - 1; j >= 0; j--) { + tmp = en[j] - offset; + + if (tmp < (7.0) * (28.0 / 20.0)) { + if (iszero == 0) { + ener = ener + (2.7) * (28.0 / 20.0); + } + } else { + if (tmp > (50.0) * (28.0 / 20.0)) { + ener = ener + 2.0 * tmp - (50.0) * (28.0 / 20.0); + } else { + ener = ener + tmp; + } + + iszero = 0; + } + } + + if (ener > target && iszero == 0) { + offset = offset + fac; + } + } + + if (offset < ind_min) { + *old_targetBits = -1; + } + + ind = MAX(ind_min, offset) - quantizedGainOff; + } + + *quantizedGainMin = ind_min; + *quantizedGain = ind; + + *gain = LC3_POW(10.0, ((ind + quantizedGainOff) / 28.0)); +} diff --git a/lc3plus/fft/cfft.c b/lc3plus/fft/cfft.c new file mode 100644 index 0000000000000000000000000000000000000000..4bd8d29ade753c2c594dc34d0680fbdb3b9c5e8a --- /dev/null +++ b/lc3plus/fft/cfft.c @@ -0,0 +1,421 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "cfft.h" +#include "iisfft.h" /* for M_PIl */ +#include /* for abs() */ +#include + +#define MAX_FFT_SIZE 1024 +#define MAX_TRIGDATA_SIZE (MAX_FFT_SIZE / 2) + +/** + * \brief table aTrigData + + Generate table: aTrigData[i] = sin( pi * i / (2*MAX_TRIGDATA_SIZE) ); i = 0, ... MAX_TRIGDATA_SIZE + */ +static const LC3_FLOAT static_table[MAX_TRIGDATA_SIZE + 1] = { + 0.0000000000e+000, 3.0679567717e-003, 6.1358846724e-003, 9.2037543654e-003, 1.2271538377e-002, 1.5339205973e-002, + 1.8406730145e-002, 2.1474080160e-002, 2.4541229010e-002, 2.7608145028e-002, 3.0674804002e-002, 3.3741172403e-002, + 3.6807224154e-002, 3.9872925729e-002, 4.2938258499e-002, 4.6003181487e-002, 4.9067676067e-002, 5.2131704986e-002, + 5.5195245892e-002, 5.8258265257e-002, 6.1320737004e-002, 6.4382627606e-002, 6.7443922162e-002, 7.0504575968e-002, + 7.3564566672e-002, 7.6623864472e-002, 7.9682439566e-002, 8.2740262151e-002, 8.5797309875e-002, 8.8853552938e-002, + 9.1908954084e-002, 9.4963498414e-002, 9.8017141223e-002, 1.0106986016e-001, 1.0412163287e-001, 1.0717242211e-001, + 1.1022220552e-001, 1.1327095330e-001, 1.1631862819e-001, 1.1936521530e-001, 1.2241067737e-001, 1.2545497715e-001, + 1.2849810719e-001, 1.3154003024e-001, 1.3458070159e-001, 1.3762012124e-001, 1.4065824449e-001, 1.4369502664e-001, + 1.4673046768e-001, 1.4976453781e-001, 1.5279719234e-001, 1.5582840145e-001, 1.5885815024e-001, 1.6188639402e-001, + 1.6491311789e-001, 1.6793829203e-001, 1.7096188664e-001, 1.7398387194e-001, 1.7700421810e-001, 1.8002289534e-001, + 1.8303988874e-001, 1.8605515361e-001, 1.8906866014e-001, 1.9208039343e-001, 1.9509032369e-001, 1.9809840620e-001, + 2.0110464096e-001, 2.0410896838e-001, 2.0711137354e-001, 2.1011184156e-001, 2.1311031282e-001, 2.1610680223e-001, + 2.1910123527e-001, 2.2209362686e-001, 2.2508391738e-001, 2.2807207704e-001, 2.3105810583e-001, 2.3404195905e-001, + 2.3702360690e-001, 2.4000301957e-001, 2.4298018217e-001, 2.4595504999e-001, 2.4892760813e-001, 2.5189781189e-001, + 2.5486564636e-001, 2.5783109665e-001, 2.6079410315e-001, 2.6375466585e-001, 2.6671275496e-001, 2.6966831088e-001, + 2.7262136340e-001, 2.7557182312e-001, 2.7851969004e-001, 2.8146493435e-001, 2.8440752625e-001, 2.8734746575e-001, + 2.9028466344e-001, 2.9321914911e-001, 2.9615089297e-001, 2.9907983541e-001, 3.0200594664e-001, 3.0492922664e-001, + 3.0784964561e-001, 3.1076714396e-001, 3.1368175149e-001, 3.1659337878e-001, 3.1950202584e-001, 3.2240769267e-001, + 3.2531028986e-001, 3.2820984721e-001, 3.3110630512e-001, 3.3399966359e-001, 3.3688986301e-001, 3.3977687359e-001, + 3.4266072512e-001, 3.4554132819e-001, 3.4841868281e-001, 3.5129275918e-001, 3.5416352749e-001, 3.5703095794e-001, + 3.5989505053e-001, 3.6275571585e-001, 3.6561298370e-001, 3.6846682429e-001, 3.7131720781e-001, 3.7416407466e-001, + 3.7700742483e-001, 3.7984719872e-001, 3.8268342614e-001, 3.8551604748e-001, 3.8834503293e-001, 3.9117038250e-001, + 3.9399203658e-001, 3.9680999517e-001, 3.9962419868e-001, 4.0243464708e-001, 4.0524131060e-001, 4.0804415941e-001, + 4.1084316373e-001, 4.1363832355e-001, 4.1642954946e-001, 4.1921690106e-001, 4.2200025916e-001, 4.2477968335e-001, + 4.2755508423e-001, 4.3032649159e-001, 4.3309381604e-001, 4.3585708737e-001, 4.3861624599e-001, 4.4137126207e-001, + 4.4412213564e-001, 4.4686883688e-001, 4.4961133599e-001, 4.5234957337e-001, 4.5508357882e-001, 4.5781329274e-001, + 4.6053871512e-001, 4.6325978637e-001, 4.6597650647e-001, 4.6868881583e-001, 4.7139674425e-001, 4.7410020232e-001, + 4.7679921985e-001, 4.7949376702e-001, 4.8218378425e-001, 4.8486924171e-001, 4.8755016923e-001, 4.9022647738e-001, + 4.9289819598e-001, 4.9556526542e-001, 4.9822765589e-001, 5.0088536739e-001, 5.0353837013e-001, 5.0618666410e-001, + 5.0883013010e-001, 5.1146882772e-001, 5.1410275698e-001, 5.1673179865e-001, 5.1935601234e-001, 5.2197527885e-001, + 5.2458965778e-001, 5.2719914913e-001, 5.2980363369e-001, 5.3240311146e-001, 5.3499764204e-001, 5.3758704662e-001, + 5.4017144442e-001, 5.4275077581e-001, 5.4532498121e-001, 5.4789406061e-001, 5.5045795441e-001, 5.5301672220e-001, + 5.5557024479e-001, 5.5811852217e-001, 5.6066155434e-001, 5.6319934130e-001, 5.6573182344e-001, 5.6825894117e-001, + 5.7078075409e-001, 5.7329714298e-001, 5.7580816746e-001, 5.7831376791e-001, 5.8081394434e-001, 5.8330863714e-001, + 5.8579784632e-001, 5.8828157187e-001, 5.9075969458e-001, 5.9323227406e-001, 5.9569931030e-001, 5.9816068411e-001, + 6.0061645508e-001, 6.0306662321e-001, 6.0551106930e-001, 6.0794979334e-001, 6.1038279533e-001, 6.1281007528e-001, + 6.1523157358e-001, 6.1764729023e-001, 6.2005722523e-001, 6.2246125937e-001, 6.2485951185e-001, 6.2725180387e-001, + 6.2963825464e-001, 6.3201874495e-001, 6.3439327478e-001, 6.3676184416e-001, 6.3912445307e-001, 6.4148104191e-001, + 6.4383155107e-001, 6.4617604017e-001, 6.4851438999e-001, 6.5084666014e-001, 6.5317285061e-001, 6.5549284220e-001, + 6.5780669451e-001, 6.6011434793e-001, 6.6241580248e-001, 6.6471099854e-001, 6.6699993610e-001, 6.6928261518e-001, + 6.7155897617e-001, 6.7382901907e-001, 6.7609268427e-001, 6.7835003138e-001, 6.8060100079e-001, 6.8284553289e-001, + 6.8508368731e-001, 6.8731534481e-001, 6.8954056501e-001, 6.9175922871e-001, 6.9397145510e-001, 6.9617712498e-001, + 6.9837623835e-001, 7.0056879520e-001, 7.0275473595e-001, 7.0493406057e-001, 7.0710676908e-001, 7.0927280188e-001, + 7.1143221855e-001, 7.1358484030e-001, 7.1573084593e-001, 7.1787005663e-001, 7.2000253201e-001, 7.2212821245e-001, + 7.2424709797e-001, 7.2635912895e-001, 7.2846436501e-001, 7.3056274652e-001, 7.3265427351e-001, 7.3473888636e-001, + 7.3681658506e-001, 7.3888731003e-001, 7.4095112085e-001, 7.4300795794e-001, 7.4505776167e-001, 7.4710059166e-001, + 7.4913638830e-001, 7.5116515160e-001, 7.5318682194e-001, 7.5520139933e-001, 7.5720882416e-001, 7.5920921564e-001, + 7.6120239496e-001, 7.6318842173e-001, 7.6516723633e-001, 7.6713889837e-001, 7.6910334826e-001, 7.7106052637e-001, + 7.7301043272e-001, 7.7495312691e-001, 7.7688848972e-001, 7.7881652117e-001, 7.8073722124e-001, 7.8265058994e-001, + 7.8455656767e-001, 7.8645521402e-001, 7.8834640980e-001, 7.9023021460e-001, 7.9210656881e-001, 7.9397547245e-001, + 7.9583692551e-001, 7.9769086838e-001, 7.9953724146e-001, 8.0137616396e-001, 8.0320751667e-001, 8.0503135920e-001, + 8.0684757233e-001, 8.0865615606e-001, 8.1045717001e-001, 8.1225061417e-001, 8.1403630972e-001, 8.1581443548e-001, + 8.1758481264e-001, 8.1934750080e-001, 8.2110249996e-001, 8.2284981012e-001, 8.2458931208e-001, 8.2632106543e-001, + 8.2804507017e-001, 8.2976120710e-001, 8.3146959543e-001, 8.3317017555e-001, 8.3486288786e-001, 8.3654773235e-001, + 8.3822470903e-001, 8.3989381790e-001, 8.4155499935e-001, 8.4320825338e-001, 8.4485358000e-001, 8.4649091959e-001, + 8.4812033176e-001, 8.4974175692e-001, 8.5135519505e-001, 8.5296058655e-001, 8.5455799103e-001, 8.5614734888e-001, + 8.5772860050e-001, 8.5930180550e-001, 8.6086696386e-001, 8.6242395639e-001, 8.6397284269e-001, 8.6551362276e-001, + 8.6704623699e-001, 8.6857068539e-001, 8.7008696795e-001, 8.7159508467e-001, 8.7309497595e-001, 8.7458664179e-001, + 8.7607008219e-001, 8.7754529715e-001, 8.7901222706e-001, 8.8047087193e-001, 8.8192129135e-001, 8.8336336613e-001, + 8.8479709625e-001, 8.8622254133e-001, 8.8763964176e-001, 8.8904833794e-001, 8.9044874907e-001, 8.9184069633e-001, + 8.9322429895e-001, 8.9459949732e-001, 8.9596623182e-001, 8.9732456207e-001, 8.9867448807e-001, 9.0001589060e-001, + 9.0134882927e-001, 9.0267330408e-001, 9.0398931503e-001, 9.0529674292e-001, 9.0659570694e-001, 9.0788608789e-001, + 9.0916800499e-001, 9.1044127941e-001, 9.1170603037e-001, 9.1296219826e-001, 9.1420978308e-001, 9.1544872522e-001, + 9.1667908430e-001, 9.1790080070e-001, 9.1911387444e-001, 9.2031830549e-001, 9.2151403427e-001, 9.2270112038e-001, + 9.2387950420e-001, 9.2504924536e-001, 9.2621022463e-001, 9.2736250162e-001, 9.2850607634e-001, 9.2964088917e-001, + 9.3076694012e-001, 9.3188428879e-001, 9.3299281597e-001, 9.3409252167e-001, 9.3518352509e-001, 9.3626564741e-001, + 9.3733900785e-001, 9.3840354681e-001, 9.3945920467e-001, 9.4050604105e-001, 9.4154405594e-001, 9.4257318974e-001, + 9.4359344244e-001, 9.4460481405e-001, 9.4560730457e-001, 9.4660091400e-001, 9.4758558273e-001, 9.4856137037e-001, + 9.4952815771e-001, 9.5048606396e-001, 9.5143502951e-001, 9.5237499475e-001, 9.5330601931e-001, 9.5422810316e-001, + 9.5514118671e-001, 9.5604526997e-001, 9.5694035292e-001, 9.5782643557e-001, 9.5870345831e-001, 9.5957154036e-001, + 9.6043050289e-001, 9.6128046513e-001, 9.6212142706e-001, 9.6295326948e-001, 9.6377605200e-001, 9.6458977461e-001, + 9.6539443731e-001, 9.6618998051e-001, 9.6697646379e-001, 9.6775382757e-001, 9.6852207184e-001, 9.6928125620e-001, + 9.7003126144e-001, 9.7077214718e-001, 9.7150391340e-001, 9.7222650051e-001, 9.7293996811e-001, 9.7364425659e-001, + 9.7433936596e-001, 9.7502535582e-001, 9.7570210695e-001, 9.7636973858e-001, 9.7702813148e-001, 9.7767734528e-001, + 9.7831737995e-001, 9.7894817591e-001, 9.7956979275e-001, 9.8018211126e-001, 9.8078525066e-001, 9.8137921095e-001, + 9.8196387291e-001, 9.8253929615e-001, 9.8310548067e-001, 9.8366242647e-001, 9.8421007395e-001, 9.8474848270e-001, + 9.8527765274e-001, 9.8579752445e-001, 9.8630809784e-001, 9.8680937290e-001, 9.8730140924e-001, 9.8778414726e-001, + 9.8825758696e-001, 9.8872166872e-001, 9.8917651176e-001, 9.8962199688e-001, 9.9005818367e-001, 9.9048507214e-001, + 9.9090266228e-001, 9.9131083488e-001, 9.9170976877e-001, 9.9209928513e-001, 9.9247956276e-001, 9.9285042286e-001, + 9.9321192503e-001, 9.9356412888e-001, 9.9390697479e-001, 9.9424046278e-001, 9.9456459284e-001, 9.9487930536e-001, + 9.9518471956e-001, 9.9548077583e-001, 9.9576741457e-001, 9.9604469538e-001, 9.9631261826e-001, 9.9657112360e-001, + 9.9682027102e-001, 9.9706006050e-001, 9.9729043245e-001, 9.9751144648e-001, 9.9772304296e-001, 9.9792528152e-001, + 9.9811810255e-001, 9.9830156565e-001, 9.9847555161e-001, 9.9864023924e-001, 9.9879544973e-001, 9.9894130230e-001, + 9.9907773733e-001, 9.9920475483e-001, 9.9932235479e-001, 9.9943059683e-001, 9.9952942133e-001, 9.9961882830e-001, + 9.9969881773e-001, 9.9976938963e-001, 9.9983060360e-001, 9.9988234043e-001, 9.9992471933e-001, 9.9995762110e-001, + 9.9998116493e-001, 9.9999529123e-001, 1.0000000000e+000}; + +/** + * \brief scramble + The function sorts the complex vector re/im of length n from 'in-order' to 'bitreversed order'. + + * \param[i/o] re: real input + * \param[i/o] im: imag input + * \param[i ] n: size of fft + * \param[i ] s: stride of real and imag input + + * \return none + */ +static void scramble(LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT n, LC3_INT s) +{ + LC3_FLOAT tmp; + LC3_INT m, k, j; + + for (m = 1, j = 0; m < (n - 1); m++) { + { + for (k = n >> 1; (!((j ^= k) & k)); k >>= 1) + ; + } + + if (j > m) { + tmp = re[s * m]; + re[s * m] = re[s * j]; + re[s * j] = tmp; + + tmp = im[s * m]; + im[s * m] = im[s * j]; + im[s * j] = tmp; + } + } +} + +/** + * \brief fft + The function performs a radix-2, decimation in time complex fft. The calculation takes place inplace. + The real and imaginary part can reside in separate buffers as well as interleaved in one buffer. The + stride length has to be set accordingly. + + * \param[i/o] re: real input / real output + * \param[i/o] im: imag input / imag output + * \param[i ] sizeOfFft: size of fft + * \param[i ] s: stride of real and imag input / output + + * \return none + */ +static void fft(const LC3_FLOAT* aTrigData, LC3_INT trigdata_size, LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT sizeOfFft, + LC3_INT s) +{ + LC3_INT trigstep, i, ldm, n; + LC3_INT trigDataSize; + LC3_INT ldn = 0; + + trigDataSize = sizeOfFft / 2; + + while (sizeOfFft >>= 1) { + ldn++; + } + + n = 1 << ldn; + + scramble(re, im, n, s); + + /* 1+2 stage implemented as radix 4 */ + for (i = 0; i < n; i += 4) { + LC3_FLOAT a00, a01, a10, a11; + LC3_FLOAT a20, a21, a30, a31; + + a00 = re[s * (i + 0)] + re[s * (i + 1)]; + a10 = re[s * (i + 2)] + re[s * (i + 3)]; + a20 = im[s * (i + 0)] + im[s * (i + 1)]; + a30 = im[s * (i + 2)] + im[s * (i + 3)]; + + a01 = re[s * (i + 0)] - re[s * (i + 1)]; + a21 = re[s * (i + 2)] - re[s * (i + 3)]; + a31 = im[s * (i + 0)] - im[s * (i + 1)]; + a11 = im[s * (i + 2)] - im[s * (i + 3)]; + + re[s * (i + 0)] = a00 + a10; + re[s * (i + 2)] = a00 - a10; + im[s * (i + 0)] = a20 + a30; + im[s * (i + 2)] = a20 - a30; + re[s * (i + 1)] = a11 + a01; + re[s * (i + 3)] = a01 - a11; + im[s * (i + 1)] = a31 - a21; + im[s * (i + 3)] = a21 + a31; + } + + /* next stages implemented as radix 2 */ + for (ldm = 3; ldm <= ldn; ++ldm) { + const LC3_INT m = (1 << ldm); + const LC3_INT mh = (m >> 1); + LC3_INT j, r; + + trigstep = ((trigDataSize * 4) >> ldm) * trigdata_size / trigDataSize; + + for (j = 0; j < mh / 2; ++j) { + LC3_FLOAT c1, c2; + + c2 = aTrigData[j * trigstep]; + c1 = aTrigData[trigdata_size - j * trigstep]; + + for (r = 0; r < n; r += m) { + LC3_FLOAT vr, vi, ur, ui; + + LC3_INT t0 = r + j; + LC3_INT t1 = s * t0; + LC3_INT t2 = s * (t0 + mh); + + vr = re[t2] * c1 + im[t2] * c2; + vi = -re[t2] * c2 + im[t2] * c1; + + ur = re[t1]; + ui = im[t1]; + + re[t1] = re[t1] + vr; + im[t1] = im[t1] + vi; + + re[t2] = ur - vr; + im[t2] = ui - vi; + + t0 = r + j + mh / 2; + t1 = s * t0; + t2 = s * (t0 + mh); + + vr = -re[t2] * c2 + im[t2] * c1; + vi = -re[t2] * c1 - im[t2] * c2; + + ur = re[t1]; + ui = im[t1]; + re[t1] = re[t1] + vr; + im[t1] = im[t1] + vi; + + re[t2] = ur - vr; + im[t2] = ui - vi; + } + } + } +} + +/** + * \brief ifft + The function performs a radix-2, decimation in time complex inverse fft. The calculation takes place + inplace. The real and imaginary part can reside in separate buffers as well as interleaved in one buffer. + The stride length has to be set accordingly. + + * \param[i/o] re: real input / real output + * \param[i/o] im: imag input / imag output + * \param[i ] sizeOfFft: size of fft + * \param[i ] s: stride of real and imag input / output + + * \return none + */ +static void ifft(const LC3_FLOAT* aTrigData, LC3_INT trigdata_size, LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT sizeOfFft, + LC3_INT s) +{ + LC3_INT trigstep, i, ldm, n; + LC3_INT trigDataSize; + LC3_INT ldn = 0; + + trigDataSize = sizeOfFft; + + while (sizeOfFft >>= 1) { + ldn++; + } + + n = 1 << ldn; + + scramble(re, im, n, s); + + /* 1+2 stage radix 4 */ + for (i = 0; i < n; i += 4) { + LC3_FLOAT a00, a01, a10, a11; + LC3_FLOAT a20, a21, a30, a31; + + a00 = re[s * (i + 0)] + re[s * (i + 1)]; + a10 = re[s * (i + 2)] + re[s * (i + 3)]; + a20 = im[s * (i + 0)] + im[s * (i + 1)]; + a30 = im[s * (i + 2)] + im[s * (i + 3)]; + + a01 = re[s * (i + 0)] - re[s * (i + 1)]; + a21 = re[s * (i + 2)] - re[s * (i + 3)]; + a31 = im[s * (i + 0)] - im[s * (i + 1)]; + a11 = im[s * (i + 2)] - im[s * (i + 3)]; + + re[s * (i + 0)] = a00 + a10; + re[s * (i + 2)] = a00 - a10; + im[s * (i + 0)] = a20 + a30; + im[s * (i + 2)] = a20 - a30; + + re[s * (i + 1)] = a01 - a11; + re[s * (i + 3)] = a01 + a11; + im[s * (i + 1)] = a31 + a21; + im[s * (i + 3)] = a31 - a21; + } + + for (ldm = 3; ldm <= ldn; ++ldm) { + const LC3_INT m = (1 << ldm); + const LC3_INT mh = (m >> 1); + LC3_INT j, r; + + trigstep = ((trigDataSize * 4) >> ldm) * trigdata_size / trigDataSize; + + for (j = 0; j < mh / 2; ++j) { + LC3_FLOAT c1, c2; + + c2 = aTrigData[j * trigstep]; + c1 = aTrigData[trigdata_size - j * trigstep]; + + for (r = 0; r < n; r += m) { + LC3_FLOAT vr, vi, ur, ui; + + LC3_INT t0 = r + j; + LC3_INT t1 = s * t0; + LC3_INT t2 = s * (t0 + mh); + + vr = re[t2] * c1 - im[t2] * c2; + vi = re[t2] * c2 + im[t2] * c1; + + ur = re[t1]; + ui = im[t1]; + + re[t1] = ur + vr; + im[t1] = ui + vi; + + re[t2] = ur - vr; + im[t2] = ui - vi; + + t0 = r + j + mh / 2; + t1 = s * t0; + t2 = s * (t0 + mh); + + vr = -re[t2] * c2 - im[t2] * c1; + vi = re[t2] * c1 - im[t2] * c2; + + ur = re[t1]; + ui = im[t1]; + + re[t1] = ur + vr; + im[t1] = ui + vi; + re[t2] = ur - vr; + im[t2] = ui - vi; + } + } + } +} + +/** + * \brief cfft + The function serves as wrapper for the forward and inverse fft. + + * \param[i/o] re: real input / real output + * \param[i/o] im: imag input / imag output + * \param[i ] sizeOfFft: size of fft + * \param[i ] s: stride of real and imag input / output + * \param[i ] iSign: forward fft: -1 / inverse fft: 1 + + * \return none + */ +void LC3_cfft(LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT length, LC3_INT stride, LC3_INT sign) +{ + assert(abs(sign) == 1); + assert(CFFT_SUPPORT(length)); + + if (sign == -1) { + fft(static_table, MAX_TRIGDATA_SIZE, re, im, length, stride); + } else { + ifft(static_table, MAX_TRIGDATA_SIZE, re, im, length, stride); + } +} + +LC3_INT LC3_cfft_plan(Cfft* handle, LC3_INT length, LC3_INT sign) +{ + /* check if length is power of two */ + if (!CFFT_PLAN_SUPPORT(length) || abs(sign) != 1) + return 0; + + handle->len = length; + handle->sign = sign; + + if (length <= MAX_FFT_SIZE) { + handle->table = NULL; + } else { + LC3_INT i = 0; + handle->table = (LC3_FLOAT*)malloc((length / 2 + 1) * sizeof(LC3_FLOAT)); + for (i = 0; i < length / 2 + 1; i++) { + handle->table[i] = (LC3_FLOAT)LC3_SIN((LC3_FLOAT)M_PIl * i / length); + } + } + return 1; +} + +void LC3_cfft_apply(Cfft* handle, LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT stride) +{ + if (handle->len <= MAX_FFT_SIZE) { + LC3_cfft(re, im, handle->len, stride, handle->sign); + } else if (handle->sign == -1) { + fft(handle->table, handle->len / 2, re, im, handle->len, stride); + } else { + ifft(handle->table, handle->len / 2, re, im, handle->len, stride); + } +} + +void LC3_cfft_free(Cfft* handle) +{ + if (handle->table) + free(handle->table); +} diff --git a/lc3plus/fft/cfft.h b/lc3plus/fft/cfft.h new file mode 100644 index 0000000000000000000000000000000000000000..3902b4c396d152f621d5f61cbfe03c853fabc26e --- /dev/null +++ b/lc3plus/fft/cfft.h @@ -0,0 +1,42 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + + +#include "../functions.h" + +#ifndef CFFT_H +#define CFFT_H + + +/* macro to check if cfft supports len */ +#define CFFT_IS_POWER_OF_TWO(n) ((n != 0) && ((n & (~n + 1)) == n)) +#define CFFT_SUPPORT(len) (len >= 4 && len <= 1024 && CFFT_IS_POWER_OF_TWO(len)) +#define CFFT_PLAN_SUPPORT(len) (len >= 4 && CFFT_IS_POWER_OF_TWO(len)) + +/** + * \brief fft_radix2 + The function serves as wrapper for the forward and inverse complex fft. + + * \param[i/o] re: real input / real output + * \param[i/o] im: imag input / imag output + * \param[i ] sizeOfFft: size of fft + * \param[i ] s: stride of real and imag input / output + * \param[i ] iSign: forward fft: -1 / inverse fft: 1 + + * \return none + */ + +void LC3_cfft(LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT sizeOfFft, LC3_INT stride, LC3_INT sign); + +LC3_INT LC3_cfft_plan(Cfft* handle, LC3_INT length, LC3_INT sign); +void LC3_cfft_apply(Cfft* handle, LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT stride); +void LC3_cfft_free(Cfft* handle); + +#endif /* FFT_RADIX2_H */ diff --git a/lc3plus/fft/fft_15_16.h b/lc3plus/fft/fft_15_16.h new file mode 100644 index 0000000000000000000000000000000000000000..83ca77353b5c83df31ef3bd2c278a251ab5d4240 --- /dev/null +++ b/lc3plus/fft/fft_15_16.h @@ -0,0 +1,401 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +/* guard against unindended includes */ +#ifndef INCLUDED_FROM_IISFFT_C +#error "this file must not be included" +#endif + +static void fft15(LC3_FLOAT* vec) +{ + LC3_FLOAT r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, i0, i1, i2, i3, i4, i5, + i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, + tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, + tmp25, tmp26, tmp27, tmp28, tmp29; + + /* Pre-additions real part */ + r1 = vec[2] + vec[8]; + r2 = vec[2] - vec[8]; + r3 = vec[4] + vec[16]; + r4 = vec[4] - vec[16]; + r5 = vec[6] + vec[24]; + r6 = vec[6] - vec[24]; + r7 = vec[10] + vec[20]; + r8 = vec[10] - vec[20]; + r9 = vec[12] + vec[18]; + r10 = vec[12] - vec[18]; + r11 = vec[14] + vec[26]; + r12 = vec[14] - vec[26]; + r13 = vec[22] + vec[28]; + r14 = vec[22] - vec[28]; + + tmp2 = r1 + r3; + tmp4 = r1 - r3; + tmp6 = r2 + r14; + tmp8 = r2 - r14; + tmp10 = r4 + r12; + tmp12 = r4 - r12; + tmp14 = r5 + r9; + tmp16 = r5 - r9; + tmp18 = r11 + r13; + tmp20 = r11 - r13; + + /* Pre-additions imaginary part */ + i1 = vec[3] + vec[9]; + i2 = vec[3] - vec[9]; + i3 = vec[5] + vec[17]; + i4 = vec[5] - vec[17]; + i5 = vec[7] + vec[25]; + i6 = vec[7] - vec[25]; + i7 = vec[11] + vec[21]; + i8 = vec[11] - vec[21]; + i9 = vec[13] + vec[19]; + i10 = vec[13] - vec[19]; + i11 = vec[15] + vec[27]; + i12 = vec[15] - vec[27]; + i13 = vec[23] + vec[29]; + i14 = vec[23] - vec[29]; + + tmp3 = i1 + i3; + tmp5 = i1 - i3; + tmp7 = i2 + i14; + tmp9 = i2 - i14; + tmp11 = i4 + i12; + tmp13 = i4 - i12; + tmp15 = i5 + i9; + tmp17 = i5 - i9; + tmp19 = i11 + i13; + tmp21 = i11 - i13; + + /* Pre-additions and core multiplications */ + tmp28 = tmp4 + tmp20; + tmp29 = tmp5 + tmp21; + r4 = tmp2 + tmp18; + i4 = tmp3 + tmp19; + r3 = (r4 + tmp14) * (LC3_FLOAT)-1.25; + i3 = (i4 + tmp15) * (LC3_FLOAT)-1.25; + r2 = (tmp29 - i8) * (LC3_FLOAT)-8.660254037844387e-1; + i2 = (tmp28 - r8) * (LC3_FLOAT)8.660254037844387e-1; + r1 = r4 + r7; + i1 = i4 + i7; + r0 = r1 + vec[0] + tmp14; + i0 = i1 + vec[1] + tmp15; + r7 = tmp4 - tmp20; + i7 = tmp5 - tmp21; + r8 = (tmp3 - tmp19) * (LC3_FLOAT)-4.841229182759272e-1; + i8 = (tmp2 - tmp18) * (LC3_FLOAT)4.841229182759272e-1; + tmp0 = tmp6 + r10; + tmp1 = tmp7 + i10; + tmp2 = r6 - tmp10; + tmp3 = i6 - tmp11; + r10 = tmp7 * (LC3_FLOAT)-2.308262652881440; + i10 = tmp6 * (LC3_FLOAT)2.308262652881440; + r11 = tmp8 * (LC3_FLOAT)1.332676064001459; + i11 = tmp9 * (LC3_FLOAT)1.332676064001459; + r6 = (r7 - tmp16) * (LC3_FLOAT)5.590169943749475e-1; + i6 = (i7 - tmp17) * (LC3_FLOAT)5.590169943749475e-1; + r12 = (tmp1 + tmp3) * (LC3_FLOAT)5.877852522924733e-1; + i12 = (tmp0 + tmp2) * (LC3_FLOAT)-5.877852522924733e-1; + r13 = (tmp7 - tmp11) * (LC3_FLOAT)-8.816778784387098e-1; + i13 = (tmp6 - tmp10) * (LC3_FLOAT)8.816778784387098e-1; + r14 = (tmp8 + tmp12) * (LC3_FLOAT)5.090369604551274e-1; + i14 = (tmp9 + tmp13) * (LC3_FLOAT)5.090369604551274e-1; + r16 = tmp11 * (LC3_FLOAT)5.449068960040204e-1; + i16 = tmp10 * (LC3_FLOAT)-5.449068960040204e-1; + r17 = tmp12 * (LC3_FLOAT)3.146021430912046e-1; + i17 = tmp13 * (LC3_FLOAT)3.146021430912046e-1; + + r4 *= (LC3_FLOAT)1.875; + i4 *= (LC3_FLOAT)1.875; + r1 *= (LC3_FLOAT)-1.5; + i1 *= (LC3_FLOAT)-1.5; + r7 *= (LC3_FLOAT)-8.385254915624212e-1; + i7 *= (LC3_FLOAT)-8.385254915624212e-1; + r5 = tmp29 * (LC3_FLOAT)1.082531754730548; + i5 = tmp28 * (LC3_FLOAT)-1.082531754730548; + r9 = tmp1 * (LC3_FLOAT)1.538841768587627; + i9 = tmp0 * (LC3_FLOAT)-1.538841768587627; + r15 = tmp3 * (LC3_FLOAT)3.632712640026803e-1; + i15 = tmp2 * (LC3_FLOAT)-3.632712640026803e-1; + + /* Post-additions real part */ + tmp2 = r0 + r1; + tmp4 = r3 + r6; + tmp6 = r3 - r6; + tmp8 = r4 + r5; + tmp10 = r4 - r5; + tmp12 = r7 + r8; + tmp14 = r7 - r8; + tmp16 = r13 + r16; + tmp18 = r14 + r17; + tmp20 = r10 - r13; + tmp22 = r11 - r14; + tmp24 = r12 + r15; + tmp26 = r12 - r9; + + r1 = tmp2 + r2; + r2 = tmp2 - r2; + r3 = tmp4 + tmp26; + r4 = tmp4 - tmp26; + r5 = tmp6 + tmp24; + r6 = tmp6 - tmp24; + r7 = tmp16 + tmp18; + r8 = tmp16 - tmp18; + r9 = tmp20 - tmp22; + r10 = tmp20 + tmp22; + r11 = r1 + tmp8; + r12 = r2 + tmp10; + r13 = r11 - tmp12; + r14 = r12 - tmp14; + r15 = r12 + tmp14; + r16 = r11 + tmp12; + + /* Post-additions imaginary part */ + tmp3 = i0 + i1; + tmp5 = i3 + i6; + tmp7 = i3 - i6; + tmp9 = i4 + i5; + tmp11 = i4 - i5; + tmp13 = i7 + i8; + tmp15 = i7 - i8; + tmp17 = i13 + i16; + tmp19 = i14 + i17; + tmp21 = i10 - i13; + tmp23 = i11 - i14; + tmp25 = i12 + i15; + tmp27 = i12 - i9; + + i1 = tmp3 + i2; + i2 = tmp3 - i2; + i3 = tmp5 + tmp27; + i4 = tmp5 - tmp27; + i5 = tmp7 + tmp25; + i6 = tmp7 - tmp25; + i7 = tmp17 + tmp19; + i8 = tmp17 - tmp19; + i9 = tmp21 - tmp23; + i10 = tmp21 + tmp23; + i11 = i1 + tmp9; + i12 = i2 + tmp11; + i13 = i11 - tmp13; + i14 = i12 - tmp15; + i15 = i12 + tmp15; + i16 = i11 + tmp13; + + *vec++ = r0; + *vec++ = i0; + *vec++ = r13 + r5 + r7; + *vec++ = i13 + i5 + i7; + *vec++ = r15 + r3 - r9; + *vec++ = i15 + i3 - i9; + *vec++ = r0 + r4; + *vec++ = i0 + i4; + *vec++ = r13 + r6 - r7; + *vec++ = i13 + i6 - i7; + *vec++ = r2; + *vec++ = i2; + *vec++ = r0 + r5; + *vec++ = i0 + i5; + *vec++ = r16 + r3 - r10; + *vec++ = i16 + i3 - i10; + *vec++ = r15 + r4 + r9; + *vec++ = i15 + i4 + i9; + *vec++ = r0 + r6; + *vec++ = i0 + i6; + *vec++ = r1; + *vec++ = i1; + *vec++ = r14 + r5 + r8; + *vec++ = i14 + i5 + i8; + *vec++ = r0 + r3; + *vec++ = i0 + i3; + *vec++ = r16 + r4 + r10; + *vec++ = i16 + i4 + i10; + *vec++ = r14 + r6 - r8; + *vec++ = i14 + i6 - i8; +} + +static void fft16(LC3_FLOAT* vec) +{ + const LC3_FLOAT INV_SQRT2 = 7.071067811865475e-1; + const LC3_FLOAT COS_PI_DIV8 = 9.238795325112867e-1; + const LC3_FLOAT COS_3PI_DIV8 = 3.826834323650898e-1; + const LC3_FLOAT SQRT2PLUS1 = 2.414213562373095; + const LC3_FLOAT SQRT2MINUS1 = 4.142135623730952e-1; + + LC3_FLOAT temp10, temp11, temp12, temp13, temp14, temp15, temp16, temp17, temp18, temp19, temp110, temp111, temp112, + temp113, temp114, temp115, temp20, temp21, temp22, temp23, temp24, temp25, temp26, temp27, temp28, temp29, + temp210, temp211, temp212, temp213, temp214, temp215, vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8, + vec9, vec10, vec11, vec12, vec13, vec14, vec15; + + /* even */ + vec0 = vec[0] + vec[16]; + vec1 = vec[1] + vec[17]; + vec2 = vec[2] + vec[18]; + vec3 = vec[3] + vec[19]; + vec4 = vec[4] + vec[20]; + vec5 = vec[5] + vec[21]; + vec6 = vec[6] + vec[22]; + vec7 = vec[7] + vec[23]; + vec8 = vec[8] + vec[24]; + vec9 = vec[9] + vec[25]; + vec10 = vec[10] + vec[26]; + vec11 = vec[11] + vec[27]; + vec12 = vec[12] + vec[28]; + vec13 = vec[13] + vec[29]; + vec14 = vec[14] + vec[30]; + vec15 = vec[15] + vec[31]; + + /* Pre-additions */ + temp10 = vec0 + vec8; + temp12 = vec0 - vec8; + temp11 = vec1 + vec9; + temp13 = vec1 - vec9; + temp14 = vec2 + vec10; + temp16 = vec2 - vec10; + temp15 = vec3 + vec11; + temp17 = vec3 - vec11; + temp18 = vec4 + vec12; + temp110 = vec4 - vec12; + temp19 = vec5 + vec13; + temp111 = vec5 - vec13; + temp112 = vec6 + vec14; + temp114 = vec6 - vec14; + temp113 = vec7 + vec15; + temp115 = vec7 - vec15; + + /* Pre-additions and core multiplications */ + temp20 = temp10 + temp18; + temp24 = temp10 - temp18; + temp21 = temp11 + temp19; + temp25 = temp11 - temp19; + temp28 = temp12 - temp111; + temp210 = temp12 + temp111; + temp29 = temp13 + temp110; + temp211 = temp13 - temp110; + temp22 = temp14 + temp112; + temp27 = temp14 - temp112; + temp23 = temp15 + temp113; + temp26 = temp113 - temp15; + + temp11 = temp16 + temp114; + temp12 = temp16 - temp114; + temp10 = temp17 + temp115; + temp13 = temp17 - temp115; + temp212 = (temp10 + temp12) * INV_SQRT2; + temp214 = (temp10 - temp12) * INV_SQRT2; + temp213 = (temp13 - temp11) * INV_SQRT2; + temp215 = (temp11 + temp13) * -INV_SQRT2; + + /* odd */ + vec0 = vec[0] - vec[16]; + vec1 = vec[1] - vec[17]; + vec2 = vec[2] - vec[18]; + vec3 = vec[3] - vec[19]; + vec4 = vec[4] - vec[20]; + vec5 = vec[5] - vec[21]; + vec6 = vec[6] - vec[22]; + vec7 = vec[7] - vec[23]; + vec8 = vec[8] - vec[24]; + vec9 = vec[9] - vec[25]; + vec10 = vec[10] - vec[26]; + vec11 = vec[11] - vec[27]; + vec12 = vec[12] - vec[28]; + vec13 = vec[13] - vec[29]; + vec14 = vec[14] - vec[30]; + vec15 = vec[15] - vec[31]; + + /* Pre-additions and core multiplications */ + temp19 = (vec2 + vec14) * -COS_3PI_DIV8; + temp110 = (vec2 - vec14) * COS_PI_DIV8; + temp18 = (vec3 + vec15) * COS_3PI_DIV8; + temp111 = (vec3 - vec15) * COS_PI_DIV8; + temp15 = (vec4 + vec12) * -INV_SQRT2; + temp16 = (vec4 - vec12) * INV_SQRT2; + temp14 = (vec5 + vec13) * INV_SQRT2; + temp17 = (vec5 - vec13) * INV_SQRT2; + temp113 = (vec6 + vec10) * -COS_PI_DIV8; + temp114 = (vec6 - vec10) * COS_3PI_DIV8; + temp112 = (vec7 + vec11) * COS_PI_DIV8; + temp115 = (vec7 - vec11) * COS_3PI_DIV8; + + /* Core multiplications */ + vec2 = temp18 * SQRT2PLUS1 - temp112 * SQRT2MINUS1; + vec3 = temp19 * SQRT2PLUS1 - temp113 * SQRT2MINUS1; + vec4 = temp110 * SQRT2MINUS1 - temp114 * SQRT2PLUS1; + vec5 = temp111 * SQRT2MINUS1 - temp115 * SQRT2PLUS1; + + /* Post-additions */ + temp18 += temp112; + temp19 += temp113; + temp110 += temp114; + temp111 += temp115; + vec6 = vec0 + temp14; + vec10 = vec0 - temp14; + vec7 = vec1 + temp15; + vec11 = vec1 - temp15; + + vec12 = temp16 - vec9; + vec14 = temp16 + vec9; + vec13 = vec8 + temp17; + vec15 = vec8 - temp17; + + temp10 = vec6 - vec14; + temp12 = vec6 + vec14; + temp11 = vec7 + vec15; + temp13 = vec7 - vec15; + temp14 = vec10 + vec12; + temp16 = vec10 - vec12; + temp15 = vec11 + vec13; + temp17 = vec11 - vec13; + + vec10 = temp18 + temp110; + temp110 = temp18 - temp110; + vec11 = temp19 + temp111; + temp111 = temp19 - temp111; + + temp112 = vec2 + vec4; + temp114 = vec2 - vec4; + temp113 = vec3 + vec5; + temp115 = vec3 - vec5; + + /* Post-additions */ + *vec++ = temp20 + temp22; + *vec++ = temp21 + temp23; + *vec++ = temp12 + vec10; + *vec++ = temp13 + vec11; + *vec++ = temp210 + temp212; + *vec++ = temp211 + temp213; + *vec++ = temp10 + temp112; + *vec++ = temp11 + temp113; + *vec++ = temp24 - temp26; + *vec++ = temp25 - temp27; + *vec++ = temp16 + temp114; + *vec++ = temp17 + temp115; + *vec++ = temp28 + temp214; + *vec++ = temp29 + temp215; + *vec++ = temp14 + temp110; + *vec++ = temp15 + temp111; + *vec++ = temp20 - temp22; + *vec++ = temp21 - temp23; + *vec++ = temp12 - vec10; + *vec++ = temp13 - vec11; + *vec++ = temp210 - temp212; + *vec++ = temp211 - temp213; + *vec++ = temp10 - temp112; + *vec++ = temp11 - temp113; + *vec++ = temp24 + temp26; + *vec++ = temp25 + temp27; + *vec++ = temp16 - temp114; + *vec++ = temp17 - temp115; + *vec++ = temp28 - temp214; + *vec++ = temp29 - temp215; + *vec++ = temp14 - temp110; + *vec++ = temp15 - temp111; +} diff --git a/lc3plus/fft/fft_240_480.h b/lc3plus/fft/fft_240_480.h new file mode 100644 index 0000000000000000000000000000000000000000..c1d96c87b8016d516ff5cd96687309a11f450cd9 --- /dev/null +++ b/lc3plus/fft/fft_240_480.h @@ -0,0 +1,185 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +/* guard against unindended includes */ +#ifndef INCLUDED_FROM_IISFFT_C +#error "this file must not be included" +#endif + +static void fft240(LC3_FLOAT* in) +{ + const LC3_INT table1[240] = { + 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 225, 1, 17, 33, 49, 65, 81, + 97, 113, 129, 145, 161, 177, 193, 209, 210, 226, 2, 18, 34, 50, 66, 82, 98, 114, 130, 146, 162, 178, + 194, 195, 211, 227, 3, 19, 35, 51, 67, 83, 99, 115, 131, 147, 163, 179, 180, 196, 212, 228, 4, 20, + 36, 52, 68, 84, 100, 116, 132, 148, 164, 165, 181, 197, 213, 229, 5, 21, 37, 53, 69, 85, 101, 117, + 133, 149, 150, 166, 182, 198, 214, 230, 6, 22, 38, 54, 70, 86, 102, 118, 134, 135, 151, 167, 183, 199, + 215, 231, 7, 23, 39, 55, 71, 87, 103, 119, 120, 136, 152, 168, 184, 200, 216, 232, 8, 24, 40, 56, + 72, 88, 104, 105, 121, 137, 153, 169, 185, 201, 217, 233, 9, 25, 41, 57, 73, 89, 90, 106, 122, 138, + 154, 170, 186, 202, 218, 234, 10, 26, 42, 58, 74, 75, 91, 107, 123, 139, 155, 171, 187, 203, 219, 235, + 11, 27, 43, 59, 60, 76, 92, 108, 124, 140, 156, 172, 188, 204, 220, 236, 12, 28, 44, 45, 61, 77, + 93, 109, 125, 141, 157, 173, 189, 205, 221, 237, 13, 29, 30, 46, 62, 78, 94, 110, 126, 142, 158, 174, + 190, 206, 222, 238, 14, 15, 31, 47, 63, 79, 95, 111, 127, 143, 159, 175, 191, 207, 223, 239}; + const LC3_INT table2[240] = { + 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 15, 31, 47, 63, 79, 95, 111, + 127, 143, 159, 175, 191, 207, 223, 239, 30, 46, 62, 78, 94, 110, 126, 142, 158, 174, 190, 206, 222, 238, + 14, 45, 61, 77, 93, 109, 125, 141, 157, 173, 189, 205, 221, 237, 13, 29, 60, 76, 92, 108, 124, 140, + 156, 172, 188, 204, 220, 236, 12, 28, 44, 75, 91, 107, 123, 139, 155, 171, 187, 203, 219, 235, 11, 27, + 43, 59, 90, 106, 122, 138, 154, 170, 186, 202, 218, 234, 10, 26, 42, 58, 74, 105, 121, 137, 153, 169, + 185, 201, 217, 233, 9, 25, 41, 57, 73, 89, 120, 136, 152, 168, 184, 200, 216, 232, 8, 24, 40, 56, + 72, 88, 104, 135, 151, 167, 183, 199, 215, 231, 7, 23, 39, 55, 71, 87, 103, 119, 150, 166, 182, 198, + 214, 230, 6, 22, 38, 54, 70, 86, 102, 118, 134, 165, 181, 197, 213, 229, 5, 21, 37, 53, 69, 85, + 101, 117, 133, 149, 180, 196, 212, 228, 4, 20, 36, 52, 68, 84, 100, 116, 132, 148, 164, 195, 211, 227, + 3, 19, 35, 51, 67, 83, 99, 115, 131, 147, 163, 179, 210, 226, 2, 18, 34, 50, 66, 82, 98, 114, + 130, 146, 162, 178, 194, 225, 1, 17, 33, 49, 65, 81, 97, 113, 129, 145, 161, 177, 193, 209}; + + const LC3_INT L = 240; + const LC3_INT A = 15; + const LC3_INT B = 16; + const LC3_INT* idx1 = table1; + const LC3_INT* idx2 = table2; + + LC3_INT k, l; + LC3_FLOAT temp[32], out[480]; + + for (k = 0; k < A; k++) { + for (l = 0; l < B; l++) { + temp[2 * l] = in[2 * *idx1]; + temp[2 * l + 1] = in[2 * *idx1 + 1]; + idx1 += A; + } + + fft16(temp); /* 16-point FFT */ + idx1 -= L; + + for (l = 0; l < B; l++) { + in[2 * *idx1] = temp[2 * l]; + in[2 * *idx1 + 1] = temp[2 * l + 1]; + idx1 += A; + } + + idx1 -= L - 1; + } + + idx1 -= A; + + for (k = 0; k < B; k++) { + for (l = 0; l < A; l++) { + temp[2 * l] = in[2 * *idx1]; + temp[2 * l + 1] = in[2 * *idx1++ + 1]; + } + + fft15(temp); /* 15-point FFT */ + + for (l = 0; l < A; l++) { + out[2 * *idx2] = temp[2 * l]; + out[2 * *idx2++ + 1] = temp[2 * l + 1]; + } + } + + memmove(in, out, 2 * L * sizeof(LC3_FLOAT)); +} + +/* description in iis_fft.h */ +static void fft480(LC3_FLOAT* in) +{ + const LC3_INT table1[480] = { + 0, 256, 32, 288, 64, 320, 96, 352, 128, 384, 160, 416, 192, 448, 224, 225, 1, 257, 33, 289, 65, 321, + 97, 353, 129, 385, 161, 417, 193, 449, 450, 226, 2, 258, 34, 290, 66, 322, 98, 354, 130, 386, 162, 418, + 194, 195, 451, 227, 3, 259, 35, 291, 67, 323, 99, 355, 131, 387, 163, 419, 420, 196, 452, 228, 4, 260, + 36, 292, 68, 324, 100, 356, 132, 388, 164, 165, 421, 197, 453, 229, 5, 261, 37, 293, 69, 325, 101, 357, + 133, 389, 390, 166, 422, 198, 454, 230, 6, 262, 38, 294, 70, 326, 102, 358, 134, 135, 391, 167, 423, 199, + 455, 231, 7, 263, 39, 295, 71, 327, 103, 359, 360, 136, 392, 168, 424, 200, 456, 232, 8, 264, 40, 296, + 72, 328, 104, 105, 361, 137, 393, 169, 425, 201, 457, 233, 9, 265, 41, 297, 73, 329, 330, 106, 362, 138, + 394, 170, 426, 202, 458, 234, 10, 266, 42, 298, 74, 75, 331, 107, 363, 139, 395, 171, 427, 203, 459, 235, + 11, 267, 43, 299, 300, 76, 332, 108, 364, 140, 396, 172, 428, 204, 460, 236, 12, 268, 44, 45, 301, 77, + 333, 109, 365, 141, 397, 173, 429, 205, 461, 237, 13, 269, 270, 46, 302, 78, 334, 110, 366, 142, 398, 174, + 430, 206, 462, 238, 14, 15, 271, 47, 303, 79, 335, 111, 367, 143, 399, 175, 431, 207, 463, 239, 240, 16, + 272, 48, 304, 80, 336, 112, 368, 144, 400, 176, 432, 208, 464, 465, 241, 17, 273, 49, 305, 81, 337, 113, + 369, 145, 401, 177, 433, 209, 210, 466, 242, 18, 274, 50, 306, 82, 338, 114, 370, 146, 402, 178, 434, 435, + 211, 467, 243, 19, 275, 51, 307, 83, 339, 115, 371, 147, 403, 179, 180, 436, 212, 468, 244, 20, 276, 52, + 308, 84, 340, 116, 372, 148, 404, 405, 181, 437, 213, 469, 245, 21, 277, 53, 309, 85, 341, 117, 373, 149, + 150, 406, 182, 438, 214, 470, 246, 22, 278, 54, 310, 86, 342, 118, 374, 375, 151, 407, 183, 439, 215, 471, + 247, 23, 279, 55, 311, 87, 343, 119, 120, 376, 152, 408, 184, 440, 216, 472, 248, 24, 280, 56, 312, 88, + 344, 345, 121, 377, 153, 409, 185, 441, 217, 473, 249, 25, 281, 57, 313, 89, 90, 346, 122, 378, 154, 410, + 186, 442, 218, 474, 250, 26, 282, 58, 314, 315, 91, 347, 123, 379, 155, 411, 187, 443, 219, 475, 251, 27, + 283, 59, 60, 316, 92, 348, 124, 380, 156, 412, 188, 444, 220, 476, 252, 28, 284, 285, 61, 317, 93, 349, + 125, 381, 157, 413, 189, 445, 221, 477, 253, 29, 30, 286, 62, 318, 94, 350, 126, 382, 158, 414, 190, 446, + 222, 478, 254, 255, 31, 287, 63, 319, 95, 351, 127, 383, 159, 415, 191, 447, 223, 479}; + const LC3_INT table2[480] = { + 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 15, 47, 79, 111, 143, 175, 207, + 239, 271, 303, 335, 367, 399, 431, 463, 30, 62, 94, 126, 158, 190, 222, 254, 286, 318, 350, 382, 414, 446, + 478, 45, 77, 109, 141, 173, 205, 237, 269, 301, 333, 365, 397, 429, 461, 13, 60, 92, 124, 156, 188, 220, + 252, 284, 316, 348, 380, 412, 444, 476, 28, 75, 107, 139, 171, 203, 235, 267, 299, 331, 363, 395, 427, 459, + 11, 43, 90, 122, 154, 186, 218, 250, 282, 314, 346, 378, 410, 442, 474, 26, 58, 105, 137, 169, 201, 233, + 265, 297, 329, 361, 393, 425, 457, 9, 41, 73, 120, 152, 184, 216, 248, 280, 312, 344, 376, 408, 440, 472, + 24, 56, 88, 135, 167, 199, 231, 263, 295, 327, 359, 391, 423, 455, 7, 39, 71, 103, 150, 182, 214, 246, + 278, 310, 342, 374, 406, 438, 470, 22, 54, 86, 118, 165, 197, 229, 261, 293, 325, 357, 389, 421, 453, 5, + 37, 69, 101, 133, 180, 212, 244, 276, 308, 340, 372, 404, 436, 468, 20, 52, 84, 116, 148, 195, 227, 259, + 291, 323, 355, 387, 419, 451, 3, 35, 67, 99, 131, 163, 210, 242, 274, 306, 338, 370, 402, 434, 466, 18, + 50, 82, 114, 146, 178, 225, 257, 289, 321, 353, 385, 417, 449, 1, 33, 65, 97, 129, 161, 193, 240, 272, + 304, 336, 368, 400, 432, 464, 16, 48, 80, 112, 144, 176, 208, 255, 287, 319, 351, 383, 415, 447, 479, 31, + 63, 95, 127, 159, 191, 223, 270, 302, 334, 366, 398, 430, 462, 14, 46, 78, 110, 142, 174, 206, 238, 285, + 317, 349, 381, 413, 445, 477, 29, 61, 93, 125, 157, 189, 221, 253, 300, 332, 364, 396, 428, 460, 12, 44, + 76, 108, 140, 172, 204, 236, 268, 315, 347, 379, 411, 443, 475, 27, 59, 91, 123, 155, 187, 219, 251, 283, + 330, 362, 394, 426, 458, 10, 42, 74, 106, 138, 170, 202, 234, 266, 298, 345, 377, 409, 441, 473, 25, 57, + 89, 121, 153, 185, 217, 249, 281, 313, 360, 392, 424, 456, 8, 40, 72, 104, 136, 168, 200, 232, 264, 296, + 328, 375, 407, 439, 471, 23, 55, 87, 119, 151, 183, 215, 247, 279, 311, 343, 390, 422, 454, 6, 38, 70, + 102, 134, 166, 198, 230, 262, 294, 326, 358, 405, 437, 469, 21, 53, 85, 117, 149, 181, 213, 245, 277, 309, + 341, 373, 420, 452, 4, 36, 68, 100, 132, 164, 196, 228, 260, 292, 324, 356, 388, 435, 467, 19, 51, 83, + 115, 147, 179, 211, 243, 275, 307, 339, 371, 403, 450, 2, 34, 66, 98, 130, 162, 194, 226, 258, 290, 322, + 354, 386, 418, 465, 17, 49, 81, 113, 145, 177, 209, 241, 273, 305, 337, 369, 401, 433}; + + const LC3_INT L = 480; + const LC3_INT A = 15; + const LC3_INT B = 32; + const LC3_INT* idx1 = table1; + const LC3_INT* idx2 = table2; + + LC3_INT k, l; + LC3_FLOAT temp[64], out[960]; + + for (k = 0; k < A; k++) { + for (l = 0; l < B; l++) { + temp[2 * l] = in[2 * *idx1]; + temp[2 * l + 1] = in[2 * *idx1 + 1]; + idx1 += A; + } + + fft32(temp); /* 32-point FFT */ + idx1 -= L; + + for (l = 0; l < B; l++) { + in[2 * *idx1] = temp[2 * l]; + in[2 * *idx1 + 1] = temp[2 * l + 1]; + idx1 += A; + } + + idx1 -= L - 1; + } + + idx1 -= A; + + for (k = 0; k < B; k++) { + for (l = 0; l < A; l++) { + temp[2 * l] = in[2 * *idx1]; + temp[2 * l + 1] = in[2 * *idx1++ + 1]; + } + + fft15(temp); /* 15-point FFT */ + + for (l = 0; l < A; l++) { + out[2 * *idx2] = temp[2 * l]; + out[2 * *idx2++ + 1] = temp[2 * l + 1]; + } + } + + memmove(in, out, 2 * L * sizeof(LC3_FLOAT)); +} diff --git a/lc3plus/fft/fft_2_9.h b/lc3plus/fft/fft_2_9.h new file mode 100644 index 0000000000000000000000000000000000000000..54f4f839dfcba878cdf037f9940d49982c58c3c0 --- /dev/null +++ b/lc3plus/fft/fft_2_9.h @@ -0,0 +1,278 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +/* guard against unindended includes */ +#ifndef INCLUDED_FROM_IISFFT_C +#error "this file must not be included" +#endif + +static __inline void butterfly(const LC3_FLOAT a, const LC3_FLOAT b, LC3_FLOAT* aPlusb, LC3_FLOAT* aMinusb) +{ + *aPlusb = a + b; + *aMinusb = a - b; +} + +static void fft2(LC3_FLOAT* vec) +{ + /* + 1.0000 1.0000 + 1.0000 -1.0000 + */ + LC3_FLOAT re1 = vec[0]; + LC3_FLOAT im1 = vec[1]; + LC3_FLOAT re2 = vec[2]; + LC3_FLOAT im2 = vec[3]; + + vec[0] = re1 + re2; + vec[1] = im1 + im2; + vec[2] = re1 - re2; + vec[3] = im1 - im2; +} + +static void fft3(LC3_FLOAT* vec) +{ + const LC3_FLOAT C31 = 0.5; /* cos(PI/3); sin(2*PI/3) */ + const LC3_FLOAT C32 = 0.866025403784439; /* cos(PI/3); sin(2*PI/3) */ + + LC3_FLOAT re1 = vec[0]; + LC3_FLOAT im1 = vec[1]; + LC3_FLOAT re2 = vec[2]; + LC3_FLOAT im2 = vec[3]; + LC3_FLOAT re3 = vec[4]; + LC3_FLOAT im3 = vec[5]; + /* + 1.0000 1.0000 1.0000 + C31 C32 + 1.0000 -0.5000 - 0.8660i -0.5000 + 0.8660i + 1.0000 -0.5000 + 0.8660i -0.5000 - 0.8660i + */ + LC3_FLOAT tmp1 = re2 + re3; + LC3_FLOAT tmp3 = im2 + im3; + LC3_FLOAT tmp2 = re2 - re3; + LC3_FLOAT tmp4 = im2 - im3; + + vec[0] = re1 + tmp1; + vec[1] = im1 + tmp3; + vec[2] = re1 - C31 * tmp1 + C32 * tmp4; + vec[4] = re1 - C31 * tmp1 - C32 * tmp4; + vec[3] = im1 - C32 * tmp2 - C31 * tmp3; + vec[5] = im1 + C32 * tmp2 - C31 * tmp3; +} + +static void fft4(LC3_FLOAT* vec) +{ + LC3_FLOAT temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7; + + /* Pre-additions */ + temp0 = vec[0] + vec[4]; + temp2 = vec[0] - vec[4]; + temp1 = vec[1] + vec[5]; + temp3 = vec[1] - vec[5]; + temp4 = vec[2] + vec[6]; + temp7 = vec[2] - vec[6]; + temp5 = vec[7] + vec[3]; + temp6 = vec[7] - vec[3]; + + /* Post-additions */ + vec[0] = temp0 + temp4; + vec[1] = temp1 + temp5; + vec[2] = temp2 - temp6; + vec[3] = temp3 - temp7; + vec[4] = temp0 - temp4; + vec[5] = temp1 - temp5; + vec[6] = temp2 + temp6; + vec[7] = temp3 + temp7; +} + +static void fft5(LC3_FLOAT* vec) +{ + const LC3_FLOAT C51 = 0.309016994374947; /* cos(2*PI/5); */ + const LC3_FLOAT C52 = 0.951056516295154; /* sin(2*PI/5); */ + const LC3_FLOAT C53 = 0.809016994374947; /* cos( PI/5); */ + const LC3_FLOAT C54 = 0.587785252292473; /* sin( PI/5); */ + + LC3_FLOAT re1, im1, re2, im2, re3, im3, re4, im4, re5, im5, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; + + re1 = vec[0]; + im1 = vec[1]; + re2 = vec[2]; + im2 = vec[3]; + re3 = vec[4]; + im3 = vec[5]; + re4 = vec[6]; + im4 = vec[7]; + re5 = vec[8]; + im5 = vec[9]; + /* + 1.0000 1.0000 1.0000 1.0000 1.0000 + C51 C52 C53 C54 + 1.0000 0.3090 - 0.9511i -0.8090 - 0.5878i -0.8090 + 0.5878i 0.3090 + 0.9511i + 1.0000 -0.8090 - 0.5878i 0.3090 + 0.9511i 0.3090 - 0.9511i -0.8090 + 0.5878i + 1.0000 -0.8090 + 0.5878i 0.3090 - 0.9511i 0.3090 + 0.9511i -0.8090 - 0.5878i + 1.0000 0.3090 + 0.9511i -0.8090 + 0.5878i -0.8090 - 0.5878i 0.3090 - 0.9511i + */ + tmp1 = re2 + re5; + tmp2 = re2 - re5; + tmp3 = im2 + im5; + tmp4 = im2 - im5; + tmp5 = re3 + re4; + tmp6 = re3 - re4; + tmp7 = im3 + im4; + tmp8 = im3 - im4; + + vec[0] = re1 + tmp1 + tmp5; + vec[1] = im1 + tmp3 + tmp7; + vec[2] = re1 + C51 * tmp1 - C53 * tmp5 + C52 * tmp4 + C54 * tmp8; + vec[8] = re1 + C51 * tmp1 - C53 * tmp5 - C52 * tmp4 - C54 * tmp8; + vec[3] = im1 - C52 * tmp2 - C54 * tmp6 + C51 * tmp3 - C53 * tmp7; + vec[9] = im1 + C52 * tmp2 + C54 * tmp6 + C51 * tmp3 - C53 * tmp7; + vec[4] = re1 - C53 * tmp1 + C51 * tmp5 + C54 * tmp4 - C52 * tmp8; + vec[6] = re1 - C53 * tmp1 + C51 * tmp5 - C54 * tmp4 + C52 * tmp8; + vec[5] = im1 - C54 * tmp2 + C52 * tmp6 - C53 * tmp3 + C51 * tmp7; + vec[7] = im1 + C54 * tmp2 - C52 * tmp6 - C53 * tmp3 + C51 * tmp7; +} + + + +static void fft8(LC3_FLOAT* vec) +{ + const LC3_FLOAT INV_SQRT2 = 7.071067811865475e-1; + LC3_FLOAT temp1[16], temp2[16]; + + /* Pre-additions */ + temp1[0] = vec[0] + vec[8]; + temp1[2] = vec[0] - vec[8]; + temp1[1] = vec[1] + vec[9]; + temp1[3] = vec[1] - vec[9]; + temp1[4] = vec[2] + vec[10]; + temp1[6] = vec[2] - vec[10]; + temp1[5] = vec[3] + vec[11]; + temp1[7] = vec[3] - vec[11]; + temp1[8] = vec[4] + vec[12]; + temp1[10] = vec[4] - vec[12]; + temp1[9] = vec[5] + vec[13]; + temp1[11] = vec[5] - vec[13]; + temp1[12] = vec[6] + vec[14]; + temp1[14] = vec[6] - vec[14]; + temp1[13] = vec[7] + vec[15]; + temp1[15] = vec[7] - vec[15]; + + /* Pre-additions and core multiplications */ + temp2[0] = temp1[0] + temp1[8]; + temp2[4] = temp1[0] - temp1[8]; + temp2[1] = temp1[1] + temp1[9]; + temp2[5] = temp1[1] - temp1[9]; + temp2[8] = temp1[2] - temp1[11]; + temp2[10] = temp1[2] + temp1[11]; + temp2[9] = temp1[3] + temp1[10]; + temp2[11] = temp1[3] - temp1[10]; + temp2[2] = temp1[4] + temp1[12]; + temp2[7] = temp1[4] - temp1[12]; + temp2[3] = temp1[5] + temp1[13]; + temp2[6] = temp1[13] - temp1[5]; + + temp1[1] = temp1[6] + temp1[14]; + temp1[2] = temp1[6] - temp1[14]; + temp1[0] = temp1[7] + temp1[15]; + temp1[3] = temp1[7] - temp1[15]; + temp2[12] = (temp1[0] + temp1[2]) * INV_SQRT2; + temp2[14] = (temp1[0] - temp1[2]) * INV_SQRT2; + temp2[13] = (temp1[3] - temp1[1]) * INV_SQRT2; + temp2[15] = (temp1[1] + temp1[3]) * -INV_SQRT2; + + /* Post-additions */ + vec[0] = temp2[0] + temp2[2]; + vec[8] = temp2[0] - temp2[2]; + vec[1] = temp2[1] + temp2[3]; + vec[9] = temp2[1] - temp2[3]; + vec[4] = temp2[4] - temp2[6]; + vec[12] = temp2[4] + temp2[6]; + vec[5] = temp2[5] - temp2[7]; + vec[13] = temp2[5] + temp2[7]; + vec[6] = temp2[8] + temp2[14]; + vec[14] = temp2[8] - temp2[14]; + vec[7] = temp2[9] + temp2[15]; + vec[15] = temp2[9] - temp2[15]; + vec[2] = temp2[10] + temp2[12]; + vec[10] = temp2[10] - temp2[12]; + vec[3] = temp2[11] + temp2[13]; + vec[11] = temp2[11] - temp2[13]; +} + + +static void fft9(LC3_FLOAT* vec) +{ + const LC3_FLOAT C91 = 0.766044443118978; /* cos(2*PI/5); */ + const LC3_FLOAT C92 = 0.642787609686539; + const LC3_FLOAT C93 = 0.17364817766693; + const LC3_FLOAT C94 = 0.984807753012208; + const LC3_FLOAT C95 = 0.5; + const LC3_FLOAT C96 = 0.866025403784439; + const LC3_FLOAT C97 = 0.939692620785908; + const LC3_FLOAT C98 = 0.342020143325669; + + LC3_FLOAT re1, im1, re2_9p, re2_9m, im2_9p, im2_9m, re3_8p, re3_8m, im3_8p, im3_8m, re4_7p, re4_7m, im4_7p, im4_7m, + re5_6p, re5_6m, im5_6p, im5_6m; + + re1 = vec[0]; + im1 = vec[1]; + + butterfly(vec[1 * 2], vec[8 * 2], &re2_9p, &re2_9m); + butterfly(vec[1 * 2 + 1], vec[8 * 2 + 1], &im2_9p, &im2_9m); + butterfly(vec[2 * 2], vec[7 * 2], &re3_8p, &re3_8m); + butterfly(vec[2 * 2 + 1], vec[7 * 2 + 1], &im3_8p, &im3_8m); + butterfly(vec[3 * 2], vec[6 * 2], &re4_7p, &re4_7m); + butterfly(vec[3 * 2 + 1], vec[6 * 2 + 1], &im4_7p, &im4_7m); + butterfly(vec[4 * 2], vec[5 * 2], &re5_6p, &re5_6m); + butterfly(vec[4 * 2 + 1], vec[5 * 2 + 1], &im5_6p, &im5_6m); + + /* + 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 1.0000 + 1.0000 C91 - C92i C93 - C94i -C95 - C96i -C97 - C98i -C97 + C98i -C95 + C96i C93 + C94i C91 + C92i + 1.0000 C93 - C94i -C97 - C98i -C95 + C96i C91 + C92i C91 - C92i -C95 - C96i -C97 + C98i C93 + C94i + 1.0000 -C95 - C96i -C95 + C96i 1.0000 -C95 - C96i -C95 + C96i 1.0000 -C95 - C96i -C95 + C96i + 1.0000 -C97 - C98i C91 + C92i -C95 - C96i C93 + C94i C93 - C94i -C95 + C96i C91 - C92i -C97 + C98i + 1.0000 -C97 + C98i C91 - C92i -C95 + C96i C93 - C94i C93 + C94i -C95 - C96i C91 + C92i -C97 - C98i + 1.0000 -C95 + C96i -C95 - C96i 1.0000 -C95 + C96i -C95 - C96i 1.0000 -C95 + C96i -C95 - C96i + 1.0000 C93 + C94i -C97 + C98i -C95 - C96i C91 - C92i C91 + C92i -C95 + C96i -C97 - C98i C93 - C94i + 1.0000 C91 + C92i C93 + C94i -C95 + C96i -C97 + C98i -C97 - C98i -C95 - C96i C93 - C94i C91 - C92i + */ + vec[0] = re1 + re2_9p + re3_8p + re4_7p + re5_6p; + vec[1] = im1 + im2_9p + im3_8p + im4_7p + im5_6p; + vec[2] = re1 + C91 * re2_9p + C93 * re3_8p - C95 * re4_7p - C97 * re5_6p + C92 * im2_9m + C94 * im3_8m + + C96 * im4_7m + C98 * im5_6m; + vec[16] = re1 + C91 * re2_9p + C93 * re3_8p - C95 * re4_7p - C97 * re5_6p - C92 * im2_9m - C94 * im3_8m - + C96 * im4_7m - C98 * im5_6m; + vec[3] = im1 - C92 * re2_9m - C94 * re3_8m - C96 * re4_7m - C98 * re5_6m + C91 * im2_9p + C93 * im3_8p - + C95 * im4_7p - C97 * im5_6p; + vec[17] = im1 + C92 * re2_9m + C94 * re3_8m + C96 * re4_7m + C98 * re5_6m + C91 * im2_9p + C93 * im3_8p - + C95 * im4_7p - C97 * im5_6p; + vec[4] = re1 + C93 * re2_9p - C97 * re3_8p - C95 * re4_7p + C91 * re5_6p + C94 * im2_9m + C98 * im3_8m - + C96 * im4_7m - C92 * im5_6m; + vec[14] = re1 + C93 * re2_9p - C97 * re3_8p - C95 * re4_7p + C91 * re5_6p - C94 * im2_9m - C98 * im3_8m + + C96 * im4_7m + C92 * im5_6m; + vec[5] = im1 - C94 * re2_9m - C98 * re3_8m + C96 * re4_7m + C92 * re5_6m + C93 * im2_9p - C97 * im3_8p - + C95 * im4_7p + C91 * im5_6p; + vec[15] = im1 + C94 * re2_9m + C98 * re3_8m - C96 * re4_7m - C92 * re5_6m + C93 * im2_9p - C97 * im3_8p - + C95 * im4_7p + C91 * im5_6p; + vec[6] = re1 - C95 * (re2_9p + re3_8p + re5_6p) + re4_7p + C96 * (im2_9m - im3_8m + im5_6m); + vec[12] = re1 - C95 * (re2_9p + re3_8p + re5_6p) + re4_7p - C96 * (im2_9m - im3_8m + im5_6m); + vec[7] = im1 - C96 * (re2_9m - re3_8m + re5_6m) - C95 * (im2_9p + im3_8p + im5_6p) + im4_7p; + vec[13] = im1 + C96 * (re2_9m - re3_8m + re5_6m) - C95 * (im2_9p + im3_8p + im5_6p) + im4_7p; + vec[8] = re1 - C97 * re2_9p + C91 * re3_8p - C95 * re4_7p + C93 * re5_6p + C98 * im2_9m - C92 * im3_8m + + C96 * im4_7m - C94 * im5_6m; + vec[10] = re1 - C97 * re2_9p + C91 * re3_8p - C95 * re4_7p + C93 * re5_6p - C98 * im2_9m + C92 * im3_8m - + C96 * im4_7m + C94 * im5_6m; + vec[9] = im1 - C98 * re2_9m + C92 * re3_8m - C96 * re4_7m + C94 * re5_6m - C97 * im2_9p + C91 * im3_8p - + C95 * im4_7p + C93 * im5_6p; + vec[11] = im1 + C98 * re2_9m - C92 * re3_8m + C96 * re4_7m - C94 * re5_6m - C97 * im2_9p + C91 * im3_8p - + C95 * im4_7p + C93 * im5_6p; +} + diff --git a/lc3plus/fft/fft_32.h b/lc3plus/fft/fft_32.h new file mode 100644 index 0000000000000000000000000000000000000000..48b891108b88b53a9529c32d035b1aba981c4968 --- /dev/null +++ b/lc3plus/fft/fft_32.h @@ -0,0 +1,467 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +/* guard against unindended includes */ +#ifndef INCLUDED_FROM_IISFFT_C +#error "this file must not be included" +#endif + +static void fft32(LC3_FLOAT* vec) +{ + const LC3_FLOAT INV_SQRT2 = 7.071067811865475e-1; + const LC3_FLOAT COS_PI_DIV8 = 9.238795325112867e-1; + const LC3_FLOAT COS_3PI_DIV8 = 3.826834323650898e-1; + const LC3_FLOAT SQRT2PLUS1 = 2.414213562373095; + const LC3_FLOAT SQRT2MINUS1 = 4.142135623730952e-1; + + const LC3_FLOAT c[4] = {9.807852804032304e-1, 8.314696123025452e-1, 5.555702330196023e-1, 1.950903220161283e-1}; + + LC3_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, + temp10, temp11, temp12, temp13, temp14, temp15, temp16, temp17, temp18, temp19, temp110, temp111, temp112, + temp113, temp114, temp115, temp20, temp21, temp22, temp23, temp24, temp25, temp26, temp27, temp28, temp29, + temp210, temp211, temp212, temp213, temp214, temp215, temp30, temp31, temp32, temp33, temp34, temp35, temp36, + temp37, temp38, temp39, temp310, temp311, temp312, temp313, temp314, temp315, temp316, temp317, temp318, + temp319, temp320, temp321, temp322, temp323, temp324, temp325, temp326, temp327, temp328, temp329, temp330, + temp331, temp40, temp41, temp42, temp43, temp44, temp45, temp46, temp47, temp48, temp49, temp410, temp411, + temp412, temp413, temp414, temp415; + + temp20 = vec[2] - vec[34]; + temp21 = vec[3] - vec[35]; + temp30 = vec[0] + vec[32]; + temp31 = vec[1] + vec[33]; + temp32 = vec[2] + vec[34]; + temp33 = vec[3] + vec[35]; + + temp22 = vec[6] - vec[38]; + temp23 = vec[7] - vec[39]; + temp34 = vec[4] + vec[36]; + temp35 = vec[5] + vec[37]; + temp36 = vec[6] + vec[38]; + temp37 = vec[7] + vec[39]; + + temp24 = vec[10] - vec[42]; + temp25 = vec[11] - vec[43]; + temp38 = vec[8] + vec[40]; + temp39 = vec[9] + vec[41]; + temp310 = vec[10] + vec[42]; + temp311 = vec[11] + vec[43]; + + temp26 = vec[14] - vec[46]; + temp27 = vec[15] - vec[47]; + temp312 = vec[12] + vec[44]; + temp313 = vec[13] + vec[45]; + temp314 = vec[14] + vec[46]; + temp315 = vec[15] + vec[47]; + + temp28 = vec[18] - vec[50]; + temp29 = vec[19] - vec[51]; + temp316 = vec[16] + vec[48]; + temp317 = vec[17] + vec[49]; + temp318 = vec[18] + vec[50]; + temp319 = vec[19] + vec[51]; + + temp210 = vec[22] - vec[54]; + temp211 = vec[23] - vec[55]; + temp320 = vec[20] + vec[52]; + temp321 = vec[21] + vec[53]; + temp322 = vec[22] + vec[54]; + temp323 = vec[23] + vec[55]; + + temp212 = vec[26] - vec[58]; + temp213 = vec[27] - vec[59]; + temp324 = vec[24] + vec[56]; + temp325 = vec[25] + vec[57]; + temp326 = vec[26] + vec[58]; + temp327 = vec[27] + vec[59]; + + temp214 = vec[30] - vec[62]; + temp215 = vec[31] - vec[63]; + temp328 = vec[28] + vec[60]; + temp329 = vec[29] + vec[61]; + temp330 = vec[30] + vec[62]; + temp331 = vec[31] + vec[63]; + + /* Pre-additions */ + temp41 = -(temp20 + temp214); + temp42 = temp20 - temp214; + temp40 = temp21 + temp215; + temp43 = temp21 - temp215; + temp45 = -(temp22 + temp212); + temp46 = temp22 - temp212; + temp44 = temp23 + temp213; + temp47 = temp23 - temp213; + temp49 = -(temp24 + temp210); + temp410 = temp24 - temp210; + temp48 = temp25 + temp211; + temp411 = temp25 - temp211; + temp413 = -(temp26 + temp28); + temp414 = temp26 - temp28; + temp412 = temp27 + temp29; + temp415 = temp27 - temp29; + + /* Core multiplications */ + temp20 = temp40 * c[3] + temp44 * c[2] + temp48 * c[1] + temp412 * c[0]; + temp24 = temp40 * c[2] + temp44 * c[0] + temp48 * c[3] - temp412 * c[1]; + temp28 = temp40 * c[1] + temp44 * c[3] - temp48 * c[0] + temp412 * c[2]; + temp212 = temp40 * c[0] - temp44 * c[1] + temp48 * c[2] - temp412 * c[3]; + temp21 = temp41 * c[3] + temp45 * c[2] + temp49 * c[1] + temp413 * c[0]; + temp25 = temp41 * c[2] + temp45 * c[0] + temp49 * c[3] - temp413 * c[1]; + temp29 = temp41 * c[1] + temp45 * c[3] - temp49 * c[0] + temp413 * c[2]; + temp213 = temp41 * c[0] - temp45 * c[1] + temp49 * c[2] - temp413 * c[3]; + temp22 = temp42 * c[0] + temp46 * c[1] + temp410 * c[2] + temp414 * c[3]; + temp26 = temp42 * c[1] - temp46 * c[3] - temp410 * c[0] - temp414 * c[2]; + temp210 = temp42 * c[2] - temp46 * c[0] + temp410 * c[3] + temp414 * c[1]; + temp214 = temp42 * c[3] - temp46 * c[2] + temp410 * c[1] - temp414 * c[0]; + temp23 = temp43 * c[0] + temp47 * c[1] + temp411 * c[2] + temp415 * c[3]; + temp27 = temp43 * c[1] - temp47 * c[3] - temp411 * c[0] - temp415 * c[2]; + temp211 = temp43 * c[2] - temp47 * c[0] + temp411 * c[3] + temp415 * c[1]; + temp215 = temp43 * c[3] - temp47 * c[2] + temp411 * c[1] - temp415 * c[0]; + + /* Post-additions */ + temp40 = temp20 + temp22; + temp414 = temp20 - temp22; + temp41 = temp21 + temp23; + temp415 = temp21 - temp23; + temp42 = temp24 + temp26; + temp412 = temp24 - temp26; + temp43 = temp25 + temp27; + temp413 = temp25 - temp27; + temp44 = temp28 + temp210; + temp410 = temp28 - temp210; + temp45 = temp29 + temp211; + temp411 = temp29 - temp211; + temp46 = temp212 + temp214; + temp48 = temp212 - temp214; + temp47 = temp213 + temp215; + temp49 = temp213 - temp215; + + /* fft16(temp3); */ + /* even */ + temp10 = temp30 + temp316; + temp11 = temp31 + temp317; + temp12 = temp32 + temp318; + temp13 = temp33 + temp319; + temp14 = temp34 + temp320; + temp15 = temp35 + temp321; + temp16 = temp36 + temp322; + temp17 = temp37 + temp323; + temp18 = temp38 + temp324; + temp19 = temp39 + temp325; + temp110 = temp310 + temp326; + temp111 = temp311 + temp327; + temp112 = temp312 + temp328; + temp113 = temp313 + temp329; + temp114 = temp314 + temp330; + temp115 = temp315 + temp331; + + /* Pre-additions */ + tmp0 = temp10 + temp18; + tmp2 = temp10 - temp18; + tmp1 = temp11 + temp19; + tmp3 = temp11 - temp19; + tmp4 = temp12 + temp110; + tmp6 = temp12 - temp110; + tmp5 = temp13 + temp111; + tmp7 = temp13 - temp111; + tmp8 = temp14 + temp112; + tmp10 = temp14 - temp112; + tmp9 = temp15 + temp113; + tmp11 = temp15 - temp113; + tmp12 = temp16 + temp114; + tmp14 = temp16 - temp114; + tmp13 = temp17 + temp115; + tmp15 = temp17 - temp115; + + /* Pre-additions and core multiplications */ + temp20 = tmp0 + tmp8; + temp24 = tmp0 - tmp8; + temp21 = tmp1 + tmp9; + temp25 = tmp1 - tmp9; + temp28 = tmp2 - tmp11; + temp210 = tmp2 + tmp11; + temp29 = tmp3 + tmp10; + temp211 = tmp3 - tmp10; + temp22 = tmp4 + tmp12; + temp27 = tmp4 - tmp12; + temp23 = tmp5 + tmp13; + temp26 = tmp13 - tmp5; + + tmp1 = tmp6 + tmp14; + tmp2 = tmp6 - tmp14; + tmp0 = tmp7 + tmp15; + tmp3 = tmp7 - tmp15; + temp212 = (tmp0 + tmp2) * INV_SQRT2; + temp214 = (tmp0 - tmp2) * INV_SQRT2; + temp213 = (tmp3 - tmp1) * INV_SQRT2; + temp215 = (tmp1 + tmp3) * -INV_SQRT2; + + /* odd */ + temp10 = temp30 - temp316; + temp11 = temp31 - temp317; + temp12 = temp32 - temp318; + temp13 = temp33 - temp319; + temp14 = temp34 - temp320; + temp15 = temp35 - temp321; + temp16 = temp36 - temp322; + temp17 = temp37 - temp323; + temp18 = temp38 - temp324; + temp19 = temp39 - temp325; + temp110 = temp310 - temp326; + temp111 = temp311 - temp327; + temp112 = temp312 - temp328; + temp113 = temp313 - temp329; + temp114 = temp314 - temp330; + temp115 = temp315 - temp331; + + /* Post-additions */ + temp30 = temp20 + temp22; + temp316 = temp20 - temp22; + temp31 = temp21 + temp23; + temp317 = temp21 - temp23; + temp38 = temp24 - temp26; + temp324 = temp24 + temp26; + temp39 = temp25 - temp27; + temp325 = temp25 + temp27; + temp312 = temp28 + temp214; + temp328 = temp28 - temp214; + temp313 = temp29 + temp215; + temp329 = temp29 - temp215; + temp34 = temp210 + temp212; + temp320 = temp210 - temp212; + temp35 = temp211 + temp213; + temp321 = temp211 - temp213; + + /* Pre-additions and core multiplications */ + tmp9 = (temp12 + temp114) * -COS_3PI_DIV8; + tmp10 = (temp12 - temp114) * COS_PI_DIV8; + tmp8 = (temp13 + temp115) * COS_3PI_DIV8; + tmp11 = (temp13 - temp115) * COS_PI_DIV8; + tmp5 = (temp14 + temp112) * -INV_SQRT2; + tmp6 = (temp14 - temp112) * INV_SQRT2; + tmp4 = (temp15 + temp113) * INV_SQRT2; + tmp7 = (temp15 - temp113) * INV_SQRT2; + tmp13 = (temp16 + temp110) * -COS_PI_DIV8; + tmp14 = (temp16 - temp110) * COS_3PI_DIV8; + tmp12 = (temp17 + temp111) * COS_PI_DIV8; + tmp15 = (temp17 - temp111) * COS_3PI_DIV8; + + /* Core multiplications */ + temp12 = tmp8 * SQRT2PLUS1 - tmp12 * SQRT2MINUS1; + temp13 = tmp9 * SQRT2PLUS1 - tmp13 * SQRT2MINUS1; + temp14 = tmp10 * SQRT2MINUS1 - tmp14 * SQRT2PLUS1; + temp15 = tmp11 * SQRT2MINUS1 - tmp15 * SQRT2PLUS1; + + /* Post-additions */ + tmp8 += tmp12; + tmp9 += tmp13; + tmp10 += tmp14; + tmp11 += tmp15; + temp16 = temp10 + tmp4; + temp110 = temp10 - tmp4; + temp17 = temp11 + tmp5; + temp111 = temp11 - tmp5; + + temp112 = tmp6 - temp19; + temp114 = tmp6 + temp19; + temp113 = temp18 + tmp7; + temp115 = temp18 - tmp7; + + tmp0 = temp16 - temp114; + tmp2 = temp16 + temp114; + tmp1 = temp17 + temp115; + tmp3 = temp17 - temp115; + tmp4 = temp110 + temp112; + tmp6 = temp110 - temp112; + tmp5 = temp111 + temp113; + tmp7 = temp111 - temp113; + + temp110 = tmp8 + tmp10; + tmp10 = tmp8 - tmp10; + temp111 = tmp9 + tmp11; + tmp11 = tmp9 - tmp11; + + tmp12 = temp12 + temp14; + tmp14 = temp12 - temp14; + tmp13 = temp13 + temp15; + tmp15 = temp13 - temp15; + + temp32 = tmp2 + temp110; + temp318 = tmp2 - temp110; + temp33 = tmp3 + temp111; + temp319 = tmp3 - temp111; + temp36 = tmp0 + tmp12; + temp322 = tmp0 - tmp12; + temp37 = tmp1 + tmp13; + temp323 = tmp1 - tmp13; + temp314 = tmp4 + tmp10; + temp330 = tmp4 - tmp10; + temp315 = tmp5 + tmp11; + temp331 = tmp5 - tmp11; + temp310 = tmp6 + tmp14; + temp326 = tmp6 - tmp14; + temp311 = tmp7 + tmp15; + temp327 = tmp7 - tmp15; + /* fft16(temp3); end */ + + /* fft8even(temp1); */ + temp10 = vec[0] - vec[32]; + temp11 = vec[1] - vec[33]; + temp12 = vec[4] - vec[36]; + temp13 = vec[5] - vec[37]; + temp14 = vec[8] - vec[40]; + temp15 = vec[9] - vec[41]; + temp16 = vec[12] - vec[44]; + temp17 = vec[13] - vec[45]; + temp18 = vec[16] - vec[48]; + temp19 = vec[17] - vec[49]; + temp110 = vec[20] - vec[52]; + temp111 = vec[21] - vec[53]; + temp112 = vec[24] - vec[56]; + temp113 = vec[25] - vec[57]; + temp114 = vec[28] - vec[60]; + temp115 = vec[29] - vec[61]; + + /* Pre-additions and core multiplications */ + tmp9 = (temp12 + temp114) * -COS_3PI_DIV8; + tmp10 = (temp12 - temp114) * COS_PI_DIV8; + tmp8 = (temp13 + temp115) * COS_3PI_DIV8; + tmp11 = (temp13 - temp115) * COS_PI_DIV8; + tmp5 = (temp14 + temp112) * -INV_SQRT2; + tmp6 = (temp14 - temp112) * INV_SQRT2; + tmp4 = (temp15 + temp113) * INV_SQRT2; + tmp7 = (temp15 - temp113) * INV_SQRT2; + tmp13 = (temp16 + temp110) * -COS_PI_DIV8; + tmp14 = (temp16 - temp110) * COS_3PI_DIV8; + tmp12 = (temp17 + temp111) * COS_PI_DIV8; + tmp15 = (temp17 - temp111) * COS_3PI_DIV8; + + /* Core multiplications */ + temp12 = tmp8 * SQRT2PLUS1 - tmp12 * SQRT2MINUS1; + temp13 = tmp9 * SQRT2PLUS1 - tmp13 * SQRT2MINUS1; + temp14 = tmp10 * SQRT2MINUS1 - tmp14 * SQRT2PLUS1; + temp15 = tmp11 * SQRT2MINUS1 - tmp15 * SQRT2PLUS1; + + /* Post-additions */ + tmp8 += tmp12; + tmp9 += tmp13; + tmp10 += tmp14; + tmp11 += tmp15; + temp16 = temp10 + tmp4; + temp110 = temp10 - tmp4; + temp17 = temp11 + tmp5; + temp111 = temp11 - tmp5; + + temp112 = tmp6 - temp19; + temp114 = tmp6 + temp19; + temp113 = temp18 + tmp7; + temp115 = temp18 - tmp7; + + tmp0 = temp16 - temp114; + tmp2 = temp16 + temp114; + tmp1 = temp17 + temp115; + tmp3 = temp17 - temp115; + tmp4 = temp110 + temp112; + tmp6 = temp110 - temp112; + tmp5 = temp111 + temp113; + tmp7 = temp111 - temp113; + + temp110 = tmp8 + tmp10; + tmp10 = tmp8 - tmp10; + temp111 = tmp9 + tmp11; + tmp11 = tmp9 - tmp11; + + tmp12 = temp12 + temp14; + tmp14 = temp12 - temp14; + tmp13 = temp13 + temp15; + tmp15 = temp13 - temp15; + + temp10 = tmp2 + temp110; + temp18 = tmp2 - temp110; + temp11 = tmp3 + temp111; + temp19 = tmp3 - temp111; + temp12 = tmp0 + tmp12; + temp110 = tmp0 - tmp12; + temp13 = tmp1 + tmp13; + temp111 = tmp1 - tmp13; + temp16 = tmp4 + tmp10; + temp114 = tmp4 - tmp10; + temp17 = tmp5 + tmp11; + temp115 = tmp5 - tmp11; + temp14 = tmp6 + tmp14; + temp112 = tmp6 - tmp14; + temp15 = tmp7 + tmp15; + temp113 = tmp7 - tmp15; + /* fft8even(temp1); end */ + + *vec++ = temp30; + *vec++ = temp31; + *vec++ = temp10 + temp40; + *vec++ = temp11 + temp41; + *vec++ = temp32; + *vec++ = temp33; + *vec++ = temp12 + temp42; + *vec++ = temp13 + temp43; + *vec++ = temp34; + *vec++ = temp35; + *vec++ = temp14 + temp44; + *vec++ = temp15 + temp45; + *vec++ = temp36; + *vec++ = temp37; + *vec++ = temp16 + temp46; + *vec++ = temp17 + temp47; + *vec++ = temp38; + *vec++ = temp39; + *vec++ = temp18 + temp48; + *vec++ = temp19 + temp49; + *vec++ = temp310; + *vec++ = temp311; + *vec++ = temp110 + temp410; + *vec++ = temp111 + temp411; + *vec++ = temp312; + *vec++ = temp313; + *vec++ = temp112 + temp412; + *vec++ = temp113 + temp413; + *vec++ = temp314; + *vec++ = temp315; + *vec++ = temp114 + temp414; + *vec++ = temp115 + temp415; + *vec++ = temp316; + *vec++ = temp317; + *vec++ = temp10 - temp40; + *vec++ = temp11 - temp41; + *vec++ = temp318; + *vec++ = temp319; + *vec++ = temp12 - temp42; + *vec++ = temp13 - temp43; + *vec++ = temp320; + *vec++ = temp321; + *vec++ = temp14 - temp44; + *vec++ = temp15 - temp45; + *vec++ = temp322; + *vec++ = temp323; + *vec++ = temp16 - temp46; + *vec++ = temp17 - temp47; + *vec++ = temp324; + *vec++ = temp325; + *vec++ = temp18 - temp48; + *vec++ = temp19 - temp49; + *vec++ = temp326; + *vec++ = temp327; + *vec++ = temp110 - temp410; + *vec++ = temp111 - temp411; + *vec++ = temp328; + *vec++ = temp329; + *vec++ = temp112 - temp412; + *vec++ = temp113 - temp413; + *vec++ = temp330; + *vec++ = temp331; + *vec++ = temp114 - temp414; + *vec++ = temp115 - temp415; +} diff --git a/lc3plus/fft/fft_384_768.h b/lc3plus/fft/fft_384_768.h new file mode 100644 index 0000000000000000000000000000000000000000..47f42e90d6546a945a4857a14a43bbc90ec2cfe9 --- /dev/null +++ b/lc3plus/fft/fft_384_768.h @@ -0,0 +1,103 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +/* guard against unindended includes */ +#ifndef INCLUDED_FROM_IISFFT_C +#error "this file must not be included" +#endif + +static void fft384(LC3_FLOAT* restrict in) +{ + const LC3_INT table1[384] = { + 0, 256, 128, 129, 1, 257, 258, 130, 2, 3, 259, 131, 132, 4, 260, 261, 133, 5, 6, 262, 134, 135, + 7, 263, 264, 136, 8, 9, 265, 137, 138, 10, 266, 267, 139, 11, 12, 268, 140, 141, 13, 269, 270, 142, + 14, 15, 271, 143, 144, 16, 272, 273, 145, 17, 18, 274, 146, 147, 19, 275, 276, 148, 20, 21, 277, 149, + 150, 22, 278, 279, 151, 23, 24, 280, 152, 153, 25, 281, 282, 154, 26, 27, 283, 155, 156, 28, 284, 285, + 157, 29, 30, 286, 158, 159, 31, 287, 288, 160, 32, 33, 289, 161, 162, 34, 290, 291, 163, 35, 36, 292, + 164, 165, 37, 293, 294, 166, 38, 39, 295, 167, 168, 40, 296, 297, 169, 41, 42, 298, 170, 171, 43, 299, + 300, 172, 44, 45, 301, 173, 174, 46, 302, 303, 175, 47, 48, 304, 176, 177, 49, 305, 306, 178, 50, 51, + 307, 179, 180, 52, 308, 309, 181, 53, 54, 310, 182, 183, 55, 311, 312, 184, 56, 57, 313, 185, 186, 58, + 314, 315, 187, 59, 60, 316, 188, 189, 61, 317, 318, 190, 62, 63, 319, 191, 192, 64, 320, 321, 193, 65, + 66, 322, 194, 195, 67, 323, 324, 196, 68, 69, 325, 197, 198, 70, 326, 327, 199, 71, 72, 328, 200, 201, + 73, 329, 330, 202, 74, 75, 331, 203, 204, 76, 332, 333, 205, 77, 78, 334, 206, 207, 79, 335, 336, 208, + 80, 81, 337, 209, 210, 82, 338, 339, 211, 83, 84, 340, 212, 213, 85, 341, 342, 214, 86, 87, 343, 215, + 216, 88, 344, 345, 217, 89, 90, 346, 218, 219, 91, 347, 348, 220, 92, 93, 349, 221, 222, 94, 350, 351, + 223, 95, 96, 352, 224, 225, 97, 353, 354, 226, 98, 99, 355, 227, 228, 100, 356, 357, 229, 101, 102, 358, + 230, 231, 103, 359, 360, 232, 104, 105, 361, 233, 234, 106, 362, 363, 235, 107, 108, 364, 236, 237, 109, 365, + 366, 238, 110, 111, 367, 239, 240, 112, 368, 369, 241, 113, 114, 370, 242, 243, 115, 371, 372, 244, 116, 117, + 373, 245, 246, 118, 374, 375, 247, 119, 120, 376, 248, 249, 121, 377, 378, 250, 122, 123, 379, 251, 252, 124, + 380, 381, 253, 125, 126, 382, 254, 255, 127, 383}; + const LC3_INT table2[384] = { + 0, 128, 256, 3, 131, 259, 6, 134, 262, 9, 137, 265, 12, 140, 268, 15, 143, 271, 18, 146, 274, 21, + 149, 277, 24, 152, 280, 27, 155, 283, 30, 158, 286, 33, 161, 289, 36, 164, 292, 39, 167, 295, 42, 170, + 298, 45, 173, 301, 48, 176, 304, 51, 179, 307, 54, 182, 310, 57, 185, 313, 60, 188, 316, 63, 191, 319, + 66, 194, 322, 69, 197, 325, 72, 200, 328, 75, 203, 331, 78, 206, 334, 81, 209, 337, 84, 212, 340, 87, + 215, 343, 90, 218, 346, 93, 221, 349, 96, 224, 352, 99, 227, 355, 102, 230, 358, 105, 233, 361, 108, 236, + 364, 111, 239, 367, 114, 242, 370, 117, 245, 373, 120, 248, 376, 123, 251, 379, 126, 254, 382, 129, 257, 1, + 132, 260, 4, 135, 263, 7, 138, 266, 10, 141, 269, 13, 144, 272, 16, 147, 275, 19, 150, 278, 22, 153, + 281, 25, 156, 284, 28, 159, 287, 31, 162, 290, 34, 165, 293, 37, 168, 296, 40, 171, 299, 43, 174, 302, + 46, 177, 305, 49, 180, 308, 52, 183, 311, 55, 186, 314, 58, 189, 317, 61, 192, 320, 64, 195, 323, 67, + 198, 326, 70, 201, 329, 73, 204, 332, 76, 207, 335, 79, 210, 338, 82, 213, 341, 85, 216, 344, 88, 219, + 347, 91, 222, 350, 94, 225, 353, 97, 228, 356, 100, 231, 359, 103, 234, 362, 106, 237, 365, 109, 240, 368, + 112, 243, 371, 115, 246, 374, 118, 249, 377, 121, 252, 380, 124, 255, 383, 127, 258, 2, 130, 261, 5, 133, + 264, 8, 136, 267, 11, 139, 270, 14, 142, 273, 17, 145, 276, 20, 148, 279, 23, 151, 282, 26, 154, 285, + 29, 157, 288, 32, 160, 291, 35, 163, 294, 38, 166, 297, 41, 169, 300, 44, 172, 303, 47, 175, 306, 50, + 178, 309, 53, 181, 312, 56, 184, 315, 59, 187, 318, 62, 190, 321, 65, 193, 324, 68, 196, 327, 71, 199, + 330, 74, 202, 333, 77, 205, 336, 80, 208, 339, 83, 211, 342, 86, 214, 345, 89, 217, 348, 92, 220, 351, + 95, 223, 354, 98, 226, 357, 101, 229, 360, 104, 232, 363, 107, 235, 366, 110, 238, 369, 113, 241, 372, 116, + 244, 375, 119, 247, 378, 122, 250, 381, 125, 253}; + + const LC3_INT L = 384; + const LC3_INT A = 3; + const LC3_INT B = 128; + const LC3_INT* idx1 = table1; + const LC3_INT* idx2 = table2; + + LC3_INT k, l; + LC3_FLOAT temp[256], out[768]; + + for (k = 0; k < A; k++) { + for (l = 0; l < B; l++) { + temp[2 * l] = in[2 * *idx1]; + temp[2 * l + 1] = in[2 * *idx1 + 1]; + idx1 += A; + } + + fft128(temp); /* 128-point FFT */ + idx1 -= L; + + for (l = 0; l < B; l++) { + in[2 * *idx1] = temp[2 * l]; + in[2 * *idx1 + 1] = temp[2 * l + 1]; + idx1 += A; + } + + idx1 -= L - 1; + } + + idx1 -= A; + + for (k = 0; k < B; k++) { + for (l = 0; l < A; l++) { + temp[2 * l] = in[2 * *idx1]; + temp[2 * l + 1] = in[2 * *idx1++ + 1]; + } + + fft3(temp); /* 3-point FFT */ + + for (l = 0; l < A; l++) { + out[2 * *idx2] = temp[2 * l]; + out[2 * *idx2++ + 1] = temp[2 * l + 1]; + } + } + + memmove(in, out, 2 * L * sizeof(LC3_FLOAT)); +} + diff --git a/lc3plus/fft/fft_60_128.h b/lc3plus/fft/fft_60_128.h new file mode 100644 index 0000000000000000000000000000000000000000..75f1aaef45cf21c69b717e39a63cdff31f2c984b --- /dev/null +++ b/lc3plus/fft/fft_60_128.h @@ -0,0 +1,161 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +/* guard against unindended includes */ +#ifndef INCLUDED_FROM_IISFFT_C +#error "this file must not be included" +#endif + +static void fft60(LC3_FLOAT* in) +{ + const LC3_INT table1[] = {0, 45, 30, 15, 16, 1, 46, 31, 32, 17, 2, 47, 48, 33, 18, 3, 4, 49, 34, 19, + 20, 5, 50, 35, 36, 21, 6, 51, 52, 37, 22, 7, 8, 53, 38, 23, 24, 9, 54, 39, + 40, 25, 10, 55, 56, 41, 26, 11, 12, 57, 42, 27, 28, 13, 58, 43, 44, 29, 14, 59}; + const LC3_INT table2[] = {0, 15, 30, 45, 4, 19, 34, 49, 8, 23, 38, 53, 12, 27, 42, 57, 16, 31, 46, 1, + 20, 35, 50, 5, 24, 39, 54, 9, 28, 43, 58, 13, 32, 47, 2, 17, 36, 51, 6, 21, + 40, 55, 10, 25, 44, 59, 14, 29, 48, 3, 18, 33, 52, 7, 22, 37, 56, 11, 26, 41}; + const LC3_INT a = 4; + const LC3_INT b = 15; + const LC3_INT L = 60; + const LC3_INT* idx1 = table1; + const LC3_INT* idx2 = table2; + + LC3_FLOAT temp[30], out[120]; + LC3_INT k, l; + + for (k = 0; k < a; k++) { + for (l = 0; l < b; l++) { + temp[2 * l] = in[2 * *idx1]; + temp[2 * l + 1] = in[2 * *idx1 + 1]; + idx1 += a; + } + + fft15(temp); /* 15-point FFT */ + idx1 -= L; + + for (l = 0; l < b; l++) { + in[2 * *idx1] = temp[2 * l]; + in[2 * *idx1 + 1] = temp[2 * l + 1]; + idx1 += a; + } + idx1 -= L - 1; + } + + idx1 -= a; + + for (k = 0; k < b; k++) { + for (l = 0; l < a; l++) { + temp[2 * l] = in[2 * *idx1]; + temp[2 * l + 1] = in[2 * *idx1++ + 1]; + } + + fft4(temp); /* 4-point FFT */ + + for (l = 0; l < a; l++) { + out[2 * *idx2] = temp[2 * l]; + out[2 * *idx2++ + 1] = temp[2 * l + 1]; + } + } + memmove(in, out, 2 * L * sizeof(LC3_FLOAT)); +} + +static void fft64(LC3_FLOAT* vec) +{ + const LC3_FLOAT w[] = { + 1.0000000000f, 0.9951847267f, 0.9807852804f, 0.9569403357f, 0.9238795325f, 0.8819212643f, 0.8314696123f, + 0.7730104534f, 0.7071067812f, 0.6343932842f, 0.5555702330f, 0.4713967368f, 0.3826834324f, 0.2902846773f, + 0.1950903220f, 0.0980171403f, 0.0000000000f, -0.0980171403f, -0.1950903220f, -0.2902846773f, -0.3826834324f, + -0.4713967368f, -0.5555702330f, -0.6343932842f, -0.7071067812f, -0.7730104534f, -0.8314696123f, -0.8819212643f, + -0.9238795325f, -0.9569403357f, -0.9807852804f, -0.9951847267f, -1.0000000000f, -0.9951847267f, -0.9807852804f, + -0.9569403357f, -0.9238795325f, -0.8819212643f, -0.8314696123f, -0.7730104534f, -0.7071067812f, -0.6343932842f, + -0.5555702330f, -0.4713967368f, -0.3826834324f, -0.2902846773f, -0.1950903220f, -0.0980171403f}; + + LC3_FLOAT temp1[64], temp2[64]; + LC3_INT i; + + for (i = 0; i < 32; i++) { + temp1[2 * i] = vec[4 * i]; + temp1[2 * i + 1] = vec[4 * i + 1]; + temp2[2 * i] = vec[4 * i + 2]; + temp2[2 * i + 1] = vec[4 * i + 3]; + } + + fft32(temp1); + fft32(temp2); + + for (i = 0; i < 32; i++) { + LC3_FLOAT re, im, wre, wim, tre, tim; + + re = temp2[2 * i]; + im = temp2[2 * i + 1]; + + wre = w[i]; + wim = w[i + 16]; + + tre = re * wre - im * wim; + tim = re * wim + im * wre; + + vec[2 * i] = temp1[2 * i] + tre; + vec[2 * i + 1] = temp1[2 * i + 1] + tim; + vec[2 * i + 64] = temp1[2 * i] - tre; + vec[2 * i + 65] = temp1[2 * i + 1] - tim; + } +} + +static void fft128(LC3_FLOAT* vec) +{ + const LC3_FLOAT w[] = { + 1.0000000000f, 0.9987954562f, 0.9951847267f, 0.9891765100f, 0.9807852804f, 0.9700312532f, 0.9569403357f, + 0.9415440652f, 0.9238795325f, 0.9039892931f, 0.8819212643f, 0.8577286100f, 0.8314696123f, 0.8032075315f, + 0.7730104534f, 0.7409511254f, 0.7071067812f, 0.6715589548f, 0.6343932842f, 0.5956993045f, 0.5555702330f, + 0.5141027442f, 0.4713967368f, 0.4275550934f, 0.3826834324f, 0.3368898534f, 0.2902846773f, 0.2429801799f, + 0.1950903220f, 0.1467304745f, 0.0980171403f, 0.0490676743f, 0.0000000000f, -0.0490676743f, -0.0980171403f, + -0.1467304745f, -0.1950903220f, -0.2429801799f, -0.2902846773f, -0.3368898534f, -0.3826834324f, -0.4275550934f, + -0.4713967368f, -0.5141027442f, -0.5555702330f, -0.5956993045f, -0.6343932842f, -0.6715589548f, -0.7071067812f, + -0.7409511254f, -0.7730104534f, -0.8032075315f, -0.8314696123f, -0.8577286100f, -0.8819212643f, -0.9039892931f, + -0.9238795325f, -0.9415440652f, -0.9569403357f, -0.9700312532f, -0.9807852804f, -0.9891765100f, -0.9951847267f, + -0.9987954562f, -1.0000000000f, -0.9987954562f, -0.9951847267f, -0.9891765100f, -0.9807852804f, -0.9700312532f, + -0.9569403357f, -0.9415440652f, -0.9238795325f, -0.9039892931f, -0.8819212643f, -0.8577286100f, -0.8314696123f, + -0.8032075315f, -0.7730104534f, -0.7409511254f, -0.7071067812f, -0.6715589548f, -0.6343932842f, -0.5956993045f, + -0.5555702330f, -0.5141027442f, -0.4713967368f, -0.4275550934f, -0.3826834324f, -0.3368898534f, -0.2902846773f, + -0.2429801799f, -0.1950903220f, -0.1467304745f, -0.0980171403f, -0.0490676743f, + }; + + LC3_FLOAT temp1[128], temp2[128]; + LC3_INT i; + + for (i = 0; i < 64; i++) { + temp1[2 * i] = vec[4 * i]; + temp1[2 * i + 1] = vec[4 * i + 1]; + temp2[2 * i] = vec[4 * i + 2]; + temp2[2 * i + 1] = vec[4 * i + 3]; + } + + fft64(temp1); + fft64(temp2); + + for (i = 0; i < 64; i++) { + LC3_FLOAT re, im, wre, wim, tre, tim; + + re = temp2[2 * i]; + im = temp2[2 * i + 1]; + + wre = w[i]; + wim = w[i + 32]; + + tre = re * wre - im * wim; + tim = re * wim + im * wre; + + vec[2 * i] = temp1[2 * i] + tre; + vec[2 * i + 1] = temp1[2 * i + 1] + tim; + vec[2 * i + 128] = temp1[2 * i] - tre; + vec[2 * i + 129] = temp1[2 * i + 1] - tim; + } +} diff --git a/lc3plus/fft/fft_generic.h b/lc3plus/fft/fft_generic.h new file mode 100644 index 0000000000000000000000000000000000000000..e517ffb2501daf1d5e4ff16fcb1bb9197d6a616e --- /dev/null +++ b/lc3plus/fft/fft_generic.h @@ -0,0 +1,699 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +/* guard against unindended includes */ +#ifndef INCLUDED_FROM_IISFFT_C +#error "this file must not be included" +#endif + +#define FFT_INTERNAL_TRIG_PREC double +#define BORDER_FOR_SECOND_SCRATCH 100 + +static const LC3_INT primeFactors[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, + 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, + 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, + 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 0}; + +/* fft, returns 1 if length is supported and fft was applied */ +static LC3_INT fft_n(LC3_FLOAT* x, LC3_INT length) +{ + switch (length) { + case 2: + fft2(x); + return 1; + case 3: + fft3(x); + return 1; + case 4: + fft4(x); + return 1; + case 5: + fft5(x); + return 1; + case 8: + fft8(x); + return 1; + case 9: + fft9(x); + return 1; + case 15: + fft15(x); + return 1; + case 16: + fft16(x); + return 1; + case 32: + fft32(x); + return 1; + case 60: + fft60(x); + return 1; + case 64: + fft64(x); + return 1; + case 128: + fft128(x); + return 1; + case 240: + fft240(x); + return 1; + case 256: + LC3_cfft(x, x + 1, 256, 2, -1); + return 1; + case 384: + fft384(x); + return 1; + case 480: + fft480(x); + return 1; + case 512: + LC3_cfft(x, x + 1, 512, 2, -1); + return 1; + case 1024: + LC3_cfft(x, x + 1, 1024, 2, -1); + return 1; + default: + return 0; + } +} + + +/* returns 1 on success or 0 if IISFFT_MAXFACTORS is too small */ +static LC3_INT factorize(LC3_INT length, LC3_INT* restrict numFactors, LC3_INT* restrict factor, + LC3_INT* restrict isPrime) +{ + LC3_INT remainder = length; + LC3_INT idx = 0, cnt = 0; + LC3_INT actFac = primeFactors[idx]; + LC3_INT inc = 0; + + *numFactors = 0; + + while (remainder > 1 && actFac != 0) { + if (remainder % actFac == 0) { + if (inc == 0) { + inc = 1; + (*numFactors)++; + } + remainder /= actFac; + } else { + actFac = primeFactors[++idx]; + inc = 0; + } + } + if (remainder > 1) { + (*numFactors)++; + } + + if (*numFactors > IISFFT_MAXFACTORS) + return 0; + + idx = 0, cnt = 0, inc = 0; + remainder = length; + actFac = primeFactors[idx]; + (factor)[cnt] = 1; + while (remainder > 1 && actFac != 0) { + if (remainder % actFac == 0) { + (factor)[cnt] *= actFac; + remainder /= actFac; + inc = 1; + if (factor[cnt] == actFac) { /* first appearance of the factor */ + isPrime[cnt] = 1; + } else { + isPrime[cnt] = 0; + } + } else { + actFac = primeFactors[++idx]; + if (inc == 1) { + cnt++; + } + inc = 0; + (factor)[cnt] = 1; + } + } + if (remainder > 1) { + factor[cnt] = remainder; + } + return 1; +} + +static void oddFFT(LC3_FLOAT* restrict x, LC3_INT length, LC3_FLOAT* restrict scratch) +{ + LC3_INT i, k, n; + LC3_FLOAT * src1, *src2, *dest1, *dest2; + FFT_INTERNAL_TRIG_PREC sinValOrg, cosValOrg; + + dest1 = scratch + 1; + dest2 = scratch + length + 1; + src1 = x + 2; + src2 = x + 2 * length - 1; + + scratch[0] = x[0]; + scratch[length] = x[1]; + + for (i = 2; i < length; i += 2) { + LC3_FLOAT tmp1R, tmp1I, tmp2R, tmp2I; + tmp1R = *src1++; + tmp1I = *src1++; + tmp2I = *src2--; + tmp2R = *src2--; + *dest1++ = tmp1R + tmp2R; + *dest1++ = tmp1R - tmp2R; + *dest2++ = tmp1I + tmp2I; + *dest2++ = tmp1I - tmp2I; + + x[0] += tmp1R + tmp2R; + x[1] += tmp1I + tmp2I; + } + + dest1 = x + 2; + dest2 = x + 2 * length - 2; + for (k = 2; k < length; k += 2) { + FFT_INTERNAL_TRIG_PREC sinVal = 0, cosVal = 1; + cosValOrg = LC3_COS(-M_PIl * k / length); + sinValOrg = LC3_SIN(-M_PIl * k / length); + + *dest1 = *dest2 = scratch[0]; + *(dest1 + 1) = *(dest2 + 1) = scratch[length]; + + src1 = scratch + 1; + src2 = scratch + length + 1; + + for (n = 2; n < length; n += 2) { + LC3_FLOAT rePre, reMre, imPim, imMim; + /* + cos(x+y) = cox(x) cos(y) - sin(x) sin(y); + sin(x+y) = sin(x) cos(y) + cos(x) sin(y); + */ + FFT_INTERNAL_TRIG_PREC tmp = cosVal * cosValOrg - sinVal * sinValOrg; + sinVal = sinVal * cosValOrg + cosVal * sinValOrg; + cosVal = tmp; + + rePre = *src1++; + reMre = *src1++; + imPim = *src2++; + imMim = *src2++; + + *dest1 += (LC3_FLOAT)cosVal * rePre - (LC3_FLOAT)sinVal * imMim; + *(dest1 + 1) += (LC3_FLOAT)sinVal * reMre + (LC3_FLOAT)cosVal * imPim; + *dest2 += (LC3_FLOAT)cosVal * rePre + (LC3_FLOAT)sinVal * imMim; + *(dest2 + 1) += (LC3_FLOAT)-sinVal * reMre + (LC3_FLOAT)cosVal * imPim; + } + dest1 += 2; + dest2 -= 2; + } +} + +static LC3_INT findInverse(LC3_INT a, LC3_INT b) +{ + LC3_INT b0 = b, t, q; + LC3_INT x0 = 0, x1 = 1; + + if (b == 1) { + return 1; + } + + while (a > 1) { + q = a / b; + t = b, b = a % b, a = t; + t = x0, x0 = x1 - q * x0, x1 = t; + } + + if (x1 < 0) { + x1 += b0; + } + + return x1; +} + +static LC3_INT getGeneratorStupid(LC3_INT groupLength) +{ + LC3_INT generator = 2; /* start value */ + LC3_INT count = 1, number = generator; + + while (generator < 100) { /* hopefully the generator is smaller than 100 */ + while (number != 1) { + number = (number * generator) % groupLength; + count++; + } + if (count == groupLength - 1) { + return generator; + } else { + generator++; + count = 1; + number = generator; + } + } + + return -1; +} + +static LC3_INT getGenerator(LC3_INT groupLength) +{ + LC3_INT generator = 2; /* start value */ + LC3_INT count, number, factorCount, found, count2; + LC3_INT factors[16] = {0}; + + /* factorize: only for a group length with factors < 300 */ + factorCount = 0; + number = groupLength - 1; + found = 0; + count = 0; + while (number != 1) { + if (primeFactors[count] == 0) { + /* Not all factors listed */ + return getGeneratorStupid(groupLength); + } + if (number % primeFactors[count] == 0) { + number /= primeFactors[count]; + if (found == 0) { + factors[factorCount++] = primeFactors[count]; + found = 1; + } + } else { + count++; + found = 0; + } + } + + for (count = 0; factors[count] != 0; count++) { + factors[count] = (groupLength - 1) / factors[count]; + } + + /* calculate generator */ + number = generator; + count = 0; + while (factors[count] != 0) { + for (count2 = 0; count2 < factors[count] - 1; count2++) { + number = (number * generator) % groupLength; + } + if (number != 1) { + count++; + number = generator; + if (factors[count] == 0) { + return generator; + } + } else { + count = 0; + generator++; + number = generator; + } + } + + return -1; +} + +static void primeFFT(LC3_FLOAT* restrict x, LC3_INT length, LC3_FLOAT* restrict scratch, LC3_INT* restrict scratch2) +{ + LC3_INT i, k, middle = (length - 1) / 2; + LC3_FLOAT *src1, *src2, *dest1, *dest2; + LC3_INT * mapping, *map; + LC3_INT generator; + + LC3_INT mappingTable[25][97] = { + {0, 2}, + {0, 2, 4}, + {0, 2, 4, 8, 6}, + {0, 2, 6, 4, 12, 8, 10}, + {0, 2, 4, 8, 16, 10, 20, 18, 14, 6, 12}, + {0, 2, 4, 8, 16, 6, 12, 24, 22, 18, 10, 20, 14}, + {0, 2, 6, 18, 20, 26, 10, 30, 22, 32, 28, 16, 14, 8, 24, 4, 12}, + {0, 2, 4, 8, 16, 32, 26, 14, 28, 18, 36, 34, 30, 22, 6, 12, 24, 10, 20}, + {0, 2, 10, 4, 20, 8, 40, 16, 34, 32, 22, 18, 44, 36, 42, 26, 38, 6, 30, 12, 14, 24, 28}, + {0, 2, 4, 8, 16, 32, 6, 12, 24, 48, 38, 18, 36, 14, 28, 56, 54, 50, 42, 26, 52, 46, 34, 10, 20, 40, 22, 44, 30}, + {0, 2, 6, 18, 54, 38, 52, 32, 34, 40, 58, 50, 26, 16, 48, 20, + 60, 56, 44, 8, 24, 10, 30, 28, 22, 4, 12, 36, 46, 14, 42}, + {0, 2, 4, 8, 16, 32, 64, 54, 34, 68, 62, 50, 26, 52, 30, 60, 46, 18, 36, + 72, 70, 66, 58, 42, 10, 20, 40, 6, 12, 24, 48, 22, 44, 14, 28, 56, 38}, + {0, 2, 12, 72, 22, 50, 54, 78, 58, 20, 38, 64, 56, 8, 48, 42, 6, 36, 52, 66, 68, + 80, 70, 10, 60, 32, 28, 4, 24, 62, 44, 18, 26, 74, 34, 40, 76, 46, 30, 16, 14}, + {0, 2, 6, 18, 54, 76, 56, 82, 74, 50, 64, 20, 60, 8, 24, 72, 44, 46, 52, 70, 38, 28, + 84, 80, 68, 32, 10, 30, 4, 12, 36, 22, 66, 26, 78, 62, 14, 42, 40, 34, 16, 48, 58}, + {0, 2, 10, 50, 62, 28, 46, 42, 22, 16, 80, 24, 26, 36, 86, 54, 82, 34, 76, 4, 20, 6, 30, 56, + 92, 84, 44, 32, 66, 48, 52, 72, 78, 14, 70, 68, 58, 8, 40, 12, 60, 18, 90, 74, 88, 64, 38}, + {0, 2, 4, 8, 16, 32, 64, 22, 44, 88, 70, 34, 68, 30, 60, 14, 28, 56, 6, 12, 24, 48, 96, 86, 66, 26, 52, + 104, 102, 98, 90, 74, 42, 84, 62, 18, 36, 72, 38, 76, 46, 92, 78, 50, 100, 94, 82, 58, 10, 20, 40, 80, 54}, + {0, 2, 4, 8, 16, 32, 64, 10, 20, 40, 80, 42, 84, 50, 100, 82, 46, 92, 66, 14, + 28, 56, 112, 106, 94, 70, 22, 44, 88, 58, 116, 114, 110, 102, 86, 54, 108, 98, 78, 38, + 76, 34, 68, 18, 36, 72, 26, 52, 104, 90, 62, 6, 12, 24, 48, 96, 74, 30, 60}, + {0, 2, 4, 8, 16, 32, 64, 6, 12, 24, 48, 96, 70, 18, 36, 72, 22, 44, 88, 54, 108, + 94, 66, 10, 20, 40, 80, 38, 76, 30, 60, 120, 118, 114, 106, 90, 58, 116, 110, 98, 74, 26, + 52, 104, 86, 50, 100, 78, 34, 68, 14, 28, 56, 112, 102, 82, 42, 84, 46, 92, 62}, + {0, 2, 4, 8, 16, 32, 64, 128, 122, 110, 86, 38, 76, 18, 36, 72, 10, 20, 40, 80, 26, 52, 104, + 74, 14, 28, 56, 112, 90, 46, 92, 50, 100, 66, 132, 130, 126, 118, 102, 70, 6, 12, 24, 48, 96, 58, + 116, 98, 62, 124, 114, 94, 54, 108, 82, 30, 60, 120, 106, 78, 22, 44, 88, 42, 84, 34, 68}, + {0, 2, 14, 98, 118, 116, 102, 4, 28, 54, 94, 90, 62, 8, 56, 108, 46, 38, 124, 16, 112, 74, 92, 76, + 106, 32, 82, 6, 42, 10, 70, 64, 22, 12, 84, 20, 140, 128, 44, 24, 26, 40, 138, 114, 88, 48, 52, 80, + 134, 86, 34, 96, 104, 18, 126, 30, 68, 50, 66, 36, 110, 60, 136, 100, 132, 72, 78, 120, 130, 58, 122}, + {0, 2, 10, 50, 104, 82, 118, 6, 30, 4, 20, 100, 62, 18, 90, 12, 60, 8, 40, + 54, 124, 36, 34, 24, 120, 16, 80, 108, 102, 72, 68, 48, 94, 32, 14, 70, 58, 144, + 136, 96, 42, 64, 28, 140, 116, 142, 126, 46, 84, 128, 56, 134, 86, 138, 106, 92, 22, + 110, 112, 122, 26, 130, 66, 38, 44, 74, 78, 98, 52, 114, 132, 76, 88}, + {0, 2, 6, 18, 54, 4, 12, 36, 108, 8, 24, 72, 58, 16, 48, 144, 116, 32, 96, 130, + 74, 64, 34, 102, 148, 128, 68, 46, 138, 98, 136, 92, 118, 38, 114, 26, 78, 76, 70, 52, + 156, 152, 140, 104, 154, 146, 122, 50, 150, 134, 86, 100, 142, 110, 14, 42, 126, 62, 28, 84, + 94, 124, 56, 10, 30, 90, 112, 20, 60, 22, 66, 40, 120, 44, 132, 80, 82, 88, 106}, + {0, 2, 4, 8, 16, 32, 64, 128, 90, 14, 28, 56, 112, 58, 116, 66, 132, 98, 30, 60, 120, + 74, 148, 130, 94, 22, 44, 88, 10, 20, 40, 80, 160, 154, 142, 118, 70, 140, 114, 62, 124, 82, + 164, 162, 158, 150, 134, 102, 38, 76, 152, 138, 110, 54, 108, 50, 100, 34, 68, 136, 106, 46, 92, + 18, 36, 72, 144, 122, 78, 156, 146, 126, 86, 6, 12, 24, 48, 96, 26, 52, 104, 42, 84}, + {0, 2, 6, 18, 54, 162, 130, 34, 102, 128, 28, 84, 74, 44, 132, 40, 120, 4, + 12, 36, 108, 146, 82, 68, 26, 78, 56, 168, 148, 88, 86, 80, 62, 8, 24, 72, + 38, 114, 164, 136, 52, 156, 112, 158, 118, 176, 172, 160, 124, 16, 48, 144, 76, 50, + 150, 94, 104, 134, 46, 138, 58, 174, 166, 142, 70, 32, 96, 110, 152, 100, 122, 10, + 30, 90, 92, 98, 116, 170, 154, 106, 140, 64, 14, 42, 126, 22, 66, 20, 60}, + {0, 2, 10, 50, 56, 86, 42, 16, 80, 12, 60, 106, 142, 128, 58, 96, 92, 72, 166, 54, + 76, 186, 154, 188, 164, 44, 26, 130, 68, 146, 148, 158, 14, 70, 156, 4, 20, 100, 112, 172, + 84, 32, 160, 24, 120, 18, 90, 62, 116, 192, 184, 144, 138, 108, 152, 178, 114, 182, 134, 88, + 52, 66, 136, 98, 102, 122, 28, 140, 118, 8, 40, 6, 30, 150, 168, 64, 126, 48, 46, 36, + 180, 124, 38, 190, 174, 94, 82, 22, 110, 162, 34, 170, 74, 176, 104, 132, 78}}; + + if (length < BORDER_FOR_SECOND_SCRATCH) { + for (i = 1;; i++) { + if (primeFactors[i] == length) { + mapping = mappingTable[i]; + break; + } + assert(primeFactors[i] != 0); + } + } else { + mapping = scratch2; + + /* get primitive root */ + generator = getGenerator(length); + assert(generator != -1); + + /* init mapping */ + mapping[0] = 0; + mapping[1] = 1; + for (i = 2; i < length; i++) { + mapping[i] = mapping[i - 1] * generator; + if (mapping[i] > length - 1) { + mapping[i] = (mapping[i] % length - 1) + 1; + } + } + + /* double mapping value */ + for (i = 1; i < length; i++) { + mapping[i] *= 2; + } + } + + /* remap input to scratch */ + scratch[0] = x[0]; + scratch[1] = x[1]; + scratch[2] = x[2]; + scratch[3] = x[3]; + map = mapping + length - 1; + for (i = 4; i < 2 * length; map--) { + scratch[i++] = x[(*map)]; + scratch[i++] = x[(*map) + 1]; + } + + /* print sums and diffs into scratch by using symmetry */ + x[length] = x[1]; /* imaginary und real part */ + dest1 = x + 1; + dest2 = x + length + 1; + src1 = scratch + 2; + src2 = scratch + length + 1; + + for (i = 2; i < length; i += 2) { + LC3_FLOAT tmp1R, tmp1I, tmp2R, tmp2I; + tmp1R = *src1++; + tmp1I = *src1++; + tmp2R = *src2++; + tmp2I = *src2++; + *dest1++ = tmp1R + tmp2R; + *dest1++ = tmp1R - tmp2R; + *dest2++ = tmp1I + tmp2I; + *dest2++ = tmp1I - tmp2I; + + scratch[0] += tmp1R + tmp2R; + scratch[1] += tmp1I + tmp2I; + } + + /* init with values from the first column */ + dest1 = scratch + 2; + for (i = 1; i < length; i++) { + *dest1++ = x[0]; /* add real part of x(0)(factor = 1) */ + *dest1++ = x[length]; /* add imaginary part of x(0)(factor = 1) */ + } + + for (k = 1; k <= middle; k++) { + /* loop through all cos/sin values */ + LC3_FLOAT sinVal, cosVal; + LC3_INT length1, length2; + LC3_FLOAT rePre, reMre, imPim, imMim; + + cosVal = (LC3_FLOAT)LC3_COS(-M_PIl * mapping[k] / length); + sinVal = (LC3_FLOAT)LC3_SIN(-M_PIl * mapping[k] / length); + + /* compute in two parts (length1, length2) to avoid if() in for loop */ + length1 = middle - k + 1; + length2 = middle - length1; + src1 = x + 1; + src2 = x + length + 1; + dest1 = scratch + 2 * k; + dest2 = scratch + 2 * (middle + k); + + for (i = 0; i < length1; i++) { + rePre = *src1++; + reMre = *src1++; + imPim = *src2++; + imMim = *src2++; + + *dest1++ += cosVal * rePre - sinVal * imMim; + *dest1++ += cosVal * imPim + sinVal * reMre; + + *dest2++ += cosVal * rePre + sinVal * imMim; + *dest2++ += cosVal * imPim - sinVal * reMre; + } + if (dest2 == scratch + 2 * length) { + dest2 = scratch + 2; + } + for (i = 0; i < length2; i++) { + rePre = *src1++; + reMre = *src1++; + imPim = *src2++; + imMim = *src2++; + + *dest1++ += cosVal * rePre - sinVal * imMim; + *dest1++ += cosVal * imPim + sinVal * reMre; + + *dest2++ += cosVal * rePre + sinVal * imMim; + *dest2++ += cosVal * imPim - sinVal * reMre; + } + } + + /* remap output to x */ + x[0] = scratch[0]; + x[1] = scratch[1]; + map = mapping + 1; + for (i = 2; i < 2 * length; map++) { + x[(*map)] = scratch[i++]; + x[(*map) + 1] = scratch[i++]; + } +} + +static void nextFFT(LC3_FLOAT* x, LC3_INT length, LC3_FLOAT* scratch) +{ + if (fft_n(x, length)) /* have function for length */ + return; + + assert(length % 2 != 0); + oddFFT(x, length, scratch); +} + +static inline LC3_INT findFactor(const LC3_INT length) +{ + static const LC3_INT factors[] = {16, 9, 8, 7, 5, 4, 3, 2, 0}; + LC3_INT i = 0, factor = 0; + for (i = 0; factors[i] != 0; i++) { + if (length % factors[i] == 0) { + factor = factors[i]; + break; + } + } + return factor; +} + +static inline void twiddle(LC3_FLOAT* x, const LC3_INT length, const LC3_INT n1, const LC3_INT n2) +{ + LC3_INT i, ii; + FFT_INTERNAL_TRIG_PREC sinValOrg, cosValOrg; + FFT_INTERNAL_TRIG_PREC sinVal = 0, cosVal = 1; + FFT_INTERNAL_TRIG_PREC twReal = 0, twImag = 1; + + cosValOrg = LC3_COS(-2 * (LC3_FLOAT)M_PIl / length); + sinValOrg = LC3_SIN(-2 * (LC3_FLOAT)M_PIl / length); + + for (i = 1; i < n1; i++) { + FFT_INTERNAL_TRIG_PREC tmp = 0.; + twReal = 1; + twImag = 0; + + tmp = cosVal * cosValOrg - sinVal * sinValOrg; + sinVal = sinVal * cosValOrg + cosVal * sinValOrg; + cosVal = tmp; + + for (ii = 1; ii < n2; ii++) { + LC3_FLOAT xRe, xIm; + FFT_INTERNAL_TRIG_PREC tmpReal; + + tmpReal = twReal * cosVal - twImag * sinVal; + twImag = twImag * cosVal + sinVal * twReal; + twReal = tmpReal; + + xRe = x[2 * (i * n2 + ii)]; + xIm = x[2 * (i * n2 + ii) + 1]; + + x[2 * (i * n2 + ii)] = (LC3_FLOAT)twReal * xRe - (LC3_FLOAT)twImag * xIm; + x[2 * (i * n2 + ii) + 1] = (LC3_FLOAT)twImag * xRe + (LC3_FLOAT)twReal * xIm; + } + } +} + +static void cooleyTukeyFFT(LC3_FLOAT* restrict x, const LC3_INT length, LC3_FLOAT* restrict scratch, + LC3_INT* restrict scratch2, LC3_INT isPrime) +{ + LC3_INT factor; + LC3_INT i, ii; + LC3_INT n1, n2; + LC3_INT cnt = 0; + LC3_FLOAT *src, *dest; + + if (fft_n(x, length)) + return; + + factor = findFactor(length); + if (factor > 0 && (length / factor > 1)) { + n1 = factor; + n2 = length / factor; + + /* DATA Resorting for stage1 */ + dest = scratch; + for (i = 0; i < 2 * n1; i += 2) { + src = x + i; + for (ii = 0; ii < n2; ii++) { + /* *dest++ = x[2*(i+ii*n1)]; */ + /* *dest++ = x[2*(i+ii*n1)+1]; */ + *dest++ = *src; + *dest++ = *(src + 1); + src += 2 * n1; + } + } + src = scratch; + dest = x; + for (i = 0; i < length; i++) { + *dest++ = *src++; + *dest++ = *src++; + } + /* perform n1 ffts of length n2 */ + for (i = 0; i < n1; i++) { + cooleyTukeyFFT(x + 2 * i * n2, n2, scratch + 2 * i * n2, scratch2, isPrime); + } + /*data twiddeling */ + twiddle(x, length, n1, n2); + /* DATA Resorting for stage2 */ + cnt = 0; + for (i = 0; i < n2; i++) { + for (ii = 0; ii < n1; ii++) { + scratch[2 * cnt] = x[2 * (i + ii * n2)]; + scratch[2 * cnt + 1] = x[2 * (i + ii * n2) + 1]; + cnt++; + } + } + /* perform n2 ffts of length n1 */ + for (i = 0; i < n2; i++) { + nextFFT(scratch + 2 * i * n1, n1, x + 2 * i * n1); + } + cnt = 0; + for (i = 0; i < n1; i++) { + for (ii = 0; ii < n2; ii++) { + x[2 * cnt] = scratch[2 * (i + ii * n1)]; + x[2 * cnt + 1] = scratch[2 * (i + ii * n1) + 1]; + cnt++; + } + } + } else { + if (isPrime == 1 && length > 23) { + primeFFT(x, length, scratch, scratch2); + } else { + oddFFT(x, length, scratch); + } + } +} + +static void pfaDFT(LC3_FLOAT* restrict x, const LC3_INT length, LC3_FLOAT* restrict scratch1, const LC3_INT numFactors, + const LC3_INT* const factor, LC3_INT* restrict scratch2, const LC3_INT* const isPrime) +{ + LC3_FLOAT* tmp = scratch1; + LC3_INT i, ii, n1, n2, idx, incr, cnt; + LC3_INT n1_inv = 1; + + if (numFactors <= 1) { + cooleyTukeyFFT(x, length, scratch1, scratch2, isPrime[0]); + return; + } + + n2 = factor[0]; + n1 = length / n2; + + n1_inv = findInverse(n1, n2); + + idx = 0; + incr = n1 * n1_inv; + cnt = 0; + for (i = 0; i < n1; i++) { + for (ii = 0; ii < n2 - 1; ii++) { + tmp[cnt++] = x[2 * idx]; + tmp[cnt++] = x[2 * idx + 1]; + + idx += incr; + if (idx > length) { + idx -= length; + } + } + tmp[cnt++] = x[2 * idx]; + tmp[cnt++] = x[2 * idx + 1]; + idx++; + } + + for (cnt = 0; cnt < length; cnt += n2) { + cooleyTukeyFFT(tmp + 2 * cnt, n2, x + 2 * cnt, scratch2, isPrime[0]); + } + for (cnt = 0; cnt < n1; cnt++) { + for (i = 0; i < n2; i++) { + x[2 * (cnt + i * n1)] = tmp[2 * (cnt * n2 + i)]; + x[2 * (cnt + i * n1) + 1] = tmp[2 * (cnt * n2 + i) + 1]; + } + } + for (cnt = 0; cnt < length; cnt += n1) { + pfaDFT(x + 2 * cnt, n1, tmp, numFactors - 1, &factor[1], scratch2, &isPrime[1]); + } + + cnt = 0; + for (i = 0; i < n2; i++) { + idx = i * n1; + for (ii = 0; ii < n1; ii++) { + tmp[2 * idx] = x[cnt++]; + tmp[2 * idx + 1] = x[cnt++]; + idx += n2; + if (idx > length) { + idx -= length; + } + } + } + + for (cnt = 0; cnt < length; cnt++) { + x[2 * cnt] = tmp[2 * cnt]; + x[2 * cnt + 1] = tmp[2 * cnt + 1]; + } +} diff --git a/lc3plus/fft/iis_fft.c b/lc3plus/fft/iis_fft.c new file mode 100644 index 0000000000000000000000000000000000000000..b1f8ab5ab8d42629700fa31642587bb93f4900e5 --- /dev/null +++ b/lc3plus/fft/iis_fft.c @@ -0,0 +1,164 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include +#include +#include +#include +#include +#include + +#include "iis_fft.h" +/**************************************************************************************************/ + +/* AFFT uses two fft implementations + * cfft is used for lengths of power of two, >= 256. + * iisfft is used for everything else. it is optimized for certain lengths. for a list of + fast lengths, check the fft_n function. +*/ + + +#define FFT_COMPLEX 1 +#define FFT_REAL 2 + + +static IIS_FFT_ERROR create(HANDLE_IIS_FFT* handle, LC3_INT type, LC3_INT len, IIS_FFT_DIR sign) +{ + IIS_FFT_ERROR err = IIS_FFT_MEMORY_ERROR; + + /* for real transforms the actual performed fft is half length */ + LC3_INT trlen = (type == FFT_COMPLEX) ? len : len / 2; + + /* check argument sanity */ + if (sign != IIS_FFT_FWD && sign != IIS_FFT_BWD) + return IIS_FFT_INTERNAL_ERROR; + + + if (!(*handle)) + (*handle) = (HANDLE_IIS_FFT)calloc(1, sizeof(IIS_FFT)); + if (!(*handle)) + return IIS_FFT_MEMORY_ERROR; + + (*handle)->len = len; + (*handle)->sign = sign; + + /* create sine lookup table for real ffts */ + if (type == FFT_REAL) + { + LC3_create_sine_table(len, (*handle)->sine_table); + if (!(*handle)->sine_table) + { + goto handle_error1; + } + } + + /* set default cfft_plan to 0(length). (and default iisfft_plan to zero length) */ + (*handle)->cfft.len = 0; /* 0 length means that cfft should not be called */ + (*handle)->iisfft.length = 0; /*saftey setting for iisfft length struct */ + + /* use cfft for legth of power two larger than 256. for length below iisfft is faster */ + if (trlen >= 256 && CFFT_PLAN_SUPPORT(trlen)) { + LC3_INT s = (type == FFT_REAL) ? IIS_FFT_FWD : sign; + err = LC3_cfft_plan(&(*handle)->cfft, trlen, s) ? IIS_FFT_NO_ERROR : IIS_FFT_INTERNAL_ERROR; + } else { + LC3_INT s = (type == FFT_REAL) ? IIS_FFT_FWD : sign; + err = LC3_iisfft_plan(&(*handle)->iisfft, trlen, s); + } + + return IIS_FFT_NO_ERROR; + +handle_error1: + free((*handle)); + + return err; +} + +IIS_FFT_ERROR LC3_IIS_RFFT_Create(HANDLE_IIS_FFT* handle, LC3_INT32 len, IIS_FFT_DIR sign) +{ + return create(handle, FFT_REAL, len, sign); +} + +static IIS_FFT_ERROR destroy(HANDLE_IIS_FFT* handle) +{ + if (handle && *handle) { + LC3_iisfft_free(&(*handle)->iisfft); + LC3_cfft_free(&(*handle)->cfft); + free(*handle); + *handle = NULL; + } + return IIS_FFT_NO_ERROR; +} + +IIS_FFT_ERROR LC3_IIS_CFFT_Create(HANDLE_IIS_FFT* handle, LC3_INT len, IIS_FFT_DIR sign) +{ + return create(handle, FFT_COMPLEX, len, sign); +} + + +IIS_FFT_ERROR LC3_IIS_xFFT_Destroy(HANDLE_IIS_FFT* handle) { return destroy(handle); } + +IIS_FFT_ERROR LC3_IIS_CFFT_Destroy(HANDLE_IIS_FFT* handle) { return destroy(handle); } + +static IIS_FFT_ERROR real_destroy(HANDLE_IIS_FFT* handle) +{ + if (handle && *handle) { + LC3_iisfft_free(&(*handle)->iisfft); + *handle = NULL; + } + return IIS_FFT_NO_ERROR; +} + +IIS_FFT_ERROR LC3_IIS_RFFT_Destroy(HANDLE_IIS_FFT* handle) { return real_destroy(handle); } + +IIS_FFT_ERROR LC3_IIS_FFT_Apply_CFFT(HANDLE_IIS_FFT handle, const Complex* input, Complex* output) +{ + LC3_FLOAT* dummy; + if (!handle) + return IIS_FFT_INTERNAL_ERROR; + + /* check for inplace operation */ + memmove(output, input, sizeof(*input) * handle->len); + dummy = (LC3_FLOAT*)output; + if (handle->cfft.len > 0) { + LC3_cfft_apply(&handle->cfft, dummy, dummy + 1, 2); + } else { + LC3_iisfft_apply(&handle->iisfft, dummy); + } + + return IIS_FFT_NO_ERROR; +} + + +IIS_FFT_ERROR LC3_IIS_FFT_Apply_RFFT(HANDLE_IIS_FFT handle, const LC3_FLOAT* in, LC3_FLOAT* out) +{ + if (!handle) { + return IIS_FFT_INTERNAL_ERROR; + } + + memmove(out, in, sizeof(LC3_FLOAT) * handle->len); + + if (handle->sign == IIS_FFT_BWD) { + LC3_rfft_pre(handle->sine_table, out, handle->len); + } + + if (handle->cfft.len > 0) { + LC3_cfft_apply(&handle->cfft, out, out + 1, 2); + } + else { + LC3_iisfft_apply(&handle->iisfft, out); + } + + if (handle->sign == IIS_FFT_FWD) { + LC3_rfft_post(handle->sine_table, out, handle->len); + } + + return IIS_FFT_NO_ERROR; +} diff --git a/lc3plus/fft/iis_fft.h b/lc3plus/fft/iis_fft.h new file mode 100644 index 0000000000000000000000000000000000000000..b658930fa7cf51fae7861d9a1dca2c46671e7fdb --- /dev/null +++ b/lc3plus/fft/iis_fft.h @@ -0,0 +1,142 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#ifndef IIS_FFT_H +#define IIS_FFT_H + +#include "../structs.h" +#include "../defines.h" +#include "cfft.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! + * \brief n-point complex FFT + * + * There are optimized FFTs for lengths 2, 3, 4, 7, 8, 9, 15, 16, 32, 60, 64, 128, + * 240, 256, 384, 480, 512, 768, 1024. Other lengths below 1024 use a stack allocated + * buffer and offer reasonable speed. Above 1024 a buffer is allocated each time + * iis_fftf() is called resulting in reduced performance. + * + * >>>>>> DO NOT USE UNOPTIMIZED LENGTHS IN PRODUCTION CODE! <<<<<< + * + * \param[in,out] vec pointer to data, interleaved real / imaginary + * \param[in] length length of fft (number of real/imaginary pairs) + * + * \return IIS_FFT_NO_ERROR on success + */ +IIS_FFT_ERROR LC3_iis_fftf(LC3_FLOAT* vec, LC3_INT length); +/*! + * \brief n-point inverse complex FFT + * + * The output is not normalized. See iis_fftf() for optimized lengths. + * + * >>>>>> DO NOT USE UNOPTIMIZED LENGTHS IN PRODUCTION CODE! <<<<<< + * + * \param[in,out] vec pointer to data, interleaved real / imaginary + * \param[in] length length of fft (number of real/imaginary pairs) + * + * \return IIS_FFT_NO_ERROR on success + */ +IIS_FFT_ERROR LC3_iis_ifftf(LC3_FLOAT* vec, LC3_INT length); + +/*! + * \brief allocate and initialize a new real FFT instance. + * + * \param[in,out] handle pointer to FFT handle + * \param[in] len transform length, must be an even number + * \param[in] sign IIS_FFT_FWD(-1) for forward, IIS_FFT_BWD(1) for backward transform + * BEWARE OF THE SIGNS! + * + * \return IIS_FFT_NO_ERROR on success + */ +IIS_FFT_ERROR LC3_IIS_RFFT_Create(HANDLE_IIS_FFT* handle, LC3_INT len, IIS_FFT_DIR sign); + +/*! + * \brief allocate and initialize a new complex FFT instance + * + * \param[in,out] handle pointer to FFT handle + * \param[in] len transform length + * \param[in] sign IIS_FFT_FWD(-1) for forward, IIS_FFT_BWD(1) for backward transform + * BEWARE OF THE SIGNS !!!!!! + * + * \return IIS_FFT_NO_ERROR on success + */ +IIS_FFT_ERROR LC3_IIS_CFFT_Create(HANDLE_IIS_FFT* handle, LC3_INT len, IIS_FFT_DIR sign); + +/*! + * \brief computes the forward or backward fourier transform of a real signal + * + * For complex data (in or out) the real part of the Nyquist band (len / 2 + 1) is stored + * in the imaginary part of the DC band (0). This allows for the complex data of + * real to complex transforms to fit into the same buffer. For this to work length must be even. + * + * Complex to real transforms are normalized (1.0/len). Input and ouput buffers may + *be identical. + * + * \param[in] handle FFT handle + * \param[in] in pointer to the input array containing real values for the forward transform (FFT) + * or packed complex values (Perm) for the backward transform (IFFT) + * \param[out] out pointer to the output array containing real values resulted from the backward transform + * (IFFT) or packed complex (perm) values reulted from the forward transform + * + * \return IIS_FFT_NO_ERROR on success + */ +IIS_FFT_ERROR LC3_IIS_FFT_Apply_RFFT(HANDLE_IIS_FFT handle, const LC3_FLOAT* in, LC3_FLOAT* out); + +/*! + * \brief compute complex backward or forward FFT + * + * Input and ouput buffers may be identical. Real/imaginary parts may be interleaved. + * The output is not normalized. + * + * \param[in] handle FFT handle + * \param[in] in_re pointer to the input array containing real parts of the signal for the + * forward transform (FFT) or for the backward transform (IFFT) + * \param[in] in_im pointer to the input array containing imaginary parts of the signal for + * the forward transform (FFT) or for the backward transform (IFFT) + * \param[out] out_re pointer to the output array containing real values resulted from the + * forward transform (FFT) or from the backward transform (IFFT) + * \param[out] out_im pointer to the output array containing imaginary values resulted from + * the forward transform (FFT) or from the backward transform (IFFT) + * + * \return IIS_FFT_NO_ERROR on success + */ +IIS_FFT_ERROR LC3_IIS_FFT_Apply_CFFT(HANDLE_IIS_FFT handle, const Complex* input, Complex* output); + +/*! + * \brief deallocate a FFT instance (complex or real) + * \param[in,out] handle pointer to FFT handle, set to NULL if call succeeds + * \return IIS_FFT_NO_ERROR on success + */ +IIS_FFT_ERROR LC3_IIS_xFFT_Destroy(HANDLE_IIS_FFT* handle); + +/*! + * \brief deallocate a real FFT instance + * \param[in,out] handle pointer to FFT handle, set to NULL if call succeeds + * \return IIS_FFT_NO_ERROR on success + */ +IIS_FFT_ERROR LC3_IIS_RFFT_Destroy(HANDLE_IIS_FFT* handle); + +/*! + * \brief deallocate a complex FFT instance + * \param[in,out] handle pointer to FFT handle, set to NULL if call succeeds + * \return IIS_FFT_NO_ERROR on success + */ +IIS_FFT_ERROR LC3_IIS_CFFT_Destroy(HANDLE_IIS_FFT* handle); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lc3plus/fft/iisfft.c b/lc3plus/fft/iisfft.c new file mode 100644 index 0000000000000000000000000000000000000000..227d2b6037c8fef97141631b512e6736987603b9 --- /dev/null +++ b/lc3plus/fft/iisfft.c @@ -0,0 +1,166 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" + +#include +#include /* for mmove */ +#include +#include +#include "iisfft.h" +#include "cfft.h" + +/* the fixed length fft functions have been split into sevelral headers to + have smaller files. to give the compiler more room to optimize the ffts + can't be in separate compilation units. the header approach seemed to be + the best compromise. to prevent them being included from anywhere else, + they are guarded by the INCLUDED_FROM_IISFFT_C macro. +*/ +#define INCLUDED_FROM_IISFFT_C +#include "fft_2_9.h" +#include "fft_15_16.h" +#include "fft_32.h" +#include "fft_60_128.h" +#include "fft_240_480.h" +#include "fft_384_768.h" +#include "fft_generic.h" + + +void LC3_iisfft_apply(Iisfft* handle, LC3_FLOAT* x) +{ + if (handle->sign == -1) { + if (!fft_n(x, handle->length)) + { + LC3_FLOAT scratch[2*MAX_LEN]; + pfaDFT(x, handle->length, scratch, handle->num_factors, handle->factors, handle->scratch2, + handle->isPrime); + } + } else { + assert(0); + } +} + +/* returns 1 if there is no specialized function for length or 1 if a scratch needs to be allocated. + check the fft_n function */ +static LC3_INT need_scratch(LC3_INT n) +{ + return n != 2 && n != 3 && n != 4 && n != 5 && n != 7 && n != 8 && n != 9 && n != 15 && n != 16 && n != 32 && + n != 60 && n != 64 && n != 128 && n != 192 && n != 240 && n != 256 && n != 384 && n != 480 && n != 512 && n != 768 && + n != 1024; +} + +IIS_FFT_ERROR LC3_iisfft_plan(Iisfft* handle, LC3_INT length, LC3_INT sign) +{ + memset(handle, 0, sizeof(Iisfft)); + if (length < 2) + return IIS_FFT_LENGTH_ERROR; + handle->length = length; + handle->sign = sign; + if (need_scratch(length)) { + /* only needed for prime numbers bigger than BORDER_FOR_SECOND_SCRATCH */ + LC3_INT i = 0; + LC3_INT lengthOfPrimeScratch = BORDER_FOR_SECOND_SCRATCH; + if (!factorize(length, &handle->num_factors, handle->factors, handle->isPrime)) + return IIS_FFT_LENGTH_ERROR; + /* create additional scratch for primeFFT() */ + for (i = 0; i < handle->num_factors; i++) { + if (handle->isPrime[i] == 1 && handle->factors[i] > lengthOfPrimeScratch) { + lengthOfPrimeScratch = handle->factors[i]; + } + } + if (lengthOfPrimeScratch > BORDER_FOR_SECOND_SCRATCH) { + handle->scratch2 = (LC3_INT*)malloc(sizeof(LC3_INT) * lengthOfPrimeScratch); + if (!handle->scratch2) + return IIS_FFT_MEMORY_ERROR; + } + } + + return IIS_FFT_NO_ERROR; +} + +void LC3_iisfft_free(Iisfft* handle) +{ + handle->length = 0; + if (handle->scratch2) + free(handle->scratch2); +} + + + +/* generate sine table needed by LC3_rfft_pre/rfft/post. the table must be freed with iisFree */ +void LC3_create_sine_table(LC3_INT32 len, LC3_FLOAT *sine_table) +{ + LC3_INT32 i; + + for (i = 0; i < len / 2 + 1; i++) { + sine_table[i] = (LC3_FLOAT)sin(2.0 * M_PIl * i / len); + } +} + +void LC3_rfft_post(const LC3_FLOAT* restrict sine_table, LC3_FLOAT* restrict buf, LC3_INT32 len) +{ + LC3_FLOAT tmp1, tmp2, tmp3, tmp4, s, c; + LC3_INT32 i; + + tmp1 = buf[0] + buf[1]; + buf[1] = buf[0] - buf[1]; + buf[0] = tmp1; + + for (i = 1; i <= (len + 2) / 4; i++) { + s = sine_table[i]; /* sin(pi*i/(len/2)) */ + c = sine_table[i + len / 4]; /* cos(pi*i/(len/2)) */ + + tmp1 = buf[2 * i] - buf[len - 2 * i]; + tmp2 = buf[2 * i + 1] + buf[len - 2 * i + 1]; + tmp3 = s * tmp1 - c * tmp2; /* real part of j*W(k,N)*[T(k) - T'(N-k)] */ + tmp4 = c * tmp1 + s * tmp2; /* imag part of j*W(k,N)*[T(k) - T'(N-k)] */ + tmp1 = buf[2 * i] + buf[len - 2 * i]; + tmp2 = buf[2 * i + 1] - buf[len - 2 * i + 1]; + + buf[2 * i] = 0.5f * (tmp1 - tmp3); + buf[2 * i + 1] = 0.5f * (tmp2 - tmp4); + buf[len - 2 * i] = 0.5f * (tmp1 + tmp3); + buf[len - 2 * i + 1] = -0.5f * (tmp2 + tmp4); + } + + return; +} + +void LC3_rfft_pre(const LC3_FLOAT* restrict sine_table, LC3_FLOAT* restrict buf, LC3_INT32 len) +{ + LC3_FLOAT scale ; + LC3_FLOAT tmp1, tmp2, tmp3, tmp4, s, c; + LC3_INT32 i; + + scale = 1.0f / len; /* constant */ + + tmp1 = buf[0] + buf[1]; + buf[1] = scale * (buf[0] - buf[1]); + buf[0] = scale * tmp1; + + for (i = 1; i <= (len + 2) / 4; i++) { + s = sine_table[i]; /* sin(pi*i/(len/2)) */ + c = sine_table[i + len / 4]; /* cos(pi*i/(len/2)) */ + + tmp1 = buf[2 * i] - buf[len - 2 * i]; + tmp2 = buf[2 * i + 1] + buf[len - 2 * i + 1]; + tmp3 = s * tmp1 + c * tmp2; /* real part of j*W(k,N)*[T(k) - T'(N-k)] */ + tmp4 = -c * tmp1 + s * tmp2; /* imag part of j*W(k,N)*[T(k) - T'(N-k)] */ + tmp1 = buf[2 * i] + buf[len - 2 * i]; + tmp2 = buf[2 * i + 1] - buf[len - 2 * i + 1]; + + buf[2 * i] = scale * (tmp1 + tmp3); + buf[2 * i + 1] = -scale * (tmp2 + tmp4); + buf[len - 2 * i] = scale * (tmp1 - tmp3); + buf[len - 2 * i + 1] = scale * (tmp2 - tmp4); + } + return; +} + diff --git a/lc3plus/fft/iisfft.h b/lc3plus/fft/iisfft.h new file mode 100644 index 0000000000000000000000000000000000000000..7b448e2bbeca4f093791f039e885c42c94688af2 --- /dev/null +++ b/lc3plus/fft/iisfft.h @@ -0,0 +1,86 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#ifndef IISFFT_H +#define IISFFT_H + +#include "../defines.h" + +#ifndef M_PIl +#define M_PIl 3.1415926535897932384626433832795029L /* pi */ +#endif + +/* compiler specific macros + + the restrict keyword only gives a improvelent if more than one pointers are + passed to a function. also note that the MSVC __restrict behaves differently + from c99, the restrict property is not transferred to aliases. + + alloca is a bit problematic because behavior is not defined in case of stack + overflow. most probably the program will crash. it might be possible to catch + those errors but it depends on compiler support. msvc has a safer _malloca + but gcc has nothing similar. */ +#if defined _MSC_VER || defined __INTEL_COMPILER +#include +#define ALLOCA(size) _alloca(size) +#define restrict __restrict +#define inline __inline +#elif defined __GNUC__ || defined __clang__ +#define ALLOCA(size) __builtin_alloca(size) +#define restrict __restrict__ +#define inline __inline +#elif defined __TI_COMPILER_VERSION__ +#include +#define ALLOCA(size) (assert(0 && "ALLOCA is not present for your compiler"), NULL) +#warn "no stack allocation for you compiler" +#else +#error "no stack allocation for your compiler" +#endif + + +#define IISFFT_MAXSTACKLENGTH 1024 +#define IISFFT_MAXFACTORS 10 + +typedef struct { + LC3_INT* scratch2; + LC3_INT length; + LC3_INT sign; + LC3_INT num_factors; + LC3_INT factors[IISFFT_MAXFACTORS]; + LC3_INT isPrime[IISFFT_MAXFACTORS]; +} Iisfft; + +typedef enum { + IIS_FFT_NO_ERROR = 0, + IIS_FFT_INTERNAL_ERROR, /**< a mystical error appeard */ + IIS_FFT_LENGTH_ERROR, /**< the requested fft length is not supported */ + IIS_FFT_MEMORY_ERROR /**< memory allocation failed */ +} IIS_FFT_ERROR; + +typedef enum { + IIS_FFT_FWD = -1, /**< forward transform */ + IIS_FFT_BWD = 1 /**< inverse / backward transform */ +} IIS_FFT_DIR; + +/* plan, apply and free forward / backward fft */ +IIS_FFT_ERROR LC3_iisfft_plan(Iisfft* handle, LC3_INT length, LC3_INT sign); +void LC3_iisfft_apply(Iisfft* handle, LC3_FLOAT* x); +void LC3_iisfft_free(Iisfft* handle); + +/* fft related helper functions */ +void LC3_create_sine_table(LC3_INT32 len, LC3_FLOAT *sine_table); + +void LC3_rfft_pre(const LC3_FLOAT* restrict sine_table, LC3_FLOAT* restrict buf, LC3_INT len); +void LC3_rfft_post(const LC3_FLOAT* restrict sine_table, LC3_FLOAT* restrict buf, LC3_INT len); +void LC3_fftf_interleave(const LC3_FLOAT* restrict re, const LC3_FLOAT* restrict im, LC3_FLOAT* restrict out, + LC3_INT len); +void LC3_fftf_deinterleave(const LC3_FLOAT* restrict in, LC3_FLOAT* restrict re, LC3_FLOAT* restrict im, LC3_INT len); + +#endif /* IISFFT_H */ diff --git a/lc3plus/functions.h b/lc3plus/functions.h new file mode 100644 index 0000000000000000000000000000000000000000..7a529a25d7acbe5e90b00b6d72f5199fa2f0ae47 --- /dev/null +++ b/lc3plus/functions.h @@ -0,0 +1,304 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#ifndef FUNCTIONS_H +#define FUNCTIONS_H + +#include "clib.h" +#include "defines.h" +#include "float.h" +#include "lc3.h" +#include "setup_dec_lc3.h" +#include "setup_enc_lc3.h" +#include "structs.h" +#include "util.h" + +/* FFT */ +#include "fft/iisfft.h" + +/* fft.c */ +void real_fft_init(Fft* fft, LC3_INT32 length, HANDLE_IIS_FFT *handle); +void real_ifft_init(Fft* fft, LC3_INT32 length, HANDLE_IIS_FFT *handle); +void real_fft_apply(Fft* fft, const LC3_FLOAT* in, LC3_FLOAT* out); + +void fft_init(Fft* fft, LC3_INT length); +void fft_free(Fft* fft); +void real_fft_free(Fft* fft); +void fft_apply(Fft* fft, const Complex* input, Complex* output); + +/* dct.c */ +void dct2_init(Dct2* dct, LC3_INT length); +void dct2_free(Dct2* dct); +void dct2_apply(Dct2* dct, const LC3_FLOAT* input, LC3_FLOAT* output); + +void dct3_init(Dct3* dct, LC3_INT length); +void dct3_free(Dct3* dct); +void dct3_apply(Dct3* dct, const LC3_FLOAT* input, LC3_FLOAT* output); + +void dct4_init(Dct4* dct, LC3_INT length); +void dct4_free(Dct4* dct); +void dct4_apply(Dct4* dct, const LC3_FLOAT* input, LC3_FLOAT* output); + +/* mdct.c */ +void mdct_init(Mdct* mdct, LC3_INT length, LC3_INT frame_dms, LC3_INT fs_idx, LC3_INT hrmode); +void mdct_free(Mdct* mdct); +void mdct_apply(const LC3_FLOAT* input, LC3_FLOAT* output, Mdct* mdct); + +#ifdef ENABLE_PADDING +LC3_INT paddingDec_fl(LC3_UINT8* bytes, LC3_INT nbbits, LC3_INT L_spec, LC3_INT bw_cutoff_bits, LC3_INT ep_enabled, LC3_INT* total_padding, LC3_INT *np_zero); +#endif + +void processEncoderEntropy_fl(LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT numbytes, LC3_INT bw_cutoff_bits, + LC3_INT bw_cutoff_idx, LC3_INT lastnz, LC3_INT N, LC3_INT lsbMode, LC3_INT gg_idx, LC3_INT num_tns_filters, + LC3_INT* tns_order, LC3_INT* ltpf_idx, LC3_INT* scf_idx, LC3_INT fac_ns_idx + , LC3_INT bfi_ext, LC3_INT fs_idx + ); +void processDecoderEntropy_fl(LC3_UINT8* bytes, LC3_INT numbytes, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT N, LC3_INT fs_idx, + LC3_INT bw_cutoff_bits, LC3_INT* bfi, LC3_INT* gg_idx, LC3_INT* scf_idx, LC3_INT* fac_ns_idx, + LC3_INT* tns_numfilters, LC3_INT* tns_order, LC3_INT* ltpf_idx, LC3_INT* bw_cutoff_idx, LC3_INT* lastnz, + LC3_INT* lsbMode, LC3_INT frame_dms + ); +void processQuantizeSpec_fl(LC3_FLOAT x[], LC3_FLOAT gain, LC3_INT xq[], LC3_INT nt, LC3_INT totalBits, LC3_INT* nbits, LC3_INT* nbits2, LC3_INT fs, + LC3_INT* lastnzout, LC3_INT* codingdata, LC3_INT* lsbMode, LC3_INT mode, LC3_INT target, LC3_INT hrmode); + +void processEstimateGlobalGain_fl(LC3_FLOAT x[], LC3_INT lg, LC3_INT nbitsSQ, LC3_FLOAT* gain, LC3_INT* quantizedGain, + LC3_INT* quantizedGainMin, LC3_INT quantizedGainOff, LC3_FLOAT* targetBitsOff, + LC3_INT* old_targetBits, LC3_INT old_specBits, LC3_INT bq_mode + , LC3_INT regBits, LC3_FLOAT frame_ms +); + +void processAriDecoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, LC3_INT L_spec, LC3_INT fs_idx, LC3_INT enable_lpc_weighting, + LC3_INT tns_numfilters, LC3_INT lsbMode, LC3_INT lastnz, LC3_INT* bfi, LC3_INT* tns_order, LC3_INT fac_ns_idx, + LC3_INT gg_idx, uint8_t* resBits, LC3_INT* x, LC3_INT* nf_seed, LC3_INT* tns_idx, LC3_INT* zero_frame, LC3_INT numbytes, + LC3_INT* nbits_residual, LC3_INT* residualPresent, LC3_INT frame_dms, + LC3_INT32 n_pc, LC3_INT32 be_bp_left, LC3_INT32 be_bp_right, LC3_INT32 enc, LC3_INT32 *b_left, LC3_INT32 *spec_inv_idx, + LC3_INT hrmode + ); + +void processMdctShaping_fl(LC3_FLOAT x[], LC3_FLOAT gains[], const LC3_INT bands_offset[], LC3_INT fdns_npts); + +void processResidualCoding_fl(LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gain, LC3_INT L_spec, LC3_INT targetBits, LC3_INT nBits, uint8_t * resBits, + LC3_INT* numResBits + , LC3_INT hrmode +); + +void processResidualDecoding_fl(LC3_INT* bitsRead, LC3_FLOAT x[], LC3_INT L_spec, uint8_t prm[], LC3_INT resQBits + , LC3_INT hrmode +); + +void processAdjustGlobalGain_fl(LC3_INT* gg_idx, LC3_INT gg_idx_min, LC3_INT gg_idx_off, LC3_FLOAT* gain, LC3_INT target, LC3_INT nBits, + LC3_INT* gainChange, LC3_INT fs_idx + , LC3_INT16 hrmode, LC3_INT16 frame_dms + ); + +void processApplyGlobalGain_fl(LC3_FLOAT x[], LC3_INT xLen, LC3_INT global_gain_idx, LC3_INT global_gain_off); + +void processNoiseFactor_fl(LC3_INT* fac_ns_idx, LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gg, LC3_INT BW_cutoff_idx, LC3_INT frame_dms, + LC3_INT target_bytes + ); + +void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, LC3_INT bw_stopband, LC3_INT frame_dms, LC3_FLOAT fac_ns_pc, LC3_INT spec_inv_idx); + +void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4, LC3_INT* mem_old_T0, LC3_INT* T0_out, + LC3_FLOAT* normcorr_out, LC3_INT len, LC3_INT frame_dms); + +void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, LC3_INT fs, LC3_INT N, LC3_INT frame_dms, LC3_INT nBits, + LC3_INT* order_out, LC3_INT* rc_idx, LC3_INT* tns_numfilters, LC3_INT* bits_out + , LC3_INT16 near_nyquist_flag + ); +void levinsonDurbin(LC3_FLOAT* r, LC3_FLOAT* out_lev, LC3_FLOAT* rc_unq, LC3_FLOAT* error, LC3_INT len); + +void processTnsDecoder_fl(LC3_FLOAT* x, LC3_INT* rc_idx, LC3_INT* order, LC3_INT numfilters, LC3_INT bw_fcbin, LC3_INT N, LC3_INT fs); + +void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor); + +void processSnsInterpolateScf_fl(LC3_FLOAT* gains, LC3_INT encoder_side, LC3_INT bands_number, LC3_FLOAT* gains_LC3_INT); + +void processDetectCutoffWarped_fl(LC3_FLOAT* d2, LC3_INT fs_idx, LC3_INT frame_dms, LC3_INT* bw_idx); +void processNearNyquistdetector_fl(LC3_INT16* near_nyquist_flag, const LC3_INT fs_idx, const LC3_INT near_nyquist_index, + const LC3_INT bands_number, const LC3_FLOAT* ener); + +void processPerBandEnergy_fl(LC3_INT bands_number, const LC3_INT* acc_coeff_per_band, LC3_INT16 hrmode, LC3_INT16 frame_dms, LC3_FLOAT* d2, LC3_FLOAT* d); + +void ProcessingIMDCT_fl(LC3_FLOAT* y, LC3_INT yLen, const LC3_FLOAT* win, LC3_INT winLen, LC3_INT last_zeros, LC3_FLOAT* mem, LC3_FLOAT* x, + Dct4* dct); + +void ProcessingITDA_WIN_OLA_fl(LC3_FLOAT* x_tda, LC3_INT32 yLen, const LC3_FLOAT* win, LC3_INT32 winLen, LC3_INT32 last_zeros, LC3_FLOAT* mem, LC3_FLOAT* x); + +void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC3_INT pitch_ol, LC3_FLOAT pitch_ol_norm_corr, LC3_INT frame_dms, + LC3_FLOAT* mem_old_x, LC3_INT memLen, LC3_FLOAT* mem_norm_corr_past, LC3_INT* mem_on, LC3_FLOAT* mem_pitch, + LC3_INT* param, LC3_FLOAT* mem_norm_corr_past_past, LC3_INT* bits); + +void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT fs, LC3_FLOAT* mem_old_x, LC3_FLOAT* mem_old_y, + LC3_INT* mem_pitch_LC3_INT, LC3_INT* mem_pitch_fr, LC3_FLOAT* mem_gain, LC3_INT* mem_beta_idx, LC3_INT bfi, + LC3_INT* param, LC3_INT* mem_param, LC3_INT conf_beta_idx, LC3_FLOAT conf_beta, LC3_INT concealMethod, LC3_FLOAT damping + , LC3_INT *mem_ltpf_active +); + +void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3_INT mem_in_len, LC3_FLOAT mem_50[], LC3_FLOAT mem_out[], + LC3_INT mem_out_len, LC3_FLOAT y[], LC3_INT* y_len, LC3_INT fs_idx, LC3_INT frame_dms, LC3_INT fs); + +void write_bit_backward_fl(LC3_UINT8* ptr, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT bit); +void write_uint_backward_fl(LC3_UINT8* ptr, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT val, LC3_INT numbits); + +void processAriEncoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, LC3_INT* x, LC3_INT* tns_order, LC3_INT tns_numfilters, + LC3_INT* tns_idx, LC3_INT lastnz, + LC3_INT* codingdata, uint8_t* res_bits, LC3_INT resBitsLen, LC3_INT lsbMode, + LC3_INT nbbits, LC3_INT enable_lpc_weighting); + +void attack_detector_fl(LC3_FLOAT* in, LC3_INT frame_size, LC3_INT fs, LC3_INT* lastAttackPosition, LC3_FLOAT* accNrg, LC3_INT* attackFlag, + LC3_FLOAT* attdec_filter_mem, LC3_INT attackHandlingOn, LC3_INT attdec_nblocks, LC3_INT attdec_hangover_threshold); + +void process_snsQuantizesScf_Enc(LC3_FLOAT* env, LC3_INT* index, LC3_FLOAT* envq, Dct2 dct2structSNS); + +void process_snsQuantizesScf_Dec(LC3_INT* scf_idx, LC3_FLOAT* scf_q); + +void processMdct_fl(LC3_FLOAT* in, LC3_FLOAT* out, Mdct* mdctStruct); + +int alloc_encoder(LC3PLUS_Enc* encoder, int channels); +void set_enc_frame_params(LC3PLUS_Enc* encoder); +LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate); + +LC3PLUS_Error FillEncSetup(LC3PLUS_Enc* encoder, int samplerate, int channels, int hrmode, int32_t lfe_channel_array[]); + +/* Setup Functions */ +int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels); +void set_dec_frame_params(LC3PLUS_Dec* decoder); +LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes); + +LC3PLUS_Error FillDecSetup(LC3PLUS_Dec* decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode, int hrmode); + +int Enc_LC3PLUS_fl(LC3PLUS_Enc* encoder, void** input, LC3_UINT8* output, int bps +, LC3_INT32 bfi_ext +); +LC3PLUS_Error Dec_LC3PLUS_fl(LC3PLUS_Dec* decoder, LC3_UINT8* input, int input_bytes, void** output, int bps, int bfi_ext); + +void* balloc(void* base, size_t* base_size, size_t size); + +void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* decoder, DecSetup* h_DecSetup, LC3_INT bfi, + PlcAdvSetup *PlcAdvSetup, PlcSetup *PlcSetup, LC3_INT plcMeth, LC3_INT ltpf_pitch_int, LC3_INT ltpf_pitch_fr, + LC3_INT tilt, const LC3_INT *bands_offset, LC3_INT bands_number, const LC3_INT *bands_offsetPLC, + LC3_INT n_bandsPLC, LC3_INT16 hrmode, pcState *statePC); + +void processPlcUpdate_fl(PlcAdvSetup *PlcAdvSetup, LC3_INT32 frame_length, LC3_FLOAT *syntM, LC3_FLOAT *scf_q, + LC3_INT32 *nbLostCmpt, LC3_FLOAT *cum_alpha, LC3_INT32 bfi, LC3_INT32 *prevBfi, LC3_INT32 *prevprevBfi); + +void processPlcUpdateSpec_fl(LC3_FLOAT *q_d_prev, LC3_FLOAT *q_d_fl_c, LC3_INT yLen); + +void processNoiseSubstitution_fl(LC3_FLOAT* spec, LC3_FLOAT* spec_prev, LC3_INT32 yLen); + +void process_cutoff_bandwidth(LC3_FLOAT* d_fl, LC3_INT len, LC3_INT bw_bin); +void update_enc_bandwidth(LC3PLUS_Enc* encoder, LC3_INT bandwidth); + +/* al_fec.c */ +LC3_INT16 fec_get_n_pccw(LC3_INT16 slot_bytes, LC3_INT16 fec_mode, LC3_INT16 ccc_flag); +LC3_INT16 fec_get_data_size(LC3_INT16 fec_mode, LC3_INT16 ccc_flag, LC3_INT16 slot_bytes); +LC3_INT16 fec_get_n_pc(LC3_INT16 fec_mode, LC3_INT16 n_pccw, LC3_INT16 slot_bytes); +void processReorderBitstream_fl(LC3_UINT8* bytes, LC3_INT32 n_pccw, LC3_INT32 n_pc, LC3_INT32 b_left, LC3_INT32 len); +void fec_encoder(LC3_INT16 mode, LC3_INT16 epmr, LC3_UINT8 *iobuf, LC3_INT16 data_bytes, LC3_INT16 slot_bytes, LC3_INT16 n_pccw); +LC3_INT32 fec_decoder(LC3_UINT8 *iobuf, LC3_INT16 slot_bytes, LC3_INT32 *data_bytes, LC3PLUS_EpModeRequest *epmr, LC3_INT16 ccc_flag, LC3_INT16 *n_pccw, LC3_INT32 *bfi, + LC3_INT16 *be_bp_left, LC3_INT16 *be_bp_right, LC3_INT16 *n_pc, LC3_INT16 *m_fec); + +LC3_FLOAT array_max_abs(LC3_FLOAT *in, LC3_INT32 len); + +void processPcClassify_fl(LC3_INT32 pitch_present, LC3_INT32 frame_dms, LC3_FLOAT *q_d_prev, LC3_FLOAT *q_old_res, LC3_INT32 yLen, LC3_INT32 spec_inv_idx, LC3_FLOAT stab_fac, LC3_INT32 *bfi); +void processPcMain_fl(LC3_INT32 *bfi, LC3PLUS_Dec* decoder, LC3_FLOAT *sqQdec, DecSetup* h_DecSetup, LC3_INT32 pitch_present, LC3_FLOAT stab_fac, LC3_INT32 gg_idx, LC3_INT32 gg_idx_off, LC3_INT32 fac_ns_idx, pcState *statePC, LC3_INT32 spec_inv_idx, LC3_INT32 yLen); +void processPcUpdate_fl(LC3_INT32 bfi, LC3_FLOAT *q_res, LC3_INT32 gg_idx, LC3_INT32 gg_idx_off, LC3_INT32 rframe, LC3_INT32 *BW_cutoff_idx_nf, LC3_INT32 *prev_BW_cutoff_idx_nf, LC3_INT32 fac_ns_idx, LC3_FLOAT *prev_fac_ns, LC3_FLOAT *fac, LC3_FLOAT *q_old_res, LC3_FLOAT *prev_gg, LC3_INT32 spec_inv_idx, LC3_INT32 yLen); +void processPcApply_fl(LC3_FLOAT *q_res, LC3_FLOAT *q_old_res, LC3_FLOAT *q_d_prev, LC3_INT32 spec_inv_idx, LC3_INT32 yLen, LC3_INT32 gg_idx, LC3_INT32 gg_idx_off, LC3_FLOAT *prev_gg, LC3_FLOAT *fac, LC3_INT32 *pc_nbLostCmpt); + +void processPlcClassify_fl(LC3_INT plcMeth, LC3_INT *concealMethod, LC3_INT32 *nbLostCmpt, LC3_INT32 bfi, + LC3_FLOAT *xcorr, LC3_INT32 framelength, LC3_INT32 frame_dms, LC3_INT32 pitch_int, + LC3_INT32 fs, const LC3_INT *band_offsets, LC3_INT32 bands_number, LC3_INT32 tilt, PlcAdvSetup *plcAd + , LC3_INT32 hrmode +); +void processPlcComputeStabFacMain_fl(LC3_FLOAT *scf_q, LC3_FLOAT *old_scf_q, LC3_FLOAT *old_old_scf_q, LC3_INT32 bfi, LC3_INT32 prev_bfi, LC3_INT32 prev_prev_bfi, LC3_FLOAT *stab_fac); + +void processPlcDampingScramblingMain_fl(LC3_INT32 *ns_seed, + LC3_INT32 *pc_seed, LC3_INT32 ns_nbLostCmpt_pc, + LC3_INT32 ns_nbLostCmpt, LC3_FLOAT *stabFac, LC3_FLOAT *cum_fading_slow, LC3_FLOAT *cum_fading_fast, + LC3_FLOAT *spec_prev, LC3_FLOAT *spec, LC3_INT32 spec_inv_idx, LC3_INT32 yLen, LC3_INT32 bfi, + LC3_INT32 frame_dms, LC3_INT32 concealMethod, LC3_INT32 pitch_present_bfi1, LC3_INT32 pitch_present_bfi2, + LC3_FLOAT *cum_fflcAtten); +void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 nbLostCmpt, LC3_FLOAT *stabFac, LC3_INT32 processDampScramb, + LC3_FLOAT *cum_fflcAtten, LC3_INT32 pitch_present, LC3_INT32 frame_dms, LC3_FLOAT *cum_fading_slow, + LC3_FLOAT *cum_fading_fast, LC3_INT32 *seed, LC3_INT32 spec_inv_idx); + +void plc_phEcu_F0_refine_first(LC3_INT32 *plocs, LC3_INT32 n_plocs, LC3_FLOAT *f0est, const LC3_INT32 Xabs_len, + LC3_FLOAT *f0binPtr, LC3_FLOAT *f0gainPtr, const LC3_INT32 nSubm); +void processTdcLpcEstimation_fl(LC3_FLOAT *r, LC3_INT32 fs_idx, LC3_INT32 len, LC3_FLOAT *A, LC3_INT32 frame_dms); + +LC3_FLOAT plc_phEcuSetF0Hz(LC3_INT32 fs, LC3_FLOAT *old_pitchPtr); + +void plc_phEcu_processPLCspec2shape(LC3_INT16 prev_bfi, LC3_INT16 bfi, LC3_FLOAT q_d[], LC3_INT32 yLen, LC3_FLOAT *stPhECU_oold_grp_shape, LC3_FLOAT *stPhECU_old_grp_shape); +void plc_phEcu_LF_peak_analysis(LC3_INT32 *plocs, LC3_INT32 *n_plocs, LC3_FLOAT *f0est, const LC3_FLOAT *Xabs, + LC3_FLOAT *f0binPtr, LC3_FLOAT *f0gainPtr, const LC3_INT32 nSubm); + +void plc_phEcu_F0_refine_first(LC3_INT32 *plocs, LC3_INT32 n_plocs, LC3_FLOAT *f0est, const LC3_INT32 Xabs_len, + LC3_FLOAT *f0binPtr, LC3_FLOAT *f0gainPtr, const LC3_INT32 nSubm); + +LC3_FLOAT plc_phEcu_imax2_jacobsen_mag(const Complex *y, LC3_FLOAT *c_jacobPtr); +LC3_FLOAT plc_phEcu_interp_max(const LC3_FLOAT *y, LC3_INT32 y_len); +void plc_phEcu_fft_spec2_sqrt_approx(const Complex* x, LC3_INT32 x_len, LC3_FLOAT* x_abs); +LC3_INT32 plc_phEcu_pitch_in_plocs(LC3_INT32* plocs, LC3_INT32 n_plocs); +void plc_phEcu_spec_ana(LC3_FLOAT* xfp, LC3_INT32 xfp_len, const LC3_FLOAT* whr, + LC3_FLOAT* pfind_sensPtr, LC3_INT32* plocs, + LC3_INT32* n_plocs, LC3_FLOAT* f0est, Complex* x, LC3_INT32* x_len, + LC3_FLOAT* f0hzLtpBinPtr, LC3_FLOAT* f0gainLtpPtr, LC3_INT32 bw_idx, Fft* PhEcu_Fft); +void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, LC3_INT32 time_offs, Complex* X, LC3_INT32 X_len, + LC3_FLOAT* mag_chg_gr, LC3_INT32 *seed, LC3_FLOAT* alpha, LC3_FLOAT* beta, LC3_FLOAT* Xavg, + LC3_INT32 t_adv_in, LC3_INT32 Lprot, LC3_INT32 delta_corr, LC3_FLOAT *corr_phase_dbg, + LC3_FLOAT *X_i_new_re_dbg, LC3_FLOAT *X_i_new_im_dbg); +void plc_phEcu_rec_frame(Complex *X_in, LC3_INT32 xfp_len, LC3_INT32 Lecu, const LC3_FLOAT *whr, const LC3_FLOAT *winMDCT, LC3_INT32 Lprot, + LC3_FLOAT *xfp, LC3_INT32 time_offs, LC3_FLOAT *x_out, + Complex *full_spec_dbg, LC3_FLOAT* ifft_out_dbg, LC3_FLOAT* xsubst_dbg, + LC3_INT32 LA_ZEROS, LC3_INT32 LA, Fft* PhEcu_Ifft + + ); +void plc_phEcu_tba_spect_Xavg(LC3_INT32 fs_idx, LC3_INT32 n_grp, LC3_FLOAT *oold_spec_shape, + LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_spec_shape, LC3_FLOAT *old_EwPtr, + LC3_FLOAT *gr_pow_left, LC3_FLOAT *gr_pow_right, LC3_FLOAT *Xavg); +void plc_phEcu_tba_per_band_gain(LC3_INT32 n_grp, LC3_FLOAT *gr_pow_left, LC3_FLOAT *gr_pow_right, LC3_FLOAT *trans, LC3_FLOAT *grp_pow_change); +void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *grp_pow_change, + LC3_FLOAT *stPhECU_beta_mute, LC3_FLOAT *stPhECU_mag_chg_1st, + LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, LC3_FLOAT *ph_dith, LC3_INT32 *tr_dec, + LC3_FLOAT *att_val, LC3_INT32 *attDegreeFrames, LC3_FLOAT *thresh_dbg); +void plc_phEcu_trans_burst_ana_sub(LC3_INT32 fs_idx, LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *oold_spect_shape, + LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_spect_shape, + LC3_FLOAT *old_EwPtr, LC3_FLOAT *stPhECU_beta_mute, + LC3_FLOAT *stPhECU_mag_chg_1st, LC3_FLOAT *stPhECU_Xavg, LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, + LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg); +void plc_phEcu_hq_ecu( + LC3_FLOAT *f0binPtr, LC3_FLOAT *f0ltpGainPtr, + LC3_FLOAT *xfp, LC3_INT16 prev_bfi, LC3_INT32 *short_flag_prev, + LC3_INT32 fs, LC3_INT32 * time_offs, + Complex *X_sav_m, LC3_INT32 *n_plocs, LC3_INT32 *plocs, LC3_FLOAT *f0est, const LC3_FLOAT *mdctWin, + LC3_FLOAT *env_stabPtr, LC3_INT32 delta_corr, + LC3_FLOAT *pfind_sensPtr, + LC3_INT32 PhECU_LA, LC3_INT32 t_adv, const LC3_FLOAT *winWhr, LC3_FLOAT *oold_grp_shape, + LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_grp_shape, + LC3_FLOAT *old_EwPtr, + LC3_FLOAT *st_beta_mute, LC3_FLOAT *st_mag_chg_1st, LC3_FLOAT *st_Xavg, LC3_INT32 LA_ZEROS, LC3_FLOAT *x_tda, LC3_FLOAT *xsubst_dbg, Complex *X_out_m_dbg, + LC3_INT32 *seed_dbg, LC3_FLOAT *mag_chg_dbg, LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg, LC3_FLOAT *X_i_new_re_dbg, LC3_FLOAT *X_i_new_im_dbg, LC3_FLOAT *corr_phase_dbg + ,Fft* PhEcu_Fft,Fft* PhEcu_Ifft +); + +void processTdcPreemphasis_fl(LC3_FLOAT *in, LC3_FLOAT *pre_emph_factor, LC3_INT32 n_bands); + +void processTdcTdac_fl(const LC3_FLOAT *synth_inp, const LC3_FLOAT *win, LC3_INT32 frame_length, LC3_INT32 la_zeroes, LC3_FLOAT *ola_mem); +void processTdcInverseOdft_fl(LC3_FLOAT *in, LC3_INT32 n_bands, LC3_FLOAT *out, LC3_INT32 lpc_order); + +void processTdcApply_fl(const LC3_INT32 pitch_LC3_INT, const LC3_FLOAT *preemphFac, const LC3_FLOAT* A, const LC3_INT32 lpc_order, const LC3_FLOAT* pcmbufHist, const LC3_INT32 max_len_pcm_plc, const LC3_INT32 N, const LC3_INT32 frame_dms, + const LC3_INT32 SampRate, const LC3_INT32 nbLostCmpt, const LC3_INT32 overlap, const LC3_FLOAT *stabFac, LC3_FLOAT harmonicBuf[MAX_PITCH], LC3_FLOAT synthHist[M], + LC3_INT32* fract, LC3_INT16* seed, LC3_FLOAT* gain_c, LC3_FLOAT* alpha, LC3_FLOAT* synth); +void* balloc(void* base, size_t* base_size, size_t size); + + + +#endif diff --git a/lc3plus/imdct.c b/lc3plus/imdct.c new file mode 100644 index 0000000000000000000000000000000000000000..5d38aa6cc78077272ea68a12eb0bcf05a5d714ee --- /dev/null +++ b/lc3plus/imdct.c @@ -0,0 +1,102 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +/* Function expects already flipped window */ +void ProcessingIMDCT_fl(LC3_FLOAT* y, LC3_INT yLen, const LC3_FLOAT* win, LC3_INT winLen, LC3_INT last_zeros, LC3_FLOAT* mem, LC3_FLOAT* x, Dct4* dct) +{ + LC3_FLOAT x_tda[MAX_LEN] = {0}, x_ov[2 * MAX_LEN] = {0}; + LC3_INT i = 0, j = 0; + + /* Flip imdct window up to down */ + i = winLen - 1; + j = 0; + + dct4_apply(dct, y, x_tda); + + move_float(x_ov, &x_tda[yLen / 2], yLen / 2); + + j = yLen / 2; + for (i = 0; i < yLen / 2; i++) { + x_ov[j] = -x_tda[yLen - 1 - i]; + j++; + } + + j = yLen; + for (i = 0; i < yLen / 2; i++) { + x_ov[j] = -x_tda[yLen / 2 - 1 - i]; + j++; + } + + j = yLen + yLen / 2; + for (i = 0; i < yLen / 2; i++) { + x_ov[j] = -x_tda[i]; + j++; + } + + for (i = 0; i < winLen; i++) { + x_ov[i] = x_ov[i] * win[winLen - 1 - i]; + } + + /* Buffer update */ + j = 0; + for (i = last_zeros; i < yLen; i++) { + x_ov[i] = x_ov[i] + mem[j]; + j++; + } + + move_float(&x[0], &x_ov[last_zeros], yLen); + + move_float(&mem[0], &x_ov[yLen + last_zeros], (winLen - (yLen + last_zeros))); +} + +void ProcessingITDA_WIN_OLA_fl(LC3_FLOAT* x_tda, LC3_INT32 yLen, const LC3_FLOAT* win, LC3_INT32 winLen, LC3_INT32 last_zeros, LC3_FLOAT* mem, LC3_FLOAT* x) +{ + LC3_FLOAT x_ov[2 * MAX_LEN] = {0}; + LC3_INT32 i, j; + + move_float(x_ov, &x_tda[yLen / 2], yLen / 2); + + j = yLen / 2; + for (i = 0; i < yLen / 2; i++) { + x_ov[j] = -x_tda[yLen - 1 - i]; + j++; + } + + j = yLen; + for (i = 0; i < yLen / 2; i++) { + x_ov[j] = -x_tda[yLen / 2 - 1 - i]; + j++; + } + + j = yLen + yLen / 2; + for (i = 0; i < yLen / 2; i++) { + x_ov[j] = -x_tda[i]; + j++; + } + + for (i = 0; i < winLen; i++) { + x_ov[i] = x_ov[i] * win[winLen - 1 - i]; + } + + /* Buffer update */ + j = 0; + + for (i = last_zeros; i < yLen; i++) { + x[j] = x_ov[i] + mem[j]; + j++; + } + + move_float(&x[j], &x_ov[last_zeros+j], yLen-j); + + move_float(&mem[0], &x_ov[yLen + last_zeros], (winLen - (yLen + last_zeros))); +} diff --git a/lc3plus/lc3.c b/lc3plus/lc3.c new file mode 100644 index 0000000000000000000000000000000000000000..17d2ccb71296628426a4edbb9598145b700ecf1f --- /dev/null +++ b/lc3plus/lc3.c @@ -0,0 +1,431 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "lc3.h" +#include "defines.h" +#include "functions.h" +#include + +#include "setup_dec_lc3.h" +#include "setup_enc_lc3.h" + +#define RETURN_IF(cond, error) \ + if (cond) \ + return (error) + +/* ensure api header constants are up to date */ +STATIC_ASSERT(LC3PLUS_MAX_SAMPLES >= MAX_LEN); +STATIC_ASSERT(LC3PLUS_MAX_CHANNELS >= MAX_CHANNELS); +STATIC_ASSERT(LC3PLUS_MAX_BYTES >= BYTESBUFSIZE); + +/* misc functions ************************************************************/ + +int lc3plus_version(void) +{ + return LC3PLUS_VERSION; +} + +int lc3plus_channels_supported(int channels) +{ + return channels >= 1 && channels <= MAX_CHANNELS; +} + +int lc3plus_samplerate_supported(int samplerate) +{ + switch (samplerate) + { + case 8000: return 1; + case 16000: return 1; + case 24000: return 1; + case 32000: return 1; + case 44100: return 1; + case 48000: return 1; + case 96000: return 1; + default: break; + } + return 0; +} + +static int lc3plus_plc_mode_supported(LC3PLUS_PlcMode plc_mode) +{ + switch ((int)plc_mode) + { + case LC3PLUS_PLC_ADVANCED: /* fallthru */ + return 1; + default: break; + } + return 0; +} + +static int lc3plus_frame_size_supported(float frame_ms) +{ + switch ((int)(ceil(frame_ms * 10))) + { + case 25: /* fallthru */ + case 50: /* fallthru */ + case 100: return 1; + default: break; + } + return 0; +} + +static int null_in_list(void **list, int n) +{ + while (--n >= 0) + RETURN_IF(list[n] == NULL, 1); + return 0; +} + +/* return pointer to aligned base + base_size, *base_size += size + 4 bytes align */ +void *balloc(void *base, size_t *base_size, size_t size) +{ + uintptr_t ptr = ((uintptr_t)base + *base_size + 3) & ~3; + assert((uintptr_t)base % 4 == 0); /* base must be 4-byte aligned */ + *base_size = (*base_size + size + 3) & ~3; + return (void *)ptr; +} + +int32_t lc3_enc_supported_lfe(void) +{ + return 1; +} + +/* encoder functions *********************************************************/ +LC3PLUS_Error lc3plus_enc_init(LC3PLUS_Enc *encoder, int samplerate, int channels, int hrmode, int32_t lfe_channel_array[]) +{ + int ch = 0; + + RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); + RETURN_IF((uintptr_t)encoder % 4 != 0, LC3PLUS_ALIGN_ERROR); + RETURN_IF(!lc3plus_samplerate_supported(samplerate), LC3PLUS_SAMPLERATE_ERROR); + RETURN_IF(!lc3plus_channels_supported(channels), LC3PLUS_CHANNELS_ERROR); + RETURN_IF(samplerate==96000 && hrmode == 0, LC3PLUS_HRMODE_ERROR); + + for (ch = 0; ch < channels; ch++) + { + RETURN_IF(!lc3_enc_supported_lfe() && lfe_channel_array[ch], LC3PLUS_LFE_MODE_NOT_SUPPORTED); + } + + return FillEncSetup(encoder, samplerate, channels, hrmode, lfe_channel_array); /* real bitrate check happens here */ +} + +int lc3plus_enc_get_size(int samplerate, int channels) +{ + RETURN_IF(!lc3plus_samplerate_supported(samplerate), 0); + RETURN_IF(!lc3plus_channels_supported(channels), 0); + return alloc_encoder(NULL, channels); +} + +/* Dummy function for API alignment */ +int lc3plus_enc_get_scratch_size(const LC3PLUS_Enc *encoder) +{ + UNUSED(encoder); + return 0; +} + +int lc3plus_enc_get_input_samples(const LC3PLUS_Enc *encoder) +{ + RETURN_IF(encoder == NULL, 0); + return encoder->frame_length; +} + +int lc3plus_enc_get_num_bytes(const LC3PLUS_Enc *encoder) +{ + RETURN_IF(encoder == NULL, 0); + + return encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in); +} + +int lc3plus_enc_get_real_bitrate(const LC3PLUS_Enc *encoder) +{ + int ch = 0, totalBytes = 0; + int bitrate; + RETURN_IF(encoder == NULL, 0); + RETURN_IF(!encoder->lc3_br_set, LC3PLUS_BITRATE_UNSET_ERROR); + + for (ch = 0; ch < encoder->channels; ch++) + { + totalBytes += encoder->channel_setup[ch]->targetBytes; + } + + bitrate = (totalBytes * 80000.0 + encoder->frame_dms - 1) / encoder->frame_dms; + + if (encoder->fs_in == 44100) + { + int rem = bitrate % 480; + bitrate = ((bitrate - rem) / 480) * 441 + (rem * 441) / 480; + } + + return bitrate; +} + + +LC3PLUS_Error lc3plus_enc_set_bitrate(LC3PLUS_Enc *encoder, int bitrate) +{ + RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); + RETURN_IF(bitrate <= 0, LC3PLUS_BITRATE_ERROR); +#ifndef STRIP_HR_MODE_API + RETURN_IF(encoder->fs_idx == 5 && encoder->hrmode == 0, LC3PLUS_HRMODE_ERROR); +#endif + return update_enc_bitrate(encoder, bitrate); +} + +int lc3plus_enc_get_delay(const LC3PLUS_Enc *encoder) +{ + RETURN_IF(encoder == NULL, 0); + return encoder->frame_length - 2 * encoder->la_zeroes; +} + +LC3PLUS_Error lc3plus_enc_set_frame_dms(LC3PLUS_Enc *encoder, int frame_dms) +{ + RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); + RETURN_IF(!lc3plus_frame_size_supported(frame_dms / 10.0), LC3PLUS_FRAMEMS_ERROR); + RETURN_IF(encoder->lc3_br_set, LC3PLUS_BITRATE_SET_ERROR); + encoder->frame_dms = frame_dms; + encoder->frame_ms = frame_dms / 10.0; + set_enc_frame_params(encoder); + return LC3PLUS_OK; +} + +LC3PLUS_Error lc3plus_enc_set_bandwidth(LC3PLUS_Enc *encoder, int bandwidth) +{ + LC3_INT effective_fs; + + RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); +#ifdef ENABLE_HR_MODE_FL_FLAG + RETURN_IF(encoder->hrmode == 1, LC3PLUS_HRMODE_BW_ERROR); +#endif + effective_fs = encoder->fs_in; + if (encoder->bandwidth != bandwidth) { + if (encoder->fs_in > 40000) { + effective_fs = 40000; + } + if ((bandwidth * 2) > effective_fs) { + return LC3PLUS_BW_WARNING; + } + else { + encoder->bandwidth = bandwidth; + encoder->bandwidth_preset = bandwidth; + encoder->bw_ctrl_active = 1; + update_enc_bitrate(encoder, encoder->bitrate); + } + } + return LC3PLUS_OK; +} + + +LC3PLUS_Error lc3plus_enc16(LC3PLUS_Enc* encoder, int16_t** input_samples, void* output_bytes, int* num_bytes +, void *scratch +) +{ + UNUSED(scratch); + return lc3plus_enc_fl(encoder, (void**)input_samples, 16, output_bytes, num_bytes); +} + +LC3PLUS_Error lc3plus_enc24(LC3PLUS_Enc* encoder, int32_t** input_samples, void* output_bytes, int* num_bytes +, void *scratch +) +{ + UNUSED(scratch); + return lc3plus_enc_fl(encoder, (void**)input_samples, 24, output_bytes, num_bytes); +} + + +LC3PLUS_Error lc3plus_enc_fl(LC3PLUS_Enc* encoder, void** input_samples, int bitdepth, void* output_bytes, int* num_bytes) +{ + RETURN_IF(!encoder || !input_samples || !output_bytes || !num_bytes, LC3PLUS_NULL_ERROR); + RETURN_IF(null_in_list(input_samples, encoder->channels), LC3PLUS_NULL_ERROR); + RETURN_IF(bitdepth != 16 && bitdepth != 24, LC3PLUS_ERROR); + *num_bytes = Enc_LC3PLUS_fl(encoder, input_samples, output_bytes, bitdepth + , *num_bytes == -1 + ); + assert(*num_bytes == lc3plus_enc_get_num_bytes(encoder)); + return LC3PLUS_OK; +} + +/* decoder functions *********************************************************/ + +LC3PLUS_Error lc3plus_dec_init(LC3PLUS_Dec* decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode, int hrmode) +{ + RETURN_IF(decoder == NULL, LC3PLUS_NULL_ERROR); + RETURN_IF(!lc3plus_samplerate_supported(samplerate), LC3PLUS_SAMPLERATE_ERROR); + RETURN_IF(!lc3plus_channels_supported(channels), LC3PLUS_CHANNELS_ERROR); + RETURN_IF(!lc3plus_plc_mode_supported(plc_mode), LC3PLUS_PLCMODE_ERROR); + RETURN_IF(samplerate==96000 && hrmode == 0, LC3PLUS_HRMODE_ERROR); + return FillDecSetup(decoder, samplerate, channels, plc_mode, hrmode); +} + +int lc3plus_dec_get_size(int samplerate, int channels) +{ + RETURN_IF(!lc3plus_samplerate_supported(samplerate), 0); + RETURN_IF(!lc3plus_channels_supported(channels), 0); + return alloc_decoder(NULL, samplerate, channels); +} + +/* Dummy function for API alignment */ +int lc3plus_dec_get_scratch_size(const LC3PLUS_Dec *decoder) +{ + UNUSED(decoder); + return 0; +} + +LC3PLUS_Error lc3plus_dec_set_frame_dms(LC3PLUS_Dec *decoder, int frame_dms) +{ + RETURN_IF(decoder == NULL, LC3PLUS_NULL_ERROR); + RETURN_IF(!lc3plus_frame_size_supported(frame_dms / 10.0), LC3PLUS_FRAMEMS_ERROR); + RETURN_IF(decoder->plcMeth == 2 && frame_dms != 100, LC3PLUS_FRAMEMS_ERROR); + + decoder->frame_dms = frame_dms; + decoder->frame_ms = frame_dms / 10.0; + set_dec_frame_params(decoder); + return LC3PLUS_OK; +} + +int lc3plus_dec_get_output_samples(const LC3PLUS_Dec* decoder) +{ + RETURN_IF(decoder == NULL, 0); + return decoder->frame_length; +} + +int lc3plus_dec_get_delay(const LC3PLUS_Dec* decoder) +{ + RETURN_IF(decoder == NULL, 0); + return decoder->frame_length - 2 * decoder->la_zeroes; +} + +LC3PLUS_Error lc3plus_dec_fl(LC3PLUS_Dec* decoder, void* input_bytes, int num_bytes, void** output_samples, int bps, int bfi_ext) +{ + RETURN_IF(!decoder || !input_bytes || !output_samples, LC3PLUS_NULL_ERROR); + RETURN_IF(null_in_list((void**)output_samples, decoder->channels), LC3PLUS_NULL_ERROR); + return Dec_LC3PLUS_fl(decoder, input_bytes, num_bytes, output_samples, bps, bfi_ext); +} + +LC3PLUS_Error lc3plus_dec16(LC3PLUS_Dec* decoder, void* input_bytes, int num_bytes, int16_t** output_samples, + void* scratch, + int bfi_ext) +{ + UNUSED(scratch); + return lc3plus_dec_fl(decoder, input_bytes, num_bytes, (void**)output_samples, 16, bfi_ext); +} + +LC3PLUS_Error lc3plus_dec24(LC3PLUS_Dec* decoder, void* input_bytes, int num_bytes, int32_t** output_samples, + void* scratch, + int bfi_ext) +{ + UNUSED(scratch); + return lc3plus_dec_fl(decoder, input_bytes, num_bytes, (void**)output_samples, 24, bfi_ext); +} + +/* memory functions *********************************************************/ + +LC3PLUS_Error lc3plus_enc_free_memory(LC3PLUS_Enc* encoder) +{ + RETURN_IF(!encoder, LC3PLUS_NULL_ERROR); + + lc3plus_free_encoder_structs(encoder); + + return LC3PLUS_OK; +} + +LC3PLUS_Error lc3plus_dec_free_memory(LC3PLUS_Dec* decoder) +{ + RETURN_IF(!decoder, LC3PLUS_NULL_ERROR); + + lc3plus_free_decoder_structs(decoder); + + return LC3PLUS_OK; +} + +LC3PLUS_Error lc3plus_free_encoder_structs(LC3PLUS_Enc* encoder) +{ + int ch = 0; + RETURN_IF(!encoder, LC3PLUS_NULL_ERROR); + + for (ch = 0; ch < encoder->channels; ch++) { + mdct_free(&encoder->channel_setup[ch]->mdctStruct); + dct2_free(&encoder->channel_setup[ch]->dct2StructSNS); + } + + return LC3PLUS_OK; +} + +LC3PLUS_Error lc3plus_free_decoder_structs(LC3PLUS_Dec* decoder) +{ + int ch = 0; + RETURN_IF(!decoder, LC3PLUS_NULL_ERROR); + + for (ch = 0; ch < decoder->channels; ch++) { + dct4_free(&decoder->channel_setup[ch]->dct4structImdct); + real_fft_free(&decoder->channel_setup[ch]->PlcAdvSetup->PlcPhEcuSetup.PhEcu_Fft); + real_fft_free(&decoder->channel_setup[ch]->PlcAdvSetup->PlcPhEcuSetup.PhEcu_Ifft); + } + + return LC3PLUS_OK; +} + + +LC3PLUS_EpModeRequest lc3plus_dec_get_ep_mode_request(const LC3PLUS_Dec *decoder) +{ + RETURN_IF(decoder == NULL, LC3PLUS_EPMR_ZERO); + return (LC3PLUS_EpModeRequest)decoder->epmr; +} + +int lc3plus_dec_get_error_report(const LC3PLUS_Dec *decoder) +{ + RETURN_IF(decoder == NULL, 0); + return decoder->error_report == 2047 ? -1 : decoder->error_report & 0x07FF; +} + +LC3PLUS_Error lc3plus_enc_set_ep_mode(LC3PLUS_Enc *encoder, LC3PLUS_EpMode epmode) +{ + LC3PLUS_EpMode oldEpmode; + LC3PLUS_Error error; + + RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); + RETURN_IF((unsigned)epmode > LC3PLUS_EP_HIGH, LC3PLUS_EPMODE_ERROR); + oldEpmode = encoder->epmode; + encoder->epmode = epmode; + error = encoder->lc3_br_set ? update_enc_bitrate(encoder, encoder->bitrate) : LC3PLUS_OK; + if (error != LC3PLUS_OK) + { + encoder->epmode = oldEpmode; // preserve old epmode in case of failure + } + return error; +} + +LC3PLUS_Error lc3plus_enc_set_ep_mode_request(LC3PLUS_Enc *encoder, LC3PLUS_EpModeRequest epmr) +{ + RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); + RETURN_IF((unsigned)epmr > LC3PLUS_EPMR_HIGH, LC3PLUS_EPMODE_ERROR); + encoder->epmr = epmr; + return LC3PLUS_OK; +} + +LC3PLUS_Error lc3plus_dec_set_ep_enabled(LC3PLUS_Dec *decoder, int32_t ep_enabled) +{ + RETURN_IF(decoder == NULL, LC3PLUS_NULL_ERROR); + decoder->ep_enabled = ep_enabled != 0; + decoder->epmr = LC3PLUS_EPMR_ZERO; + return LC3PLUS_OK; +} + +int lc3plus_dec_get_epok_flags(const LC3PLUS_Dec *decoder) +{ + RETURN_IF(decoder == NULL, 0); + return decoder->error_report >> 11; +} + +#ifndef STRIP_ERROR_PROTECTION_API_FL +#endif /* STRIP_ERROR_PROTECTION_API_FL */ + +#ifndef STRIP_ERROR_PROTECTION_API_FL +#endif /* STRIP_ERROR_PROTECTION_API_FL */ + diff --git a/lc3plus/lc3.h b/lc3plus/lc3.h new file mode 100644 index 0000000000000000000000000000000000000000..3e45438fede66c23bfeb2efc0b3927e7a46e78d0 --- /dev/null +++ b/lc3plus/lc3.h @@ -0,0 +1,517 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +/*! \file lc3.h + * This header provides the API for LC3plus. + * + * This library is targeting devices with extreme memory limitations, so memory management + * must be handeled by the user. This includes allocating memory for the structs. The structs are persistent + * between function calls. + * + * The amount of memory needed for various configurations can be obtained from the lc3plus_*_get_size + * function. The LC3PLUS_*_MAX_SIZE macro can be used for all configurations. + * + * Depending on the build configuration some functions might not be available. + */ + +#ifndef LC3PLUS_H +#define LC3PLUS_H + +#ifndef _MSC_VER +#include +#else +typedef unsigned char uint8_t; +typedef __int16 int16_t; +typedef __int32 int32_t; +#endif + +/*! Construct version number from major/minor/micro values. */ +#define LC3PLUS_VERSION_INT(major, minor, micro) (((major) << 16) | ((minor) << 8) | (micro)) + +/*! Version number to ensure header and binary are matching. */ +#define LC3PLUS_VERSION LC3PLUS_VERSION_INT(1, 6, 9) + +/*! Maximum number of supported channels. The actual binary might support + * less, use lc3plus_channels_supported() to check. */ +#define LC3PLUS_MAX_CHANNELS 2 + +/*! Maximum number of samples per channel that can be stored in one LC3plus frame. + */ +#define LC3PLUS_MAX_SAMPLES 960 + +/*! Maximum number of bytes of one LC3plus frame. */ +#define LC3PLUS_MAX_BYTES 1250 + +/*! Maximum size needed to store encoder state. */ +#define LC3PLUS_ENC_MAX_SIZE 20392 + +/*! Maximum size needed to store decoder state. */ +#define LC3PLUS_DEC_MAX_SIZE 87528 + +/*! Error codes returned by functions. */ +typedef enum +{ + LC3PLUS_PLC_ADVANCED = 1 /*!< Enhanced concealment method */ +} LC3PLUS_PlcMode; + +/*! Error protection mode. LC3PLUS_EP_ZERO differs to LC3PLUS_EP_OFF in that + * errors can be detected but not corrected. */ +typedef enum +{ + LC3PLUS_EP_OFF = 0, /*!< Error protection is disabled */ + LC3PLUS_EP_ZERO = 1, /*!< Error protection with 0 bit correction */ + LC3PLUS_EP_LOW = 2, /*!< Error protection correcting one symbol per codeword */ + LC3PLUS_EP_MEDIUM = 3, /*!< Error protection correcting two symbols per codeword */ + LC3PLUS_EP_HIGH = 4 /*!< Error protection correcting three symbols per codeword */ +} LC3PLUS_EpMode; + +/*! Error protection mode request. On the encoder sidem, LC3PLUS_EPMR_ZERO to LC3PLUS_EPMR_HIGH + * can be set. The decoder returns mode requests with different confidences. */ +typedef enum +{ + LC3PLUS_EPMR_ZERO = 0, /*!< Request no error correction. High confidence if returned by decoder. */ + LC3PLUS_EPMR_LOW = 1, /*!< Request low error correction. High confidence if returned by decoder. */ + LC3PLUS_EPMR_MEDIUM = 2, /*!< Request medium error correction. High confidence if returned by decoder. */ + LC3PLUS_EPMR_HIGH = 3, /*!< Request high error correction. High confidence if returned by decoder. */ + LC3PLUS_EPMR_ZERO_MC = 4, /*!< No error correction requested, medium confidence. */ + LC3PLUS_EPMR_LOW_MC = 5, /*!< Low error correction requested, medium confidence. */ + LC3PLUS_EPMR_MEDIUM_MC = 6, /*!< Medium error correction requested, medium confidence. */ + LC3PLUS_EPMR_HIGH_MC = 7, /*!< High error correction requested, medium confidence. */ + LC3PLUS_EPMR_ZERO_NC = 8, /*!< No error correction requested, unvalidated. */ + LC3PLUS_EPMR_LOW_NC = 9, /*!< Low error correction requested, unvalidated. */ + LC3PLUS_EPMR_MEDIUM_NC = 10, /*!< Medium error correction requested, unvalidated. */ + LC3PLUS_EPMR_HIGH_NC = 11 /*!< High error correction requested, unvalidated. */ +} LC3PLUS_EpModeRequest; + +/*! Error codes returned by functions. */ +typedef enum +{ + LC3PLUS_OK = 0, /*!< No error occurred */ + LC3PLUS_ERROR = 1, /*!< Function call failed */ + LC3PLUS_DECODE_ERROR = 2, /*!< Frame failed to decode and was concealed */ + LC3PLUS_NULL_ERROR = 3, /*!< Pointer argument is null */ + LC3PLUS_SAMPLERATE_ERROR = 4, /*!< Invalid samplerate value */ + LC3PLUS_CHANNELS_ERROR = 5, /*!< Invalid channels value */ + LC3PLUS_BITRATE_ERROR = 6, /*!< Invalid bitrate value */ + LC3PLUS_NUMBYTES_ERROR = 7, /*!< Invalid num_bytes value */ + LC3PLUS_EPMODE_ERROR = 8, /*!< Invalid plc_method value */ + LC3PLUS_FRAMEMS_ERROR = 9, /*!< Invalid epmode value */ + LC3PLUS_ALIGN_ERROR = 10, /*!< Invalid frame_ms value */ + LC3PLUS_HRMODE_ERROR = 11, /*!< Unaligned pointer */ + LC3PLUS_BITRATE_UNSET_ERROR = 12, /*!< Invalid epmr value */ + LC3PLUS_BITRATE_SET_ERROR = 13, /*!< Invalid usage of hrmode, sampling rate and frame size */ + LC3PLUS_HRMODE_BW_ERROR = 14, /*!< Function called before bitrate has been set */ + LC3PLUS_PLCMODE_ERROR = 15, /*!< Function called after bitrate has been set */ + LC3PLUS_EPMR_ERROR = 16, /*!< Invalid external bad frame index */ + LC3PLUS_PADDING_ERROR = 17, /*!< Incorrect padding value */ + FRAMESIZE_ERROR = 18, /*!< Incorrect frame size during decoding */ + LC3PLUS_LFE_MODE_NOT_SUPPORTED = 19, /*!< LFE support not available */ + + /* START WARNING */ + LC3PLUS_WARNING = 20, + LC3PLUS_BW_WARNING = 21 /*!< Invalid bandwidth cutoff frequency */ + +} LC3PLUS_Error; + +typedef struct LC3PLUS_Enc LC3PLUS_Enc; /*!< Opaque encoder struct. */ +typedef struct LC3PLUS_Dec LC3PLUS_Dec; /*!< Opaque decoder struct. */ + +/*! \addtogroup Misc + * \{ */ + +/*! Test LFE mode support. + * + * Tests the support of the LFE mode. + * + * \return 1 for true, 0 for false. + */ +int32_t lc3_enc_supported_lfe(void); + +/*! Return library version number. It should match LC3PLUS_VERSION. */ +int lc3plus_version(void); + +/*! Tests if the library supports number of channels. + * + * \param[in] channels Number of channels. + * \return 1 for true, 0 for false. + */ +int lc3plus_channels_supported(int channels); + +/*! Tests if the library supports a sampling rate. + * + * \param[in] samplerate Sampling rate + * \return 1 for true, 0 for false + */ +int lc3plus_samplerate_supported(int samplerate); + +/*! \} + * \addtogroup Encoder + * \{ */ + +/*! + * Initialize LC3plus encoder. + * + * This function is used to fill a user-allocated encoder struct. This is typically + * called once for a samplerate / channel configuration. After init and before encoding + * the first frame you must call lc3plus_enc_set_bitrate(). + * + * \param[out] encoder Pointer to allocated encoder memory. It must have a size provided + * by lc3plus_enc_get_size() for matching samplerate / channels + * configuration or LC3PLUS_ENC_MAX_SIZE. + * \param[in] channels Number of channels. + * \param[in] samplerate Input sampling rate. Allowed sampling rates are: + * 8000, 16000, 24000, 32000, 44100, 48000 + * \param[in] hrmode High resolution mode. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc_init(LC3PLUS_Enc* encoder, int samplerate, int channels, int hrmode, int32_t lfe_channel_array[]); + +/*! + * Encode LC3plus frame with 16 bit input. + * + * Each call consumes a fixed number of samples. The number of input samples + * can be obtained from lc3plus_enc_get_input_samples(). + * Scratch parameter only works as dummy parameter to align fixed-point and floating-point APIs + * + * \param[in] encoder Encoder handle initialized by lc3plus_enc_init(). + * \param[in] input_samples Input samples. The left channel is stored in input_samples[0], + * the right channel in input_samples[1]. The input is not changed + * by the encoder. + * \param[out] output_bytes Output buffer. It must have a at least lc3plus_enc_get_num_bytes() + * or at most LC3PLUS_MAX_BYTES. + * \param[out] num_bytes Number of bytes written to output_bytes. + * \param scratch See comment above. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc16(LC3PLUS_Enc* encoder, int16_t** input_samples, void* output_bytes, int* num_bytes +, void *scratch +); + +/*! Encode LC3plus frame with 24 bit input. + * + * The input samples are expected to be 24-bit values, sign-extended to 32-bit. + * See lc3plus_enc16() for parameter documentation. + */ +LC3PLUS_Error lc3plus_enc24(LC3PLUS_Enc* encoder, int32_t** input_samples, void* output_bytes, int* num_bytes +, void *scratch +); + +/*! + * Internal function. Use lc3plus_enc16() or lc3plus_enc24() for encoding. + */ + +LC3PLUS_Error lc3plus_enc_fl(LC3PLUS_Enc* encoder, void** input_samples, int bitdepth, void* output_bytes, int* num_bytes); + +/*! Get the size of the LC3plus encoder struct for a samplerate / channel + * configuration. If memory is not restricted LC3PLUS_ENC_MAX_SIZE can be used for + * all configurations. + * + * \param[in] samplerate Sampling rate. + * \param[in] channels Number of channels. + * \return Size in bytes or 0 on error. + */ +int lc3plus_enc_get_size(int samplerate, int channels); + +/*! Dummy function as no scratch management available in floating-point code. Returns always zero. Used to align fixed-point and floating-point APIs. + * + * \param[in] encoder Encoder handle. + * \return Size in bytes or 0 on error. + */ +int lc3plus_enc_get_scratch_size(const LC3PLUS_Enc *encoder); + +/*! Get number of samples per channel expected by lc3plus_enc16() or lc3plus_enc24(). + * + * \param[in] encoder Encoder handle. + * \return Number of samples or 0 on error. + */ +int lc3plus_enc_get_input_samples(const LC3PLUS_Enc* encoder); + +/*! Get real internal bitrate of the encoder. It might differ from the requested + * bitrate due to 44.1 kHz input. + * + * \param[in] encoder Encoder handle. + * \return Bitrate in bits per second or 0 on error. + */ +int lc3plus_enc_get_real_bitrate(const LC3PLUS_Enc* encoder); + +/*! Get the maximum number of bytes produced by lc3plus_enc16() or lc3plus_enc24() for the current + * bitrate. It should be equal to the num_bytes output of lc3plus_enc16/24(). + * + * \param[in] encoder Encoder handle. + * \return Size in bytes or 0 on error. + */ +int lc3plus_enc_get_num_bytes(const LC3PLUS_Enc *encoder); + +/*! Set encoder bitrate for all channels. + * This function must be called at least once before encoding the first frame, but + * after other configuration functions such as lc3plus_enc_set_frame_ms(). + * + * Recommended bitrates for input sampling rates with 10 ms framing: + * kHz | kbps + * --------|----- + * 8 | 24 + * 16 | 32 + * 24 | 48 + * 32 | 64 + * 44.1/48 | 80(voice) 128(music) + * 96 | 128 + * + * \param[in] encoder Encoder handle. + * \param[in] bitrate Bitrate in bits per second. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc_set_bitrate(LC3PLUS_Enc* encoder, int bitrate); + +/*! Get the encoder delay in number of samples. + * + * \param[in] encoder Encoder handle. + * \return Encoder in samples or 0 on error. + */ +int lc3plus_enc_get_delay(const LC3PLUS_Enc *encoder); + +/*! Set the frame length for LC3plus decoder in deci milliseconds. + * Not all lengths may be enabled, in that case LC3PLUS_FRAMEMS_ERROR is returned. + * This only works correcly if the encoder was configured with the same vale. + * + * \param[in] decoder Decoder handle. + * \param[in] frame_ms Frame length in ms. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc_set_frame_dms(LC3PLUS_Enc *encoder, int frame_ms); + + +/*! Set encoder Low-frequency effect moded. deactivates LTPF, TNS, NF + * + * \param[in] encoder Encoder handle. + * \param[in] lfe LFE mode flag + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc_set_lfe(LC3PLUS_Enc* encoder, int lfe); + +/*! Free memory allocated within LC3plus encoder struct. + * + * \param[in] encoder Encoder handle. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc_free_memory(LC3PLUS_Enc* encoder); + +/*! Set encoder bandwidth to a different value. All frequency bins above the cutoff + * frequency are cut off. Allowed frequencies are: 4 kHz, 8 kHz, 12 kHz, 16 kHz and 24 kHz. + * + * \param[in] encoder Encoder handle. + * \param[in] bandwidth Cutoff Frequency in Hz + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc_set_bandwidth(LC3PLUS_Enc *encoder, int bandwidth); + +/*! Internal function called by lc3plus_enc_free_memory. + * + * \param[in] encoder Encoder handle. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_free_encoder_structs(LC3PLUS_Enc* encoder); + +/*! Sets error protection mode request transmitted in each channel encoded frame. + * The channel coder includes an error protection mode request (EPMR) in every frame. + * The EPMR takes value 0, 1, 2, and 3 which request ep modes 1, 2, 3, and 4 from the + * decoding device. The EPMR can be retrieved from the channel decoder via the interface + * routine lc3plus_dec_get_ep_mode_request(). + * + * \param[in] encoder Encoder handle. + * \param[in] epmr Error Protection Mode Request + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc_set_ep_mode_request(LC3PLUS_Enc *encoder, LC3PLUS_EpModeRequest epmr); + +/*! Set error protection mode. The default is LC3PLUS_EP_OFF. It is possible to switch between + * different modees during encoding. Dynamic switching is only allowed between LC3PLUS_EP_ZERO, + * LC3PLUS_EP_LOW, LC3_EP_MEDIUM, and LC3PLUS_EP_HIGH. The the decoder must be notified with + * lc3plus_dec_set_ep_enabled() to expect protected data if epmode is other than LC3PLUS_EP_OFF. + * + * \param[in] encoder Encoder handle. + * \param[in] epmode Error protection mode. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc_set_ep_mode(LC3PLUS_Enc *encoder, LC3PLUS_EpMode epmode); + +/*! \} + * \addtogroup Decoder + * \{ */ + +/*! + * Initialize LC3plus decoder. + * + * This function is used to fill a user-allocated decoder struct. This is + * typically called once for a samplerate / channel configuration. + * + * The samplerate and channel arguments must have the same values that were + * used for encoding. LC3plus does not provide a signalling scheme, transporting + * these values is the responsibility of the application. + * + * \param[out] decoder Pointer to decoder memory. It must have as size + * of least lc3plus_dec_get_size() or at most LC3PLUS_DEC_MAX_SIZE. + * \param[in] samplerate Bitstream sampling rate. \param[in] channels Bitstream + * number of channels. + * + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_dec_init(LC3PLUS_Dec* decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode, int hrmode); + + + +/*! + * Decode compressed LC3plus frame to 16 bit PCM output. + * + * Each call decodes a fixed number of samples. Use lc3plus_dec_get_output_samples() to obtain this + * number. When the input is corrupted and can not be decoded, LC3PLUS_DECODE_ERROR is returned and + * packet loss concealment is applied, so the output is still usable. + * If error protection is enabled and the errors can be corrected the frame is corrected and + * normally decoded. Use lc3plus_dec_get_error_report() to check if errors were corrected. + * + * \param[in] decoder Decoder initialized by lc3plus_dec_init(). + * \param[in] input_bytes Input bytes. If error protection is enabled the input bytes can be + * altered when error correction is applied. This is why this buffer + * must be writable. + * \param[in] num_bytes Number of valid bytes in input_bytes. To signal a lost frame and + * generate concealment output this value must be set to 0. + * \param[out] output_samples Array of pointers to output channel buffers. Each channel buffer + * should provide enough space to hold at most LC3PLUS_MAX_SAMPLES. The + * left channel is stored in output_samples[0], the right channel in + * output_samples[1]. + * \param scratch Scratch parameter only works as dummy parameter to align fixed-point and floating-point APIs + * \return Returns LC3PLUS_OK on success or appropriate error code. Note there is + * a special case for LC3PLUS_DECODE_ERROR where the output is still valid. + */ +LC3PLUS_Error lc3plus_dec16(LC3PLUS_Dec* decoder, void* input_bytes, int num_bytes, int16_t** output_samples, + void* scratch, + int bfi_ext); + +/*! Decode compressed LC3plus frame to 24 bit PCM output. + * + * The output samples are 24-bit values, sign-extended to 32-bit. + * See lc3plus_dec16() for parameter documentation. + */ +LC3PLUS_Error lc3plus_dec24(LC3PLUS_Dec* decoder, void* input_bytes, int num_bytes, int32_t** output_samples, + void* scratch, + int bfi_ext); + +/* Internal function */ + LC3PLUS_Error lc3plus_dec_fl(LC3PLUS_Dec* decoder, void* input_bytes, int num_bytes, void** output_samples, int bps, int bfi_ext); + +/*! Get the size of the LC3plus decoder struct for a samplerate / channel + * configuration. If memory is not restricted LC3PLUS_DEC_MAX_SIZE can be used for + * all configurations. + * + * \param[in] channels Number of channels. + * \param[in] samplerate Sampling rate. + * \return Size in bytes or 0 on error. + */ +int lc3plus_dec_get_size(int samplerate, int channels); + +/*! Dummy function as no scratch management available in floating-point code. Returns always zero. Used to align fixed-point and floating-point APIs. + * + * \param[in] decoder Decoder handle. + * \return Size in bytes or 0 on error. + */ +int lc3plus_dec_get_scratch_size(const LC3PLUS_Dec *decoder); + +/*! Get the number of samples per channel produced by lc3plus_dec16() or lc3plus_dec24. + * + * \param[in] decoder Decoder handle. + * \return Number of samples or 0 on error. + */ +int lc3plus_dec_get_output_samples(const LC3PLUS_Dec* decoder); + +/*! Get the decoder delay in number of samples. + * + * \param[in] decoder Decoder handle. + * \return Delay in samples or 0 on error. + */ +int lc3plus_dec_get_delay(const LC3PLUS_Dec* decoder); + +/*! Set the frame length for LC3plus encoder in deci milliseconds. + * Not all lengths may be enabled, in that case LC3PLUS_FRAMEMS_ERROR is returned. + * This function must be called before lc3plus_enc_set_bitrate(). The decoder must be + * configured with lc3plus_dec_set_frame_dms() with the same value. + * + * \param[in] encoder Encoder handle. + * \param[in] frame_ms Frame length in ms. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_dec_set_frame_dms(LC3PLUS_Dec *decoder, int frame_ms); + + +/*! Free memory allocated within LC3plus decoder struct. + * + * \param[in] decoder Decoder handle. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_dec_free_memory(LC3PLUS_Dec* decoder); + +/*! Internal function called by lc3plus_dec_free_memory. + * + * \param[in] decoder Decoder handle. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_free_decoder_structs(LC3PLUS_Dec* decoder); + +/*! Enable or disable error protection. Default value is 0 (disabled). If error protection is + * enabled, the decoder expects that the frames were encoded with error protection mode + * LC3PLUS_EP_ZERO or higher. + * + * \param[in] decoder Decoder handle. + * \param[in] ep_enabled 1 (or any nonzero) for true, 0 for false. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_dec_set_ep_enabled(LC3PLUS_Dec *decoder, int ep_enabled); + +/*! Retrieves the error protection mode reqeust from channel decoder. + * + * The return value encodes both the error protection mode request (EPMR) + * and the confidence of the method by which it was retrieved. + * + * The requested error protection mode is (epmr % 4) + 1, where epmr is the + * function's return value. The confidence is specified as follows. + * + * Confidence | Range + * -----------|------------- + * high | 0 <= epmr < 4 + * medium | 4 <= epmr < 8 + * no | 8 <= epmr < 12 + * + * When receiving stereo content of separately channel encoded audio frames the + * return value is the minimum of two values retrieved from the individual channels. + * + * \param[in] decoder Decoder handle. + * \return Error protection mode reqeust. + */ +LC3PLUS_EpModeRequest lc3plus_dec_get_ep_mode_request(const LC3PLUS_Dec *decoder); + +/*! Get the number of corrected bit errors in the last decoded frame. This only works if + * error protection is active. If the number of errors is greater than the current error + * protection mode can correct, -1 is returned. If the last frame had no errors or the + * decoder handle is NULL, 0 is returned, + * + * \param[in] decoder Decoder handle. + * \return Number of corrected bits or -1. See description for details. + */ +int lc3plus_dec_get_error_report(const LC3PLUS_Dec *decoder); +/*! This function returns an set of flags indicating whether the last frame + * would have been channel decodable in epmode m, m ranging from 1 to 4. Note that + * this information is not available in case the last frame was not channel + * decodable in which case the return value is 0. If the last frame would have + * been decodable in epmode m, m-1th of the return value will be 1. + * Otherwise, if the frame would not have been decodable or if this information + * cannot be retrieved, the m-1th bit of the return value will be 0. + */ +int lc3plus_dec_get_epok_flags(const LC3PLUS_Dec *decoder); + +/*! \} */ +#endif /* LC3plus */ diff --git a/lc3plus/lc3plus_fft.c b/lc3plus/lc3plus_fft.c new file mode 100644 index 0000000000000000000000000000000000000000..14f443f860d995f76b063ecbbe8636f54b52720f --- /dev/null +++ b/lc3plus/lc3plus_fft.c @@ -0,0 +1,99 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" +#include "fft/iis_fft.c" +#include "fft/iisfft.c" +#include "fft/cfft.c" + +void fft_init(Fft* fft, int length) +{ + HANDLE_IIS_FFT handle = NULL; + IIS_FFT_ERROR error = 0; + assert(length % 2 == 0); + + fft->length = length; + + error = LC3_IIS_CFFT_Create(&handle, length, IIS_FFT_FWD); + + assert(error == IIS_FFT_NO_ERROR); + fft->handle = handle; +} + +void fft_free(Fft* fft) +{ + IIS_FFT_ERROR error = 0; + + if (fft) { + error = LC3_IIS_CFFT_Destroy((HANDLE_IIS_FFT *) &fft->handle); + + assert(error == IIS_FFT_NO_ERROR); + memset(fft, 0, sizeof(*fft)); + } +} + +void real_fft_free(Fft* fft) +{ + IIS_FFT_ERROR error = 0; + + if (fft) { + error = LC3_IIS_RFFT_Destroy((HANDLE_IIS_FFT *) &fft->handle); + + assert(error == IIS_FFT_NO_ERROR); + memset(fft, 0, sizeof(*fft)); + } +} + +void real_fft_init(Fft* fft, LC3_INT32 length, HANDLE_IIS_FFT *handle) +{ + IIS_FFT_ERROR error = IIS_FFT_NO_ERROR; + assert(length % 4 == 0); /* due to current limitation of core complex FFTs*/ + + fft->length = length; + + error = LC3_IIS_RFFT_Create(handle, length, IIS_FFT_FWD); + assert(error == IIS_FFT_NO_ERROR); + fft->handle = *handle; +} + + +void real_ifft_init(Fft* fft, LC3_INT32 length, HANDLE_IIS_FFT *handle) +{ + IIS_FFT_ERROR error = IIS_FFT_NO_ERROR; + assert(length % 4 == 0); /* due to current limitation of core complex FFTs*/ + + fft->length = length; + + error = LC3_IIS_RFFT_Create(handle, length, IIS_FFT_BWD); + + assert(error == IIS_FFT_NO_ERROR); + fft->handle = *handle; +} + +void fft_apply(Fft* fft, const Complex* input, Complex* output) +{ + IIS_FFT_ERROR error = 0; + error = LC3_IIS_FFT_Apply_CFFT(fft->handle, input, output); + + assert(error == IIS_FFT_NO_ERROR); +} + + +void real_fft_apply(Fft* fft, const LC3_FLOAT* input, LC3_FLOAT* output) +{ + IIS_FFT_ERROR error = IIS_FFT_NO_ERROR; + + UNUSED(error); + + error = LC3_IIS_FFT_Apply_RFFT(fft->handle, input, output); + + assert(error == IIS_FFT_NO_ERROR); +} diff --git a/lc3plus/license.h b/lc3plus/license.h new file mode 100644 index 0000000000000000000000000000000000000000..d9d6c89675d4fadc0455effff0f0edae8fc2193c --- /dev/null +++ b/lc3plus/license.h @@ -0,0 +1,22 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "defines.h" + +static const char *const LICENSE = + "*******************************************************************************\n" + "* ETSI TS 103 634 V1.4.1 *\n" + "* Low Complexity Communication Codec Plus (LC3plus) *\n" + "* Floating Point Software V%i.%i.%iETSI, " __DATE__ " *\n" + "* Copyright licence is solely granted through ETSI Intellectual Property *\n" + "* Rights Policy, 3rd April 2019. No patent licence is granted by implication, *\n" + "* estoppel or otherwise. *\n" + "*******************************************************************************\n" + "\n"; diff --git a/lc3plus/ltpf_coder.c b/lc3plus/ltpf_coder.c new file mode 100644 index 0000000000000000000000000000000000000000..fac8c481c003aee4bf8fb8b2d03b921cd33a047f --- /dev/null +++ b/lc3plus/ltpf_coder.c @@ -0,0 +1,264 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +static LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len); + +LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len) +{ + LC3_INT max_i = 0, i = 0; + LC3_FLOAT max = 0; + + if (len <= 0) { + return -128; + } + + for (i = 0; i < len; i++) { + if (in[i] > max) { + max = in[i]; + max_i = i; + } + } + + return max_i; +} + +void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC3_INT pitch_ol, LC3_FLOAT pitch_ol_norm_corr, LC3_INT frame_dms, + LC3_FLOAT* mem_old_x, LC3_INT memLen, LC3_FLOAT* mem_norm_corr_past, LC3_INT* mem_on, LC3_FLOAT* mem_pitch, + LC3_INT* param, LC3_FLOAT* mem_norm_corr_past_past, LC3_INT* bits) +{ + LC3_FLOAT buffer[LTPF_MEMIN_LEN + LEN_12K8 + 1 + (LEN_12K8 >> 2)] = {0}, sum = 0, buf_tmp[MAX_LEN] = {0}, cor_up[MAX_LEN] = {0}, *x; + LC3_INT i = 0, j = 0, k = 0, n = 0, step = 0, N = 0, ltpf_active = 0, pitch_search_delta = 0, + pitch_search_upsamp = 0, pitch_search_L_interpol1 = 0, + t0_min = 0, t0_max = 0, t_min = 0, t_max = 0, temp2 = 0, t1 = 0, pitch_int = 0, pitch_fr = 0, midpoint = 0, + delta_up = 0, delta_down = 0, pitch_index = 0, gain = 0, acflen = 0; + LC3_FLOAT norm_corr = 0, cor[MAX_LEN] = {0}, cor_int[MAX_LEN] = {0}, currFrame[MAX_LEN] = {0}, predFrame[MAX_LEN] = {0}, sum1 = 0, sum2 = 0, sum3 = 0; + LC3_FLOAT pitch = 0; + + /* Signal Buffer */ + N = xLen - 1; + x = &buffer[memLen]; + + move_float(buffer, mem_old_x, memLen); + move_float(x, xin, xLen); + move_float(mem_old_x, &buffer[N], xLen + memLen - N); + + ltpf_active = 0; + norm_corr = 0; + + pitch_search_delta = 4; + pitch_search_upsamp = 4; + pitch_search_L_interpol1 = 4; + + if (pitch_ol_norm_corr > 0.6) { + /* Search Bounds */ + t0_min = pitch_ol - pitch_search_delta; + t0_max = pitch_ol + pitch_search_delta; + t0_min = MAX(t0_min, MIN_PITCH_12K8); + t0_max = MIN(t0_max, MAX_PITCH_12K8); + acflen = N; + + if (frame_dms == 25) + { + acflen = 2 * N; + x = x - N; + } + + /* Cross-Correlation Bounds */ + t_min = t0_min - pitch_search_L_interpol1; + t_max = t0_max + pitch_search_L_interpol1; + + /* Compute norm */ + sum1 = sum2 = 0; + for (j = 0; j < acflen; j++) { + sum1 += x[j] * x[j]; + sum2 += x[j - t_min] * x[j - t_min]; + } + + /* Compute Cross-Correlation */ + for (i = t_min; i <= t_max; i++) { + sum = 0; + for (j = 0; j < acflen; j++) { + sum += x[j] * x[j - i]; + } + + if (i > t_min) { + sum2 = sum2 + x[-i]*x[-i] + - x[acflen - 1 - ( i - 1 )]*x[acflen - 1 - ( i - 1 )]; + } + sum3 = LC3_SQRT(sum1 * sum2) + LC3_POW(10, -5); + norm_corr = sum / sum3; + + norm_corr = MAX(0, norm_corr); + cor[i - t_min] = norm_corr; + + } + + /* Find Integer Pitch-Lag */ + j = 0; + for (i = pitch_search_L_interpol1; i <= t_max - t_min - pitch_search_L_interpol1; i++) { + buf_tmp[j] = cor[i]; + j++; + } + + temp2 = searchMaxIndice(buf_tmp, j); + + t1 = temp2 + t0_min; + assert(t1 >= t0_min && t1 <= t0_max); + + /* Find Fractional Pitch-Lag */ + if (t1 >= RES2_PITCH_12K8) { + pitch_int = t1; + pitch_fr = 0; + } else { + j = 0; + + for (i = 0; i < pitch_search_upsamp * (t_max - t_min) + 1; i = i + pitch_search_upsamp) { + cor_up[i] = cor[j]; + j++; + } + + for (i = 0; i < pitch_search_upsamp * (t0_max - t0_min + 1); i++) { + sum = 0; + + k = 0; + for (j = i; j < i + 32; j++) { + sum += cor_up[j] * inter4_1[k]; + k++; + } + + cor_int[i] = sum; + } + + if (t1 >= RES4_PITCH_12K8) { + step = 2; + } else { + step = 1; + } + + midpoint = pitch_search_upsamp * (t1 - t0_min) + 1; + delta_up = pitch_search_upsamp - step; + + if (t1 == t0_min) { + delta_down = 0; + } else { + delta_down = pitch_search_upsamp - step; + } + + j = 0; + for (i = midpoint - delta_down - 1; i <= midpoint + delta_up; i = i + step) { + buf_tmp[j] = cor_int[i]; + j++; + } + + temp2 = searchMaxIndice(buf_tmp, ((midpoint + delta_up) - (midpoint - delta_down)) / step + 1); + pitch_fr = temp2 * step - delta_down; + + if (pitch_fr >= 0) { + pitch_int = t1; + } else { + pitch_int = t1 - 1; + pitch_fr = pitch_search_upsamp + pitch_fr; + } + } + + assert((pitch_int <= MAX_PITCH_12K8 && pitch_int >= RES2_PITCH_12K8 && pitch_fr == 0) || + (pitch_int < RES2_PITCH_12K8 && pitch_int >= RES4_PITCH_12K8 && (pitch_fr == 0 || pitch_fr == 2)) || + (pitch_int < RES4_PITCH_12K8 && pitch_int >= MIN_PITCH_12K8 && + (pitch_fr == 0 || pitch_fr == 1 || pitch_fr == 2 || pitch_fr == 3))); + + if (pitch_int < RES4_PITCH_12K8) { + pitch_index = pitch_int * 4 + pitch_fr - (MIN_PITCH_12K8 * 4); + } else if (pitch_int < RES2_PITCH_12K8) { + pitch_index = pitch_int * 2 + floor(pitch_fr / 2) - (RES4_PITCH_12K8 * 2) + ((RES4_PITCH_12K8 - MIN_PITCH_12K8) * 4); + } else { + pitch_index = pitch_int - RES2_PITCH_12K8 + ((RES4_PITCH_12K8 - MIN_PITCH_12K8) * 4) + ((RES2_PITCH_12K8 - RES4_PITCH_12K8) * 2); + } + + assert(pitch_index >= 0 && pitch_index < 512); + pitch = (LC3_FLOAT) pitch_int + (LC3_FLOAT) pitch_fr / 4.0; + + + for (n = 0; n < acflen; n++) + { + currFrame[n] = x[n + 1] * enc_inter_filter[0][0] + + x[n] * enc_inter_filter[0][1] + + x[n - 1] * enc_inter_filter[0][2]; + + predFrame[n] = x[n - pitch_int + 1] * enc_inter_filter[pitch_fr][0] + + x[n - pitch_int] * enc_inter_filter[pitch_fr][1] + + x[n - pitch_int - 1] * enc_inter_filter[pitch_fr][2] + + x[n - pitch_int - 2] * enc_inter_filter[pitch_fr][3]; + } + + /* Normalized Correlation */ + sum1 = sum2 = sum3 = 0; + + for (i = 0; i < acflen; i++) { + sum1 += currFrame[i] * predFrame[i]; + } + + for (i = 0; i < acflen; i++) { + sum2 += currFrame[i] * currFrame[i]; + } + + for (i = 0; i < acflen; i++) { + sum3 += predFrame[i] * predFrame[i]; + } + + sum2 = LC3_SQRT(sum2 * sum3) + LC3_POW(10, -5); + norm_corr = sum1 / sum2; + + assert(norm_corr >= -1.00001 && norm_corr <= 1.00001); + norm_corr = MIN(1, MAX(-1, norm_corr)); + if (norm_corr < 0) { + norm_corr = 0; + } + + if (ltpf_enable == 1) { + /* Decision if ltpf active */ + if ((*mem_on == 0 && (frame_dms == 100 || *mem_norm_corr_past_past > 0.94) && *mem_norm_corr_past > 0.94 && + norm_corr > 0.94) || + (*mem_on == 1 && norm_corr > 0.9) || + (*mem_on == 1 && LC3_FABS(pitch - *mem_pitch) < 2 && (norm_corr - *mem_norm_corr_past) > -0.1 && + norm_corr > 0.84)) { + ltpf_active = 1; + } + } + + gain = 4; + + } else { + gain = 0; + norm_corr = pitch_ol_norm_corr; + pitch = 0; + } + + if (gain > 0) { + param[0] = 1; + param[1] = ltpf_active; + param[2] = pitch_index; + *bits = 11; + } else { + zero_int(param, 3); + + *bits = 1; + } + + if (frame_dms < 100) { + *mem_norm_corr_past_past = *mem_norm_corr_past; + } + + *mem_norm_corr_past = norm_corr; + *mem_on = ltpf_active; + *mem_pitch = pitch; +} diff --git a/lc3plus/ltpf_decoder.c b/lc3plus/ltpf_decoder.c new file mode 100644 index 0000000000000000000000000000000000000000..a40c85213a13afa678bd1e4cbff6a62b5169086a --- /dev/null +++ b/lc3plus/ltpf_decoder.c @@ -0,0 +1,356 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT fs, LC3_FLOAT* mem_old_x, LC3_FLOAT* mem_old_y, + LC3_INT* mem_pitch_int, LC3_INT* mem_pitch_fr, LC3_FLOAT* mem_gain, LC3_INT* mem_beta_idx, LC3_INT bfi, + LC3_INT* param, LC3_INT* mem_param, LC3_INT conf_beta_idx, LC3_FLOAT conf_beta, LC3_INT concealMethod, + LC3_FLOAT damping + , LC3_INT *mem_ltpf_active +) +{ + LC3_INT i = 0, j = 0, n = 0, N = 0, L_past_x = 0, N4 = 0, N34 = 0, + pitch_int = 0, pitch_fr = 0, p1 = 0, p2 = 0, L_past_y = 0, inter_len = 0, tilt_len = 0, + tilt_len_r = 0, inter_len_r = 0, old_x_len = 0, old_y_len = 0; + + LC3_FLOAT conf_alpha = 0, gain = 0, a1[MAX_LEN] = {0}, a2[MAX_LEN] = {0}, b1[MAX_LEN] = {0}, b2[MAX_LEN] = {0}, + buf_x[4 * MAX_LEN] = {0}, buf_y[4 * MAX_LEN] = {0}, buf_z[4 * MAX_LEN] = {0}, pitch = 0, sum1 = 0, sum2 = 0; + + const LC3_FLOAT *inter_filter[4], *tilt_filter[4]; + + + conf_alpha = 0.85; + + if (bfi != 1) { + /* Decode pitch */ + if (param[0] == 1) { + if (param[2] < (RES4_PITCH_12K8 - MIN_PITCH_12K8) * 4) { + pitch_int = MIN_PITCH_12K8 + floor(param[2] / 4); + pitch_fr = param[2] - ((pitch_int - MIN_PITCH_12K8) * 4); + } else if (param[2] < ((RES4_PITCH_12K8 - MIN_PITCH_12K8) * 4) + ((RES2_PITCH_12K8 - RES4_PITCH_12K8) * 2)) { + param[2] = param[2] - ((RES4_PITCH_12K8 - MIN_PITCH_12K8) * 4); + pitch_int = RES4_PITCH_12K8 + floor(param[2] / 2); + pitch_fr = param[2] - ((pitch_int - RES4_PITCH_12K8) * 2); + pitch_fr = pitch_fr * 2; + } else { + pitch_int = + param[2] + (RES2_PITCH_12K8 - ((RES4_PITCH_12K8 - MIN_PITCH_12K8) * 4) - ((RES2_PITCH_12K8 - RES4_PITCH_12K8) * 2)); + pitch_fr = 0; + } + + pitch = ((LC3_FLOAT)pitch_int + (LC3_FLOAT)pitch_fr / 4.0) * (LC3_FLOAT)fs / 12800.0; + pitch = round(pitch * 4.0) / 4.0; + pitch_int = floor(pitch); + pitch_fr = (LC3_INT)((pitch - (LC3_FLOAT)pitch_int) * 4.0); + } else { + pitch_int = 0; + pitch_fr = 0; + } + + /* Decode gain */ + if (conf_beta_idx < 0) { + param[1] = 0; + } + + if (param[1] == 1) { + gain = conf_beta; + } else { + gain = 0; + } + } + else if (concealMethod > 0) { + if (conf_beta_idx < 0) { + if (mem_param[1] && *mem_beta_idx >= 0) + { + conf_beta_idx = *mem_beta_idx; + } + } + + memmove(param, mem_param, sizeof(LC3_INT32) * 3); + if (concealMethod == 2) + { + /* cause the ltpf to "fade_out" and only filter during initial 2.5 ms and then its buffer during 7.5 ms */ + assert(bfi == 1); + param[1] = 0; /* ltpf_active = 0 */ + } + + pitch_int = *mem_pitch_int; + pitch_fr = *mem_pitch_fr; + gain = (LC3_FLOAT) *mem_gain * damping; + } + + if ((conf_beta <= 0) && (*mem_ltpf_active == 0)) + { + if (fs == 8000 || fs == 16000) { + tilt_len = 4 - 2; + } + else if (fs == 24000) { + tilt_len = 6 - 2; + } + else if (fs == 32000) { + tilt_len = 8 - 2; + } + else if (fs == 44100 || fs == 48000) { + tilt_len = 12 - 2; + } + + N = xLen; + old_x_len = tilt_len; + inter_len = MAX(fs, 16000) / 8000; + old_y_len = ceilf((LC3_FLOAT)228.0 * fs / 12800.0) + inter_len; /* 228.0 needed to make use of ceil */ + + move_float(mem_old_y, &mem_old_y[N], (old_y_len - N)); + move_float(&mem_old_y[old_y_len - N], x, N); + move_float(mem_old_x, &x[N - old_x_len], old_x_len); + + *mem_ltpf_active = 0; + } + else + { + inter_len_r = 0; tilt_len_r = 0; + if (fs == 8000 || fs == 16000) { + inter_filter[0] = conf_inter_filter_16[0]; + inter_filter[1] = conf_inter_filter_16[1]; + inter_filter[2] = conf_inter_filter_16[2]; + inter_filter[3] = conf_inter_filter_16[3]; + inter_len_r = 4; + + tilt_filter[0] = conf_tilt_filter_16[0]; + tilt_filter[1] = conf_tilt_filter_16[1]; + tilt_filter[2] = conf_tilt_filter_16[2]; + tilt_filter[3] = conf_tilt_filter_16[3]; + tilt_len = 4 - 2; + tilt_len_r = 3; + } else if (fs == 24000) { + inter_filter[0] = conf_inter_filter_24[0]; + inter_filter[1] = conf_inter_filter_24[1]; + inter_filter[2] = conf_inter_filter_24[2]; + inter_filter[3] = conf_inter_filter_24[3]; + inter_len_r = 6; + + tilt_filter[0] = conf_tilt_filter_24[0]; + tilt_filter[1] = conf_tilt_filter_24[1]; + tilt_filter[2] = conf_tilt_filter_24[2]; + tilt_filter[3] = conf_tilt_filter_24[3]; + tilt_len = 6 - 2; + tilt_len_r = 5; + } else if (fs == 32000) { + inter_filter[0] = conf_inter_filter_32[0]; + inter_filter[1] = conf_inter_filter_32[1]; + inter_filter[2] = conf_inter_filter_32[2]; + inter_filter[3] = conf_inter_filter_32[3]; + inter_len_r = 8; + + tilt_filter[0] = conf_tilt_filter_32[0]; + tilt_filter[1] = conf_tilt_filter_32[1]; + tilt_filter[2] = conf_tilt_filter_32[2]; + tilt_filter[3] = conf_tilt_filter_32[3]; + tilt_len = 8 - 2; + tilt_len_r = 7; + } else if (fs == 44100 || fs == 48000) { + inter_filter[0] = conf_inter_filter_48[0]; + inter_filter[1] = conf_inter_filter_48[1]; + inter_filter[2] = conf_inter_filter_48[2]; + inter_filter[3] = conf_inter_filter_48[3]; + inter_len_r = 12; + + tilt_filter[0] = conf_tilt_filter_48[0]; + tilt_filter[1] = conf_tilt_filter_48[1]; + tilt_filter[2] = conf_tilt_filter_48[2]; + tilt_filter[3] = conf_tilt_filter_48[3]; + tilt_len = 12 - 2; + tilt_len_r = 11; + } + + inter_len = MAX(fs, 16000) / 8000; + + /* Init buffers */ + N = xLen; + old_x_len = tilt_len; + old_y_len = ceilf(228.0 * fs / 12800.0) + inter_len; + L_past_x = old_x_len; + move_float(buf_x, mem_old_x, old_x_len); + move_float(&buf_x[old_x_len], x, xLen); + L_past_y = old_y_len; + move_float(buf_y, mem_old_y, old_y_len); + zero_float(&buf_y[old_y_len], xLen); + + N4 = fs * 0.0025; + N34 = N - N4; + + /* Init filter parameters */ + if (mem_param[1] == 1) { + for (i = 0; i < inter_len_r; i++) { + a1[i] = *mem_gain * inter_filter[*mem_pitch_fr][i]; + } + + for (i = 0; i < tilt_len_r; i++) { + b1[i] = conf_alpha * (*mem_gain) * tilt_filter[*mem_beta_idx][i]; + } + + p1 = *mem_pitch_int; + } + + if (param[1] == 1) { + for (i = 0; i < tilt_len_r; i++) { + b2[i] = conf_alpha * gain * tilt_filter[conf_beta_idx][i]; + } + + for (i = 0; i < inter_len_r; i++) { + a2[i] = gain * inter_filter[pitch_fr][i]; + } + + p2 = pitch_int; + } + + /* First quarter of the current frame: cross-fading */ + if (mem_param[1] == 0 && param[1] == 0) { + memmove(&buf_y[L_past_y], &buf_x[L_past_x], sizeof(LC3_FLOAT) * N4); + + } else if (mem_param[1] == 1 && param[1] == 0) { + for (n = 0; n < N4; n++) { + sum1 = 0; + sum2 = 0; + j = 0; + for (i = L_past_x + n; i >= L_past_x + n - tilt_len; i--) { + sum1 += b1[j] * buf_x[i]; + j++; + } + + j = 0; + for (i = L_past_y + n - p1 + inter_len - 1; i >= L_past_y + n - p1 - inter_len; i--) { + sum2 += a1[j] * buf_y[i]; + j++; + } + + buf_y[L_past_y + n] = buf_x[L_past_x + n] - (((LC3_FLOAT)N4 - (LC3_FLOAT)n) / (LC3_FLOAT)N4) * sum1 + + (((LC3_FLOAT)N4 - (LC3_FLOAT)n) / (LC3_FLOAT)N4) * sum2; + } + + } else if (mem_param[1] == 0 && param[1] == 1) { + for (n = 0; n < N4; n++) { + sum1 = 0; + sum2 = 0; + j = 0; + for (i = L_past_x + n; i >= L_past_x + n - tilt_len; i--) { + sum1 += b2[j] * buf_x[i]; + j++; + } + + j = 0; + for (i = L_past_y + n - p2 + inter_len - 1; i >= L_past_y + n - p2 - inter_len; i--) { + sum2 += a2[j] * buf_y[i]; + j++; + } + + buf_y[L_past_y + n] = buf_x[L_past_x + n] - ((LC3_FLOAT)n / (LC3_FLOAT)N4) * sum1 + ((LC3_FLOAT)n / (LC3_FLOAT)N4) * sum2; + } + } else if (*mem_pitch_int == pitch_int && *mem_pitch_fr == pitch_fr) { + for (n = 0; n < N4; n++) { + sum1 = 0; + sum2 = 0; + j = 0; + for (i = L_past_x + n; i >= L_past_x + n - tilt_len; i--) { + sum1 += b2[j] * buf_x[i]; + j++; + } + + j = 0; + for (i = L_past_y + n - p2 + inter_len - 1; i >= L_past_y + n - p2 - inter_len; i--) { + sum2 += a2[j] * buf_y[i]; + j++; + } + + buf_y[L_past_y + n] = buf_x[L_past_x + n] - sum1 + sum2; + } + } else { + for (n = 0; n < N4; n++) { + sum1 = 0; + sum2 = 0; + j = 0; + for (i = L_past_x + n; i >= L_past_x + n - tilt_len; i--) { + sum1 += b1[j] * buf_x[i]; + j++; + } + + j = 0; + for (i = L_past_y + n - p1 + inter_len - 1; i >= L_past_y + n - p1 - inter_len; i--) { + sum2 += a1[j] * buf_y[i]; + j++; + } + + buf_y[L_past_y + n] = buf_x[L_past_x + n] - (((LC3_FLOAT)N4 - (LC3_FLOAT)n) / (LC3_FLOAT)N4) * sum1 + + (((LC3_FLOAT)N4 - (LC3_FLOAT)n) / (LC3_FLOAT)N4) * sum2; + } + + memmove(buf_z, buf_y, sizeof(LC3_FLOAT) * 4 * MAX_LEN); + + for (n = 0; n < N4; n++) { + sum1 = 0; + sum2 = 0; + j = 0; + for (i = L_past_y + n; i >= L_past_y + n - tilt_len; i--) { + sum1 += b2[j] * buf_z[i]; + j++; + } + + j = 0; + for (i = L_past_y + n - p2 + inter_len - 1; i >= L_past_y + n - p2 - inter_len; i--) { + sum2 += a2[j] * buf_y[i]; + j++; + } + + buf_y[L_past_y + n] = buf_z[L_past_y + n] - ((LC3_FLOAT)n / (LC3_FLOAT)N4) * sum1 + ((LC3_FLOAT)n / (LC3_FLOAT)N4) * sum2; + } + } + + /* Second quarter of the current frame */ + if (param[1] == 0) { + memmove(&buf_y[L_past_y + N4], &buf_x[L_past_x + N4], + sizeof(LC3_FLOAT) * ((L_past_x + N4 + N34) - (L_past_x + N4))); + } else { + for (n = 0; n < N34; n++) { + sum1 = 0; + sum2 = 0; + j = 0; + for (i = L_past_x + N4 + n; i >= L_past_x + n + N4 - tilt_len; i--) { + sum1 += b2[j] * buf_x[i]; + j++; + } + + j = 0; + for (i = L_past_y + N4 + n - p2 + inter_len - 1; i >= L_past_y + N4 + n - p2 - inter_len; i--) { + sum2 += a2[j] * buf_y[i]; + j++; + } + + buf_y[L_past_y + N4 + n] = buf_x[L_past_x + N4 + n] - sum1 + sum2; + } + } + + /* Output */ + move_float(y, &buf_y[L_past_y], N); + + /* Update memory */ + move_float(mem_old_x, &buf_x[N], old_x_len); + move_float(mem_old_y, &buf_y[N], old_y_len); + + *mem_ltpf_active = (conf_beta > 0); + } + + /* Update ltpf param memory */ + move_int(mem_param, param, 3); + *mem_pitch_int = pitch_int; + *mem_pitch_fr = pitch_fr; + *mem_gain = gain; + *mem_beta_idx = conf_beta_idx; +} diff --git a/lc3plus/mdct.c b/lc3plus/mdct.c new file mode 100644 index 0000000000000000000000000000000000000000..11618b9465d4e3303f4251a50142f1f3b2954f31 --- /dev/null +++ b/lc3plus/mdct.c @@ -0,0 +1,128 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +static const LC3_FLOAT* mdct_window(LC3_INT length, LC3_INT frame_dms, LC3_INT hrmode) +{ + if (frame_dms == 100) { + switch (length) { + case 80: + return MDCT_WINS_10ms[hrmode][0]; + case 160: + return MDCT_WINS_10ms[hrmode][1]; + case 240: + return MDCT_WINS_10ms[hrmode][2]; + case 320: + return MDCT_WINS_10ms[hrmode][3]; + case 480: + return MDCT_WINS_10ms[hrmode][4]; + case 960: + return MDCT_WINS_10ms[hrmode][5]; + default: + return NULL; + } + } + else if (frame_dms == 50) { + switch (length) { + case 40: + return MDCT_WINS_5ms[hrmode][0]; + case 80: + return MDCT_WINS_5ms[hrmode][1]; + case 120: + return MDCT_WINS_5ms[hrmode][2]; + case 160: + return MDCT_WINS_5ms[hrmode][3]; + case 240: + return MDCT_WINS_5ms[hrmode][4]; + case 480: + return MDCT_WINS_5ms[hrmode][5]; + default: + return NULL; + } + } + else if (frame_dms == 25) { + switch (length) { + case 20: + return MDCT_WINS_2_5ms[hrmode][0]; + case 40: + return MDCT_WINS_2_5ms[hrmode][1]; + case 60: + return MDCT_WINS_2_5ms[hrmode][2]; + case 80: + return MDCT_WINS_2_5ms[hrmode][3]; + case 120: + return MDCT_WINS_2_5ms[hrmode][4]; + case 240: + return MDCT_WINS_2_5ms[hrmode][5]; + default: + return NULL; + } + } + return NULL; +} + +void mdct_init(Mdct* mdct, LC3_INT length, LC3_INT frame_dms, LC3_INT fs_idx, LC3_INT hrmode) +{ + if (frame_dms == 100) { + mdct->leading_zeros = MDCT_la_zeroes[fs_idx]; + } + else if (frame_dms == 50) { + mdct->leading_zeros = MDCT_la_zeroes_5ms[fs_idx]; + } + else if (frame_dms == 25) { + mdct->leading_zeros = MDCT_la_zeroes_2_5ms[fs_idx]; + } + else { + assert(!"invalid frame_ms"); + } + + mdct->length = length; + mdct->mem_length = length - mdct->leading_zeros; + mdct->window = mdct_window(length, frame_dms, hrmode); + mdct->mem = calloc(sizeof(*mdct->mem), mdct->mem_length); + dct4_init(&mdct->dct, length); +} + +void mdct_free(Mdct* mdct) +{ + if (mdct) { + free(mdct->mem); + dct4_free(&mdct->dct); + memset(mdct, 0, sizeof(*mdct)); + } +} + +void mdct_apply(const LC3_FLOAT* input, LC3_FLOAT* output, Mdct* mdct) +{ + LC3_FLOAT tmp[MAX_LEN * 2] = {0}; + LC3_INT i = 0; + LC3_INT hlen; + + move_float(tmp, mdct->mem, mdct->mem_length); + move_float(tmp + mdct->mem_length, input, mdct->length); + zero_float(tmp + mdct->length * 2 - mdct->leading_zeros, mdct->leading_zeros); + move_float(mdct->mem, tmp + mdct->length, mdct->mem_length); + + mult_vec(tmp, mdct->window, mdct->length * 2); + + hlen = mdct->length / 2; + for (i = 0; i < hlen; i++) { + output[i] = -tmp[hlen * 3 - i - 1] - tmp[hlen * 3 + i]; + output[hlen + i] = tmp[i] - tmp[hlen * 2 - i - 1]; + } + + move_float(tmp, output, mdct->length); + + dct4_apply(&mdct->dct, tmp, output); +} + +void processMdct_fl(LC3_FLOAT* in, LC3_FLOAT* out, Mdct* mdctStruct) { mdct_apply(in, out, mdctStruct); } diff --git a/lc3plus/mdct_shaping.c b/lc3plus/mdct_shaping.c new file mode 100644 index 0000000000000000000000000000000000000000..18761925042015e48be9b8e9f9bbb2ea46a0e376 --- /dev/null +++ b/lc3plus/mdct_shaping.c @@ -0,0 +1,23 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +void processMdctShaping_fl(LC3_FLOAT x[], LC3_FLOAT scf[], const LC3_INT bands_offset[], LC3_INT fdns_npts) +{ + LC3_INT i = 0, j = 0; + + for (i = 0; i < fdns_npts; i++) { + for (; j < bands_offset[i + 1]; j++) { + x[j] = x[j] * scf[i]; + } + } +} diff --git a/lc3plus/near_nyquist_detector.c b/lc3plus/near_nyquist_detector.c new file mode 100644 index 0000000000000000000000000000000000000000..ce94351302bcce089ac5c764420ae8fb4487cff2 --- /dev/null +++ b/lc3plus/near_nyquist_detector.c @@ -0,0 +1,38 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" +#include "options.h" + + +void processNearNyquistdetector_fl(LC3_INT16* near_nyquist_flag, const LC3_INT fs_idx, const LC3_INT near_nyquist_index, + const LC3_INT bands_number, const LC3_FLOAT* ener) +{ + *near_nyquist_flag = 0; + + if (fs_idx < 4) + { + LC3_INT i = 0; + LC3_FLOAT ener_low = FLT_EPSILON, ener_high = 0; + + for (i=0; i NN_thresh * ener_low){ + *near_nyquist_flag = 1; + } + } +} diff --git a/lc3plus/noise_factor.c b/lc3plus/noise_factor.c new file mode 100644 index 0000000000000000000000000000000000000000..c5aa582e456812b02a60d7a27d3ad935e55fb210 --- /dev/null +++ b/lc3plus/noise_factor.c @@ -0,0 +1,112 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +void processNoiseFactor_fl(LC3_INT* fac_ns_idx, LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gg, LC3_INT BW_cutoff_idx, LC3_INT frame_dms, + LC3_INT target_bytes +) +{ + LC3_INT sumZeroLines = 0, kZeroLines = 0, startOffset = 0, nTransWidth = 0, end = 0, start = 0, i = 0, j = 0, k = 0, + allZeros = 0, m = 0; + LC3_FLOAT fac_ns_unq = 0, mean = 0, idx = 0, nsf1 = 0, nsf2 = 0; + LC3_INT zeroLines[MAX_LEN] = {0}, zL1[MAX_LEN] = {0}, zL2[MAX_LEN] = {0}; + + switch (frame_dms) + { + case 25: + nTransWidth = 4; + startOffset = 6; + break; + case 50: + nTransWidth = 4; + startOffset = 12; + break; + case 100: + nTransWidth = 8; + startOffset = 24; + break; + } + + for (k = startOffset; k < BW_cutoff_idx; k++) { + allZeros = 1; + + start = k - (nTransWidth - 2) / 2; + end = MIN(BW_cutoff_idx - 1, k + (nTransWidth - 2) / 2); + + for (i = start; i <= end; i++) { + if (xq[i] != 0) { + allZeros = 0; + } + } + + if (allZeros == 1) { + zeroLines[j] = k + 1; + kZeroLines++; + j++; + } + } + + for (i = 0; i < kZeroLines; i++) { + sumZeroLines += zeroLines[i]; + } + + if (sumZeroLines > 0) { + for (j = 0; j < kZeroLines; j++) { + mean += LC3_FABS(x[zeroLines[j] - 1]); + } + + fac_ns_unq = mean / (gg * kZeroLines); + } else { + fac_ns_unq = 0; + } + + if (kZeroLines > 0) + { + if (target_bytes <= 20 && frame_dms == 100) { + j = 0, k = 0; + m = floor(sumZeroLines / kZeroLines); + + for (i = 0; i < kZeroLines; i++) { + if (zeroLines[i] <= m) { + zL1[j] = zeroLines[i]; + j++; + } + + if (zeroLines[i] > m) { + zL2[k] = zeroLines[i]; + k++; + } + } + + mean = 0; + for (i = 0; i < j; i++) { + mean += LC3_FABS(x[zL1[i] - 1]) / gg; + } + + nsf1 = mean / j; + + mean = 0; + for (i = 0; i < k; i++) { + mean += LC3_FABS(x[zL2[i] - 1]) / gg; + } + + nsf2 = mean / k; + + fac_ns_unq = MIN(nsf1, nsf2); + } + } + + idx = round(8 - 16 * fac_ns_unq); + idx = MIN(MAX(idx, 0), 7); + + *fac_ns_idx = idx; +} diff --git a/lc3plus/noise_filling.c b/lc3plus/noise_filling.c new file mode 100644 index 0000000000000000000000000000000000000000..7fac5e0f72de7b66130fcbbd93ee99e794543d3e --- /dev/null +++ b/lc3plus/noise_filling.c @@ -0,0 +1,81 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, LC3_INT bw_stopband, LC3_INT frame_dms, LC3_FLOAT fac_ns_pc, LC3_INT spec_inv_idx) +{ + LC3_INT zeroLines[MAX_LEN] = {0}; + LC3_INT nTransWidth = 0, startOffset = 0, i = 0, j = 0, k = 0, start = 0, end = 0, allZeros = 0, kZeroLines = 0; + LC3_FLOAT fac_ns = 0; + + switch (frame_dms) + { + case 25: + nTransWidth = 1; + startOffset = 6; + break; + case 50: + nTransWidth = 1; + startOffset = 12; + break; + case 100: + nTransWidth = 3; + startOffset = 24; + break; + } + + fac_ns = (8.0 - fac_ns_idx) / 16.0; + + j = 0; + + for (k = startOffset; k < bw_stopband; k++) { + allZeros = 1; + + start = k - nTransWidth; + end = MIN(bw_stopband - 1, k + nTransWidth); + + for (i = start; i <= end; i++) { + if (xq[i] != 0) { + allZeros = 0; + } + } + + if (allZeros == 1) { + zeroLines[j] = k; + kZeroLines++; + j++; + } + } + + for (k = 0; k < kZeroLines; k++) { + nfseed = (13849 + (nfseed + 32768) * 31821) & 65535; + nfseed -= 32768; + + if (nfseed >= 0) { + if (zeroLines[k] < spec_inv_idx) + { + xq[zeroLines[k]] = fac_ns; + } else { + xq[zeroLines[k]] = fac_ns_pc; + } + } else { + if (zeroLines[k] < spec_inv_idx) + { + xq[zeroLines[k]] = -fac_ns; + } else { + xq[zeroLines[k]] = -fac_ns_pc; + } + } + } + + return; +} diff --git a/lc3plus/olpa.c b/lc3plus/olpa.c new file mode 100644 index 0000000000000000000000000000000000000000..6bec50952e5966214080221eb36e156b9ba0b176 --- /dev/null +++ b/lc3plus/olpa.c @@ -0,0 +1,144 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +static void filter_olpa(LC3_FLOAT* in, LC3_FLOAT* out, const LC3_FLOAT* buf, LC3_FLOAT len_buf, LC3_INT len_input); +static LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len); + +void filter_olpa(LC3_FLOAT* in, LC3_FLOAT* out, const LC3_FLOAT* buf, LC3_FLOAT len_buf, LC3_INT len_input) +{ + LC3_INT i = 0, j = 0; + LC3_FLOAT sum = 0; + /* a = 1, so denominator == 1, nothing to do here */ + + for (i = 0; i < len_input; i++) { + j = 0; + sum = 0; + for (j = 0; (j < len_buf) && (j <= i); j++) { + sum += buf[j] * in[i - j]; + } + + out[i] = sum; + } +} + +LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len) +{ + LC3_INT max_i = 0, i = 0; + LC3_FLOAT max = in[0]; + + if (len <= 0) { + return -128; + } + + for (i = 0; i < len; i++) { + if (in[i] > max) { + max = in[i]; + max_i = i; + } + } + + return max_i; +} + +void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4, LC3_INT* mem_old_T0, LC3_INT* T0_out, + LC3_FLOAT* normcorr_out, LC3_INT len, LC3_INT frame_dms) +{ + LC3_FLOAT norm_corr = 0, sum = 0, sum0 = 0, sum1 = 0, sum2 = 0, norm_corr2 = 0, *s6k4; + LC3_FLOAT buf[LEN_6K4 + MAX_PITCH_6K4] = {0}, filt_out[LEN_12K8 + 3] = {0}, d_wsp[LEN_6K4] = {0}, R0[RANGE_PITCH_6K4] = {0}, R[RANGE_PITCH_6K4] = {0}; /* constant length */ + LC3_INT i = 0, j = 0, len2 = 0, T0 = 0, T02 = 0, min_pitch = 0, max_pitch = 0, L = 0, mem_in_len = 0, acflen = 0; + + + mem_in_len = MAX_PITCH_6K4; + len2 = len / 2; + acflen = len2; + if (frame_dms == 25) + { + mem_in_len += 16; + acflen += 16; + } + + /* Downsampling */ + move_float(buf, mem_s12k8, 3); + move_float(&buf[3], s_12k8, len); + move_float(mem_s12k8, &buf[len], 3); + filter_olpa(buf, filt_out, olpa_down2, 5, len + 3); + for (i = 4, j = 0; i < len + 3; i = i + 2) { + d_wsp[j] = filt_out[i]; + j++; + } + + /* Compute autocorrelation */ + s6k4 = &buf[mem_in_len]; + move_float(buf, mem_s6k4, mem_in_len); + move_float(s6k4, d_wsp, len2); + move_float(mem_s6k4, &buf[len2], mem_in_len); + if (frame_dms == 25) + { + s6k4 = s6k4 - 16; + } + for (i = MIN_PITCH_6K4; i <= MAX_PITCH_6K4; i++) { + sum = 0; + for (j = 0; j < acflen; j++) { + sum += s6k4[j] * s6k4[j - i]; + } + R0[i - MIN_PITCH_6K4] = sum; + } + + /* Weight autocorrelation and find maximum */ + move_float(R, R0, RANGE_PITCH_6K4); + for (i = 0; i < RANGE_PITCH_6K4; i++) { + R0[i] = R0[i] * olpa_acw[i]; + } + L = searchMaxIndice(R0, RANGE_PITCH_6K4); + T0 = L + MIN_PITCH_6K4; + + /* Compute normalized correlation */ + sum0 = sum1 = sum2 = 0; + for (i = 0; i < acflen; i++) { + sum0 += s6k4[i] * s6k4[i - T0]; + sum1 += s6k4[i - T0] * s6k4[i - T0]; + sum2 += s6k4[i] * s6k4[i]; + } + sum1 = sum1 * sum2; + sum1 = LC3_SQRT(sum1) + LC3_POW(10.0, -5.0); + norm_corr = sum0 / sum1; + norm_corr = MAX(0, norm_corr); + + /* Second try in the neighborhood of the previous pitch */ + min_pitch = MAX(MIN_PITCH_6K4, *mem_old_T0 - 4); + max_pitch = MIN(MAX_PITCH_6K4, *mem_old_T0 + 4); + L = searchMaxIndice(&R[min_pitch - MIN_PITCH_6K4], max_pitch - min_pitch + 1 ); + T02 = L + min_pitch; + + if (T02 != T0) { + sum0 = sum1 = sum2 = 0; + for (i = 0; i < acflen; i++) { + sum0 += s6k4[i] * s6k4[i - T02]; + sum1 += s6k4[i - T02] * s6k4[i - T02]; + sum2 += s6k4[i] * s6k4[i]; + } + sum1 = sum1 * sum2; + sum1 = LC3_SQRT(sum1) + LC3_POW(10.0, -5.0); + norm_corr2 = sum0 / sum1; + norm_corr2 = MAX(0, norm_corr2); + + if (norm_corr2 > (norm_corr * 0.85)) { + T0 = T02; + norm_corr = norm_corr2; + } + } + + *mem_old_T0 = T0; + *T0_out = T0 * 2.0; + *normcorr_out = norm_corr; +} diff --git a/lc3plus/pc_apply.c b/lc3plus/pc_apply.c new file mode 100644 index 0000000000000000000000000000000000000000..1d1bc40005b4d9382cb951570a6dbf569d5ab19a --- /dev/null +++ b/lc3plus/pc_apply.c @@ -0,0 +1,73 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + + +void processPcApply_fl(LC3_FLOAT *q_res, LC3_FLOAT *q_old_res, LC3_FLOAT *q_d_prev, LC3_INT32 spec_inv_idx, LC3_INT32 yLen, LC3_INT32 gg_idx, LC3_INT32 gg_idx_off, LC3_FLOAT *prev_gg, LC3_FLOAT *fac, LC3_INT32 *pc_nbLostCmpt) +{ + LC3_FLOAT gg, mean_nrg_low, mean_nrg_high, ener_prev, ener_curr, fac_local; + LC3_INT32 i; + + ener_prev = 0; ener_curr = 0; mean_nrg_low = 0; mean_nrg_high = 0; + + *pc_nbLostCmpt = *pc_nbLostCmpt + 1; + + assert(spec_inv_idx > 1); + + gg = LC3_POW(10, (((LC3_FLOAT) (gg_idx + gg_idx_off)) / 28.0)); + + for (i = 0; i < spec_inv_idx; i++) + { + mean_nrg_low += LC3_POW(q_d_prev[i], 2); + } + + mean_nrg_low /= (LC3_FLOAT) spec_inv_idx; + + if (spec_inv_idx < yLen) + { + for (i = spec_inv_idx; i < yLen; i++) + { + mean_nrg_high += LC3_POW(q_d_prev[i], 2); + } + } + + mean_nrg_high /= (LC3_FLOAT) (yLen - spec_inv_idx); + + for (i = 0; i < spec_inv_idx; i++) + { + ener_prev += LC3_POW(q_old_res[i], 2); + ener_curr += LC3_POW(q_res[i], 2); + } + + *fac = 1; + if (ener_prev > 0) + { + *fac = LC3_SQRT(ener_curr / ener_prev); + } + + fac_local = *fac; + if (mean_nrg_low <= mean_nrg_high || ener_prev * LC3_POW(*prev_gg, 2) <= ener_curr * LC3_POW(gg, 2)) + { + fac_local = *prev_gg / gg; + } + + for (i = spec_inv_idx; i < yLen; i++) + { + q_res[i] = q_old_res[i] * fac_local; + + if (LC3_FABS(q_res[i]) < (1 - 0.375)) + { + q_res[i] = 0; + } + } +} + diff --git a/lc3plus/pc_classify.c b/lc3plus/pc_classify.c new file mode 100644 index 0000000000000000000000000000000000000000..71196edb89692cf1ebdbf8a1508e31174e92b8ae --- /dev/null +++ b/lc3plus/pc_classify.c @@ -0,0 +1,170 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + + +LC3_FLOAT pc_peak_detector(LC3_FLOAT *q_d_prev, LC3_INT32 yLen); + +void processPcClassify_fl(LC3_INT32 pitch_present, LC3_INT32 frame_dms, LC3_FLOAT *q_d_prev, LC3_FLOAT *q_old_res, LC3_INT32 yLen, LC3_INT32 spec_inv_idx, LC3_FLOAT stab_fac, LC3_INT32 *bfi) +{ + LC3_INT32 maxPitchBin, xover, i; + LC3_FLOAT part_nrg, full_nrg; + + part_nrg = 0; full_nrg = 0; + + if (spec_inv_idx < (4 * frame_dms / 10)) + { + if (stab_fac < 0.5) + { + *bfi = 1; + } else if (pitch_present == 1) + { + maxPitchBin = 8; + if (frame_dms == 50) + { + maxPitchBin = 4; + } + xover = pc_peak_detector(q_d_prev, yLen); + if (spec_inv_idx < xover || spec_inv_idx < maxPitchBin) + { + *bfi = 1; + } + } else { + for (i = 0; i < spec_inv_idx; i++) + { + part_nrg += LC3_POW(q_old_res[i], 2); + } + + for (i = 0; i < yLen; i++) + { + full_nrg += LC3_POW(q_old_res[i], 2); + } + + if (part_nrg < (0.3 * full_nrg)) + { + *bfi = 1; + } + } + } +} + +LC3_FLOAT pc_peak_detector(LC3_FLOAT *q_d_prev, LC3_INT32 yLen) +{ + LC3_INT32 block_size, thresh1, i, peak, j, k; + LC3_FLOAT fac, mean_block_nrg, cur_max, block_cent, maxPeak, next_max, prev_max; + + mean_block_nrg = 0; + + block_size = 3; + thresh1 = 8; + fac = 0.3; + + for (i = 0; i < yLen; i++) + { + mean_block_nrg += LC3_POW(q_d_prev[i], 2); + } + + mean_block_nrg /= yLen; + + maxPeak = 0; + peak = 0; + + if (LC3_FABS(q_d_prev[0]) > LC3_FABS(q_d_prev[1])) + { + block_cent = LC3_POW(q_d_prev[0], 2) + LC3_POW(q_d_prev[1], 2); + + if ((block_cent / block_size) > (thresh1 * mean_block_nrg)) + { + cur_max = MAX(LC3_FABS(q_d_prev[0]), LC3_FABS(q_d_prev[1])); + next_max = array_max_abs(&q_d_prev[2], 3); + + if (cur_max > next_max) + { + maxPeak = block_cent; + peak = 1; + } + } + } + + for (i = 0; i < block_size; i++) + { + if ((LC3_FABS(q_d_prev[i + 1]) >= LC3_FABS(q_d_prev[i])) && LC3_FABS(q_d_prev[i + 1]) >= LC3_FABS(q_d_prev[i + 2])) + { + block_cent = 0; + for (j = i; j < i + block_size; j++) + { + block_cent += LC3_POW(q_d_prev[j], 2); + } + + if ((block_cent / block_size) > (thresh1 * mean_block_nrg)) + { + cur_max = array_max_abs(&q_d_prev[i], block_size); + prev_max = 0; + + for (k = i - block_size; k < i; k++) + { + if (k > 0) + { + prev_max = MAX(LC3_FABS(q_d_prev[k]), prev_max); + } + } + next_max = array_max_abs(&q_d_prev[i + block_size], block_size); + + if ((cur_max >= prev_max) && (cur_max > next_max)) + { + if (block_cent > (fac * maxPeak)) + { + peak = i + block_size - 1; + if (block_cent >= maxPeak) + { + maxPeak = block_cent; + } + } + } + } + } + } + + for (i = block_size; i < yLen - (2 * block_size); i++) + { + if ((LC3_FABS(q_d_prev[i + 1]) >= LC3_FABS(q_d_prev[i])) && LC3_FABS(q_d_prev[i + 1]) >= LC3_FABS(q_d_prev[i + 2])) + { + block_cent = 0; + for (j = i; j < i + block_size; j++) + { + block_cent += LC3_POW(q_d_prev[j], 2); + } + + if ((block_cent / block_size) > (thresh1 * mean_block_nrg)) + { + cur_max = array_max_abs(&q_d_prev[i], block_size); + prev_max = array_max_abs(&q_d_prev[i - block_size], block_size); + next_max = array_max_abs(&q_d_prev[i + block_size], block_size); + + if ((cur_max >= prev_max) && (cur_max > next_max)) + { + if (block_cent > (fac * maxPeak)) + { + peak = i + block_size - 1; + if (block_cent >= maxPeak) + { + maxPeak = block_cent; + } + } + } + } + } + } + + return peak; +} + diff --git a/lc3plus/pc_main.c b/lc3plus/pc_main.c new file mode 100644 index 0000000000000000000000000000000000000000..268ee94d2a383cf043d99089da3829907702c9c4 --- /dev/null +++ b/lc3plus/pc_main.c @@ -0,0 +1,43 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + + +void processPcMain_fl(LC3_INT32 *bfi, LC3PLUS_Dec* decoder, LC3_FLOAT *sqQdec, DecSetup* h_DecSetup, LC3_INT32 pitch_present, LC3_FLOAT stab_fac, LC3_INT32 gg_idx, LC3_INT32 gg_idx_off, LC3_INT32 fac_ns_idx, pcState *statePC, LC3_INT32 spec_inv_idx, LC3_INT32 yLen) +{ + LC3_FLOAT fac; + + /* PC Classifier */ + if (*bfi == 2) + { + processPcClassify_fl(pitch_present, decoder->frame_dms, h_DecSetup->PlcSetup.q_d_prev, statePC->q_old_res, decoder->yLen, h_DecSetup->spec_inv_idx, stab_fac, bfi); + } + + /* PC Apply */ + if (*bfi == 2) + { + processPcApply_fl(sqQdec, statePC->q_old_res, h_DecSetup->PlcSetup.q_d_prev, h_DecSetup->spec_inv_idx, decoder->yLen, gg_idx, gg_idx_off, &statePC->prev_gg, &fac, &statePC->ns_nbLostCmpt_pc); + } + + /* PC Update */ + if (*bfi != 1) + { + processPcUpdate_fl(*bfi, sqQdec, gg_idx, gg_idx_off, decoder->rframe, &h_DecSetup->BW_cutoff_idx_nf, &h_DecSetup->prev_BW_cutoff_idx_nf, fac_ns_idx, &h_DecSetup->prev_fac_ns, &fac, statePC->q_old_res, &statePC->prev_gg, spec_inv_idx, yLen); + } + + /* Reset counter */ + if (*bfi == 0) + { + statePC->ns_nbLostCmpt_pc = 0; + } +} + diff --git a/lc3plus/pc_update.c b/lc3plus/pc_update.c new file mode 100644 index 0000000000000000000000000000000000000000..57539b50797673f624e35305a0bddb11614911b2 --- /dev/null +++ b/lc3plus/pc_update.c @@ -0,0 +1,37 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + + +void processPcUpdate_fl(LC3_INT32 bfi, LC3_FLOAT *q_res, LC3_INT32 gg_idx, LC3_INT32 gg_idx_off, LC3_INT32 rframe, LC3_INT32 *BW_cutoff_idx_nf, LC3_INT32 *prev_BW_cutoff_idx_nf, + LC3_INT32 fac_ns_idx, LC3_FLOAT *prev_fac_ns, LC3_FLOAT *fac, LC3_FLOAT *q_old_res, LC3_FLOAT *prev_gg, LC3_INT32 spec_inv_idx, LC3_INT32 yLen) +{ + LC3_FLOAT gg; + + gg = LC3_POW(10.0, ((LC3_FLOAT) (gg_idx + gg_idx_off)) / 28.0); + *prev_gg = gg; + move_float(q_old_res, q_res, yLen); + + if (rframe == 0) + { + *prev_BW_cutoff_idx_nf = *BW_cutoff_idx_nf; + *prev_fac_ns = (8.0 - (LC3_FLOAT) fac_ns_idx) / 16.0; + } else if ((bfi == 2) && (*BW_cutoff_idx_nf != *prev_BW_cutoff_idx_nf) && (spec_inv_idx < yLen)) + { + *BW_cutoff_idx_nf = *prev_BW_cutoff_idx_nf; + *prev_fac_ns = *prev_fac_ns * (*fac); + *prev_fac_ns = MAX(*prev_fac_ns, (8.0 - 7.0) / 16.0); + *prev_fac_ns = MIN(*prev_fac_ns, (8.0 - 0.0) / 16.0); + } + +} + diff --git a/lc3plus/per_band_energy.c b/lc3plus/per_band_energy.c new file mode 100644 index 0000000000000000000000000000000000000000..db1b5b2d0f411925327aacd78ace3c30ce239b47 --- /dev/null +++ b/lc3plus/per_band_energy.c @@ -0,0 +1,59 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +void processPerBandEnergy_fl(LC3_INT bands_number, const LC3_INT* acc_coeff_per_band, LC3_INT16 hrmode, LC3_INT16 frame_dms, LC3_FLOAT* d2, LC3_FLOAT* d) +{ + LC3_INT i = 0, j = 0, start = 0, stop = 0, maxBwBin = 0; + LC3_FLOAT sum = 0; + +# ifdef ENABLE_HR_MODE_FL + if (hrmode) + { + maxBwBin = MAX_BW_HR; + } + else +# else + UNUSED(hrmode); +# endif + { + maxBwBin = MAX_BW; + } + switch (frame_dms) + { +# ifdef ENABLE_2_5MS_MODE + case 25: + maxBwBin = maxBwBin >> 2; + break; +# endif +# ifdef ENABLE_5MS_MODE + case 50: + maxBwBin = maxBwBin >> 1; + break; +# endif + } + + for (i = 0; i < bands_number; i++) { + sum = 0; + start = acc_coeff_per_band[i]; + stop = MIN(acc_coeff_per_band[i + 1], maxBwBin); + + for (j = start; j < stop; j++) { + sum += d[j] * d[j]; + } + + if (stop - start > 0) { + sum = sum / (LC3_FLOAT)(stop - start); + } + d2[i] = sum; + } +} diff --git a/lc3plus/plc_classify.c b/lc3plus/plc_classify.c new file mode 100644 index 0000000000000000000000000000000000000000..619a1f7419b1301242a9bb9264b5f7fe77330c89 --- /dev/null +++ b/lc3plus/plc_classify.c @@ -0,0 +1,199 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + + +static void plc_xcorr_lc(LC3_FLOAT *pcmbufHist, LC3_INT32 max_len_pcm_plc, LC3_INT32 pitch_int, LC3_INT32 framelength, LC3_INT32 frame_dms, LC3_INT32 fs, LC3_FLOAT *xcorr); +static void spectral_centroid_lc(LC3_FLOAT *gains, LC3_INT32 tilt, const LC3_INT *bands_offset, LC3_INT32 bands_number, LC3_INT32 framelength, LC3_INT32 fs, LC3_FLOAT *sc); + +void processPlcClassify_fl(LC3_INT plcMeth, LC3_INT *concealMethod, LC3_INT32 *nbLostCmpt, LC3_INT32 bfi, + LC3_FLOAT *xcorr, LC3_INT32 framelength, LC3_INT32 frame_dms, LC3_INT32 pitch_int, + LC3_INT32 fs, const LC3_INT *band_offsets, LC3_INT32 bands_number, LC3_INT32 tilt, PlcAdvSetup *plcAd + , LC3_INT32 hrmode +) +{ + LC3_FLOAT sc, class; + + if (plcAd) + { + *xcorr = 0; + } + + if (bfi == 1) + { + *nbLostCmpt = *nbLostCmpt + 1; + + /* Use pitch correlation at ltpf integer lag if available */ + if (*nbLostCmpt == 1) + { + *concealMethod = plcMeth; // this is a dangerous mapping! + + /* Advanced PLC */ + if (pitch_int > 0) + { + *concealMethod = 3; /* Timedomain PLC assumed */ + plc_xcorr_lc(plcAd->pcmbufHist, plcAd->max_len_pcm_plc, pitch_int, framelength, frame_dms, fs, xcorr); + + spectral_centroid_lc(plcAd->scf_q_old, tilt, band_offsets, bands_number, framelength, fs, &sc); + class = *xcorr * 7640.0/32768.0 - sc - 5112.0/32768.0; + + if (class <= 0) + { + if (frame_dms == 100 && hrmode == 0) + { + *concealMethod = 2; /* PhaseEcu selected */ + } + else + { + *concealMethod = 4; /* Noise Substitution */ + } + } + } + else + { + *concealMethod = 4; /* Noise Substitution */ + } + } + } +} + +static void spectral_centroid_lc(LC3_FLOAT *gains, LC3_INT32 tilt, const LC3_INT *band_offsets, LC3_INT32 bands_number, LC3_INT32 framelength, LC3_INT32 fs, LC3_FLOAT *sc) +{ + LC3_FLOAT gains_lin[M], gains_dee[M], numerator, denumerator; + LC3_INT32 i, j, sum, len, start, stop; + LC3_INT band_offsets_local[MAX_BANDS_NUMBER + 1]; + + numerator = 0; + + for (i = 0; i < M; i++) + { + gains_lin[i] = LC3_POW(2, gains[i]); + } + + for (i = 0; i < M; i++) + { + gains_dee[i] = gains_lin[i] / LC3_POW(10, i * (LC3_FLOAT) tilt / (LC3_FLOAT) (M - 1) / 10.0); + } + + if (bands_number == 64) + { + memmove(band_offsets_local, band_offsets, (bands_number + 1) * sizeof(LC3_INT)); + } + + if (bands_number < 32) + { + band_offsets_local[0] = 0; + j = 32 - bands_number; + for (i = bands_number - 1; i >= j; i--) + { + band_offsets_local[(i + j) * 2 + 1 + 1] = band_offsets[i + 1]; + band_offsets_local[(i + j) * 2 + 0 + 1] = band_offsets[i + 1]; + } + for (i = j - 1; i >= 0; i--) + { + band_offsets_local[i * 4 + 3 + 1] = band_offsets[i + 1]; + band_offsets_local[i * 4 + 2 + 1] = band_offsets[i + 1]; + band_offsets_local[i * 4 + 1 + 1] = band_offsets[i + 1]; + band_offsets_local[i * 4 + 0 + 1] = band_offsets[i + 1]; + } + } + else + if (bands_number < 64) + { + band_offsets_local[0] = 0; + j = 64 - bands_number; + for (i = bands_number - 1; i >= j; i--) + { + band_offsets_local[i + j + 1] = band_offsets[i + 1]; + } + for (i = j - 1; i >= 0; i--) + { + band_offsets_local[i * 2 + 1 + 1] = band_offsets[i + 1]; + band_offsets_local[i * 2 + 0 + 1] = band_offsets[i + 1]; + } + } + + denumerator = 0.001; + + for (i = 0; i < M; i++) + { + sum = 0; len = 0; + start = band_offsets_local[i * 4] + 1; stop = band_offsets_local[i * 4 + 4]; + + for (j = stop; j >= start; j--) + { + sum += j; + len++; + } + + numerator += gains_dee[i] * ((LC3_FLOAT) sum / (LC3_FLOAT) framelength); + denumerator += gains_dee[i] * len; + } + + *sc = numerator / denumerator; + *sc = *sc * (LC3_FLOAT) fs / 48000.0; /* scaling, because training is for 48kHz */ +} + +static void plc_xcorr_lc(LC3_FLOAT *pcmbufHist, LC3_INT32 max_len_pcm_plc, LC3_INT32 pitch_int, LC3_INT32 framelength, + LC3_INT32 frame_dms, LC3_INT32 fs, LC3_FLOAT *xcorr) +{ + LC3_INT32 max_corr_len, pitch_min, corr_len, min_corr_len, pcm_max_corr_len, range1Start, range2Start, i; + LC3_FLOAT norm_w, norm_w_t; + + norm_w_t = 0; norm_w = 0; + + assert(pitch_int >= 0); + assert(pitch_int <= MAX_LEN*100*MAX_PITCH_12K8/12800); + + *xcorr = 0; + + if (pitch_int > 0) + { + pitch_min = fs * MIN_PITCH_12K8/12800; + pcm_max_corr_len = max_len_pcm_plc - pitch_int; + + min_corr_len = 2 * pitch_min; /* at least 5 ms (=2*pitchmin*) corr length */ + max_corr_len = framelength*100/frame_dms; /* maximum 10 ms */ + max_corr_len = MIN( max_corr_len, pcm_max_corr_len ); + + corr_len = MIN( max_corr_len, pitch_int ); /* pitch_int is prefered, but maximum 10ms or left pcm buf size */ + corr_len = MAX( min_corr_len, corr_len ); + + range1Start = max_len_pcm_plc - corr_len; + range2Start = range1Start - pitch_int; + + assert( corr_len >= min_corr_len ); + assert( corr_len <= max_corr_len ); + assert( range2Start >= 0 ); + + for (i = 0; i < corr_len; i++) + { + norm_w += pcmbufHist[range1Start + i] * pcmbufHist[range1Start + i]; + } + + for (i = 0; i < corr_len; i++) + { + norm_w_t += pcmbufHist[range2Start + i] * pcmbufHist[range2Start + i]; + } + + for (i = 0; i < corr_len; i++) + { + *xcorr = *xcorr + pcmbufHist[range1Start + i] * pcmbufHist[range2Start + i]; + } + + *xcorr = *xcorr / sqrt(norm_w * norm_w_t + 0.1); + *xcorr = MAX(0, *xcorr); + } else { + *xcorr = 0; + } +} + diff --git a/lc3plus/plc_compute_stab_fac.c b/lc3plus/plc_compute_stab_fac.c new file mode 100644 index 0000000000000000000000000000000000000000..4a1111a2c7317f29d815fe0c0346d314b9e17569 --- /dev/null +++ b/lc3plus/plc_compute_stab_fac.c @@ -0,0 +1,64 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + + +static void processPlcComputeStabFac_fl(LC3_FLOAT *scf_q, LC3_FLOAT *old_scf_q, LC3_INT32 prev_bfi, LC3_FLOAT *stab_fac); + +void processPlcComputeStabFacMain_fl(LC3_FLOAT *scf_q, LC3_FLOAT *old_scf_q, LC3_FLOAT *old_old_scf_q, LC3_INT32 bfi, LC3_INT32 prev_bfi, + LC3_INT32 prev_prev_bfi, LC3_FLOAT *stab_fac) +{ + if (bfi == 1) + { + if (prev_bfi != 1) + { + processPlcComputeStabFac_fl(old_scf_q, old_old_scf_q, prev_prev_bfi, stab_fac); + } + } + else if (bfi == 2) + { + processPlcComputeStabFac_fl(scf_q, old_scf_q, prev_bfi, stab_fac); + } +} + +static void processPlcComputeStabFac_fl(LC3_FLOAT *scf_q, LC3_FLOAT *old_scf_q, LC3_INT32 prev_bfi, LC3_FLOAT *stab_fac) +{ + LC3_FLOAT tmp; + LC3_INT32 i; + + tmp = 0; + + if (prev_bfi == 1) + { + *stab_fac = 0.8; + } + else + { + for (i = 0; i < M; i++) + { + tmp += (scf_q[i] - old_scf_q[i]) * (scf_q[i] - old_scf_q[i]); + } + + *stab_fac = 1.25 - tmp / 25.0; + + if (*stab_fac > 1) + { + *stab_fac = 1; + } + + if (*stab_fac < 0) + { + *stab_fac = 0; + } + } +} + diff --git a/lc3plus/plc_damping_scrambling.c b/lc3plus/plc_damping_scrambling.c new file mode 100644 index 0000000000000000000000000000000000000000..ecea32be5fa151684a7ced58dd0c5d7e04b045d7 --- /dev/null +++ b/lc3plus/plc_damping_scrambling.c @@ -0,0 +1,206 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + + +void processPlcDampingScramblingMain_fl(LC3_INT32 *ns_seed, + LC3_INT32 *pc_seed, LC3_INT32 ns_nbLostCmpt_pc, + LC3_INT32 ns_nbLostCmpt, LC3_FLOAT *stabFac, LC3_FLOAT *cum_fading_slow, LC3_FLOAT *cum_fading_fast, + LC3_FLOAT *spec_prev, LC3_FLOAT *spec, LC3_INT32 spec_inv_idx, LC3_INT32 yLen, LC3_INT32 bfi, + LC3_INT32 frame_dms, LC3_INT32 concealMethod, LC3_INT32 pitch_present_bfi1, LC3_INT32 pitch_present_bfi2, + LC3_FLOAT *cum_fflcAtten) +{ + + LC3_INT32 processDampScramb; + + processDampScramb = 0; + + + if ( bfi != 0 ) + { + if (concealMethod == 4 || bfi == 2) + { + processDampScramb = 1; + } + if ( bfi == 1 ) + { + processPlcDampingScrambling_fl(spec, yLen, ns_nbLostCmpt, stabFac, processDampScramb, cum_fflcAtten, + pitch_present_bfi1, frame_dms, cum_fading_slow, cum_fading_fast, ns_seed, 0); + } + else /* bfi == 2 */ + { + processPlcDampingScrambling_fl(spec, yLen, ns_nbLostCmpt_pc, stabFac, processDampScramb, cum_fflcAtten, + pitch_present_bfi2, frame_dms, cum_fading_slow, cum_fading_fast, pc_seed, spec_inv_idx); + processPlcUpdateSpec_fl(spec_prev, spec, yLen); + } + } +} + +void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 nbLostCmpt, LC3_FLOAT *stabFac, LC3_INT32 processDampScramb, + LC3_FLOAT *cum_fflcAtten, LC3_INT32 pitch_present, LC3_INT32 frame_dms, LC3_FLOAT *cum_fading_slow, + LC3_FLOAT *cum_fading_fast, LC3_INT32 *seed, LC3_INT32 spec_inv_idx) +{ + LC3_INT32 plc_start_inFrames, plc_end_inFrames, plc_duration_inFrames, x, b, i, ad_ThreshFac_start; + LC3_FLOAT slow, fast, linFuncStartStop, randThreshold, ad_ThreshFac_end, ad_threshFac, frame_energy, mean_energy, energThreshold, fac, m, n, fflcAtten, cum_fading_slow_local, cum_fading_fast_local; + + frame_energy = 0; + + /* Main process */ + if (nbLostCmpt == 1) + { + *cum_fading_slow = 1; + *cum_fading_fast = 1; + *cum_fflcAtten = 1; + } + + slow = 0.8 + 0.2 * (*stabFac); + fast = 0.3 + 0.2 * (*stabFac); + + switch (frame_dms) + { + case 25: + slow = LC3_SQRT(LC3_SQRT(slow)); + fast = LC3_SQRT(LC3_SQRT(fast)); + break; + case 50: + slow = LC3_SQRT(slow); + fast = LC3_SQRT(fast); + break; + } + + *cum_fading_slow = *cum_fading_slow * slow; + *cum_fading_fast = *cum_fading_fast * fast; + + if (processDampScramb == 1) + { + fflcAtten = 1; + cum_fading_slow_local = *cum_fading_slow; + cum_fading_fast_local = *cum_fading_fast; + + if (spec_inv_idx == 0) + { + if (nbLostCmpt * frame_dms > PLC_FADEOUT_IN_MS * 10) + { + fflcAtten = 0; + *cum_fflcAtten = 0; + } + else if (nbLostCmpt * frame_dms > 200) + { + switch(frame_dms) + { + case 25: fflcAtten = PLC34_ATTEN_FAC_025; break; + case 50: fflcAtten = PLC34_ATTEN_FAC_050; break; + case 100: fflcAtten = PLC34_ATTEN_FAC_100; break; + } + } + + + *cum_fflcAtten = *cum_fflcAtten * fflcAtten; + cum_fading_slow_local = *cum_fading_slow * *cum_fflcAtten; + cum_fading_fast_local = *cum_fading_fast * *cum_fflcAtten; + } + + if (pitch_present == 0) + { + plc_start_inFrames = 1; + } else { + plc_start_inFrames = floor(PLC4_TRANSIT_START_IN_MS / (frame_dms / 10.0)); + } + + plc_end_inFrames = floor(PLC4_TRANSIT_END_IN_MS / (frame_dms / 10.0)); + plc_duration_inFrames = plc_end_inFrames - plc_start_inFrames; + + if (nbLostCmpt <= plc_start_inFrames) + { + linFuncStartStop = 1; + } else if (nbLostCmpt >= plc_end_inFrames) + { + linFuncStartStop = 0; + } else { + x = nbLostCmpt; + m = -1.0 / plc_duration_inFrames; + b = -plc_end_inFrames; + linFuncStartStop = m * (x + b); + } + + randThreshold = -32768 * linFuncStartStop; + + for (i = spec_inv_idx; i < yLen; i++) + { + *seed = 16831 + *seed * 12821; + + *seed = (LC3_INT16)(*seed); + if (*seed == 32768) + { + *seed -= 32768; + } + + if (*seed < 0) + { + if (pitch_present == 0 || *seed < randThreshold) + { + spec[i] = -spec[i]; + } + } + } + + ad_ThreshFac_start = 10; + ad_ThreshFac_end = 1.2; + ad_threshFac = (ad_ThreshFac_start - ad_ThreshFac_end) * linFuncStartStop + ad_ThreshFac_end; + + if (spec_inv_idx < yLen) + { + for (i = spec_inv_idx; i < yLen; i++) + { + frame_energy = frame_energy + (spec[i] * spec[i]); + } + + mean_energy = frame_energy * 1 / (yLen - spec_inv_idx); + } + else + { + mean_energy = 0; + } + + energThreshold = LC3_SQRT(ad_threshFac * mean_energy); + fac = (cum_fading_slow_local - cum_fading_fast_local) * energThreshold; + + for (i = spec_inv_idx; i < yLen; i++) + { + if (LC3_FABS(spec[i]) < energThreshold) + { + m = cum_fading_slow_local; + n = 0; + } + else + { + m = cum_fading_fast_local; + + if (spec[i] > 0) + { + n = fac; + } + else if (spec[i] == 0) + { + n = 0; + } + else + { + n = -fac; + } + } + + spec[i] = m * spec[i] + n; + } + } +} + diff --git a/lc3plus/plc_main.c b/lc3plus/plc_main.c new file mode 100644 index 0000000000000000000000000000000000000000..df3fd184d903c169de288fd2630816b027129b3f --- /dev/null +++ b/lc3plus/plc_main.c @@ -0,0 +1,209 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* decoder, DecSetup* h_DecSetup, LC3_INT bfi, + PlcAdvSetup *PlcAdvSetup, PlcSetup *PlcSetup, LC3_INT plcMeth, LC3_INT ltpf_pitch_int, LC3_INT ltpf_pitch_fr, + LC3_INT tilt, const LC3_INT *bands_offset, LC3_INT bands_number, const LC3_INT *bands_offsetPLC, + LC3_INT n_bandsPLC, LC3_INT16 hrmode, pcState *statePC +) +{ + LC3_FLOAT r[MAX_BANDS_NUMBER_PLC], A[M + 1], synth[MAX_LEN + MDCT_MEM_LEN_MAX], energies[MAX_BANDS_NUMBER_PLC]; + LC3_INT32 pitch_classifier; + LC3_FLOAT xcorr; + LC3_INT32 yLen; + LC3_INT16 prev_bfi_plc2; + LC3_FLOAT phEcu_env_stab_local[1]; + LC3_FLOAT phEcu_pfind_sens[1]; + + prev_bfi_plc2 = 1; + if (PlcSetup->nbLostCmpt == 0) + { + prev_bfi_plc2 = 0; + } + assert((h_DecSetup->PlcSetup.prevBfi == 1) == (prev_bfi_plc2 == 1)); + + if (bfi == 1 && PlcAdvSetup) + { + /* FFLC increases the PFLC counter */ + statePC->ns_nbLostCmpt_pc = statePC->ns_nbLostCmpt_pc + 1; + } + + pitch_classifier = ltpf_pitch_int; +#ifdef NONBE_PLC_CLASSIFER_LAG_FIX + if (ltpf_pitch_fr > 2) + { + pitch_classifier++; + } +#endif + + processPlcClassify_fl(plcMeth, &h_DecSetup->concealMethod, &PlcSetup->nbLostCmpt, bfi, &xcorr, + decoder->frame_length, decoder->frame_dms, pitch_classifier, decoder->fs, + bands_offset, bands_number, tilt, PlcAdvSetup, hrmode + ); + + if (bfi == 1) + { + switch (h_DecSetup->concealMethod) + { + case 2: + { + LC3_FLOAT pitch_fl_c; + + assert(decoder->fs_idx == floor(decoder->fs / 10000)); + // phaseECU supports only 10ms framing + assert(PlcSetup->nbLostCmpt != 0 || decoder->frame_dms == 100); + + if (decoder->frame_dms != 100) + { + // muting, if frame size changed during phaseECU concealment + memset(q_d_fl_c, 0, sizeof(LC3_FLOAT) * decoder->frame_length); + h_DecSetup->alpha = 0; + break; + } + + /* call phaseEcu */ + pitch_fl_c = (LC3_FLOAT)ltpf_pitch_int + (LC3_FLOAT)ltpf_pitch_fr / 4.0; /* use non-rounded pitch indeces */ + + + if (prev_bfi_plc2 == 0) + { + /* convert fractional pitch lag info at current fs to a normalized fractional bin-frequency */ + PlcAdvSetup->PlcPhEcuSetup.PhECU_f0hzLtpBin = plc_phEcuSetF0Hz(decoder->fs, &pitch_fl_c); + /* several buffers used in Cflt , a copy pcmbufHist, right before calling PhEcu in bad frames */ + assert(bfi == 1); + move_float(PlcAdvSetup->PlcPhEcuSetup.PhECU_xfp, + &(PlcAdvSetup->pcmbufHist[PlcAdvSetup->max_len_pcm_plc - PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot]), + PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot); + + /* a first bfi frame:: calc windowed 16 ms energy twice in a 26 ms buffer separated by 10 ms*/ + { + const LC3_FLOAT *w, *prev_xfp; + LC3_INT32 i, oold_start; + + oold_start = PlcAdvSetup->max_len_pcm_plc - (decoder->frame_length + PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot); + assert(oold_start > 0); + w = PhECU_whr16ms_wins[decoder->fs_idx]; /* hammrect table */ + prev_xfp = &(PlcAdvSetup->pcmbufHist[oold_start + 0]); + + PlcAdvSetup->PlcPhEcuSetup.PhECU_L_oold_xfp_w_E = 0; + PlcAdvSetup->PlcPhEcuSetup.PhECU_L_old_xfp_w_E = 0; + for (i = 0; i < PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot; i++) + { + PlcAdvSetup->PlcPhEcuSetup.PhECU_L_oold_xfp_w_E += sqrf(prev_xfp[i] * w[i]); + PlcAdvSetup->PlcPhEcuSetup.PhECU_L_old_xfp_w_E += sqrf(PlcAdvSetup->PlcPhEcuSetup.PhECU_xfp[i] * w[i]); + } + + } + + } /* (prev_bfi_plc2 == 0)*/ + else + { + /* overwrite last 3.75 ms of xfp with most recent pcmbufHist tail , right before calling PhEcu in bursts of bad frames */ + LC3_INT32 lenCopyOla = decoder->la_zeroes; /*copy_part + ola_part = 3.75 ms for 10 ms frame*/ + + assert(bfi == 1 && prev_bfi_plc2); + move_float(&(PlcAdvSetup->PlcPhEcuSetup.PhECU_xfp[PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot-lenCopyOla]), + &(PlcAdvSetup->pcmbufHist[PlcAdvSetup->max_len_pcm_plc - lenCopyOla]), lenCopyOla); + + } + + { + LC3_FLOAT x_tda[MAX_LEN]; /* 960/2 */ + PlcAdvSetup->PlcPhEcuSetup.PhECU_norm_corr = xcorr; + phEcu_env_stab_local[0] = (LC3_FLOAT)PHECU_ENV_STAB_LOCAL; + phEcu_pfind_sens[0] = (LC3_FLOAT)PHECU_PFIND_SENS; + + plc_phEcu_hq_ecu(&(PlcAdvSetup->PlcPhEcuSetup.PhECU_f0hzLtpBin), + &(PlcAdvSetup->PlcPhEcuSetup.PhECU_norm_corr), + PlcAdvSetup->PlcPhEcuSetup.PhECU_xfp, + prev_bfi_plc2, + &(PlcAdvSetup->PlcPhEcuSetup.PhECU_short_flag_prev), + decoder->fs, + &(PlcAdvSetup->PlcPhEcuSetup.PhECU_time_offs), + PlcAdvSetup->PlcPhEcuSetup.PhECU_X_sav_m, /* Complex */ + &(PlcAdvSetup->PlcPhEcuSetup.PhECU_num_plocs), + PlcAdvSetup->PlcPhEcuSetup.PhECU_plocs, + PlcAdvSetup->PlcPhEcuSetup.PhECU_f0est, + MDCT_WINS_10ms[hrmode][decoder->fs_idx], + + phEcu_env_stab_local, + PHECU_DELTA_CORR, + phEcu_pfind_sens, + PHECU_LA, + PlcAdvSetup->PlcPhEcuSetup.PhECU_t_adv, + PhECU_whr16ms_wins[decoder->fs_idx], + PlcAdvSetup->PlcPhEcuSetup.PhECU_oold_grp_shape, + &(PlcAdvSetup->PlcPhEcuSetup.PhECU_L_oold_xfp_w_E), + PlcAdvSetup->PlcPhEcuSetup.PhECU_old_grp_shape, + &(PlcAdvSetup->PlcPhEcuSetup.PhECU_L_old_xfp_w_E), + &(PlcAdvSetup->PlcPhEcuSetup.PhECU_beta_mute), + PlcAdvSetup->PlcPhEcuSetup.PhECU_mag_chg_1st, + PlcAdvSetup->PlcPhEcuSetup.PhECU_Xavg, + decoder->la_zeroes, + x_tda, /* time domain aliased output */ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + , + &(PlcAdvSetup->PlcPhEcuSetup.PhEcu_Fft), + &(PlcAdvSetup->PlcPhEcuSetup.PhEcu_Ifft) + ); + + + ProcessingITDA_WIN_OLA_fl(x_tda, decoder->frame_length, decoder->imdct_win, decoder->imdct_winLen, decoder->imdct_laZeros, + h_DecSetup->imdct_mem, synth); + move_float(syntM_fl_c, synth, decoder->frame_length); + + + + } + } + break; + case 3: + if (PlcSetup->nbLostCmpt == 1) + { + PlcAdvSetup->PlcTdcSetup.fract = ltpf_pitch_fr; + } + + processPerBandEnergy_fl(n_bandsPLC, bands_offsetPLC, hrmode, decoder->frame_dms, energies, PlcSetup->q_d_prev); + processTdcPreemphasis_fl(energies, &PlcAdvSetup->PlcTdcSetup.preemphFac, n_bandsPLC); + processTdcInverseOdft_fl(energies, n_bandsPLC, r, PlcAdvSetup->PlcTdcSetup.lpcorder); + processTdcLpcEstimation_fl(r, decoder->fs_idx, PlcAdvSetup->PlcTdcSetup.lpcorder + 1, A, decoder->frame_dms); + processTdcApply_fl(ltpf_pitch_int, &PlcAdvSetup->PlcTdcSetup.preemphFac, A, PlcAdvSetup->PlcTdcSetup.lpcorder, PlcAdvSetup->pcmbufHist, PlcAdvSetup->max_len_pcm_plc, decoder->frame_length, + decoder->frame_dms, decoder->fs, PlcSetup->nbLostCmpt, decoder->frame_length - decoder->la_zeroes, &PlcAdvSetup->stabFac, PlcAdvSetup->PlcTdcSetup.harmonicBuf, + PlcAdvSetup->PlcTdcSetup.synthHist, &PlcAdvSetup->PlcTdcSetup.fract, &PlcAdvSetup->PlcTdcSetup.seed, &PlcAdvSetup->PlcTdcSetup.gain_c, + &h_DecSetup->alpha, synth); + + processTdcTdac_fl(synth, decoder->imdct_win, decoder->frame_length, decoder->la_zeroes, h_DecSetup->imdct_mem); + memmove(syntM_fl_c, synth, sizeof(LC3_FLOAT) * decoder->frame_length); + break; + case 4: + processNoiseSubstitution_fl(q_d_fl_c, PlcSetup->q_d_prev, decoder->yLen); + break; + default: + assert("Invalid PLC method!"); + } + } + + if (bfi == 0) + { + processPlcUpdateSpec_fl(PlcSetup->q_d_prev, q_d_fl_c, decoder->yLen); + } + + yLen = MIN(decoder->frame_length, MAX_PLC_LMEM); + if (PlcAdvSetup != NULL && (decoder->frame_dms == 100) && (hrmode == 0)) + { + /* BASOP processPLCspec2shape_fx(prev_bfi, bfi, q_old_d_fx, yLen, plcAd->PhECU_oold_grp_shape_fx, plcAd->PhECU_old_grp_shape_fx);*/ + plc_phEcu_processPLCspec2shape(prev_bfi_plc2, bfi, q_d_fl_c, yLen, + PlcAdvSetup->PlcPhEcuSetup.PhECU_oold_grp_shape, PlcAdvSetup->PlcPhEcuSetup.PhECU_old_grp_shape); + } +} + diff --git a/lc3plus/plc_noise_substitution.c b/lc3plus/plc_noise_substitution.c new file mode 100644 index 0000000000000000000000000000000000000000..4913ee53e5f2ac954d9f1e12f81b5979c49baf60 --- /dev/null +++ b/lc3plus/plc_noise_substitution.c @@ -0,0 +1,22 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + + +void processNoiseSubstitution_fl(LC3_FLOAT* spec, LC3_FLOAT* spec_prev, LC3_INT32 yLen) +{ + memmove(spec, spec_prev, sizeof(LC3_FLOAT) * yLen); + + spec[0] *= 0.2; + spec[1] *= 0.5; +} + diff --git a/lc3plus/plc_noise_substitution0.c b/lc3plus/plc_noise_substitution0.c new file mode 100644 index 0000000000000000000000000000000000000000..da050e3dd2f73f95ae9dd254e9e189973db7967d --- /dev/null +++ b/lc3plus/plc_noise_substitution0.c @@ -0,0 +1,14 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + + diff --git a/lc3plus/plc_phecu_f0_refine_first.c b/lc3plus/plc_phecu_f0_refine_first.c new file mode 100644 index 0000000000000000000000000000000000000000..11ebf276b151b9c4f58f37de5632863aa8341ae1 --- /dev/null +++ b/lc3plus/plc_phecu_f0_refine_first.c @@ -0,0 +1,75 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "defines.h" +#include "functions.h" + + +void plc_phEcu_F0_refine_first( LC3_INT32 *plocs, /* i/o 0 ... Lprot/2 +1*/ + LC3_INT32 n_plocs, + LC3_FLOAT *f0est, /* i/o f0est */ + const LC3_INT32 Xabs_len, + LC3_FLOAT *f0binPtr, /* i */ + LC3_FLOAT *f0gainPtr, /* i */ + const LC3_INT32 nSubm + ) +{ + LC3_FLOAT sens; + LC3_INT32 i, j, high_idx, breakflag; + LC3_FLOAT f0est_lim[MAX_PLC_NPLOCS]; + LC3_FLOAT f0bin; + LC3_FLOAT f0gain; + + f0bin = *f0binPtr; + f0gain = *f0gainPtr; + + if (n_plocs > 0 && f0gain > 0.25) { + + sens = 0.5; + if (f0gain < 0.75) { + sens = 0.25; + } + + high_idx = -1; + for (i = 0; i < n_plocs; i++) { + if (plocs[i] <= 25) { /* 25 ~= 1550 Hz */ + high_idx = MAX(high_idx, i); + } else { + /* Optimization, only works if plocs vector is sorted. Which it should be. */ + break; + } + } + + if (high_idx != -1) { + high_idx++; + move_float(f0est_lim, f0est, high_idx); + + breakflag = 0; + for (i = 0; i < nSubm; i++) { + for (j = 0; j < high_idx; j++) { + if (LC3_FABS(f0est_lim[j] - (i+1) * f0bin) < sens) { + f0est[j] = (i+1)*f0bin; + plocs[j] = MIN(Xabs_len-1, MAX(1,(LC3_INT32) LC3_ROUND(f0est[j]))); + breakflag = 1; + break; + } + } + if (breakflag) { + break; + } + sens *= 0.875; + } + } + } + + return; +} + diff --git a/lc3plus/plc_phecu_fec_hq.c b/lc3plus/plc_phecu_fec_hq.c new file mode 100644 index 0000000000000000000000000000000000000000..c25466c3e995a0310ce70c92f81070558dc6d87e --- /dev/null +++ b/lc3plus/plc_phecu_fec_hq.c @@ -0,0 +1,159 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "defines.h" +#include "functions.h" + + +LC3_FLOAT plc_phEcu_imax2_jacobsen_mag(const Complex *y, LC3_FLOAT *c_jacobPtr) { + + LC3_FLOAT posi; + const Complex *pY; + Complex y_m1, y_0, y_p1; + Complex N; + Complex D; + LC3_FLOAT numer, denom; + + /* Jacobsen estimates peak offset relative y_0 using + * X_m1 - X_p1 + * d = REAL ( ------------------- ) * c_jacob + * 2*X_0 - X_m1 -Xp1 + * + * Where c_jacob is a window dependent constant + */ + + /* Get the parameters into variables */ + pY = y; + y_m1 = *pY++; + y_0 = *pY++; + y_p1 = *pY++; + + /* prepare numerator real and imaginary parts*/ + N = csub(y_m1, y_p1); + + /* prepare denominator real and imaginary parts */ + D = cmul(cmplx(2.0, 0.0), y_0); + D = csub(D, y_m1); + D = csub(D, y_p1); + + /* REAL part of complex division */ + numer = N.r*D.r + N.i*D.i; + denom = D.r*D.r + D.i*D.i; + + if (numer != 0 && denom != 0) { + posi = numer / denom * (*c_jacobPtr); + } else { + posi = 0.0; /* flat top, division is not possible choose center freq */ + } + + + posi = fclampf(-1.0, posi, 1.0); + return posi; +} + +/*-------------------------------------------------------------------* + * imax() + * + * Get interpolated maximum position + *-------------------------------------------------------------------*/ + +LC3_FLOAT plc_phEcu_interp_max(const LC3_FLOAT *y, LC3_INT32 y_len) { + LC3_FLOAT posi, y1, y2, y3, y3_y1, y2i; + LC3_FLOAT ftmp_den1, ftmp_den2; + + /* Seek the extrema of the parabola P(x) defined by 3 consecutive points so that P([-1 0 1]) = [y1 y2 y3] */ + y1 = y[0]; + y2 = y[1]; + + /* If interp between two values only */ + if (y_len == 2) { + if (y1 < y2) { + return 1.0; + } else { + return 0.0; + } + } + + y3 = y[2]; + y3_y1 = y3-y1; + ftmp_den1 = (y1+y3-2*y2); + ftmp_den2 = (4*y2 - 2*y1 - 2*y3); + + if(ftmp_den2 == 0.0 || ftmp_den1 == 0.0) { + return 0.0; /* early exit with left-most value */ + } + + y2i = ((LC3_FLOAT)-0.125) * sqrf(y3_y1) /(ftmp_den1) + y2; + /* their corresponding normalized locations */ + posi = y3_y1/(ftmp_den2); + /* Interpolated maxima if locations are not within [-1,1], calculated extrema are ignored */ + if (posi >= (LC3_FLOAT)1.0 || posi <= (LC3_FLOAT)-1.0) { + posi = y3 > y1 ? (LC3_FLOAT)1.0 : (LC3_FLOAT)-1.0; + } else { + if (y1 >= y2i) { + posi = (y1 > y3) ? (LC3_FLOAT)-1.0 :(LC3_FLOAT) 1.0; + } else if (y3 >= y2i) { + posi = (LC3_FLOAT)1.0; + } + } + + return posi + (LC3_FLOAT)1.0; +} + +/*----------------------------------------------------------------------------- + * fft_spec2_sqrt_approx_ () + * + * Approximation of sqrt(Square magnitude) of fft spectrum + * if min_abs <= 0.4142135*max_abs + * abs = 0.99 max_abs + 0.197*min_abs + * else + * abs = 0.84 max_abs + 0.561*min_abs + * end + * + + *----------------------------------------------------------------------------*/ + +void plc_phEcu_fft_spec2_sqrt_approx(const Complex* x, LC3_INT32 x_len, LC3_FLOAT* x_abs) { + LC3_INT32 i; + LC3_FLOAT max_abs, min_abs, re, im; + + for (i = 0; i < x_len; i++) { + re = LC3_FABS(x[i].r); + im = LC3_FABS(x[i].i); + max_abs = MAX(re, im); + min_abs = MIN(re, im); + + if (min_abs <= (LC3_FLOAT)0.4142135 * max_abs) { + x_abs[i] = (LC3_FLOAT)0.99*max_abs + (LC3_FLOAT)0.197*min_abs; + } else { + x_abs[i] = (LC3_FLOAT)0.84*max_abs + (LC3_FLOAT)0.561*min_abs; + } + } + + return; +} + +LC3_INT32 plc_phEcu_pitch_in_plocs(LC3_INT32* plocs, LC3_INT32 n_plocs) { + + LC3_INT32 i; + LC3_INT32 p_in_plocs; + + p_in_plocs = 0; + + for (i = 0; i < n_plocs; i++) { + if (plocs[i] > 0 && plocs[i] < 7) { + p_in_plocs++; + } + } + + return p_in_plocs; +} + diff --git a/lc3plus/plc_phecu_hq_ecu.c b/lc3plus/plc_phecu_hq_ecu.c new file mode 100644 index 0000000000000000000000000000000000000000..5b1978bcabfe7995abd483962079984e38e1ab71 --- /dev/null +++ b/lc3plus/plc_phecu_hq_ecu.c @@ -0,0 +1,116 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "defines.h" +#include "functions.h" + + +void plc_phEcu_hq_ecu( + LC3_FLOAT *f0binPtr, LC3_FLOAT *f0ltpGainPtr, LC3_FLOAT *xfp, + LC3_INT16 prev_bfi, LC3_INT32 *short_flag_prev, LC3_INT32 fs, + LC3_INT32 *time_offs, Complex *X_sav_m, LC3_INT32 *n_plocs, LC3_INT32 *plocs, LC3_FLOAT *f0est, + const LC3_FLOAT *mdctWin, LC3_FLOAT *env_stabPtr, LC3_INT32 delta_corr, LC3_FLOAT *pfind_sensPtr, + LC3_INT32 PhECU_LA, LC3_INT32 t_adv, const LC3_FLOAT *winWhr, + LC3_FLOAT *oold_grp_shape, LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_grp_shape, LC3_FLOAT *old_EwPtr, + LC3_FLOAT *st_beta_mute, LC3_FLOAT *st_mag_chg_1st, LC3_FLOAT *st_Xavg, LC3_INT32 LA_ZEROS, LC3_FLOAT *x_tda, + LC3_FLOAT *xsubst_dbg, Complex *X_out_m_dbg, + LC3_INT32 *seed_dbg, LC3_FLOAT *mag_chg_dbg, LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg, LC3_FLOAT *X_i_new_re_dbg, LC3_FLOAT *X_i_new_im_dbg, + LC3_FLOAT *corr_phase_dbg, + Fft *PhEcu_Fft, Fft *PhEcu_Ifft) +{ + LC3_INT32 i; + LC3_INT32 fs_idx, L, Lprot, n_grp, Lecu, LXsav, Lxfp_inuse; + LC3_FLOAT alpha[8]; + LC3_FLOAT beta[8]; + LC3_FLOAT mag_chg[8]; + LC3_FLOAT xfp_local_rnd[2*MAX_LEN]; + Complex X_out_m[2*MAX_LEN]; + LC3_INT32 seed; + LC3_INT32 burst_len; + + + fs_idx = (LC3_INT32)floor(fs / 10000.0); + L = (LC3_INT32)floor(0.01 * fs); + Lprot = (LC3_INT32)(1.6 * L); + n_grp = xavg_N_grp[fs_idx]; + Lecu = 2 * L; + LXsav = Lprot / 2 + 1; /* 48 kHz may be optimized , to save only up to 20 kHz as in BASOP */ + Lxfp_inuse = Lprot ; + if (prev_bfi == 1){ + Lxfp_inuse = (LC3_INT32)(L*(3.75/10.0)); + } + + UNUSED(env_stabPtr); + UNUSED(xsubst_dbg); + UNUSED(X_out_m_dbg); + UNUSED(seed_dbg); + UNUSED(mag_chg_dbg); + UNUSED(tr_dec_dbg); + UNUSED(gpc_dbg); + UNUSED(X_i_new_re_dbg); + UNUSED(X_i_new_im_dbg); + UNUSED(corr_phase_dbg); + + + if (prev_bfi != 1) + { + for (i = (Lprot-Lxfp_inuse); i < Lprot; i++) { + xfp_local_rnd[i] = xfp[i]; + /* hysteresis of low level input aligns float fft analysis and peak picking to BASOP performance for low level noisy signals */ + if (xfp[i] >= -0.5 && xfp[i] <= 0.5) { + xfp_local_rnd[i] = 0.0; + } + } + + + *time_offs = 0; + burst_len = (*time_offs / L + 1); + plc_phEcu_trans_burst_ana_sub(fs_idx, burst_len, n_grp, oold_grp_shape, oold_EwPtr , old_grp_shape, old_EwPtr, st_beta_mute, + st_mag_chg_1st, st_Xavg, alpha, beta, mag_chg, NULL, NULL); + + plc_phEcu_spec_ana(xfp_local_rnd, Lprot, winWhr, pfind_sensPtr, plocs, n_plocs, f0est, X_sav_m, &LXsav, f0binPtr, f0ltpGainPtr, fs_idx, PhEcu_Fft); + } + else + { + *time_offs = *time_offs + L; + *time_offs = imin(32767 ,*time_offs); /* limit to Word16 range as in BASOP ~= 70 10ms frames@48kHz */ + burst_len = ((*time_offs / L) + 1); + + plc_phEcu_trans_burst_ana_sub(fs_idx, burst_len, n_grp, oold_grp_shape, oold_EwPtr, old_grp_shape, old_EwPtr, st_beta_mute, + st_mag_chg_1st, st_Xavg, alpha, beta, mag_chg, NULL, NULL); + + } + + seed = *time_offs; + + if (*short_flag_prev != 0) + { + *n_plocs = 0; + } + + move_cmplx( X_out_m, X_sav_m, LXsav); + + /* inplace X_out_m update */ + plc_phEcu_subst_spec(plocs, *n_plocs, f0est, *time_offs, X_out_m, LXsav, mag_chg, &seed, alpha, beta, st_Xavg, t_adv, Lprot, delta_corr, + NULL, NULL, NULL); + + + + + plc_phEcu_rec_frame(X_out_m, L, Lecu, winWhr, mdctWin, Lprot, + xfp, /* last 3.75ms of non-rounded xfp used here */ + *time_offs, + x_tda /* output */, + NULL, NULL, NULL, + LA_ZEROS, PhECU_LA, PhEcu_Ifft); + +} + diff --git a/lc3plus/plc_phecu_lf_peak_analysis.c b/lc3plus/plc_phecu_lf_peak_analysis.c new file mode 100644 index 0000000000000000000000000000000000000000..0bcc98d7a489b37cdf94f118131188d17ca1a5ba --- /dev/null +++ b/lc3plus/plc_phecu_lf_peak_analysis.c @@ -0,0 +1,112 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "defines.h" +#include "functions.h" + + +void plc_phEcu_LF_peak_analysis(LC3_INT32 *plocs, /* i/o 0 ... Lprot/2 +1*/ + LC3_INT32 *n_plocs, /* i/o 0.. MAX_PLOCS */ + LC3_FLOAT *f0est, /* i/o Q16*/ + const LC3_FLOAT *Xabs, + LC3_FLOAT *f0binPtr, + LC3_FLOAT *f0gainPtr, + const LC3_INT32 nSubm +) +{ + LC3_INT32 i, j, fin, f_ind, prel_low, prel_high, start; + LC3_FLOAT f0est_prel[3]; + LC3_INT32 plocs_prel[3]; + LC3_INT32 n_prel; + LC3_FLOAT f0est_old[MAX_PLC_NPLOCS]; + LC3_INT32 plocs_old[MAX_PLC_NPLOCS]; + LC3_FLOAT peakLF_Xval, f; + LC3_FLOAT f0bin ; + LC3_FLOAT f0gain ; + + f0bin = *f0binPtr; + f0gain = *f0gainPtr; + + if (*n_plocs > 0 && f0gain > 0.25 && f0bin < 2.75) { + + /* Assumes sorted plocs */ + if (plocs[0] < 3) { + fin = MIN(3, *n_plocs); + peakLF_Xval = Xabs[plocs[0]]; + for (i = 1; i < fin; i++) { + peakLF_Xval = MAX(peakLF_Xval, Xabs[plocs[i]]); + } + + n_prel = 0; + for (i = 0; i < nSubm; i++) { + f = (i+1)*f0bin; + f_ind = (LC3_INT32)LC3_ROUND(f); + if (f*PHECU_FRES <= 400 && Xabs[f_ind] > peakLF_Xval*0.375) { + f0est_prel[n_prel] = f; + plocs_prel[n_prel] = f_ind; + n_prel++; + } + } + + if (n_prel > 0) { + prel_low = plocs_prel[0]; + prel_high = plocs_prel[n_prel-1]; + + /* initial assumption:: all original peaks (1 or 2 of them) are positioned below prel_low */ + start = (*n_plocs); /* at this point 'start' is the location_c where to add any harmonics peaks */ + for (i = (*n_plocs)-1; i >= 0; i--) { + if (plocs[i] >= prel_low) { + start = i; + } + } + + /* found position_c where to start adding */ + start = (start-1 ); /* one step lower, now start is of original LF peaks to keep */ + start = MAX(start, -1); /* limit for loop */ + + if (prel_high < plocs[0]) { + fin = 0; + } else { + fin = (*n_plocs)+1; + for (i = 0; i < *n_plocs; i++) { + if (plocs[i] <= prel_high) { + fin = i; + } + } + fin++; + } + + move_int(plocs_old, plocs, *n_plocs); + move_float(f0est_old, f0est, *n_plocs); + + j = (start+1); /* [0..(j-1)] of original LF peaks will be kept */ + /* j now points to first location_c where to add peaks */ + + for (i = 0; i < n_prel; i++) { + plocs[j] = plocs_prel[i]; + f0est[j] = f0est_prel[i]; + j++; + } + for (i = fin; i < *n_plocs; i++) { + plocs[j] = plocs_old[i]; + f0est[j] = f0est_old[i]; + j++; + } + + *n_plocs = j; + + } + } + } + + return; +} + diff --git a/lc3plus/plc_phecu_rec_frame.c b/lc3plus/plc_phecu_rec_frame.c new file mode 100644 index 0000000000000000000000000000000000000000..0e6570743ae7f8464e17d0b891a389ee3b1cccd0 --- /dev/null +++ b/lc3plus/plc_phecu_rec_frame.c @@ -0,0 +1,147 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "defines.h" +#include "functions.h" + + +void plc_phEcu_rec_frame(Complex *X_in, + LC3_INT32 L, + LC3_INT32 Lecu, + const LC3_FLOAT *whr, + const LC3_FLOAT *winMDCT, + LC3_INT32 Lprot, + LC3_FLOAT *xfp, + LC3_INT32 time_offs, + LC3_FLOAT *x_out, + Complex *full_spec_dbg, + LC3_FLOAT* ifft_out_dbg, + LC3_FLOAT* xsubst_dbg, + LC3_INT32 LA_ZEROS, + LC3_INT32 LA, + Fft* PhEcu_ifft +) +{ + + LC3_INT32 i; + + LC3_FLOAT xrec[2*MAX_LEN]; + LC3_FLOAT xsubst[2*MAX_LEN]; + LC3_FLOAT xsubst_LL[2*MAX_LEN]; + LC3_FLOAT *pXsubst_LL; + + LC3_INT32 fs_idx; + + LC3_FLOAT *pXfp, *pOlaXsubst, *pXOut; + LC3_INT32 work_part, copy_part, ola_part; + + const LC3_FLOAT *hannOla; + const LC3_FLOAT *pHannOla; + + UNUSED(time_offs); + UNUSED(full_spec_dbg); + UNUSED(ifft_out_dbg); + UNUSED(xsubst_dbg); + UNUSED(xsubst_LL); + fs_idx = FRAME2FS_IDX(L); + hannOla = hannOla_wins[fs_idx]; + + X_in[0].i = X_in[Lprot / 2].r; /* move fs/2 real to imag part of X_in[0]*/ + + real_fft_apply(PhEcu_ifft, (LC3_FLOAT*)X_in, xrec); + + move_float(xsubst, xrec, Lprot); + + + + + { + for (i = 0; i < Lprot; i++) { + + if (whr[i] != 0) { + xsubst[i] = xsubst[i] / whr[i]; /* inverse stored in BASOP */ + } + + } + + assert(xsubst_LL != NULL); + zero_float(xsubst_LL, (Lecu-Lprot)/2); /* initial 2ms */ + zero_float(&(xsubst_LL[ Lecu- (Lecu-Lprot)/2]), (Lecu-Lprot)/2); /* tail 2ms */ + { + /* position reconstruction properly */ + /* pXsubst_LL = &xsubst_LL[Lecu - Lprot - (Lecu - Lprot) / 2]; */ + pXsubst_LL = &xsubst_LL[(Lecu - Lprot) / 2]; + for (i = 0; i < Lprot ; i++) { + *pXsubst_LL++ = xsubst[i]; /* copy required 14.25 ms into center */ + } + } + + } + + + + work_part = LA_ZEROS + LA; + copy_part = (Lecu - Lprot) / 2; + ola_part = work_part - copy_part; + + pXfp = &xfp[Lprot - work_part]; + for (i = 0; i < copy_part; i++) { + xsubst_LL[i] = *pXfp++; + } + + assert(xsubst_LL != NULL); + pOlaXsubst = &(xsubst_LL[copy_part]); + pHannOla = hannOla; + for (i = 0; i < ola_part; i++) { + *pOlaXsubst = *pOlaXsubst * *pHannOla++; + pOlaXsubst++; + } + + pOlaXsubst = &(xsubst_LL[copy_part]); + for (i = 0; i < ola_part; i++) { + *pOlaXsubst = *pOlaXsubst + *pXfp++ * *pHannOla--; + pOlaXsubst++; + } + + + /* clear x_out to start with */ + assert(x_out != NULL); + zero_float(x_out, L); + + + for (i = 0; i < (Lecu - LA_ZEROS); i++) { + + xsubst_LL[i] = xsubst_LL[i] * winMDCT[i]; /* xsubstLL windowing up to 16.25 ms i.e not last 3.75 ms */ + + } + zero_float(&(xsubst_LL[Lecu - LA_ZEROS]), LA_ZEROS); /* tail 3.75ms always zero */ + + /* perform tda */ + + /* first half */ + pXsubst_LL = &xsubst_LL[3 * Lecu / 4]; + pXfp = &xsubst_LL[(3 * Lecu / 4) - 1]; + + pXOut = x_out; + for (i = 0; i < Lecu / 4; i++) { + *pXOut++ = -*pXsubst_LL++ - *pXfp--; /* 3.75 ms mults with 0 . may be skipped, see BASOP */ + } + + /* second half */ + /* */ + + pXsubst_LL = &(xsubst_LL[0]); + pXfp = &xsubst_LL[(Lecu / 2) - 1]; + for (i = 0; i < Lecu / 4; i++) { + *pXOut++ = *pXsubst_LL++ - *pXfp--; + } +} + diff --git a/lc3plus/plc_phecu_setf0hz.c b/lc3plus/plc_phecu_setf0hz.c new file mode 100644 index 0000000000000000000000000000000000000000..b14327e2b2af0f4c04c1f9bc633e0ac06a1a2114 --- /dev/null +++ b/lc3plus/plc_phecu_setf0hz.c @@ -0,0 +1,28 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "defines.h" +#include "functions.h" + + +LC3_FLOAT plc_phEcuSetF0Hz(LC3_INT32 fs, LC3_FLOAT * old_pitchPtr) +{ + LC3_FLOAT result; + + result = 0; + if (*old_pitchPtr != 0) + { + result = LC3_ROUND(fs/(*old_pitchPtr)/PHECU_FRES * 128.0) / 128.0; + } + + return result; +} + diff --git a/lc3plus/plc_phecu_spec_ana.c b/lc3plus/plc_phecu_spec_ana.c new file mode 100644 index 0000000000000000000000000000000000000000..b49690030596c08363f4168b5b6d1abd8c9d3b7b --- /dev/null +++ b/lc3plus/plc_phecu_spec_ana.c @@ -0,0 +1,599 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "defines.h" +#include "functions.h" + + +#define PEAK_LOCATOR_RES_FX 1 /* fixed point resolution minimum value */ + + +static LC3_INT16 plc_phEcu_find_ind_fx( /* o : output maximum indx 0.. len-1 */ + const LC3_INT16 *inp, /* i : vector */ + const LC3_INT16 len, /* i : length */ + const LC3_INT16 val /* i : value to find */ +); + +static void plc_phEcu_peak_locator_fxlike(const LC3_INT16 *inp, /* i: vector with values >=0 ,Qx */ + const LC3_INT16 inp_len, /* i: length of inp */ + LC3_INT16 * int_plocs, /* o: array of filtered integer plocs Q0 */ + LC3_INT16 * n_fsc, /* o: total_ number of filtered located highs Q0 */ + const LC3_INT16 sens, /* i sensitivity, Qx */ + const LC3_INT16 inp_high, /* i global high , Qx */ + const LC3_INT16 inp_low /* i: global low, Qx */ +); + + +void plc_phEcu_spec_ana(LC3_FLOAT* xfp, + LC3_INT32 xfp_len, + const LC3_FLOAT* whr, + LC3_FLOAT *pfind_sensPtr, + LC3_INT32* plocs, + LC3_INT32* n_plocs, + LC3_FLOAT* f0est, + Complex* x, + LC3_INT32* x_len, + LC3_FLOAT * f0hzLtpBinPtr, + LC3_FLOAT * f0gainLtpPtr, + LC3_INT32 bw_idx, + Fft* PhEcu_fft +) +{ + + + LC3_INT32 i, peak_range_1, curr; + LC3_FLOAT xfp_w[MAX_PLC_LPROT]; + + LC3_FLOAT Xabs[MAX_LEN] = {0}; + LC3_FLOAT inp_high, inp_low, sens; + LC3_FLOAT interPos; + Complex Xana_p[3]; + LC3_INT32 P_in_plocs; + LC3_INT32 nSubs; + LC3_INT32 n_plocs_in; + LC3_FLOAT phEcu_c_jacob[1]; + + LC3_FLOAT fx_fft_scale; + LC3_FLOAT fft_fs_scale; + + LC3_FLOAT max_xfp_abs; + LC3_FLOAT PLC2_Q_flt; + LC3_FLOAT Q_scale_flt; + + LC3_INT16 Xabs_fx[MAX_LEN]; + LC3_INT16 plocs_fx[MAX_LEN]; + + LC3_INT16 sens_fx; + LC3_INT16 inp_high_fx; + LC3_INT16 inp_low_fx; + LC3_INT16 n_plocs_fx; + + LC3_FLOAT pfind_sens ; + LC3_FLOAT f0hzLtpBin ; + LC3_FLOAT f0gainLtp ; + + pfind_sens = *pfind_sensPtr; + f0hzLtpBin = *f0hzLtpBinPtr; + f0gainLtp = *f0gainLtpPtr; + + for (i = 0; i < xfp_len; i++) + { + xfp_w[i] = xfp[i] * whr[i]; /* whr windowing may be split into three segments , two loops, and possibly inplace */ + } + real_fft_apply(PhEcu_fft, xfp_w, (LC3_FLOAT *)x); + + x[xfp_len/2].r = x[0].i; /* move the real Fs/2 value to end */ + x[xfp_len/2].i = 0; /* safety clear imaginary Fs/2 value at end */ + x[0].i = 0.0; /* safety, make DC value only real */ + + + *x_len = xfp_len/2 + 1; + + i =(LC3_INT32) LC3_FLOOR(20000.0/PHECU_FRES)+1; + zero_cmplx( &(x[i]), *x_len - i); + + peak_range_1 = (LC3_INT32) MIN(*x_len, (40000.0 / 100 * 1.6) / 2 + 1); + + plc_phEcu_fft_spec2_sqrt_approx(x, peak_range_1, Xabs); + + zero_float(&(Xabs[peak_range_1]), *x_len - peak_range_1); + + inp_high = Xabs[0]; + inp_low = Xabs[0]; + + for (i = 1; i < peak_range_1; i++) { + inp_high = MAX(inp_high, Xabs[i]); + inp_low = MIN(inp_low, Xabs[i]); + } + + sens = (inp_high-inp_low)*(1-pfind_sens); + + if (inp_high > ((LC3_FLOAT) PEAK_LOCATOR_RES_FX)/2.0) + { + { + /* from ROM constants.c */ + LC3_FLOAT fx_fft_scales[5] = { 6, 7, 7, 8, 8 }; /*NB,WB, sSWB, SWB, FB*/ + fx_fft_scale = LC3_POW(2.0, fx_fft_scales[bw_idx]); /*% scaling due to up / dn pre shifts in fx FFT */ + } + { /* from ROM constants.c */ + LC3_FLOAT fx_fs_scales[5] = { 1.0, 1.0, 1.5, 1.0, 1.5 }; /*NB,WB, sSWB, SWB, FB*/ + fft_fs_scale = fx_fs_scales[bw_idx]; + } + + + max_xfp_abs = (LC3_FLOAT) LC3_FABS(xfp[0]); + for (i = 1; i < xfp_len; i++) { + max_xfp_abs = (LC3_FLOAT) MAX(max_xfp_abs, LC3_FABS(xfp[i])); + } + + if (max_xfp_abs >= 0.5) + { + PLC2_Q_flt = (LC3_FLOAT)LC3_FLOOR(LC3_LOGTWO(32768 / 2 / 2 / max_xfp_abs)); + Q_scale_flt = LC3_POW(2.0, PLC2_Q_flt) / fx_fft_scale / fft_fs_scale; /* basop way using xfp scale */ + + /* C-Float additional safety limit/verification of the integer xfp based scaling using the available C-float Xabs max value inp_high as well */ + { + LC3_FLOAT tmp_scale; + tmp_scale = LC3_POW(2.0, LC3_FLOOR(LC3_LOGTWO(32768 / 2 / 2 / inp_high))); + if (Q_scale_flt > tmp_scale) { + Q_scale_flt = tmp_scale; + } + } + /* Round sens, inp_high, inp_low according to BASOP fix-point scaling */ + + for (i = 0; i < peak_range_1; i++) { + Xabs_fx[i] = (LC3_INT16) LC3_ROUND(Xabs[i] * Q_scale_flt) ; + } + sens_fx = (LC3_INT16) LC3_ROUND(sens * Q_scale_flt) ; + inp_high_fx = (LC3_INT16) LC3_ROUND(inp_high * Q_scale_flt) ; + inp_low_fx = (LC3_INT16) LC3_ROUND(inp_low * Q_scale_flt) ; + plc_phEcu_peak_locator_fxlike(Xabs_fx, peak_range_1, plocs_fx, &n_plocs_fx, sens_fx, inp_high_fx, inp_low_fx); + + *n_plocs = (LC3_INT32)n_plocs_fx; + for (i = 0; i < *n_plocs; i++) { + plocs[i] = (LC3_INT32)plocs_fx[i]; /* short Word16 values now stored/saved as Word32 */ + } + } + else + { + *n_plocs = 0; /* time domain xfp level near zero */ + } + } + else + { + *n_plocs = 0; /* Freq domain Xabs max level near zero */ + } + + for (i = 0; i < *n_plocs; i++) { + curr = plocs[i]; + if (curr == 0) { + interPos = plc_phEcu_interp_max(Xabs, 3); /* returns 0.0 ... 2.0 */ + if (interPos == 2) { + /* integer peak was at DC, restrict to one of coeffs at [DC or DC+1] */ + interPos = plc_phEcu_interp_max(Xabs, 2); /* returns 0.0 or 1.0 */ + } + interPos += plocs[i]; + } else if (curr == 1) { + interPos = plc_phEcu_interp_max(Xabs, 3); + interPos += plocs[i] - 1; + } else if (curr == *x_len - 2) { + interPos = plc_phEcu_interp_max(&Xabs[*x_len - 3], 3); + interPos += plocs[i] - 1; + } else if (curr == *x_len - 1) { + /* integer curr at Fs/2, a real coeff */ + interPos = plc_phEcu_interp_max(&Xabs[*x_len - 3], 3); /* returns 0.0 ... 2.0 */ + interPos += plocs[i] - 2; /* valid for range ]... 1.0 ... 2.0] , where 1 is fs/2-1 and 2.0 is Fs/2 */ + if (interPos == 0) { + /* restrict to one of coeffs at [fs/2-1, fs/2 ] */ + interPos = plc_phEcu_interp_max(&Xabs[*x_len - 2], 2); /* returns 0.0 or 1.0 */ + interPos += plocs[i] - 1; + } + + if (interPos > (*x_len - 1) ) { /* interPos only defined up to Fs/2 */ + interPos = (LC3_FLOAT)(*x_len - 1); + } + } else { + Xana_p[0] = x[plocs[i]-1]; + Xana_p[1] = x[plocs[i]]; + Xana_p[2] = x[plocs[i]+1]; + phEcu_c_jacob[0] = (LC3_FLOAT)PHECU_C_JACOB; + interPos = plc_phEcu_imax2_jacobsen_mag(Xana_p, phEcu_c_jacob ); + interPos += (LC3_FLOAT) plocs[i]; + } + f0est[i] = interPos; + } + + if (*n_plocs >= 2 && plocs[0] == 0 && + f0est[0] > f0est[1] && plocs[1] <= 2 && Xabs[0] < Xabs[plocs[1]+1]) + { + f0est[0] = f0est[1]; + } + + P_in_plocs = plc_phEcu_pitch_in_plocs(plocs, *n_plocs); + + if (f0hzLtpBin > 0.0 && P_in_plocs > 0) { + nSubs = 2; + n_plocs_in = *n_plocs; + plc_phEcu_LF_peak_analysis(plocs, n_plocs, f0est, Xabs, &f0hzLtpBin, &f0gainLtp, nSubs); + + if (n_plocs_in == *n_plocs) { + nSubs = 3; + plc_phEcu_F0_refine_first(plocs, *n_plocs, f0est, *x_len, &f0hzLtpBin, &f0gainLtp, nSubs); + } + } + + if (f0gainLtp > 0.0 && f0gainLtp < 0.5 && *n_plocs > 14) { + if (P_in_plocs > 0) { + *n_plocs = 0; + } + } + + return; +} + + +#define sub(a,b) (a - b) +#define add(a,b) (a + b) +#define s_xor(a,b) (a ^ b) + +/* in case a value (e.g max or min) is already known , find the first corresponding array index */ +static LC3_INT16 plc_phEcu_find_ind_fx( /* o : output maximum indx 0.. len-1 */ + const LC3_INT16 *inp, /* i : vector */ + const LC3_INT16 len, /* i : length */ + const LC3_INT16 val /* i : value to find */ +) +{ + LC3_INT16 val_ind; + LC3_INT16 pos; + + val_ind = -1; + + for(pos = 0; pos < len; pos++) + { + if (sub(inp[pos], val) == 0) + { + val_ind = pos; + } + } + + return val_ind; +} + + + +/* BASOP function adapted to compile in float/integer environment */ +/*----------------------------------------------------------------------------- + * plc_phEcu_peak_locator_fxlike() + *----------------------------------------------------------------------------*/ +static void plc_phEcu_peak_locator_fxlike(const LC3_INT16 *inp, /* i: vector with values >=0 ,Qx */ + const LC3_INT16 inp_len, /* i: length of inp */ + LC3_INT16 * int_plocs, /* o: array of filtered integer plocs Q0 */ + LC3_INT16 * n_fsc, /* o: total_ number of filtered located highs Q0 */ + const LC3_INT16 sens, /* i sensitivity, Qx */ + const LC3_INT16 inp_high, /* i global high , Qx */ + const LC3_INT16 inp_low /* i: global low, Qx */ +) +{ + + LC3_INT16 j, k, n, idx_high, idx_low; + LC3_INT16 inp_len_minus1; + LC3_INT16 pairs_start, pairs_end; + LC3_INT16 *p_tmp; + LC3_INT16 prev_delta, curr_delta; + LC3_INT16 delta_predc, delta_fin; + LC3_INT16 add_dc_flag, add_fin_flag; + LC3_INT16 low_val_cand_pairs, val_range; + LC3_INT16 num_pairs, n_tail_values; + LC3_INT16 cand_phase_start, cand_idx, prev_low_plus_sens, tmp; + LC3_INT16 cand_high, prev_low; + LC3_INT16 *cand_pairs; /* actually [DC ] + pairs + [FS/2] */ + + LC3_INT16 sc_idx[1 + 368 + 1]; + LC3_INT16 cand_pairs_buf[1 + 1 + 368 + 1]; + LC3_INT16 fsc_idx[1 + 368 / 2 + 1]; + + + inp_len_minus1 = sub(inp_len, 1); /* size of delta=derivative array ,and last index in inp */ + + cand_pairs = &cand_pairs_buf[1]; /* ptr init , make space for storing a lowest amplitude value in location -1 */ + pairs_start = 1; /* adjusted to zero or 1 or 2 when/if, DC is injected as sc_idx[0], or initial plateau skipped */ + + p_tmp = &(sc_idx[pairs_start]); /* ptr init */ + + + /* xor high/low pairs of delta_inp and save sign changes */ + prev_delta = sub(inp[1], inp[0]); /* precompute very first delta */ + + for(n = 1; n < inp_len_minus1; n++) + { /* sign change analysis */ + curr_delta = sub(inp[n + 1], inp[n]); /* n+1 ,n , are loop ptrs */ + if (s_xor(prev_delta, curr_delta) < 0) /* a "0" delta treated as a positive sign */ + { + *p_tmp++ = n; /* store sign change bin locations , location n in the inp[] signal */ + } + prev_delta = curr_delta; + } + + k = (LC3_INT16)(p_tmp - &(sc_idx[pairs_start])); + + /* copy sign change location values to a pairs array */ + /* leave one initial sc_idx location open for a potential initial DC value */ + + for(j = 0; j < k; j++){ + cand_pairs[j + pairs_start] = inp[sc_idx[j + pairs_start]]; + } + + /* filter away a potential single initial/trailing plateau + to enable correct analysis for adding DC or fs/2 bins */ + + + if((sub(k, 2) >= 0) && + (sub(cand_pairs[pairs_start], cand_pairs[pairs_start + 1]) == 0)){ + pairs_start = add(pairs_start, 1); + k = sub(k, 1); + } + + /* filter away potential single trailing plateu */ + pairs_end = sub(add(pairs_start, k), 1); /* point to last established sign change element */ + + if ((sub(k, 2) >= 0) && + (sub(cand_pairs[sub(pairs_end, 1)], cand_pairs[pairs_end]) == 0)){ + k = sub(k, 1); + } + pairs_end = sub(add(pairs_start, k), 1); /* recalc ptr to last element */ + + + /* conditionally add high/lows on both sides of input (pre_dc or fin) as candidates */ + add_dc_flag = 0; + add_fin_flag = 0; + + + if(sub(k, 1) == 0) /* one single sign change found special case */ + { + if (sub(inp[0], cand_pairs[pairs_start]) != 0) + { + add_dc_flag = 1; /* not plateau */ + } + + if (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) != 0) + { + add_fin_flag = 1; /* not plateau */ + } + } + + if(sub(k, 2) >= 0) + { + delta_predc = sub(cand_pairs[pairs_start + 1], cand_pairs[pairs_start]); + delta_fin = sub(cand_pairs[pairs_end], cand_pairs[pairs_end - 1]); + + /* plateaus are allowed to be detected by xor sign change, + but still not allowed at the start nor at the end */ + + add_dc_flag = 1; + if (sub(inp[0], cand_pairs[pairs_start]) == 0) + { + add_dc_flag = 0; /* plateau down or , plateaus up., --> do not add DC */ + } + + + if ((sub(inp[0], cand_pairs[pairs_start]) < 0) && (delta_predc > 0)) + { + add_dc_flag = -1; /*UP - up ... replace */ + } + + if ((sub(inp[0], cand_pairs[pairs_start]) > 0) && (delta_predc < 0)) + { + add_dc_flag = -1; /* DOWN - down ... % replace */ + } + + add_fin_flag = 1; + if (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) == 0) + { + add_fin_flag = 0; /* up - plateau ... */ + } + + if ((delta_fin > 0) && (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) < 0)) + { + add_fin_flag = -1; /* up - UP ... % replace , hard to hit */ + } + + if ((delta_fin < 0) && (sub(cand_pairs[pairs_end], inp[inp_len_minus1]) > 0)) + { + add_fin_flag = -1; /*down - DOWN ... % replace */ + } + + } + + if(add_dc_flag > 0) + { /* add DC */ + pairs_start = sub(pairs_start, 1); + cand_pairs[pairs_start] = inp[0]; + sc_idx[pairs_start] = 0; + k = add(k, 1); + } + if(add_dc_flag < 0) + { /* -1 --> replace with DC*/ + cand_pairs[pairs_start] = inp[0]; + sc_idx[pairs_start] = 0; + } + + if(add_fin_flag > 0) + { /* add FS/2 */ + pairs_end = add(pairs_end, 1); + cand_pairs[pairs_end] = inp[inp_len_minus1]; + sc_idx[pairs_end] = inp_len_minus1; + k = add(k, 1); + } + if(add_fin_flag < 0) + { /* -1, replace tail with FS/2*/ + cand_pairs[pairs_end] = inp[inp_len_minus1]; + sc_idx[pairs_end] = inp_len_minus1; + } + /* preliminary cand_pairs now only have highs , lows , no initial/trailing plateaus */ + + + /* we allow the DC/FsBy2 lows to be used as the candidatelLow */ + low_val_cand_pairs = inp_low; + val_range = sub(inp_high, low_val_cand_pairs); /* used to determine if search is useful at all */ + + + if ((sub(val_range, PEAK_LOCATOR_RES_FX) < 0) || + (sub(inp_high, sens) < 0)) + { + k = 0; + } + + + if ((k == 0) && (sub(val_range, sens) >= 0)) + { + k = 1; + } + + + if(sub(k, 2) > 0) + { + /* low, high, low, ... or + high, low, high, ...*/ + + cand_phase_start = pairs_start; /*assume first candidate is a high */ + if (sub(cand_pairs[pairs_start], cand_pairs[pairs_start + 1]) < 0) + { + cand_phase_start = add(pairs_start, 1); /* first is a low, --> skip to next higher cand */ + } + + /* high, low, high, ... */ + tmp = k; + if (sub(cand_phase_start, pairs_start) != 0) + { + tmp = sub(tmp, 1); + } + num_pairs = tmp / 2; // shr(tmp, 1); + n_tail_values = sub(tmp, num_pairs * 2); // shl(num_pairs, 1)); + + /* filter preliminary sign changes into sensitivity filtered sign changes */ + + *n_fsc = 0; /* counter of filtered fsc_idx */ + cand_high = low_val_cand_pairs; + cand_idx = -1; /* sentinel location for no high cand found yet. */ + cand_pairs[-1] = low_val_cand_pairs; + + prev_low = low_val_cand_pairs; + prev_low_plus_sens = add(prev_low, sens); + + /* filter loop for high - low sign change pairs */ + /* idx_high, idx_low are raw pointers into the cand_pairs and sc_idx arrays */ + + for(idx_high = cand_phase_start; idx_high < (cand_phase_start + 2 * num_pairs); idx_high += 2) + { + idx_low = idx_high + 1; /* loop ptr increase */ + + /* new high candidate larger than previous candidate and */ + /* sensitivity still larger than the the previous low */ + tmp = MAX(cand_high, prev_low_plus_sens); + if (sub(cand_pairs[idx_high], tmp) > 0) + { + cand_idx = idx_high; /* enable or shift candidate position fwd */ + } + cand_high = cand_pairs[cand_idx]; /* NB, cand_pairs[-1] , has the low_val_cand_pairs value stored */ + + /* now check the fwd idx_low of the current {high,low} pair */ + prev_low = MIN(cand_pairs[idx_low], prev_low); + + tmp = sub(cand_high, sens); + if(sub(tmp, cand_pairs[idx_low]) > 0) + { + /* this low point is now low enough to fix a previous high candidate */ + + fsc_idx[*n_fsc] = cand_idx; /*% add cand high idx -> output idx list*/ + *n_fsc = add(*n_fsc, 1); + + prev_low = cand_pairs[idx_low]; /* use this value as new low estimate */ + cand_idx = -1; /* no candidate until next pair or tail bin, and pt to lowVal */ + cand_high = low_val_cand_pairs; /* enable next candidate to be selected immediately */ + } + prev_low_plus_sens = add(prev_low, sens); + } /* { high, low} for loop */ + + + if((n_tail_values == 0) && (cand_idx >= 0)) + { + /* no tail low or high value to analyze + still may need to lock a non-locked but qualified candidate */ + fsc_idx[*n_fsc] = cand_idx; + *n_fsc = add(*n_fsc, 1); + } + + + /* cand_pairs vector may have a last orphan value */ + if(n_tail_values > 0) + { + /* cand_pairs vector may have a last orphan tail value */ + /* + logic boils down to if (nTailValues > 0) && (cand_pairs(n_end) > tmp) + there is a last one trailing high to process + + a) the last high, may be a new high Peak if we have not yet + locked the current candidate + b) if we have locked the last candidate, the last high may also be + a highpeak if it is high enough from the(newly set previous) valley floor. + + tmp=a||b + */ + + tmp = MAX(cand_high, prev_low_plus_sens); + tmp = sub(cand_pairs[pairs_end], tmp); + if(tmp > 0) + { + fsc_idx[*n_fsc] = pairs_end; + *n_fsc = add(*n_fsc, 1); + } + else + { + if(cand_idx >= 0) + { /* we have a previously established high candidate */ + fsc_idx[*n_fsc] = cand_idx; + *n_fsc = add(*n_fsc, 1); + } + + } + } + + /* move high locations info from fsc_idx , to output */ + for(j = 0; j < *n_fsc; j++) + { + int_plocs[j] = sc_idx[fsc_idx[j]]; + + } + + } /* end of pairs + [tail] section filtering */ + else + { + /* constant/single rise or constant decay or very low overall values, cases */ + *n_fsc = 0; + + tmp = sub(inp_high, sens); + if((k != 0) && (sub(tmp, low_val_cand_pairs) > 0)) + { + /* low,high */ + /* high,low */ + tmp = plc_phEcu_find_ind_fx(inp, inp_len, inp_high); + int_plocs[0] = tmp; /* simply locate the high peak*/ + *n_fsc = 1; + if (tmp < 0) + { /*safety in case max value index was not found */ + *n_fsc = 0; + } + } + } + + return; +} + diff --git a/lc3plus/plc_phecu_subst_spec.c b/lc3plus/plc_phecu_subst_spec.c new file mode 100644 index 0000000000000000000000000000000000000000..43f806339b8ed85c9b5a1ebae1f1586210dda817 --- /dev/null +++ b/lc3plus/plc_phecu_subst_spec.c @@ -0,0 +1,247 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "defines.h" +#include "functions.h" +#include "constants.h" + + +static LC3_INT32 own_rand(LC3_INT32 seed); +static Complex valley_magnitude_adj(Complex X_i_in, LC3_INT32 uni_seed, LC3_FLOAT cos_F); +static LC3_INT32 rand_phase(LC3_INT32 seed_in, LC3_FLOAT* cos_F); + +void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, LC3_INT32 time_offs, Complex* X, LC3_INT32 X_len, + LC3_FLOAT* mag_chg_gr, LC3_INT32 *seed, LC3_FLOAT* alpha, LC3_FLOAT* beta, LC3_FLOAT* Xavg, + LC3_INT32 t_adv_in, LC3_INT32 Lprot, LC3_INT32 delta_corr, LC3_FLOAT *corr_phase_dbg, + LC3_FLOAT *X_i_new_re_dbg, LC3_FLOAT *X_i_new_im_dbg) { + + LC3_INT32 i, i2, lprotBy2Minus1, one_peak_flag_mask, noise_mag_scale; + LC3_INT32 t_adv; + LC3_FLOAT corr_phase[MAX_PLC_NPLOCS] = {0}; + LC3_FLOAT cos_F, mag_chg_local, alpha_local, beta_local, tmp; + Complex X_i, X_i_new; + LC3_INT32 segmentLen, e; + LC3_FLOAT Xph; + LC3_FLOAT seed_local; + LC3_INT32 binCounter, subInd; + + UNUSED(corr_phase_dbg); + UNUSED(X_i_new_re_dbg); + UNUSED(X_i_new_im_dbg); + + seed_local = (LC3_FLOAT) *seed; + + + lprotBy2Minus1 = imin(320, Lprot/2 - 1); /* limit to 20 KHz */ + + + t_adv = t_adv_in + time_offs; + + for (i = 0; i < n_plocs; i++) { + corr_phase[i] = (LC3_FLOAT)2.0 * (LC3_FLOAT)M_PI * (f0est[i]/Lprot)*(LC3_FLOAT)t_adv; + } + + + // EVOLVE PHASE ----------------- + binCounter = 1; + subInd = 0; + + one_peak_flag_mask = -1; + if (n_plocs < 3 && n_plocs > 0) { + one_peak_flag_mask = 0; + } + + noise_mag_scale = 0; + if (n_plocs == 0 || time_offs != 0) { + noise_mag_scale = 1; + } + + if (n_plocs == 0) { + X[0] = realtoc(0); + X[X_len-1] = realtoc(0); + } + + + if (n_plocs != 0) { + for (i = 0; i < n_plocs; i++) { + LC3_INT32 delta_corr_dn = delta_corr; + LC3_INT32 delta_corr_up = delta_corr; + + if (i > 0) { + delta_corr_dn = imin( ((plocs[i] - plocs[i - 1] - 1) / 2), delta_corr_dn); + } + + if (i < n_plocs - 1) { + delta_corr_up = imin( ((plocs[i + 1] - plocs[i] - 1) / 2), delta_corr_up); + } + + segmentLen = (plocs[i] - delta_corr_dn) - binCounter; + + for (i2 = 0; i2 < segmentLen; i2++) { + seed_local = (LC3_FLOAT)rand_phase((LC3_INT32)seed_local, &cos_F); + + X_i = X[binCounter]; + X_i_new = cmul(X_i, cexpi((LC3_FLOAT)M_PI*seed_local / (LC3_FLOAT)32768.0)); + + + seed_local = (LC3_FLOAT)own_rand((LC3_INT32)seed_local); + + if (noise_mag_scale != 0) { + X_i = valley_magnitude_adj(X_i_new,(LC3_INT32) seed_local, cos_F); + X_i_new = X_i; + } + + mag_chg_local = mag_chg_gr[subInd]; + alpha_local = alpha[subInd]; + + if (beta[subInd] != 0) { + tmp = beta[subInd] * Xavg[subInd]; + if (one_peak_flag_mask == 0) { + tmp = 0; + X_i_new = realtoc(0); + } + X[binCounter] = cadd(cmul(realtoc(alpha_local), X_i_new), cmul(realtoc(tmp), cexpi((LC3_FLOAT)M_PI*seed_local / (LC3_FLOAT)32768.0))); + } + else { + if (one_peak_flag_mask == 0) { + X_i_new = realtoc(0); + } + + X[binCounter] = cmul(realtoc(mag_chg_local), X_i_new); + } + + binCounter++; + + if (binCounter >= gwlpr[subInd + 1]) { + subInd++; + } + } + + e = plocs[i] + delta_corr_up; + if (e > lprotBy2Minus1) { + e = lprotBy2Minus1; + } + + Xph = corr_phase[i]; + + segmentLen = e - (binCounter - 1); + + for (i2 = 0; i2 < segmentLen; i2++) + { + seed_local = (LC3_FLOAT)own_rand((LC3_INT32)seed_local); + X_i = X[binCounter]; + + { + LC3_INT32 nrep =(LC3_INT32) LC3_FLOOR(Xph / (2.0f*(LC3_FLOAT)M_PI)); + + X_i_new = cmul(X_i, cexpi(Xph - (2.0f*(LC3_FLOAT)M_PI*(LC3_FLOAT)nrep))); + } + + + seed_local = (LC3_FLOAT)own_rand((LC3_INT32)seed_local); + + mag_chg_local = mag_chg_gr[subInd]; + alpha_local = alpha[subInd]; + beta_local = beta[subInd]; + if (beta_local != 0) { + + assert(alpha_local == mag_chg_local); + tmp = beta_local * Xavg[subInd]; + + X[binCounter] = cadd(cmul(realtoc(alpha_local), X_i_new), cmul(realtoc(tmp), cexpi((LC3_FLOAT)M_PI*seed_local / (LC3_FLOAT)32768.0))); + } + else + { + X[binCounter] = cmul(realtoc(mag_chg_local), X_i_new); + } + + binCounter++; + + if (binCounter >= gwlpr[subInd + 1]) { + subInd++; + } + } + } + } + + segmentLen = lprotBy2Minus1 - (binCounter - 1); + + for (i = 0; i < segmentLen; i++) { + seed_local = (LC3_FLOAT)rand_phase((LC3_INT32)seed_local, &cos_F); + + X_i = X[binCounter]; + X_i_new = cmul(X_i, cexpi((LC3_FLOAT)M_PI*seed_local/(LC3_FLOAT)32768.0)); + + seed_local = (LC3_FLOAT)own_rand((LC3_INT32)seed_local); + + if (noise_mag_scale != 0) { + X_i = valley_magnitude_adj(X_i_new, (LC3_INT32)seed_local, cos_F); + X_i_new = X_i; + } + + if (one_peak_flag_mask == 0) { + X_i_new = realtoc(0); + } + + alpha_local = alpha[subInd]; + mag_chg_local = mag_chg_gr[subInd]; + + if (beta[subInd] != 0) { + assert(alpha_local == mag_chg_local); + tmp = beta[subInd]*Xavg[subInd]; + + if (one_peak_flag_mask == 0) { + tmp = 0; + } + + X[binCounter] = cadd(cmul(realtoc(alpha_local), X_i_new), cmul(realtoc(tmp), cexpi((LC3_FLOAT)M_PI*seed_local/(LC3_FLOAT)32768.0))); + } + else + { + X[binCounter] = cmul(realtoc(mag_chg_local), X_i_new); + } + + binCounter++; + + if (binCounter >= gwlpr[subInd + 1]) { + subInd++; + } + } + + + *seed = (LC3_INT32)seed_local; +} + +static LC3_INT32 own_rand(LC3_INT32 seed) { + LC3_INT32 retSeed; + assert(seed <= 32767 && seed >= -32768); + retSeed = (13849 + (seed + 32768) * 31821) & 65535; + retSeed -= 32768; + assert(retSeed <= 32767 && retSeed >= -32768); + return retSeed; +} + +static Complex valley_magnitude_adj(Complex X_i_in, LC3_INT32 uni_seed, LC3_FLOAT cos_F) { + LC3_FLOAT scale = ((LC3_FLOAT)0.5*(LC3_FLOAT)uni_seed/(LC3_FLOAT)32768.0) + (LC3_FLOAT)0.5*cos_F; + scale = (LC3_FLOAT)1.0 + (LC3_FLOAT)0.25*scale; + + assert(scale <= (LC3_FLOAT)1.25); + assert(scale >= (LC3_FLOAT)0.75); + + return cmul(X_i_in, realtoc(scale)); +} + +static LC3_INT32 rand_phase(LC3_INT32 seed_in, LC3_FLOAT* cos_F) { + LC3_FLOAT seed = (LC3_FLOAT)own_rand(seed_in); + *cos_F = LC3_COS((LC3_FLOAT)M_PI*seed/(LC3_FLOAT)32768.0); + return (LC3_INT32) seed; +} + diff --git a/lc3plus/plc_phecu_tba_per_band_gain.c b/lc3plus/plc_phecu_tba_per_band_gain.c new file mode 100644 index 0000000000000000000000000000000000000000..9f585f28dd8104991b5598f8f029df55f69d0433 --- /dev/null +++ b/lc3plus/plc_phecu_tba_per_band_gain.c @@ -0,0 +1,44 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "defines.h" +#include "functions.h" + + +void plc_phEcu_tba_per_band_gain(LC3_INT32 n_grp, LC3_FLOAT *gr_pow_left, LC3_FLOAT *gr_pow_right, LC3_FLOAT *trans, LC3_FLOAT *grp_pow_change) +{ + LC3_INT32 i; + + /* per band gain */ + for (i = 0; i < n_grp; i++) { + if (gr_pow_left[i] > 0) + { + trans[i] = gr_pow_right[i] / gr_pow_left[i]; + } + else + { + /* handle division by zero case */ + if (gr_pow_right[i] > 0) + { + trans[i] = 10.0; /* positive/0 transient */ + } + else + { + trans[i] = 1.0; /* 0/0 no transient , no power change */ + } + } + grp_pow_change[i] = (LC3_FLOAT) 10.0 * LC3_LOGTEN(trans[i]); + + } + + return; +} + diff --git a/lc3plus/plc_phecu_tba_spect_Xavg.c b/lc3plus/plc_phecu_tba_spect_Xavg.c new file mode 100644 index 0000000000000000000000000000000000000000..600b9714e45865fb437ea653d8de8e2dab182a23 --- /dev/null +++ b/lc3plus/plc_phecu_tba_spect_Xavg.c @@ -0,0 +1,45 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "defines.h" +#include "functions.h" + + +void plc_phEcu_tba_spect_Xavg(LC3_INT32 fs_idx, LC3_INT32 n_grp, LC3_FLOAT *oold_spec_shape, + LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_spec_shape, + LC3_FLOAT *old_EwPtr, LC3_FLOAT *gr_pow_left, LC3_FLOAT *gr_pow_right, LC3_FLOAT *Xavg) +{ + LC3_INT32 i; + LC3_FLOAT XavgEn[MAX_LGW]; + LC3_FLOAT xfp_w_scale, oold_Escale, old_Escale; + + /* 8k 16k 24k 32k 48k */ + LC3_FLOAT flt_xfp_wE_MDCT2FFT_target[5] = { (LC3_FLOAT) 1.9906, (LC3_FLOAT) 4.0445, (LC3_FLOAT) 6.0980, (LC3_FLOAT) 8.1533, (LC3_FLOAT) 12.2603 }; + LC3_INT32 gw_0[10] = { 1, 3, 5, 9, 17, 33, 49, 65, 81, 97 }; + + /* prepare scale factor */ + + xfp_w_scale = LC3_ROUND(flt_xfp_wE_MDCT2FFT_target[fs_idx]/(LC3_FLOAT)16.0*(LC3_FLOAT) 32768.0) / (LC3_FLOAT) LC3_POW(2,11); + + /* prepare left and right subband energies */ + oold_Escale = (*oold_EwPtr) * xfp_w_scale; + old_Escale = (*old_EwPtr) * xfp_w_scale; + for (i = 0;i < n_grp;i++) { + gr_pow_left[i] = oold_spec_shape[i] * oold_Escale; + gr_pow_right[i] = old_spec_shape[i] * old_Escale; + + XavgEn[i] = ((LC3_FLOAT) 0.5) * (gr_pow_left[i] + gr_pow_right[i]) / (gw_0[i + 1] - gw_0[i]); + Xavg[i] = LC3_SQRT(XavgEn[i]); + } + + return; +} + diff --git a/lc3plus/plc_phecu_tba_trans_dect_gains.c b/lc3plus/plc_phecu_tba_trans_dect_gains.c new file mode 100644 index 0000000000000000000000000000000000000000..e5f0d3caae0d71e0600e9281e0e84f7c781489b4 --- /dev/null +++ b/lc3plus/plc_phecu_tba_trans_dect_gains.c @@ -0,0 +1,320 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "defines.h" +#include "functions.h" + + +#define BETA_MUTE_FAC 0.5 /* % attenuation factor per additional bad frame, FX uses 0.5 (shift right with 1 bit) */ +#define BETA_MUTE_FAC_INI 0.5 + + +#define OFF_FRAMES_LIMIT 30 /* 300 ms for LC3 10 ms */ + + + +#define LGW32k 7 +#define LGW16k 5 + + +/* Tables for attentuation of mag_chg, copied from FX */ +/* Tables are in Q15 */ +/* 0.3 dB attenuation per frame for 16 frames, then 6 dB attenuation per frame */ +const LC3_INT32 POW_ATT_TABLE1[OFF_FRAMES_LIMIT + 1] = { 32767, 31656, 30581, 29543, 28540, 27571, 26635, 25731, 24857, 24013, + 23198, 22410, 21650, 20915, 20205, 19519, 9759, 4880, 2440, 1220, + 610, 305, 152, 76, 38, 19, 10, 5, 2, 1, + 0 }; +/* % 0.4 dB attenuation per frame for 16 frames, then 6 dB attenuation per frame */ +const LC3_INT32 POW_ATT_TABLE0[OFF_FRAMES_LIMIT + 1] = { 32767, 31293, 29885, 28540, 27255, 26029, 24857, 23738, 22670, 21650, + 20675, 19745, 18856, 18007, 17197, 16423, 8211, 4106, 2053, 1026, + 513, 257, 128, 64, 32, 16, 8, 4, 2, 1, + 0 }; + +#ifdef PLC2_FADEOUT_IN_MS +#if PLC2_FADEOUT_IN_MS == 0 +/* default setting only requieres two tables */ +const Word16* const POW_ATT_TABLES[1 + 2] = +{ NULL, POW_ATT_TABLE1/*1 0.3dB steps */ , POW_ATT_TABLE0/*2 0.4 dB steps*/, +}; +#else +const LC3_INT32 POW_ATT_TABLE_p3x8_6[] = { + 32767, 31656, 30581, 29543, 28540, 27571, 26635, 25731, 12865, 6433, + 3216, 1608, 804, 402, 201, 101, 50, 25, 13, 6, + 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; +const LC3_INT32 POW_ATT_TABLE_p4x8_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 31293, 29885, 28540, 27255, 26029, 24857, 23738, 11869, 5935, + 2967, 1484, 742, 371, 185, 93, 46, 23, 12, 6, + 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; + +const LC3_INT32 POW_ATT_TABLE_p3x4_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 31656, 30581, 29543, 14772, 7386, 3693, 1847, 923, 462, + 231, 115, 58, 29, 14, 7, 4, 2, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +const LC3_INT32 POW_ATT_TABLE_p4x4_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 31293, 29885, 28540, 14270, 7135, 3568, 1784, 892, 446, + 223, 111, 56, 28, 14, 7, 3, 2, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +const LC3_INT32 POW_ATT_TABLE_p3x2_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 31656, 15828, 7914, 3957, 1979, 989, 495, 247, 124, + 62, 31, 15, 8, 4, 2, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +const LC3_INT32 POW_ATT_TABLE_p4x2_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 31293, 15647, 7823, 3912, 1956, 978, 489, 244, 122, + 61, 31, 15, 8, 4, 2, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +const LC3_INT32 POW_ATT_TABLE_p3x1_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, + 32, 16, 8, 4, 2, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +const LC3_INT32 POW_ATT_TABLE_p4x1_6[OFF_FRAMES_LIMIT + 1] = { + 32767, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, + 32, 16, 8, 4, 2, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + +const LC3_INT32* const POW_ATT_TABLES[1 + 10] = +{ NULL, + POW_ATT_TABLE1 , POW_ATT_TABLE0, /* .3dB x16,16 6dB steps */ /* .4dB x16, 16 6dB steps */ /*original/default */ + POW_ATT_TABLE_p3x8_6, POW_ATT_TABLE_p4x8_6, /* .3dB x8, 24 6dB steps */ /* .4dB x8, 24 6dB steps */ + POW_ATT_TABLE_p3x4_6, POW_ATT_TABLE_p4x4_6, /* .3dB x4, 28 6dB steps */ /* .4dB x4, 28 6dB steps */ + POW_ATT_TABLE_p3x2_6, POW_ATT_TABLE_p4x2_6, /* .3dB x2, 30 6dB steps */ /* .4dB x2, 30 6dB steps */ + POW_ATT_TABLE_p3x1_6, POW_ATT_TABLE_p4x1_6 /* .3dB x1, 30 6dB steps */ /* .4dB x1, 30 6dB steps */ +}; +#endif +#endif + +void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *grp_pow_change, + LC3_FLOAT *stPhECU_beta_mute, LC3_FLOAT *stPhECU_mag_chg_1st, + LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, LC3_FLOAT *ph_dith, LC3_INT32 *tr_dec, + LC3_FLOAT *att_val, LC3_INT32 *attDegreeFrames_dbg, LC3_FLOAT *thresh_dbg) +{ + + LC3_INT32 i; + LC3_FLOAT thresh_tr_dB, max_increase_grp_pow; + LC3_FLOAT max_increase_grp_pow_lin; + LC3_FLOAT grp_pow_change_lin[MAX_LGW]; + LC3_FLOAT XavgFadeinFactor; + + LC3_INT32 burst_att_thresh; + LC3_INT32 att_per_frame_idx; + LC3_INT32 att_always, attDegreeFrames; + + LC3_INT32 FADEOUT_IN_MS, PLC_P800_SPEECH_FADEOUT_IN_FRAMES, + PLC2_FADEOUT_IN_FRAMES, BURST_ATT_THRESH_PRE; + const LC3_INT32 *TABLEQ15; + LC3_INT32 BURST_ATT_THRESH; /* start attenuate with losses in a row, also starts FADE2AVG actions */ + LC3_INT32 ATT_PER_FRAME; /* initial msuic attenuation table ptr, actually implemented in table lookup! */ + LC3_INT32 BETA_MUTE_THR; /* time threshold in 10 ms frames to start beta - noise attenuation */ + + UNUSED(attDegreeFrames_dbg); + + /* constants setup */ + att_always = 0; + + XavgFadeinFactor = -1.0; + + if (PLC2_FADEOUT_IN_MS != 0) + { + if (PLC2_FADEOUT_IN_MS < 0) + { + FADEOUT_IN_MS = PLC_FADEOUT_IN_MS; /* % use TDC - SETTING as input */ + } + else + { + FADEOUT_IN_MS = PLC2_FADEOUT_IN_MS; /* % use a PLC2 individual settinsg */ + } + + PLC_P800_SPEECH_FADEOUT_IN_FRAMES = (LC3_INT32) LC3_FLOOR((LC3_FLOAT)FADEOUT_IN_MS / (LC3_FLOAT)10.0); /* % nominal svaleu for speech */ + + PLC2_FADEOUT_IN_FRAMES = MIN(OFF_FRAMES_LIMIT, MAX(6, 3 * PLC_P800_SPEECH_FADEOUT_IN_FRAMES)); /* for PLC2 we typically maintain energy 3x longer */ + + BURST_ATT_THRESH_PRE = MIN(5, MAX(1, (1 * PLC2_FADEOUT_IN_FRAMES) / 6)); /* nominal 20-40 ms to start actual muting, will be thresh +1 fot assumed music */ + + ATT_PER_FRAME = MIN(10, MAX(2, 2 * (6 - BURST_ATT_THRESH_PRE))); /* % we let the BURST_ATT_thresh control the initial table selection */ + BURST_ATT_THRESH = MIN(BURST_ATT_THRESH_PRE, 4); + BETA_MUTE_THR = MIN(4 + (OFF_FRAMES_LIMIT / 2) + 1, MAX(4, BURST_ATT_THRESH + 1 + (LC3_INT32)LC3_POW((LC3_FLOAT)2.0,BURST_ATT_THRESH_PRE - (LC3_FLOAT)1))); /* nominal time to start mandatory decrease of Xavg */ + } + + + /* Initialize in the same way as done in trans_burst_ana_fx(), even though this is not really needed */ + burst_att_thresh = BURST_ATT_THRESH; + att_per_frame_idx = ATT_PER_FRAME; + + + /* 10ms constants */ + thresh_tr_dB = 10.0; /* dB threshold kept same as for 20ms, even though transient analysis frame size was shortened */ + max_increase_grp_pow = 0; /* maximum amplification(dB) in case of onset transients, offset always deacy */ + + max_increase_grp_pow_lin = (LC3_FLOAT)1.0*LC3_POW((LC3_FLOAT)10.0, max_increase_grp_pow / (LC3_FLOAT)10.0)*(LC3_FLOAT)(32767.0 / 32768.0); + + + /* envelope setting */ + burst_att_thresh = BURST_ATT_THRESH + 1; + att_per_frame_idx = ATT_PER_FRAME - 1; + + + attDegreeFrames = 0; + if (burst_len > burst_att_thresh) + { + att_always = 1; + + /* Added to be able to able to use tables to be aligned with FX */ + /* Limit attDegreeFrames to OFF_FRAMES_LIMIT */ + attDegreeFrames = burst_len - burst_att_thresh; + + if (attDegreeFrames > OFF_FRAMES_LIMIT) + { + attDegreeFrames = OFF_FRAMES_LIMIT; + } + } + + + set_vec(1.0 * (32767.0/32768.0), mag_chg, n_grp); + set_vec(0.0, ph_dith, n_grp); + + set_vec(1.0 * (32767.0/32768.0), alpha, n_grp); + set_vec(0.0, beta, n_grp); + set_vec_int(0, tr_dec, n_grp); + + set_vec(1.0 * (32767.0/32768.0), att_val, n_grp); + + + + /* transient detection per band */ + for (i = 0;i < n_grp; i++) { + if(burst_len == 1) + { + /* first bad frame */ + grp_pow_change_lin[i] = LC3_POW((LC3_FLOAT)10.0, grp_pow_change[i]/(LC3_FLOAT)10.0); + + *stPhECU_beta_mute = BETA_MUTE_FAC_INI; + *stPhECU_beta_mute = *stPhECU_beta_mute / (LC3_FLOAT)2.0; + + /* transient processing */ + /* transients may be both rise and decay transients !! */ + + + if(LC3_FABS(grp_pow_change[i]) >= thresh_tr_dB) + { + + tr_dec[i] = 1; + } + + + /* magnitude modification */ + att_val[i] = 0.0f; + if(tr_dec[i] || att_always) { + + att_val[i] = MIN(max_increase_grp_pow_lin, grp_pow_change_lin[i]); /* % linear values !! */ + att_val[i] = LC3_SQRT(att_val[i]); + mag_chg[i] = att_val[i]; + stPhECU_mag_chg_1st[i] = att_val[i]; + } + else + { + mag_chg[i] = 1.0 * (LC3_FLOAT)(32767.0/32768.0); + stPhECU_mag_chg_1st[i] = (LC3_FLOAT)1.0; + } + } + else + { + /* burst handling based on states */ + + assert(burst_len >= 2); /* states used here */ + tr_dec[i] = 0; + + if (PLC_FADEOUT_IN_MS > 0) + { + assert(att_per_frame_idx >= 1 && att_per_frame_idx <= 10); + TABLEQ15 = POW_ATT_TABLES[att_per_frame_idx]; + att_val[i] = (LC3_FLOAT)1.0 * ( (LC3_FLOAT) TABLEQ15[MIN(OFF_FRAMES_LIMIT, attDegreeFrames )] / (LC3_FLOAT)32768.0); /* Table idx 0...N-1 therefore no + 1 */ + att_val[i] = att_val[i]; + } + else + { + + if (att_per_frame_idx == ATT_PER_FRAME) + { + att_val[i] = (LC3_FLOAT)1.0 * ( (LC3_FLOAT)POW_ATT_TABLE0[MIN(OFF_FRAMES_LIMIT, attDegreeFrames)] / (LC3_FLOAT)32768.0); + } + else + { + att_val[i] = (LC3_FLOAT)1.0 * ( (LC3_FLOAT)POW_ATT_TABLE1[MIN(OFF_FRAMES_LIMIT, attDegreeFrames)] / (LC3_FLOAT)32768.0); + } + } + + + if ( (att_val[i] != 0) && (att_val[i] * (LC3_FLOAT)32768.0 < (LC3_FLOAT)0.5) ) + { + att_val[i] = 0.0; /* for SNR measurments match in float lowest possible level to BASOP representation */ + } + + /* Apply attenuation */ + mag_chg[i] = stPhECU_mag_chg_1st[i]; + + mag_chg[i] = mag_chg[i] * att_val[i]; /* add additional attenuation from burst attenation logic */ + + if ((mag_chg[i] != 0) && (mag_chg[i] * (LC3_FLOAT)32768.0 < (LC3_FLOAT)0.5)) + { + mag_chg[i] = 0; /* for SNR measurments match in float lowest possible level to BASOP representation */ + } + + + + if(burst_len > BETA_MUTE_THR) + { + *stPhECU_beta_mute = *stPhECU_beta_mute * (LC3_FLOAT)BETA_MUTE_FAC; + } + + alpha[i] = mag_chg[i]; + + if (alpha[i] >= (LC3_FLOAT)(32766.0 / 32768.0)) + { + beta[i] = 0; /* align to BASOP more efficent use of beta */ + } + else + { + beta[i] = LC3_SQRT((LC3_FLOAT)1.0 - alpha[i]* alpha[i]) * *stPhECU_beta_mute; + } + + if ( i >= LGW32k-1) { + beta[i] = beta[i] * (LC3_FLOAT)0.1; + } + else if( i >= LGW16k-1) + { + beta[i] = beta[i] * (LC3_FLOAT)0.5; + } + + + /* limit Xavg noise contribution further in case of offset / tr_decay */ + + if ((burst_len <= burst_att_thresh) && (stPhECU_mag_chg_1st[i] < (LC3_FLOAT)(32767.0 / 32768.0))) + { + XavgFadeinFactor = (LC3_FLOAT)(burst_len - (LC3_FLOAT)1.0) / burst_att_thresh; + + XavgFadeinFactor = MIN((LC3_FLOAT)1.0, XavgFadeinFactor); + + beta[i] = beta[i] * XavgFadeinFactor; + + } + } + } + + if (thresh_dbg != NULL) + { + *thresh_dbg = XavgFadeinFactor; + } + + return; +} + diff --git a/lc3plus/plc_phecu_trans_burst_ana_sub.c b/lc3plus/plc_phecu_trans_burst_ana_sub.c new file mode 100644 index 0000000000000000000000000000000000000000..c860cd6ce3d69968dbd7b217ae7f363a7e791e27 --- /dev/null +++ b/lc3plus/plc_phecu_trans_burst_ana_sub.c @@ -0,0 +1,48 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "defines.h" +#include "functions.h" + + +void plc_phEcu_trans_burst_ana_sub(LC3_INT32 fs_idx, LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *oold_spect_shape, + LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_spect_shape, + LC3_FLOAT *old_EwPtr, LC3_FLOAT *stPhECU_beta_mute, + LC3_FLOAT *stPhECU_mag_chg_1st, LC3_FLOAT *stPhECU_Xavg, LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg) +{ + LC3_FLOAT gr_pow_left[MAX_LGW]; + LC3_FLOAT gr_pow_right[MAX_LGW]; + LC3_FLOAT trans[MAX_LGW]; + LC3_FLOAT grp_pow_change[MAX_LGW]; + LC3_FLOAT ph_dith[MAX_LGW]; + LC3_FLOAT att_val[MAX_LGW]; + LC3_INT32 tr_dec[MAX_LGW]; + + LC3_INT32 attDegreeFrames; + LC3_FLOAT thresh_dbg; + + UNUSED(tr_dec_dbg); + UNUSED(gpc_dbg); + + if (burst_len <= 1) + { + plc_phEcu_tba_spect_Xavg(fs_idx, n_grp, oold_spect_shape, oold_EwPtr, old_spect_shape, old_EwPtr, gr_pow_left, gr_pow_right, stPhECU_Xavg); + + plc_phEcu_tba_per_band_gain(n_grp, gr_pow_left, gr_pow_right, trans, grp_pow_change); + + } + + + plc_phEcu_tba_trans_dect_gains(burst_len, n_grp, grp_pow_change, stPhECU_beta_mute, stPhECU_mag_chg_1st, alpha, beta, mag_chg, ph_dith, tr_dec, att_val, &attDegreeFrames, &thresh_dbg); + + return; +} + diff --git a/lc3plus/plc_tdc.c b/lc3plus/plc_tdc.c new file mode 100644 index 0000000000000000000000000000000000000000..1a1a408f4d9d3b6216f048c34704735256eb5562 --- /dev/null +++ b/lc3plus/plc_tdc.c @@ -0,0 +1,763 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +/***************************************************************************\ + * contents/description: Main function for Time domain concealment +\***************************************************************************/ + +#include +#include "functions.h" + + +static LC3_INT16 TDC_random_short(LC3_INT16 *seed); +static LC3_FLOAT TDC_get_gainp(const LC3_FLOAT x[], const LC3_FLOAT y[], LC3_INT32 n); +static LC3_FLOAT TDC_get_gainc(const LC3_FLOAT x[], const LC3_FLOAT y[], const LC3_FLOAT *gain_p, const LC3_INT32 n, const LC3_INT32 frame_dms); +static void TDC_LPC_synthesis(const LC3_FLOAT a[], LC3_FLOAT x[], LC3_FLOAT y[], LC3_INT32 l, const LC3_FLOAT mem[], LC3_INT32 lpcorder, LC3_FLOAT *buf); +static void TDC_LPC_residu(const LC3_FLOAT *a, LC3_FLOAT *x, LC3_FLOAT *y, LC3_INT32 l, LC3_INT32 lpcorder); +static void TDC_highPassFiltering(const LC3_INT32 L_buffer, LC3_FLOAT exc2[], const LC3_FLOAT hp_filt[], const LC3_INT32 l_fir_fer); +static void TDC_f_preemph(LC3_FLOAT *signal, const LC3_FLOAT *mu, LC3_INT32 L, LC3_FLOAT *mem); +static void TDC_deemph(LC3_FLOAT *signal, const LC3_FLOAT *mu, LC3_INT32 L, const LC3_FLOAT *mem); +const LC3_FLOAT TDC_high_16[TDC_L_FIR_HP] = { 0.f, -0.0205f, -0.0651f, -0.1256f, -0.1792f, 0.8028f, -0.1792f, -0.1256f, -0.0651f, -0.0205f, 0.f }; +const LC3_FLOAT TDC_high_32[TDC_L_FIR_HP] = {-0.0517f, -0.0587f, -0.0820f, -0.1024f, -0.1164f, 0.8786f, -0.1164f, -0.1024f, -0.0820f, -0.0587f, -0.0517f}; +const LC3_FLOAT TDC_high_16_harm[TDC_L_FIR_HP] = { 0.0053f, 0.0000f, -0.0440f, 0.0000f, 0.2637f, 0.5500f, 0.2637f, 0.0000f, -0.0440f, 0.0000f, 0.0053f}; +const LC3_FLOAT TDC_high_32_harm[TDC_L_FIR_HP] = {-0.0053f, -0.0037f, -0.0140f, 0.0180f, 0.2668f, 0.4991f, 0.2668f, 0.0180f, -0.0140f, -0.0037f, -0.0053f}; +static void TDC_levinson(LC3_FLOAT *acf, LC3_INT32 len, LC3_FLOAT *out); +static void TDC_copyFLOAT(const LC3_FLOAT * X, LC3_FLOAT * Z, LC3_INT32 n); +static LC3_FLOAT TDC_dotFLOAT(const LC3_FLOAT * X, const LC3_FLOAT * Y, LC3_INT32 n); + +const LC3_INT32 beforeNextIncArray[4][4] = {{0,0,0,1}, + {0,1,0,1}, + {0,1,1,1}, + {1,1,1,1}}; +const LC3_INT32 nextIncArray[4][4] = {{1,0,0,0}, + {1,0,1,0}, + {1,0,1,1}, + {1,1,1,1}}; + +void processTdcApply_fl(const LC3_INT32 pitch_int, + const LC3_FLOAT *preemphFac, + const LC3_FLOAT* A, + const LC3_INT32 lpc_order, + const LC3_FLOAT* pcmbufHist, + const LC3_INT32 max_len_pcm_plc, + const LC3_INT32 N, + const LC3_INT32 frame_dms, + const LC3_INT32 SampRate, + const LC3_INT32 nbLostFramesInRow, + const LC3_INT32 overlap, + const LC3_FLOAT *stabFac, + LC3_FLOAT harmonicBuf[MAX_PITCH], + LC3_FLOAT synthHist[M], + LC3_INT32* fract, + LC3_INT16* seed, + LC3_FLOAT* gain_c, + LC3_FLOAT* alpha, + LC3_FLOAT* synth + ) +{ + LC3_FLOAT step, step_n; + LC3_INT32 i, len, Tc, nbLostCmpt_loc, nextInc, beforeNextInc; + LC3_FLOAT gain_h, tmp, gain_p; + LC3_FLOAT *exc2, *exc_buf, *exc, *x_pre, *buf, *pt_exc, *pt1_exc, *synthMemPtr; + LC3_FLOAT *harmonicBufPtr; + LC3_FLOAT synth_mem[M]; + const LC3_FLOAT *hp_filt, *high_harm; + LC3_FLOAT gainInov; + LC3_FLOAT hpBlendFac; + char *scratchSpace1st, *scratchSpaceTmp; + char scratchSpace[(MAX_LEN_PCM_PLC + MDCT_MEM_LEN_MAX + MAX_LEN_PCM_PLC + 1 + M) * sizeof(LC3_FLOAT)]; + LC3_FLOAT alphaPrev; + LC3_FLOAT throttle; + LC3_INT32 frame_dms_idx, nbLostFramesInRow_mod; + + memset(synth_mem, 0, M * sizeof(LC3_FLOAT)); + memset(scratchSpace, 0, (MAX_LEN_PCM_PLC + MDCT_MEM_LEN_MAX + MAX_LEN_PCM_PLC + 1 + M) * sizeof(LC3_FLOAT)); + + /* len of synthesized signal */ + len = N + overlap; + + nbLostCmpt_loc = floor(frame_dms/100.0 * (nbLostFramesInRow - 1) + 1); + frame_dms_idx = frame_dms / 25 - 1; /* 0,1,2,3 */ + nbLostFramesInRow_mod = (nbLostFramesInRow - 1) % 4; + + beforeNextInc = beforeNextIncArray[frame_dms_idx][nbLostFramesInRow_mod]; + nextInc = nextIncArray [frame_dms_idx][nbLostFramesInRow_mod]; + + if (nbLostCmpt_loc > PLC_FADEOUT_IN_MS/10) + { + gain_p = 0; + *gain_c = 0; + *alpha = 0; + memset(synth, 0, len * sizeof(LC3_FLOAT)); + return; + } + + Tc = pitch_int; + if (*fract > 0) { + Tc++; + } + + /*---------------------------------------------------------------- + * Buffer Initialization for timeDomainConcealment_Apply + * + * 1st + * |--exc_buf--|--x_pre--| + * | |--exc2--| + * | |--buf (LPC Syn)--| + * + *---------------------------------------------------------------*/ + + scratchSpace1st = scratchSpace; + exc_buf = (LC3_FLOAT*)scratchSpace1st; scratchSpace1st += (LC3_INT32)sizeof(LC3_FLOAT) * (Tc + N/2 + len); + exc = exc_buf + (Tc + N/2); + + scratchSpaceTmp = scratchSpace1st; + x_pre = (LC3_FLOAT*)scratchSpaceTmp; scratchSpaceTmp += (LC3_INT32)sizeof(LC3_FLOAT) * (lpc_order + Tc + N/2 + 1); + + /*---------------------------------------------------------------* + * LPC Residual * + *---------------------------------------------------------------*/ + if (nbLostFramesInRow == 1) + { + /* copy buffer to pre-emphasis buffer */ + TDC_copyFLOAT(&(pcmbufHist[max_len_pcm_plc-(lpc_order+Tc+N/2+1)]), &(x_pre[0]), lpc_order+Tc+N/2+1); + + /* apply pre-emphasis to the signal */ + TDC_f_preemph(&(x_pre[1]), preemphFac, lpc_order+Tc+N/2, &x_pre[0]); + + /* copy memory for LPC synth */ + TDC_copyFLOAT(&(x_pre[Tc+N/2+1]), synth_mem, lpc_order); + + /* LPC Residual */ + TDC_LPC_residu(A, &(x_pre[lpc_order+1]), &(exc[-(Tc+N/2)]), Tc+N/2, lpc_order); + } + + /*---------------------------------------------------------------* + * Calculate gains * + *---------------------------------------------------------------*/ + if (nbLostFramesInRow == 1) + { + if (pitch_int == Tc) + { + gain_p = TDC_get_gainp( &(x_pre[lpc_order+Tc+1]), &(x_pre[lpc_order+1]), N/2 ); + } + else + { + tmp = TDC_get_gainp( &(x_pre[lpc_order+Tc+1]), &(x_pre[lpc_order+2]), N/2 ); + gain_p = TDC_get_gainp( &(x_pre[lpc_order+Tc+1]), &(x_pre[lpc_order+1]), N/2 ); + + if (tmp > gain_p) { + Tc = pitch_int; + gain_p = tmp; + *fract = 0; + } + } + + if(gain_p < 0.0f) + { + gain_p = 0.0f; + } + + if(gain_p > 1.0f) + { + gain_p = 1.0f; + } + + *gain_c = 0.0f; + + if (pitch_int == Tc) + { + *gain_c = TDC_get_gainc( &(exc[-1]), &(exc[-1-Tc]), &gain_p, N/2, frame_dms ); + } + else + { + tmp = TDC_get_gainc( &(exc[-1]), &(exc[-1-pitch_int]), &gain_p, N/2, frame_dms ); + *gain_c = TDC_get_gainc( &(exc[-1]), &(exc[-1-Tc]) , &gain_p, N/2, frame_dms ); + *gain_c = MIN(*gain_c, tmp); + } + } + else + { + gain_p = *alpha; + } + + /*---------------------------------------------------------------* + * Damping factor * + *---------------------------------------------------------------*/ + + alphaPrev = 1; + if (nbLostFramesInRow > 1) + { + alphaPrev = *alpha; + } + + if (nextInc != 0) + { + switch (nbLostCmpt_loc) + { + case 1: + *alpha = (LC3_FLOAT)sqrt(gain_p); + if ( *alpha > 0.98f ) + { + *alpha = 0.98f; + } + else if ( *alpha < 0.925f ) + { + *alpha = 0.925f; + } + break; + case 2: + *alpha = (0.63f + 0.35f * (*stabFac)) * gain_p; + if ( *alpha < 0.919f ) + { + *alpha = 0.919f; + } + break; + default: + *alpha = (0.652f + 0.328f * (*stabFac)) * gain_p; + } + } + + if (nbLostCmpt_loc > 3) + { + switch (frame_dms) + { + case 25: *alpha *= PLC34_ATTEN_FAC_025; break; + case 50: *alpha *= PLC34_ATTEN_FAC_050; break; + case 100: *alpha *= PLC34_ATTEN_FAC_100; break; + } + } + + if (nbLostCmpt_loc > 5) + { + gain_p = *alpha; + } + + /*---------------------------------------------------------------* + * Construct the harmonic part * + * Last pitch cycle of the previous frame is repeatedly copied. * + *---------------------------------------------------------------*/ + + pt_exc = harmonicBuf; + pt1_exc = exc - Tc; + + if( nbLostFramesInRow == 1 ) + { + if (*stabFac >= 1) + { + TDC_copyFLOAT(pt1_exc, pt_exc, Tc); + } + else + { + /* These values are necessary for the last five filtered samples */ + TDC_copyFLOAT(&exc[-Tc], exc, (TDC_L_FIR_HP-1)/2); + + high_harm = TDC_high_32_harm; + if (SampRate <= 16000) + { + high_harm = TDC_high_16_harm; + } + + for( i = 0; i < Tc; i++ ) + { + pt_exc[i] = TDC_dotFLOAT(&pt1_exc[i-(TDC_L_FIR_HP-1)/2], high_harm, TDC_L_FIR_HP); + } + } + } + + /*---------------------------------------------------------------* + * Construct the random part of excitation * + *---------------------------------------------------------------*/ + scratchSpaceTmp = scratchSpace1st; + exc2 = (LC3_FLOAT*)scratchSpaceTmp; scratchSpaceTmp += (LC3_INT32)sizeof(LC3_FLOAT) * (len + TDC_L_FIR_HP - 1); + + for (i = 0; i < len + TDC_L_FIR_HP - 1; i++) { + exc2[i] = (LC3_FLOAT)TDC_random_short(seed); + } + + /* high pass noise */ + if (SampRate <= 16000 ) + { + hp_filt = TDC_high_16; + } else { + hp_filt = TDC_high_32; + } + + if ( nbLostFramesInRow == 1 ) + { + TDC_highPassFiltering(len, exc2, hp_filt, TDC_L_FIR_HP); + } + else + { + /* moves from 0 to 1, speed is defined by PLC3_HPBLENDTHROTTLE */ + throttle = (LC3_FLOAT)nbLostCmpt_loc / (nbLostCmpt_loc + PLC3_HPBLENDTHROTTLE); + hpBlendFac = (1 - *alpha) * throttle; + + for (i = 0; i < len; i++) + { + exc2[i] = hpBlendFac * exc2[i+TDC_L_FIR_HP/2] + (1 - hpBlendFac) * TDC_dotFLOAT(&exc2[i], hp_filt, TDC_L_FIR_HP ); + } + } + + /* normalize energy */ + gainInov = 1.0f / (LC3_FLOAT)sqrt(TDC_dotFLOAT( exc2, exc2, N ) / (LC3_FLOAT)N + 0.01f ); + gainInov *= (1.1f - 0.75* gain_p); + + /* gains */ + gain_h = alphaPrev; + tmp = *gain_c * *alpha / alphaPrev; + + /* update steps */ + step = (1.0f/(LC3_FLOAT)N) * (gain_h - *alpha); + step_n = (1.0f/(LC3_FLOAT)N) * (*gain_c - tmp); + + /*---------------------------------------------------------------* + * Construct the total excitation * + *---------------------------------------------------------------*/ + harmonicBufPtr = harmonicBuf + ((nbLostFramesInRow - 1) * N) % Tc; + + for ( i = 0; i < len; i++ ) { + /* harmonic */ + if (harmonicBufPtr - harmonicBuf >= Tc) { + harmonicBufPtr = harmonicBuf; + } + exc[i] = *harmonicBufPtr++; + exc[i] *= gain_h; + + /* random */ + exc2[i] *= *gain_c * gainInov; + + /* total */ + exc[i] = exc[i] + exc2[i]; + + /* update */ + gain_h -= step; + gain_h = MAX(gain_h, 0); + *gain_c -= step_n; + *gain_c = MAX(*gain_c, 0); + } + + *gain_c = tmp; + + /*----------------------------------------------------------* + * Compute the synthesis speech * + *----------------------------------------------------------*/ + buf = (LC3_FLOAT*)scratchSpace1st; scratchSpace1st += (LC3_INT32)sizeof(LC3_FLOAT) * (len + lpc_order); + synthMemPtr = synth_mem; + if (nbLostFramesInRow != 1) + { + synthMemPtr = synthHist; + } + + TDC_LPC_synthesis(A, + &exc[0], + synth, + len, + synthMemPtr, + lpc_order, + buf); + + TDC_copyFLOAT(&synth[N-lpc_order], synthHist, lpc_order); + + /*----------------------------------------------------------* + * Deemphasis * + *----------------------------------------------------------*/ + TDC_deemph( synth, preemphFac, len, &pcmbufHist[max_len_pcm_plc-1] ); + + /*----------------------------------------------------------* + * Fade to zero * + *----------------------------------------------------------*/ + if (beforeNextInc != 0) + { + if (nbLostCmpt_loc == PLC_FADEOUT_IN_MS/10) + { + gain_h = 1; + step = 1.0f/(LC3_FLOAT)N; + for ( i = 0; i < N; i++ ) { + synth[i] *= gain_h; + gain_h -= step; + } + memset(&synth[N], 0, overlap * sizeof(LC3_FLOAT)); + } + } +} + +/* Take only real part */ +void processTdcInverseOdft_fl(LC3_FLOAT *in, LC3_INT32 n_bands, LC3_FLOAT *out, LC3_INT32 lpc_order) +{ + LC3_INT32 i, j, k; + LC3_FLOAT buf[2*MAX_BANDS_NUMBER_PLC]; + Complex sum; + Complex res; + + /* Buffer for ifft */ + j = 0; + for (i = 0; i < n_bands - 1; i += 2) + { + buf[j] = in[i]; + j++; + } + + for (i = n_bands - 1; i > 0; i -= 2) + { + buf[j] = in[i]; + j++; + } + + for (i = 0; i < n_bands; i++) + { + buf[j] = in[i]; + j++; + } + + /* ifft */ + for (j = 0; j < n_bands; j++) + { + sum.r = 0, sum.i = 0; + res.r = 0, res.i = 0; + for (k = 0; k < n_bands; k++) + { + res = cexpi((2 * M_PI * (LC3_FLOAT) (j * k)) / (LC3_FLOAT) n_bands); + res.r = res.r * buf[k]; + res.i = res.i * buf[k]; + sum = cadd(sum, res); + } + + res = cexpi((LC3_FLOAT) j * M_PI / (2.0 * (LC3_FLOAT) n_bands)); + out[j] = (sum.r * res.r - sum.i * res.i); + } + + out[0] = out[0] * 1.0001; + if (out[0] == 0) + { + out[0] = 1; + zero_float(&out[1], lpc_order); + } +} + +void processTdcPreemphasis_fl(LC3_FLOAT *in, LC3_FLOAT *pre_emph_factor, LC3_INT32 n_bands) +{ + LC3_INT32 i; + + for (i = 0; i < n_bands; i++) + { + in[i] = in[i] * (1.0 - 2.0 * (*pre_emph_factor) * LC3_COS(2.0 * M_PI * (0.5 + (LC3_FLOAT) i) / (2.0 * (LC3_FLOAT) n_bands)) + (*pre_emph_factor) * (*pre_emph_factor)); + } +} + +void processTdcLpcEstimation_fl(LC3_FLOAT *r, LC3_INT32 fs_idx, LC3_INT32 len, LC3_FLOAT *A, LC3_INT32 frame_dms) +{ + LC3_INT32 i; + const LC3_FLOAT *lpc_array; + + lpc_array = plc_tdc_lpc_all[fs_idx]; + + if (fs_idx == 0 && frame_dms == 25) + { + lpc_array = plc_tdc_lpc_8_25ms; + } + + /* r[0] = r[0] * 1 */ + for (i = 1; i < len; i++) + { + r[i] = r[i] * lpc_array[i]; + } + + TDC_levinson(r, len - 1, A); +} + +/** random + * + * Parameters: + * seed I/O: seed for random number + * + * Function: + * Signed 16 bits random generator. + * + * Returns: + * random number + */ +static LC3_INT16 TDC_random_short(LC3_INT16 *seed) +{ + *seed = (LC3_INT16) (*seed * 12821L + 16831L); + return(*seed); +} + +static LC3_FLOAT TDC_get_gainp( /* output: gain of pitch */ + const LC3_FLOAT x[], /* input : input signal */ + const LC3_FLOAT y[], /* input : shifted input signal */ + LC3_INT32 n /* input : vector length */ +) +{ + LC3_FLOAT corr, ener; + LC3_INT16 i; + + corr = 0; ener = 1e-6f; + + for (i = 0; i < n; i++) + { + corr += x[i]*y[i]; + ener += y[i]*y[i]; + } + + return(corr/ener); +} + +static LC3_FLOAT TDC_get_gainc( /* output: gain of code */ + const LC3_FLOAT x[], /* input : input signal */ + const LC3_FLOAT y[], /* input : shifted input signal */ + const LC3_FLOAT *gain_p, /* input : gain of pitch */ + const LC3_INT32 n, /* input : vector length */ + const LC3_INT32 frame_dms /* input : frame length in dms */ +) +{ + LC3_FLOAT gain_c; + LC3_FLOAT gain_c_max; + LC3_INT16 i; + + gain_c = 0; gain_c_max = 0; + + for (i = 0; i < n; i++) + { + gain_c += ( x[-i] - *gain_p * y[-i] ) * ( x[-i] - *gain_p * y[-i] ); + } + + if (frame_dms < 100) + { + for (i = 0; i < n; i++) + { + gain_c_max += (x[-i] * x[-i]); + } + gain_c = MIN(gain_c, gain_c_max); + } + + gain_c = (LC3_FLOAT)sqrt(gain_c / n ); + + return gain_c; +} + +static void TDC_highPassFiltering(const LC3_INT32 L_buffer, /* i: buffer length */ + LC3_FLOAT exc2[], /* i/o: unvoiced excitation before the high pass filtering */ + const LC3_FLOAT hp_filt[], /* i: high pass filter coefficients */ + const LC3_INT32 l_fir_fer) /* i: high pass filter length */ +{ + LC3_INT32 i; + + for( i=0 ; i< L_buffer; i++ ) { + exc2[i] = TDC_dotFLOAT(&exc2[i], hp_filt, l_fir_fer); + } +} + +static void TDC_LPC_synthesis( + const LC3_FLOAT a[], + LC3_FLOAT x[], + LC3_FLOAT y[], + LC3_INT32 l, + const LC3_FLOAT mem[], + LC3_INT32 lpcorder, + LC3_FLOAT *buf + ) +{ + LC3_FLOAT s, *yy; + LC3_INT32 i, j; + + /* copy initial filter states into synthesis buffer */ + for (i=0; i < lpcorder; i++) + { + buf[i] = mem[i]; + } + yy = &buf[i]; + + for (i = 0; i < l; i++) + { + s = x[i]; + for (j = 1; j <= lpcorder; j++) + { + s -= a[j] * yy[i- j]; + } + y[i] = s; + yy[i] = y[i]; + } + + return; +} + + +/** TDC_LPC_residu + * + * Parameters: + * a I: LP filter coefficients (Q12) + * x I: input signal (usually speech) + * y O: output signal (usually residual) + * l I: size of filtering + * lpcorder I: Order of LP filter + * + * Function: + * Compute the LP residual by filtering the input speech through A(z). + * + * Returns: + * void + */ +static void TDC_LPC_residu(const LC3_FLOAT *a, LC3_FLOAT *x, LC3_FLOAT *y, LC3_INT32 l, LC3_INT32 lpcorder) +{ + LC3_FLOAT s; + LC3_INT32 i, j; + + for (i = 0; i < l; i++) + { + s = x[i]; + for (j = 1; j <= lpcorder; j++) + { + s += a[j] * x[i - j]; + } + y[i] = s; + } + + return; +} + + +/** TDC_f_preemph + * + * Parameters: + * signal I/O: signal + * mu I: preemphasis factor + * L I: vector size + * mem I: memory (x[-1]) + * + * Function: + * Filtering through 1 - mu z^-1 + * + * + * Returns: + * void + */ + +static void TDC_f_preemph(LC3_FLOAT *signal, const LC3_FLOAT *mu, LC3_INT32 L, LC3_FLOAT *mem) +{ + LC3_INT32 i; + + for (i = L - 1; i > 0; i--) + { + signal[i] = signal[i] - *mu * signal[i - 1]; + } + + signal[0] -= *mu * (*mem); + + return; +} + +/* + * TDC_deemph + * + * Parameters: + * signal I/O: signal + * mu I: deemphasis factor + * L I: vector size + * mem I: memory (signal[-1]) + * + * Function: + * Filtering through 1/(1-mu z^-1) + * Signal is divided by 2. + * + * Returns: + * void + */ +static void TDC_deemph(LC3_FLOAT *signal, const LC3_FLOAT *mu, LC3_INT32 L, const LC3_FLOAT *mem) +{ + LC3_INT32 i; + + signal[0] = signal[0] + *mu * (*mem); + + for (i = 1; i < L; i++) + { + signal[i] = signal[i] + *mu * signal[i - 1]; + } + + return; +} + +static void TDC_copyFLOAT(const LC3_FLOAT * X, LC3_FLOAT * Z, LC3_INT32 n) +{ + /* no values to copy */ + if ( (n < 1) || (X == Z) ){ + return; + } + /* If overlapping */ + if ( ( (Z > X) && (Z < X+n) ) || ( (Z < X) && (X < Z+n) ) ) { + memmove(Z, X, sizeof(LC3_FLOAT)*n); + } + else{ + memcpy(Z, X, sizeof(LC3_FLOAT)*n); + } +} + +static LC3_FLOAT TDC_dotFLOAT(const LC3_FLOAT * X, const LC3_FLOAT * Y, LC3_INT32 n) +{ + LC3_FLOAT acc; + LC3_INT32 i; + + acc = 0; + if (n) { + acc = X[0]*Y[0]; + } + + for (i=1; i= 0; i--) + { + out[j] = buf[k] - g * buf2[i]; + j++; k++; + } + + v = v * (1.0 - g * g); + } + + move_float(buf, out, len); + out[0] = 1; + + j = 1; + for (i = len - 1; i >= 0; i--) + { + out[j] = -buf[i]; + j++; + } +} + diff --git a/lc3plus/plc_tdc_tdac.c b/lc3plus/plc_tdc_tdac.c new file mode 100644 index 0000000000000000000000000000000000000000..329361b14c7f995b74a6ca2de051011c81ec088c --- /dev/null +++ b/lc3plus/plc_tdc_tdac.c @@ -0,0 +1,80 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + + +void processTdcTdac_fl(const LC3_FLOAT *synth_inp, const LC3_FLOAT *win, LC3_INT32 frame_length, LC3_INT32 la_zeroes, LC3_FLOAT *ola_mem) +{ + LC3_INT32 i, L, LD2, NZ, synth_len; + LC3_FLOAT synth[(MAX_LEN + MDCT_MEM_LEN_MAX)], *synth1, *synth2, *ola_mem1, *ola_mem2, sz; + const LC3_FLOAT *win1, *win2, *win3, *win4; + + assert(la_zeroes <= frame_length / 2); + + L = frame_length; + LD2 = L/2; + NZ = LD2 - la_zeroes; + synth_len = 2*L - la_zeroes; + + move_float(synth, synth_inp, synth_len); + + /* calculate x_ov[L+la_zeroes] ... x_ov[2*L-1] */ + win1 = &win[L + LD2 - 1]; + win2 = &win[L + LD2]; + + win3 = &win[LD2 - 1]; + win4 = &win[LD2]; + + synth1 = &synth[L + LD2 - 1 - la_zeroes]; + synth2 = &synth[L + LD2 - la_zeroes]; + + ola_mem1 = &ola_mem[LD2 - la_zeroes]; + ola_mem2 = &ola_mem[LD2 - la_zeroes - 1]; + + for (i = 0; i < NZ; i++) + { + /* analysis windowing + 2N -> N */ + sz = *synth1 * *win1 + *synth2 * *win2; + + /* N -> 2N + synthesis windowing */ + *ola_mem1 = sz * *win3; + *ola_mem2 = sz * *win4; + + /* pointer update */ + win1--; + win2++; + win3--; + win4++; + synth1--; + synth2++; + ola_mem1++; + ola_mem2--; + } + + for (; i < LD2; i++) + { + /* analysis windowing + 2N -> N */ + sz = *synth1 * *win1; + + /* N -> 2N + synthesis windowing */ + *ola_mem1 = sz * *win3; + + /* pointer update */ + win1--; + win2++; + win3--; + synth1--; + synth2++; + ola_mem1++; + } +} + diff --git a/lc3plus/plc_update.c b/lc3plus/plc_update.c new file mode 100644 index 0000000000000000000000000000000000000000..a151420eb7484c7fca0aaa3af5b67f4f994eec27 --- /dev/null +++ b/lc3plus/plc_update.c @@ -0,0 +1,125 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" +#include "options.h" + + +void processPlcUpdate_fl(PlcAdvSetup *PlcAdvSetup, LC3_INT32 frame_length, LC3_FLOAT *syntM, LC3_FLOAT *scf_q, + LC3_INT32 *nbLostCmpt, LC3_FLOAT *cum_alpha, LC3_INT32 bfi, LC3_INT32 *prevBfi, LC3_INT32 *prevprevBfi) +{ + LC3_FLOAT tmp[MAX_LEN_PCM_PLC]; + + move_float(tmp, &PlcAdvSetup->pcmbufHist[frame_length], PlcAdvSetup->max_len_pcm_plc - frame_length); + move_float(&PlcAdvSetup->pcmbufHist[0], tmp, PlcAdvSetup->max_len_pcm_plc - frame_length); + move_float(&PlcAdvSetup->pcmbufHist[PlcAdvSetup->max_len_pcm_plc - frame_length], syntM, frame_length); + + if (bfi != 1) + { + *nbLostCmpt = 0; + *cum_alpha = 1; + + if (PlcAdvSetup) + { + move_float(PlcAdvSetup->scf_q_old_old, PlcAdvSetup->scf_q_old, M); + move_float(PlcAdvSetup->scf_q_old, scf_q, M); + /* PLC fullband transient detector setting for non-bfi frames */ + PlcAdvSetup->PlcPhEcuSetup.PhECU_short_flag_prev = 0; /* fullband transient not active */ + } + } + + *prevprevBfi = *prevBfi; + *prevBfi = bfi; +} + +void plc_phEcu_processPLCspec2shape(LC3_INT16 prev_bfi, LC3_INT16 bfi, LC3_FLOAT q_d[], LC3_INT32 yLen, + LC3_FLOAT *stPhECU_oold_grp_shape, LC3_FLOAT *stPhECU_old_grp_shape) +{ + LC3_INT32 i, j, N_grp; + LC3_INT32 local_prev_bfi; + LC3_INT32 fs_idx; + LC3_FLOAT E_tot = 0.0; + LC3_INT32 l_grp; + LC3_FLOAT *pX; + + if (bfi != 1) /* compute only for bfi== 0 or 2 */ + { + fs_idx = (LC3_INT32)floor(yLen / 100); + assert(fs_idx < 5); + N_grp = xavg_N_grp[fs_idx]; + + local_prev_bfi = prev_bfi; + if (local_prev_bfi == 2) { + local_prev_bfi = 0; + } + + + /* Copy old to oold grp shape */ + for (i = 0; i < MAX_LGW; i++) + { + stPhECU_oold_grp_shape[i] = stPhECU_old_grp_shape[i]; + } + + /* Accumulate DC-coupled bins to total */ + E_tot = 0; + pX = q_d; /* ptr setup */ + for (i = 0; i < mdct_grp_bins[0]; i++) + { + E_tot += sqrf( *pX ); + pX++; + } + + /* Accumulate middle grps and add to total */ + for (i = 0; i < (N_grp - 1); i++) + { + l_grp = mdct_grp_bins[i + 1] - mdct_grp_bins[i]; ; + stPhECU_old_grp_shape[i] = 0.0; + for (j = 0; j < l_grp; j++) { + stPhECU_old_grp_shape[i] += sqrf( *pX ); + pX++; + } + E_tot += stPhECU_old_grp_shape[i]; + } + + /* Accumulate last subbband and add to total */ + stPhECU_old_grp_shape[(N_grp - 1)] = 0.0; + l_grp = mdct_grp_bins[N_grp] - mdct_grp_bins[N_grp - 1] - mdct_grp_bins[0]; + assert( (mdct_grp_bins[N_grp] - mdct_grp_bins[0]) <= yLen); + for (j = 0; j < l_grp; j++) + { + stPhECU_old_grp_shape[(N_grp - 1)] += sqrf( *pX ); + pX++; + } + E_tot += stPhECU_old_grp_shape[(N_grp - 1)]; + + + /* Normalize shape */ + for (i = 0; i < (N_grp); i++) { + if (E_tot > 0.0) { + stPhECU_old_grp_shape[i] /= E_tot; + } + else + { + stPhECU_old_grp_shape[i] = 0.0; + } + } + if (local_prev_bfi == 1) { + for (i = 0; i < MAX_LGW; i++) { + stPhECU_oold_grp_shape[i] = stPhECU_old_grp_shape[i]; + } + } + }/*bfi*/ + return; +} + +void processPlcUpdateSpec_fl(LC3_FLOAT *q_d_prev, LC3_FLOAT *q_d_fl_c, LC3_INT32 yLen) +{ + move_float(q_d_prev, q_d_fl_c, yLen); +} + diff --git a/lc3plus/quantize_spec.c b/lc3plus/quantize_spec.c new file mode 100644 index 0000000000000000000000000000000000000000..7886b4586d6e412a8c9aa44dbf004ed738ec61a6 --- /dev/null +++ b/lc3plus/quantize_spec.c @@ -0,0 +1,196 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +static LC3_INT sign(LC3_FLOAT x); + +LC3_INT sign(LC3_FLOAT x) +{ + if (x > 0) + return 1; + + if (x < 0) + return -1; + + return 0; +} + +void processQuantizeSpec_fl(LC3_FLOAT x[], LC3_FLOAT gain, LC3_INT xq[], LC3_INT nt, LC3_INT totalBits, LC3_INT* nbits, LC3_INT* nbits2, LC3_INT fs, + LC3_INT* lastnzout, LC3_INT* codingdata, LC3_INT* lsbMode, LC3_INT mode, LC3_INT target, LC3_INT hrmode) +{ + + LC3_INT rateFlag = 0, i = 0, lastnz2 = 0, m = 0, maxlev = 0, k = 0; + LC3_INT nbits_lsb = 0; + LC3_INT c = 0; + LC3_INT a = 0, b = 0, lev1 = 0, sym = 0, t = 0, pki = 0; + LC3_INT a1_msb = 0, b1_msb = 0; + LC3_INT lastnz = 1; + LC3_FLOAT offset = 0.375; + + if (hrmode) + { + offset = 0.5; + } + + + /* Quantization */ + for (i = 0; i < nt; i++) { + xq[i] = trunc(x[i] / gain + offset * sign(x[i])); + if (hrmode == 0) { + assert(xq[i] <= 32767 && xq[i] >= -32768); + } + } + + /* Rate flag */ + + if ((fs < 48000 && totalBits > 320 + (fs / 8000 - 2) * 160) || (fs == 48000 && totalBits > 800)) { + rateFlag = 512; + } + + /* Init */ + if (mode == 0 && ((fs < 48000 && totalBits >= 640 + (fs / 8000 - 2) * 160) || (fs == 48000 && totalBits >= 1120))) { + mode = 1; + } + + /* Last non-zero 2-tuple */ + + for (i = nt - 2; i >= 2; i = i - 2) { + if (xq[i + 1] != 0 || xq[i] != 0) { + lastnz = i + 1; + break; + } + } + + + if (mode < 0) { + lastnz2 = lastnz + 1; + } else { + lastnz2 = 2; + } + + *nbits = 0; + *nbits2 = 0; + + /* Calculate number of estimated bits */ + + for (k = 0; k < lastnz; k = k + 2) { + t = c + rateFlag; + if (k > nt / 2) { + t += 256; + } + + codingdata[0] = t; + + a = abs(xq[k]); + b = abs(xq[k + 1]); + m = MAX(a, b); + + if (m == 0) { + maxlev = -1; + } else { + maxlev = 29 - (clz_func(MAX(m, 3)) - 1); + } + + codingdata[1] = maxlev; + + if (mode <= 0) { + *nbits = *nbits + MIN(a, 1) * 2048; + *nbits = *nbits + MIN(b, 1) * 2048; + } + + lev1 = 0; + + while (MAX(a, b) >= 4) { + pki = ari_spec_lookup_fl[t + lev1 * 1024]; + *nbits = *nbits + ari_spec_bits_fl[pki][16]; + + if (lev1 == 0 && mode > 0) { + nbits_lsb += 2; + } else { + *nbits = *nbits + 2 * 2048; + } + + a = a >> 1; + b = b >> 1; + lev1 = MIN(lev1 + 1, 3); + } + + pki = ari_spec_lookup_fl[t + lev1 * 1024]; + sym = a + 4 * b; + codingdata[2] = sym; + codingdata += 3; + *nbits = *nbits + ari_spec_bits_fl[pki][sym]; + + if (mode > 0) { + a1_msb = abs(xq[k]); + b1_msb = abs(xq[k + 1]); + + if (lev1 > 0) { + a1_msb = a1_msb >> 1; + b1_msb = b1_msb >> 1; + + if (a1_msb == 0 && xq[k] != 0) { + nbits_lsb++; + } + + if (b1_msb == 0 && xq[k + 1] != 0) { + nbits_lsb++; + } + } + + *nbits = *nbits + MIN(a1_msb, 1) * 2048; + *nbits = *nbits + MIN(b1_msb, 1) * 2048; + } + + if (mode >= 0 && (abs(xq[k]) != 0 || abs(xq[k + 1]) != 0) && *nbits <= target * 2048) { + lastnz2 = k + 2; + *nbits2 = *nbits; + } + + lev1 = lev1 - 1; + if (lev1 <= 0) { + t = 1 + (a + b) * (lev1 + 2); + } else { + t = 13 + lev1; + } + + c = (c & 15) * 16 + t; + } + + /* Number of bits */ + *nbits = ceil((LC3_FLOAT)*nbits / 2048.0); + + if (mode >= 0) { + *nbits2 = ceil((LC3_FLOAT)*nbits2 / 2048.0); + } else { + *nbits2 = *nbits; + } + + if (mode > 0) { + *nbits += nbits_lsb; + *nbits2 += nbits_lsb; + } + + /* Truncation of high-frequency coefficients */ + for (i = lastnz2; i <= lastnz; i++) { + xq[i] = 0; + } + + /* Truncation of LSBs */ + if (mode > 0 && *nbits > target) { + *lsbMode = 1; + } else { + *lsbMode = 0; + } + + *lastnzout = lastnz2; +} diff --git a/lc3plus/reorder_bitstream.c b/lc3plus/reorder_bitstream.c new file mode 100644 index 0000000000000000000000000000000000000000..77b50d7a13ba0dc8ffda32396bb5342b6438961d --- /dev/null +++ b/lc3plus/reorder_bitstream.c @@ -0,0 +1,41 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + + +void processReorderBitstream_fl(LC3_UINT8* bytes, LC3_INT32 n_pccw, LC3_INT32 n_pc, LC3_INT32 b_left, LC3_INT32 len) +{ + LC3_UINT8 bytes_local[MAX_NBYTES2]; + LC3_INT32 i, block_bytes; + + assert(b_left > 0); + + memcpy(bytes_local, bytes, len * sizeof(LC3_UINT8)); + + if (n_pccw == 0) + { + return; + } + + block_bytes = ceil((LC3_FLOAT) n_pc / 2.0); + + for (i = 0; i < block_bytes; i++) + { + bytes[i] = bytes_local[b_left + i]; + } + + for (i = 0; i < b_left; i++) + { + bytes[block_bytes + i] = bytes_local[i]; + } +} + diff --git a/lc3plus/resamp12k8.c b/lc3plus/resamp12k8.c new file mode 100644 index 0000000000000000000000000000000000000000..0cab5daae94fdd67d480dd8d3b2f7ef2cd55db4f --- /dev/null +++ b/lc3plus/resamp12k8.c @@ -0,0 +1,107 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3_INT mem_in_len, LC3_FLOAT mem_50[], LC3_FLOAT mem_out[], + LC3_INT mem_out_len, LC3_FLOAT y[], LC3_INT* y_len, LC3_INT fs_idx, LC3_INT frame_dms, LC3_INT fs) +{ + + + LC3_INT len_12k8 = 0, N12k8 = 0, i = 0, k = 0; + LC3_FLOAT mac = 0, buf_out[120 + MAX_LEN] = {0}, bufdown[128] = {0}, buf[120 + MAX_LEN] = {0}; + LC3_INT32 index_int, index_frac, resamp_upfac, resamp_delay, resamp_off_int, resamp_off_frac; + LC3_FLOAT u_11, u_21, u_1, u_2; + + const LC3_FLOAT *filter; + const LC3_FLOAT *filt_input, *filt_coeff; + + + switch (frame_dms) + { + case 25: + len_12k8 = LEN_12K8 / 4; + break; + case 50: + len_12k8 = LEN_12K8 / 2; + break; + case 100: + len_12k8 = LEN_12K8; + break; + } + + *y_len = len_12k8; + N12k8 = x_len * 12800 / fs; + + /* Init Input Buffer */ + memmove(buf, mem_in, mem_in_len * sizeof(LC3_FLOAT)); + memmove(&buf[mem_in_len], x, x_len * sizeof(LC3_FLOAT)); + memmove(mem_in, &buf[x_len], mem_in_len * sizeof(LC3_FLOAT)); + + + + filter = lp_filter[fs_idx]; + + /* Upsampling & Low-pass Filtering & Downsampling */ + + index_int = 1; + index_frac = 0; + resamp_upfac = resamp_params[fs_idx][0]; + resamp_delay = resamp_params[fs_idx][1]; + resamp_off_int = resamp_params[fs_idx][2]; + resamp_off_frac = resamp_params[fs_idx][3]; + + k = 0; + for (i = 0; i < N12k8; i++) { + + filt_input = &buf[index_int]; + filt_coeff = &filter[index_frac * resamp_delay * 2]; + + mac = mac_loop(filt_input, filt_coeff, (2 * resamp_delay)); + + bufdown[k++] = mac; + + index_int = index_int + resamp_off_int; + index_frac = index_frac + resamp_off_frac; + + if ((resamp_upfac - index_frac) <= 0) + { + index_int = index_int + 1; + index_frac = index_frac - resamp_upfac; + } + } + + + /* 50Hz High-Pass */ + u_11 = mem_50[0]; + u_21 = mem_50[1]; + + for (i = 0; i < len_12k8; i++) { + LC3_FLOAT y1 = (highpass50_filt_b[0] * bufdown[i] + u_11); + u_1 = (highpass50_filt_b[1] * bufdown[i] + u_21) - highpass50_filt_a[1] * y1; + u_2 = highpass50_filt_b[2] * bufdown[i] - highpass50_filt_a[2] * y1; + u_11 = u_1; + u_21 = u_2; + bufdown[i] = (LC3_FLOAT)y1; + } + + mem_50[0] = (LC3_FLOAT)u_11; + mem_50[1] = (LC3_FLOAT)u_21; + + /* Output Buffer */ + memmove(buf_out, mem_out, mem_out_len * sizeof(LC3_FLOAT)); + + memmove(&buf_out[mem_out_len], bufdown, len_12k8 * sizeof(LC3_FLOAT)); + + memmove(y, buf_out, (*y_len + 1) * sizeof(LC3_FLOAT)); + + memmove(mem_out, &buf_out[N12k8], mem_out_len * sizeof(LC3_FLOAT)); +} diff --git a/lc3plus/residual_coding.c b/lc3plus/residual_coding.c new file mode 100644 index 0000000000000000000000000000000000000000..42094d275f2a2cfb6b42b92dd0ad21f79b503fd1 --- /dev/null +++ b/lc3plus/residual_coding.c @@ -0,0 +1,76 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +void processResidualCoding_fl(LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gain, LC3_INT L_spec, LC3_INT targetBits, LC3_INT nBits, uint8_t* resBits, LC3_INT* numResBits + , LC3_INT hrmode +) +{ + LC3_INT n = 0, m = 0, k = 0; + LC3_INT iter=0; + LC3_FLOAT offset; + LC3_INT iter_max = 1; + LC3_INT nz_idx[MAX_LEN] = {0}; + LC3_INT N_nz = 0, idx = 0; + + + memset(resBits, 0, MAX_RESBITS_LEN); + + m = targetBits - nBits + 4; + if (hrmode) + { + m += 10; + } + + assert(m <= MAX_RESBITS); + + offset = .25; + if (hrmode) + { + iter_max = EXT_RES_ITER_MAX; + + } + for (k = 0; k < L_spec; k ++) + { + if (xq[k]) + { + nz_idx[N_nz ++] = k; + } + } + while (iter < iter_max && n < m) + { + k = 0; + while (k < N_nz && n < m) + { + idx = nz_idx[k]; + + if (x[idx] >= (LC3_FLOAT)xq[idx] * gain) + { + resBits[n >> 3] |= 1 << (n & 7); + x[idx] -= gain * offset; + } + else + { + resBits[n >> 3] &= ~(1 << (n & 7)); + x[idx] += gain * offset; + } + + n++; + + k++; + } + iter ++; + offset *= .5; + } + + *numResBits = n; +} diff --git a/lc3plus/residual_decoding.c b/lc3plus/residual_decoding.c new file mode 100644 index 0000000000000000000000000000000000000000..97fd94afc35e19d43c5a7866bbffb92758cdad96 --- /dev/null +++ b/lc3plus/residual_decoding.c @@ -0,0 +1,97 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +void processResidualDecoding_fl(LC3_INT* bitsRead, LC3_FLOAT x[], LC3_INT L_spec, uint8_t prm[], LC3_INT resQBits + , LC3_INT hrmode +) +{ + LC3_INT k = 0, n = 0; + LC3_FLOAT offset1 = 0, offset2 = 0; + LC3_FLOAT offset = 0; + LC3_INT nz_idx[MAX_LEN] = {0}; + LC3_INT N_nz = 0, idx = 0; + + LC3_INT iter = 0, iter_max = 1; + + if (hrmode) + { + iter_max = EXT_RES_ITER_MAX; + offset = offset1 = offset2 = 0.25; + } + else + { + offset1 = 0.1875; + offset2 = 0.3125; + } + + if (hrmode) + { + /* enumerat non-zero coefficients */ + for (k = 0; k < L_spec; k ++) + { + if (x[k]) + { + nz_idx[N_nz ++] = k; + } + } + /* apply residual corrections */ + while (n < resQBits && iter < iter_max) + { + for (k = 0; k < N_nz; k ++) + { + idx = nz_idx[k]; + + if ((prm[n >> 3] & 1 << (n & 7)) == 0) + { + x[idx] -= offset; + } + else + { + + x[idx] += offset; + } + if (++n >= resQBits) + { + break; + } + } + offset /= 2; + iter ++; + } + } + else + { + while (k < L_spec && n < resQBits) { + if (x[k] != 0) { + if ((prm[n >> 3] & 1 << (n & 7)) == 0) + { + if (x[k] > 0) { + x[k] -= offset1; + } else { + x[k] -= offset2; + } + } else { + if (x[k] > 0) { + x[k] += offset2; + } else { + x[k] += offset1; + } + } + n++; + } + + k++; + } + } + *bitsRead = n; +} diff --git a/lc3plus/setup_com_lc3.c b/lc3plus/setup_com_lc3.c new file mode 100644 index 0000000000000000000000000000000000000000..17054d1ffcfdd63015e0e169b199ae606379217f --- /dev/null +++ b/lc3plus/setup_com_lc3.c @@ -0,0 +1,30 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + +#include "functions.h" +#include "options.h" + +LC3_FLOAT array_max_abs(LC3_FLOAT *in, LC3_INT32 len) +{ + LC3_FLOAT max; + LC3_INT32 i; + + max = LC3_FABS(in[0]); + + for (i = 0; i < len; i++) + { + if (LC3_FABS(in[i]) > LC3_FABS(max)) + { + max = LC3_FABS(in[i]); + } + } + + return max; +} + diff --git a/lc3plus/setup_dec_lc3.c b/lc3plus/setup_dec_lc3.c new file mode 100644 index 0000000000000000000000000000000000000000..c14309720ec4e0cae213b81d64ef7b170a5b651d --- /dev/null +++ b/lc3plus/setup_dec_lc3.c @@ -0,0 +1,444 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "setup_dec_lc3.h" +#include "functions.h" +#include +#include + +/* if decoder is null only size is reported */ +# include "fft/iis_fft.h" + +int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels) +{ + int ch = 0; + size_t size = sizeof(LC3PLUS_Dec); + size_t frame_len = DYN_MAX_LEN_EXT(samplerate); + + void *PlcAdvSetup = NULL; + LC3_FLOAT *pcmbufHist, *harmonicBuf; + LC3_FLOAT *PhECU_oold_grp_shape, *PhECU_old_grp_shape; + LC3_FLOAT *PhECU_xfp; + Complex *PhECU_X_sav_m; + LC3_INT32 *PhECU_plocs; + LC3_FLOAT *PhECU_f0est, *PhECU_mag_chg_1st, *PhECU_Xavg; + LC3_FLOAT *sine_table1_phecu, *sine_table2_phecu; + HANDLE_IIS_FFT handle_fft_phaseecu; + HANDLE_IIS_FFT handle_ifft_phaseecu; + LC3_FLOAT *q_old_res; + + for (ch = 0; ch < channels; ch++) { + DecSetup* setup = balloc(decoder, &size, sizeof(DecSetup)); + + size_t max_pitch = ceilf(228.0 * CODEC_FS(samplerate) / 12800.0); + size_t pcm_plc_len = max_pitch + frame_len; + pcmbufHist = balloc(decoder, &size, sizeof(LC3_FLOAT) * pcm_plc_len); + harmonicBuf = balloc(decoder, &size, sizeof(LC3_FLOAT) * max_pitch); + PlcAdvSetup = balloc(decoder, &size, sizeof(*setup->PlcAdvSetup)); + PhECU_oold_grp_shape = balloc(decoder, &size, sizeof(LC3_FLOAT) *MAX_LGW); /* BASOP Word16 PhECU_oold_grp_shape_fx[MAX_LGW]; */ + PhECU_old_grp_shape = balloc(decoder, &size, sizeof(LC3_FLOAT) *MAX_LGW); /* BASOP Word16 PhECU_old_grp_shape_fx[MAX_LGW] ; */ + PhECU_xfp = balloc(decoder, &size, sizeof(LC3_FLOAT) *(frame_len * 16 / 10)); + PhECU_X_sav_m = balloc(decoder, &size, sizeof(Complex) *(((frame_len * 16 / 10) / 2) + 1));/*MAX_PLC_LMSPEC*/ + PhECU_plocs = balloc(decoder, &size, sizeof(LC3_INT32) * (((frame_len * 16 / 10) / 4) + 1 + 1)); /* BASOP Word16 *PhECU_plocs; */ + + handle_fft_phaseecu = balloc(decoder, &size, sizeof(IIS_FFT) * 1); + handle_ifft_phaseecu = balloc(decoder, &size, sizeof(IIS_FFT) * 1); + PhECU_f0est = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((frame_len * 16 / 10) / 4) + 1)); /*BASOP Word32 *PhECU_f0est;*/ + PhECU_mag_chg_1st = balloc(decoder, &size, sizeof(LC3_FLOAT) *MAX_LGW); /* BASOP Word16 PhECU_mag_chg_1st[MAX_LGW];*/ + PhECU_Xavg = balloc(decoder, &size, sizeof(LC3_FLOAT) * MAX_LGW); /* BASOP Word16 PhECU_Xavg[MAX_LGW] ; */ + + sine_table1_phecu = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((CODEC_FS(samplerate) * 16) / 1000) / 2 + 1)); + sine_table2_phecu = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((CODEC_FS(samplerate) * 16) / 1000) / 2 + 1)); + + q_old_res = balloc(decoder, &size, sizeof(LC3_FLOAT) * frame_len); + + if (decoder) { + decoder->channel_setup[ch] = setup; + + setup->PlcAdvSetup = PlcAdvSetup; + + setup->PlcAdvSetup->pcmbufHist = pcmbufHist; + setup->PlcAdvSetup->PlcTdcSetup.harmonicBuf = harmonicBuf; + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_oold_grp_shape = PhECU_oold_grp_shape; + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_old_grp_shape = PhECU_old_grp_shape; + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_xfp = PhECU_xfp; + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_X_sav_m = PhECU_X_sav_m; + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_plocs = PhECU_plocs; + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_f0est = PhECU_f0est; + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_mag_chg_1st = PhECU_mag_chg_1st; + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Xavg = PhECU_Xavg; + setup->PlcAdvSetup->PlcPhEcuSetup.handle_fft_phaseecu = handle_fft_phaseecu; + setup->PlcAdvSetup->PlcPhEcuSetup.handle_ifft_phaseecu = handle_ifft_phaseecu; + + setup->PlcAdvSetup->PlcPhEcuSetup.handle_fft_phaseecu->sine_table = sine_table1_phecu; + setup->PlcAdvSetup->PlcPhEcuSetup.handle_ifft_phaseecu->sine_table = sine_table2_phecu; + + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot = (CODEC_FS(samplerate) * 16) / 1000; + real_fft_init(&(setup->PlcAdvSetup->PlcPhEcuSetup.PhEcu_Fft), setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot, &(setup->PlcAdvSetup->PlcPhEcuSetup.handle_fft_phaseecu)); + real_ifft_init(&(setup->PlcAdvSetup->PlcPhEcuSetup.PhEcu_Ifft), setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot, &(setup->PlcAdvSetup->PlcPhEcuSetup.handle_ifft_phaseecu)); + setup->statePC.q_old_res = q_old_res; + } + } + + return (int)size; +} + +LC3PLUS_Error FillDecSetup(LC3PLUS_Dec* decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode + , int hrmode +) +{ + memset(decoder, 0, lc3plus_dec_get_size(samplerate, channels)); + alloc_decoder(decoder, samplerate, channels); + + decoder->fs = CODEC_FS(samplerate); + decoder->fs_out = samplerate; + decoder->fs_idx = FS2FS_IDX(decoder->fs); + decoder->plcMeth = plc_mode; + + decoder->hrmode = hrmode != 0; + + if (decoder->fs_idx > 4) { + decoder->fs_idx = 5; + } + decoder->channels = channels; + decoder->frame_ms = 10; + decoder->frame_dms = 100; + decoder->BW_cutoff_bits = BW_cutoff_bits_all[decoder->fs_idx]; + + if (decoder->fs == 8000) { + decoder->tilt = 14; + } else if (decoder->fs == 16000) { + decoder->tilt = 18; + } else if (decoder->fs == 24000) { + decoder->tilt = 22; + } else if (decoder->fs == 32000) { + decoder->tilt = 26; + } else if (decoder->fs == 48000) { + decoder->tilt = 30; + } + else if (decoder->fs == 96000) { + decoder->tilt = 34; + } + + set_dec_frame_params(decoder); + + lc3plus_dec_set_ep_enabled(decoder, 0); + + return LC3PLUS_OK; +} + +/* set frame config params */ +void set_dec_frame_params(LC3PLUS_Dec* decoder) +{ + int ch = 0; + + if (decoder->fs_idx == 5) + { + decoder->hrmode = 1; + } + + decoder->frame_length = ceil(decoder->fs * 10 / 1000); /* fs * 0.01*2^6 */ + if (decoder->hrmode == 1) + { + decoder->yLen = decoder->frame_length; + } + else + { + decoder->yLen = MIN(MAX_BW, decoder->frame_length); + } + + decoder->bands_number = 64; + if (decoder->frame_ms == 2.5) + { + decoder->frame_length = decoder->frame_length >> 2; + decoder->yLen /= 4; + if (decoder->hrmode) + { + decoder->bands_number = bands_number_2_5ms_HR[decoder->fs_idx]; + } + else + { + decoder->bands_number = bands_number_2_5ms[decoder->fs_idx]; + } + } + if (decoder->frame_ms == 5) + { + decoder->frame_length = decoder->frame_length >> 1; + decoder->yLen /= 2; + decoder->bands_number = bands_number_5ms[decoder->fs_idx]; + } + + if (decoder->hrmode) + { + decoder->BW_cutoff_bits = 0; + } + else + { + decoder->BW_cutoff_bits = BW_cutoff_bits_all[decoder->fs_idx]; + } + + if (decoder->frame_ms == 10) + { + if (decoder->hrmode) + { + decoder->bands_offset = ACC_COEFF_PER_BAND_HR[decoder->fs_idx]; + } + else + { + decoder->bands_offset = ACC_COEFF_PER_BAND[decoder->fs_idx]; + } + decoder->cutoffBins = BW_cutoff_bin_all; + } + else if (decoder->frame_ms == 2.5) + { + if (decoder->hrmode) + { + decoder->bands_offset = ACC_COEFF_PER_BAND_2_5ms_HR[decoder->fs_idx]; + } + else + { + decoder->bands_offset = ACC_COEFF_PER_BAND_2_5ms[decoder->fs_idx]; + } + decoder->cutoffBins = BW_cutoff_bin_all_2_5ms; + } + else if (decoder->frame_ms == 5) + { + if (decoder->hrmode) + { + decoder->bands_offset = ACC_COEFF_PER_BAND_5ms_HR[decoder->fs_idx]; + } + else + { + decoder->bands_offset = ACC_COEFF_PER_BAND_5ms[decoder->fs_idx]; + } + decoder->cutoffBins = BW_cutoff_bin_all_5ms; + } + + decoder->n_bandsPLC = MIN(decoder->frame_length, 80); + + if (decoder->frame_ms == 10) + { + decoder->bands_offsetPLC = ACC_COEFF_PER_BAND_PLC[decoder->fs_idx]; + } + else if (decoder->frame_ms == 5) + { + decoder->bands_offsetPLC = ACC_COEFF_PER_BAND_PLC_5ms[decoder->fs_idx]; + + if (decoder->fs == 24000) + { + decoder->n_bandsPLC = 40; + } + } + else if (decoder->frame_ms == 2.5) + { + decoder->bands_offsetPLC = ACC_COEFF_PER_BAND_PLC_2_5ms[decoder->fs_idx]; + + if (decoder->fs == 48000) + { + decoder->n_bandsPLC = 60; + } + } + assert(decoder->bands_offsetPLC); + + if (decoder->frame_ms == 10) { + decoder->imdct_win = MDCT_WINS_10ms[decoder->hrmode][decoder->fs_idx]; + decoder->imdct_laZeros = MDCT_la_zeroes[decoder->fs_idx]; + decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_10ms[decoder->fs_idx]; + } + else if (decoder->frame_ms == 2.5) { + decoder->imdct_win = MDCT_WINS_2_5ms[decoder->hrmode][decoder->fs_idx]; + decoder->imdct_laZeros = MDCT_la_zeroes_2_5ms[decoder->fs_idx]; + decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_2_5ms[decoder->fs_idx]; + } + else if (decoder->frame_ms == 5) { + decoder->imdct_win = MDCT_WINS_5ms[decoder->hrmode][decoder->fs_idx]; + decoder->imdct_laZeros = MDCT_la_zeroes_5ms[decoder->fs_idx]; + decoder->imdct_winLen = MDCT_WINDOWS_LENGTHS_5ms[decoder->fs_idx]; + } + + decoder->la_zeroes = decoder->imdct_laZeros; + + decoder->imdct_memLen = decoder->frame_length - decoder->imdct_laZeros; + + for (ch = 0; ch < decoder->channels; ch++) { + DecSetup* setup = decoder->channel_setup[ch]; + + setup->ltpf_mem_beta_idx = -1; + + setup->statePC.seed = 24607; + + if (decoder) { + /* Init DCT4 structs */ + if (setup->dct4structImdct.length != 0) { + dct4_free(&setup->dct4structImdct); + dct4_init(&setup->dct4structImdct, decoder->frame_length); + } else { + dct4_init(&setup->dct4structImdct, decoder->frame_length); + } + + setup->PlcNsSetup.cum_alpha = 1; + setup->PlcNsSetup.seed = 24607; + setup->alpha = 1; + if (setup->PlcAdvSetup) + { + LC3_INT32 pitch_max = 0, pitch_ana_len = 0, tdc_synt_len = 0; + pitch_max = ceil(228.0 * (LC3_FLOAT) decoder->fs / 12800.0); + pitch_ana_len = pitch_max + decoder->frame_length * (LC3_FLOAT) 100 / decoder->frame_dms; + tdc_synt_len = 16 + 1 + pitch_max + ceil(decoder->frame_length / 2); + setup->PlcAdvSetup->max_len_pcm_plc = MAX(pitch_ana_len, tdc_synt_len); + setup->PlcAdvSetup->PlcTdcSetup.preemphFac = plc_preemph_fac[decoder->fs_idx]; + setup->PlcAdvSetup->PlcTdcSetup.seed = 24607; + setup->PlcAdvSetup->PlcTdcSetup.lpcorder = 16; + + if (decoder->fs_idx == 0 && decoder->frame_dms == 25) + { + setup->PlcAdvSetup->PlcTdcSetup.lpcorder = 8; + } + + setup->PlcAdvSetup->stabFac = 1; + setup->PlcAdvSetup->cum_fading_fast = 1; + setup->PlcAdvSetup->cum_fading_slow = 1; + setup->PlcAdvSetup->cum_fflcAtten = 1; + + if (decoder->fs_idx <= 4 && decoder->frame_dms == 100) + { + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot = (decoder->fs * 16) / 1000; /* 16 ms of samples at fs*/ + + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_f0hzLtpBin = 0; + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_norm_corr = 0; + + set_vec(PHECU_GRP_SHAPE_INIT, setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_oold_grp_shape, MAX_LGW); + set_vec(PHECU_GRP_SHAPE_INIT, setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_old_grp_shape, MAX_LGW); + + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_L_oold_xfp_w_E = (LC3_FLOAT)PHECU_LTOT_MIN_MAN * LC3_POW(2.0, PHECU_LTOT_MIN_EXP - 31); + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_L_old_xfp_w_E = (LC3_FLOAT)PHECU_LTOT_MIN_MAN * LC3_POW(2.0, PHECU_LTOT_MIN_EXP - 31); + + /* CFL uses separate buffers for pcmHist, xfp and Xsav and q_d , BASOP uses an optimized joint buffer*/ + zero_float(setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_xfp, setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot); + zero_cmplx(setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_X_sav_m, (setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot/2 + 1)); + + set_vec(POS_ONE_Q15, setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_mag_chg_1st, MAX_LGW); + + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_beta_mute = (16384.0/32768.0); + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_seed = 21845; + + assert(decoder->frame_dms == 100); + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_LDWIN_OLAP = (decoder->frame_length / 4 ); /* 2.5 ms for regular 10 ms MDCT */ + + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_t_adv = ( + decoder->frame_length + + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_Lprot + + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_LDWIN_OLAP )/ 2; + } + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_short_flag_prev = 0; /* fullband transient */ + setup->PlcAdvSetup->PlcPhEcuSetup.PhECU_num_plocs = 0; + } + } + } +} + +LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes) +{ + int totalBits = 0, bitsTmp = 0, channel_bytes = 0, maxBytes = 0, minBytes = 0; + DecSetup* setup; + + if (decoder->hrmode) + { + switch (decoder->frame_dms) + { + case 25: + maxBytes = 210; + minBytes = MIN_NBYTES; + break; + case 50: + maxBytes = 375; + minBytes = MIN_NBYTES; + break; + case 100: + maxBytes = 625; + minBytes = MIN_NBYTES; + break; + default: + return LC3PLUS_HRMODE_ERROR; + } + } + else + { + minBytes = MIN_NBYTES; + maxBytes = MAX_NBYTES_100; // for backward compatibility, MAX_NBYTES_100 is used for all frame lengths + } + + channel_bytes = nBytes; + + setup = decoder->channel_setup[ch]; + + if (channel_bytes < minBytes || channel_bytes > maxBytes) + { + return LC3PLUS_NUMBYTES_ERROR; + } + + setup->targetBytes = channel_bytes; + setup->total_bits = setup->targetBytes << 3; + setup->enable_lpc_weighting = (setup->total_bits < 480); + setup->quantizedGainOff = + -(MIN(115, setup->total_bits / (10 * (decoder->fs_idx + 1))) + 105 + 5 * (decoder->fs_idx + 1)); + + if (decoder->hrmode && decoder->fs_idx == 5) + { + setup->quantizedGainOff = MAX(setup->quantizedGainOff, -181); + } + + totalBits = setup->total_bits; + + if (decoder->frame_ms == 2.5) { + setup->enable_lpc_weighting = setup->total_bits < 120; + totalBits = setup->total_bits * 4.0 * (1.0 - 0.4); + } + if (decoder->frame_ms == 5) { + setup->enable_lpc_weighting = (setup->total_bits < 240); + totalBits = setup->total_bits * 2 - 160; + } + + if (decoder->frame_length > 40 * ((LC3_FLOAT) (decoder->frame_dms) / 10.0)) { + setup->N_red_tns = 40 * ((LC3_FLOAT) (decoder->frame_dms) / 10.0); + setup->fs_red_tns = 40000; + } else { + setup->N_red_tns = decoder->frame_length; + setup->fs_red_tns = decoder->fs; + } + + bitsTmp = totalBits; + + if (bitsTmp < 400 + (decoder->fs_idx - 1) * 80) { + setup->ltpf_conf_beta = 0.4; + setup->ltpf_conf_beta_idx = 0; + } else if (bitsTmp < 480 + (decoder->fs_idx - 1) * 80) { + setup->ltpf_conf_beta = 0.35; + setup->ltpf_conf_beta_idx = 1; + } else if (bitsTmp < 560 + (decoder->fs_idx - 1) * 80) { + setup->ltpf_conf_beta = 0.3; + setup->ltpf_conf_beta_idx = 2; + } else if (bitsTmp < 640 + (decoder->fs_idx - 1) * 80) { + setup->ltpf_conf_beta = 0.25; + setup->ltpf_conf_beta_idx = 3; + } else { + setup->ltpf_conf_beta = 0; + setup->ltpf_conf_beta_idx = -1; + } + + /* No LTPF in hrmode */ + if (decoder->hrmode == 1) { + setup->ltpf_conf_beta = 0; + setup->ltpf_conf_beta_idx = -1; + } + + return LC3PLUS_OK; +} diff --git a/lc3plus/setup_dec_lc3.h b/lc3plus/setup_dec_lc3.h new file mode 100644 index 0000000000000000000000000000000000000000..6ed0f438ea7601d9646d9c821730f1ae9c1a630f --- /dev/null +++ b/lc3plus/setup_dec_lc3.h @@ -0,0 +1,112 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#ifndef SETUP_DEC_LC3_FL_H +#define SETUP_DEC_LC3_FL_H + +#include "constants.h" + +/* Channel state and bitrate-derived values go in this struct */ +typedef struct { + LC3_INT* stDec_ola_mem_fx; /* MDCT_MEM_LEN_MAX */ + LC3_INT total_bits; + LC3_INT enable_lpc_weighting; + LC3_INT targetBytes; + LC3_INT quantizedGainOff; + LC3_INT ltpf_param[3]; + LC3_INT ltpf_param_mem[3]; + LC3_INT ltpf_mem_pitch; + LC3_INT ltpf_mem_active; + LC3_INT ltpf_mem_pitch_fr; + LC3_INT ltpf_mem_beta_idx; + LC3_INT ltpf_conf_beta_idx; + LC3_INT spec_inv_idx; + LC3_INT concealMethod; + LC3_INT last_size; + LC3_INT BW_cutoff_idx_nf; + LC3_INT prev_BW_cutoff_idx_nf; + LC3_INT fs_red_tns; + LC3_INT N_red_tns; + LC3_INT scf_idx[SCF_MAX_PARAM]; + uint8_t resBits[MAX_RESBITS_LEN]; + LC3_INT tns_idx[TNS_NUMFILTERS_MAX * MAXLAG]; + + LC3_FLOAT prev_fac_ns; + LC3_FLOAT ltpf_mem_x[3 * MAX_LEN]; + LC3_FLOAT ltpf_mem_y[3 * MAX_LEN]; + LC3_FLOAT ltpf_mem_gain; + LC3_FLOAT ltpf_conf_beta; + LC3_FLOAT sqQdec_fl[MAX_LEN]; + LC3_FLOAT scf_q[M]; + LC3_FLOAT int_scf[MAX_BANDS_NUMBER]; + LC3_FLOAT x_fl[MAX_LEN]; + LC3_FLOAT imdct_mem[MAX_LEN]; + LC3_FLOAT alpha; + + Dct4 dct4structImdct; + + PlcSetup PlcSetup; + PlcNsSetup PlcNsSetup; + + pcState statePC; + PlcAdvSetup* PlcAdvSetup; +} DecSetup; + +/* Constants and sampling rate derived values go in this struct */ +struct LC3PLUS_Dec { + DecSetup* channel_setup[MAX_CHANNELS]; + const LC3_INT* W_fx; + const LC3_INT* bands_offset; + const LC3_INT* cutoffBins; + + LC3_INT fs; /* sampling rate, 44.1 maps to 48 */ + LC3_INT fs_out; /* output sampling rate */ + LC3_INT fs_idx; /* sampling rate index */ + LC3_INT frame_length; /* sampling rate index */ + LC3_INT channels; /* number of channels */ + LC3_FLOAT frame_ms; /* frame length in ms (wrong for 44.1) */ + LC3_INT frame_dms; /* frame length in ms * 10 (wrong for 44.1) */ + LC3_INT last_size; /* size of last frame, without error protection */ + LC3_INT ep_enabled; /* error protection enabled */ + LC3_INT error_report; /* corrected errors in last frame or -1 on error */ + + LC3_INT imdct_memLen; + LC3_INT imdct_winLen; + LC3_INT imdct_laZeros; + const LC3_FLOAT* imdct_win; + + LC3_INT yLen; + LC3_INT W_size; + LC3_INT la_zeroes; + LC3_INT bands_number; + LC3_INT ltpf_mem_x_len; + LC3_INT ltpf_mem_y_len; + LC3_INT BW_cutoff_bits; + LC3_INT tilt; + + LC3_INT hrmode; + LC3_INT specflip; + + const LC3_INT* bands_offsetPLC; + LC3_INT n_bandsPLC; + + LC3_INT32 rframe; + int plcMeth; /* PLC method for all channels */ + LC3_INT16 n_pccw; + LC3_INT16 be_bp_left; + LC3_INT16 be_bp_right; + LC3_INT16 n_pc; + LC3_INT16 m_fec; + int epmr; + LC3_INT16 combined_channel_coding; + int last_error; +}; + +#endif diff --git a/lc3plus/setup_enc_lc3.c b/lc3plus/setup_enc_lc3.c new file mode 100644 index 0000000000000000000000000000000000000000..986b43d6085443e801d293370634cd30bf9c7b6d --- /dev/null +++ b/lc3plus/setup_enc_lc3.c @@ -0,0 +1,546 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "setup_enc_lc3.h" +#include "functions.h" +#include + +/* if encoder is null only size is reported */ +int alloc_encoder(LC3PLUS_Enc* encoder, int channels) +{ + int ch = 0; + size_t size = sizeof(LC3PLUS_Enc); + + for (ch = 0; ch < channels; ch++) { + EncSetup* setup = balloc(encoder, &size, sizeof(EncSetup)); + if (encoder) { + encoder->channel_setup[ch] = setup; + } + } + + return (int)size; +} + +LC3PLUS_Error FillEncSetup(LC3PLUS_Enc* encoder, int samplerate, int channels + , int hrmode + , int32_t lfe_channel_array[] +) +{ + int ch = 0; + memset(encoder, 0, lc3plus_enc_get_size(samplerate, channels)); + alloc_encoder(encoder, channels); + + encoder->fs = CODEC_FS(samplerate); + encoder->fs_in = samplerate; + encoder->fs_idx = FS2FS_IDX(encoder->fs); + encoder->frame_dms = 100; + if (encoder->fs_idx > 4) { + encoder->fs_idx = 5; + } + + encoder->hrmode = hrmode != 0; + + encoder->channels = channels; + encoder->frame_ms = 10; + encoder->envelope_bits = 38; + encoder->global_gain_bits = 8; + encoder->noise_fac_bits = 3; + encoder->BW_cutoff_bits = BW_cutoff_bits_all[encoder->fs_idx]; + + encoder->r12k8_mem_in_len = 2 * 8 * encoder->fs / 12800; + encoder->r12k8_mem_out_len = 24; + + for (ch = 0; ch < encoder->channels; ch++) + { + encoder->channel_setup[ch]->lfe = lfe_channel_array[ch] != 0; + } + + encoder->bw_ctrl_active = 0; + encoder->bandwidth = encoder->fs / 2; + encoder->bandwidth_preset = encoder->fs / 2; + + + if (encoder->fs == 8000) { + encoder->tilt = 14; + } else if (encoder->fs == 16000) { + encoder->tilt = 18; + } else if (encoder->fs == 24000) { + encoder->tilt = 22; + } else if (encoder->fs == 32000) { + encoder->tilt = 26; + } else if (encoder->fs == 48000) { + encoder->tilt = 30; + } + else if (encoder->fs == 96000) { + encoder->tilt = 34; + } + + set_enc_frame_params(encoder); + return LC3PLUS_OK; +} + +/* set frame config params */ +void set_enc_frame_params(LC3PLUS_Enc* encoder) +{ + int ch = 0; + EncSetup* setup; + + encoder->frame_length = ceil(encoder->fs * 10 / 1000); /* fs * 0.01*2^6 */ + if (encoder->hrmode == 1) + { + encoder->yLen = encoder->frame_length; + } + else + { + encoder->yLen = MIN(MAX_BW, encoder->frame_length); + encoder->sns_damping = 0.85; + } + encoder->stEnc_mdct_mem_len = encoder->frame_length - encoder->la_zeroes; + encoder->bands_number = 64; + encoder->nSubdivisions = 3; + encoder->near_nyquist_index = encoder->bands_number - 2; + encoder->near_nyquist_flag = 0; + encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN; + + if (encoder->fs_idx == 5) + { + encoder->hrmode = 1; + } + + if (encoder->hrmode) + { + encoder->BW_cutoff_bits = 0; + } + else + { + encoder->BW_cutoff_bits = BW_cutoff_bits_all[encoder->fs_idx]; + } + + if (encoder->frame_ms == 10) { + encoder->la_zeroes = MDCT_la_zeroes[encoder->fs_idx]; + if (encoder->hrmode) + { + encoder->bands_offset = ACC_COEFF_PER_BAND_HR[encoder->fs_idx]; + } + else + { + encoder->bands_offset = ACC_COEFF_PER_BAND[encoder->fs_idx]; + } + encoder->cutoffBins = BW_cutoff_bin_all; + + encoder->attdec_nblocks = 4; + encoder->attdec_damping = 0.5; + encoder->attdec_hangover_thresh = 2; + } + else if (encoder->frame_ms == 2.5) { + encoder->la_zeroes = MDCT_la_zeroes_2_5ms[encoder->fs_idx]; + if (encoder->hrmode) + { + encoder->bands_offset = ACC_COEFF_PER_BAND_2_5ms_HR[encoder->fs_idx]; + } + else + { + encoder->bands_offset = ACC_COEFF_PER_BAND_2_5ms[encoder->fs_idx]; + } + encoder->cutoffBins = BW_cutoff_bin_all_2_5ms; + } + else if (encoder->frame_ms == 5) { + encoder->la_zeroes = MDCT_la_zeroes_5ms[encoder->fs_idx]; + if (encoder->hrmode) + { + encoder->bands_offset = ACC_COEFF_PER_BAND_5ms_HR[encoder->fs_idx]; + } + else + { + encoder->bands_offset = ACC_COEFF_PER_BAND_5ms[encoder->fs_idx]; + } + encoder->cutoffBins = BW_cutoff_bin_all_5ms; + } + + if (encoder->frame_ms == 2.5) { + encoder->frame_length = encoder->frame_length >> 2; + encoder->yLen /= 4; + encoder->stEnc_mdct_mem_len = encoder->frame_length - encoder->la_zeroes; + if (encoder->hrmode) + { + encoder->bands_number = bands_number_2_5ms_HR[encoder->fs_idx]; + } + else + { + encoder->bands_number = bands_number_2_5ms[encoder->fs_idx]; + } + + encoder->nSubdivisions = 2; + encoder->near_nyquist_index = encoder->bands_number - 2; + encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN + (LEN_12K8 >> 2); + } + + + if (encoder->frame_ms == 5) { + encoder->frame_length = encoder->frame_length >> 1; + encoder->yLen /= 2; + encoder->stEnc_mdct_mem_len = encoder->frame_length - encoder->la_zeroes; + encoder->bands_number = bands_number_5ms[encoder->fs_idx]; + encoder->nSubdivisions = 2; + encoder->near_nyquist_index = encoder->bands_number - 3; + } + + for (ch = 0; ch < encoder->channels; ch++) { + setup = encoder->channel_setup[ch]; + + setup->olpa_mem_pitch = 17; + + if (setup->mdctStruct.mem != NULL) { + mdct_free(&setup->mdctStruct); + mdct_init(&setup->mdctStruct, encoder->frame_length, encoder->frame_dms, encoder->fs_idx, encoder->hrmode); + + dct2_free(&setup->dct2StructSNS); + dct2_init(&setup->dct2StructSNS, M); + } + else + { + mdct_init(&setup->mdctStruct, encoder->frame_length, encoder->frame_dms, encoder->fs_idx, encoder->hrmode); + dct2_init(&setup->dct2StructSNS, M); + } + } +} + +/* change encoder bitrate */ +LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) +{ + int ch = 0, bitsTmp = 0, minBR = 0, maxBR = 0, totalBytes = 0; + LC3_INT channel_bytes = 0, max_bytes = 0; + + if (encoder->hrmode) + { +#ifdef ENABLE_HR_MODE_FL + switch (encoder->frame_dms) + { + case 25: + maxBR = 672000; + if (encoder->fs == 48000) {minBR = MIN_BR_25MS_48KHZ_HR;} + else if (encoder->fs == 96000) {minBR = MIN_BR_25MS_96KHZ_HR;} + else { return LC3PLUS_HRMODE_ERROR;} + break; + case 50: + maxBR = 600000; + if (encoder->fs == 48000) {minBR = MIN_BR_50MS_48KHZ_HR;} + else if (encoder->fs == 96000) {minBR = MIN_BR_50MS_96KHZ_HR;} + else { return LC3PLUS_HRMODE_ERROR;} + break; + case 100: + maxBR = 500000; + if (encoder->fs == 48000) {minBR = MIN_BR_100MS_48KHZ_HR;} + else if (encoder->fs == 96000) {minBR = MIN_BR_100MS_96KHZ_HR;} + else { return LC3PLUS_HRMODE_ERROR;} + break; + default: + return LC3PLUS_HRMODE_ERROR; + } +#endif + } + else + { + minBR = (MIN_NBYTES << 3); + maxBR = MAX_BR; + + switch (encoder->frame_dms) + { + case 25: + minBR = MIN_BR_025DMS; + maxBR = MAX_BR; + break; + case 50: + minBR = MIN_BR_050DMS; + maxBR = MAX_BR; + /* have additional limitations for 5.0ms */ + switch (encoder->fs_in) + { + case 8000: maxBR = MAX_BR_050DMS_NB; break; + default: break; + } + break; + case 100: + /* have additional limitations for 10ms */ + minBR = MIN_BR_100DMS; + maxBR = MAX_BR; + switch (encoder->fs_in) + { + case 8000: maxBR = MAX_BR_100DMS_NB ; break; + case 16000: maxBR = MAX_BR_100DMS_WB ; break; + case 24000: maxBR = MAX_BR_100DMS_SSWB; break; + default: maxBR = MAX_BR; break; + } + break; + default: return LC3PLUS_FRAMEMS_ERROR; + } + maxBR *= (encoder->fs_in == 44100 ? 441. / 480 : 1); + } + minBR *= encoder->channels; + maxBR *= encoder->channels; + + encoder->combined_channel_coding = 0; + + if (encoder->channels > 1 && encoder->epmode) + { + if (encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in) <= 160) + { + encoder->combined_channel_coding = 1; + } + } + + if (encoder->epmode > 0) + { + max_bytes = bitrate * encoder->frame_length / (8 * encoder->fs_in * encoder->channels); + if (max_bytes < FEC_SLOT_BYTES_MIN || max_bytes > FEC_SLOT_BYTES_MAX) + { + encoder->lc3_br_set = 0; + return LC3PLUS_BITRATE_ERROR; + } + } + + if (encoder->combined_channel_coding) + { + totalBytes = fec_get_data_size(encoder->epmode, encoder->combined_channel_coding, + bitrate * encoder->frame_length / (8 * encoder->fs_in)); + + encoder->channel_setup[0]->n_pccw = + fec_get_n_pccw(bitrate * encoder->frame_length / (8 * encoder->fs_in), encoder->epmode, + encoder->combined_channel_coding); + + encoder->channel_setup[0]->n_pc = fec_get_n_pc(encoder->epmode, encoder->channel_setup[0]->n_pccw, + bitrate * encoder->frame_length / (8 * encoder->fs_in)); + } + else + { + totalBytes = bitrate * encoder->frame_length / (8 * encoder->fs_in); + } + + if (encoder->frame_dms <= 50) + { + encoder->tnsMaxOrder = 4; + } else { + encoder->tnsMaxOrder = 8; + } + + if (bitrate < minBR || bitrate > maxBR) { + return LC3PLUS_BITRATE_ERROR; + } + + encoder->lc3_br_set = 1; + for (ch = 0; ch < encoder->channels; ch++) { + + EncSetup* setup = encoder->channel_setup[ch]; + + setup->targetBytes = totalBytes / encoder->channels + (ch < (totalBytes % encoder->channels)); + channel_bytes = totalBytes / encoder->channels + (ch < (totalBytes % encoder->channels)); + + if (encoder->combined_channel_coding) + { + setup->targetBytes = channel_bytes; + } + else + { + setup->targetBytes = fec_get_data_size(encoder->epmode, encoder->combined_channel_coding, channel_bytes); + setup->n_pccw = fec_get_n_pccw(channel_bytes, encoder->epmode, encoder->combined_channel_coding); + setup->n_pc = fec_get_n_pc(encoder->epmode, setup->n_pccw, channel_bytes); + } + // reduce bandwith to 12kHz if bitrate is low + if (encoder->frame_dms == 100 && + ((setup->targetBytes < 40 && encoder->fs == 48000) || + (setup->targetBytes < 36 && encoder->fs == 32000))) + { + encoder->bandwidth = MIN(12000, encoder->bandwidth_preset); + } + else + { + /* channel with highest index has lowest bitrate. + For a second channel with lower targetBytes, bandwidth is overwritten */ + encoder->bandwidth = encoder->bandwidth_preset; + } + encoder->bw_ctrl_cutoff_bin = encoder->bandwidth * encoder->frame_dms / 5000; + encoder->bw_index = (encoder->bandwidth / 4000) - 1; + setup->total_bits = setup->targetBytes << 3; + setup->targetBitsInit = setup->total_bits - encoder->envelope_bits - encoder->global_gain_bits - + encoder->noise_fac_bits - encoder->BW_cutoff_bits - + ceil(LC3_LOGTWO(encoder->frame_length / 2)) - 2 - 1; + + if (setup->total_bits > 1280) { + setup->targetBitsInit = setup->targetBitsInit - 1; + } + if (setup->total_bits > 2560) { + setup->targetBitsInit = setup->targetBitsInit - 1; + } + + if (encoder->hrmode) + { + setup->targetBitsInit -= 1; + } + + setup->targetBitsAri = setup->total_bits; + setup->enable_lpc_weighting = setup->total_bits < 480; + + if (encoder->frame_ms == 5) { + setup->enable_lpc_weighting = setup->total_bits < 240; + } + if (encoder->frame_ms == 2.5) { + setup->enable_lpc_weighting = setup->total_bits < 120; + } + + setup->quantizedGainOff = + -(MIN(115, setup->total_bits / (10 * (encoder->fs_idx + 1))) + 105 + 5 * (encoder->fs_idx + 1)); + + if (encoder->hrmode && encoder->fs_idx == 5) + { + setup->quantizedGainOff = MAX(setup->quantizedGainOff, -181); + } + + if (encoder->frame_ms == 10 && ((encoder->fs_in >= 44100 && setup->targetBytes >= 100) || + (encoder->fs_in == 32000 && setup->targetBytes >= 81)) && setup->targetBytes < 340 && encoder->hrmode == 0) { + setup->attack_handling = 1; + + } + else if (encoder->frame_dms == 75 && ((encoder->fs_in >= 44100 && setup->targetBytes >= 75) || + (encoder->fs_in == 32000 && setup->targetBytes >= 61)) && setup->targetBytes < 150 && encoder->hrmode == 0) + { + setup->attack_handling = 1; + } + else + { + /* reset for bitrate switching */ + setup->attack_handling = 0; + + setup->attdec_filter_mem[0] = 0; + setup->attdec_filter_mem[1] = 0; + + setup->attdec_detected = 0; + setup->attdec_position = 0; + setup->attdec_acc_energy = 0; + } + + bitsTmp = setup->total_bits; + if (encoder->frame_ms == 2.5) { + bitsTmp = bitsTmp * 4.0 * (1.0 - 0.4); + } + if (encoder->frame_ms == 5) { + bitsTmp = bitsTmp * 2 - 160; + } + + if (bitsTmp < 400 + (encoder->fs_idx - 1) * 80) { + setup->ltpf_enable = 1; + } else if (bitsTmp < 480 + (encoder->fs_idx - 1) * 80) { + setup->ltpf_enable = 1; + } else if (bitsTmp < 560 + (encoder->fs_idx - 1) * 80) { + setup->ltpf_enable = 1; + } else if (bitsTmp < 640 + (encoder->fs_idx - 1) * 80) { + setup->ltpf_enable = 1; + } else { + setup->ltpf_enable = 0; + } + if (encoder->hrmode) { + setup->ltpf_enable = 0; + } + + /* turn down SNS shaping for higher rates */ + if (encoder->hrmode == 0) { + encoder->sns_damping = 0.85; + } else { + encoder->sns_damping = 0.6; + if (encoder->fs_idx >= 4) { + if (encoder->frame_ms == 10) + { + if (setup->total_bits > 4400) { + encoder->sns_damping = 6881.0/32768.0; + } + } + if (encoder->frame_ms == 5) + { + if (setup->total_bits > 4600/2) { + encoder->sns_damping = 4915.0/32768.0; + } + } + if (encoder->frame_ms == 2.5) + { + if (setup->total_bits > 4600/4) { + encoder->sns_damping = 4915.0/32768.0; + } + } + } + } + + if (encoder->hrmode && encoder->fs_idx >= 4) + { + int real_rate = setup->targetBytes * 8000 / encoder->frame_ms; + setup->regBits = real_rate / 12500; + + if (encoder->fs_idx == 5) + { + if (encoder->frame_ms == 10) + { + setup->regBits +=2; + } + if (encoder->frame_ms == 2.5) + { + setup->regBits -= 6; + } + } + else + { + if (encoder->frame_ms == 2.5) + { + setup->regBits -= 6; + } + else if (encoder->frame_ms == 5) + { + setup->regBits += 0; + } + if (encoder->frame_ms == 10) + { + setup->regBits += 5; + } + } + if (setup->regBits < 6) + { + setup->regBits = 6; + } + if (setup->regBits > 23) + { + setup->regBits = 23; + } + } + else + { + setup->regBits = -1; + } + } + + encoder->bitrate = bitrate; + + return LC3PLUS_OK; +} + +void update_enc_bandwidth(LC3PLUS_Enc* encoder, int bandwidth) +{ + int index = 0; + + if (bandwidth >= encoder->fs_in) { + encoder->bandwidth = 0; + } + else + { + encoder->bandwidth = bandwidth; + index = FS2FS_IDX(bandwidth); + if (index > 4) { + index = 5; + } + encoder->bw_ctrl_cutoff_bin = encoder->cutoffBins[index]; + } +} diff --git a/lc3plus/setup_enc_lc3.h b/lc3plus/setup_enc_lc3.h new file mode 100644 index 0000000000000000000000000000000000000000..31f0cbeb50edfb2f21c87c29192f3539f9045401 --- /dev/null +++ b/lc3plus/setup_enc_lc3.h @@ -0,0 +1,119 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#ifndef SETUP_ENC_LC3_FL_H +#define SETUP_ENC_LC3_FL_H + +#include "constants.h" + +/* Channel state and bitrate-derived values go in this struct */ +typedef struct { + LC3_FLOAT targetBitsOff; + LC3_FLOAT ltpf_mem_normcorr; + LC3_FLOAT ltpf_mem_mem_normcorr; + LC3_FLOAT attdec_filter_mem[2]; + LC3_FLOAT attdec_acc_energy; + LC3_FLOAT r12k8_mem_50[2]; + LC3_FLOAT r12k8_mem_in[120]; + LC3_FLOAT r12k8_mem_out[24]; + LC3_FLOAT olpa_mem_s12k8[3]; + LC3_FLOAT olpa_mem_s6k4[LEN_6K4 + MAX_PITCH_6K4 + 16]; + LC3_FLOAT ltpf_mem_in[LTPF_MEMIN_LEN + LEN_12K8 + 1]; + LC3_FLOAT s_in_scaled[MAX_LEN]; + LC3_FLOAT s_12k8[LEN_12K8 + 1]; + LC3_FLOAT ener[MAX_BANDS_NUMBER]; + LC3_FLOAT scf_q[M]; + LC3_FLOAT scf[M]; + LC3_FLOAT int_scf[MAX_BANDS_NUMBER]; + LC3_FLOAT ltpf_mem_pitch; + + LC3_INT targetBytes; + LC3_INT total_bits; + LC3_INT targetBitsInit; + LC3_INT targetBitsAri; + LC3_INT enable_lpc_weighting; + LC3_INT ltpf_enable; + LC3_INT quantizedGainOff; + LC3_INT tns_bits; + LC3_INT targetBitsQuant; + LC3_INT olpa_mem_pitch; + LC3_INT ltpf_mem_ltpf_on; + LC3_INT mem_targetBits; + LC3_INT mem_specBits; + LC3_INT attack_handling; /* flag to enable attack handling */ + LC3_INT attdec_detected; + LC3_INT attdec_position; + LC3_INT ltpf_param[3]; + LC3_INT L_scf_idx[SCF_MAX_PARAM]; + LC3_INT codingdata[3 * MAX_LEN]; + uint8_t resBits[MAX_RESBITS_LEN]; + LC3_INT regBits; + + LC3_INT16 n_pc; + LC3_INT16 n_pccw; + LC3_INT16 be_bp_left; + LC3_INT16 be_bp_right; + + Mdct mdctStruct; + Dct2 dct2StructSNS; + + LC3_INT lfe; +} EncSetup; + +/* Constants and sampling rate derived values go in this struct */ +struct LC3PLUS_Enc { + EncSetup* channel_setup[MAX_CHANNELS]; + const LC3_INT* W_fx; + const LC3_INT* bands_offset; + const LC3_INT* cutoffBins; + + LC3_INT fs; /* encoder sampling rate 44.1 -> 48 */ + LC3_INT fs_in; /* input sampling rate */ + LC3_INT bitrate; /* global bitrate */ + LC3_INT fs_idx; /* sampling rate index */ + LC3_INT frame_length; /* audio samples / frame */ + LC3_INT channels; /* number of channels */ + LC3_INT epmode; /* error protection mode */ + LC3_FLOAT frame_ms; /* frame length in ms (wrong for 44.1) */ + LC3_INT frame_dms; /* frame length in ms * 10 (wrong for 44.1) */ + LC3_INT tilt; + LC3_INT lc3_br_set; + LC3_INT yLen; + LC3_INT W_size; + LC3_INT la_zeroes; + LC3_INT stEnc_mdct_mem_len; + LC3_INT bands_number; + LC3_INT nSubdivisions; + LC3_INT ltpf_mem_in_len; + LC3_INT envelope_bits; + LC3_INT global_gain_bits; + LC3_INT noise_fac_bits; + LC3_INT BW_cutoff_bits; + LC3_INT r12k8_mem_in_len; + LC3_INT r12k8_mem_out_len; + LC3_INT16 near_nyquist_index; + LC3_INT16 near_nyquist_flag; + LC3_INT tnsMaxOrder; + LC3_INT hrmode; + LC3_INT bandwidth; + LC3_INT bandwidth_preset; + LC3_INT bw_ctrl_active; + LC3_INT bw_ctrl_cutoff_bin; + LC3_INT bw_index; + LC3_FLOAT sns_damping; + LC3_INT attdec_nblocks; + LC3_FLOAT attdec_damping; + LC3_INT attdec_hangover_thresh; + + LC3_INT16 combined_channel_coding; + LC3_INT16 epmr; +}; + +#endif diff --git a/lc3plus/sns_compute_scf.c b/lc3plus/sns_compute_scf.c new file mode 100644 index 0000000000000000000000000000000000000000..5cb041925bbcf0dc5b8a0c47f0b5d8aa07d01bd1 --- /dev/null +++ b/lc3plus/sns_compute_scf.c @@ -0,0 +1,177 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor) +{ + LC3_INT bands_number = 0, d = 0, i = 0, j = 0, n = 0, n2 = 0, n4 = 0, mapping[64] = {0}; + LC3_FLOAT tmp[64] = {0}, x_tmp1[MAX_LEN] = {0}, x_tmp2[MAX_LEN] = {0}, sum = 0, mean = 0, xl4[16] = {0}, nf = 0, xl[64] = {0}, gains_smooth[M] = {0}, ratio = 0; + LC3_FLOAT W[6] = {1.0 / 12.0, 2.0 / 12.0, 3.0 / 12.0, 3.0 / 12.0, 2.0 / 12.0, 1.0 / 12.0}; + + bands_number = xLen; + assert(bands_number <= 64); + + /* 5 ms */ + if (bands_number < 64) { + d = 64 - bands_number; + + if (d < xLen) + { + j = 0; + for (i = 0; i < 2 * d; i = i + 2) { + tmp[i] = x[j]; + tmp[i + 1] = x[j]; + j++; + } + + move_float(&tmp[2 * d], &x[d], 64 - 2 * d); + } else if (ceil(64.0 / (LC3_FLOAT) xLen) == 4) + { + ratio = LC3_FABS((LC3_FLOAT) (1.0 - 32.0 / (LC3_FLOAT) xLen)); + n4 = round(ratio * xLen); + n2 = xLen - n4; + + j = 0; + for(i = 1; i <= n4; i++) + { + mapping[j] = i; + mapping[j + 1] = i; + mapping[j + 2] = i; + mapping[j + 3] = i; + j += 4; + } + + for (i = n4 + 1; i <= n4 + n2; i++) + { + mapping[j] = i; + mapping[j + 1] = i; + j += 2; + } + + + for (i = 0; i < 64; i++) + { + tmp[i] = x[mapping[i] - 1]; + } + } else { + assert(0 && "Unsupported number of bands!"); + } + + move_float(x, tmp, 64); + + bands_number = 64; + xLen = bands_number; + } + + + /* Smoothing */ + + x_tmp1[0] = x[0]; + + move_float(&x_tmp1[1], &x[0], xLen - 1); + + move_float(&x_tmp2[0], &x[1], xLen - 1); + + x_tmp2[xLen - 1] = x[xLen - 1]; + + for (i = 0; i < xLen; i++) { + x[i] = 0.5 * x[i] + 0.25 * (x_tmp1[i] + x_tmp2[i]); + } + + /* Pre-emphasis */ + for (i = 0; i < xLen; i++) { + x[i] = x[i] * LC3_POW(10.0, (LC3_FLOAT)i * (LC3_FLOAT)tilt / ((LC3_FLOAT)bands_number - 1.0) / 10.0); + } + + /* Noise floor at -40dB */ + for (i = 0; i < 64; i++) { + sum += x[i]; + } + + mean = sum / (LC3_FLOAT)xLen; + + nf = mean * LC3_POW(10.0, -40.0 / 10.0); + nf = MAX(nf, LC3_POW(2.0, -32.0)); + + for (i = 0; i < 64; i++) { + if (x[i] < nf) { + x[i] = nf; + } + } + + /* Log-domain */ + for (i = 0; i < 64; i++) { + xl[i] = LC3_LOGTWO(x[i]) / 2.0; + } + + /* Downsampling */ + for (n = 0; n < bands_number / 4; n++) { + if (n == 0) { + tmp[0] = xl[0]; + + move_float(&tmp[1], &xl[0], 5); + + } else if (n == (bands_number / 4 - 1)) { + move_float(tmp, &xl[59], 5); + + tmp[5] = xl[63]; + + } else { + move_float(tmp, &xl[n * 4 - 1], ((n * 4 + 5 - 1) - (n * 4 - 1) + 1)); + } + + sum = 0; + for (i = 0; i < 6; i++) { + sum += tmp[i] * W[i]; + } + + xl4[n] = sum; + } + + + /* Remove mean and scaling */ + + sum = 0; + for (i = 0; i < bands_number / 4; i++) { + sum += xl4[i]; + } + + mean = sum / ((LC3_FLOAT)bands_number / 4.0); + + for (i = 0; i < bands_number / 4; i++) { + gains[i] = sns_damping * (xl4[i] - mean); + } + + /* Smoothing */ + if (smooth) { + gains_smooth[0] = (gains[0] + gains[1] + gains[2]) / 3.0; + gains_smooth[1] = (gains[0] + gains[1] + gains[2] + gains[3]) / 4.0; + + for (i = 2; i < 14; i++) { + gains_smooth[i] = (gains[i - 2] + gains[i - 1] + gains[i] + gains[i + 1] + gains[i + 2]) / 5.0; + } + + gains_smooth[M - 2] = (gains[M - 4] + gains[M - 3] + gains[M - 2] + gains[M - 1]) / 4.0; + gains_smooth[M - 1] = (gains[M - 3] + gains[M - 2] + gains[M - 1]) / 3.0; + + sum = 0; + for (i = 0; i < M; i++) { + sum += gains_smooth[i]; + } + + mean = sum / (LC3_FLOAT)M; + + for (i = 0; i < M; i++) { + gains[i] = attdec_damping_factor * (gains_smooth[i] - mean); + } + } +} diff --git a/lc3plus/sns_interpolate_scf.c b/lc3plus/sns_interpolate_scf.c new file mode 100644 index 0000000000000000000000000000000000000000..4419397890d890f097d538b3ee4799ca1a14c7b9 --- /dev/null +++ b/lc3plus/sns_interpolate_scf.c @@ -0,0 +1,90 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +void processSnsInterpolateScf_fl(LC3_FLOAT* gains, LC3_INT encoder_side, LC3_INT bands_number, LC3_FLOAT* gains_int) +{ + LC3_INT i = 0, n = 0, d = 0, n4 = 0; + LC3_FLOAT tmp[MAX_BANDS_NUMBER_PLC] = {0}, ratio = 0; + + /* Interpolation */ + + gains_int[0] = gains[0]; + gains_int[1] = gains[0]; + + for (n = 0; n <= 14; n++) { + gains_int[n * 4 + 2] = gains[n] + (gains[n + 1] - gains[n]) / 8.0; + gains_int[n * 4 + 3] = gains[n] + 3.0 * (gains[n + 1] - gains[n]) / 8.0; + gains_int[n * 4 + 4] = gains[n] + 5.0 * (gains[n + 1] - gains[n]) / 8.0; + gains_int[n * 4 + 5] = gains[n] + 7.0 * (gains[n + 1] - gains[n]) / 8.0; + } + + gains_int[62] = gains[15] + (gains[15] - gains[14]) / 8.0; + gains_int[63] = gains[15] + 3.0 * (gains[15] - gains[14]) / 8.0; + + /* For 5ms */ + + if (bands_number < 64) { + d = 64 - bands_number; + + if (d < 32) + { + i = 0; + for (n = 0; n < 2 * d; n = n + 2) { + tmp[i] = (gains_int[n] + gains_int[n + 1]) / (LC3_FLOAT)2.0; + i++; + } + + for (n = 1; n < d; n++) { + gains_int[n] = gains_int[2 * n]; + } + + for (n = 2 * d; n < 64; n++) { + gains_int[n - d] = gains_int[n]; + } + + move_float(gains_int, tmp, d); + } else if (ceil(64.0 / (LC3_FLOAT) bands_number) == 4) + { + ratio = LC3_FABS((LC3_FLOAT) ((LC3_FLOAT)1.0 - (LC3_FLOAT)32.0 / (LC3_FLOAT) bands_number)); + n4 = LC3_ROUND(ratio * (LC3_FLOAT)bands_number); + + for (i = 0; i < n4; i++) + { + tmp[i] = (gains_int[4 * i] + gains_int[4 * i + 1] + gains_int[4 * i + 2] + gains_int[4 * i + 3]) / 4.0; + } + + for (i = 0; i < bands_number - n4; i++) + { + tmp[n4 + i] = (gains_int[4 * n4 + 2 * i] + gains_int[4 * n4 + 2 * i + 1]) / 2.0; + } + + move_float(gains_int, tmp, bands_number); + } else { + assert(0 && "Unsupported number of bands!"); + } + } + + /* Inversion at encoder-side */ + + if (encoder_side == 1) { + for (n = 0; n < bands_number; n++) { + gains_int[n] = -gains_int[n]; + } + } + + /* Linear domain */ + + for (n = 0; n < bands_number; n++) { + gains_int[n] = LC3_POW(2, gains_int[n]); + } +} diff --git a/lc3plus/sns_quantize_scf.c b/lc3plus/sns_quantize_scf.c new file mode 100644 index 0000000000000000000000000000000000000000..704127cce71fdab61027a76f66f9382859048ed4 --- /dev/null +++ b/lc3plus/sns_quantize_scf.c @@ -0,0 +1,517 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +static void pvq_dec(LC3_INT k, LC3_INT m, LC3_INT LS_ind, LC3_INT MPVQ_ind, LC3_INT* pulses); +static LC3_INT find_last_indice_le(LC3_INT compare, const LC3_INT* array, LC3_INT len); +static void idct_II(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT len); + +void idct_II(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT len) +{ + LC3_INT i; + LC3_FLOAT norm1, sum; + + norm1 = 0.353553390593274; /* sqrt(2 / 16) */ + + for (i = 0; i < len; i++) { + sum = mac_loop(in, idct_lookup[i], len); + out[i] = norm1 * sum; + } +} + +static LC3_INT pvq_pulse_search(LC3_FLOAT *xabs, LC3_FLOAT *ener, LC3_FLOAT *corr, LC3_INT *y, LC3_INT start, LC3_INT end) +{ + LC3_INT i; + LC3_INT nBest; + LC3_FLOAT bestCorrSq, bestEn; + LC3_FLOAT corrSq, currCorr, currEn; + + nBest = 0; + bestCorrSq = 0.0; + bestEn = 0.0; + + *ener += 1; // Added once for the entire loop + + i = start; + + currCorr = *corr + xabs[i]; + currEn = *ener + (2 * y[i]); + + corrSq = currCorr * currCorr; + + bestEn = currEn; + bestCorrSq = corrSq; + nBest = i; + + /* Iterative max search as recommended in the spec */ + for (; i < end; i++) + { + currCorr = *corr + xabs[i]; + currEn = *ener + (2 * y[i]); + + corrSq = currCorr * currCorr; + + if ((corrSq * bestEn) > (bestCorrSq * currEn)) + { + bestEn = currEn; + bestCorrSq = corrSq; + nBest = i; + } + } + + *corr += xabs[nBest]; + *ener += (2 * y[nBest]); + + y[nBest] += 1; /* Add the selected unit pulse */ + + return nBest; +} + +static void pvq_enc_vec_normalize(LC3_FLOAT *vec, LC3_INT N) +{ + LC3_FLOAT mag = 0.0, norm_fac; + LC3_INT i; + + for (i = 0; i < N; i++) + { + mag += (vec[i] * vec[i]); + } + + norm_fac = 1.0 / LC3_SQRT(mag); + + for (i = 0; i < N; i++) + { + vec[i] = vec[i] * norm_fac; + } + + return; +} + +static void pvq_enc_search(LC3_FLOAT* x_in, LC3_INT y[4][M]) +{ + LC3_INT i, N, K, pulse_total, N_setA; + LC3_FLOAT abs_sum, projfac; + LC3_FLOAT xabs[16]; + LC3_FLOAT yy, xy; + + abs_sum = 0.0; + + /* Step 1 : Projection to pyramid N=16, K=6 */ + N = 16; + K = 6; + pulse_total = 0; + N_setA = 10; + + yy = xy = 0.0f; + + for (i = 0; i < N; i++) + { + xabs[i] = LC3_FABS(x_in[i]); + abs_sum += xabs[i]; + } + + projfac = (K - 1) / abs_sum; + + for (i = 0; i < N; i++) + { + y[3][i] = floor(xabs[i] * projfac); + + pulse_total += y[3][i]; + + yy += (y[3][i] * y[3][i]); + xy += (xabs[i] * y[3][i]); + } + + /* Step 2: Adding unit pulses up to K = 6 */ + for (; pulse_total < K; pulse_total++) + { + pvq_pulse_search(xabs, &yy, &xy, y[3], 0, N); + } + + /* Step 3: Adding unit pulses up to K = 8 */ + memcpy(y[2], y[3], sizeof(LC3_INT)*N); + K = 8; + + for (; pulse_total < K; pulse_total++) + { + pvq_pulse_search(xabs, &yy, &xy, y[2], 0, N); + } + + memcpy(y[1], y[2], sizeof(LC3_INT)*N_setA); + + /* Step 4: Remove unit pulses not belonging to set A */ + for (i = N_setA; i < N; i++) + { + y[1][i] = 0; + } + + /* Step 5: Update yy and xy terms to reflect y1 */ + yy = 0; + xy = 0; + pulse_total = 0; + + for (i = 0; i < N_setA; i++) + { + yy += (y[1][i] * y[1][i]); + xy += (xabs[i] * y[1][i]); + + pulse_total += y[1][i]; + } + + /* Step 6: Add unit pulses until K = 10 over N = 10 */ + K = 10; + for (; pulse_total < K; pulse_total++) + { + pvq_pulse_search(xabs, &yy, &xy, y[1], 0, N_setA); + } + + memcpy(y[0], y[1], sizeof(LC3_INT)*N); + + /* Step 7: Add unit pulses until K = 1 over N = 6 in set B*/ + pvq_pulse_search(xabs, &yy, &xy, y[0], N_setA, N); + + /* Step 8: Add signs to each of the 4 vectors from x */ + for (i = 0; i < N; i++) + { + if (x_in[i] < 0) + { + y[0][i] = -y[0][i]; + y[1][i] = -y[1][i]; + y[2][i] = -y[2][i]; + y[3][i] = -y[3][i]; + } + } + + return; +} + +static inline LC3_FLOAT calc_mse(LC3_FLOAT *t2rot, LC3_FLOAT *y, LC3_FLOAT gain, LC3_INT N) +{ + LC3_FLOAT mse; + LC3_INT i; + + mse = 0.0; + + for (i = 0; i < N; i++) + { + LC3_FLOAT err = (t2rot[i] - gain * y[i]); + mse += (err * err); + } + + return mse; +} + +static void sns_quant_adj_gain_shape_search(LC3_FLOAT *t2rot, LC3_INT y[4][M] , + LC3_INT *gain_idx, LC3_INT *shape_idx, LC3_FLOAT *y_norm, LC3_FLOAT *scq_gain) +{ + LC3_INT gidx, sidx; + LC3_FLOAT min_mse, mse; + LC3_INT N; + LC3_FLOAT yCur[4][16]; + LC3_INT i; + + const LC3_INT gain_levels[4] = { 2, 4, 4, 8 }; + const LC3_FLOAT *sns_vq_gains[4] = { sns_vq_reg_adj_gains_fl , sns_vq_reg_lf_adj_gains_fl , + sns_vq_near_adj_gains_fl , sns_vq_far_adj_gains_fl }; + + min_mse = -1.0; + N = 16; + + + *gain_idx = *shape_idx = 0; + + for (sidx = 0; sidx < 4; sidx++) + { + for (i = 0; i < N; i++) + { + yCur[sidx][i] = (LC3_FLOAT)y[sidx][i]; + } + + /* Step 9: Normalize the vectors */ + pvq_enc_vec_normalize(yCur[sidx], N); + + for (gidx = 0; gidx < gain_levels[sidx]; gidx++) + { + mse = calc_mse(t2rot, yCur[sidx], sns_vq_gains[sidx][gidx], N); + + if ((mse < min_mse) || (min_mse < 0)) + { + *gain_idx = gidx; + *shape_idx = sidx; + min_mse = mse; + } + } + } + + for (i = 0; i < N; i++) + { + y_norm[i] = yCur[*shape_idx][i]; + } + + *scq_gain = sns_vq_gains[*shape_idx][*gain_idx]; + + return; +} + +static void enc_push_sign(LC3_FLOAT val, LC3_UINT32 *next_sign_ind, LC3_INT *index) +{ + if (((*next_sign_ind & 0x80000000U) == 0) && (val != 0)) { + *index = 2 * (*index) + *next_sign_ind; + } + if (val < 0) { + *next_sign_ind = 1; + } + if (val > 0) { + *next_sign_ind = 0; + } + + return; +} + +static void MPVQ_enum(LC3_INT dim, LC3_INT *sns_vec, LC3_INT *index_val, LC3_INT *lead_sign_ind) +{ + LC3_UINT32 next_sign_ind; + LC3_INT k_val_acc; + LC3_INT pos; + LC3_INT index, n; + LC3_INT const *row_ptr; + + /* MPVQ-index composition loop */ + LC3_INT tmp_h_row; + LC3_INT tmp_val; + + next_sign_ind = 0x80000000U; + k_val_acc = 0; + pos = dim; + index = 0; + n = 0; + + row_ptr = (LC3_INT const *)&(pvq_enc_A[n]); + tmp_h_row = row_ptr[0]; + + for (pos--; pos >= 0; pos--) + { + tmp_val = sns_vec[pos]; + enc_push_sign(tmp_val, &next_sign_ind, &index); + + index += tmp_h_row; + k_val_acc += abs(tmp_val); + if (pos != 0) { + n += 1; /* switch row in offset table MPVQ_offsets(n, k) */ + } + row_ptr = (LC3_INT const *)&(pvq_enc_A[n]); + + tmp_h_row = row_ptr[k_val_acc]; + } + + *index_val = index; + *lead_sign_ind = next_sign_ind; + + return; +} + +static LC3_INT MSEsearch (LC3_FLOAT *scf, const LC3_FLOAT sns_CB[8][32]) +{ + LC3_FLOAT distance, mse; + LC3_INT i, n, ind; + + ind = 0; + + distance = (LC3_FLOAT) LC3_CONST_POW_2_100; + for (i = 0; i < 32; i++) { + mse = 0; + for (n = 0; n < 8; n++) { + mse += (scf[n] - sns_CB[n][i]) * (scf[n] - sns_CB[n][i]); + } + + if (mse < distance) { + distance = mse; + ind = i; + } + } + return ind; +} + +void process_snsQuantizesScf_Enc(LC3_FLOAT* env, LC3_INT* index, LC3_FLOAT* envq, Dct2 dct2structSNS) +{ + LC3_FLOAT stage2_en1_norm_sub[M]; + LC3_INT i, j; + LC3_FLOAT st1_vector[M]; + LC3_FLOAT pvq_target_pre[M]; + LC3_FLOAT pvq_target[M]; + LC3_FLOAT stage2_en1_norm_pre_sub[M]; + LC3_INT gain, shape; + LC3_FLOAT scfq_gain; + LC3_INT y[4][M]; + + /* Stage 1 split VQ */ + index[0] = MSEsearch(&env[0], sns_LFCB); /* ind_LF */ + index[1] = MSEsearch(&env[8], sns_HFCB); /* ind_HF */ + + j = 8; + for (i = 0; i < 8; i++, j++) { + st1_vector[i] = sns_LFCB[i][index[0]]; + st1_vector[j] = sns_HFCB[i][index[1]]; + } + + /* STAGE 2 */ + for (i = 0; i < 16; i++) { + pvq_target_pre[i] = env[i] - st1_vector[i]; + } + + dct2_apply(&dct2structSNS, pvq_target_pre, pvq_target); + pvq_enc_search(pvq_target, y); + sns_quant_adj_gain_shape_search(pvq_target, y, &gain, &shape, stage2_en1_norm_pre_sub, &scfq_gain); + + /* Inverse transform */ + idct_II(stage2_en1_norm_pre_sub, stage2_en1_norm_sub, M); + + index[2] = shape; + index[3] = gain; + + if (shape < 2) { + MPVQ_enum(10, y[shape], &index[5], &index[4]); + } + else { + MPVQ_enum(M, y[shape], &index[5], &index[4]); + } + + if (shape == 0) { + LC3_INT ls_ind, ind; + MPVQ_enum(6, &y[shape][10], &ind, &ls_ind); + index[6] = ind * 2 + ls_ind; + } + else if (shape == 2) { + index[6] = -1; + } + else { + index[6] = -2; + } + + for (i = 0; i < M; i++) { + envq[i] = st1_vector[i] + (stage2_en1_norm_sub[i] * scfq_gain); + } +} + +LC3_INT find_last_indice_le(LC3_INT compare, const LC3_INT* array, LC3_INT len) +{ + LC3_INT idx = 0, i = 0; + + for (i = 0; i < len; i++) { + if (compare >= array[i]) { + idx++; + } + } + + if (idx > 0) { + idx--; + } + + return idx; +} + +void pvq_dec(LC3_INT k, LC3_INT m, LC3_INT LS_ind, LC3_INT MPVQ_ind, LC3_INT* pulses) +{ + LC3_INT leading_sign = 0, idx = 0, k_delta = 0, pos = 0; + + leading_sign = 1 - 2 * LS_ind; + + /* Decoding loop */ + + for (pos = 0; pos < m; pos++) { + if (MPVQ_ind != 0) { + /* Find last indice */ + idx = find_last_indice_le(MPVQ_ind, &pvq_enc_A[m - pos - 1][0], k + 1); + MPVQ_ind = MPVQ_ind - pvq_enc_A[m - pos - 1][idx]; + k_delta = k - idx; + } else { + pulses[pos] = leading_sign * k; + break; + } + + if (k_delta != 0) { + pulses[pos] = leading_sign * k_delta; + if ((MPVQ_ind % 2) != 0) { + leading_sign = -1; + } else { + leading_sign = 1; + } + + MPVQ_ind = floor(MPVQ_ind / 2); + k = k - k_delta; + } + } +} + +void process_snsQuantizesScf_Dec(LC3_INT* scf_idx, LC3_FLOAT* scf_q) +{ + LC3_INT i = 0, submode = 0; + LC3_INT pulses2[6] = {0}, pulses[M] = {0}; + LC3_FLOAT st2_vector[M] = {0}, st2_vector_idct[M] = {0}, sum = 0; + + /* Decode first stage */ + + for (i = 0; i < 8; i++) { + scf_q[i] = sns_LFCB[i][scf_idx[0]]; + scf_q[i + 8] = sns_HFCB[i][scf_idx[1]]; + } + + /* STAGE 2 */ + /* Decode submode */ + + submode = scf_idx[2]; + + /* Decode pulses */ + + if (submode < 2) { + pvq_dec(10, 10, scf_idx[4], scf_idx[5], pulses); + + if (submode == 0) { + pvq_dec(1, 6, (scf_idx[6] % 2), floor(scf_idx[6] / 2), pulses2); + + move_int(&pulses[10], pulses2, 6); + + } else { + pulses[15] = 0; + } + } else if (submode == 2) { + pvq_dec(8, 16, scf_idx[4], scf_idx[5], pulses); + } else { + pvq_dec(6, 16, scf_idx[4], scf_idx[5], pulses); + } + + /* Normalization */ + + for (i = 0; i < M; i++) { + sum += pulses[i] * pulses[i]; + } + + sum = 1.0 / LC3_SQRT(sum); + + for (i = 0; i < M; i++) { + st2_vector[i] = pulses[i] * sum; + } + + /* Inverse transform */ + idct_II(st2_vector, st2_vector_idct, M); + + /* Gain */ + for (i = 0; i < M; i++) { + st2_vector_idct[i] = st2_vector_idct[i] * sns_dec_gains[submode][scf_idx[3]]; + } + + /* Add stage 1 and stage 2 */ + + for (i = 0; i < M; i++) { + scf_q[i] = scf_q[i] + st2_vector_idct[i]; + } +} diff --git a/lc3plus/structs.h b/lc3plus/structs.h new file mode 100644 index 0000000000000000000000000000000000000000..fea377da412ed0c7c1df662d74537495d911353c --- /dev/null +++ b/lc3plus/structs.h @@ -0,0 +1,186 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#ifndef STRUCTS_H +#define STRUCTS_H + +#include "defines.h" +#include "fft/iisfft.h" + +typedef struct { + LC3_FLOAT r; /* real part */ + LC3_FLOAT i; /* imaginary part */ +} Complex; + +typedef struct { + LC3_INT length; + void *handle; +} Fft; + +typedef struct { + LC3_INT length; + Fft fft; +} Dct2; + +typedef struct { + LC3_INT length; + Fft fft; +} Dct3; + +typedef struct { + LC3_INT length; + Complex *twid1; + Complex *twid2; + Fft fft; +} Dct4; + +typedef struct { + LC3_INT length; + LC3_INT leading_zeros; + LC3_INT mem_length; + const LC3_FLOAT *window; + LC3_FLOAT *mem; + Dct4 dct; +} Mdct; + +typedef struct { + uint32_t ac_low_fl; + uint32_t ac_range_fl; + int BER_detect; + + LC3_INT32 pc_c_bp; + LC3_INT32 pc_c_bp_side; + LC3_INT32 pc_bytes; + LC3_INT32 pc_b_left; + LC3_INT32 pc_b_right; + LC3_INT32 pc_enc; + LC3_INT32 pc_bfi; + LC3_INT32 pc_bbi; + LC3_INT32 pc_be_bp_left; + LC3_INT32 pc_be_bp_right; + LC3_INT32 pc_return; +} Decoder_State_fl; + +typedef struct { + LC3_INT bp; + LC3_INT low; + LC3_INT range; + LC3_INT cache; + LC3_INT carry; + LC3_INT carry_count; + uint8_t *ptr; + LC3_INT *bp_side; + LC3_INT *mask_side; +} Encoder_State_fl; + +typedef struct { + LC3_INT nbLostCmpt; + LC3_INT prevBfi; + LC3_INT prevprevBfi; + LC3_FLOAT q_d[MAX_LEN]; + LC3_FLOAT q_d_prev[MAX_LEN]; +} PlcSetup; + + +typedef struct { + LC3_FLOAT cum_alpha; + LC3_INT seed; +} PlcNsSetup; + +typedef struct { + LC3_INT32 seed; + LC3_INT32 ns_nbLostCmpt_pc; + LC3_FLOAT *q_old_res; + LC3_FLOAT prev_gg; +} pcState; + +typedef struct { + LC3_INT len; + LC3_INT sign; + LC3_FLOAT* table; +} Cfft; + +typedef struct T_IIS_FFT { + IIS_FFT_DIR sign; + LC3_INT32 len; + LC3_FLOAT* buffer; + LC3_FLOAT* sine_table; + Iisfft iisfft; + Cfft cfft; +} IIS_FFT; + +typedef struct T_IIS_FFT* HANDLE_IIS_FFT; + +typedef struct { + Fft PhEcu_Fft; /*no counterpart in BASOP */ + Fft PhEcu_Ifft; /*no counterpart in BASOP */ + + + LC3_FLOAT PhECU_f0hzLtpBin; /* BASOP Word16 PhECU_f0hzLtpBinQ7 */ + LC3_FLOAT PhECU_norm_corr; /* BASOP Word16 norm_corrQ15 */ + + LC3_FLOAT *PhECU_oold_grp_shape; /* BASOP Word16 PhECU_oold_grp_shape_fx[MAX_LGW]; */ + LC3_FLOAT *PhECU_old_grp_shape; /* BASOP Word16 PhECU_old_grp_shape_fx[MAX_LGW] ; */ + + LC3_FLOAT PhECU_L_oold_xfp_w_E; /* BASOP Word32 PhECU_L_oold_xfp_w_E_fx;*/ + LC3_FLOAT PhECU_L_old_xfp_w_E; /* BASOP Word32 PhECU_L_old_xfp_w_E_fx; */ + + LC3_INT32 PhECU_Lprot ; /* BASOP Word16 PhECU_Lprot_fx;*/ + + LC3_FLOAT *PhECU_xfp; + Complex *PhECU_X_sav_m; + LC3_INT32 *PhECU_plocs; /* BASOP Word16 *PhECU_plocs; */ /* MAX_PLOCS */ + LC3_FLOAT *PhECU_f0est; /*BASOP Word32 *PhECU_f0est;*/ + + LC3_FLOAT *PhECU_mag_chg_1st; /* BASOP Word16 PhECU_mag_chg_1st[MAX_LGW];*/ + LC3_FLOAT *PhECU_Xavg; /* BASOP Word16 PhECU_Xavg[MAX_LGW] ; */ + + LC3_FLOAT PhECU_beta_mute; /* BASOP Word16 PhECU_beta_mute*/ + + LC3_INT16 PhECU_seed; /* BASOP Word16 PhECU_seed_fx;*/ + + LC3_INT32 PhECU_LDWIN_OLAP; /* BASOP Word16 PhECU_LDWIN_OLAP; */ + LC3_INT32 PhECU_t_adv; /* BASOP Word16 t_adv; */ + + LC3_INT32 PhECU_short_flag_prev; + LC3_INT32 PhECU_time_offs; + LC3_INT32 PhECU_num_plocs; + HANDLE_IIS_FFT handle_fft_phaseecu; + HANDLE_IIS_FFT handle_ifft_phaseecu; + +} PlcPhEcuSetup; + +typedef struct { + LC3_INT16 seed; + LC3_FLOAT gain_c; + LC3_INT32 lpcorder; + LC3_FLOAT A[M+1]; + LC3_INT32 fract; + LC3_INT32 lagw_bw; + LC3_FLOAT preemphFac; + LC3_FLOAT *harmonicBuf; + LC3_FLOAT synthHist[M]; +} PlcTdcSetup; + +typedef struct { + LC3_FLOAT *pcmbufHist; + LC3_INT32 max_len_pcm_plc; + PlcTdcSetup PlcTdcSetup; + LC3_FLOAT stabFac; + LC3_FLOAT cum_fading_slow; + LC3_FLOAT cum_fading_fast; + LC3_FLOAT cum_fflcAtten; + LC3_FLOAT scf_q_old[M]; + LC3_FLOAT scf_q_old_old[M]; + PlcPhEcuSetup PlcPhEcuSetup; +} PlcAdvSetup; + + +#endif diff --git a/lc3plus/tns_coder.c b/lc3plus/tns_coder.c new file mode 100644 index 0000000000000000000000000000000000000000..ff3883d2b5fa964a7a2c4a4523757432d080a5cb --- /dev/null +++ b/lc3plus/tns_coder.c @@ -0,0 +1,374 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +static void xcorr(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT lag, LC3_INT inLen); +static void levdown(LC3_FLOAT* anxt, LC3_FLOAT* out_a, LC3_INT* len); +static void poly2rc(LC3_FLOAT* a, LC3_FLOAT* out, LC3_INT len); +static LC3_INT findRC_idx(const LC3_FLOAT* in1, const LC3_FLOAT* in2, LC3_FLOAT checkValue); + +void xcorr(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT lag, LC3_INT inLen) +{ + LC3_INT i = 0, m = 0; + LC3_FLOAT sum = 0, tmp_buf[MAX_LEN] = {0}; + + for (m = -lag; m <= lag; m++) { + /* Append zeros and input vector */ + + zero_float(tmp_buf, abs(m)); + + move_float(&tmp_buf[abs(m)], in, inLen - abs(m)); + + /* Calculate sum */ + sum = 0; + + for (i = 0; i < inLen; i++) { + sum += in[i] * tmp_buf[i]; + } + + out[m + lag] = sum; + } +} + +void levinsonDurbin(LC3_FLOAT* r, LC3_FLOAT* out_lev, LC3_FLOAT* rc_unq, LC3_FLOAT* error, LC3_INT len) +{ + LC3_INT t = 0, i = 0, j = 0; + LC3_FLOAT g = 0, v = 0, sum = 0, buf_tmp[MAX_LEN] = {0}; + + g = r[1] / r[0]; + out_lev[0] = g; + + v = (1.0 - g * g) * r[0]; + rc_unq[0] = -g; + + for (t = 1; t < len; t++) { + zero_float(buf_tmp, len + 1); + + sum = 0; + for (i = 1; i <= t; i++) { + sum += out_lev[i - 1] * r[i]; + } + + g = (r[t + 1] - sum) / v; + + j = 1; + for (i = t - 1; i >= 0; i--) { + buf_tmp[j] = out_lev[j - 1] - g * out_lev[i]; + j++; + } + + move_float(&out_lev[1], &buf_tmp[1], len); + + out_lev[0] = g; + + v = v * (1 - g * g); + rc_unq[t] = -g; + } + + /* Reorder out_lev */ + out_lev[0] = 1; + j = 1; + for (i = len - 1; i >= 0; i--) { + buf_tmp[j] = -out_lev[i]; + j++; + } + + move_float(&out_lev[1], &buf_tmp[1], (len - 1)); + + out_lev[len] = rc_unq[len - 1]; + + *error = v; +} + +void levdown(LC3_FLOAT* anxt, LC3_FLOAT* out_a, LC3_INT* len) +{ + LC3_INT i = 0, j = 0; + LC3_FLOAT tmp_buf[8] = {0}, tmp_buf1[8] = {0}, tmp_buf2[8] = {0}, knxt = 0; + + /* Initial length = 9 */ + + /* Drop the leading 1 */ + + move_float(&tmp_buf[0], &anxt[1], (*len - 1)); + + *len = *len - 1; /* Lenght = 8 */ + + /* Last coefficient */ + knxt = tmp_buf[*len - 1]; /* At [7] */ + + *len = *len - 1; /* Lenght = 7 */ + + move_float(tmp_buf1, tmp_buf, *len); + + j = 0; + for (i = *len - 1; i >= 0; i--) { + tmp_buf2[j] = knxt * tmp_buf[i]; + j++; + } + + out_a[0] = 1; + for (i = 0; i < *len; i++) { + out_a[i + 1] = (tmp_buf1[i] - tmp_buf2[i]) / (1.0 - (LC3_FABS(knxt)) * (LC3_FABS(knxt))); + } + + *len = *len + 1; /* Length = 8 */ +} + +void poly2rc(LC3_FLOAT* a, LC3_FLOAT* out, LC3_INT len) +{ + LC3_INT k = 0, i = 0, len_old = 0; + LC3_FLOAT buf[9] = {0}; + + len_old = len; + + zero_float(out, len - 1); + + /* Length = 9 */ + + /* Normalize */ + for (i = 0; i < len; i++) { + a[i] = a[i] / a[0]; + } + + out[len - 1] = a[len - 1]; + + /* Process */ + for (k = len - 2; k >= 0; k--) { + levdown(a, buf, &len); + out[k] = buf[len - 1]; /* Store last value */ + + move_float(a, buf, len); + } + + /* Shift output array by one to the left to lose leading 1 */ + for (i = 0; i < len_old - 1; i++) { + out[i] = out[i + 1]; + } +} + +LC3_INT findRC_idx(const LC3_FLOAT* in1, const LC3_FLOAT* in2, LC3_FLOAT checkValue) +{ + LC3_INT i = 0, ret = 0; + + for (i = 0; i < 17; i++) { + if (checkValue <= in1[i] && checkValue > in2[i]) { + ret = i; + } + } + + return ret; +} + +void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, LC3_INT fs, LC3_INT N, LC3_INT frame_dms, LC3_INT nBits, + LC3_INT* order_out, LC3_INT* rc_idx, LC3_INT* tns_numfilters, LC3_INT* bits_out + , LC3_INT16 near_nyquist_flag +) +{ + LC3_INT i = 0, stopfreq[2] = {0}, startfreq[2] = {0}, f = 0, numfilters = 0, maxOrder = 0, bits = 0, sub = 0, + subdiv_startfreq = 0, subdiv_stopfreq = 0, j = 0, rc_idx_tmp[8] = {0}, order_tmp[8] = {0}, tmp = 0, tns = 0; + LC3_FLOAT minPGfac = 0, minPredictionGain = 0, maxPG = 0, xcorr_out[MAX_LEN] = {0}, buf_tmp[MAX_LEN] = {0}, sum = 0, + subdiv_len = 0, nSubdivisions = 0, r[9] = {0}, out_lev[9] = {0}, rc_unq[9] = {0}, error_lev = 0, predGain = 0, + alpha = 0, rc[8] = {0}, st[9] = {0}, s = 0, tmpSave = 0, tmp_fl = 0; + const LC3_INT* order; + + /* Init */ + + if (fs >= 32000 && frame_dms >= 50) { + numfilters = 2; + } else { + numfilters = 1; + } + + if (N > 40 * ((LC3_FLOAT) (frame_dms) / 10.0)) { + N = 40 * ((LC3_FLOAT) (frame_dms) / 10.0); + fs = 40000; + } + + if (numfilters == 1) { + startfreq[0] = floor(600 * N * 2 / fs) + 1; + stopfreq[0] = N; + } else { + startfreq[0] = floor(600 * N * 2 / fs) + 1; + startfreq[1] = N / 2 + 1; + stopfreq[0] = N / 2; + stopfreq[1] = N; + } + + switch (frame_dms) + { + case 25: + maxOrder = 4; + nSubdivisions = 2.0; + break; + case 50: + maxOrder = 4; + nSubdivisions = 2.0; + break; + case 100: + maxOrder = 8; + nSubdivisions = 3.0; + break; + } + + minPGfac = 0.85; + maxPG = 2; + minPredictionGain = 1.5; + + if ((frame_dms >= 50 && nBits >= 48 * ((LC3_FLOAT) frame_dms / 10.0)) || frame_dms == 25) { + maxPG = minPredictionGain; + } + + if ((frame_dms >= 50 && nBits >= 48 * ((LC3_FLOAT) frame_dms / 10.0)) || frame_dms == 25) { + order = order1_tns; + } else { + order = order2_tns; + } + + /* Processing */ + if (bw_cutoff_idx >= 3 && numfilters == 2) { + numfilters = 2; + startfreq[1] = bw_fcbin / 2 + 1; + stopfreq[0] = bw_fcbin / 2; + stopfreq[1] = bw_fcbin; + } else { + numfilters = 1; + stopfreq[0] = bw_fcbin; + } + + bits = 0; + + for (f = 0; f < numfilters; f++) { + subdiv_len = ((LC3_FLOAT)stopfreq[f] + 1.0 - (LC3_FLOAT)startfreq[f]) / nSubdivisions; + + zero_float(r, 9); + + for (sub = 1; sub <= nSubdivisions; sub++) { + subdiv_startfreq = floor(subdiv_len * (sub - 1)) + startfreq[f] - 1; + subdiv_stopfreq = floor(subdiv_len * sub) + startfreq[f] - 1; + + sum = 0; + for (i = subdiv_startfreq; i < subdiv_stopfreq; i++) { + sum += x[i] * x[i]; + } + + if (sum < LC3_EPS) + { + zero_float(r, 9); + r[0] = 1; + break; + } + + move_float(buf_tmp, &x[subdiv_startfreq], subdiv_stopfreq - subdiv_startfreq); + + xcorr(buf_tmp, xcorr_out, maxOrder, subdiv_stopfreq - subdiv_startfreq); + + j = 0; + for (i = maxOrder; i >= 0; i--) { + r[j] = r[j] + xcorr_out[i] / sum; + j++; + } + } + + for (i = 0; i <= maxOrder; i++) { + r[i] = r[i] * lagw_tns[i]; + } + + levinsonDurbin(r, out_lev, rc_unq, &error_lev, maxOrder); + + predGain = r[0] / error_lev; + + if (predGain > minPredictionGain && near_nyquist_flag == 0) { + tns = 1; + } else { + tns = 0; + } + + bits++; + + if (tns == 1) { + /* LPC weighting */ + if (predGain < maxPG) { + alpha = (maxPG - predGain) * (minPGfac - 1.0) / (maxPG - minPredictionGain) + 1.0; + + for (i = 0; i <= maxOrder; i++) { + out_lev[i] = out_lev[i] * LC3_POW(alpha, i); + } + + poly2rc(out_lev, rc_unq, maxOrder + 1); + } + + /* PARCOR Quantization */ + for (i = 0; i < maxOrder; i++) { + rc_idx_tmp[i] = findRC_idx(&quants_thr_tns[1], &quants_thr_tns[0], rc_unq[i]); + } + + /* Filter Order */ + j = 0; + for (i = 0; i < maxOrder; i++) { + rc[i] = quants_pts_tns[rc_idx_tmp[i]]; + + if (rc[i] != 0) { + order_tmp[j] = i + 1; + j++; + } + } + + order_out[f] = order_tmp[j - 1]; + // Disable TNS if order is 0: + if (order_out[f] == 0) { + tns = 0; + + // Jump to else statement + goto tns_disabled; + } + tmp = order[order_out[f] - 1]; + + /* Huffman Coding of PARCOR coefficients */ + for (i = 0; i <= order_out[f] - 1; i++) { + tmp += huff_bits_tns[i][rc_idx_tmp[i]]; + } + + bits = bits + ceil((LC3_FLOAT)tmp / 2048.0); + + j = 0; + for (i = f * 8; i <= f * 8 + order_out[f] - 1; i++) { + rc_idx[i] = rc_idx_tmp[j]; + j++; + } + } + + /* Filtering */ + if (tns == 1) { + for (i = startfreq[f]; i <= stopfreq[f]; i++) { + s = x[i - 1]; + tmpSave = s; + + for (j = 0; j < order_out[f] - 1; j++) { + tmp_fl = rc[j] * s + st[j]; + s += rc[j] * st[j]; + + st[j] = tmpSave; + tmpSave = tmp_fl; + } + + s += rc[order_out[f] - 1] * st[order_out[f] - 1]; + + st[order_out[f] - 1] = tmpSave; + x[i - 1] = s; + } + } + } +tns_disabled: + + *tns_numfilters = numfilters; + *bits_out = bits; +} diff --git a/lc3plus/tns_decoder.c b/lc3plus/tns_decoder.c new file mode 100644 index 0000000000000000000000000000000000000000..d3aeefc3a379a224273e7cc7b7be1eee545af774 --- /dev/null +++ b/lc3plus/tns_decoder.c @@ -0,0 +1,52 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#include "options.h" +#include "functions.h" + +void processTnsDecoder_fl(LC3_FLOAT* x, LC3_INT* rc_idx, LC3_INT* order, LC3_INT numfilters, LC3_INT bw_fcbin, LC3_INT N, LC3_INT fs) +{ + LC3_INT startfreq[2] = {0}, stopfreq[2] = {0}, f = 0, i = 0, j = 0, m = 0, l = 0, rc_idx_f[9] = {0}; + LC3_FLOAT rc[9] = {0}, s = 0, st[9] = {0}; + + if (numfilters == 2) { + startfreq[0] = floor(600 * N * 2 / fs) + 1; + stopfreq[0] = bw_fcbin / 2; + startfreq[1] = bw_fcbin / 2 + 1; + stopfreq[1] = bw_fcbin; + } else { + startfreq[0] = floor(600 * N * 2 / fs) + 1; + stopfreq[0] = bw_fcbin; + } + + for (f = 0; f < numfilters; f++) { + if (order[f] > 0) { + j = 0; + + for (i = f * 8; i < f * 8 + 8; i++) { + rc_idx_f[j] = rc_idx[i]; + rc[j] = quants_pts_tns[rc_idx_f[j]]; + j++; + } + + for (m = startfreq[f]; m <= stopfreq[f]; m++) { + s = x[m - 1] - rc[order[f] - 1] * st[order[f] - 1]; + + for (l = order[f] - 2; l >= 0; l--) { + s = s - rc[l] * st[l]; + st[l + 1] = rc[l] * s + st[l]; + } + + st[0] = s; + x[m - 1] = s; + } + } + } +} diff --git a/lc3plus/util.h b/lc3plus/util.h new file mode 100644 index 0000000000000000000000000000000000000000..7ef6dedef7600c79a45549dabb1c4cf4d2d37f7f --- /dev/null +++ b/lc3plus/util.h @@ -0,0 +1,222 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* Low Complexity Communication Codec Plus (LC3plus) * +* * +* Copyright licence is solely granted through ETSI Intellectual Property * +* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * +* estoppel or otherwise. * +******************************************************************************/ + + +#ifndef UTIL_H +#define UTIL_H + +#include "clib.h" +#include "math.h" + +#ifdef _MSC_VER +/* strcasecmp is not available on visual studio */ +static LC3_INT strcasecmp(const char* a, const char* b) { + return _stricmp(a,b); +} +#endif + +/* restrict is not available on visual studio */ +#ifdef _MSC_VER +#define restrict __restrict +/* inline is not recognized in visual studio 13 required by matlab r2015a in win10 */ +#define inline __inline +#endif + +/* number of elements in array */ +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +/* min max with no side effects */ +static inline LC3_INT imin(LC3_INT a, LC3_INT b) { return a < b ? a : b; } +static inline LC3_INT imax(LC3_INT a, LC3_INT b) { return a > b ? a : b; } + +/* restrict x to range [min, max] */ +static inline LC3_INT iclamp(LC3_INT min, LC3_INT x, LC3_INT max) { + return x < min ? min : x > max ? max : x; +} +static inline double fcmamp(double min, double x, double max) { + return x < min ? min : x > max ? max : x; +} +static inline LC3_FLOAT fclampf(LC3_FLOAT min, LC3_FLOAT x, LC3_FLOAT max) { + return x < min ? min : x > max ? max : x; +} + +/* x² */ +static inline LC3_FLOAT sqrf(LC3_FLOAT x) { return x * x; } + +/* convenience wrappers around memmove */ +static inline void move_float(LC3_FLOAT *dst, const LC3_FLOAT *src, LC3_INT len) { + memmove(dst, src, len * sizeof(LC3_FLOAT)); +} +static inline void move_int(LC3_INT *dst, const LC3_INT *src, LC3_INT len) { + memmove(dst, src, len * sizeof(LC3_INT)); +} + +/* convenience wrappers around memset */ +static inline void zero_float(LC3_FLOAT *x, LC3_INT len) { + memset(x, 0, len * sizeof(LC3_FLOAT)); +} +static inline void zero_int(LC3_INT *x, LC3_INT len) { + memset(x, 0, len * sizeof(LC3_INT)); +} + +/* multiply float vectors element by element, in-place */ +static inline void mult_vec(LC3_FLOAT *a, const LC3_FLOAT *b, + LC3_INT len) { + LC3_INT i = 0; + for (i = 0; i < len; i++) { + a[i] *= b[i]; + } +} + +/* multiply float vector with constant, in-place */ +static inline void mult_const(LC3_FLOAT *a, LC3_FLOAT b, LC3_INT len) { + LC3_INT i = 0; + for (i = 0; i < len; i++) { + a[i] *= b; + } +} + +/* sum of vector */ +static inline LC3_FLOAT sum_vec(const LC3_FLOAT *x, LC3_INT len) { + LC3_FLOAT sum = 0; + LC3_INT i = 0; + for (i = 0; i < len; i++) { + sum += x[i]; + } + return sum; +} + +/* complex constructor */ +static inline Complex cmplx(LC3_FLOAT r, LC3_FLOAT i) { return (Complex){r, i}; } + +/* complex a + b */ +static inline Complex cadd(Complex a, Complex b) { + return cmplx(a.r + b.r, a.i + b.i); +} + +/* complex a * b */ +static inline Complex cmul(Complex a, Complex b) { + return cmplx(a.r * b.r - a.i * b.i, a.i * b.r + a.r * b.i); +} + +/* mac operator */ +static inline LC3_FLOAT mac_loop(const LC3_FLOAT *array1, const LC3_FLOAT *array2, LC3_INT len) +{ + LC3_INT i; + LC3_FLOAT sum = 0.0; + + for (i = 0; i < len; i++) + { + sum += (*array1++) * (*array2++); + } + + return sum; +} + +/* complex eᶦˣ */ +static inline Complex cexpi(LC3_FLOAT x) { return cmplx(LC3_COS(x), LC3_SIN(x)); } + +/* complex -x */ +static inline Complex cneg(Complex x) { return cmplx(-x.r, -x.i); } + +/* convert string to number. return true on success */ +static inline bool str_to_int(const char *str, LC3_INT *value) { + char *end = NULL; + long v = str ? strtol(str, &end, 0) : 0; + *value = (LC3_INT)v; + return str && *end == 0 && v >= INT_MIN && v <= INT_MAX; +} + +/* returns true if str ends with str ends with suffix. ignoring case. str may be + * NULL */ +static inline bool str_ends_with(const char *str, const char *suffix) { + char *tmp = str ? strrchr(str, suffix[0]) : NULL; + return tmp && !strcasecmp(tmp, suffix); +} + +/* complex a - b */ +static inline Complex csub(Complex a, Complex b) { + return cmplx(a.r - b.r, a.i - b.i); +} + +static inline void move_cmplx(Complex *dst, const Complex *src, LC3_INT32 len) { + if (len > 0) { + memmove(dst, src, len * sizeof(Complex)); + assert(src[len - 1].r == dst[len - 1].r && src[len - 1].i == dst[len - 1].i); /*check that Cmplx is stored contiguously*/ + assert(src[0].r == dst[0].r && src[0].i == dst[0].i); /*check that Cmplx is stored contiguously*/ + } +} + +static inline void zero_cmplx(Complex *x, LC3_INT32 len) { + if(len > 0) { + memset(x, 0, len * sizeof(Complex)); + assert(x[0].r == 0 && x[0].i == 0 && x[len-1].r == 0 && x[len-1].i == 0); + } +} + +static inline Complex realtoc(LC3_FLOAT r) { return cmplx(r, 0); } + +/* set float vector to constant */ +static inline void set_vec(const LC3_FLOAT c, LC3_FLOAT *x, LC3_INT32 len) { + LC3_INT32 i = 0; + for (i = 0; i < len; i++) { + x[i] = c; + } +} + +/* set float vector to constant */ +static inline void set_vec_int(const LC3_INT32 c, LC3_INT32 *x, LC3_INT32 len) { + LC3_INT32 i = 0; + for (i = 0; i < len; i++) { + x[i] = c; + } +} + +static inline LC3_INT32 clz_func(LC3_INT32 inp) +{ +#if defined(__clang__) || defined(__GNUC__) + if (inp == 0) + { + return 0; + } + return __builtin_clz(inp); + +#elif defined(_WIN32) || defined(_WIN64) + LC3_INT32 leading_zero = 0; + + if (_BitScanReverse(&leading_zero, inp)) + { + return 31 - leading_zero; + } + else + return 0; + +#else + LC3_INT32 i = 0; + int64_t x = inp; + + if (inp == 0) + { + return 0; + } + + inp = (inp < 0) ? ~inp : inp; + + while (x < (int64_t)0x80000000L) + { + inp <<= 1; + i += 1; + } + + return i; +#endif +} + + +#endif diff --git a/lib_com/cnst.h b/lib_com/cnst.h index e1362b0d759ea2fc1762f11aa305f3290c3a8218..b5d414d29e9cf1b99b35ddb2c3900883fbc1ec99 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -626,6 +626,9 @@ enum #define CLDFB_NO_COL_MAX_SWITCH_BFI 10 /* CLDFB resampling - max number of CLDFB col. for switching, BFI */ #define CLDFB_OVRLP_MIN_SLOTS 3 /* CLDFB resampling - minimize processing to minimum required for transition frame ACELP->TCX/HQ */ #define INV_CLDFB_BANDWIDTH ( 1.f / 800.f ) +#ifdef SPLIT_REND_PLC +#define CLDFB_PLC_XF 2 /* Length of cross-fade into first good frame after frame loss in CLDFB cols. */ +#endif #define L_FILT_2OVER3 12 #define L_FILT_2OVER3_LP 3 diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 2dc926dfc26c3438ca36234086508137279c8fe9..909a16b514a222c27b1085d6985818fd1cb88603 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -89,6 +89,49 @@ typedef struct } IVAS_QUATERNION; +#ifdef SPLIT_REND_WITH_HEAD_ROT +typedef enum +{ + DEFAULT_AXIS, + YAW, + PITCH, + ROLL, + YAW_PITCH, + YAW_ROLL, + PITCH_ROLL +} IVAS_SPLIT_REND_ROT_AXIS; +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef SPLIT_REND_LC3PLUS +typedef enum +{ + IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE, + IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB, +} IVAS_SPLIT_REND_POSE_CORRECTION_MODE; +#endif + +#ifdef SPLIT_REND_LC3PLUS +typedef enum +{ + IVAS_SPLIT_REND_CODEC_LCLD, + IVAS_SPLIT_REND_CODEC_LC3PLUS, + IVAS_SPLIT_REND_CODEC_NONE +} IVAS_SPLIT_REND_CODEC; +#endif + +typedef struct ivas_split_rend_bits_t +{ + uint8_t *bits_buf; + int32_t buf_len; /*size of bits_buf in bytes. This field should be set by allocator of bits_buf*/ + int32_t bits_written; + int32_t bits_read; +#ifdef SPLIT_REND_LC3PLUS + IVAS_SPLIT_REND_CODEC codec; + IVAS_SPLIT_REND_POSE_CORRECTION_MODE pose_correction; +#endif +} ivas_split_rend_bits_t, IVAS_SPLIT_REND_BITS, *IVAS_SPLIT_REND_BITS_HANDLE; +#endif typedef struct { float x, y, z; @@ -111,7 +154,7 @@ typedef struct ivas_hrtfs_crend_structure *IVAS_DEC_HRTF_CREND_HANDLE; typedef struct ivas_hrtfs_fastconv_struct *IVAS_DEC_HRTF_FASTCONV_HANDLE; typedef struct ivas_hrtfs_parambin_struct *IVAS_DEC_HRTF_PARAMBIN_HANDLE; -#ifdef DEBUGGING +#if ( defined DEBUGGING ) || ( defined SPLIT_REND_WITH_HEAD_ROT ) typedef enum { IVAS_RENDER_TYPE_OVERRIDE_NONE, @@ -141,12 +184,36 @@ typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG float inputPreDelay; /* Offset in seconds from where DSR is computed in the RIR (0 = at source), float, range [0.001..10] */ } IVAS_ROOM_ACOUSTICS_CONFIG_DATA; +#ifdef SPLIT_REND_WITH_HEAD_ROT + +typedef struct _IVAS_SPLIT_REND_CONFIG +{ + int32_t splitRendBitRate; /*Bit rate for split rendering mode, if "pcm_out" is set then "splitRendBitRate" is used as a limit for MD bitrate */ + int16_t hq_mode; /*High quality 3DOF mode with additional side information. Requires more pre-renditions. */ + int16_t dof; /*flag to specify if pose correction is needed for 1, 2 or 3 degree of freedoms*/ + /*The axis can be set dynamically per frame based on a file input */ + /*possible values: + 1 - (1dof correction. By default YAW correction) + 2 - (2dof correction. By default YAW and PITCH correction) + 3 - (3dof correction. By default YAW, PITCH and ROLL correction) + */ + int16_t codec_delay_ms; /*PLACEHOLDER (currently being ignored) : look ahead delay of the codec that is used to code BIN signal output of pre-renderer*/ +#ifdef SPLIT_REND_LC3PLUS + IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; + IVAS_SPLIT_REND_CODEC codec; +#endif +} IVAS_SPLIT_REND_CONFIG_DATA; +#endif + typedef struct _IVAS_RENDER_CONFIG { -#ifdef DEBUGGING +#if ( defined DEBUGGING ) || ( defined SPLIT_REND_WITH_HEAD_ROT ) IVAS_RENDER_TYPE_OVERRIDE renderer_type_override; #endif IVAS_ROOM_ACOUSTICS_CONFIG_DATA room_acoustics; +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_CONFIG_DATA split_rend_config; +#endif float directivity[3]; } IVAS_RENDER_CONFIG_DATA, *IVAS_RENDER_CONFIG_HANDLE; diff --git a/lib_com/delay_comp.c b/lib_com/delay_comp.c index 003d9422451fb3fd2b6fda1c1ff11047a0a3d816..97b5472309bf21a0c6f97228a8d5162cda8c92fb 100644 --- a/lib_com/delay_comp.c +++ b/lib_com/delay_comp.c @@ -55,6 +55,10 @@ int32_t get_delay( const int32_t io_fs, /* i : input/output sampling frequency */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ HANDLE_CLDFB_FILTER_BANK hCldfb /* i : Handle of Cldfb analysis */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + AUDIO_CONFIG output_config /* i : decoder output config */ +#endif ) { int32_t delay = 0; @@ -98,10 +102,15 @@ int32_t get_delay( { delay = IVAS_DEC_DELAY_NS; - if ( hCldfb != NULL ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config != AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) +#endif { - /* compensate for filterbank delay */ - delay += IVAS_FB_DEC_DELAY_NS; + if ( hCldfb != NULL ) + { + /* compensate for filterbank delay */ + delay += IVAS_FB_DEC_DELAY_NS; + } } if ( ivas_format == MASA_FORMAT ) diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h old mode 100755 new mode 100644 index 60807f62cbb847157cf4d56de29a811cc1ad2c71..70e63ad65d64cdafef9d16396d36d753f18000dc --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -101,6 +101,10 @@ typedef enum AUDIO_CONFIG_HOA3, /* ambisonics, order 3 */ AUDIO_CONFIG_OBA, /* object based audio */ AUDIO_CONFIG_BINAURAL, /* binaural with HRIR */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB, /* split binaural with CLDFB coded output */ + AUDIO_CONFIG_BINAURAL_SPLIT_PCM, /* split binaural with PCM coded output */ +#endif AUDIO_CONFIG_BINAURAL_ROOM_IR, /* binaural with BRIR */ AUDIO_CONFIG_BINAURAL_ROOM_REVERB, /* binaural with HRIR + reverb */ AUDIO_CONFIG_ISM1, /* ISM1 */ @@ -113,7 +117,7 @@ typedef enum } AUDIO_CONFIG; -#ifdef DEBUGGING +#if ( defined DEBUGGING ) || ( defined SPLIT_REND_WITH_HEAD_ROT ) typedef enum { RENDER_TYPE_OVERRIDE_NONE, @@ -1492,6 +1496,18 @@ typedef enum EFAP_DMX_INTENSITY } EFAP_VTX_DMX_TYPE; +#ifdef SPLIT_REND_WITH_HEAD_ROT +typedef enum +{ + ANY_YAW, + PITCH_ONLY, + ANY_ROLL, + PRED_ONLY, + COM_GAIN_ONLY, + LR_GAIN_ONLY +} IVAS_SPLIT_REND_POSE_TYPE; +#endif + #define VBAP_NUM_SEARCH_SECTORS 4 /*----------------------------------------------------------------------------------* @@ -1503,6 +1519,67 @@ typedef enum #define BINAURAL_NTAPS 5 #define BINAURAL_NTAPS_MAX 96 +#ifdef SPLIT_REND_WITH_HEAD_ROT +#define SPLIT_REND_DECOR_ALPHA (0.25f) + +#define SPLIT_REND_MAX_YAW_ONLY_POSES (2) +#define SPLIT_REND_MAX_PITCH_ONLY_POSES (2) +#define SPLIT_REND_MAX_ROLL_ONLY_POSES (2) +#define SPLIT_REND_MAX_ONE_AXIS_MD_POSES (2) +#define MAX_EXTRAPOLATION_ANGLE (15.0f) /* this means additional 15 degrees can be extrapolated on top of MD probing poses*/ + +#ifdef SPLIT_REND_LC3PLUS +#define SPLIT_REND_MAX_DOF (3) +#define SPLIT_REND_MSPC_NPOSES_0DOF (1) +#define SPLIT_REND_MSPC_NPOSES_1DOF (3) +#define SPLIT_REND_MSPC_NPOSES_2DOF (7) +#define SPLIT_REND_MSPC_NPOSES_3DOF (8) +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef SPLIT_REND_LC3PLUS +#define MAX_HEAD_ROT_POSES (2 + SPLIT_REND_MAX_YAW_ONLY_POSES + SPLIT_REND_MAX_PITCH_ONLY_POSES + SPLIT_REND_MAX_ROLL_ONLY_POSES) /* TODO tmu : revisit for harmonization */ +#else +#define MAX_HEAD_ROT_POSES (1 + SPLIT_REND_MAX_YAW_ONLY_POSES + SPLIT_REND_MAX_PITCH_ONLY_POSES + SPLIT_REND_MAX_ROLL_ONLY_POSES) +#endif +#else +#define MAX_HEAD_ROT_POSES (1 + SPLIT_REND_MAX_YAW_ONLY_POSES) +#endif +#define MAX_SPLIT_REND_MD_BANDS (20) +#define MAX_SPLIT_MD_SUBFRAMES (1) +#define COMPLEX_MD_BAND_THRESH (MAX_SPLIT_REND_MD_BANDS) +#define COMPLEX_MD_BAND_THRESH_LOW (5) + + +#define IVAS_SPLIT_REND_NUM_QUANT_STRATS (3) +#define IVAS_SPLIT_REND_PRED_QUANT_PNTS ( 31 ) +#define IVAS_SPLIT_REND_D_QUANT_PNTS ( 15 ) +#define IVAS_SPLIT_REND_PRED_MIN_VAL ( -1.0f ) +#define IVAS_SPLIT_REND_PRED_MAX_VAL ( 1.0f ) +#ifdef SPLIT_REND_WITH_HEAD_ROT +#define IVAS_SPLIT_REND_PITCH_G_MIN_VAL (0.5f) +#define IVAS_SPLIT_REND_PITCH_G_MAX_VAL (1.5f) +#define IVAS_SPLIT_REND_PITCH_G_QUANT_PNTS ( IVAS_SPLIT_REND_D_QUANT_PNTS ) +#define IVAS_SPLIT_REND_D_MIN_VAL ( 0.0f ) +#else +#define IVAS_SPLIT_REND_D_MIN_VAL ( 0.0f ) +#endif +#define IVAS_SPLIT_REND_D_MAX_VAL ( 1.0f ) + +#define IVAS_SPLIT_REND_PRED_Q_STEP (( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL ) / ( IVAS_SPLIT_REND_PRED_QUANT_PNTS - 1 )) +#define IVAS_SPLIT_REND_PRED_1BYQ_STEP (( IVAS_SPLIT_REND_PRED_QUANT_PNTS - 1 )/( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL )) +#define IVAS_SPLIT_REND_D_Q_STEP (( IVAS_SPLIT_REND_D_MAX_VAL - IVAS_SPLIT_REND_D_MIN_VAL ) / ( IVAS_SPLIT_REND_D_QUANT_PNTS - 1 )) +#define IVAS_SPLIT_REND_D_1BYQ_STEP (( IVAS_SPLIT_REND_D_QUANT_PNTS - 1 )/( IVAS_SPLIT_REND_D_MAX_VAL - IVAS_SPLIT_REND_D_MIN_VAL )) +#define IVAS_SPLIT_REND_PITCH_G_Q_STEP (( IVAS_SPLIT_REND_PITCH_G_MAX_VAL - IVAS_SPLIT_REND_PITCH_G_MIN_VAL ) / ( IVAS_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 )) +#define IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP (( IVAS_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 )/( IVAS_SPLIT_REND_PITCH_G_MAX_VAL - IVAS_SPLIT_REND_PITCH_G_MIN_VAL )) + +#define IVAS_SPLIT_REND_MAX_NUM_BYTES (4000) +#define IVAS_SPLIT_REND_HEAD_POSE_BITS (9) +#define IVAS_SPLIT_REND_DOF_BITS (2) +#define IVAS_SPLIT_REND_HQ_MODE_BITS (1) +#define IVAS_SPLIT_REND_ROT_AXIS_BITS (3) +#endif + #define HRTF_SH_ORDER 3 #define HRTF_SH_CHANNELS 16 #define HRTF_LS_CHANNELS 15 @@ -1727,6 +1804,29 @@ typedef enum #define SPAR_DIRAC_DTX_BANDS ( SPAR_DTX_BANDS + DIRAC_DTX_BANDS ) #define CLDFB_PAR_WEIGHT_START_BAND 7 +/*----------------------------------------------------------------------------------* + * Split rendering bitrate constants + *----------------------------------------------------------------------------------*/ + +#ifndef SPLIT_REND_LC3PLUS +#define SIZE_SPLIT_REND_BRATE_TBL (4) +#endif +#define SPLIT_REND_256k 256000 +#ifdef SPLIT_REND_LC3PLUS +#define SPLIT_REND_320k 320000 +#endif +#define SPLIT_REND_384k 384000 +#define SPLIT_REND_512k 512000 +#define SPLIT_REND_768k 768000 +#define SPLIT_REND_MAX_BRATE SPLIT_REND_768k +#ifdef SPLIT_REND_LC3PLUS_HBR_DBG +#define SPLIT_REND_LC3PLUS_HBR 128000 /* bitrate per LC3plus core */ +#endif + +#ifdef SPLIT_REND_CLDFB_HUFF_SAN_FIX +#define SPLIT_REND_ADDITIONAL_BYTES_TO_READ ( 1 ) +#endif + #define QUANT_STRAT_0 0 #define QUANT_STRAT_2 2 diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index c86d94712598e3cd155dc04cc561140b0f178f9f..49e907fe3d355b73260f6421734f8dc665a04b0f 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -135,6 +135,10 @@ typedef enum IVAS_ERR_INVALID_INPUT_ID, IVAS_ERR_WRONG_NUM_CHANNELS, IVAS_ERR_INVALID_BUFFER_SIZE, +#ifdef SPLIT_REND_LC3PLUS + IVAS_ERR_LC3PLUS_INVALID_BITRATE, + IVAS_ERR_INVALID_SPLIT_REND_CONFIG, +#endif /*----------------------------------------* * unknown error * @@ -233,6 +237,12 @@ static inline const char *ivas_error_to_string( ivas_error error_code ) return "Wrong mode"; case IVAS_ERR_HEAD_ROTATION_NOT_SUPPORTED: return "Head rotation not supported"; +#ifdef SPLIT_REND_LC3PLUS + case IVAS_ERR_LC3PLUS_INVALID_BITRATE: + return "Specified split rendering bit rate is not supported"; + case IVAS_ERR_INVALID_SPLIT_REND_CONFIG: + return "Specified split rendering configuration is invalid"; +#endif case IVAS_ERR_EXT_ORIENTATION_NOT_SUPPORTED: return "External orientation not supported"; case IVAS_ERR_INVALID_HRTF: diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 9bc253776da52a8e80ea43224cf48643136b72d4..4d91ff2a9818050b2a5d6b465c25abe1120b61c6 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -308,6 +308,10 @@ void stereo_dmx_evs_close_encoder( ivas_error ivas_dec( Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ int16_t *data /* o : output synthesis signal */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits +#endif ); ivas_error ivas_dec_setup( @@ -4947,7 +4951,15 @@ void ivas_quantise_real_values( float *quant, const int16_t dim ); - +#ifndef FIX_SPLIT_REND_MERGE +ivas_error ivas_deindex_real_index( + const int16_t *index, + const int16_t q_levels, + const float min_value, + const float max_value, + float *quant, + const int16_t num_ch_dim2 ); +#endif void ivas_spar_get_uniform_quant_strat( ivas_spar_md_com_cfg *pSpar_md_com_cfg, const int16_t table_idx @@ -5159,14 +5171,26 @@ void ivas_binaural_cldfb_sf( #endif void ivas_binRenderer( - BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */ + BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HEAD_TRACK_DATA_HANDLE hPostRendHeadTrackData, +#endif + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle */ int16_t subframe_idx, /* i : subframe index */ - const int16_t numTimeSlots, /* i : number of time slots to process */ - float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ - float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] /* i : LS signals */ + const int16_t numTimeSlots, /* i: : number of time slots to process */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + float Cldfb_RealBuffer_Binaural[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */ + float Cldfb_ImagBuffer_Binaural[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */ +#else + float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ + float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ +#endif + float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ + float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] /* i : LS signals */ ); void ivas_binaural_add_LFE( diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index 6679a70a0e88a6c6e807d3add4159d62a47a04c9..ea2f059b25ea298f5099725334e754f27361e033 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -1157,7 +1157,6 @@ void v_sort_ind( return; } - /*-------------------------------------------------------------------* * is_IVAS_bitrate() * diff --git a/lib_com/options.h b/lib_com/options.h index e4d3a06b589e5bc8982f4c9a738860aa0751817b..247c850a0ea0dbf95dcef577777a0040f7e9a7d6 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -140,6 +140,10 @@ /*#define FIX_I4_OL_PITCH*/ /* fix open-loop pitch used for EVS core switching */ +#define TD_TDREND_FIX_NULLPTR_ACCESS /* FhG: avoid nullptr access in ivas_rend_TDObjRendOpen */ +#define TD_REND_FIX_DIV_BY_ZERO /* FhG: avoid division by zero in sincResample fn */ +#define RENAME_GWLPR /* FhG: Rename clashing symbol */ + #define FIX_563_PARAMMC_LIMITER /* FhG: issue 563: fix ILD limiter when coming from silence w/o transient set */ #define FIX_560_VAD_FLAG /* Eri: Issue 560 - VAD flag issue for unified stereo */ #define FIX_549_DMX_GAIN /* FhG: issue 549: ParamISM output too quiet */ @@ -162,6 +166,53 @@ #define FIX_580_PARAMMC_ENER_BURSTS /* FhG: issue 580: energy bursts due to ILD holding when energy relations change too much */ +#define SPLIT_REND_WITH_HEAD_ROT +#ifdef SPLIT_REND_WITH_HEAD_ROT + +#define FIX_SPLIT_REND_MERGE /* Resolving the compilation warnings after splitrenderer main updation */ + + +//#define SPLIT_REND_WITH_HEAD_ROT_DEBUG // only for debugging purposes +//#define DBG_WAV_WRITER + +#define SPLIT_REND_CLDFB_ISM + +#define SPLIT_SIN_SCALING_AND_EXTRAPOL_LIMIT + +#define SPLIT_REND_ZERO_OUT_YAW_D +//#define SPLIT_REND_REAL_ONLY_ROLL + +//#define SPIT_ABS_SCALING_INTERP + +//#define USE_DOLBY_HRTFS_WITH_LIB_REND_HOA3 + +//#define SPLIT_MD_CODING_DEBUG +#define SPLIT_REND_IVAS_DEC_HT_TR + +/*CLDFB CODEC SWITCHES -- START*/ +#define ENABLE_MS_PRED +#define BUG_FIX_03_15_23_INIT_GROUPING +#define FORCE_GROUPS_OF_2 +#define USE_BIT_COUNT_MERGE_COST +#define OPTIMIZE_DPCM_QUANT +#define SPLIT_REND_PLC +/*CLDFB CODEC SWITCHES -- END*/ + +#define REND_STATIC_MEM_OPT +#define EUALER2QUAT_FIX +#define SBA_CREND_ROT_OPT + +#define ROM_TO_RAM /*switch to convert CQMF decoder tables to RAM*/ +#define SPLIT_REND_CLANG_SAN_FIX +#define SPLIT_REND_CLDFB_HUFF_SAN_FIX +#define SPLIT_REND_STACK_OPT + +#define SPLIT_REND_LC3PLUS /* FhG: split rendering using LC3plus codec */ +#define SPLIT_REND_LC3PLUS_MC /* FhG: split rendering using LC3plus codec for Multichannel content */ +#define FIX_SPLIT_REND_OPEN_ERROR_HANDLING /* adds missing error handling around ivas_split_renderer_open calls */ +// #define SPLIT_REND_LC3PLUS_HBR_DBG /* Override bitrate per LC3 core */ +#endif + /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_com/prot.h b/lib_com/prot.h index 592d0253d3c96bd051a055a394a9f7b23beb6c3b..5625b6e0643eae1c67bf82344420703b68727af1 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -726,6 +726,10 @@ int32_t get_delay( const int32_t io_fs, /* i : input/output sampling frequency */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ HANDLE_CLDFB_FILTER_BANK hCldfb /* i : Handle of Cldfb analysis */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + AUDIO_CONFIG output_config /* i : decoder output config */ +#endif ); void decision_matrix_enc( diff --git a/lib_debug/debug.c b/lib_debug/debug.c index ce10231876d27e76b141333f2fa70423abb4430e..26fe37acbf0e83146922f2055141923db3b61d69 100644 --- a/lib_debug/debug.c +++ b/lib_debug/debug.c @@ -35,6 +35,7 @@ #include #include #include +#include #include "options.h" #ifdef DEBUGGING #include "debug.h" @@ -53,6 +54,9 @@ #include #else #endif +#ifdef DBG_WAV_WRITER +#include "tinywaveout_c.h" +#endif #include "wmc_auto.h" @@ -89,12 +93,19 @@ int16_t debug_level = 0; static FILE *in_fileptr[N_FILEPTR]; static FILE *out_fileptr[N_FILEPTR]; - +#ifdef DBG_WAV_WRITER +static WAVEFILEOUT *out_wavfileptr[N_FILEPTR]; +#endif static char *in_filename[N_FILEPTR]; static char *out_filename[N_FILEPTR]; - +#ifdef DBG_WAV_WRITER +static char *out_wavfilename[N_FILEPTR]; +#endif static int16_t in_count = 0; static int16_t out_count = 0; +#ifdef DBG_WAV_WRITER +static int16_t out_wav_count = 0; +#endif static int16_t flag_count = 0; static char *flag_name[N_DBGFLAG]; @@ -391,7 +402,13 @@ void dbgclose() fclose( out_fileptr[i] ); free( out_filename[i] ); } - +#ifdef DBG_WAV_WRITER + for ( i = 0; i < out_wav_count; i++ ) + { + CloseWav( out_wavfileptr[i] ); + free( out_wavfilename[i] ); + } +#endif for ( i = 0; i < snr_count; i++ ) { free( snr_name[i] ); @@ -847,4 +864,114 @@ int16_t make_dirs( const char *const pathname ) return 0; } +#ifdef DBG_WAV_WRITER +int16_t dbgwrite_wav( + const float *buffer[], /* i : Write buffer */ + const int16_t count_per_ch, /* i : Number of elements */ + const char *const filename, + int32_t fs, + int16_t num_chs ) +{ + int16_t index, i; + int16_t *tmp_buf; + + index = lookup( filename, (const char *const *) out_wavfilename, out_wav_count ); + + if ( index == -1 ) + { + if ( make_dirs( filename ) != 0 ) + { + fprintf( stderr, "dbgwrite: Could not create directory structure for %s. Exiting..\n", filename ); + exit( -1 ); + } + + index = out_wav_count; + out_wavfileptr[index] = CreateWav( (const char *) filename, fs, num_chs, 16 /* const uint32_t writeWaveExt */ ); + out_wavfilename[index] = malloc( sizeof( char ) * ( strlen( filename ) + 1 ) ); + strcpy( out_wavfilename[index], filename ); + out_wav_count++; + } + + if ( out_wavfileptr[index] != NULL ) + { + int16_t j, k; + float tmp; + tmp_buf = (int16_t *) calloc( count_per_ch * num_chs, sizeof( int16_t ) ); + k = 0; + for ( j = 0; j < count_per_ch; j++ ) + { + for ( i = 0; i < num_chs; i++, k++ ) + { + tmp = roundf( buffer[i][j] ); + tmp_buf[k] = ( tmp > MAX16B_FLT ) ? MAX16B : ( tmp < MIN16B_FLT ) ? MIN16B + : (short) tmp; + } + } + WriteWavShort( out_wavfileptr[index], tmp_buf, count_per_ch * num_chs ); + free( tmp_buf ); + } + else + { + fprintf( stderr, "dbgwrite_wav: Could not write to file: %s. Exiting..\n", filename ); + exit( -1 ); + } + + return 0; +} + + +int16_t dbgwrite_txt( + const float *buffer, /* i : Write buffer */ + const int16_t count, /* i : Number of elements */ + const char *const filename, + const char *const msg_opt ) +{ + int16_t index, i; + + index = lookup( filename, (const char *const *) out_filename, out_count ); + + if ( index == -1 ) + { + if ( make_dirs( filename ) != 0 ) + { + fprintf( stderr, "dbgwrite: Could not create directory structure for %s. Exiting..\n", filename ); + exit( -1 ); + } + + index = out_count; + out_fileptr[index] = fopen( filename, "w" ); + out_filename[index] = malloc( sizeof( char ) * ( strlen( filename ) + 1 ) ); + strcpy( out_filename[index], filename ); + out_count++; + } + + if ( out_fileptr[index] != NULL ) + { + if ( buffer != NULL ) + { + if ( msg_opt == NULL ) + { + for ( i = 0; i < count; i++ ) + { + fprintf( out_fileptr[index], "%f\n", buffer[i] ); + } + } + else + { + for ( i = 0; i < count; i++ ) + { + fprintf( out_fileptr[index], "%s %f\n", msg_opt, buffer[i] ); + } + } + } + } + else + { + fprintf( stderr, "dbgwrite_txt: Could not write to file: %s. Exiting..\n", filename ); + exit( -1 ); + } + + return 0; +} +#endif #endif /* DEBUGGING */ diff --git a/lib_debug/debug.h b/lib_debug/debug.h index 3d59cb00a0555a73c094ba80aa34de7fd9013710..5b7e45585848aa58bb7fbba772d95688ac64dd78 100644 --- a/lib_debug/debug.h +++ b/lib_debug/debug.h @@ -97,7 +97,19 @@ int16_t dbgwrite( const char *const filename #endif ); - +#ifdef DBG_WAV_WRITER +int16_t dbgwrite_wav( + const float *buffer[], /* i : Write buffer */ + const int16_t count_per_ch, /* i : Number of elements */ + const char *const filename, + int32_t fs, + int16_t num_chs ); +int16_t dbgwrite_txt( + const float *buffer, /* i : Write buffer */ + const int16_t count, /* i : Number of elements */ + const char *const filename, + const char *const msg_opt ); +#endif void dbgwrite_mat_repeat( float *buffer, /* i : write buffer */ int16_t nRow, /* i : matrix size (rows) */ diff --git a/lib_dec/FEC_HQ_phase_ecu.c b/lib_dec/FEC_HQ_phase_ecu.c index 96974b9f8e7d1b96d9a759ecb2c815222193dafc..e4fddda6d2b91795e68cd9bab7aa4418372aee9c 100644 --- a/lib_dec/FEC_HQ_phase_ecu.c +++ b/lib_dec/FEC_HQ_phase_ecu.c @@ -1079,7 +1079,11 @@ static void subst_spec( } i++; im_ind--; +#ifdef RENAME_GWLPR + if ( i >= ivas_gwlpr[k + 1] ) +#else if ( i >= gwlpr[k + 1] ) +#endif { k++; } @@ -1191,7 +1195,11 @@ static void subst_spec( i++; im_ind--; +#ifdef RENAME_GWLPR + if ( i >= ivas_gwlpr[k + 1] ) +#else if ( i >= gwlpr[k + 1] ) +#endif { k++; } @@ -1246,7 +1254,11 @@ static void subst_spec( } i++; +#ifdef RENAME_GWLPR + if ( i >= ivas_gwlpr[k + 1] ) +#else if ( i >= gwlpr[k + 1] ) +#endif { k++; } diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 5bd09236e0e40471c499b7d55495a096578e0c4f..c29d8a685802b9c23cedca0bfcb38e3b1d648011 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -42,6 +42,10 @@ #include "ivas_rom_dec.h" #include "ivas_rom_com.h" #include "ivas_rom_binauralRenderer.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "ivas_rom_dec.h" +#include "lib_rend.h" +#endif #ifdef DEBUGGING #include "debug.h" #endif @@ -61,6 +65,10 @@ static void ivas_binRenderer_filterModule( float CLDFB_imag[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : imag part of LS signals */ const int16_t numTimeSlots, /* i : number of time slots to process */ BINAURAL_RENDERER_HANDLE hBinRenderer /* i/o: fastconv binaural renderer handle */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + int16_t pos_idx +#endif ) { int16_t bandIdx, k, chIdx, tapIdx; @@ -71,8 +79,13 @@ static void ivas_binRenderer_filterModule( { for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + filterStatesLeftRealPtr = (float *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftReal[pos_idx][bandIdx][chIdx][0] ); + filterStatesLeftImagPtr = (float *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftImag[pos_idx][bandIdx][chIdx][0] ); +#else filterStatesLeftRealPtr = (float *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx][0] ); filterStatesLeftImagPtr = (float *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx][0] ); +#endif filterTapsLeftRealPtr = hBinRenderer->hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx]; filterTapsLeftImagPtr = hBinRenderer->hBinRenConvModule->filterTapsLeftImag[bandIdx][chIdx]; @@ -115,7 +128,6 @@ static void ivas_binRenderer_filterModule( return; } - /*------------------------------------------------------------------------- * ivas_binRenderer_convModuleOpen() * @@ -127,10 +139,19 @@ static ivas_error ivas_binRenderer_convModuleOpen( const int16_t renderer_type, const int16_t isLoudspeaker, const AUDIO_CONFIG input_config, - const HRTFS_FASTCONV_HANDLE hHrtf ) + const HRTFS_FASTCONV_HANDLE hHrtf +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + const int16_t num_poses +#endif +) { int16_t bandIdx, chIdx; BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; +#endif + /*-----------------------------------------------------------------* * prepare library opening @@ -233,7 +254,56 @@ static ivas_error ivas_binRenderer_convModuleOpen( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( hBinRenConvModule->filterStatesLeftReal = (float ****) malloc( num_poses * sizeof( float *** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + if ( ( hBinRenConvModule->filterStatesLeftImag = (float ****) malloc( num_poses * sizeof( float *** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + if ( ( hBinRenConvModule->filterStatesLeftReal[pos_idx] = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + if ( ( hBinRenConvModule->filterStatesLeftImag[pos_idx] = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) + { + if ( ( hBinRenConvModule->filterStatesLeftReal[pos_idx][bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + if ( ( hBinRenConvModule->filterStatesLeftImag[pos_idx][bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) + { + if ( ( hBinRenConvModule->filterStatesLeftReal[pos_idx][bandIdx][chIdx] = (float *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + if ( ( hBinRenConvModule->filterStatesLeftImag[pos_idx][bandIdx][chIdx] = (float *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + } + } + } +#else if ( ( hBinRenConvModule->filterStatesLeftReal = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); @@ -269,8 +339,10 @@ static ivas_error ivas_binRenderer_convModuleOpen( } } } +#endif /* set memories */ + for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) { for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) @@ -309,10 +381,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( if ( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { - /* set the memories to zero */ - set_zero( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] ); - set_zero( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] ); - if ( isLoudspeaker ) { hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx] = hHrtf->leftBRIRReal[bandIdx][tmp]; @@ -330,10 +398,6 @@ static ivas_error ivas_binRenderer_convModuleOpen( } else { - /* set the memories to zero */ - set_zero( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx], hBinRenConvModule->numTaps ); - set_zero( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx], hBinRenConvModule->numTaps ); - if ( isLoudspeaker ) { hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx] = hHrtf->leftHRIRReal[bandIdx][tmp]; @@ -376,6 +440,31 @@ static ivas_error ivas_binRenderer_convModuleOpen( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) + { + for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) + { + /* set the memories to zero */ + set_zero( hBinRenConvModule->filterStatesLeftReal[pos_idx][bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] ); + set_zero( hBinRenConvModule->filterStatesLeftImag[pos_idx][bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] ); + } + } + } +#else + for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) + { + for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) + { + /* set the memories to zero */ + set_zero( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] ); + set_zero( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] ); + } + } +#endif + hBinRenderer->hBinRenConvModule = hBinRenConvModule; return IVAS_ERR_OK; @@ -580,6 +669,92 @@ static void ivas_binaural_obtain_DMX( return; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*------------------------------------------------------------------------- + * ivas_rend_openCldfbRend() + * + * Allocate and initialize CLDFB fast conv renderer handle + *------------------------------------------------------------------------*/ + +ivas_error ivas_rend_openCldfbRend( + CLDFB_REND_WRAPPER *pCldfbRend, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int32_t output_Fs ) +{ + BINAURAL_RENDERER_HANDLE hBinRenderer; + int16_t convBand; + ivas_error error; + AUDIO_CONFIG in_config, out_config; + + error = IVAS_ERR_OK; + + /*-----------------------------------------------------------------* + * prepare library opening + *-----------------------------------------------------------------*/ + + if ( ( hBinRenderer = (BINAURAL_RENDERER_HANDLE) malloc( sizeof( BINAURAL_RENDERER ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Renderer\n" ) ); + } + + if ( ( hBinRenderer->hInputSetup = (IVAS_OUTPUT_SETUP_HANDLE) malloc( sizeof( IVAS_OUTPUT_SETUP ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for output setup Binaural Renderer\n" ) ); + } + + hBinRenderer->rotInCldfb = 1; + hBinRenderer->ivas_format = SBA_FORMAT; + + hBinRenderer->max_band = (int16_t) ( ( BINAURAL_MAXBANDS * output_Fs ) / 48000 ); + convBand = hBinRenderer->max_band; + + hBinRenderer->timeSlots = MAX_PARAM_SPATIAL_SUBFRAMES; /* Corresponds to 5 msec sound to motion latency */ + in_config = getIvasAudioConfigFromRendAudioConfig( inConfig ); + out_config = getIvasAudioConfigFromRendAudioConfig( outConfig ); + + if ( convBand > BINAURAL_CONVBANDS ) + { + hBinRenderer->conv_band = BINAURAL_CONVBANDS; + } + else + { + hBinRenderer->conv_band = convBand; + } + hBinRenderer->hInputSetup->is_loudspeaker_setup = 0; + getAudioConfigNumChannels( inConfig, &hBinRenderer->hInputSetup->nchan_out_woLFE ); + + if ( ( out_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) || ( out_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + hBinRenderer->numPoses = pMultiBinPoseData->num_poses + 1; +#else + hBinRenderer->numPoses = pMultiBinPoseData->num_poses; +#endif + } + else + { + hBinRenderer->numPoses = 1; + } + /* Load HRTF tables */ + ivas_binaural_hrtf_open( &pCldfbRend->hHrtfFastConv ); + + /* Allocate memories and buffers needed for convolutional module */ + if ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, RENDERER_BINAURAL_FASTCONV, hBinRenderer->hInputSetup->is_loudspeaker_setup, in_config, + pCldfbRend->hHrtfFastConv, hBinRenderer->numPoses ) ) != IVAS_ERR_OK ) + { + return error; + } + pCldfbRend->binaural_latency_ns = (int32_t) ( FASTCONV_HOA3_latency_s * 1000000000.f ); + hBinRenderer->hReverb = NULL; + hBinRenderer->hEFAPdata = NULL; + + pCldfbRend->hCldfbRend = hBinRenderer; + + return error; +} +#endif /*------------------------------------------------------------------------- * ivas_binRenderer_open() @@ -615,6 +790,22 @@ ivas_error ivas_binRenderer_open( hBinRenderer->rotInCldfb = 1; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) || + ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + hBinRenderer->numPoses = st_ivas->splitBinRend.splitrend.multiBinPoseData.num_poses + 1; +#else + hBinRenderer->numPoses = st_ivas->splitBinRend.splitrend.multiBinPoseData.num_poses; +#endif + } + else + { + hBinRenderer->numPoses = 1; + } +#endif + /* Declare some common variables needed for renderer */ /* Which format used for binaural rendering (needed for late reverb) ? MC or SBA */ if ( st_ivas->hIntSetup.is_loudspeaker_setup ) @@ -659,7 +850,12 @@ ivas_error ivas_binRenderer_open( st_ivas->renderer_type, 1, AUDIO_CONFIG_7_1_4, - st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK ) + st_ivas->hHrtfFastConv +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + hBinRenderer->numPoses +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -684,7 +880,12 @@ ivas_error ivas_binRenderer_open( st_ivas->renderer_type, st_ivas->hIntSetup.is_loudspeaker_setup, st_ivas->hIntSetup.output_config, - st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK ) + st_ivas->hHrtfFastConv +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + hBinRenderer->numPoses +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -790,9 +991,16 @@ ivas_error ivas_binRenderer_open( static void ivas_binRenderer_convModuleClose( BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: fastconv binaural renderer handle */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + int16_t num_poses +#endif ) { int16_t bandIdx, chIdx; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t posIdx; +#endif BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule; hBinRenConvModule = ( *hBinRenderer )->hBinRenConvModule; @@ -829,7 +1037,39 @@ static void ivas_binRenderer_convModuleClose( free( hBinRenConvModule->filterTapsRightImag ); hBinRenConvModule->filterTapsRightImag = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( posIdx = 0; posIdx < num_poses; posIdx++ ) + { + for ( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ ) + { + for ( chIdx = 0; chIdx < ( *hBinRenderer )->nInChannels; chIdx++ ) + { + free( hBinRenConvModule->filterStatesLeftReal[posIdx][bandIdx][chIdx] ); + hBinRenConvModule->filterStatesLeftReal[posIdx][bandIdx][chIdx] = NULL; + + free( hBinRenConvModule->filterStatesLeftImag[posIdx][bandIdx][chIdx] ); + hBinRenConvModule->filterStatesLeftImag[posIdx][bandIdx][chIdx] = NULL; + } + + free( hBinRenConvModule->filterStatesLeftReal[posIdx][bandIdx] ); + hBinRenConvModule->filterStatesLeftReal[posIdx][bandIdx] = NULL; + + free( hBinRenConvModule->filterStatesLeftImag[posIdx][bandIdx] ); + hBinRenConvModule->filterStatesLeftImag[posIdx][bandIdx] = NULL; + } + + free( hBinRenConvModule->filterStatesLeftReal[posIdx] ); + hBinRenConvModule->filterStatesLeftReal[posIdx] = NULL; + + free( hBinRenConvModule->filterStatesLeftImag[posIdx] ); + hBinRenConvModule->filterStatesLeftImag[posIdx] = NULL; + } + free( hBinRenConvModule->filterStatesLeftReal ); + hBinRenConvModule->filterStatesLeftReal = NULL; + free( hBinRenConvModule->filterStatesLeftImag ); + hBinRenConvModule->filterStatesLeftImag = NULL; +#else for ( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ ) { for ( chIdx = 0; chIdx < ( *hBinRenderer )->nInChannels; chIdx++ ) @@ -853,7 +1093,7 @@ static void ivas_binRenderer_convModuleClose( free( hBinRenConvModule->filterStatesLeftImag ); hBinRenConvModule->filterStatesLeftImag = NULL; - +#endif free( ( *hBinRenderer )->hBinRenConvModule ); ( *hBinRenderer )->hBinRenConvModule = NULL; @@ -861,6 +1101,25 @@ static void ivas_binRenderer_convModuleClose( return; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*------------------------------------------------------------------------- + * ivas_rend_openCldfbRend() + * + * Close CLDFB based fastconv binaural renderer memories + *------------------------------------------------------------------------*/ +void ivas_rend_closeCldfbRend( CLDFB_REND_WRAPPER *pCldfbRend ) +{ + if ( pCldfbRend->hCldfbRend->hInputSetup != NULL ) + { + free( pCldfbRend->hCldfbRend->hInputSetup ); + pCldfbRend->hCldfbRend->hInputSetup = NULL; + } + ivas_binRenderer_close( &pCldfbRend->hCldfbRend ); + + ivas_HRTF_fastconv_binary_close( &pCldfbRend->hHrtfFastConv ); + return; +} +#endif /*------------------------------------------------------------------------- * ivas_binRenderer_close() @@ -879,7 +1138,12 @@ void ivas_binRenderer_close( if ( ( *hBinRenderer )->hBinRenConvModule != NULL ) { - ivas_binRenderer_convModuleClose( hBinRenderer ); + ivas_binRenderer_convModuleClose( hBinRenderer +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + ( *hBinRenderer )->numPoses +#endif + ); } if ( ( *hBinRenderer )->hReverb != NULL ) @@ -956,8 +1220,13 @@ void ivas_binaural_cldfb( { float Cldfb_RealBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + float Cldfb_RealBuffer_Binaural[1][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[1][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#else float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#endif int16_t slot_idx, subframeIdx, index_slot, idx_in, idx_lfe, maxBand, ch; /* Implement a 5 msec loops */ @@ -994,7 +1263,18 @@ void ivas_binaural_cldfb( } /* Implement binaural rendering */ - ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hCombinedOrientationData, subframeIdx, JBM_CLDFB_SLOTS_IN_SUBFRAME, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); + ivas_binRenderer( st_ivas->hBinRenderer, +#ifdef SPLIT_REND_WITH_HEAD_ROT + &st_ivas->splitBinRend.splitrend.multiBinPoseData, +#endif + st_ivas->hCombinedOrientationData, + subframeIdx, JBM_CLDFB_SLOTS_IN_SUBFRAME, +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + NULL, +#endif + Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, + Cldfb_RealBuffer, + Cldfb_ImagBuffer ); /* Implement CLDFB synthesis */ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) @@ -1006,8 +1286,13 @@ void ivas_binaural_cldfb( for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[0][ch][slot_idx]; + ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[0][ch][slot_idx]; +#else RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[ch][slot_idx]; ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[ch][slot_idx]; +#endif } cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * maxBand] ), maxBand * MAX_PARAM_SPATIAL_SUBFRAMES, st_ivas->cldfbSynDec[ch] ); @@ -1032,8 +1317,13 @@ void ivas_binaural_cldfb_sf( { float Cldfb_RealBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#ifdef FIX_SPLIT_REND_MERGE + float Cldfb_RealBuffer_Binaural[1][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[1][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#else float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#endif int16_t slot_idx, subframeIdx, index_slot, idx_in, idx_lfe, maxBand, ch; int16_t slot_size, slots_to_render, first_sf, last_sf; int16_t slot_index_start, slot_index_start_cldfb; @@ -1086,7 +1376,11 @@ void ivas_binaural_cldfb_sf( } /* Implement binaural rendering */ - ivas_binRenderer( st_ivas->hBinRenderer, st_ivas->hCombinedOrientationData, subframeIdx, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); + ivas_binRenderer( st_ivas->hBinRenderer, +#ifdef SPLIT_REND_WITH_HEAD_ROT + &st_ivas->splitBinRend.splitrend.multiBinPoseData, +#endif + st_ivas->hCombinedOrientationData, subframeIdx, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); /* Implement CLDFB synthesis */ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) @@ -1096,8 +1390,13 @@ void ivas_binaural_cldfb_sf( for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; slot_idx++ ) { +#ifdef FIX_SPLIT_REND_MERGE + RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[0][ch][slot_idx]; + ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[0][ch][slot_idx]; +#else RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[ch][slot_idx]; ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[ch][slot_idx]; +#endif } cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][slot_index_start_cldfb * maxBand] ), maxBand * st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], st_ivas->cldfbSynDec[ch] ); @@ -1112,7 +1411,6 @@ void ivas_binaural_cldfb_sf( } #endif - /*------------------------------------------------------------------------- * ivas_binRenderer() * @@ -1120,22 +1418,52 @@ void ivas_binaural_cldfb_sf( *-------------------------------------------------------------------------*/ void ivas_binRenderer( - BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/ - int16_t subframe_idx, /* i : subframe index */ - const int16_t numTimeSlots, /* i : number of time slots to render */ - float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ - float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] /* i : LS signals */ + BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, +#endif + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle */ + int16_t subframe_idx, /* i : subframe index */ + const int16_t numTimeSlots, +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HEAD_TRACK_DATA_HANDLE hPostRendHeadTrackData, +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + float Cldfb_RealBuffer_Binaural[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */ + float Cldfb_ImagBuffer_Binaural[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */ +#else + float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ + float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ +#endif + float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ + float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] /* i : LS signals */ ) { int16_t chIdx, k; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx, num_poses; +#endif push_wmops( "fastconv_binaural_rendering" ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + num_poses = hBinRenderer->numPoses; +#endif /* Compute Convolution */ /* memory reset for the binaural output */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) + { + for ( k = 0; k < numTimeSlots; k++ ) + { + set_zero( Cldfb_RealBuffer_Binaural[pos_idx][chIdx][k], CLDFB_NO_CHANNELS_MAX ); + set_zero( Cldfb_ImagBuffer_Binaural[pos_idx][chIdx][k], CLDFB_NO_CHANNELS_MAX ); + } + } + } +#else for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) { for ( k = 0; k < numTimeSlots; k++ ) @@ -1144,6 +1472,7 @@ void ivas_binRenderer( set_zero( Cldfb_ImagBuffer_Binaural[chIdx][k], CLDFB_NO_CHANNELS_MAX ); } } +#endif /* Head rotation in HOA3 or CICPx */ if ( @@ -1174,7 +1503,82 @@ void ivas_binRenderer( ivas_sba2mc_cldfb( *( hBinRenderer->hInputSetup ), RealBuffer, ImagBuffer, hBinRenderer->nInChannels, hBinRenderer->conv_band, numTimeSlots, hBinRenderer->hoa_dec_mtx ); } - ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural[0], Cldfb_ImagBuffer_Binaural[0], RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer, 0 ); +#else + ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, RealBuffer, ImagBuffer, hBinRenderer +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 0 +#endif + ); +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT + /*TODO : move this to a separate function*/ + if ( pMultiBinPoseData != NULL ) + { + if ( pMultiBinPoseData->num_poses > 1 ) + { + IVAS_QUATERNION Quaternions_rel, Quaternions_abs, *Quaternions_ref; + float Rmat_local[3][3]; + + if ( hCombinedOrientationData && hBinRenderer->rotInCldfb ) + { + Quaternions_ref = &hCombinedOrientationData->Quaternions[0]; + Quaternions_rel.w = -3.0f; /*euler*/ + Quaternions_abs.w = -3.0f; /*euler*/ + Quat2EulerDegree( *Quaternions_ref, &Quaternions_abs.z, &Quaternions_abs.y, &Quaternions_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ + + for ( pos_idx = 1; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + Quaternions_rel.x = pMultiBinPoseData->relative_head_poses[pos_idx][0] - pMultiBinPoseData->relative_head_poses[pos_idx - 1][0]; + Quaternions_rel.y = pMultiBinPoseData->relative_head_poses[pos_idx][1] - pMultiBinPoseData->relative_head_poses[pos_idx - 1][1]; + Quaternions_rel.z = pMultiBinPoseData->relative_head_poses[pos_idx][2] - pMultiBinPoseData->relative_head_poses[pos_idx - 1][2]; + Quaternions_abs.x = Quaternions_abs.x + Quaternions_rel.x; + Quaternions_abs.y = Quaternions_abs.y + Quaternions_rel.y; + Quaternions_abs.z = Quaternions_abs.z + Quaternions_rel.z; + + + QuatToRotMat( Quaternions_rel, Rmat_local ); + rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, Rmat_local, hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 ); + ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural[pos_idx], Cldfb_ImagBuffer_Binaural[pos_idx], RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + pos_idx +#endif + ); + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + if ( hPostRendHeadTrackData != NULL ) + { + IVAS_QUATERNION *Quaternions_new1; + IVAS_QUATERNION Quaternions_new; + Quaternions_new1 = &hPostRendHeadTrackData->Quaternions[hPostRendHeadTrackData->num_quaternions++]; + Quaternions_new.w = -3.0f; /*euler*/ + Quat2EulerDegree( *Quaternions_new1, &Quaternions_new.z, &Quaternions_new.y, &Quaternions_new.x ); /*order in Quat2Euler seems to be reversed ?*/ + Quaternions_rel.x = Quaternions_new.x - Quaternions_abs.x; + Quaternions_rel.y = Quaternions_new.y - Quaternions_abs.y; + Quaternions_rel.z = Quaternions_new.z - Quaternions_abs.z; + Quaternions_abs.x = Quaternions_abs.x + Quaternions_rel.x; + Quaternions_abs.y = Quaternions_abs.y + Quaternions_rel.y; + Quaternions_abs.z = Quaternions_abs.z + Quaternions_rel.z; + + QuatToRotMat( Quaternions_rel, Rmat_local ); + rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, Rmat_local, hBinRenderer->hInputSetup->nchan_out_woLFE, 3 ); + ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural[num_poses], Cldfb_ImagBuffer_Binaural[num_poses], RealBuffer, ImagBuffer, hBinRenderer +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + num_poses +#endif + ); + } +#endif + } + } + } +#endif /* Obtain the binaural dmx and compute the reverb */ if ( hBinRenderer->hReverb != NULL ) @@ -1201,9 +1605,18 @@ void ivas_binRenderer( { for ( k = 0; k < numTimeSlots; k++ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + /* Combine first and second parts to generate binaural output signal with room effect */ + v_add( Cldfb_RealBuffer_Binaural[pos_idx][chIdx][k], reverbRe[chIdx][k], Cldfb_RealBuffer_Binaural[pos_idx][chIdx][k], hBinRenderer->conv_band ); + v_add( Cldfb_ImagBuffer_Binaural[pos_idx][chIdx][k], reverbIm[chIdx][k], Cldfb_ImagBuffer_Binaural[pos_idx][chIdx][k], hBinRenderer->conv_band ); + } +#else /* Combine first and second parts to generate binaural output signal with room effect */ v_add( Cldfb_RealBuffer_Binaural[chIdx][k], reverbRe[chIdx][k], Cldfb_RealBuffer_Binaural[chIdx][k], hBinRenderer->conv_band ); v_add( Cldfb_ImagBuffer_Binaural[chIdx][k], reverbIm[chIdx][k], Cldfb_ImagBuffer_Binaural[chIdx][k], hBinRenderer->conv_band ); +#endif } } } @@ -1212,3 +1625,86 @@ void ivas_binRenderer( return; } + +#ifdef SPLIT_REND_WITH_HEAD_ROT +void ivas_rend_CldfbMultiBinRendProcess( + const BINAURAL_RENDERER_HANDLE hCldfbRend, + const COMBINED_ORIENTATION_HANDLE *pCombinedOrientationData, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_Out_Real[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ + float Cldfb_Out_Imag[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t low_res_pre_rend_rot ) +{ + int16_t sf_idx, slot_idx, ch_idx, idx, pose_idx, i, j; + float Cldfb_RealBuffer_sfIn[MAX_INPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_sfIn[MAX_INPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HEAD_TRACK_DATA head_track_post; + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#else + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#endif + + + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + idx = sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES + slot_idx; + for ( ch_idx = 0; ch_idx < hCldfbRend->nInChannels; ch_idx++ ) + { + mvr2r( &Cldfb_In_Real[ch_idx][idx][0], &Cldfb_RealBuffer_sfIn[ch_idx][slot_idx][0], hCldfbRend->max_band ); + mvr2r( &Cldfb_In_Imag[ch_idx][idx][0], &Cldfb_ImagBuffer_sfIn[ch_idx][slot_idx][0], hCldfbRend->max_band ); + } + } + + if ( ( *pCombinedOrientationData ) != NULL ) + { + if ( low_res_pre_rend_rot ) + { + ( *pCombinedOrientationData )->Quaternions[sf_idx] = ( *pCombinedOrientationData )->Quaternions[0]; + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + ( *pCombinedOrientationData )->Rmat[sf_idx][i][j] = ( *pCombinedOrientationData )->Rmat[0][i][j]; + } + } + } + ( *pCombinedOrientationData )->shd_rot_max_order = -1; + } +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + head_track_post.num_quaternions = 0; + head_track_post.shd_rot_max_order = -1; + head_track_post.Quaternions[0] = ivas_split_rend_get_sf_rot_data( pHeadRotData->headPositionsPostRend, sf_idx ); +#endif + + ivas_binRenderer( hCldfbRend, + pMultiBinPoseData, + *pCombinedOrientationData, sf_idx, MAX_PARAM_SPATIAL_SUBFRAMES, +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + &head_track_post, +#endif + Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_sfIn, Cldfb_ImagBuffer_sfIn ); + + for ( pose_idx = 0; pose_idx < hCldfbRend->numPoses; pose_idx++ ) + { + for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + idx = sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES + slot_idx; + for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + mvr2r( &Cldfb_RealBuffer_Binaural[pose_idx][ch_idx][slot_idx][0], &Cldfb_Out_Real[pose_idx][ch_idx][idx][0], hCldfbRend->max_band ); + mvr2r( &Cldfb_ImagBuffer_Binaural[pose_idx][ch_idx][slot_idx][0], &Cldfb_Out_Imag[pose_idx][ch_idx][idx][0], hCldfbRend->max_band ); + } + } + } + } + + return; +} +#endif diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index 439a90fb2c5cf291ad0206e248c167cd46aa404e..6db9d8417cdb5394409637dd2e2f7aab2deda503 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -44,7 +44,6 @@ #endif #include "wmc_auto.h" - /*--------------------------------------------------------------------------* * ivas_dec() * @@ -54,6 +53,10 @@ ivas_error ivas_dec( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ int16_t *data /* o : output synthesis signal */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits +#endif ) { int16_t n, output_frame, nchan_out; @@ -113,6 +116,25 @@ ivas_error ivas_dec( return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) || + ( output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { +#ifdef SPLIT_REND_LC3PLUS +#ifdef SPLIT_REND_LC3PLUS_MC + assert( ( st_ivas->ivas_format == SBA_FORMAT || + ( st_ivas->ivas_format == ISM_FORMAT && st_ivas->ism_mode == ISM_MODE_DISC ) || + ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCT ) ) && + ( output_Fs == 48000 ) && "split binaural mode is currently supported with SBA, discrete ISM, or MCT-MC formats and 48 kHz sampling rate only" ); +#else + assert( ( st_ivas->ivas_format == SBA_FORMAT || ( st_ivas->ivas_format == ISM_FORMAT && st_ivas->ism_mode == ISM_MODE_DISC ) ) && ( output_Fs == 48000 ) && "split binaural mode is currently supported with SBA or discrete ISM format and 48k sampling rate only" ); +#endif +#else + assert( st_ivas->ivas_format == SBA_FORMAT && ( output_Fs == 48000 ) && "split binaural mode is currently supported with SBA format and 48k sampling rate only" ); +#endif + ivas_set_split_rend_setup( &st_ivas->splitBinRend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hCombinedOrientationData, hSplitRendBits ); + } +#endif /*----------------------------------------------------------------* * Decoding + Rendering *----------------------------------------------------------------*/ @@ -252,16 +274,36 @@ ivas_error ivas_dec( /* Binaural rendering */ if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { - - if ( ( ivas_td_binaural_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) +#ifdef SPLIT_REND_LC3PLUS +#ifdef SPLIT_REND_CLDFB_ISM + if ( ( output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) || + ( output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else + if ( output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) +#endif { - return error; + ObjRenderIvasFrame_splitBinaural( st_ivas, output, output_frame ); } + else + { +#endif + if ( ( error = ivas_td_binaural_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } +#ifdef SPLIT_REND_LC3PLUS + } +#endif } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_BINAURAL_ROOM_IR, NULL, - NULL, NULL, NULL, p_output, output_Fs ) ) != IVAS_ERR_OK ) + NULL, NULL, NULL, p_output, output_Fs +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 0 +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -476,13 +518,30 @@ ivas_error ivas_dec( /* Rendering */ if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { - if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, - st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, p_output, output_Fs ) ) != IVAS_ERR_OK ) +#ifdef SPLIT_REND_LC3PLUS_MC + if ( output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) { - return error; + ivas_rend_crendProcessSplitBin( st_ivas, output, output_frame ); } + else + { +#endif + if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, + st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, p_output, output_Fs +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 0 +#endif + ) ) != IVAS_ERR_OK ) - ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); + { + return error; + } + + ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); +#ifdef SPLIT_REND_LC3PLUS_MC + } +#endif } else if ( st_ivas->renderer_type == RENDERER_MC ) { @@ -494,12 +553,23 @@ ivas_error ivas_dec( } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { - if ( ( ivas_td_binaural_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) +#ifdef SPLIT_REND_LC3PLUS_MC + if ( output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) { - return error; + ObjRenderIvasFrame_splitBinaural( st_ivas, output, output_frame ); // TODO tmu check } + else + { +#endif + if ( ( ivas_td_binaural_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } - ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); + ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); +#ifdef SPLIT_REND_LC3PLUS_MC + } +#endif } } else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) @@ -535,7 +605,12 @@ ivas_error ivas_dec( if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, - st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, p_output, output_Fs ) ) != IVAS_ERR_OK ) + st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, p_output, output_Fs +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 0 +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -704,6 +779,36 @@ ivas_error ivas_dec( } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /*split rendering process calls*/ + if ( ( output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) || + ( output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend; + int16_t max_band; + int16_t pcm_out; + hSplitBinRend = &st_ivas->splitBinRend; + max_band = (int16_t) ( ( BINAURAL_MAXBANDS * output_Fs ) / 48000 ); + pcm_out = ( output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; + + ivas_renderMultiBinToSplitBinaural( &hSplitBinRend->splitrend, + st_ivas->hHeadTrackData->Quaternions, + st_ivas->hRenderConfig->split_rend_config.splitRendBitRate, +#ifdef SPLIT_REND_LC3PLUS + st_ivas->hRenderConfig->split_rend_config.codec, +#endif + hSplitBinRend->hSplitRendBits, + hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural, + hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural, + max_band, output, 1, +#ifdef SPLIT_REND_LC3PLUS + st_ivas->ivas_format != SBA_FORMAT, +#endif + pcm_out ); + + free( st_ivas->splitBinRend.hMultiBinCldfbData ); + } +#endif /*----------------------------------------------------------------* * Write IVAS output channels * - compensation for saturation diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index f3ea6912f32005efd1ec1d658363fc71a270bd22..dc36c64f9f74f43701593351c542ef7f6947e2dc 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -2350,8 +2350,19 @@ void ivas_dirac_dec_render_sf( /*CLDFB: last output channels reserved to LFT for CICPx*/ float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#else + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#endif +#else float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#endif + int16_t index, num_freq_bands; /* local copies of azi, ele, diffuseness */ @@ -2922,6 +2933,9 @@ void ivas_dirac_dec_render_sf( { /* Perform binaural rendering */ ivas_binRenderer( st_ivas->hBinRenderer, +#ifdef SPLIT_REND_WITH_HEAD_ROT + &st_ivas->splitBinRend.splitrend.multiBinPoseData, +#endif st_ivas->hCombinedOrientationData, subframe_idx, hDirAC->subframe_nbslots[subframe_idx], @@ -2929,7 +2943,28 @@ void ivas_dirac_dec_render_sf( Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); - +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) || + ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + int16_t pos_idx; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ ) +#else + for ( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ ) +#endif + { + for ( slot_idx = 0; slot_idx < hDirAC->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) + { + mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->splitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx_start + slot_idx], hDirAC->num_freq_bands ); + mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->splitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx_start + slot_idx], hDirAC->num_freq_bands ); + } + } + } + } +#endif /* Inverse CLDFB*/ for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) { @@ -2939,8 +2974,13 @@ void ivas_dirac_dec_render_sf( for ( i = 0; i < hDirAC->subframe_nbslots[subframe_idx]; i++ ) { +#ifdef FIX_SPLIT_REND_MERGE + RealBuffer[i] = Cldfb_RealBuffer_Binaural[0][ch][i]; + ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[0][ch][i]; +#else RealBuffer[i] = Cldfb_RealBuffer_Binaural[ch][i]; ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[ch][i]; +#endif } cldfbSynthesis( RealBuffer, diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 22942030530dd939ed9d9fc5d666c1b78fef11e7..cfb45b5eb0d7e1adcc615e1dada8e0efd72172fc 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -672,7 +672,11 @@ ivas_error ivas_init_decoder_front( * Allocate and initialize Binaural Renderer configuration handle *--------------------------------------------------------------------*/ - if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_ROOM_IR || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) + if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_ROOM_IR || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif + ) { if ( ( error = ivas_render_config_open( &( st_ivas->hRenderConfig ) ) ) != IVAS_ERR_OK ) { @@ -1251,10 +1255,40 @@ ivas_error ivas_init_decoder( if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) || + ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + ivas_renderSplitGetMultiBinPoseData( + &st_ivas->hRenderConfig->split_rend_config, + &st_ivas->splitBinRend.splitrend.multiBinPoseData, + st_ivas->hHeadTrackData->sr_pose_pred_axis ); + } +#endif if ( ( error = ivas_binRenderer_open( st_ivas ) ) != IVAS_ERR_OK ) { return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) || + ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { +#ifdef FIX_SPLIT_REND_OPEN_ERROR_HANDLING + error = +#endif + ivas_split_renderer_open( &st_ivas->splitBinRend.splitrend, + &st_ivas->hRenderConfig->split_rend_config, + hDecoderConfig->output_Fs, + 1, ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ); + +#ifdef FIX_SPLIT_REND_OPEN_ERROR_HANDLING + if ( error != IVAS_ERR_OK ) + { + return error; + } +#endif + } +#endif } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) { @@ -1287,6 +1321,43 @@ ivas_error ivas_init_decoder( } } +#ifdef SPLIT_REND_LC3PLUS +#ifdef SPLIT_REND_CLDFB_ISM + if ( ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) || + ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else + if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) +#endif + { + ivas_renderSplitGetMultiBinPoseData( + &st_ivas->hRenderConfig->split_rend_config, + &st_ivas->splitBinRend.splitrend.multiBinPoseData, + st_ivas->hHeadTrackData->sr_pose_pred_axis ); + /* Split rendering with MC/ISMs only supported with LC3plus */ +#ifndef SPLIT_REND_CLDFB_ISM + assert( st_ivas->hRenderConfig->split_rend_config.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ); +#endif +#ifdef FIX_SPLIT_REND_OPEN_ERROR_HANDLING + error = +#endif + ivas_split_renderer_open( &st_ivas->splitBinRend.splitrend, + &st_ivas->hRenderConfig->split_rend_config, + hDecoderConfig->output_Fs, 0, +#ifdef SPLIT_REND_CLDFB_ISM + ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 +#else + 0 +#endif + ); + +#ifdef FIX_SPLIT_REND_OPEN_ERROR_HANDLING + if ( error != IVAS_ERR_OK ) + { + return error; + } +#endif + } +#endif if ( st_ivas->hDecoderConfig->voip_active ) { granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); @@ -1321,9 +1392,39 @@ ivas_error ivas_init_decoder( return error; } } +#ifdef SPLIT_REND_LC3PLUS_MC + + if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) + { + ivas_renderSplitGetMultiBinPoseData( + &st_ivas->hRenderConfig->split_rend_config, + &st_ivas->splitBinRend.splitrend.multiBinPoseData, + st_ivas->hHeadTrackData->sr_pose_pred_axis ); + + /* Split rendering with MC only supported with LC3plus */ + assert( st_ivas->hRenderConfig->split_rend_config.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ); + + error = ivas_split_renderer_open( &st_ivas->splitBinRend.splitrend, + &st_ivas->hRenderConfig->split_rend_config, + hDecoderConfig->output_Fs, 0, 0 ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + } +#endif if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, - st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs +#ifdef SPLIT_REND_WITH_HEAD_ROT + , +#ifdef SPLIT_REND_LC3PLUS_MC + ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) ? st_ivas->splitBinRend.splitrend.multiBinPoseData.num_poses : 1 +#else + 1 +#endif +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -1670,6 +1771,11 @@ void ivas_initialize_handles_dec( /* rendering handles */ st_ivas->hBinRenderer = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + st_ivas->splitBinRend.hMultiBinCldfbData = NULL; + st_ivas->splitBinRend.hSplitRendBits = NULL; + ivas_init_split_rend_handles( &st_ivas->splitBinRend.splitrend ); +#endif st_ivas->hDiracDecBin = NULL; st_ivas->hLsSetUpConversion = NULL; st_ivas->hEFAPdata = NULL; @@ -1824,12 +1930,24 @@ void ivas_destroy_dec( /* Fastconv binaural renderer handle */ ivas_binRenderer_close( &st_ivas->hBinRenderer ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* Split binaural renderer handle */ + ivas_split_renderer_close( &st_ivas->splitBinRend.splitrend ); + +#else + +#endif /* Parametric binaural renderer handle */ ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); /* Crend handle */ - ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 1 +#endif + ); /* Reverb handle */ ivas_reverb_close( &st_ivas->hReverb ); @@ -2162,7 +2280,11 @@ static ivas_error doSanityChecks_IVAS( if ( st_ivas->hDecoderConfig->Opt_Headrotation ) { - if ( !( output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) + if ( !( output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == AUDIO_CONFIG_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + || output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB || output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif + ) ) { return IVAS_ERROR( IVAS_ERR_HEAD_ROTATION_NOT_SUPPORTED, "Wrong set-up: Head-rotation not supported in this configuration" ); } diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index c031ec8c4bd36f36f7cd001f840f9ebfaeffa7ff..2aaf57f0402bd64d44d03e7641afe77699b05fab 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -212,7 +212,12 @@ static ivas_error ivas_ism_bitrate_switching( ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); /* Open Crend Binaural renderer */ - if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 1 +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -289,7 +294,12 @@ static ivas_error ivas_ism_bitrate_switching( } /* close the crend binaural renderer */ - ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 1 +#endif + ); } } diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index e67e96307df1ea0bfdbfeece7ebbc45bab264ec3..bd55264e5b11b6fd8a86d1027987159a91e3fe71 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -1397,6 +1397,7 @@ void ivas_param_mc_dec_digest_tc( int16_t nchan_transport, nchan_out_transport, nchan_out_cldfb; int16_t nchan_out_cov; /*CLDFB*/ + float cx[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; float cx_imag[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; float real_part, imag_part; @@ -1552,8 +1553,13 @@ void ivas_param_mc_dec_render( /*CLDFB*/ float Cldfb_RealBuffer[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + float Cldfb_RealBuffer_Binaural[1][BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[1][BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; +#else float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; +#endif /*Decorrelator*/ float onset_filter[MAX_CICP_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* format converter */ @@ -1750,8 +1756,15 @@ void ivas_param_mc_dec_render( if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { ivas_binRenderer( st_ivas->hBinRenderer, +#ifdef SPLIT_REND_WITH_HEAD_ROT + &st_ivas->splitBinRend.splitrend.multiBinPoseData, +#endif st_ivas->hCombinedOrientationData, subframe_idx, hParamMC->subframe_nbslots[subframe_idx], + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + NULL, +#endif Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); } else if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_CLDFB ) @@ -1773,8 +1786,13 @@ void ivas_param_mc_dec_render( { if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + RealBuffer[i] = Cldfb_RealBuffer_Binaural[0][ch][i]; + ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[0][ch][i]; +#else RealBuffer[i] = Cldfb_RealBuffer_Binaural[ch][i]; ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[ch][i]; +#endif } else { diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 7742656899b573b0cc86254b5cf43ebc76661131..070d059dc68a65a1a9e1fd5456575aac0013a4c4 100755 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -1132,9 +1132,18 @@ static ivas_error ivas_mc_dec_reconfig( ivas_binRenderer_close( &st_ivas->hBinRenderer ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hCrend[0] != NULL ) && ( st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV && st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV_ROOM && ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD || st_ivas->hIntSetup.output_config != AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) +#else if ( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hCrend != NULL ) && ( st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV && st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV_ROOM && ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD || st_ivas->hIntSetup.output_config != AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) +#endif { - ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 1 +#endif + ); } if ( st_ivas->hBinRendererTd != NULL && ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD ) ) @@ -1192,21 +1201,40 @@ static ivas_error ivas_mc_dec_reconfig( if ( st_ivas->hIntSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { - if ( ( error = ivas_rend_initCrendWrapper( &st_ivas->hCrendWrapper ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_initCrendWrapper( &st_ivas->hCrendWrapper +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 1 +#endif + ) ) != IVAS_ERR_OK ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend Wrapper\n" ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + st_ivas->hCrendWrapper->hCrend[0] = NULL; + st_ivas->hCrendWrapper->hHrtfCrend = NULL; + if ( ( st_ivas->hCrendWrapper->hCrend[0] = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend\n" ); + } +#else st_ivas->hCrendWrapper->hCrend = NULL; st_ivas->hCrendWrapper->hHrtfCrend = NULL; if ( ( st_ivas->hCrendWrapper->hCrend = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend\n" ); } +#endif } } else if ( st_ivas->hCrendWrapper == NULL && ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) { - if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 1 +#endif + ) ) != IVAS_ERR_OK ) { return error; } diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config.c index 16787b63cdd383b24bb8b3c93fe50513e1bca5d3..0684349a5938a0cb923c94ad086af7b7b0df481a 100644 --- a/lib_dec/ivas_output_config.c +++ b/lib_dec/ivas_output_config.c @@ -34,6 +34,9 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_prot.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "ivas_prot_rend.h" +#endif #include "ivas_stat_dec.h" #ifdef DEBUGGING #include "debug.h" @@ -76,7 +79,11 @@ void ivas_renderer_select( st_ivas->hCombinedOrientationData->shd_rot_max_order = -1; } - if ( output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) + if ( output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == AUDIO_CONFIG_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + || output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB || output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif + ) { if ( st_ivas->ivas_format == ISM_FORMAT ) { @@ -127,7 +134,11 @@ void ivas_renderer_select( else if ( st_ivas->ivas_format == MASA_FORMAT || ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->nchan_transport <= 2 ) ) { *internal_config = output_config; - if ( output_config == AUDIO_CONFIG_BINAURAL ) + if ( output_config == AUDIO_CONFIG_BINAURAL +#ifdef SPLIT_REND_WITH_HEAD_ROT + || output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB || output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif + ) { *renderer_type = RENDERER_BINAURAL_PARAMETRIC; } @@ -139,7 +150,12 @@ void ivas_renderer_select( else if ( st_ivas->ivas_format == SBA_FORMAT ) { *internal_config = AUDIO_CONFIG_HOA3; - if ( output_config == AUDIO_CONFIG_BINAURAL ) + + if ( output_config == AUDIO_CONFIG_BINAURAL +#ifdef SPLIT_REND_WITH_HEAD_ROT + || output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB || output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif + ) { *renderer_type = RENDERER_BINAURAL_FASTCONV; } @@ -187,7 +203,11 @@ void ivas_renderer_select( else { *internal_config = transport_config; +#ifdef SPLIT_REND_LC3PLUS_MC + if ( output_config == AUDIO_CONFIG_BINAURAL || output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB || output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#else if ( output_config == AUDIO_CONFIG_BINAURAL ) +#endif { #ifdef DEBUGGING if ( ( ( ( st_ivas->transport_config == AUDIO_CONFIG_5_1 || st_ivas->transport_config == AUDIO_CONFIG_7_1 ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) || ( st_ivas->hDecoderConfig->force_rend == FORCE_TD_RENDERER ) ) && ( st_ivas->mc_mode == MC_MODE_MCT || st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) && !( st_ivas->hDecoderConfig->force_rend == FORCE_CLDFB_RENDERER ) ) @@ -430,3 +450,39 @@ void ivas_renderer_select( return; } + +#ifdef SPLIT_REND_WITH_HEAD_ROT +void ivas_set_split_rend_setup( IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, IVAS_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits ) +{ + hSplitRendBits->bits_written = 0; + hSplitRendBits->bits_read = 0; + hSplitBinRend->hSplitRendBits = hSplitRendBits; + + hSplitBinRend->hMultiBinCldfbData = (IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE) malloc( sizeof( IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA ) ); + + ivas_renderSplitGetMultiBinPoseData( + hSplitBinConfig, + &hSplitBinRend->splitrend.multiBinPoseData, + hCombinedOrientationData->sr_pose_pred_axis ); + +#ifdef SPLIT_REND_IVAS_DEC_HT_TR + if ( hCombinedOrientationData != NULL ) + { + int16_t sf, i, j; + for ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + hCombinedOrientationData->Quaternions[sf] = hCombinedOrientationData->Quaternions[0]; + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + hCombinedOrientationData->Rmat[sf][i][j] = hCombinedOrientationData->Rmat[0][i][j]; + } + } + } + } +#endif + + return; +} +#endif diff --git a/lib_dec/ivas_rom_dec.c b/lib_dec/ivas_rom_dec.c index 6a33a36aaa072eb8fb15cf98c29159072bd55bcd..5a12186cff9838ad597b0dd70e7fc4cb371bd28f 100644 --- a/lib_dec/ivas_rom_dec.c +++ b/lib_dec/ivas_rom_dec.c @@ -541,6 +541,81 @@ const float dmxmtx_table[BINAURAL_CHANNELS][11] = }; +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------* + * split rendering ROM tables + *-----------------------------------------------------------------------*/ + +#ifndef SPLIT_REND_LC3PLUS /* Functionality moved to ivas_split_rend_validate_config() */ +/*----------------------------------------------------------------------------------* + * Table of Split rendering bitrates + *----------------------------------------------------------------------------------*/ +const int32_t split_rend_brate_tbl[SIZE_SPLIT_REND_BRATE_TBL] = +{ + SPLIT_REND_256k, SPLIT_REND_384k, SPLIT_REND_512k, SPLIT_REND_768k +}; +#endif + +/*rotations in this array are relative to ref rotation */ +const float split_rend_relative_yaw_pos_angles[SPLIT_REND_MAX_YAW_ONLY_POSES] = {-15.0f, 15.0f}; +const float split_rend_relative_pitch_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {10.0f, 10.0f}; +const float split_rend_relative_roll_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {10.0f, 10.0f}; +const float split_rend_relative_one_axis_pos_angles[SPLIT_REND_MAX_ONE_AXIS_MD_POSES] = {-15.0f, 15.0f}; + +const float split_rend_relative_yaw_pos_angles_hq[SPLIT_REND_MAX_YAW_ONLY_POSES] = {-15.0f, 15.0f}; +const float split_rend_relative_pitch_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {-15.0f, 15.0f}; +const float split_rend_relative_roll_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES] = {-15.0f, 15.0f}; +const float split_rend_relative_one_axis_pos_angles_hq[SPLIT_REND_MAX_ONE_AXIS_MD_POSES] = {-15.0f, 15.0f}; + +const int16_t SplitRend_band_grouping[MAX_SPLIT_REND_MD_BANDS + 1] = +{ + //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, 32, 34, 36, 38, 40, 50, 60 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 20, 25, 30, 35, 40, 50, 60 + //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 21, 23, 25, 27, 30, 35, 40, 50, 60 + //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 25, 40, 60 +}; + +const int32_t ivas_split_rend_huff_p_d_consts[IVAS_SPLIT_REND_D_QUANT_PNTS][3] = { +{0,8,252},{1,8,253},{2,7,124},{3,6,60},{4,5,28},{5,4,12}, +{6,3,4},{7,1,0},{8,3,5},{9,4,13},{10,5,29},{11,6,61}, +{12,7,125},{13,8,254},{14,8,255} +}; + +const int32_t ivas_split_rend_huff_p_d_diff_consts[IVAS_SPLIT_REND_D_QUANT_PNTS][3] = { + { 0, 1, 0 },{ 1, 2, 2 },{ 2, 3, 6 },{ 3, 4, 14 }, + { 4, 5, 30 },{ 5, 6, 62 },{ 6, 7, 126 },{ 7, 8, 254 }, + { 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 }, + { 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 } +}; + +const int32_t ivas_split_rend_huff_d_consts[IVAS_SPLIT_REND_D_QUANT_PNTS][3] = { + { 0, 1, 0 },{ 1, 2, 2 },{ 2, 3, 6 },{ 3, 4, 14 }, + { 4, 5, 30 },{ 5, 6, 62 },{ 6, 7, 126 },{ 7, 8, 254 }, + { 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 }, + { 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 } +}; +const int32_t ivas_split_rend_huff_pred_consts[IVAS_SPLIT_REND_PRED_QUANT_PNTS][3] = { + /* + { -15, 16, 65532 },{ -14, 16, 65533 },{ -13, 15, 32764 },{ -12, 14, 16380 }, + { -11, 13, 8188 },{ -10, 12, 4092 },{ -9, 11, 2044 },{ -8, 10, 1020 },{ -7, 9, 508 }, + { -6, 8, 252 },{ -5, 7, 124 },{ -4, 6, 60 },{ -3, 5, 28 }, + { -2, 4, 12 },{ -1, 3, 4 },{ 0, 1, 0 },{ 1, 3, 5 }, + { 2, 4, 13 },{ 3, 5, 29 },{ 4, 6, 61 },{ 5, 7, 125 }, + { 6, 8, 253 },{ 7, 9, 509 },{ 8, 10, 1021 },{ 9, 11, 2045 }, + { 10, 12, 4093 },{ 11, 13, 8189 },{ 12, 14, 16381 },{ 13, 15, 32765 }, + { 14, 16, 65534 },{ 15, 16, 65535 }*/ + +{-15,10,1020},{-14,10,1021},{-13,9,506},{-12,9,507}, +{-11,8,250},{-10,8,251},{-9,7,120},{-8,7,121}, +{-7,6,56},{-6,6,57},{-5,5,24},{-4,5,25},{-3,4,8}, +{-2,4,9},{-1,3,2},{0,2,0},{1,3,3}, +{2,4,10},{3,4,11},{4,5,26},{5,5,27}, +{6,6,58},{7,6,59},{8,7,122},{9,7,123}, +{10,7,124},{11,8,252},{12,9,508},{13,9,509}, +{14,10,1022},{15,10,1023}, +}; +#endif + /* clang-format on */ diff --git a/lib_dec/ivas_rom_dec.h b/lib_dec/ivas_rom_dec.h index 7a19f170c0b00f12d5050d4224dcd05cc7960b98..d3287d05ee530c17cc883ed08fbf03f3c6343f43 100644 --- a/lib_dec/ivas_rom_dec.h +++ b/lib_dec/ivas_rom_dec.h @@ -121,6 +121,29 @@ extern const int16_t sba_map_tc_512[11]; extern const float dmxmtx_table[BINAURAL_CHANNELS][11]; +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------* + * split rendering ROM tables + *-----------------------------------------------------------------------*/ +extern const float split_rend_relative_yaw_pos_angles[SPLIT_REND_MAX_YAW_ONLY_POSES]; +extern const float split_rend_relative_pitch_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const float split_rend_relative_roll_pos_angles[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const float split_rend_relative_one_axis_pos_angles[SPLIT_REND_MAX_ONE_AXIS_MD_POSES]; +extern const float split_rend_relative_one_axis_pos_angles_hq[SPLIT_REND_MAX_ONE_AXIS_MD_POSES]; + +extern const float split_rend_relative_yaw_pos_angles_hq[SPLIT_REND_MAX_YAW_ONLY_POSES]; +extern const float split_rend_relative_pitch_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES]; +extern const float split_rend_relative_roll_pos_angles_hq[SPLIT_REND_MAX_PITCH_ONLY_POSES]; + + +extern const float split_rend_relative_pos_angles[MAX_HEAD_ROT_POSES][3]; +extern const int16_t SplitRend_band_grouping[MAX_SPLIT_REND_MD_BANDS + 1]; +extern const int32_t ivas_split_rend_huff_d_consts[IVAS_SPLIT_REND_D_QUANT_PNTS][3]; +extern const int32_t ivas_split_rend_huff_pred_consts[IVAS_SPLIT_REND_PRED_QUANT_PNTS][3]; +extern const int32_t ivas_split_rend_huff_p_d_consts[IVAS_SPLIT_REND_D_QUANT_PNTS][3]; +extern const int32_t ivas_split_rend_huff_p_d_diff_consts[IVAS_SPLIT_REND_D_QUANT_PNTS][3]; +extern const int32_t split_rend_brate_tbl[]; +#endif extern const int16_t huff_nodes_first_band_alpha[32][2]; extern const int16_t huff_nodes_first_band_alpha_coarse[16][2]; diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 22258a93658c1a4dbe219e21ac09eb3505e8fbd4..51bac11136113699311825b76b47dec1e926c16e 100755 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -231,15 +231,49 @@ ivas_error ivas_sba_dec_reconfigure( if ( st_ivas->hBinRenderer == NULL && ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) || + ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + ivas_renderSplitGetMultiBinPoseData( + &st_ivas->hRenderConfig->split_rend_config, + &st_ivas->splitBinRend.splitrend.multiBinPoseData, + st_ivas->hHeadTrackData->sr_pose_pred_axis ); + } +#endif /* open fastconv binaural renderer */ if ( ( error = ivas_binRenderer_open( st_ivas ) ) != IVAS_ERR_OK ) { return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) || + ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { +#ifdef SPLIT_REND_LC3PLUS + assert( st_ivas->hRenderConfig->split_rend_config.codec == IVAS_SPLIT_REND_CODEC_LCLD ); +#endif +#ifdef FIX_SPLIT_REND_OPEN_ERROR_HANDLING + error = +#endif + ivas_split_renderer_open( &st_ivas->splitBinRend.splitrend, + &st_ivas->hRenderConfig->split_rend_config, + hDecoderConfig->output_Fs, 1, ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ); +#ifdef FIX_SPLIT_REND_OPEN_ERROR_HANDLING + if ( error != IVAS_ERR_OK ) + { + return error; + } +#endif + } +#endif } else if ( st_ivas->hBinRenderer != NULL && ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV && st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV_ROOM ) ) { ivas_binRenderer_close( &st_ivas->hBinRenderer ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_split_renderer_close( &st_ivas->splitBinRend.splitrend ); +#endif } if ( st_ivas->renderer_type != old_renderer_type ) diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 906a73b31730d63c67fed8184637fa8f4a5e3532..fc5be70877059810fdbd4a14a53aed12beab3dc7 100755 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -1678,7 +1678,11 @@ void ivas_spar_dec_upmixer_sf( } else { - if ( hDecoderConfig->output_config == AUDIO_CONFIG_FOA || !( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM_IR || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) + if ( hDecoderConfig->output_config == AUDIO_CONFIG_FOA || !( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM_IR || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif + ) ) { for ( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) { diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index e83aa7e6174a85bb02b6be3cb08d87c7034d8c2c..e602aa265bfe11ae1ae882f74863a7ec6a227ad9 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -2810,7 +2810,7 @@ static void ivas_parse_parameter_bitstream_dtx( * Deindex real index *-----------------------------------------------------------------------------------------*/ -static ivas_error ivas_deindex_real_index( +ivas_error ivas_deindex_real_index( const int16_t *index, const int16_t q_levels, const float min_value, diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 315cfbad668d813f787933ea38d810ec8daed60d..991e00614ef1ae66bb7b845675572c51cf10dbb4 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1075,7 +1075,7 @@ typedef struct renderer_struct } ISM_RENDERER_DATA, *ISM_RENDERER_HANDLE; - +#ifndef SPLIT_REND_WITH_HEAD_ROT /* Fastconv binaural data structure */ typedef struct ivas_binaural_rendering_struct { @@ -1098,8 +1098,11 @@ typedef struct ivas_binaural_rendering_struct float earlyPartEneCorrection[CLDFB_NO_CHANNELS_MAX]; REVERB_STRUCT_HANDLE hReverb; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t numPoses; +#endif } BINAURAL_RENDERER, *BINAURAL_RENDERER_HANDLE; - +#endif /*----------------------------------------------------------------------------------* * MASA decoder structures @@ -1198,6 +1201,24 @@ typedef struct decoder_config_structure int16_t Opt_delay_comp; /* flag indicating delay compensation active */ } DECODER_CONFIG, *DECODER_CONFIG_HANDLE; +#ifdef SPLIT_REND_WITH_HEAD_ROT +typedef struct +{ +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; +#else + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; +#endif +} IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA, *IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE; +typedef struct +{ + IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE hMultiBinCldfbData; /*scratch buffer for frame by frame processing*/ + IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits; /*scratch buffer for frame by frame processing*/ + SPLIT_REND_WRAPPER splitrend; +} IVAS_DEC_SPLIT_REND_WRAPPER; +#endif typedef struct decoder_tc_buffer_structure { @@ -1344,6 +1365,10 @@ typedef struct Decoder_Struct int16_t ism_extmeta_active; /* Extended metadata active in decoder */ int16_t ism_extmeta_cnt; /* Change frame counter for extended metadata */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_DEC_SPLIT_REND_WRAPPER splitBinRend; +#endif + } Decoder_Struct; /* clang-format on */ diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 5cc4bdd9b9a5d1b8f5fb9f9ffa075f1a3855fffc..86f08ac778047394f5f31a1bad47509c273614ae 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -37,6 +37,9 @@ #include "jbm_jb4sb.h" #include "jbm_pcmdsp_apa.h" #include "jbm_pcmdsp_fifo.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "ivas_rom_dec.h" +#endif #include #include #include @@ -217,6 +220,30 @@ ivas_error IVAS_DEC_Open( return IVAS_ERR_WRONG_PARAMS; } +#ifndef SPLIT_REND_LC3PLUS /* Functionality moved to ivas_split_rend_validate_config() */ +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-------------------------------------------------------------------* + * is_SplitRend_BitRate() + * + * check if the bitrate is SPLIT REND supported active bitrate + *-------------------------------------------------------------------*/ +static int16_t is_SplitRend_BitRate( const int32_t splitRendBitRate ) +{ + int16_t j; + + j = 0; + while ( j < SIZE_SPLIT_REND_BRATE_TBL && splitRendBitRate != split_rend_brate_tbl[j] ) + { + j++; + } + if ( j >= SIZE_SPLIT_REND_BRATE_TBL ) + { + return 0; + } + return 1; +} +#endif +#endif /*---------------------------------------------------------------------* * init_decoder_config() @@ -356,6 +383,16 @@ static AUDIO_CONFIG mapOutputFormat( { output_config = AUDIO_CONFIG_BINAURAL_ROOM_REVERB; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + else if ( outputFormat == IVAS_DEC_OUTPUT_SPLIT_BINAURAL_CLDFB ) + { + output_config = AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB; + } + else if ( outputFormat == IVAS_DEC_OUTPUT_SPLIT_BINAURAL_PCM ) + { + output_config = AUDIO_CONFIG_BINAURAL_SPLIT_PCM; + } +#endif else { output_config = AUDIO_CONFIG_INVALID; @@ -704,6 +741,10 @@ ivas_error IVAS_DEC_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits +#endif ) { Decoder_Struct *st_ivas; @@ -730,7 +771,12 @@ ivas_error IVAS_DEC_GetSamples( else if ( hIvasDec->mode == IVAS_DEC_MODE_IVAS ) { /* run the main IVAS decoding routine */ - if ( ( error = ivas_dec( st_ivas, pcmBuf ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_dec( st_ivas, pcmBuf +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + hSplitRendBits +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -1147,6 +1193,10 @@ ivas_error IVAS_DEC_FeedHeadTrackData( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ IVAS_QUATERNION *orientation, /* i : head-tracking data, listener orientation */ IVAS_VECTOR3 *Pos /* i : listener position */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + IVAS_SPLIT_REND_ROT_AXIS rot_axis +#endif ) { HEAD_TRACK_DATA_HANDLE hHeadTrackData; @@ -1168,18 +1218,30 @@ ivas_error IVAS_DEC_FeedHeadTrackData( for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) { /* check for Euler angle signaling */ - if ( orientation[i].w == -3.0f ) +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifndef EUALER2QUAT_FIX + /* TODO: temp change until Euler2Quat() is fixed*/ + if ( ( hIvasDec->st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) && + ( hIvasDec->st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#endif +#endif { - Euler2Quat( deg2rad( orientation[i].x ), deg2rad( orientation[i].y ), deg2rad( orientation[i].z ), &orientation[i] ); + if ( orientation[i].w == -3.0f ) + { + Euler2Quat( deg2rad( orientation[i].x ), deg2rad( orientation[i].y ), deg2rad( orientation[i].z ), &orientation[i] ); + } } - ivas_orient_trk_Process( hHeadTrackData->OrientationTracker, orientation[i], FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES, &hHeadTrackData->Quaternions[i] ); hHeadTrackData->Pos[i].x = Pos[i].x; hHeadTrackData->Pos[i].y = Pos[i].y; hHeadTrackData->Pos[i].z = Pos[i].z; } - hIvasDec->st_ivas->hHeadTrackData->num_quaternions = 0; + hHeadTrackData->num_quaternions = 0; + +#ifdef SPLIT_REND_WITH_HEAD_ROT + hHeadTrackData->sr_pose_pred_axis = rot_axis; +#endif return IVAS_ERR_OK; } @@ -1463,6 +1525,17 @@ ivas_error IVAS_DEC_GetRenderConfig( mvr2r( hRCin->roomAcoustics.pAcoustic_dsr, hRCout->room_acoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); mvr2r( hRCin->directivity, hRCout->directivity, 3 ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + hRCout->split_rend_config.splitRendBitRate = SPLIT_REND_768k; + hRCout->split_rend_config.dof = 3; + hRCout->split_rend_config.hq_mode = 0; + hRCout->split_rend_config.codec_delay_ms = 0; +#endif +#ifdef SPLIT_REND_LC3PLUS + hRCout->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_LCLD; + hRCout->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; +#endif + return IVAS_ERR_OK; } @@ -1479,6 +1552,9 @@ ivas_error IVAS_DEC_FeedRenderConfig( ) { RENDER_CONFIG_HANDLE hRenderConfig; +#ifdef SPLIT_REND_LC3PLUS + ivas_error error; +#endif if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hRenderConfig == NULL ) { @@ -1506,6 +1582,22 @@ ivas_error IVAS_DEC_FeedRenderConfig( mvr2r( renderConfig.room_acoustics.pAcoustic_dsr, hRenderConfig->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); mvr2r( renderConfig.directivity, hRenderConfig->directivity, 3 ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + hRenderConfig->split_rend_config = renderConfig.split_rend_config; +#endif +#ifdef SPLIT_REND_LC3PLUS + /* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */ + if ( hRenderConfig->split_rend_config.dof == 0 ) + { + hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + } + + if ( ( error = ivas_split_rend_validate_config( &hRenderConfig->split_rend_config ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + return IVAS_ERR_OK; } @@ -1538,9 +1630,14 @@ ivas_error IVAS_DEC_GetDelay( st_ivas = hIvasDec->st_ivas; hDecoderConfig = st_ivas->hDecoderConfig; - +#ifdef SPLIT_REND_WITH_HEAD_ROT + nSamples[1] = NS2SA( hDecoderConfig->output_Fs, get_delay( DEC, hDecoderConfig->output_Fs, st_ivas->ivas_format, st_ivas->cldfbAnaDec[0], hDecoderConfig->output_config ) ); +#else nSamples[1] = NS2SA( hDecoderConfig->output_Fs, get_delay( DEC, hDecoderConfig->output_Fs, st_ivas->ivas_format, st_ivas->cldfbAnaDec[0] ) ); +#endif + nSamples[2] = (int16_t) roundf( (float) st_ivas->binaural_latency_ns * hDecoderConfig->output_Fs / 1000000000.f ); + nSamples[0] = nSamples[1] + nSamples[2]; if ( st_ivas->ivas_format == MASA_FORMAT ) @@ -2431,6 +2528,16 @@ static ivas_error get_channel_config( { strcpy( str, "Binaural: room with reverb" ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + else if ( config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) + { + strcpy( str, "Binaural_Split_CLDFB" ); + } + else if ( config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + strcpy( str, "Binaural_Split_PCM" ); + } +#endif else if ( config == AUDIO_CONFIG_EXTERNAL ) { strcpy( str, "External renderer" ); diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index ebcdd099c80da0eefb9519e848d5cd71399655ee..4e884f453670552d476e746f9f70ba9612de8091 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -55,6 +55,10 @@ typedef enum _IVAS_DEC_OUTPUT_CONFIG IVAS_DEC_OUTPUT_HOA2, IVAS_DEC_OUTPUT_HOA3, IVAS_DEC_OUTPUT_BINAURAL, +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_DEC_OUTPUT_SPLIT_BINAURAL_CLDFB, /* ToDo: Also includes LC3plus, should be renamed during harmonization */ + IVAS_DEC_OUTPUT_SPLIT_BINAURAL_PCM, +#endif IVAS_DEC_OUTPUT_BINAURAL_ROOM_IR, IVAS_DEC_OUTPUT_BINAURAL_ROOM_REVERB, IVAS_DEC_OUTPUT_EXT, @@ -172,6 +176,10 @@ ivas_error IVAS_DEC_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits /* o : bitstream output for split rendering mode*/ +#endif ); /*! r: error code */ @@ -199,6 +207,10 @@ ivas_error IVAS_DEC_FeedHeadTrackData( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ IVAS_QUATERNION *orientation, /* i : head-tracking data */ IVAS_VECTOR3 *Pos /* i : listener position */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + IVAS_SPLIT_REND_ROT_AXIS rot_axis /*i : external control for rotation axis for split rendering*/ +#endif ); /*! r: error code */ diff --git a/lib_dec/rom_dec.c b/lib_dec/rom_dec.c index beba87c3dab82627e2d7182eac0a38746e59471f..6f0751dc56a154317a734c8617baa807e1e25300 100644 --- a/lib_dec/rom_dec.c +++ b/lib_dec/rom_dec.c @@ -92,7 +92,11 @@ const float lsf_tab[LPC_SHB_ORDER] = const int16_t gw[LGW_MAX] = { 1, 3, 6, 10, 16, 32, 64, 128, 192 }; /* 31.25 343.75 718.75 1218.75 1968.75 4000 8000 16000 24000 */ +#ifdef RENAME_GWLPR +const int16_t ivas_gwlpr[LGW_MAX] = { 1, 3*QUOT_LPR_LTR-1, 6*QUOT_LPR_LTR-1, 10*QUOT_LPR_LTR-1, 16*QUOT_LPR_LTR-1, 32*QUOT_LPR_LTR, 64*QUOT_LPR_LTR, 128*QUOT_LPR_LTR, 192*QUOT_LPR_LTR }; +#else const int16_t gwlpr[LGW_MAX] = { 1, 3*QUOT_LPR_LTR-1, 6*QUOT_LPR_LTR-1, 10*QUOT_LPR_LTR-1, 16*QUOT_LPR_LTR-1, 32*QUOT_LPR_LTR, 64*QUOT_LPR_LTR, 128*QUOT_LPR_LTR, 192*QUOT_LPR_LTR }; +#endif const float w_hamm48k_2[L_TRANA48k/2] = { diff --git a/lib_dec/rom_dec.h b/lib_dec/rom_dec.h index 751a2e4da0c52c6f92ae2cea45ca9428c6a1cf19..604bfc2fe0ce9ef7ad37db1daad5d009a5bf0ee8 100644 --- a/lib_dec/rom_dec.h +++ b/lib_dec/rom_dec.h @@ -56,7 +56,11 @@ extern const int16_t hestable[15]; extern const float lsf_tab[LPC_SHB_ORDER]; extern const int16_t gw[LGW_MAX]; +#ifdef RENAME_GWLPR +extern const int16_t ivas_gwlpr[LGW_MAX]; +#else extern const int16_t gwlpr[LGW_MAX]; +#endif extern const float w_hamm32k_2[L_TRANA32k / 2]; extern const float w_hamm16k_2[L_TRANA16k / 2]; extern const float w_hamm_sana32k_2[L_PROT_HAMM_LEN2_32k]; diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 18cfb9247d3df5f5e6c988b0e462bc0477692a7b..fcf270be97785bd7a72378c516a0ff5995625553 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -947,7 +947,11 @@ ivas_error IVAS_ENC_GetDelay( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + *delay = NS2SA( hEncoderConfig->input_Fs, get_delay( ENC, hEncoderConfig->input_Fs, hEncoderConfig->ivas_format, NULL, AUDIO_CONFIG_INVALID ) ); +#else *delay = NS2SA( hEncoderConfig->input_Fs, get_delay( ENC, hEncoderConfig->input_Fs, hEncoderConfig->ivas_format, NULL ) ); +#endif *delay *= hEncoderConfig->nchan_inp; diff --git a/lib_rend/ivas_CQMFDecoder.c b/lib_rend/ivas_CQMFDecoder.c new file mode 100644 index 0000000000000000000000000000000000000000..b5fe0b38eacc71c2c927f7c6c12c69faa3502485 --- /dev/null +++ b/lib_rend/ivas_CQMFDecoder.c @@ -0,0 +1,1695 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby +International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der +angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips +N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge +Corporation, and other contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, +Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung +e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph +and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings +Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their +respective contributions in the software. This notice grants no license of any +kind, including but not limited to patent license, nor is any license granted by +implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration +agreement before making contributions. + + This software is provided "AS IS", without any express or implied warranties. +The software is in the development stage. It is intended exclusively for experts +who have experience with such software and solely for the purpose of inspection. +All implied warranties of non-infringement, merchantability and fitness for a +particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing +this software shall be submitted to and settled by the final, binding +jurisdiction of the courts of Munich, Germany in accordance with the laws of the +Federal Republic of Germany excluding its conflict of law rules and the United +Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "ivas_CQMFDecoder.h" +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT + +#include "ivas_NoiseGen.h" +#include "ivas_PerceptualModel.h" +#include "ivas_lcld_tables.h" +#include "ivas_cldfb_codec_bitstream.h" +#include "prot.h" +#include +#include +#include +#include +#ifdef ENABLE_MS_PRED +#include "ivas_MSPred.h" +#endif +#include "ivas_PredDecoder.h" +#include "ivas_prot_rend.h" +#include "wmc_auto.h" + +#ifdef ROM_TO_RAM +typedef struct TableNode +{ + struct TableNode **ppoNextTable; + struct TableNode *poOrderedNext; + + int32_t *piCodeIndex; + int32_t *piDifference; + int32_t *piLength; +} TableNode; +typedef struct TableList +{ + TableNode *poOrderedTop; + TableNode *poOrderedBottom; + +} TableList; +#endif +struct CQMF_DECODER +{ + int32_t iSampleRate; + int32_t iChannels; + int32_t iNumBlocks; + + int32_t iNumBands; + const int32_t *piBandwidths; + + int32_t iMSMode; + int32_t *piMSFlags; +#ifdef ROM_TO_RAM + TableList *ptable_list; + uint32_t ( *c_apauiHuffDecTable_RAM[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE]; + uint32_t num_decode_table[2 * ALLOC_TABLE_SIZE]; +#endif +#ifdef ENABLE_MS_PRED + int32_t piMSPredCoefs[MAX_BANDS]; + int32_t piLRPhaseDiffs[MAX_BANDS]; +#endif +#ifdef ENABLE_PMOD_ADJUST + int32_t **ppiHiSMRFlags; +#endif + // uint8_t *pReadBuff; + int32_t iCommonGrouping; + int32_t *piNumGroups; + int32_t **ppiGroupLengths; + + int32_t ***pppiRMSEnvelope; + int32_t ***pppiSMR; + int32_t ***pppiExcitation; + int32_t ***pppiAlloc; + + int32_t iAllocOffset; + + int32_t ***pppiCQMFSignReal; + int32_t ***pppiCQMFSignImag; + int32_t ***pppiQCQMFReal; + int32_t ***pppiQCQMFImag; + + PredictionDecoder *psPredictionDecoder; + + + NoiseGen *psNoiseGen; + + int32_t iLastError; +}; +#ifdef ROM_TO_RAM +static void CreateDecodeTable( CQMFDecoder *psCQMFDecoder, int32_t num, const uint16_t ( *ppuiEncTable )[2], int32_t iSize, int32_t iReadLength, uint32_t *iTables ); +static TableNode *CreateTableList( int32_t iReadLength ); +static void DeleteTableList( TableList *ptable_list, int32_t iTables ); +static TableNode *GetNextTable( int32_t iIndex, TableList *table_list, TableNode *poParent, int32_t iReadLength, uint32_t *iTablesCreated ); +static void AddcodeTableList( TableList *ptable_list, int32_t iLength, int32_t iCode, int32_t iCodeIndex, int32_t iReadLength, uint32_t *iTables ); +static void CompleteTables( CQMFDecoder *psCQMFDecoder, int32_t n, TableList *ptable_list, int32_t iReadLength, int32_t iTablesCreated ); + +static TableNode *CreateTableList( int32_t iReadLength ) +{ + int32_t n; + int32_t iMaxTables; + TableNode *ptable_top; + iMaxTables = 1 << iReadLength; + ptable_top = (TableNode *) malloc( sizeof( TableNode ) ); + ptable_top->ppoNextTable = + (TableNode **) malloc( iMaxTables * sizeof( TableNode * ) ); + ptable_top->piCodeIndex = (int32_t *) malloc( iMaxTables * sizeof( int32_t ) ); + ptable_top->piDifference = (int32_t *) malloc( iMaxTables * sizeof( int32_t ) ); + ptable_top->piLength = (int32_t *) malloc( iMaxTables * sizeof( int32_t ) ); + for ( n = 0; n < iMaxTables; n++ ) + { + ptable_top->ppoNextTable[n] = NULL; + ptable_top->piCodeIndex[n] = 0xffff; + ptable_top->piDifference[n] = 0; + ptable_top->piLength[n] = 0; + } + + return ptable_top; +} +static void DeleteTableList( TableList *ptable_list, int32_t iTables ) +{ + + TableNode *node; + node = ptable_list->poOrderedTop; + + while ( ( iTables ) ) + { + + TableNode *node1 = node; + node = node1->poOrderedNext; + if ( node1->piCodeIndex != NULL ) + { + free( node1->piCodeIndex ); + } + if ( node1->piLength != NULL ) + { + free( node1->piLength ); + } + if ( node1->piDifference != NULL ) + { + free( node1->piDifference ); + } + if ( node1->ppoNextTable != NULL ) + { + free( node1->ppoNextTable ); + } + if ( node1 != NULL ) + { + free( node1 ); + } + iTables--; + } + if ( ptable_list != NULL ) + { + free( ptable_list ); + } +} +static TableNode *GetNextTable( int32_t iIndex, TableList *table_list, TableNode *poParent, int32_t iReadLength, uint32_t *iTablesCreated ) +{ + TableNode *poNextNode; + + if ( poParent->ppoNextTable[iIndex] == NULL ) + { + poNextNode = CreateTableList( iReadLength ); + poParent->ppoNextTable[iIndex] = poNextNode; + poParent->piDifference[iIndex] = + *iTablesCreated; // this is a link to the next table rather than the + // difference + table_list->poOrderedBottom->poOrderedNext = poNextNode; + table_list->poOrderedBottom = poNextNode; + + ( *iTablesCreated )++; + } + else + { + poNextNode = poParent->ppoNextTable[iIndex]; + } + + return poNextNode; +} +static void CompleteTables( CQMFDecoder *psCQMFDecoder, int32_t n, TableList *ptable_list, int32_t iReadLength, int32_t iTablesCreated ) +{ + + int32_t iMaxTables; + int32_t j; + TableNode *poNode; + + iMaxTables = 1 << iReadLength; + psCQMFDecoder->c_apauiHuffDecTable_RAM[n] = + malloc( iTablesCreated * iMaxTables * sizeof( uint32_t * ) ); + + poNode = ptable_list->poOrderedTop; + for ( j = 0; j < iTablesCreated; j++ ) + { + int32_t k; + if ( poNode != NULL ) + { + for ( k = 0; k < iMaxTables; k++ ) + { + uint32_t uiCode; + uiCode = poNode->piDifference[k]; + uiCode <<= 16; + uiCode |= poNode->piCodeIndex[k]; + psCQMFDecoder->c_apauiHuffDecTable_RAM[n][j][k] = uiCode; + } + } + poNode = poNode->poOrderedNext; + } +} +static void AddcodeTableList( TableList *ptable_list, int32_t iLength, int32_t iCode, int32_t iCodeIndex, int32_t iReadLength, uint32_t *iTables ) +{ + int32_t iDifference; + int32_t iMask; + int32_t iCurrentLength; + int32_t iIndex; + int32_t iCodeLow; + int32_t iCodeHigh; + + TableNode *poNode; + poNode = ptable_list->poOrderedTop; + iMask = ( 1 << iReadLength ) - 1; + iCurrentLength = iLength; + while ( iCurrentLength > iReadLength ) + { + iDifference = iCurrentLength - iReadLength; + iIndex = iCode >> iDifference; + iIndex &= iMask; + poNode = GetNextTable( iIndex, ptable_list, poNode, iReadLength, iTables ); + iCurrentLength -= iReadLength; + } + + iMask = ( 1 << iCurrentLength ) - 1; + iDifference = iReadLength - iCurrentLength; + iCodeLow = ( iCode & iMask ) << iDifference; + iMask = ( 1 << iDifference ) - 1; + iCodeHigh = iCodeLow | iMask; + for ( iIndex = iCodeLow; iIndex <= iCodeHigh; iIndex++ ) + { + poNode->piCodeIndex[iIndex] = iCodeIndex; + poNode->piDifference[iIndex] = iDifference; + poNode->piLength[iIndex] = iLength; + } +} + +static void CreateDecodeTable( CQMFDecoder *psCQMFDecoder, int32_t num, const uint16_t ( *ppuiEncTable )[2], int32_t iSize, int32_t iReadLength, uint32_t *iTables ) +{ + int32_t n; + uint32_t **ppsort_enc_table; + TableList *ptable_list; + ptable_list = (TableList *) malloc( sizeof( TableList ) ); + + ppsort_enc_table = (uint32_t **) malloc( iSize * sizeof( int32_t * ) ); + for ( n = 0; n < iSize; n++ ) + { + + ppsort_enc_table[n] = (uint32_t *) malloc( 3 * sizeof( int32_t ) ); + ppsort_enc_table[n][0] = (uint32_t) ppuiEncTable[n][0]; + ppsort_enc_table[n][1] = (uint32_t) ppuiEncTable[n][1]; + ppsort_enc_table[n][2] = (uint32_t) n; + } + + for ( n = 0; n < iSize; n++ ) + { + uint32_t iMin; + int32_t iMinIndex; + int32_t k; + + iMin = ppsort_enc_table[n][0]; + iMinIndex = n; + for ( k = n; k < iSize; k++ ) + { + if ( ppsort_enc_table[k][0] < iMin ) + { + iMin = ppsort_enc_table[k][0]; + iMinIndex = k; + } + } + + if ( iMinIndex != n ) + { + uint32_t uiLength; + uint32_t uiCode; + uint32_t uiCodeIndex; + + uiLength = ppsort_enc_table[n][0]; + uiCode = ppsort_enc_table[n][1]; + uiCodeIndex = ppsort_enc_table[n][2]; + + ppsort_enc_table[n][0] = ppsort_enc_table[iMinIndex][0]; + ppsort_enc_table[n][1] = ppsort_enc_table[iMinIndex][1]; + ppsort_enc_table[n][2] = ppsort_enc_table[iMinIndex][2]; + + ppsort_enc_table[iMinIndex][0] = uiLength; + ppsort_enc_table[iMinIndex][1] = uiCode; + ppsort_enc_table[iMinIndex][2] = uiCodeIndex; + } + } + ptable_list->poOrderedTop = CreateTableList( iReadLength ); + ptable_list->poOrderedBottom = ptable_list->poOrderedTop; + for ( n = 0; n < iSize; n++ ) + { + int32_t iLength; + int32_t iCode; + int32_t iCodeIndex; + + iLength = ppsort_enc_table[n][0]; + iCode = ppsort_enc_table[n][1]; + iCodeIndex = ppsort_enc_table[n][2]; + AddcodeTableList( ptable_list, iLength, iCode, iCodeIndex, iReadLength, + iTables ); + } + + CompleteTables( psCQMFDecoder, num, ptable_list, iReadLength, *iTables ); + DeleteTableList( ptable_list, *iTables ); + for ( n = 0; n < iSize; n++ ) + { + free( ppsort_enc_table[n] ); + } + free( ppsort_enc_table ); +} +#endif +CQMFDecoder *CreateCQMFDecoder( const int32_t iSampleRate, + const int32_t iChannels ) +{ + int32_t n; +#ifdef ROM_TO_RAM + int32_t read_length; +#endif + CQMFDecoder *psCQMFDecoder = NULL; + + assert( iSampleRate == 48000 ); // Fix + + psCQMFDecoder = (CQMFDecoder *) malloc( sizeof( CQMFDecoder ) ); + psCQMFDecoder->iSampleRate = iSampleRate; + psCQMFDecoder->iChannels = iChannels; + psCQMFDecoder->iNumBlocks = CQMF_BLOCKS_PER_FRAME; + psCQMFDecoder->iAllocOffset = 0; + + psCQMFDecoder->iNumBands = MAX_BANDS_48; // Fix + psCQMFDecoder->piBandwidths = c_aiBandwidths48; // Fix + + psCQMFDecoder->iMSMode = 0; + psCQMFDecoder->piMSFlags = + (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ); +#ifdef ENABLE_MS_PRED + for ( n = 0; n < MAX_BANDS; n++ ) + { + psCQMFDecoder->piLRPhaseDiffs[n] = 0; + psCQMFDecoder->piMSPredCoefs[n] = 0; + } +#endif +#ifdef ENABLE_PMOD_ADJUST + psCQMFDecoder->ppiHiSMRFlags = + (int32_t **) malloc( psCQMFDecoder->iChannels * sizeof( int32_t * ) ); +#endif + + psCQMFDecoder->iCommonGrouping = + 1; // Common grouping always on only impacts stereo + psCQMFDecoder->piNumGroups = + (int32_t *) malloc( psCQMFDecoder->iChannels * sizeof( int32_t ) ); + psCQMFDecoder->ppiGroupLengths = + (int32_t **) malloc( psCQMFDecoder->iChannels * sizeof( int32_t * ) ); + psCQMFDecoder->pppiRMSEnvelope = + (int32_t ***) malloc( psCQMFDecoder->iChannels * sizeof( int32_t ** ) ); + psCQMFDecoder->pppiSMR = + (int32_t ***) malloc( psCQMFDecoder->iChannels * sizeof( int32_t ** ) ); + psCQMFDecoder->pppiExcitation = + (int32_t ***) malloc( psCQMFDecoder->iChannels * sizeof( int32_t ** ) ); + psCQMFDecoder->pppiAlloc = + (int32_t ***) malloc( psCQMFDecoder->iChannels * sizeof( int32_t ** ) ); + + psCQMFDecoder->pppiCQMFSignReal = + (int32_t ***) malloc( psCQMFDecoder->iChannels * sizeof( int32_t ** ) ); + psCQMFDecoder->pppiCQMFSignImag = + (int32_t ***) malloc( psCQMFDecoder->iChannels * sizeof( int32_t ** ) ); + psCQMFDecoder->pppiQCQMFReal = + (int32_t ***) malloc( psCQMFDecoder->iChannels * sizeof( int32_t ** ) ); + psCQMFDecoder->pppiQCQMFImag = + (int32_t ***) malloc( psCQMFDecoder->iChannels * sizeof( int32_t ** ) ); + for ( n = 0; n < iChannels; n++ ) + { + int32_t k; +#ifdef ENABLE_PMOD_ADJUST + psCQMFDecoder->ppiHiSMRFlags[n] = + (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ); + ; +#endif + psCQMFDecoder->ppiGroupLengths[n] = + (int32_t *) malloc( CQMF_BLOCKS_PER_FRAME * sizeof( int32_t ) ); + psCQMFDecoder->pppiRMSEnvelope[n] = + (int32_t **) malloc( CQMF_BLOCKS_PER_FRAME * sizeof( int32_t * ) ); + psCQMFDecoder->pppiSMR[n] = + (int32_t **) malloc( CQMF_BLOCKS_PER_FRAME * sizeof( int32_t * ) ); + psCQMFDecoder->pppiExcitation[n] = + (int32_t **) malloc( CQMF_BLOCKS_PER_FRAME * sizeof( int32_t * ) ); + psCQMFDecoder->pppiAlloc[n] = + (int32_t **) malloc( CQMF_BLOCKS_PER_FRAME * sizeof( int32_t * ) ); + + psCQMFDecoder->pppiCQMFSignReal[n] = + (int32_t **) malloc( CQMF_BLOCKS_PER_FRAME * sizeof( int32_t * ) ); + psCQMFDecoder->pppiCQMFSignImag[n] = + (int32_t **) malloc( CQMF_BLOCKS_PER_FRAME * sizeof( int32_t * ) ); + psCQMFDecoder->pppiQCQMFReal[n] = + (int32_t **) malloc( CQMF_BLOCKS_PER_FRAME * sizeof( int32_t * ) ); + psCQMFDecoder->pppiQCQMFImag[n] = + (int32_t **) malloc( CQMF_BLOCKS_PER_FRAME * sizeof( int32_t * ) ); + for ( k = 0; k < CQMF_BLOCKS_PER_FRAME; k++ ) + { + psCQMFDecoder->pppiRMSEnvelope[n][k] = + (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ); + psCQMFDecoder->pppiSMR[n][k] = + (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ); + psCQMFDecoder->pppiExcitation[n][k] = + (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ); + psCQMFDecoder->pppiAlloc[n][k] = + (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ); + + psCQMFDecoder->pppiCQMFSignReal[n][k] = + (int32_t *) malloc( CQMF_BANDS * sizeof( int32_t ) ); + psCQMFDecoder->pppiCQMFSignImag[n][k] = + (int32_t *) malloc( CQMF_BANDS * sizeof( int32_t ) ); + psCQMFDecoder->pppiQCQMFReal[n][k] = + (int32_t *) malloc( CQMF_BANDS * sizeof( int32_t ) ); + psCQMFDecoder->pppiQCQMFImag[n][k] = + (int32_t *) malloc( CQMF_BANDS * sizeof( int32_t ) ); + } + } +#ifdef ROM_TO_RAM + read_length = READ_LENGTH; + for ( n = 0; n < ALLOC_TABLE_SIZE * 2; n++ ) + { + psCQMFDecoder->num_decode_table[n] = 1; // initialising the value to 1 + if ( c_apauiHuffEncTabels[n] != NULL ) + { + + CreateDecodeTable( psCQMFDecoder, n, c_apauiHuffEncTabels[n], num_row_aauiCQMFHuff[n], read_length, &psCQMFDecoder->num_decode_table[n] ); + } + else + { + psCQMFDecoder->c_apauiHuffDecTable_RAM[n] = NULL; + } + } +#endif + psCQMFDecoder->psPredictionDecoder = + CreatePredictionDecoder( iChannels, psCQMFDecoder->iNumBlocks ); + // psCQMFDecoder->pReadBuff = + // (uint8_t *) malloc( 4096 * sizeof( uint8_t ) ); + psCQMFDecoder->psNoiseGen = + NULL; // CreateNoiseGen(); // No noise fill for now + + psCQMFDecoder->iLastError = DECODER_ERROR_NONE; + + return psCQMFDecoder; +} + +void DeleteCQMFDecoder( CQMFDecoder *psCQMFDecoder ) +{ + if ( psCQMFDecoder != NULL ) + { + + if ( psCQMFDecoder->piMSFlags != NULL ) + { + free( psCQMFDecoder->piMSFlags ); + } + + if ( psCQMFDecoder->piNumGroups != NULL ) + { + free( psCQMFDecoder->piNumGroups ); + } + + if ( psCQMFDecoder->ppiGroupLengths != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFDecoder->iChannels; n++ ) + { + free( psCQMFDecoder->ppiGroupLengths[n] ); + } + free( psCQMFDecoder->ppiGroupLengths ); + } + + if ( psCQMFDecoder->pppiRMSEnvelope != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFDecoder->iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < CQMF_BLOCKS_PER_FRAME; k++ ) + { + free( psCQMFDecoder->pppiRMSEnvelope[n][k] ); + } + free( psCQMFDecoder->pppiRMSEnvelope[n] ); + } + free( psCQMFDecoder->pppiRMSEnvelope ); + } + + if ( psCQMFDecoder->pppiSMR != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFDecoder->iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < CQMF_BLOCKS_PER_FRAME; k++ ) + { + free( psCQMFDecoder->pppiSMR[n][k] ); + } + free( psCQMFDecoder->pppiSMR[n] ); + } + free( psCQMFDecoder->pppiSMR ); + } + + if ( psCQMFDecoder->pppiExcitation != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFDecoder->iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < CQMF_BLOCKS_PER_FRAME; k++ ) + { + free( psCQMFDecoder->pppiExcitation[n][k] ); + } + free( psCQMFDecoder->pppiExcitation[n] ); + } + free( psCQMFDecoder->pppiExcitation ); + } + +#ifdef ENABLE_PMOD_ADJUST + if ( psCQMFDecoder->ppiHiSMRFlags != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFDecoder->iChannels; n++ ) + { + free( psCQMFDecoder->ppiHiSMRFlags[n] ); + } + free( psCQMFDecoder->ppiHiSMRFlags ); + } +#endif + + if ( psCQMFDecoder->pppiAlloc != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFDecoder->iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < CQMF_BLOCKS_PER_FRAME; k++ ) + { + free( psCQMFDecoder->pppiAlloc[n][k] ); + } + free( psCQMFDecoder->pppiAlloc[n] ); + } + free( psCQMFDecoder->pppiAlloc ); + } + + if ( psCQMFDecoder->pppiCQMFSignReal != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFDecoder->iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < CQMF_BLOCKS_PER_FRAME; k++ ) + { + free( psCQMFDecoder->pppiCQMFSignReal[n][k] ); + } + free( psCQMFDecoder->pppiCQMFSignReal[n] ); + } + free( psCQMFDecoder->pppiCQMFSignReal ); + } + + if ( psCQMFDecoder->pppiCQMFSignImag != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFDecoder->iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < CQMF_BLOCKS_PER_FRAME; k++ ) + { + free( psCQMFDecoder->pppiCQMFSignImag[n][k] ); + } + free( psCQMFDecoder->pppiCQMFSignImag[n] ); + } + free( psCQMFDecoder->pppiCQMFSignImag ); + } + + if ( psCQMFDecoder->pppiQCQMFReal != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFDecoder->iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < CQMF_BLOCKS_PER_FRAME; k++ ) + { + free( psCQMFDecoder->pppiQCQMFReal[n][k] ); + } + free( psCQMFDecoder->pppiQCQMFReal[n] ); + } + free( psCQMFDecoder->pppiQCQMFReal ); + } + + if ( psCQMFDecoder->pppiQCQMFImag != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFDecoder->iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < CQMF_BLOCKS_PER_FRAME; k++ ) + { + free( psCQMFDecoder->pppiQCQMFImag[n][k] ); + } + free( psCQMFDecoder->pppiQCQMFImag[n] ); + } + free( psCQMFDecoder->pppiQCQMFImag ); + } + + // if ( psCQMFDecoder->pReadBuff != NULL ) + //{ + // free( psCQMFDecoder->pReadBuff ); + // } +#ifdef ROM_TO_RAM + for ( uint32_t n = 0; n < ALLOC_TABLE_SIZE * 2; n++ ) + { + if ( psCQMFDecoder->num_decode_table[n] > 1 ) + { + + if ( psCQMFDecoder->c_apauiHuffDecTable_RAM[n] != NULL ) + { + free( psCQMFDecoder->c_apauiHuffDecTable_RAM[n] ); + } + } + } +#endif + + DeletePredictionDecoder( psCQMFDecoder->psPredictionDecoder ); + + if ( psCQMFDecoder->psNoiseGen != NULL ) + { + DeleteNoiseGen( psCQMFDecoder->psNoiseGen ); + } + + free( psCQMFDecoder ); + } +} + +int32_t CQMFDecoderGetError( CQMFDecoder *psCQMFDecoder ) +{ + return psCQMFDecoder->iLastError; +} + +static void ApplyRMSEnvelope( const int32_t iNumBands, + const int32_t *piBandwidths, + const int32_t iNumGroups, + const int32_t *piGroupLengths, + int32_t **ppiRMSEnvelope, + float **ppfReal, + float **ppfImag ); + +static void ReplaceSign( const int32_t iNumBlocks, const int32_t iNumCQMFBands, int32_t **ppiSignReal, int32_t **ppiSignImag, float **ppfReal, float **ppfImag ); + +static void +InvQuantizeSpectrum( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, int32_t **ppiAlloc, int32_t **ppiQReal, int32_t **ppiQImag, float **ppfReal, float **ppfImag, + NoiseGen *psNoiseGen ); // Nullable + +static void InvMSCoding( const int32_t iNumBlocks, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t iMSMode, const int32_t *piMSFlags, +#ifdef ENABLE_MS_PRED + const int32_t *piLRPhaseDiffs, + const int32_t *piMSPredCoefs, +#endif + float ***pppfReal, + float ***pppfImag ); + +/* Currently only the number of bands in frame */ +static int32_t ReadHeaderInformation( int32_t *piNumBands, + ivas_split_rend_bits_t *pBits ); + +static int32_t ReadMSInformation( const int32_t iNumBands, int32_t *piMSMode, int32_t *piMSFlags, +#ifdef ENABLE_MS_PRED + int32_t *piLRPhaseDiffs, + int32_t *piMSPredCoefs, +#endif + ivas_split_rend_bits_t *pBits ); + +static int32_t ReadGroupInformation( const int32_t iChannels, + const int32_t iNumBlocks, + int32_t *piCommonGrouping, + int32_t *piNumGroups, + int32_t **ppiGroupLengths, + ivas_split_rend_bits_t *pBits ); + +static int32_t ReadHuff( const uint32_t ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], + int32_t *piSymbol, + ivas_split_rend_bits_t *pBits ); + +static int32_t ReadRMSEnvelope( const int32_t iChannels, + const int32_t *piNumGroups, + const int32_t iNumBands, + int32_t ***pppiRMSEnvelope, + ivas_split_rend_bits_t *pBits ); +static int32_t ReadAllocInformation( int32_t *piAllocOffset, + ivas_split_rend_bits_t *pBits ); +#ifdef ROM_TO_RAM +static int32_t +ReadCQMFData( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t *piPredEnable, int32_t **ppiAlloc, int32_t **ppiSignReal, int32_t **ppiSignImag, int32_t **ppiQReal, int32_t **ppiQImag, ivas_split_rend_bits_t *pBits, uint32_t ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] ); +#else +static int32_t +ReadCQMFData( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t *piPredEnable, int32_t **ppiAlloc, int32_t **ppiSignReal, int32_t **ppiSignImag, int32_t **ppiQReal, int32_t **ppiQImag, ivas_split_rend_bits_t *pBits ); +#endif + +static void ComputeAllocation( const int32_t iChannels, + const int32_t *piNumGroups, + const int32_t iNumBands, + int32_t ***pppiSMR, + const int32_t iAllocOffset, + int32_t ***pppiAlloc ); + +int32_t DecodeFrame( CQMFDecoder *psCQMFDecoder, + ivas_split_rend_bits_t *pBits, + float ***pppfCQMFReal, + float ***pppfCQMFImag ) +{ + int32_t n; + int32_t iBitsRead; + + iBitsRead = 0; + + iBitsRead += + ReadHeaderInformation( &psCQMFDecoder->iNumBands, pBits ); + + if ( psCQMFDecoder->iChannels == 2 ) + { + iBitsRead += ReadMSInformation( + psCQMFDecoder->iNumBands, &psCQMFDecoder->iMSMode, + psCQMFDecoder->piMSFlags, +#ifdef ENABLE_MS_PRED + psCQMFDecoder->piLRPhaseDiffs, psCQMFDecoder->piMSPredCoefs, +#endif + pBits ); + } + iBitsRead += ReadPredictors( psCQMFDecoder->psPredictionDecoder, + pBits ); + + + iBitsRead += ReadGroupInformation( + psCQMFDecoder->iChannels, psCQMFDecoder->iNumBlocks, + &psCQMFDecoder->iCommonGrouping, psCQMFDecoder->piNumGroups, + psCQMFDecoder->ppiGroupLengths, + pBits ); + + iBitsRead += ReadRMSEnvelope( + psCQMFDecoder->iChannels, (const int32_t *) psCQMFDecoder->piNumGroups, + psCQMFDecoder->iNumBands, psCQMFDecoder->pppiRMSEnvelope, + pBits ); + +#ifdef ENABLE_PMOD_ADJUST + iBitsRead += + ReadPmodInformation( psCQMFDecoder->ppiHiSMRFlags, psCQMFDecoder->psBSRead, + psCQMFDecoder->iChannels, psCQMFDecoder->iNumBands ); +#endif + + iBitsRead += ReadAllocInformation( &psCQMFDecoder->iAllocOffset, + pBits ); + + if ( psCQMFDecoder->iChannels == 2 && + psCQMFDecoder->iCommonGrouping == 1 ) + { // MS Mode? + int32_t k; + for ( k = 0; k < psCQMFDecoder->piNumGroups[0]; k++ ) + { + PerceptualModelStereo( psCQMFDecoder->iNumBands, psCQMFDecoder->piMSFlags, + psCQMFDecoder->pppiRMSEnvelope[0][k], + psCQMFDecoder->pppiRMSEnvelope[1][k], + psCQMFDecoder->pppiExcitation[0][k], + psCQMFDecoder->pppiExcitation[1][k], + psCQMFDecoder->pppiSMR[0][k], + psCQMFDecoder->pppiSMR[1][k] ); + } + } + else + { + for ( n = 0; n < psCQMFDecoder->iChannels; + n++ ) + { // This will be updated to support multiple sample rates + int32_t k; + for ( k = 0; k < psCQMFDecoder->piNumGroups[n]; k++ ) + { + PerceptualModel( + psCQMFDecoder->iNumBands, psCQMFDecoder->pppiRMSEnvelope[n][k], + psCQMFDecoder->pppiExcitation[n][k], psCQMFDecoder->pppiSMR[n][k] ); + } + } + } + + ComputeAllocation( + psCQMFDecoder->iChannels, (const int32_t *) psCQMFDecoder->piNumGroups, + psCQMFDecoder->iNumBands, psCQMFDecoder->pppiSMR, + psCQMFDecoder->iAllocOffset, psCQMFDecoder->pppiAlloc ); + + for ( n = 0; n < psCQMFDecoder->iChannels; n++ ) + { + iBitsRead += ReadCQMFData( + psCQMFDecoder->piNumGroups[n], + (const int32_t *) psCQMFDecoder->ppiGroupLengths[n], + psCQMFDecoder->iNumBands, psCQMFDecoder->piBandwidths, + (const int32_t *) + psCQMFDecoder->psPredictionDecoder->ppiPredBandEnable[n], + psCQMFDecoder->pppiAlloc[n], + psCQMFDecoder->pppiCQMFSignReal[n], psCQMFDecoder->pppiCQMFSignImag[n], + psCQMFDecoder->pppiQCQMFReal[n], psCQMFDecoder->pppiQCQMFImag[n], + pBits +#ifdef ROM_TO_RAM + , + psCQMFDecoder->c_apauiHuffDecTable_RAM +#endif + ); + } + + for ( n = 0; n < psCQMFDecoder->iChannels; n++ ) + { + InvQuantizeSpectrum( psCQMFDecoder->piNumGroups[n], + (const int32_t *) psCQMFDecoder->ppiGroupLengths[n], + psCQMFDecoder->iNumBands, psCQMFDecoder->piBandwidths, + psCQMFDecoder->pppiAlloc[n], + psCQMFDecoder->pppiQCQMFReal[n], + psCQMFDecoder->pppiQCQMFImag[n], + pppfCQMFReal[n], pppfCQMFImag[n], + psCQMFDecoder->psNoiseGen ); + + ReplaceSign( psCQMFDecoder->iNumBlocks, CQMF_BANDS, + psCQMFDecoder->pppiCQMFSignReal[n], + psCQMFDecoder->pppiCQMFSignImag[n], + pppfCQMFReal[n], pppfCQMFImag[n] ); + } + + ApplyInversePredictros( psCQMFDecoder->psPredictionDecoder, pppfCQMFReal, + pppfCQMFImag ); + + for ( n = 0; n < psCQMFDecoder->iChannels; n++ ) + { + ApplyRMSEnvelope( psCQMFDecoder->iNumBands, psCQMFDecoder->piBandwidths, + psCQMFDecoder->piNumGroups[n], + (const int32_t *) psCQMFDecoder->ppiGroupLengths[n], + psCQMFDecoder->pppiRMSEnvelope[n], + pppfCQMFReal[n], pppfCQMFImag[n] ); + } + + if ( psCQMFDecoder->iChannels == 2 && psCQMFDecoder->iMSMode > 0 ) + { + InvMSCoding( psCQMFDecoder->iNumBlocks, psCQMFDecoder->iNumBands, + psCQMFDecoder->piBandwidths, psCQMFDecoder->iMSMode, + (const int32_t *) psCQMFDecoder->piMSFlags, +#ifdef ENABLE_MS_PRED + (const int32_t *) psCQMFDecoder->piLRPhaseDiffs, + (const int32_t *) psCQMFDecoder->piMSPredCoefs, +#endif + pppfCQMFReal, pppfCQMFImag ); + } + + return 0; +} + +static void ApplyRMSEnvelope( const int32_t iNumBands, + const int32_t *piBandwidths, + const int32_t iNumGroups, + const int32_t *piGroupLengths, + int32_t **ppiRMSEnvelope, + float **ppfReal, + float **ppfImag ) +{ + int32_t n; + int32_t iBlockOffset; + + iBlockOffset = 0; + for ( n = 0; n < iNumGroups; n++ ) + { + int32_t k; + + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + int32_t b; + int32_t iFBOffset; + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t m; + int32_t iRMSEnv; + float fGain; + + iRMSEnv = ppiRMSEnvelope[n][b]; + fGain = + c_afRMSEnvReconstructTable[ENV_RECONSTRUCT_TABLE_CENTER + iRMSEnv]; + for ( m = 0; m < piBandwidths[b]; m++ ) + { + ppfReal[iBlockOffset][iFBOffset] *= fGain; + ppfImag[iBlockOffset][iFBOffset] *= fGain; + iFBOffset++; + } + } + iBlockOffset++; + } + } +} + +static void ReplaceSign( const int32_t iNumBlocks, const int32_t iNumCQMFBands, int32_t **ppiSignReal, int32_t **ppiSignImag, float **ppfReal, float **ppfImag ) +{ + int32_t n; + for ( n = 0; n < iNumBlocks; n++ ) + { + int32_t b; + for ( b = 0; b < iNumCQMFBands; b++ ) + { + if ( ppiSignReal[n][b] == 1 ) + { + ppfReal[n][b] = -ppfReal[n][b]; + } + if ( ppiSignImag[n][b] == 1 ) + { + ppfImag[n][b] = -ppfImag[n][b]; + } + } + } +} + +static void InvQuantizeSpectrum( + const int32_t iNumGroups, + const int32_t *piGroupLengths, + const int32_t iNumBands, + const int32_t *piBandwidths, + int32_t **ppiAlloc, + int32_t **ppiQReal, + int32_t **ppiQImag, + float **ppfReal, + float **ppfImag, + NoiseGen *psNoiseGen ) // Pass in NULL to swicth off noise gen +{ + int32_t n; + int32_t iBlockOffest; + + iBlockOffest = 0; + for ( n = 0; n < iNumGroups; n++ ) + { + int32_t k; + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + int32_t b; + int32_t iFBOffset; + + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t m; + int32_t iAlloc; + float fInvSCFGain; + + iAlloc = ppiAlloc[n][b]; + fInvSCFGain = c_afInvScaleFactor[iAlloc]; + + if ( iAlloc > 0 ) + { + for ( m = 0; m < piBandwidths[b]; m++ ) + { + int32_t iQuantValue; + + iQuantValue = ppiQReal[iBlockOffest][iFBOffset]; + ppfReal[iBlockOffest][iFBOffset] = (float) iQuantValue * fInvSCFGain; + + iQuantValue = ppiQImag[iBlockOffest][iFBOffset]; + ppfImag[iBlockOffest][iFBOffset] = (float) iQuantValue * fInvSCFGain; + + iFBOffset++; + } + } + else if ( psNoiseGen != NULL ) + { + for ( m = 0; m < piBandwidths[b]; m++ ) + { + ppfReal[iBlockOffest][iFBOffset] = 0.7f * GetNoise( psNoiseGen ); + ppfImag[iBlockOffest][iFBOffset] = 0.7f * GetNoise( psNoiseGen ); + + iFBOffset++; + } + } + else + { + iFBOffset += piBandwidths[b]; + } + } + + iBlockOffest++; + } + } +} + +static void InvMSCoding( const int32_t iNumBlocks, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t iMSMode, const int32_t *piMSFlags, +#ifdef ENABLE_MS_PRED + const int32_t *piLRPhaseDiffs, + const int32_t *piMSPredCoefs, +#endif + float ***pppfReal, + float ***pppfImag ) +{ + if ( iMSMode > 0 ) + { + int32_t b; + int32_t iFBOffset; +#ifdef ENABLE_MS_PRED + int32_t bms = 0; +#if defined SIMPLE_PHASE + void( *pFuncPhaseRotateOptions[4] ) = { &rot_zero, &rot_m_pi_2, &rot_pm_pi, + &rot_p_pi_2 }; +#endif +#endif + + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + if ( piMSFlags[b] == 1 ) + { + int32_t n; +#if defined ENABLE_MS_PRED && defined SIMPLE_PHASE + void ( *pFuncPhaseRotate )( float *, float * ) = + pFuncPhaseRotateOptions[piLRPhaseDiffs[bms]]; +#endif + for ( n = 0; n < piBandwidths[b]; n++ ) + { + int32_t k; + for ( k = 0; k < iNumBlocks; k++ ) + { + float fLeftReal; + float fLeftImag; + float fRightReal; + float fRightImag; +#ifdef ENABLE_MS_PRED + if ( iMSMode == 3 ) + { + float fPred; + fPred = dequantPred( piMSPredCoefs[bms] ); + pppfReal[1][k][iFBOffset] += fPred * pppfReal[0][k][iFBOffset]; + pppfImag[1][k][iFBOffset] += fPred * pppfImag[0][k][iFBOffset]; + } +#endif + fLeftReal = ( pppfReal[0][k][iFBOffset] + pppfReal[1][k][iFBOffset] ); + fLeftImag = ( pppfImag[0][k][iFBOffset] + pppfImag[1][k][iFBOffset] ); + fRightReal = + ( pppfReal[0][k][iFBOffset] - pppfReal[1][k][iFBOffset] ); + fRightImag = + ( pppfImag[0][k][iFBOffset] - pppfImag[1][k][iFBOffset] ); +#ifdef ENABLE_MS_PRED + if ( iMSMode == 3 ) + { +#ifdef SIMPLE_PHASE + ( *pFuncPhaseRotate )( &fRightReal, &fRightImag ); +#else + int32_t phaseIdx; + phaseIdx = piLRPhaseDiffs[bms] - PHASE_MIN_VAL; + cplxmult( &fRightReal, &fRightImag, c_afRotRealImag[phaseIdx][0], + -c_afRotRealImag[phaseIdx][1] ); +#endif + } +#endif + pppfReal[0][k][iFBOffset] = fLeftReal; + pppfReal[1][k][iFBOffset] = fRightReal; + pppfImag[0][k][iFBOffset] = fLeftImag; + pppfImag[1][k][iFBOffset] = fRightImag; + } + iFBOffset++; + } +#ifdef ENABLE_MS_PRED + bms++; +#endif + } + else + { + iFBOffset += piBandwidths[b]; + } + } + } +} + +/* Currently only the number of bands in frame */ +static int32_t ReadHeaderInformation( int32_t *piNumBands, + ivas_split_rend_bits_t *pBits ) +{ + int32_t iBitsRead; + + iBitsRead = 0; + *piNumBands = ivas_split_rend_bitstream_read_int32( pBits, 5 ); + iBitsRead += 5; + + return iBitsRead; +} + +static int32_t ReadMSInformation( const int32_t iNumBands, int32_t *piMSMode, int32_t *piMSFlags, +#ifdef ENABLE_MS_PRED + int32_t *piLRPhaseDiffs, + int32_t *piMSPredCoefs, +#endif + ivas_split_rend_bits_t *pBits ) +{ + int32_t iBitsRead; + + iBitsRead = 0; + *piMSMode = ivas_split_rend_bitstream_read_int32( pBits, 2 ); + iBitsRead += 2; + + if ( *piMSMode == 0 ) + { + int32_t n; + for ( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = 0; + } + } + else if ( *piMSMode == 1 ) + { + int32_t n; + for ( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = 1; + } + } + else if ( *piMSMode == 2 ) + { + int32_t n; + for ( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + } + } +#ifdef ENABLE_MS_PRED + else if ( *piMSMode == 3 ) + { + int32_t n; + int32_t iMSPredAll; + int32_t iNumMSPredBands = 0; + int32_t anyNonZero; + iMSPredAll = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + if ( iMSPredAll ) + { + iNumMSPredBands = iNumBands; + for ( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = 1; + } + } + else + { + for ( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + if ( piMSFlags[n] ) + { + iNumMSPredBands++; + } + } + } + anyNonZero = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + if ( anyNonZero ) + { +#ifdef SIMPLE_PHASE + for ( n = 0; n < iNumMSPredBands; n++ ) + { + piLRPhaseDiffs[n] = BSGetBits( psBSRead, SIMPLE_PHASE_BITS ); + iBitsRead += SIMPLE_PHASE_BITS; + } +#else + piLRPhaseDiffs[0] = ivas_split_rend_bitstream_read_int32( pBits, PHASE_BAND0_BITS ); + piLRPhaseDiffs[0] += PHASE_MIN_VAL; + iBitsRead += PHASE_BAND0_BITS; + for ( n = 1; n < iNumMSPredBands; n++ ) + { + int32_t tabIdx; + iBitsRead += ReadHuff( c_aaiRMSEnvHuffDec, &tabIdx, pBits ); + piLRPhaseDiffs[n] = tabIdx + ENV_DELTA_MIN; + } + DecodePhase( piLRPhaseDiffs, iNumMSPredBands, PHASE_DIFF_DIM ); +#endif + } + else + { + for ( n = 0; n < iNumMSPredBands; n++ ) + { + piLRPhaseDiffs[n] = 0; + } + } + anyNonZero = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + if ( anyNonZero ) + { + piMSPredCoefs[0] = ivas_split_rend_bitstream_read_int32( pBits, PRED_BAND0_BITS ); + piMSPredCoefs[0] += PRED_MIN_VAL; + iBitsRead += PRED_BAND0_BITS; + for ( n = 1; n < iNumMSPredBands; n++ ) + { + int32_t tabIdx; + iBitsRead += ReadHuff( c_aaiRMSEnvHuffDec, &tabIdx, pBits ); + piMSPredCoefs[n] = tabIdx + ENV_DELTA_MIN; + } + DecodePredCoef( piMSPredCoefs, iNumMSPredBands ); + } + else + { + for ( n = 0; n < iNumMSPredBands; n++ ) + { + piMSPredCoefs[n] = 0; + } + } +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid = 0; + if ( !fid ) + { + fid = fopen( "ms_mode_dec.txt", "wt" ); + } + writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSPredBands, + iNumBands, fid, piMSFlags ); + } +#endif + } +#endif + else + { + printf( "ERROR UNSUPPORTED MS MODE\n" ); + } + + return iBitsRead; +} + +static int32_t +ReadGroupInformation( const int32_t iChannels, const int32_t iNumBlocks, int32_t *piCommonGrouping, int32_t *piNumGroups, int32_t **ppiGroupLengths, ivas_split_rend_bits_t *pBits ) +{ + int32_t iBitsRead; + + iBitsRead = 0; + if ( iChannels == 2 ) + { + *piCommonGrouping = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + + if ( *piCommonGrouping == 1 ) + { + int32_t k; + + piNumGroups[0] = 0; + ppiGroupLengths[0][piNumGroups[0]] = 1; + for ( k = 0; k < ( iNumBlocks - 1 ); k++ ) + { + int32_t iGroupStart; + + iGroupStart = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + + if ( iGroupStart == 1 ) + { + piNumGroups[0]++; + ppiGroupLengths[0][piNumGroups[0]] = 1; + } + else + { + ppiGroupLengths[0][piNumGroups[0]]++; + } + } + piNumGroups[0]++; + + piNumGroups[1] = piNumGroups[0]; + for ( k = 0; k < piNumGroups[1]; k++ ) + { + ppiGroupLengths[1][k] = ppiGroupLengths[0][k]; + } + } + else + { + int32_t c; + + for ( c = 0; c < iChannels; c++ ) + { + int32_t k; + + piNumGroups[c] = 0; + ppiGroupLengths[c][piNumGroups[c]] = 1; + for ( k = 0; k < ( iNumBlocks - 1 ); k++ ) + { + int32_t iGroupStart; + + iGroupStart = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + + if ( iGroupStart == 1 ) + { + piNumGroups[c]++; + ppiGroupLengths[c][piNumGroups[c]] = 1; + } + else + { + ppiGroupLengths[c][piNumGroups[c]]++; + } + } + piNumGroups[c]++; + } + } + } + else + { + int32_t c; + + for ( c = 0; c < iChannels; c++ ) + { + int32_t k; + + piNumGroups[c] = 0; + ppiGroupLengths[c][piNumGroups[c]] = 1; + for ( k = 0; k < ( iNumBlocks - 1 ); k++ ) + { + int32_t iGroupStart; + + iGroupStart = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + + if ( iGroupStart == 1 ) + { + piNumGroups[c]++; + ppiGroupLengths[c][piNumGroups[c]] = 1; + } + else + { + ppiGroupLengths[c][piNumGroups[c]]++; + } + } + piNumGroups[c]++; + } + } + + return iBitsRead; +} + +static int32_t ReadHuff( const uint32_t ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], + int32_t *piSymbol, + ivas_split_rend_bits_t *pBits ) +{ + int32_t iBitsRead; + int32_t iSymbol; + int32_t iIndex; + int32_t iVal; + + iVal = 0; + iIndex = 0; + iSymbol = 0xFFFF; + iBitsRead = 0; + while ( iSymbol == 0xFFFF ) + { + iIndex = ivas_split_rend_bitstream_read_int32( pBits, HUFF_READ_SIZE ); + iBitsRead += HUFF_READ_SIZE; + + iIndex = pauiHuffDecTable[iVal][iIndex]; + iSymbol = ( iIndex & 0xFFFF ); + + iVal = ( iIndex >> 16 ); + } + + if ( iVal ) + { + BSForceBack( + pBits, + iIndex, iVal ); + iBitsRead -= iVal; + } + + *piSymbol = iSymbol; + + return iBitsRead; +} + +static int32_t ReadRMSEnvelope( const int32_t iChannels, + const int32_t *piNumGroups, + const int32_t iNumBands, + int32_t ***pppiRMSEnvelope, + ivas_split_rend_bits_t *pBits ) +{ + int32_t n; + int32_t iBitsRead; + + iBitsRead = 0; + for ( n = 0; n < iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < piNumGroups[n]; k++ ) + { + int32_t b; + int32_t iLastRMSVal; + + iLastRMSVal = ivas_split_rend_bitstream_read_int32( pBits, ENV0_BITS ); + iBitsRead += ENV0_BITS; + + iLastRMSVal += ENV_MIN; + pppiRMSEnvelope[n][k][0] = iLastRMSVal; + for ( b = 1; b < iNumBands; b++ ) + { + int32_t iDelta; + + iBitsRead += ReadHuff( c_aaiRMSEnvHuffDec, &iDelta, pBits ); + + iDelta += ENV_DELTA_MIN; + iLastRMSVal += iDelta; + pppiRMSEnvelope[n][k][b] = iLastRMSVal; + } + } + } + + return iBitsRead; +} + +#ifdef ENABLE_PMOD_ADJUST +static int32_t ReadPmodInformation( int32_t **ppiHiSMRFlags, Bitstream *psBSRead, int32_t iChannels, int32_t iNumBands ) +{ + int32_t iBitsRead; + int32_t c; + iBitsRead = 0; + for ( c = 0; c < iChannels; c++ ) + { + int32_t b; + int32_t iFlags = BSGetBits( psBSRead, 1 ); + iBitsRead += 1; + if ( iFlags ) + { + for ( b = 0; b < iNumBands; b++ ) + { + ppiHiSMRFlags[c][b] = BSGetBits( psBSRead, 1 ); + ; + iBitsRead += 1; + } + } + else + { + for ( b = 0; b < iNumBands; b++ ) + { + ppiHiSMRFlags[c][b] = 0; + } + } + } +#ifdef WRITE_HISMR_FLAGS + { + static FILE *fid = 0; + if ( !fid ) + { + fid = fopen( "hismr_dec.txt", "wt" ); + } + for ( c = 0; c < iChannels; c++ ) + { + int32_t b; + for ( b = 0; b < iNumBands; b++ ) + { + if ( c == iChannels - 1 && b == iNumBands - 1 ) + { + fprintf( fid, "%d\n", ppiHiSMRFlags[c][b] ); + } + else + { + fprintf( fid, "%d ", ppiHiSMRFlags[c][b] ); + } + } + } + } +#endif + return iBitsRead; +} +#endif + +static int32_t ReadAllocInformation( int32_t *piAllocOffset, + ivas_split_rend_bits_t *pBits ) +{ + int32_t iBitsRead; + + iBitsRead = 0; + *piAllocOffset = ivas_split_rend_bitstream_read_int32( pBits, ALLOC_OFFSET_BITS ); + *piAllocOffset += MIN_ALLOC_OFFSET; + iBitsRead += ALLOC_OFFSET_BITS; + + return iBitsRead; +} +#ifdef ROM_TO_RAM +static int32_t +ReadCQMFData( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t *piPredEnable, int32_t **ppiAlloc, int32_t **ppiSignReal, int32_t **ppiSignImag, int32_t **ppiQReal, int32_t **ppiQImag, ivas_split_rend_bits_t *pBits, uint32_t ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] ) +#else +static int32_t +ReadCQMFData( const int32_t iNumGroups, const int32_t *piGroupLengths, const int32_t iNumBands, const int32_t *piBandwidths, const int32_t *piPredEnable, int32_t **ppiAlloc, int32_t **ppiSignReal, int32_t **ppiSignImag, int32_t **ppiQReal, int32_t **ppiQImag, ivas_split_rend_bits_t *pBits ) +#endif +{ + int32_t n; + int32_t iBitsRead; + int32_t iBlockOffest; + + iBitsRead = 0; + iBlockOffest = 0; + for ( n = 0; n < iNumGroups; n++ ) + { + int32_t k; + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + int32_t b; + int32_t iFBOffset; + + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t m; + int32_t iAlloc; + int32_t iHuffDim; + int32_t iHuffMod; + + iAlloc = ppiAlloc[n][b]; + + iHuffDim = c_aiHuffmanDim[iAlloc]; + iHuffMod = c_aiHuffmanMod[iAlloc]; + + if ( iAlloc > 0 ) + { + const uint32_t( *pauiHuffmanTable )[HUFF_DEC_TABLE_SIZE] = NULL; + const uint32_t( *pauiHuffmanTableDPCM )[HUFF_DEC_TABLE_SIZE] = NULL; +#ifdef USE_DEMOD_TABLES + const int32_t( *paiDemodTable )[2] = NULL; +#endif +#ifdef ROM_TO_RAM + pauiHuffmanTable = (const uint32_t( * )[HUFF_DEC_TABLE_SIZE]) c_apauiHuffDecTables[iAlloc]; + pauiHuffmanTableDPCM = (const uint32_t( * )[HUFF_DEC_TABLE_SIZE]) c_apauiHuffDecTables[ALLOC_TABLE_SIZE + iAlloc]; +#else + pauiHuffmanTable = c_apauiHuffDecTables[iAlloc]; + pauiHuffmanTableDPCM = c_apauiHuffDecTables[ALLOC_TABLE_SIZE + iAlloc]; +#endif +#ifdef USE_DEMOD_TABLES + paiDemodTable = c_apaiDemodTables[iAlloc]; +#endif + for ( m = 0; m < piBandwidths[b]; m++ ) + { + int32_t iQuantValue1 = 0; + int32_t iQuantValue2 = 0; + + if ( piPredEnable[iFBOffset] == 1 ) + { + if ( iHuffDim == 2 ) + { + int32_t iSymbol; + iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iSymbol, pBits ); +#ifdef USE_DEMOD_TABLES + iQuantValue1 = paiDemodTable[iSymbol][0]; + iQuantValue2 = paiDemodTable[iSymbol][1]; +#else + iQuantValue1 = iSymbol / iHuffMod; + iQuantValue2 = iSymbol % iHuffMod; +#endif + } + else + { + iBitsRead += + ReadHuff( pauiHuffmanTableDPCM, &iQuantValue1, + pBits ); + iBitsRead += + ReadHuff( pauiHuffmanTableDPCM, &iQuantValue2, + pBits ); + } + } + else + { + if ( iHuffDim == 2 ) + { + int32_t iSymbol; + + iBitsRead += ReadHuff( pauiHuffmanTable, &iSymbol, + pBits ); +#ifdef USE_DEMOD_TABLES + iQuantValue1 = paiDemodTable[iSymbol][0]; + iQuantValue2 = paiDemodTable[iSymbol][1]; +#else + iQuantValue1 = iSymbol / iHuffMod; + iQuantValue2 = iSymbol % iHuffMod; +#endif + } + else + { + iBitsRead += + ReadHuff( pauiHuffmanTable, &iQuantValue1, + pBits ); + iBitsRead += + ReadHuff( pauiHuffmanTable, &iQuantValue2, + pBits ); + } + } + + ppiQReal[iBlockOffest][iFBOffset] = iQuantValue1; + ppiQImag[iBlockOffest][iFBOffset] = iQuantValue2; + + if ( iQuantValue1 > 0 ) + { + ppiSignReal[iBlockOffest][iFBOffset] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + } +#ifdef SPLIT_REND_CLANG_SAN_FIX + else + { + ppiSignReal[iBlockOffest][iFBOffset] = 0; + } +#endif + if ( iQuantValue2 > 0 ) + { + ppiSignImag[iBlockOffest][iFBOffset] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + } +#ifdef SPLIT_REND_CLANG_SAN_FIX + else + { + ppiSignImag[iBlockOffest][iFBOffset] = 0; + } +#endif + + iFBOffset++; + } + } + else + { +#ifdef SPLIT_REND_CLANG_SAN_FIX + for ( m = 0; m < piBandwidths[b]; m++ ) + { + ppiSignReal[iBlockOffest][iFBOffset] = 0; + ppiSignImag[iBlockOffest][iFBOffset] = 0; + iFBOffset++; + } +#else + iFBOffset += piBandwidths[b]; +#endif + } + } + + iBlockOffest++; + } + } + + return iBitsRead; +} + +static void ComputeAllocation( const int32_t iChannels, + const int32_t *piNumGroups, + const int32_t iNumBands, + int32_t ***pppiSMR, + const int32_t iAllocOffset, + int32_t ***pppiAlloc ) +{ + int32_t n; + + for ( n = 0; n < iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < piNumGroups[n]; k++ ) + { + int32_t b; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t iAlloc; + iAlloc = ( ( pppiSMR[n][k][b] + iAllocOffset * ALLOC_OFFSET_SCALE ) >> 5 ); + iAlloc = ( iAlloc > MIN_ALLOC ) ? iAlloc : MIN_ALLOC; + iAlloc = ( iAlloc < MAX_ALLOC ) ? iAlloc : MAX_ALLOC; + pppiAlloc[n][k][b] = iAlloc; + } + } + } +} +#endif diff --git a/lib_rend/ivas_CQMFDecoder.h b/lib_rend/ivas_CQMFDecoder.h new file mode 100644 index 0000000000000000000000000000000000000000..f331ed20d38569c697e4c697328cbb479fb0fceb --- /dev/null +++ b/lib_rend/ivas_CQMFDecoder.h @@ -0,0 +1,67 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef _IVAS_CQMF_DECODER_H_ +#define _IVAS_CQMF_DECODER_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT + +#include "lib_rend.h" +#define DECODER_ERROR_NONE ( 0 ) +#define DECODER_ERROR_FS_NOT_SUPPORTED ( -1 ) +#define DECODER_ERROR_CHAN_NOT_SUPPORTED ( -2 ) +#define DECODER_ERROR_UNKNOWN ( -100 ) + + typedef struct CQMF_DECODER CQMFDecoder; + + CQMFDecoder *CreateCQMFDecoder( const int32_t iSampleRate, + const int32_t iChannels ); + + void DeleteCQMFDecoder( CQMFDecoder *psCQMFDecoder ); + + int32_t CQMFDecoderGetError( CQMFDecoder *psCQMFDecoder ); + + int32_t DecodeFrame( CQMFDecoder *psCQMFDecoder, + ivas_split_rend_bits_t *pBits, + float ***pppfCQMFReal, + float ***pppfCQMFImag ); +#endif +#ifdef __cplusplus +} +#endif +#endif /* _CQMF_DECODER_H_ */ diff --git a/lib_rend/ivas_CQMFEncoder.c b/lib_rend/ivas_CQMFEncoder.c new file mode 100644 index 0000000000000000000000000000000000000000..755fb670f46e2bd28aa200d6d97deec79b9fc055 --- /dev/null +++ b/lib_rend/ivas_CQMFEncoder.c @@ -0,0 +1,2056 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "ivas_CQMFEncoder.h" +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include +#include +#include +#include "ivas_lcld_tables.h" +#include "prot.h" +#include "ivas_RMSEnvGrouping.h" +#include "ivas_PerceptualModel.h" +#include "ivas_cldfb_codec_bitstream.h" +#include "ivas_prot_rend.h" +#ifdef ENABLE_MS_PRED +#include "ivas_MSPred.h" +#endif +#ifdef ENABLE_PMOD_ADJUST +#include "ton_corr.h" +#endif +#include "ivas_PredEncoder.h" +#include "wmc_auto.h" + +struct CQMF_ENCODER +{ + int32_t iSampleRate; + int32_t iChannels; + int32_t iNumBlocks; + + int32_t iTargetBitRate; + int32_t iTargetBitsPerFrame; + + int32_t iNumBands; + const int32_t *piBandwidths; + + int32_t iMSMode; + int32_t *piMSFlags; +#ifdef ENABLE_MS_PRED + int32_t piMSPredCoefs[MAX_BANDS]; + int32_t piLRPhaseDiffs[MAX_BANDS]; + int32_t iAllowSidePred; +#endif +#ifdef ENABLE_PMOD_ADJUST + int32_t **ppiHiSMRFlags; +#endif + + RMSEnvelopeGrouping *psRMSEnvelopeGrouping; + + int32_t iCommonGrouping; + int32_t *piNumGroups; + int32_t **ppiGroupLengths; + + int32_t ***pppiRMSEnvelope; + int32_t ***pppiSMR; + int32_t ***pppiExcitation; + int32_t ***pppiAlloc; + + int32_t iAllocOffset; + + int32_t ***pppiCQMFSignReal; + int32_t ***pppiCQMFSignImag; + int32_t ***pppiQCQMFReal; + int32_t ***pppiQCQMFImag; + + + PredictionEncoder *psPredictionEncoder; + int32_t iLastError; +}; + +CQMFEncoder *CreateCQMFEncoder( const int32_t iSampleRate, + const int32_t iChannels, + const int32_t iTargetBitRate, + const int32_t iAllowSidePred ) +{ + int32_t n; + CQMFEncoder *psCQMFEncoder = NULL; + + assert( iSampleRate == 48000 ); // Fix + + psCQMFEncoder = (CQMFEncoder *) malloc( sizeof( CQMFEncoder ) ); + psCQMFEncoder->iSampleRate = iSampleRate; + psCQMFEncoder->iChannels = iChannels; + psCQMFEncoder->iNumBlocks = CQMF_BLOCKS_PER_FRAME; + psCQMFEncoder->iAllocOffset = 0; + + psCQMFEncoder->iTargetBitRate = iTargetBitRate; + psCQMFEncoder->iTargetBitsPerFrame = iTargetBitRate * CQMF_BLOCKS_PER_FRAME * CQMF_BANDS / iSampleRate; + + psCQMFEncoder->iNumBands = MAX_BANDS_48; // Fix + psCQMFEncoder->piBandwidths = c_aiBandwidths48; // Fix + + psCQMFEncoder->iMSMode = 0; + psCQMFEncoder->piMSFlags = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ); +#ifdef ENABLE_MS_PRED + for ( n = 0; n < MAX_BANDS; n++ ) + { + psCQMFEncoder->piLRPhaseDiffs[n] = 0; + psCQMFEncoder->piMSPredCoefs[n] = 0; + } + psCQMFEncoder->iAllowSidePred = iAllowSidePred; +#endif + psCQMFEncoder->psRMSEnvelopeGrouping = CreateRMSEnvelopeGrouping( psCQMFEncoder->iNumBlocks ); + + psCQMFEncoder->iCommonGrouping = 1; // Common grouping always on only impacts stereo + psCQMFEncoder->piNumGroups = (int32_t *) malloc( psCQMFEncoder->iChannels * sizeof( int32_t ) ); + psCQMFEncoder->ppiGroupLengths = (int32_t **) malloc( psCQMFEncoder->iChannels * sizeof( int32_t * ) ); + psCQMFEncoder->pppiRMSEnvelope = (int32_t ***) malloc( psCQMFEncoder->iChannels * sizeof( int32_t ** ) ); + psCQMFEncoder->pppiSMR = (int32_t ***) malloc( psCQMFEncoder->iChannels * sizeof( int32_t ** ) ); + psCQMFEncoder->pppiExcitation = (int32_t ***) malloc( psCQMFEncoder->iChannels * sizeof( int32_t ** ) ); + psCQMFEncoder->pppiAlloc = (int32_t ***) malloc( psCQMFEncoder->iChannels * sizeof( int32_t ** ) ); + + psCQMFEncoder->pppiCQMFSignReal = (int32_t ***) malloc( psCQMFEncoder->iChannels * sizeof( int32_t ** ) ); + psCQMFEncoder->pppiCQMFSignImag = (int32_t ***) malloc( psCQMFEncoder->iChannels * sizeof( int32_t ** ) ); + psCQMFEncoder->pppiQCQMFReal = (int32_t ***) malloc( psCQMFEncoder->iChannels * sizeof( int32_t ** ) ); + psCQMFEncoder->pppiQCQMFImag = (int32_t ***) malloc( psCQMFEncoder->iChannels * sizeof( int32_t ** ) ); +#ifdef ENABLE_PMOD_ADJUST + psCQMFEncoder->ppiHiSMRFlags = (int32_t **) malloc( psCQMFEncoder->iChannels * sizeof( int32_t * ) ); +#endif + + for ( n = 0; n < iChannels; n++ ) + { + int32_t k; +#ifdef ENABLE_PMOD_ADJUST + psCQMFEncoder->ppiHiSMRFlags[n] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ); + ; +#endif + psCQMFEncoder->ppiGroupLengths[n] = (int32_t *) malloc( CQMF_BLOCKS_PER_FRAME * sizeof( int32_t ) ); + psCQMFEncoder->pppiRMSEnvelope[n] = (int32_t **) malloc( CQMF_BLOCKS_PER_FRAME * sizeof( int32_t * ) ); + psCQMFEncoder->pppiSMR[n] = (int32_t **) malloc( CQMF_BLOCKS_PER_FRAME * sizeof( int32_t * ) ); + psCQMFEncoder->pppiExcitation[n] = (int32_t **) malloc( CQMF_BLOCKS_PER_FRAME * sizeof( int32_t * ) ); + psCQMFEncoder->pppiAlloc[n] = (int32_t **) malloc( CQMF_BLOCKS_PER_FRAME * sizeof( int32_t * ) ); + + psCQMFEncoder->pppiCQMFSignReal[n] = (int32_t **) malloc( CQMF_BLOCKS_PER_FRAME * sizeof( int32_t * ) ); + psCQMFEncoder->pppiCQMFSignImag[n] = (int32_t **) malloc( CQMF_BLOCKS_PER_FRAME * sizeof( int32_t * ) ); + psCQMFEncoder->pppiQCQMFReal[n] = (int32_t **) malloc( CQMF_BLOCKS_PER_FRAME * sizeof( int32_t * ) ); + psCQMFEncoder->pppiQCQMFImag[n] = (int32_t **) malloc( CQMF_BLOCKS_PER_FRAME * sizeof( int32_t * ) ); + for ( k = 0; k < CQMF_BLOCKS_PER_FRAME; k++ ) + { + psCQMFEncoder->pppiRMSEnvelope[n][k] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ); + psCQMFEncoder->pppiSMR[n][k] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ); + psCQMFEncoder->pppiExcitation[n][k] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ); + psCQMFEncoder->pppiAlloc[n][k] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ); + + psCQMFEncoder->pppiCQMFSignReal[n][k] = (int32_t *) malloc( CQMF_BANDS * sizeof( int32_t ) ); + psCQMFEncoder->pppiCQMFSignImag[n][k] = (int32_t *) malloc( CQMF_BANDS * sizeof( int32_t ) ); + psCQMFEncoder->pppiQCQMFReal[n][k] = (int32_t *) malloc( CQMF_BANDS * sizeof( int32_t ) ); + psCQMFEncoder->pppiQCQMFImag[n][k] = (int32_t *) malloc( CQMF_BANDS * sizeof( int32_t ) ); + } + } + + psCQMFEncoder->psPredictionEncoder = CreatePredictionEncoder( iChannels, psCQMFEncoder->iNumBlocks ); + psCQMFEncoder->iLastError = ENCODER_ERROR_NONE; + + return psCQMFEncoder; +} + +void DeleteCQMFEncoder( CQMFEncoder *psCQMFEncoder ) +{ + if ( psCQMFEncoder != NULL ) + { + + if ( psCQMFEncoder->piMSFlags != NULL ) + { + free( psCQMFEncoder->piMSFlags ); + } + + if ( psCQMFEncoder->piNumGroups != NULL ) + { + free( psCQMFEncoder->piNumGroups ); + } + + if ( psCQMFEncoder->psRMSEnvelopeGrouping != NULL ) + { + DeleteRMSEnvelopeGrouping( psCQMFEncoder->psRMSEnvelopeGrouping ); + } + + if ( psCQMFEncoder->ppiGroupLengths != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFEncoder->iChannels; n++ ) + { + free( psCQMFEncoder->ppiGroupLengths[n] ); + } + free( psCQMFEncoder->ppiGroupLengths ); + } +#ifdef ENABLE_PMOD_ADJUST + if ( psCQMFEncoder->ppiHiSMRFlags != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFEncoder->iChannels; n++ ) + { + free( psCQMFEncoder->ppiHiSMRFlags[n] ); + } + free( psCQMFEncoder->ppiHiSMRFlags ); + } +#endif + if ( psCQMFEncoder->pppiRMSEnvelope != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFEncoder->iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < CQMF_BLOCKS_PER_FRAME; k++ ) + { + free( psCQMFEncoder->pppiRMSEnvelope[n][k] ); + } + free( psCQMFEncoder->pppiRMSEnvelope[n] ); + } + free( psCQMFEncoder->pppiRMSEnvelope ); + } + + if ( psCQMFEncoder->pppiSMR != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFEncoder->iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < CQMF_BLOCKS_PER_FRAME; k++ ) + { + free( psCQMFEncoder->pppiSMR[n][k] ); + } + free( psCQMFEncoder->pppiSMR[n] ); + } + free( psCQMFEncoder->pppiSMR ); + } + + if ( psCQMFEncoder->pppiExcitation != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFEncoder->iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < CQMF_BLOCKS_PER_FRAME; k++ ) + { + free( psCQMFEncoder->pppiExcitation[n][k] ); + } + free( psCQMFEncoder->pppiExcitation[n] ); + } + free( psCQMFEncoder->pppiExcitation ); + } + + if ( psCQMFEncoder->pppiAlloc != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFEncoder->iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < CQMF_BLOCKS_PER_FRAME; k++ ) + { + free( psCQMFEncoder->pppiAlloc[n][k] ); + } + free( psCQMFEncoder->pppiAlloc[n] ); + } + free( psCQMFEncoder->pppiAlloc ); + } + + if ( psCQMFEncoder->pppiCQMFSignReal != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFEncoder->iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < CQMF_BLOCKS_PER_FRAME; k++ ) + { + free( psCQMFEncoder->pppiCQMFSignReal[n][k] ); + } + free( psCQMFEncoder->pppiCQMFSignReal[n] ); + } + free( psCQMFEncoder->pppiCQMFSignReal ); + } + + if ( psCQMFEncoder->pppiCQMFSignImag != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFEncoder->iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < CQMF_BLOCKS_PER_FRAME; k++ ) + { + free( psCQMFEncoder->pppiCQMFSignImag[n][k] ); + } + free( psCQMFEncoder->pppiCQMFSignImag[n] ); + } + free( psCQMFEncoder->pppiCQMFSignImag ); + } + + if ( psCQMFEncoder->pppiQCQMFReal != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFEncoder->iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < CQMF_BLOCKS_PER_FRAME; k++ ) + { + free( psCQMFEncoder->pppiQCQMFReal[n][k] ); + } + free( psCQMFEncoder->pppiQCQMFReal[n] ); + } + free( psCQMFEncoder->pppiQCQMFReal ); + } + + if ( psCQMFEncoder->pppiQCQMFImag != NULL ) + { + int32_t n; + for ( n = 0; n < psCQMFEncoder->iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < CQMF_BLOCKS_PER_FRAME; k++ ) + { + free( psCQMFEncoder->pppiQCQMFImag[n][k] ); + } + free( psCQMFEncoder->pppiQCQMFImag[n] ); + } + free( psCQMFEncoder->pppiQCQMFImag ); + } + + + DeletePredictionEncoder( psCQMFEncoder->psPredictionEncoder ); + free( psCQMFEncoder ); + } +} + +int32_t CQMFEncoderGetError( CQMFEncoder *psCQMFEncoder ) +{ + return psCQMFEncoder->iLastError; +} + +static int32_t MSModeCalculation( const int32_t iNumBlocks, + const int32_t iNumBands, + const int32_t *piBandwidths, + float ***pppfReal, + float ***pppfImag, + int32_t *piMSMode, +#ifdef ENABLE_MS_PRED + int32_t *piLRPhaseDiff, + int32_t *piMSPredCoef, + const int32_t iAllowSidePred, +#endif + int32_t *piMSFlags ); + +static void RemoveRMSEnvelope( const int32_t iNumBands, + const int32_t *piBandwidths, + const int32_t iNumGroups, + const int32_t *piGroupLengths, + int32_t **ppiRMSEnvelope, + float **ppfReal, + float **ppfImag ); + + +static int32_t CountCQMFBits( const int32_t iNumGroups, + const int32_t *piGroupLengths, + const int32_t iNumBands, + const int32_t *piBandwidths, + const int32_t *piPredEnable, + int32_t **ppiAlloc, + int32_t **ppiQReal, + int32_t **ppiQImag ); + +/* Currently only the number of bands in frame */ +static int32_t WriteHeaderInformation( const int32_t iNumBands, + ivas_split_rend_bits_t *pBits ); + +static int32_t WritePmodInformation( const int32_t **ppiHiSMRFlags, + Bitstream *psBSWrite, + int32_t iChannels, + int32_t iNumBands ); + +static int32_t WriteMSInformation( const int32_t iNumBands, + const int32_t iMSMode, + const int32_t *piMSFlags, +#ifdef ENABLE_MS_PRED + const int32_t *piLRPhaseDiffs, + const int32_t *piMSPredCoefs, + int32_t iNumMSPredBands, +#endif + ivas_split_rend_bits_t *pBits ); + +static int32_t WriteGroupInformation( const int32_t iChannels, + const int32_t iCommonGrouping, + const int32_t *piNumGroups, + int32_t **ppiGroupLengths, + ivas_split_rend_bits_t *pBits ); + +static int32_t WriteRMSEnvelope( const int32_t iChannels, + const int32_t *piNumGroups, + const int32_t iNumBands, + int32_t ***pppiRMSEnvelope, + ivas_split_rend_bits_t *pBits ); + +static int32_t WriteAllocInformation( const int32_t iAllocOffset, + ivas_split_rend_bits_t *pBits ); + +static int32_t WriteCQMFData( const int32_t iNumGroups, + const int32_t *piGroupLengths, + const int32_t iNumBands, + const int32_t *piBandwidths, + const int32_t *piPredEnable, + int32_t **ppiAlloc, + int32_t **ppiSignReal, + int32_t **ppiSignImag, + int32_t **ppiQReal, + int32_t **ppiQImag, + ivas_split_rend_bits_t *pBits ); + +static int32_t ComputeAllocation( const int32_t iChannels, + const int32_t *piNumGroups, + int32_t **ppiGroupLengths, + const int32_t iNumBands, + const int32_t *piBandwidths, + float ***pppfReal, + float ***pppfImag, + int32_t ***pppiSMR, + const int32_t iAvailableBits, + int32_t *piAllocOffset, + int32_t ***pppiAlloc, + int32_t ***pppiQReal, + int32_t ***pppiQImag, + int32_t ***pppiSignReal, + int32_t ***pppiSignImag, + int32_t **ppiPredEnable, + float **ppfA1Real, + float **ppfA1Imag ); + +int32_t EncodeFrame( CQMFEncoder *psCQMFEncoder, float ***pppfCQMFReal, float ***pppfCQMFImag, int32_t *piBitsWritten, const int32_t available_bits, ivas_split_rend_bits_t *pBits ) +{ + int32_t n; + int32_t iAvailableBits, iBitsWritten; + // int32_t iCQMFBits; + int32_t iNumMSBands = 0; + iAvailableBits = available_bits; // HCBR for now + iBitsWritten = 0; + + /* Do MS calc here */ + if ( psCQMFEncoder->iChannels == 2 ) + { + iNumMSBands = MSModeCalculation( psCQMFEncoder->iNumBlocks, + psCQMFEncoder->iNumBands, + psCQMFEncoder->piBandwidths, + pppfCQMFReal, + pppfCQMFImag, + &psCQMFEncoder->iMSMode, +#ifdef ENABLE_MS_PRED + psCQMFEncoder->piLRPhaseDiffs, + psCQMFEncoder->piMSPredCoefs, + psCQMFEncoder->iAllowSidePred, +#endif + psCQMFEncoder->piMSFlags ); + + if ( psCQMFEncoder->iMSMode > 0 ) + { + psCQMFEncoder->iCommonGrouping = 1; // Make sure common grouping is enabled when MS is in use + } + } + +#ifdef ENABLE_PMOD_ADJUST + CalcTonQuotas( psCQMFEncoder->iChannels, psCQMFEncoder->iNumBands, psCQMFEncoder->piBandwidths, pppfCQMFReal, pppfCQMFImag, psCQMFEncoder->ppiHiSMRFlags ); +#endif + + /* Compute Grouping and RMS Envelopes */ + if ( psCQMFEncoder->iChannels == 2 && psCQMFEncoder->iCommonGrouping == 1 ) + { + ComputeEnvelopeGrouping( psCQMFEncoder->psRMSEnvelopeGrouping, + psCQMFEncoder->iChannels, + psCQMFEncoder->iNumBands, + psCQMFEncoder->piBandwidths, + pppfCQMFReal, + pppfCQMFImag, +#ifndef USE_BIT_COUNT_MERGE_COST + 8.0, + 20.0, // Use these to trade off RMS Env bits and quantizer loading +#endif + &psCQMFEncoder->piNumGroups[0], + psCQMFEncoder->ppiGroupLengths[0], + psCQMFEncoder->pppiRMSEnvelope ); + + psCQMFEncoder->piNumGroups[1] = psCQMFEncoder->piNumGroups[0]; + for ( n = 0; n < psCQMFEncoder->piNumGroups[0]; n++ ) + { + psCQMFEncoder->ppiGroupLengths[1][n] = psCQMFEncoder->ppiGroupLengths[0][n]; + } + } + else + { + for ( n = 0; n < psCQMFEncoder->iChannels; n++ ) + { + ComputeEnvelopeGrouping( psCQMFEncoder->psRMSEnvelopeGrouping, + psCQMFEncoder->iChannels, + psCQMFEncoder->iNumBands, + psCQMFEncoder->piBandwidths, + &pppfCQMFReal[n], + &pppfCQMFImag[n], +#ifndef USE_BIT_COUNT_MERGE_COST + 8.0, + 20.0, // Use these to trade off RMS Env bits and quantizer loading +#endif + &psCQMFEncoder->piNumGroups[n], + psCQMFEncoder->ppiGroupLengths[n], + &psCQMFEncoder->pppiRMSEnvelope[n] ); + } + } + + for ( n = 0; n < psCQMFEncoder->iChannels; n++ ) + { + RemoveRMSEnvelope( psCQMFEncoder->iNumBands, + psCQMFEncoder->piBandwidths, + psCQMFEncoder->piNumGroups[n], + (const int32_t *) psCQMFEncoder->ppiGroupLengths[n], + psCQMFEncoder->pppiRMSEnvelope[n], + pppfCQMFReal[n], + pppfCQMFImag[n] ); + } + + ComputePredictors( psCQMFEncoder->psPredictionEncoder, + pppfCQMFReal, + pppfCQMFImag ); + + iBitsWritten += WriteHeaderInformation( psCQMFEncoder->iNumBands, + pBits ); + + if ( psCQMFEncoder->iChannels == 2 ) + { + iBitsWritten += WriteMSInformation( psCQMFEncoder->iNumBands, + psCQMFEncoder->iMSMode, + (const int32_t *) psCQMFEncoder->piMSFlags, +#ifdef ENABLE_MS_PRED + (const int32_t *) psCQMFEncoder->piLRPhaseDiffs, + (const int32_t *) psCQMFEncoder->piMSPredCoefs, + iNumMSBands, +#endif + pBits ); + } + + + iBitsWritten += WritePredictors( psCQMFEncoder->psPredictionEncoder, + pBits ); + + iBitsWritten += WriteGroupInformation( psCQMFEncoder->iChannels, + psCQMFEncoder->iCommonGrouping, + (const int32_t *) psCQMFEncoder->piNumGroups, + psCQMFEncoder->ppiGroupLengths, + pBits ); + + iBitsWritten += WriteRMSEnvelope( psCQMFEncoder->iChannels, + (const int32_t *) psCQMFEncoder->piNumGroups, + psCQMFEncoder->iNumBands, + psCQMFEncoder->pppiRMSEnvelope, + pBits ); + +#ifdef ENABLE_PMOD_ADJUST + iBitsWritten += WritePmodInformation( psCQMFEncoder->ppiHiSMRFlags, + psCQMFEncoder->psBSWrite, + psCQMFEncoder->iChannels, + psCQMFEncoder->iNumBands ); +#endif + + if ( psCQMFEncoder->iChannels == 2 && psCQMFEncoder->iCommonGrouping == 1 ) + { + int32_t k; + for ( k = 0; k < psCQMFEncoder->piNumGroups[0]; k++ ) + { + PerceptualModelStereo( psCQMFEncoder->iNumBands, + psCQMFEncoder->piMSFlags, + psCQMFEncoder->pppiRMSEnvelope[0][k], + psCQMFEncoder->pppiRMSEnvelope[1][k], + psCQMFEncoder->pppiExcitation[0][k], + psCQMFEncoder->pppiExcitation[1][k], + psCQMFEncoder->pppiSMR[0][k], + psCQMFEncoder->pppiSMR[1][k] ); + } + } + else + { + for ( n = 0; n < psCQMFEncoder->iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < psCQMFEncoder->piNumGroups[n]; k++ ) + { + PerceptualModel( psCQMFEncoder->iNumBands, + psCQMFEncoder->pppiRMSEnvelope[n][k], + psCQMFEncoder->pppiExcitation[n][k], + psCQMFEncoder->pppiSMR[n][k] ); + } + } + } + + iAvailableBits -= iBitsWritten; + ComputeAllocation( psCQMFEncoder->iChannels, + (const int32_t *) psCQMFEncoder->piNumGroups, + psCQMFEncoder->ppiGroupLengths, + psCQMFEncoder->iNumBands, + psCQMFEncoder->piBandwidths, + pppfCQMFReal, + pppfCQMFImag, + psCQMFEncoder->pppiSMR, + iAvailableBits, + &psCQMFEncoder->iAllocOffset, + psCQMFEncoder->pppiAlloc, + psCQMFEncoder->pppiQCQMFReal, + psCQMFEncoder->pppiQCQMFImag, + psCQMFEncoder->pppiCQMFSignReal, + psCQMFEncoder->pppiCQMFSignImag, + psCQMFEncoder->psPredictionEncoder->ppiPredBandEnable, + psCQMFEncoder->psPredictionEncoder->ppfA1Real, + psCQMFEncoder->psPredictionEncoder->ppfA1Imag ); + + iBitsWritten += WriteAllocInformation( psCQMFEncoder->iAllocOffset, + pBits ); + + for ( n = 0; n < psCQMFEncoder->iChannels; n++ ) + { + iBitsWritten += WriteCQMFData( psCQMFEncoder->piNumGroups[n], + (const int32_t *) psCQMFEncoder->ppiGroupLengths[n], + psCQMFEncoder->iNumBands, + psCQMFEncoder->piBandwidths, + (const int32_t *) psCQMFEncoder->psPredictionEncoder->ppiPredBandEnable[n], + psCQMFEncoder->pppiAlloc[n], + psCQMFEncoder->pppiCQMFSignReal[n], + psCQMFEncoder->pppiCQMFSignImag[n], + psCQMFEncoder->pppiQCQMFReal[n], + psCQMFEncoder->pppiQCQMFImag[n], + pBits ); + } + *piBitsWritten = iBitsWritten; + return 0; +} + +int32_t GetNumGroups( CQMFEncoder *psCQMFEncoder ) +{ + return psCQMFEncoder->piNumGroups[0]; +} + +static int32_t MSModeCalculation( const int32_t iNumBlocks, + const int32_t iNumBands, + const int32_t *piBandwidths, + float ***pppfReal, + float ***pppfImag, + int32_t *piMSMode, +#ifdef ENABLE_MS_PRED + int32_t *piLRPhaseDiffs, + int32_t *piMSPredCoefs, + const int32_t iAllowSidePred, +#endif + int32_t *piMSFlags ) +{ + int32_t b; + int32_t iFBOffset; + int32_t iNumMSBands; +#ifdef ENABLE_MS_PRED + int32_t piMSPredFlags[MAX_BANDS] = { 0 }; + int32_t iNumMSPredBands = 0; + float msBitsReduction = 0.0f; + float msPredBitsReduction = 0.0f; + int32_t msBits; + int32_t msPredBits; + float fPred; +#if defined ENABLE_MS_PRED && defined SIMPLE_PHASE + void( *pFuncPhaseRotateOptions[4] ) = { &rot_zero, &rot_p_pi_2, &rot_pm_pi, &rot_m_pi_2 }; +#endif + const float one_by_log10_2 = 3.32192809488736f; +#endif + *piMSMode = 0; + iFBOffset = 0; + iNumMSBands = 0; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t n; + float fLeftEnergy; + float fRightEnergy; + float fMidEnergy; + float fSideEnergy; + float fLRRatio; + float fMSRatio; +#ifdef ENABLE_MS_PRED + float fMSPredRatio; + float fMidEnergyPred; + float fSideEnergyPred; + float fLRCovReal = 0.0f; + float fLRCovImag = 0.0f; + int32_t iPhase; + int32_t iPred; + int32_t tabIdx = 0; +#endif + + fLeftEnergy = 0.0f; + fRightEnergy = 0.0f; + fMidEnergy = 0.0; + fSideEnergy = 0.0; + + for ( n = 0; n < piBandwidths[b]; n++ ) + { + int32_t k; + for ( k = 0; k < iNumBlocks; k++ ) + { + float fMidReal; + float fMidImag; + float fSideReal; + float fSideImag; + + fMidReal = 0.5f * ( pppfReal[0][k][iFBOffset] + pppfReal[1][k][iFBOffset] ); + fMidImag = 0.5f * ( pppfImag[0][k][iFBOffset] + pppfImag[1][k][iFBOffset] ); + fSideReal = 0.5f * ( pppfReal[0][k][iFBOffset] - pppfReal[1][k][iFBOffset] ); + fSideImag = 0.5f * ( pppfImag[0][k][iFBOffset] - pppfImag[1][k][iFBOffset] ); + + fLeftEnergy += ( pppfReal[0][k][iFBOffset] * pppfReal[0][k][iFBOffset] + pppfImag[0][k][iFBOffset] * pppfImag[0][k][iFBOffset] ); + fRightEnergy += ( pppfReal[1][k][iFBOffset] * pppfReal[1][k][iFBOffset] + pppfImag[1][k][iFBOffset] * pppfImag[1][k][iFBOffset] ); + fMidEnergy += ( fMidReal * fMidReal + fMidImag * fMidImag ); + fSideEnergy += ( fSideReal * fSideReal + fSideImag * fSideImag ); + +#ifdef ENABLE_MS_PRED + fLRCovReal += ( pppfReal[0][k][iFBOffset] * pppfReal[1][k][iFBOffset] + pppfImag[0][k][iFBOffset] * pppfImag[1][k][iFBOffset] ); + fLRCovImag += ( pppfImag[0][k][iFBOffset] * pppfReal[1][k][iFBOffset] - pppfImag[1][k][iFBOffset] * pppfReal[0][k][iFBOffset] ); +#endif + } + + iFBOffset++; + } +#ifdef ENABLE_MS_PRED + /* compute L/R phase difference if high coherence */ + if ( fLRCovReal * fLRCovReal + fLRCovImag * fLRCovImag > 0.5f * fLeftEnergy * fRightEnergy ) + { + float fPhase = (float) atan2( fLRCovImag, fLRCovReal ); + iPhase = quantPhase( fPhase ); + } + else + { + iPhase = 0; + } + piLRPhaseDiffs[b] = iPhase; + + /* adjust covariance based on phase rotation */ +#ifdef SIMPLE_PHASE + cplxmult( &fLRCovReal, &fLRCovImag, c_afRotRealImagSimple[iPhase][0], -c_afRotRealImagSimple[iPhase][1] ); +#else + tabIdx = iPhase - PHASE_MIN_VAL; + cplxmult( &fLRCovReal, &fLRCovImag, c_afRotRealImag[tabIdx][0], -c_afRotRealImag[tabIdx][1] ); +#endif + /* compute MS prediction coefficient based on LR covariance*/ + fMidEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy + 2.0f * fLRCovReal ); + fSideEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy - 2.0f * fLRCovReal ); + + /* M/S prediction */ + fPred = fMidEnergyPred == 0.0f ? 0.0f : 0.25f * ( fLeftEnergy - fRightEnergy ) / fMidEnergyPred; + iPred = quantPred( fPred ); + fPred = dequantPred( iPred ); + piMSPredCoefs[b] = iPred; + + /* evaluation */ + fSideEnergyPred += ( fPred * fPred * fMidEnergyPred - 2.0f * fPred * 0.25f * ( fLeftEnergy - fRightEnergy ) ); + /* -= fPred * fPred * fMidEnergyPred doesn't work because fPred is quantized and does not match MS/MM exactly */ + fMSPredRatio = (float) log10f( ( fMidEnergyPred + 1e-12f ) / ( fSideEnergyPred + 1e-12f ) ); +#endif + fLeftEnergy = log10f( fLeftEnergy + 1e-12f ); + fRightEnergy = log10f( fRightEnergy + 1e-12f ); + fMidEnergy = log10f( fMidEnergy + 1e-12f ); + fSideEnergy = log10f( fSideEnergy + 1e-12f ); + + if ( fLeftEnergy > fRightEnergy ) + { + fLRRatio = fLeftEnergy - fRightEnergy; + } + else + { + fLRRatio = fRightEnergy - fLeftEnergy; + } + + if ( fMidEnergy > fSideEnergy ) + { + fMSRatio = fMidEnergy - fSideEnergy; + } + else + { + fMSRatio = fSideEnergy - fMidEnergy; + } + + if ( fMSRatio > fLRRatio ) + { + iNumMSBands++; + piMSFlags[b] = 1; + } + else + { + piMSFlags[b] = 0; + } +#ifdef ENABLE_MS_PRED + if ( fMSRatio > fLRRatio ) + { + float maskThresShift_dB_by_10 = ( fMSRatio - fLRRatio ) * (float) c_aiDefaultTheta48[b] / 16.0f; + msBitsReduction += (float) ( piBandwidths[b] * iNumBlocks * 2 ) * one_by_log10_2 * maskThresShift_dB_by_10; /* * 2 for real/imag */ + } + if ( fMSPredRatio > fLRRatio ) + { + float maskThresShift_dB_by_10 = ( fMSPredRatio - fLRRatio ) * (float) c_aiDefaultTheta48[b] / 16.0f; + msPredBitsReduction += (float) ( piBandwidths[b] * iNumBlocks * 2 ) * one_by_log10_2 * maskThresShift_dB_by_10; + iNumMSPredBands++; + piMSPredFlags[b] = 1; + } + else + { + piMSPredFlags[b] = 0; + } +#endif + } + +#ifdef ENABLE_MS_PRED + msPredBits = CountMSBits( iNumBands, 3, piMSPredFlags, piLRPhaseDiffs, piMSPredCoefs ); + msPredBitsReduction = max( msPredBitsReduction - (float) msPredBits, 0.0f ); + msBits = CountMSBits( iNumBands, 2, piMSFlags, NULL, NULL ); + msBitsReduction = max( msBitsReduction - (float) msBits, 0.0f ); +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid = 0; + if ( !fid ) + { + fid = fopen( "bit_red.txt", "wt" ); + } + fprintf( fid, "%.1f %.1f %d %d\n", msBitsReduction, msPredBitsReduction, msBits, msPredBits ); + } +#endif + if ( iAllowSidePred && msPredBitsReduction > 1.1f * msBitsReduction ) + { + *piMSMode = 3; + for ( b = 0; b < iNumBands; b++ ) + { + piMSFlags[b] = piMSPredFlags[b]; + } + iNumMSBands = iNumMSPredBands; + } + else +#endif + if ( iNumMSBands == iNumBands ) + { + *piMSMode = 1; + } + else if ( iNumMSBands > 0 ) + { + *piMSMode = 2; + } + else + { + *piMSMode = 0; + } + + if ( *piMSMode > 0 ) + { + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { +#if defined ENABLE_MS_PRED && defined SIMPLE_PHASE + void ( *pFuncPhaseRotate )( float *, float * ) = pFuncPhaseRotateOptions[piLRPhaseDiffs[b]]; +#endif + if ( piMSFlags[b] == 1 ) + { + int32_t n; + for ( n = 0; n < piBandwidths[b]; n++ ) + { + int32_t k; + for ( k = 0; k < iNumBlocks; k++ ) + { + float fMidReal; + float fMidImag; + float fSideReal; + float fSideImag; +#ifdef ENABLE_MS_PRED + if ( *piMSMode == 3 ) + { +#ifdef SIMPLE_PHASE + ( *pFuncPhaseRotate )( &pppfReal[1][k][iFBOffset], &pppfImag[1][k][iFBOffset] ); +#else + int32_t phaseIdx; + + phaseIdx = piLRPhaseDiffs[b] - PHASE_MIN_VAL; + cplxmult( &pppfReal[1][k][iFBOffset], &pppfImag[1][k][iFBOffset], c_afRotRealImag[phaseIdx][0], c_afRotRealImag[phaseIdx][1] ); +#endif + } +#endif + fMidReal = 0.5f * ( pppfReal[0][k][iFBOffset] + pppfReal[1][k][iFBOffset] ); + fMidImag = 0.5f * ( pppfImag[0][k][iFBOffset] + pppfImag[1][k][iFBOffset] ); + fSideReal = 0.5f * ( pppfReal[0][k][iFBOffset] - pppfReal[1][k][iFBOffset] ); + fSideImag = 0.5f * ( pppfImag[0][k][iFBOffset] - pppfImag[1][k][iFBOffset] ); +#ifdef ENABLE_MS_PRED + if ( *piMSMode == 3 ) + { + fPred = dequantPred( piMSPredCoefs[b] ); + fSideReal -= fPred * fMidReal; + fSideImag -= fPred * fMidImag; + } +#endif + pppfReal[0][k][iFBOffset] = fMidReal; + pppfReal[1][k][iFBOffset] = fSideReal; + pppfImag[0][k][iFBOffset] = fMidImag; + pppfImag[1][k][iFBOffset] = fSideImag; + } + iFBOffset++; + } + } + else + { + iFBOffset += piBandwidths[b]; + } + } + } +#ifdef ENABLE_MS_PRED +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid = 0; + if ( !fid ) + { + fid = fopen( "ms_mode_enc_raw.txt", "wt" ); + } + writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumBands, iNumBands, fid, piMSFlags ); + } +#endif + if ( *piMSMode == 3 ) + { + /* Differential Coding of Phase Data*/ + PrepEncode( piLRPhaseDiffs, piMSFlags, iNumBands ); + PrepEncode( piMSPredCoefs, piMSFlags, iNumBands ); +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid = 0; + if ( !fid ) + { + fid = fopen( "ms_mode_enc.txt", "wt" ); + } + writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags ); + } +#endif + /* Differential Coding*/ +#ifndef SIMPLE_PHASE + EncodePhase( piLRPhaseDiffs, iNumMSBands, PHASE_DIFF_DIM ); +#endif + EncodePredCoef( piMSPredCoefs, iNumMSBands ); +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid = 0; + if ( !fid ) + { + fid = fopen( "ms_mode_enc_diff.txt", "wt" ); + } + writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags ); + } +#endif + } +#endif + + return iNumMSBands; +} + +static void RemoveRMSEnvelope( const int32_t iNumBands, + const int32_t *piBandwidths, + const int32_t iNumGroups, + const int32_t *piGroupLengths, + int32_t **ppiRMSEnvelope, + float **ppfReal, + float **ppfImag ) +{ + int32_t n; + int32_t iBlockOffset; + + iBlockOffset = 0; + for ( n = 0; n < iNumGroups; n++ ) + { + int32_t k; + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + int32_t b; + int32_t iFBOffset; + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t m; + int32_t iRMSEnv; + float fGain; + + iRMSEnv = ppiRMSEnvelope[n][b]; + fGain = c_afRMSEnvReconstructTable[ENV_RECONSTRUCT_TABLE_CENTER - iRMSEnv]; + for ( m = 0; m < piBandwidths[b]; m++ ) + { + ppfReal[iBlockOffset][iFBOffset] *= fGain; + ppfImag[iBlockOffset][iFBOffset] *= fGain; + iFBOffset++; + } + } + iBlockOffset++; + } + } +} + +static void QuantizeSpectrumDPCM_Opt( const int32_t iNumGroups, + const int32_t *piGroupLengths, + const int32_t iNumBands, + const int32_t *piBandwidths, + int32_t **ppiAlloc, + float **ppfReal, + float **ppfImag, + int32_t **ppiQReal, + int32_t **ppiQImag, + int32_t **ppiSignReal, + int32_t **ppiSignImag, + int32_t *piPredEnable, + float *pfA1Real, + float *pfA1Imag ) // Pass in 2 previous value buffers NULLABLE +{ + + int32_t b; + int32_t iFBOffset; + + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t m; + for ( m = 0; m < piBandwidths[b]; m++ ) + { + int32_t n; + int32_t iBlockOffset; + float fPrevReal; + float fPrevImag; + + iBlockOffset = 0; + fPrevReal = 0.0; + fPrevImag = 0.0; + for ( n = 0; n < iNumGroups; n++ ) + { + int32_t k; + int32_t iAlloc; + int32_t iMaxQuantVal; + float fSCFGain; + float fInvSCFGain; + + + iAlloc = ppiAlloc[n][b]; + iMaxQuantVal = c_aiQuantMaxValues[iAlloc]; + fSCFGain = c_afScaleFactor[iAlloc]; + fInvSCFGain = c_afInvScaleFactor[iAlloc]; + + if ( piPredEnable[iFBOffset] == 1 ) + { + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + int32_t iQuantValue; + float fPredReal = 0.0; + float fPredImag = 0.0; + float fVal; + + fPredReal = pfA1Real[iFBOffset] * fPrevReal - pfA1Imag[iFBOffset] * fPrevImag; + fPredImag = pfA1Real[iFBOffset] * fPrevImag + pfA1Imag[iFBOffset] * fPrevReal; + + fVal = ppfReal[iBlockOffset][iFBOffset] + fPredReal; + if ( fVal > 0.0 ) + { + iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); + ppiSignReal[iBlockOffset][iFBOffset] = 0; + } + else + { + iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); + ppiSignReal[iBlockOffset][iFBOffset] = 1; + } + iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; + + ppiQReal[iBlockOffset][iFBOffset] = iQuantValue; + + fVal = ppfImag[iBlockOffset][iFBOffset] + fPredImag; + if ( fVal > 0.0 ) + { + iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); + ppiSignImag[iBlockOffset][iFBOffset] = 0; + } + else + { + iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); + ppiSignImag[iBlockOffset][iFBOffset] = 1; + } + + iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; + ppiQImag[iBlockOffset][iFBOffset] = iQuantValue; + + + if ( ppiSignReal[iBlockOffset][iFBOffset] == 0 ) + { + fPrevReal = fInvSCFGain * (float) ppiQReal[iBlockOffset][iFBOffset] - fPredReal; + } + else + { + fPrevReal = -fInvSCFGain * (float) ppiQReal[iBlockOffset][iFBOffset] - fPredReal; + } + if ( ppiSignImag[iBlockOffset][iFBOffset] == 0 ) + { + fPrevImag = fInvSCFGain * (float) ppiQImag[iBlockOffset][iFBOffset] - fPredImag; + } + else + { + fPrevImag = -fInvSCFGain * (float) ppiQImag[iBlockOffset][iFBOffset] - fPredImag; + } + + iBlockOffset++; + } + } + else + { + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + int32_t iQuantValue; + float fVal; + + fVal = ppfReal[iBlockOffset][iFBOffset]; + if ( fVal > 0.0 ) + { + iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); + ppiSignReal[iBlockOffset][iFBOffset] = 0; + } + else + { + iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); + ppiSignReal[iBlockOffset][iFBOffset] = 1; + } + iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; + + ppiQReal[iBlockOffset][iFBOffset] = iQuantValue; + + fVal = ppfImag[iBlockOffset][iFBOffset]; + if ( fVal > 0.0 ) + { + iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); + ppiSignImag[iBlockOffset][iFBOffset] = 0; + } + else + { + iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); + ppiSignImag[iBlockOffset][iFBOffset] = 1; + } + iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; + ppiQImag[iBlockOffset][iFBOffset] = iQuantValue; + iBlockOffset++; + } + } + } + + iFBOffset++; + } + } +} + +static void QuantizeSpectrumDPCM( const int32_t iNumGroups, + const int32_t *piGroupLengths, + const int32_t iNumBands, + const int32_t *piBandwidths, + int32_t **ppiAlloc, + float **ppfReal, + float **ppfImag, + int32_t **ppiQReal, + int32_t **ppiQImag, + int32_t **ppiSignReal, + int32_t **ppiSignImag, + int32_t *piPredEnable, + float *pfA1Real, + float *pfA1Imag ) // Pass in 2 previous value buffers NULLABLE +{ + int32_t b; + int32_t iFBOffset; + + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t m; + for ( m = 0; m < piBandwidths[b]; m++ ) + { + int32_t n; + int32_t iBlockOffset; + float fPrevReal; + float fPrevImag; + + iBlockOffset = 0; + fPrevReal = 0.0; + fPrevImag = 0.0; + for ( n = 0; n < iNumGroups; n++ ) + { + int32_t k; + int32_t iAlloc; + int32_t iMaxQuantVal; + float fSCFGain; + float fInvSCFGain; + + + iAlloc = ppiAlloc[n][b]; + iMaxQuantVal = c_aiQuantMaxValues[iAlloc]; + fSCFGain = c_afScaleFactor[iAlloc]; + fInvSCFGain = c_afInvScaleFactor[iAlloc]; + + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + int32_t iQuantValue; + float fPredReal = 0.0; + float fPredImag = 0.0; + float fVal; + + if ( piPredEnable[iFBOffset] == 1 ) + { + fPredReal = pfA1Real[iFBOffset] * fPrevReal - pfA1Imag[iFBOffset] * fPrevImag; + fPredImag = pfA1Real[iFBOffset] * fPrevImag + pfA1Imag[iFBOffset] * fPrevReal; + } + else + { // don't need + fPredReal = 0.0; + fPredImag = 0.0; + } + + fVal = ppfReal[iBlockOffset][iFBOffset] + fPredReal; + if ( fVal > 0.0 ) + { + iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); + ppiSignReal[iBlockOffset][iFBOffset] = 0; + } + else + { + iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); + ppiSignReal[iBlockOffset][iFBOffset] = 1; + } +#ifdef _DEBUG_VERBOSE + if ( iQuantValue > iMaxQuantVal ) + { + printf( "Value out of range %d\t%d\t%d\t%d\n", b, iAlloc, iQuantValue, iMaxQuantVal ); + iQuantValue = iMaxQuantVal; + } +#else + iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; +#endif + + ppiQReal[iBlockOffset][iFBOffset] = iQuantValue; + + fVal = ppfImag[iBlockOffset][iFBOffset] + fPredImag; + if ( fVal > 0.0 ) + { + iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); + ppiSignImag[iBlockOffset][iFBOffset] = 0; + } + else + { + iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); + ppiSignImag[iBlockOffset][iFBOffset] = 1; + } + +#ifdef _DEBUG_VERBOSE + if ( iQuantValue > iMaxQuantVal ) + { + printf( "Value out of range %d\t%d\t%d\t%d\n", b, iAlloc, iQuantValue, iMaxQuantVal ); + iQuantValue = iMaxQuantVal; + } +#else + iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; +#endif + ppiQImag[iBlockOffset][iFBOffset] = iQuantValue; + + if ( piPredEnable[iFBOffset] == 1 ) + { + if ( ppiSignReal[iBlockOffset][iFBOffset] == 0 ) + { + fPrevReal = fInvSCFGain * (float) ppiQReal[iBlockOffset][iFBOffset] - fPredReal; + } + else + { + fPrevReal = -fInvSCFGain * (float) ppiQReal[iBlockOffset][iFBOffset] - fPredReal; + } + if ( ppiSignImag[iBlockOffset][iFBOffset] == 0 ) + { + fPrevImag = fInvSCFGain * (float) ppiQImag[iBlockOffset][iFBOffset] - fPredImag; + } + else + { + fPrevImag = -fInvSCFGain * (float) ppiQImag[iBlockOffset][iFBOffset] - fPredImag; + } + } + else + { // don't need + fPrevReal = 0.0; + fPrevImag = 0.0; + } + + iBlockOffset++; + } + } + + iFBOffset++; + } + } +} + +static int32_t CountCQMFBits( const int32_t iNumGroups, + const int32_t *piGroupLengths, + const int32_t iNumBands, + const int32_t *piBandwidths, + const int32_t *piPredEnable, + int32_t **ppiAlloc, + int32_t **ppiQReal, + int32_t **ppiQImag ) +{ + int32_t n; + int32_t iBits; + int32_t iBlockOffest; + + iBits = 0; + iBlockOffest = 0; + for ( n = 0; n < iNumGroups; n++ ) + { + int32_t k; + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + int32_t b; + int32_t iFBOffset; + + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t m; + int32_t iAlloc; + int32_t iHuffDim; + int32_t iHuffMod; + + iAlloc = ppiAlloc[n][b]; + + iHuffDim = c_aiHuffmanDim[iAlloc]; + iHuffMod = c_aiHuffmanMod[iAlloc]; + + + if ( iAlloc > 0 ) + { +#ifndef ROM_TO_RAM + const uint32_t( *pauiHuffmanTable )[2] = NULL; + const uint32_t( *pauiHuffmanTableDPCM )[2] = NULL; +#else + const uint16_t( *pauiHuffmanTable )[2] = NULL; + const uint16_t( *pauiHuffmanTableDPCM )[2] = NULL; +#endif + // pauiHuffmanTable = GetHuffEncTable(iAlloc); + pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc]; + pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc]; + for ( m = 0; m < piBandwidths[b]; m++ ) + { + int32_t iQuantValue1; + int32_t iQuantValue2; + + iQuantValue1 = ppiQReal[iBlockOffest][iFBOffset]; + iQuantValue2 = ppiQImag[iBlockOffest][iFBOffset]; + + iBits += ( iQuantValue1 > 0 ) ? 1 : 0; // Sign bit for vals > 0 + iBits += ( iQuantValue2 > 0 ) ? 1 : 0; // Sign bit for vals > 0 + + if ( piPredEnable[iFBOffset] == 1 ) + { + if ( iHuffDim == 2 ) + { + iQuantValue1 *= iHuffMod; + iQuantValue1 += iQuantValue2; + iBits += pauiHuffmanTableDPCM[iQuantValue1][0]; + } + else + { + iBits += pauiHuffmanTableDPCM[iQuantValue1][0]; + iBits += pauiHuffmanTableDPCM[iQuantValue2][0]; + } + } + else + { + if ( iHuffDim == 2 ) + { + iQuantValue1 *= iHuffMod; + iQuantValue1 += iQuantValue2; + iBits += pauiHuffmanTable[iQuantValue1][0]; + } + else + { + iBits += pauiHuffmanTable[iQuantValue1][0]; + iBits += pauiHuffmanTable[iQuantValue2][0]; + } + } + + iFBOffset++; + } + } + else + { + iFBOffset += piBandwidths[b]; + } + } + + iBlockOffest++; + } + } + + return iBits; +} + +/* Currently only the number of bands in frame */ +static int32_t WriteHeaderInformation( const int32_t iNumBands, + ivas_split_rend_bits_t *pBits ) +{ + int32_t iBitsWritten; + + iBitsWritten = 0; + ivas_split_rend_bitstream_write_int32( pBits, iNumBands, 5 ); + iBitsWritten += 5; + + return iBitsWritten; +} + +static int32_t WriteMSInformation( const int32_t iNumBands, + const int32_t iMSMode, + const int32_t *piMSFlags, +#ifdef ENABLE_MS_PRED + const int32_t *piLRPhaseDiff, + const int32_t *piMSPredCoef, + int32_t iNumMSPredBands, +#endif + ivas_split_rend_bits_t *pBits ) +{ + int32_t iBitsWritten; +#ifdef ENABLE_MS_PRED + int32_t iMSPredAll = ( iNumMSPredBands == iNumBands ); +#ifdef DEBUG_WRITE_MS_PRED + int32_t iBitsWrittenTmp = 0; +#endif +#endif + iBitsWritten = 0; + ivas_split_rend_bitstream_write_int32( pBits, iMSMode, 2 ); + iBitsWritten += 2; +#ifdef ENABLE_MS_PRED + if ( iMSMode == 3 ) + { + ivas_split_rend_bitstream_write_int32( pBits, iMSPredAll, 1 ); + iBitsWritten += 1; + } + if ( iMSMode == 2 || ( iMSMode == 3 && !iMSPredAll ) ) +#else + if ( iMSMode == 2 ) +#endif + { + int32_t n; + for ( n = 0; n < iNumBands; n++ ) + { + ivas_split_rend_bitstream_write_int32( pBits, piMSFlags[n], 1 ); + iBitsWritten += 1; + } + } +#ifdef ENABLE_MS_PRED +#ifdef DEBUG_WRITE_MS_PRED + iBitsWrittenTmp = iBitsWritten; +#endif + if ( iMSMode == 3 ) + { + int32_t b; + int32_t anyNonZero; + anyNonZero = 0; + for ( b = 0; b < iNumMSPredBands; b++ ) + { + if ( piLRPhaseDiff[b] != 0 ) + { + anyNonZero = 1; + break; + } + } + ivas_split_rend_bitstream_write_int32( pBits, anyNonZero, 1 ); + iBitsWritten++; + if ( anyNonZero ) + { +#ifdef SIMPLE_PHASE + for ( b = 0; b < iNumMSPredBands; b++ ) + { + BSPutBits( psBSWrite, piLRPhaseDiff[b], SIMPLE_PHASE_BITS ); + iBitsWritten += SIMPLE_PHASE_BITS; + } +#else + ivas_split_rend_bitstream_write_int32( + pBits, piLRPhaseDiff[0] - PHASE_MIN_VAL, PHASE_BAND0_BITS ); + iBitsWritten += PHASE_BAND0_BITS; + for ( b = 1; b < iNumMSPredBands; b++ ) + { + int32_t tabIdx = piLRPhaseDiff[b] - ENV_DELTA_MIN; + ivas_split_rend_bitstream_write_int32( + pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], + c_aaiRMSEnvHuffEnc[tabIdx][0] ); + iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; + } +#endif + } + anyNonZero = 0; + for ( b = 0; b < iNumMSPredBands; b++ ) + { + if ( piMSPredCoef[b] != 0 ) + { + anyNonZero = 1; + break; + } + } + ivas_split_rend_bitstream_write_int32( pBits, anyNonZero, + 1 ); + iBitsWritten++; + if ( anyNonZero ) + { + ivas_split_rend_bitstream_write_int32( + pBits, piMSPredCoef[0] - PRED_MIN_VAL, PRED_BAND0_BITS ); + iBitsWritten += PRED_BAND0_BITS; + for ( b = 1; b < iNumMSPredBands; b++ ) + { + int32_t tabIdx = piMSPredCoef[b] - ENV_DELTA_MIN; + ivas_split_rend_bitstream_write_int32( + pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], + c_aaiRMSEnvHuffEnc[tabIdx][0] ); + iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; + } + } + } +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid = 0; + if ( !fid ) + { + fid = fopen( "ms_pred_bitrate.txt", "wt" ); + } + fprintf( fid, "%f\n", (float) ( ( iBitsWritten - iBitsWrittenTmp ) * ( iMSMode == 3 ) * 50 ) / 1000.0f ); /*kb/s*/ + } +#endif +#endif + + return iBitsWritten; +} + +static int32_t WriteGroupInformation( const int32_t iChannels, + const int32_t iCommonGrouping, + const int32_t *piNumGroups, + int32_t **ppiGroupLengths, + ivas_split_rend_bits_t *pBits ) +{ + int32_t iBitsWritten; + + iBitsWritten = 0; + if ( iChannels == 2 && iCommonGrouping == 1 ) + { + int32_t n; + ivas_split_rend_bitstream_write_int32( pBits, iCommonGrouping, + 1 ); + iBitsWritten += 1; + + for ( n = 0; n < piNumGroups[0]; n++ ) + { + int32_t k; + for ( k = 1; k < ppiGroupLengths[0][n]; k++ ) + { + ivas_split_rend_bitstream_write_int32( pBits, 0, 1 ); + iBitsWritten += 1; + } + if ( n < ( piNumGroups[0] - 1 ) ) + { + ivas_split_rend_bitstream_write_int32( pBits, 1, 1 ); + iBitsWritten += 1; + } + } + } + else if ( iChannels == 2 ) + { + int32_t c; + ivas_split_rend_bitstream_write_int32( pBits, iCommonGrouping, 1 ); + iBitsWritten += 1; + + for ( c = 0; c < iChannels; c++ ) + { + int32_t n; + + for ( n = 0; n < piNumGroups[c]; n++ ) + { + int32_t k; + for ( k = 1; k < ppiGroupLengths[c][n]; k++ ) + { + ivas_split_rend_bitstream_write_int32( pBits, 0, + 1 ); + iBitsWritten += 1; + } + if ( n < ( piNumGroups[c] - 1 ) ) + { + ivas_split_rend_bitstream_write_int32( pBits, 1, 1 ); + iBitsWritten += 1; + } + } + } + } + else + { + int32_t c; + + for ( c = 0; c < iChannels; c++ ) + { + int32_t n; + + for ( n = 0; n < piNumGroups[c]; n++ ) + { + int32_t k; + for ( k = 1; k < ppiGroupLengths[c][n]; k++ ) + { + ivas_split_rend_bitstream_write_int32( pBits, 0, 1 ); + iBitsWritten += 1; + } + if ( n < ( piNumGroups[c] - 1 ) ) + { + ivas_split_rend_bitstream_write_int32( pBits, 1, 1 ); + iBitsWritten += 1; + } + } + } + } + + return iBitsWritten; +} + +static int32_t WriteRMSEnvelope( const int32_t iChannels, + const int32_t *piNumGroups, + const int32_t iNumBands, + int32_t ***pppiRMSEnvelope, + ivas_split_rend_bits_t *pBits ) +{ + int32_t n; + int32_t iBitsWritten; + + iBitsWritten = 0; + for ( n = 0; n < iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < piNumGroups[n]; k++ ) + { + int32_t b; + int32_t iLastRMSVal; + + iLastRMSVal = pppiRMSEnvelope[n][k][0]; + iLastRMSVal = ( iLastRMSVal > ENV_MIN ) ? iLastRMSVal : ENV_MIN; + iLastRMSVal = ( iLastRMSVal < ENV_MAX ) ? iLastRMSVal : ENV_MAX; + ivas_split_rend_bitstream_write_int32( pBits, ( iLastRMSVal - ENV_MIN ), ENV0_BITS ); + iBitsWritten += ENV0_BITS; + + for ( b = 1; b < iNumBands; b++ ) + { + int32_t iDelta; + + iDelta = pppiRMSEnvelope[n][k][b] - iLastRMSVal; + iDelta = ( iDelta > ENV_DELTA_MIN ) ? iDelta : ENV_DELTA_MIN; + iDelta = ( iDelta < ENV_DELTA_MAX ) ? iDelta : ENV_DELTA_MAX; + iDelta -= ENV_DELTA_MIN; + ivas_split_rend_bitstream_write_int32( + pBits, c_aaiRMSEnvHuffEnc[iDelta][1], + c_aaiRMSEnvHuffEnc[iDelta][0] ); + iBitsWritten += c_aaiRMSEnvHuffEnc[iDelta][0]; + + iLastRMSVal = pppiRMSEnvelope[n][k][b]; + } + } + } + + return iBitsWritten; +} + +#ifdef ENABLE_PMOD_ADJUST +static int32_t WritePmodInformation( const int32_t **ppiHiSMRFlags, Bitstream *psBSWrite, int32_t iChannels, int32_t iNumBands ) +{ + int32_t iBitsWritten, c, b; + + iBitsWritten = 0; + + for ( c = 0; c < iChannels; c++ ) + { + int32_t anyNonZero = 0; + const int32_t *flags = ppiHiSMRFlags[c]; + for ( b = 0; b < iNumBands; b++ ) + { + if ( flags[b] ) + { + anyNonZero = 1; + break; + } + } + BSPutBits( psBSWrite, anyNonZero, 1 ); + iBitsWritten += 1; + if ( anyNonZero ) + { + for ( b = 0; b < iNumBands; b++ ) + { + BSPutBits( psBSWrite, flags[b], 1 ); + iBitsWritten += 1; + } + } + } +#ifdef WRITE_HISMR_FLAGS + { + static FILE *fid = 0; + if ( !fid ) + { + fid = fopen( "hismr_enc.txt", "wt" ); + } + for ( c = 0; c < iChannels; c++ ) + { + int32_t b; + for ( b = 0; b < iNumBands; b++ ) + { + if ( c == iChannels - 1 && b == iNumBands - 1 ) + { + fprintf( fid, "%d\n", ppiHiSMRFlags[c][b] ); + } + else + { + fprintf( fid, "%d ", ppiHiSMRFlags[c][b] ); + } + } + } + } +#endif + + return iBitsWritten; +} +#endif + +static int32_t WriteAllocInformation( const int32_t iAllocOffset, + ivas_split_rend_bits_t *pBits ) +{ + int32_t iBitsWritten; + + iBitsWritten = 0; + + if ( iAllocOffset < MIN_ALLOC_OFFSET || iAllocOffset > MAX_ALLOC_OFFSET ) + { + printf( "Serious error\n" ); + } + ivas_split_rend_bitstream_write_int32( pBits, + ( iAllocOffset - MIN_ALLOC_OFFSET ), ALLOC_OFFSET_BITS ); + iBitsWritten += ALLOC_OFFSET_BITS; + + return iBitsWritten; +} + +static int32_t WriteCQMFData( const int32_t iNumGroups, + const int32_t *piGroupLengths, + const int32_t iNumBands, + const int32_t *piBandwidths, + const int32_t *piPredEnable, + int32_t **ppiAlloc, + int32_t **ppiSignReal, + int32_t **ppiSignImag, + int32_t **ppiQReal, + int32_t **ppiQImag, + ivas_split_rend_bits_t *pBits ) +{ + int32_t n; + int32_t iBitsWritten; + int32_t iBlockOffest; + + iBitsWritten = 0; + iBlockOffest = 0; + + + for ( n = 0; n < iNumGroups; n++ ) + { + int32_t k; + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + int32_t b; + int32_t iFBOffset; + + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t m; + int32_t iAlloc; + int32_t iHuffDim; + int32_t iHuffMod; + + iAlloc = ppiAlloc[n][b]; + + iHuffDim = c_aiHuffmanDim[iAlloc]; + iHuffMod = c_aiHuffmanMod[iAlloc]; + + + if ( iAlloc > 0 ) + { +#ifndef ROM_TO_RAM + const uint32_t( *pauiHuffmanTable )[2] = NULL; + const uint32_t( *pauiHuffmanTableDPCM )[2] = NULL; +#else + const uint16_t( *pauiHuffmanTable )[2] = NULL; + const uint16_t( *pauiHuffmanTableDPCM )[2] = NULL; +#endif + // pauiHuffmanTable = GetHuffEncTable(iAlloc); + pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc]; + pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc]; + for ( m = 0; m < piBandwidths[b]; m++ ) + { + int32_t iQuantValue1; + int32_t iQuantValue2; + + iQuantValue1 = ppiQReal[iBlockOffest][iFBOffset]; + iQuantValue2 = ppiQImag[iBlockOffest][iFBOffset]; + + if ( piPredEnable[iFBOffset] == 1 ) + { + if ( iHuffDim == 2 ) + { + int32_t iSymbol; + iSymbol = iQuantValue1; + iSymbol *= iHuffMod; + iSymbol += iQuantValue2; + ivas_split_rend_bitstream_write_int32( + pBits, pauiHuffmanTableDPCM[iSymbol][1], + pauiHuffmanTableDPCM[iSymbol][0] ); + iBitsWritten += pauiHuffmanTableDPCM[iSymbol][0]; + } + else + { + ivas_split_rend_bitstream_write_int32( + pBits, pauiHuffmanTableDPCM[iQuantValue1][1], + pauiHuffmanTableDPCM[iQuantValue1][0] ); + iBitsWritten += pauiHuffmanTableDPCM[iQuantValue1][0]; + + ivas_split_rend_bitstream_write_int32( + pBits, + pauiHuffmanTableDPCM[iQuantValue2][1], + pauiHuffmanTableDPCM[iQuantValue2][0] ); + iBitsWritten += pauiHuffmanTableDPCM[iQuantValue2][0]; + } + } + else + { + if ( iHuffDim == 2 ) + { + int32_t iSymbol; + iSymbol = iQuantValue1; + iSymbol *= iHuffMod; + iSymbol += iQuantValue2; + ivas_split_rend_bitstream_write_int32( + pBits, pauiHuffmanTable[iSymbol][1], + pauiHuffmanTable[iSymbol][0] ); + iBitsWritten += pauiHuffmanTable[iSymbol][0]; + } + else + { + ivas_split_rend_bitstream_write_int32( + pBits, pauiHuffmanTable[iQuantValue1][1], + pauiHuffmanTable[iQuantValue1][0] ); + iBitsWritten += pauiHuffmanTable[iQuantValue1][0]; + + ivas_split_rend_bitstream_write_int32( + pBits, pauiHuffmanTable[iQuantValue2][1], + pauiHuffmanTable[iQuantValue2][0] ); + iBitsWritten += pauiHuffmanTable[iQuantValue2][0]; + } + } + + if ( iQuantValue1 > 0 ) + { + ivas_split_rend_bitstream_write_int32( + pBits, ppiSignReal[iBlockOffest][iFBOffset], + 1 ); + iBitsWritten += 1; + } + if ( iQuantValue2 > 0 ) + { + ivas_split_rend_bitstream_write_int32( + pBits, ppiSignImag[iBlockOffest][iFBOffset], 1 ); + iBitsWritten += 1; + } + + iFBOffset++; + } + } + else + { + iFBOffset += piBandwidths[b]; + } + } + + iBlockOffest++; + } + } + + return iBitsWritten; +} + +static int32_t ComputeAllocation( const int32_t iChannels, + const int32_t *piNumGroups, + int32_t **ppiGroupLengths, + const int32_t iNumBands, + const int32_t *piBandwidths, + float ***pppfReal, + float ***pppfImag, + int32_t ***pppiSMR, + const int32_t iAvailableBits, + int32_t *piAllocOffset, + int32_t ***pppiAlloc, + int32_t ***pppiQReal, + int32_t ***pppiQImag, + int32_t ***pppiSignReal, + int32_t ***pppiSignImag, + int32_t **ppiPredEnable, + float **ppfA1Real, + float **ppfA1Imag ) +{ + int32_t iBitsUsed; + int32_t iDone; + int32_t iDelta; + + iBitsUsed = ALLOC_OFFSET_BITS; // Bits used for Alloc Offset + + iDone = 0; + iDelta = -MIN_ALLOC_OFFSET; + *piAllocOffset = 0; + + while ( iDone == 0 ) + { + int32_t n; + int32_t iLimitAllocOffset; + iBitsUsed = ALLOC_OFFSET_BITS; + + iLimitAllocOffset = *piAllocOffset; + iLimitAllocOffset = ( iLimitAllocOffset > MIN_ALLOC_OFFSET ) ? iLimitAllocOffset : MIN_ALLOC_OFFSET; + iLimitAllocOffset = ( iLimitAllocOffset < MAX_ALLOC_OFFSET ) ? iLimitAllocOffset : MAX_ALLOC_OFFSET; + + for ( n = 0; n < iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < piNumGroups[n]; k++ ) + { + int32_t b; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t iAlloc; + iAlloc = ( ( pppiSMR[n][k][b] + iLimitAllocOffset * ALLOC_OFFSET_SCALE ) >> 5 ); + iAlloc = ( iAlloc > MIN_ALLOC ) ? iAlloc : MIN_ALLOC; + iAlloc = ( iAlloc < MAX_ALLOC ) ? iAlloc : MAX_ALLOC; + pppiAlloc[n][k][b] = iAlloc; + } + } +#ifdef OPTIMIZE_DPCM_QUANT + QuantizeSpectrumDPCM_Opt( piNumGroups[n], + (const int32_t *) ppiGroupLengths[n], + iNumBands, + piBandwidths, + pppiAlloc[n], + pppfReal[n], + pppfImag[n], + pppiQReal[n], + pppiQImag[n], + pppiSignReal[n], + pppiSignImag[n], + ppiPredEnable[n], + ppfA1Real[n], + ppfA1Imag[n] ); +#else + QuantizeSpectrumDPCM( piNumGroups[n], + (const int32_t *) ppiGroupLengths[n], + iNumBands, + piBandwidths, + pppiAlloc[n], + pppfReal[n], + pppfImag[n], + pppiQReal[n], + pppiQImag[n], + pppiSignReal[n], + pppiSignImag[n], + ppiPredEnable[n], + ppfA1Real[n], + ppfA1Imag[n] ); +#endif + + iBitsUsed += CountCQMFBits( piNumGroups[n], + (const int32_t *) ppiGroupLengths[n], + iNumBands, + piBandwidths, + (const int32_t *) ppiPredEnable[n], + pppiAlloc[n], + pppiQReal[n], + pppiQImag[n] ); + } + + if ( *piAllocOffset <= MIN_ALLOC_OFFSET && iBitsUsed > iAvailableBits ) + { +#ifdef DEBUG_VERBOSE + printf( "Frame can not be coded with the number of bits available\n" ); +#endif + // iLastError = ENC_ERROR_STREAM_FAILURE; + return -1; + } + else if ( *piAllocOffset >= MAX_ALLOC_OFFSET && iBitsUsed < iAvailableBits ) + { + *piAllocOffset = MAX_ALLOC_OFFSET; + iDone++; + } + else + { + if ( iDelta == 0 && iBitsUsed > iAvailableBits ) + { + iDelta = 1; + } + else if ( iDelta == 0 && iBitsUsed < iAvailableBits ) + { + iDone++; + } + else if ( iBitsUsed == iAvailableBits ) + { + iDone++; + } + + if ( iBitsUsed > iAvailableBits ) + { + *piAllocOffset -= iDelta; + iDelta >>= 1; + } + else if ( iBitsUsed < iAvailableBits ) + { + *piAllocOffset += iDelta; + iDelta >>= 1; + } + } + } + + // printf("%d\n",*piAllocOffset); + // printf("%d\t%d\t%d\n",pppiAlloc[0][0][0],pppiAlloc[0][0][1],pppiAlloc[0][0][22]); + + // printf("%d\t%d\t%d\t%d\n",*piAllocOffset,iAvailableBits,iBitsUsed,iAvailableBits - iBitsUsed); + + return iBitsUsed; +} +#endif diff --git a/lib_rend/ivas_CQMFEncoder.h b/lib_rend/ivas_CQMFEncoder.h new file mode 100644 index 0000000000000000000000000000000000000000..e78aa4614d93347231bb5fff6706f504cbcf13e2 --- /dev/null +++ b/lib_rend/ivas_CQMFEncoder.h @@ -0,0 +1,70 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef _IVAS_CQMF_ENCODER_H_ +#define _IVAS_CQMF_ENCODER_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "lib_rend.h" +#define ENCODER_ERROR_NONE ( 0 ) +#define ENCODER_ERROR_FS_NOT_SUPPORTED ( -1 ) +#define ENCODER_ERROR_CHAN_NOT_SUPPORTED ( -2 ) +#define ENCODER_ERROR_UNKNOWN ( -100 ) + + typedef struct CQMF_ENCODER CQMFEncoder; + + CQMFEncoder *CreateCQMFEncoder( const int32_t iSampleRate, + const int32_t iChannels, + const int32_t iTargetBitRate, + const int32_t iAllowSidePred ); + + void DeleteCQMFEncoder( CQMFEncoder *psCQMFEncoder ); + + int32_t CQMFEncoderGetError( CQMFEncoder *psCQMFEncoder ); + int32_t EncodeFrame( + CQMFEncoder *psCQMFEncoder, + float ***pppfCQMFReal, + float ***pppfCQMFImag, + int32_t *piNumiBites, + const int32_t available_bits, + ivas_split_rend_bits_t *pBits ); + int32_t GetNumGroups( CQMFEncoder *psCQMFEncoder ); +#endif +#ifdef __cplusplus +} +#endif +#endif /* _CQMF_ENCODER_H_ */ diff --git a/lib_rend/ivas_MSPred.c b/lib_rend/ivas_MSPred.c new file mode 100644 index 0000000000000000000000000000000000000000..cec626c3aa4a86debc0d018a4a255ddfe37dbfcb --- /dev/null +++ b/lib_rend/ivas_MSPred.c @@ -0,0 +1,359 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "ivas_MSPred.h" +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "ivas_lcld_tables.h" +#include +#include +#include "prot.h" +#include "ivas_prot_rend.h" +#include "wmc_auto.h" + +int32_t _round( float val ) +{ + return ( val > 0.0f ? (int32_t) ( val + 0.5f ) : (int32_t) ( val - 0.5f ) ); +} + +int32_t quantPhase( float phase ) +{ +#ifdef SIMPLE_PHASE + int32_t phaseQ; + if ( phase < 0.0f ) + { + phase += 2.0f * _PI_; + } + phaseQ = _round( phase * SIMPLE_PHASE_QUANT_FACTOR ); + phaseQ = ( phaseQ > SIMPLE_PHASE_MAX_VAL ? SIMPLE_PHASE_MIN_VAL : phaseQ ); +#else + int32_t phaseQ; + + phaseQ = _round( phase * PHASE_QUANT_FACTOR ); + if ( phaseQ == PHASE_MAX_VAL ) + { + phaseQ = PHASE_MIN_VAL; + } +#endif + return phaseQ; +} + +void rot_pm_pi( float *pr, float *pi ) +{ + /* (-1 + j0) */ + *pr = -( *pr ); + *pi = -( *pi ); +} + +void rot_p_pi_2( float *pr, float *pi ) +{ + /* (0 + j) */ + float r = *pr; + *pr = -( *pi ); + *pi = r; +} + +void rot_m_pi_2( float *pr, float *pi ) +{ + /* (0 - j) */ + float r = *pr; + *pr = *pi; + *pi = -r; +} + +void cplxmult( float *pr1, float *pi1, float r2, float i2 ) +{ + float r1 = *pr1, i1 = *pi1; + *pr1 = r1 * r2 - i1 * i2; + *pi1 = r1 * i2 + i1 * r2; +} + +int32_t requantPhase( int32_t phaseQ ) +{ + + if ( phaseQ >= PHASE_MAX_VAL ) + { + phaseQ += PHASE_MAX_VAL; + phaseQ %= ( 2 * PHASE_MAX_VAL ); + phaseQ -= PHASE_MAX_VAL; + } + else if ( phaseQ < PHASE_MIN_VAL ) + { + phaseQ -= PHASE_MAX_VAL; + phaseQ %= ( 2 * PHASE_MAX_VAL ); + phaseQ += PHASE_MAX_VAL; + if ( phaseQ == PHASE_MAX_VAL ) + { + phaseQ = PHASE_MIN_VAL; + } + } + + return phaseQ; +} + +int32_t quantPred( float pred ) +{ + int32_t predQ = _round( pred * PRED_QUANT_FACTOR ); + predQ = predQ > PRED_MAX_VAL ? PRED_MAX_VAL : predQ; + predQ = predQ < PRED_MIN_VAL ? PRED_MIN_VAL : predQ; + + return predQ; +} + +float dequantPhase( int32_t phaseQ ) +{ +#ifdef SIMPLE_PHASE + return (float) phaseQ / SIMPLE_PHASE_QUANT_FACTOR; +#else + return (float) phaseQ / PHASE_QUANT_FACTOR; +#endif +} + +float dequantPred( int32_t predQ ) +{ + return (float) predQ / PRED_QUANT_FACTOR; +} + +int32_t PrepEncode( int32_t *piQuant, const int32_t *piMSFlags, const int32_t numBands ) +{ + int32_t b, numMSBands = 0; + for ( b = 0; b < numBands; b++ ) + { + if ( piMSFlags[b] ) + { + piQuant[numMSBands++] = piQuant[b]; + } + } + for ( b = numMSBands; b < numBands; b++ ) + { + piQuant[b] = 0; + } + return numMSBands; +} + +void EncodePhase( int32_t *phaseQuant, int32_t numMSBands, int32_t diffDim ) +{ + int32_t b; + if ( diffDim > 0 ) + { + int32_t tmp1, tmp2; + tmp1 = phaseQuant[0]; + for ( b = 1; b < numMSBands; b++ ) + { + tmp2 = phaseQuant[b]; + phaseQuant[b] -= tmp1; + tmp1 = tmp2; + } + } + if ( diffDim > 1 ) + { + int32_t tmp1, tmp2; + tmp1 = phaseQuant[1]; + for ( b = 2; b < numMSBands; b++ ) + { + tmp2 = phaseQuant[b]; + phaseQuant[b] -= tmp1; + tmp1 = tmp2; + } + } + for ( b = 1; b < numMSBands; b++ ) + { + phaseQuant[b] = requantPhase( phaseQuant[b] ); + } +} + +void DecodePhase( int32_t *phaseQuant, int32_t numMSBands, int32_t diffDim ) +{ + int32_t b; + if ( diffDim > 1 ) + { + for ( b = 2; b < numMSBands; b++ ) + { + phaseQuant[b] += phaseQuant[b - 1]; + } + } + if ( diffDim > 0 ) + { + for ( b = 1; b < numMSBands; b++ ) + { + phaseQuant[b] += phaseQuant[b - 1]; + } + } + for ( b = 1; b < numMSBands; b++ ) + { + phaseQuant[b] = requantPhase( phaseQuant[b] ); + } +} + +int32_t EncodePredCoef( int32_t *predQuant, int32_t numMSBands ) +{ + int32_t b, tmp1, tmp2; + tmp1 = predQuant[0]; + for ( b = 1; b < numMSBands; b++ ) + { + tmp2 = predQuant[b]; + predQuant[b] -= tmp1; + tmp1 = tmp2; + } + return numMSBands; +} + +void DecodePredCoef( int32_t *phaseQuant, int32_t numMSBands ) +{ + int32_t b; + for ( b = 1; b < numMSBands; b++ ) + { + phaseQuant[b] += phaseQuant[b - 1]; + } +} + +int32_t CountMSBits( int32_t iNumBands, const int32_t iMSMode, const int32_t *piMSFlags, const int32_t *piLRPhaseDiff, const int32_t *piMSPredCoef ) +{ + int32_t iBitsWritten = 0; + int32_t b; + int32_t anyNonZero; + int32_t iNumMSBands = 0; + int32_t piPhaseCopy[MAX_BANDS_48] = { 0 }; + int32_t piPredCopy[MAX_BANDS_48] = { 0 }; + + iBitsWritten += 2; /* iMSMode */ + for ( b = 0; b < iNumBands; b++ ) + { + iNumMSBands += ( piMSFlags[b] != 0 ); + } + + if ( iNumMSBands == 0 ) + { + return iBitsWritten; + } + + if ( iNumMSBands < iNumBands ) + { + iBitsWritten += iNumBands; /* piMSFlags */ + } + + if ( iMSMode < 3 ) + { + return iBitsWritten; + } + + /* prepare arrays for coding evaluation */ + for ( b = 0; b < iNumBands; b++ ) + { + piPhaseCopy[b] = piLRPhaseDiff[b]; + piPredCopy[b] = piMSPredCoef[b]; + } + + /* Differential Coding of Phase Data*/ + PrepEncode( piPhaseCopy, piMSFlags, iNumBands ); + PrepEncode( piPredCopy, piMSFlags, iNumBands ); +#ifndef SIMPLE_PHASE + EncodePhase( piPhaseCopy, iNumMSBands, PHASE_DIFF_DIM ); +#endif + EncodePredCoef( piPredCopy, iNumMSBands ); + + iBitsWritten += 1; /* iMSPredAll */ + anyNonZero = 0; /* phase */ + for ( b = 0; b < iNumMSBands; b++ ) + { + if ( piPhaseCopy[b] != 0 ) + { + anyNonZero = 1; + break; + } + } + iBitsWritten++; /*anyNonZero Phase*/ + if ( anyNonZero ) + { +#ifdef SIMPLE_PHASE + iBitsWritten += iNumMSBands * SIMPLE_PHASE_BITS; +#else + iBitsWritten += PHASE_BAND0_BITS; + for ( b = 1; b < iNumMSBands; b++ ) + { + int32_t tabIdx = piPhaseCopy[b] - ENV_DELTA_MIN; + iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; + } +#endif + } + anyNonZero = 0; /* prediction */ + for ( b = 0; b < iNumMSBands; b++ ) + { + if ( piPredCopy[b] != 0 ) + { + anyNonZero = 1; + break; + } + } + + iBitsWritten++; /* any nonZero Pred */ + if ( anyNonZero ) + { + iBitsWritten += PRED_BAND0_BITS; + for ( b = 1; b < iNumMSBands; b++ ) + { + int32_t tabIdx = piPredCopy[b] - ENV_DELTA_MIN; + iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; + } + } + + return iBitsWritten; +} + +void writeMSPred( int32_t *phaseQuant, int32_t *predQuant, int32_t MSMode, int32_t numMSBands, int32_t numBands, void *fid, int32_t *piMsFlags ) +{ + int32_t b; + fid = (FILE *) fid; + fprintf( fid, "%d %d", MSMode, numMSBands ); + for ( b = 0; b < numMSBands; b++ ) + { + fprintf( fid, " %d", phaseQuant[b] ); + } + for ( b = numMSBands; b < numBands; b++ ) + { + fprintf( fid, " %d", 0 ); + } + for ( b = 0; b < numMSBands; b++ ) + { + fprintf( fid, " %d", predQuant[b] ); + } + for ( b = numMSBands; b < numBands; b++ ) + { + fprintf( fid, " %d", 0 ); + } + for ( b = 0; b < numBands; b++ ) + { + fprintf( fid, " %d", piMsFlags[b] ); + } + fprintf( fid, "\n" ); +} +#endif diff --git a/lib_rend/ivas_MSPred.h b/lib_rend/ivas_MSPred.h new file mode 100644 index 0000000000000000000000000000000000000000..a2e94b7ba72a5995e572503bc8b619bbec952a9b --- /dev/null +++ b/lib_rend/ivas_MSPred.h @@ -0,0 +1,62 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef _IVAS_MS_PRED_H_ +#define _IVAS_MS_PRED_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif +#include + int32_t _round( float val ); + int32_t quantPhase( float phase ); + void cplxmult( float *pr1, float *pi1, float r2, float i2 ); + void rot_pm_pi( float *pr, float *pi ); + void rot_p_pi_2( float *pr, float *pi ); + void rot_m_pi_2( float *pr, float *pi ); + int32_t requantPhase( int32_t phaseQ ); + int32_t quantPred( float pred ); + float dequantPhase( int32_t phaseQ ); + float dequantPred( int32_t predQ ); + int32_t PrepEncode( int32_t *piQuant, const int32_t *piMSFlags, const int32_t numBands ); + void EncodePhase( int32_t *phaseQuant, int32_t numMSBands, int32_t diffDim ); + void DecodePhase( int32_t *phaseQuant, int32_t numMSBands, int32_t diffDim ); + int32_t EncodePredCoef( int32_t *predQuant, int32_t numMSBands ); + void DecodePredCoef( int32_t *phaseQuant, int32_t numMSBands ); + void writeMSPred( int32_t *phaseQuant, int32_t *predQuant, int32_t MSMode, int32_t numMSBands, int32_t numBands, void *fid, int32_t *piMsFlags ); + int32_t CountMSBits( int32_t iNumBands, const int32_t iMSMode, const int32_t *piMSFlags, const int32_t *piLRPhaseDiff, const int32_t *piMSPredCoef ); +#ifdef __cplusplus +} +#endif + +#endif /* _MS_PRED_H_ */ diff --git a/lib_rend/ivas_NoiseGen.c b/lib_rend/ivas_NoiseGen.c new file mode 100644 index 0000000000000000000000000000000000000000..44a794b69abf9d7252d906327017c37073fa8a35 --- /dev/null +++ b/lib_rend/ivas_NoiseGen.c @@ -0,0 +1,85 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "ivas_NoiseGen.h" +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include +#include +#include "prot.h" +#include "ivas_prot_rend.h" +#include "wmc_auto.h" + +NoiseGen *CreateNoiseGen( void ) +{ + int32_t n; + + NoiseGen *psNoiseGen = NULL; + + psNoiseGen = (NoiseGen *) malloc( sizeof( NoiseGen ) ); + psNoiseGen->iNoiseBufferLength = 2048; + psNoiseGen->iNoiseBufferMask = 2047; + psNoiseGen->iNoiseBufferIndex = 0; + + psNoiseGen->pfNoiseBuffer = (float *) malloc( psNoiseGen->iNoiseBufferLength * sizeof( float ) ); + + /* Generate Laplacian distributed noise */ + for ( n = 0; n < psNoiseGen->iNoiseBufferLength; n++ ) + { + float fNoise = 0.0f; + float fScale = 0.707f; + fNoise = (float) ( ( rand() & ( RAND_MAX - 1 ) ) - ( RAND_MAX >> 1 ) ) / (float) RAND_MAX; + + if ( fNoise < 0.0 ) + { + fNoise = fScale * (float) logf( 1.0f + 1.9999999f * fNoise ); + } + else + { + fNoise = -fScale * (float) logf( 1.0f - 1.9999999f * fNoise ); + } + + psNoiseGen->pfNoiseBuffer[n] = fNoise; + } + + return psNoiseGen; +} + +void DeleteNoiseGen( NoiseGen *psNoiseGen ) +{ + free( psNoiseGen->pfNoiseBuffer ); + free( psNoiseGen ); +} + +extern float GetNoise( NoiseGen *psNoiseGen ); +#endif diff --git a/lib_rend/ivas_NoiseGen.h b/lib_rend/ivas_NoiseGen.h new file mode 100644 index 0000000000000000000000000000000000000000..b56b1f9f84a7488b15b78c0d5eecebea9f07ef01 --- /dev/null +++ b/lib_rend/ivas_NoiseGen.h @@ -0,0 +1,68 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef _IVAS_NOISE_GEN_H_ +#define _IVAS_NOISE_GEN_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif +#include + typedef struct NOISE_GEN + { + int32_t iNoiseBufferLength; + int32_t iNoiseBufferMask; + int32_t iNoiseBufferIndex; + float *pfNoiseBuffer; + } NoiseGen; + + NoiseGen *CreateNoiseGen( void ); + + void DeleteNoiseGen( NoiseGen *psNoiseGen ); + + inline float GetNoise( NoiseGen *psNoiseGen ) + { + float fNoiseSample; + + fNoiseSample = psNoiseGen->pfNoiseBuffer[psNoiseGen->iNoiseBufferIndex]; + psNoiseGen->iNoiseBufferIndex++; + psNoiseGen->iNoiseBufferIndex &= psNoiseGen->iNoiseBufferMask; + + return fNoiseSample; + } + +#ifdef __cplusplus +} +#endif + +#endif /* _NOISE_GEN_H_ */ diff --git a/lib_rend/ivas_PerceptualModel.c b/lib_rend/ivas_PerceptualModel.c new file mode 100644 index 0000000000000000000000000000000000000000..131ca8af0dac6c82455f2bf2753589f4351a4971 --- /dev/null +++ b/lib_rend/ivas_PerceptualModel.c @@ -0,0 +1,206 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "ivas_PerceptualModel.h" +#include "prot.h" +#include "ivas_prot_rend.h" +#include +#include "wmc_auto.h" + + +/* clang-format off */ + +static inline int32_t LogAdd(int32_t iVal1,int32_t iVal2) +{ + int32_t iRetVal; + + if(iVal1 > iVal2){ + iRetVal = iVal1 - iVal2; + iRetVal = (iRetVal < (LOG_ADD_TABLE_LENGTH - 1)) ? iRetVal : (LOG_ADD_TABLE_LENGTH - 1); + iRetVal = iVal1 + c_aiLogAddTable[iRetVal]; + } + else{ + iRetVal = iVal2 - iVal1; + iRetVal = (iRetVal < (LOG_ADD_TABLE_LENGTH - 1)) ? iRetVal : (LOG_ADD_TABLE_LENGTH - 1); + iRetVal = iVal2 + c_aiLogAddTable[iRetVal]; + } + + return iRetVal; +} + +void PerceptualModel( const int32_t iMaxQuantBands, + const int32_t *piRMSEnvelope, + int32_t *piExcitation, + int32_t *piSMR ) +{ + int32_t n; + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t iSLOffset; + + piExcitation[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope[n] + c_aiBandwidthAdjust48[n]; + // Calculate sensation level offset + iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT; + // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0; + // Offset envelope by sensation level offset + piExcitation[n] -= iSLOffset; + // Convert to loudness domain (x^0.3) + piExcitation[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + } + + // Spread excitation function + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t k; + const int32_t *piSpread; + + piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48]; + piSMR[n] = piExcitation[n] + piSpread[n]; + for ( k = 0; k < iMaxQuantBands; k++ ) + { + if ( k != n ) + { + piSMR[n] = LogAdd( piSMR[n], piExcitation[k] + piSpread[k] ); + } + } + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + piSMR[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + piSMR[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope[n] + c_aiBandwidthAdjust48[n] - piSMR[n]; + } +} + +void PerceptualModelStereo( const int32_t iMaxQuantBands, + const int32_t *piMSFlags, + const int32_t *piRMSEnvelope0, + const int32_t *piRMSEnvelope1, + int32_t *piExcitation0, + int32_t *piExcitation1, + int32_t *piSMR0, + int32_t *piSMR1 ) +{ + int32_t n; + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t iMaxRMSEnv; + int32_t iSLOffset; + + iMaxRMSEnv = piRMSEnvelope0[n]; + + piExcitation0[n] = PERCEPTUAL_MODEL_SCALE * iMaxRMSEnv + c_aiBandwidthAdjust48[n]; // piRMSEnvelope0[n] + // Calculate sensation level offset + iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation0[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT; + // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0; + // Offset envelope by sensation level offset + piExcitation0[n] -= iSLOffset; + // Convert to loudness domain (x^0.3) + piExcitation0[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation0[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + } + + // Spread excitation function + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t k; + const int32_t *piSpread; + + piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48]; + piSMR0[n] = piExcitation0[n] + piSpread[n]; + for ( k = 0; k < iMaxQuantBands; k++ ) + { + if ( k != n ) + { + piSMR0[n] = LogAdd( piSMR0[n], piExcitation0[k] + piSpread[k] ); + } + } + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t iMaxRMSEnv; + int32_t iSLOffset; + + iMaxRMSEnv = piRMSEnvelope1[n]; + + piExcitation1[n] = PERCEPTUAL_MODEL_SCALE * iMaxRMSEnv + c_aiBandwidthAdjust48[n]; // piRMSEnvelope1[n] + // Calculate sensation level offset + iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation1[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT; + // iSLOffset = (iSLOffset > 0) ? iSLOffset : 0; + // Offset envelope by sensation level offset + piExcitation1[n] -= iSLOffset; + // Convert to loudness domain (x^0.3) + piExcitation1[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation1[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + } + + // Spread excitation function + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t k; + const int32_t *piSpread; + + piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48]; + piSMR1[n] = piExcitation1[n] + piSpread[n]; + for ( k = 0; k < iMaxQuantBands; k++ ) + { + if ( k != n ) + { + piSMR1[n] = LogAdd( piSMR1[n], piExcitation1[k] + piSpread[k] ); + } + } + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + if ( piMSFlags[n] == 1 ) + { + piSMR0[n] = ( piSMR0[n] > piSMR1[n] ) ? piSMR0[n] : piSMR1[n]; + piSMR1[n] = piSMR0[n]; + } + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + piSMR0[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR0[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + piSMR0[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope0[n] + c_aiBandwidthAdjust48[n] - piSMR0[n]; + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + piSMR1[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR1[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + piSMR1[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope1[n] + c_aiBandwidthAdjust48[n] - piSMR1[n]; + } +} +#endif diff --git a/lib_rend/ivas_PerceptualModel.h b/lib_rend/ivas_PerceptualModel.h new file mode 100644 index 0000000000000000000000000000000000000000..269bfa4a3f800a8fb2a45f941b773416fc256934 --- /dev/null +++ b/lib_rend/ivas_PerceptualModel.h @@ -0,0 +1,75 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef _IVAS_PERCEPTUAL_MODEL_H_ +#define _IVAS_PERCEPTUAL_MODEL_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif +#include + +#define LOG_ADD_TABLE_LENGTH ( 512 ) +#define PERCEPTUAL_MODEL_SCALE ( 64 ) +#define PERCEPTUAL_MODEL_SCALE_SHIFT ( 6 ) +#define PERCEPTUAL_MODEL_ALPHA_SCALE ( 614 ) +#define PERCEPTUAL_MODEL_ALPHA_INV_SCALE ( 6827 ) +#define PERCEPTUAL_MODEL_ALPHA_SHIFT ( 11 ) +#define PERCEPTUAL_MODEL_SLGAIN_SHIFT ( 8 ) //(4) +#define MAX_BANDS_48 ( 23 ) + + extern const int32_t c_aiLogAddTable[LOG_ADD_TABLE_LENGTH]; + extern const int32_t c_aiBandwidthAdjust48[MAX_BANDS_48]; + extern const int32_t c_aiAbsoluteThresh48[MAX_BANDS_48]; + extern const int32_t c_aiDefaultTheta48[MAX_BANDS_48]; + extern const int32_t c_aaiSpreadFunction48[MAX_BANDS_48 * MAX_BANDS_48]; + + extern void PerceptualModel( const int32_t iMaxQuantBands, + const int32_t *piRMSEnvelope, + int32_t *piExcitation, + int32_t *piSMR ); + + extern void PerceptualModelStereo( const int32_t iMaxQuantBands, + const int32_t *piMSFlags, + const int32_t *piRMSEnvelope0, + const int32_t *piRMSEnvelope1, + int32_t *piExcitation0, + int32_t *piExcitation1, + int32_t *piSMR0, + int32_t *piSMR1 ); + +#ifdef __cplusplus +} +#endif + +#endif /* _PERCEPTUAL_MODEL_H_ */ diff --git a/lib_rend/ivas_PredDecoder.c b/lib_rend/ivas_PredDecoder.c new file mode 100644 index 0000000000000000000000000000000000000000..0105abedb58259350df3742e93d2a02a041debfb --- /dev/null +++ b/lib_rend/ivas_PredDecoder.c @@ -0,0 +1,262 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "ivas_PredDecoder.h" +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include +#include +#include "prot.h" +#include "ivas_prot_rend.h" +#include "ivas_lcld_tables.h" +#include "ivas_PredTables.h" +#include "ivas_cldfb_codec_bitstream.h" +#include "wmc_auto.h" + + +PredictionDecoder *CreatePredictionDecoder( const int32_t iChannels, + const int32_t iNumBlocks ) +{ + int32_t n; + + PredictionDecoder *psPredictionDecoder = NULL; + + psPredictionDecoder = (PredictionDecoder *) malloc( sizeof( PredictionDecoder ) ); + + psPredictionDecoder->iChannels = iChannels; + psPredictionDecoder->iNumBlocks = iNumBlocks; + + psPredictionDecoder->piPredChanEnable = (int32_t *) malloc( sizeof( int32_t ) * iChannels ); + psPredictionDecoder->piNumPredBands = (int32_t *) malloc( sizeof( int32_t ) * iChannels ); + + psPredictionDecoder->ppfEstPredGain = (float **) malloc( sizeof( float * ) * iChannels ); + psPredictionDecoder->ppiPredBandEnable = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ); + psPredictionDecoder->ppfA1Real = (float **) malloc( sizeof( float * ) * iChannels ); + psPredictionDecoder->ppfA1Imag = (float **) malloc( sizeof( float * ) * iChannels ); + psPredictionDecoder->ppiA1Mag = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ); + psPredictionDecoder->ppiA1Phase = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ); + for ( n = 0; n < psPredictionDecoder->iChannels; n++ ) + { + psPredictionDecoder->ppfEstPredGain[n] = (float *) malloc( sizeof( float ) * CQMF_BANDS ); + psPredictionDecoder->ppiPredBandEnable[n] = (int32_t *) malloc( sizeof( int32_t ) * CQMF_BANDS ); + psPredictionDecoder->ppfA1Real[n] = (float *) malloc( sizeof( float ) * CQMF_BANDS ); + psPredictionDecoder->ppfA1Imag[n] = (float *) malloc( sizeof( float ) * CQMF_BANDS ); + psPredictionDecoder->ppiA1Mag[n] = (int32_t *) malloc( sizeof( int32_t ) * CQMF_BANDS ); + psPredictionDecoder->ppiA1Phase[n] = (int32_t *) malloc( sizeof( int32_t ) * CQMF_BANDS ); + } + + /* pre-define these tables? */ + psPredictionDecoder->pfMagLUT = (float *) malloc( sizeof( float ) * ( 1 << PRED_QUNAT_FILTER_MAG_BITS ) ); + psPredictionDecoder->pfP2RRealLUT = (float *) malloc( sizeof( float ) * ( 1 << PRED_QUANT_FILTER_PHASE_BITS ) ); + psPredictionDecoder->pfP2RImagLUT = (float *) malloc( sizeof( float ) * ( 1 << PRED_QUANT_FILTER_PHASE_BITS ) ); + + for ( n = 0; n < ( 1 << PRED_QUNAT_FILTER_MAG_BITS ); n++ ) + { + const float fInvMagScale = M_PI / ( 2.0f * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0f ); + psPredictionDecoder->pfMagLUT[n] = sinf( fInvMagScale * (float) n ); + } + + for ( n = 0; n < ( 1 << PRED_QUANT_FILTER_PHASE_BITS ); n++ ) + { + const float fInvPhaseScale = M_PI / (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) ); + int32_t iVal; + + iVal = n + PRED_QUANT_FILTER_PHASE_MIN; + psPredictionDecoder->pfP2RRealLUT[n] = cosf( fInvPhaseScale * (float) iVal ); + psPredictionDecoder->pfP2RImagLUT[n] = sinf( fInvPhaseScale * (float) iVal ); + } + + + return psPredictionDecoder; +} + +void DeletePredictionDecoder( PredictionDecoder *psPredictionDecoder ) +{ + int32_t n; + + for ( n = 0; n < psPredictionDecoder->iChannels; n++ ) + { + free( psPredictionDecoder->ppfEstPredGain[n] ); + free( psPredictionDecoder->ppiPredBandEnable[n] ); + free( psPredictionDecoder->ppfA1Real[n] ); + free( psPredictionDecoder->ppfA1Imag[n] ); + free( psPredictionDecoder->ppiA1Mag[n] ); + free( psPredictionDecoder->ppiA1Phase[n] ); + } + free( psPredictionDecoder->piPredChanEnable ); + free( psPredictionDecoder->piNumPredBands ); + free( psPredictionDecoder->ppfEstPredGain ); + free( psPredictionDecoder->ppiPredBandEnable ); + free( psPredictionDecoder->ppfA1Real ); + free( psPredictionDecoder->ppfA1Imag ); + free( psPredictionDecoder->ppiA1Mag ); + free( psPredictionDecoder->ppiA1Phase ); + + free( psPredictionDecoder->pfMagLUT ); + free( psPredictionDecoder->pfP2RRealLUT ); + free( psPredictionDecoder->pfP2RImagLUT ); + + free( psPredictionDecoder ); +} +#define USE_TABLE_LOOKUP +int32_t ReadPredictors( PredictionDecoder *psPredictionDecoder, + ivas_split_rend_bits_t *pBits ) +{ + int32_t iBitsRead = 0; + int32_t c; + + for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) + { + psPredictionDecoder->piPredChanEnable[c] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + + if ( psPredictionDecoder->piPredChanEnable[c] ) + { + int32_t b; + + for ( b = 0; b < CQMF_BANDS; b++ ) + { + psPredictionDecoder->ppiPredBandEnable[c][b] = 0; + } + psPredictionDecoder->piNumPredBands[c] = ivas_split_rend_bitstream_read_int32( pBits, 6 ); + iBitsRead += 6; + + for ( b = 0; b < psPredictionDecoder->piNumPredBands[c]; b++ ) + { + psPredictionDecoder->ppiPredBandEnable[c][b] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + + if ( psPredictionDecoder->ppiPredBandEnable[c][b] == 1 ) + { +#ifdef USE_TABLE_LOOKUP + int32_t iA1Mag; + int32_t iA1Phase; + float fA1Real; + float fA1Imag; + iA1Mag = ivas_split_rend_bitstream_read_int32( pBits, PRED_QUNAT_FILTER_MAG_BITS ); + iBitsRead += PRED_QUNAT_FILTER_MAG_BITS; + iA1Phase = ivas_split_rend_bitstream_read_int32( pBits, PRED_QUANT_FILTER_PHASE_BITS ); + iBitsRead += PRED_QUANT_FILTER_PHASE_BITS; + + psPredictionDecoder->ppiA1Mag[c][b] = iA1Mag; + psPredictionDecoder->ppiA1Phase[c][b] = iA1Phase + PRED_QUANT_FILTER_PHASE_MIN; + + fA1Real = psPredictionDecoder->pfMagLUT[iA1Mag] * psPredictionDecoder->pfP2RRealLUT[iA1Phase]; + fA1Imag = psPredictionDecoder->pfMagLUT[iA1Mag] * psPredictionDecoder->pfP2RImagLUT[iA1Phase]; + + psPredictionDecoder->ppfA1Real[c][b] = fA1Real; + psPredictionDecoder->ppfA1Imag[c][b] = fA1Imag; +#else + const float fInvMagScale = M_PI / ( 2.0 * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0 ); + const float fInvPhaseScale = M_PI / (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) ); + int32_t iA1Mag; + int32_t iA1Phase; + float fA1Mag; + float fA1Phase; + float fA1Real; + float fA1Imag; + + iA1Mag = BSGetBits( psBSRead, PRED_QUNAT_FILTER_MAG_BITS ); + iBitsRead += PRED_QUNAT_FILTER_MAG_BITS; + + iA1Phase = BSGetBits( psBSRead, PRED_QUANT_FILTER_PHASE_BITS ); + iBitsRead += PRED_QUANT_FILTER_PHASE_BITS; + iA1Phase += PRED_QUANT_FILTER_PHASE_MIN; + + psPredictionDecoder->ppiA1Mag[c][b] = iA1Mag; + psPredictionDecoder->ppiA1Phase[c][b] = iA1Phase; + + fA1Mag = sinf( fInvMagScale * (float) iA1Mag ); + fA1Phase = fInvPhaseScale * (float) iA1Phase; + + fA1Real = fA1Mag * cosf( fA1Phase ); + fA1Imag = fA1Mag * sinf( fA1Phase ); + + psPredictionDecoder->ppfA1Real[c][b] = fA1Real; + psPredictionDecoder->ppfA1Imag[c][b] = fA1Imag; + + // printf("Dec %f\t%f\t%f\n",fA1Real,fA1Imag,fA1Real * fA1Real + fA1Imag * fA1Imag); +#endif + } + } + } + else + { + int32_t b; + for ( b = 0; b < CQMF_BANDS; b++ ) + { + psPredictionDecoder->ppiPredBandEnable[c][b] = 0; + } + } + } + + return iBitsRead; +} + +void ApplyInversePredictros( PredictionDecoder *psPredictionDecoder, + float ***pppfReal, + float ***pppfImag ) +{ + int32_t c; + for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) + { + if ( psPredictionDecoder->piPredChanEnable[c] == 1 ) + { + int32_t b; + for ( b = 0; b < psPredictionDecoder->piNumPredBands[c]; b++ ) + { + if ( psPredictionDecoder->ppiPredBandEnable[c][b] == 1 ) + { + int32_t n; + float fA1Real; + float fA1Imag; + + fA1Real = psPredictionDecoder->ppfA1Real[c][b]; + fA1Imag = psPredictionDecoder->ppfA1Imag[c][b]; + for ( n = 1; n < psPredictionDecoder->iNumBlocks; n++ ) + { + float fReal; + float fImag; + + fReal = pppfReal[c][n][b] - fA1Real * pppfReal[c][n - 1][b] + fA1Imag * pppfImag[c][n - 1][b]; + fImag = pppfImag[c][n][b] - fA1Real * pppfImag[c][n - 1][b] - fA1Imag * pppfReal[c][n - 1][b]; + + pppfReal[c][n][b] = fReal; + pppfImag[c][n][b] = fImag; + } + } + } + } + } +} +#endif diff --git a/lib_rend/ivas_PredDecoder.h b/lib_rend/ivas_PredDecoder.h new file mode 100644 index 0000000000000000000000000000000000000000..47f986bc7dd643e59f5a866c7737fbc3dda584ee --- /dev/null +++ b/lib_rend/ivas_PredDecoder.h @@ -0,0 +1,87 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef _IVAS_PRED_DECODER_H_ +#define _IVAS_PRED_DECODER_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT + +#include "ivas_cldfb_codec_bitstream.h" + + // typedef struct PREDICTION_DECODER PredictionDecoder; + + typedef struct PREDICTION_DECODER + { + int32_t iChannels; + int32_t iNumBlocks; + + int32_t *piPredChanEnable; + int32_t *piNumPredBands; + + float **ppfEstPredGain; + int32_t **ppiPredBandEnable; + + float **ppfA1Real; + float **ppfA1Imag; + + int32_t **ppiA1Mag; + int32_t **ppiA1Phase; + + float *pfMagLUT; + float *pfP2RRealLUT; + float *pfP2RImagLUT; + } PredictionDecoder; + + PredictionDecoder *CreatePredictionDecoder( const int32_t iChannels, + const int32_t iNumBlocks ); + + void DeletePredictionDecoder( PredictionDecoder *psPredictionDecoder ); + + int32_t ReadPredictors( PredictionDecoder *psPredictionDecoder, + ivas_split_rend_bits_t *pBits ); + + void ApplyInversePredictros( PredictionDecoder *psPredictionDecoder, + float ***pppfReal, + float ***pppfImag ); + +#endif +#ifdef __cplusplus +} +#endif + +#endif /* _PRED_DECODER_H_ */ diff --git a/lib_rend/ivas_PredEncoder.c b/lib_rend/ivas_PredEncoder.c new file mode 100644 index 0000000000000000000000000000000000000000..e982cf7eed69837d12de002c3245a3b45d271754 --- /dev/null +++ b/lib_rend/ivas_PredEncoder.c @@ -0,0 +1,479 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "ivas_PredEncoder.h" +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include +#include +#include "ivas_lcld_tables.h" +#include "ivas_PredTables.h" +#include "prot.h" +#include "ivas_prot_rend.h" +#include "ivas_cldfb_codec_bitstream.h" +#include "wmc_auto.h" + + +PredictionEncoder *CreatePredictionEncoder( const int32_t iChannels, + const int32_t iNumBlocks ) +{ + int32_t n; + + PredictionEncoder *psPredictionEncoder = NULL; + + psPredictionEncoder = (PredictionEncoder *) malloc( sizeof( PredictionEncoder ) ); + + psPredictionEncoder->iChannels = iChannels; + psPredictionEncoder->iNumBlocks = iNumBlocks; + + psPredictionEncoder->pfWindow = (float *) malloc( sizeof( float ) * iNumBlocks ); + for ( n = 0; n < iNumBlocks; n++ ) + { + psPredictionEncoder->pfWindow[n] = 0.54f - 0.46f * cosf( 2.0f * M_PI * ( (float) n + 0.5f ) / (float) iNumBlocks ); + } + + + psPredictionEncoder->pfRxxReal = (float *) malloc( sizeof( float ) * 2 ); + psPredictionEncoder->pfRxxImag = (float *) malloc( sizeof( float ) * 2 ); + + psPredictionEncoder->piPredChanEnable = (int32_t *) malloc( sizeof( int32_t ) * iChannels ); + psPredictionEncoder->piNumPredBands = (int32_t *) malloc( sizeof( int32_t ) * iChannels ); + for ( n = 0; n < psPredictionEncoder->iChannels; n++ ) + { + psPredictionEncoder->piPredChanEnable[n] = 0; + psPredictionEncoder->piNumPredBands[n] = 40; // Will need to be set correctly + } + + psPredictionEncoder->ppfEstPredGain = (float **) malloc( sizeof( float * ) * iChannels ); + psPredictionEncoder->ppfEstPredBitGain = (float **) malloc( sizeof( float * ) * iChannels ); + psPredictionEncoder->ppiPredBandEnable = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ); + psPredictionEncoder->ppfA1Real = (float **) malloc( sizeof( float * ) * iChannels ); + psPredictionEncoder->ppfA1Imag = (float **) malloc( sizeof( float * ) * iChannels ); + psPredictionEncoder->ppiA1Mag = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ); + psPredictionEncoder->ppiA1Phase = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ); + for ( n = 0; n < psPredictionEncoder->iChannels; n++ ) + { + int32_t k; + + psPredictionEncoder->ppfEstPredGain[n] = (float *) malloc( sizeof( float ) * CQMF_BANDS ); + psPredictionEncoder->ppfEstPredBitGain[n] = (float *) malloc( sizeof( float ) * CQMF_BANDS ); + psPredictionEncoder->ppiPredBandEnable[n] = (int32_t *) malloc( sizeof( int32_t ) * CQMF_BANDS ); + psPredictionEncoder->ppfA1Real[n] = (float *) malloc( sizeof( float ) * CQMF_BANDS ); + psPredictionEncoder->ppfA1Imag[n] = (float *) malloc( sizeof( float ) * CQMF_BANDS ); + psPredictionEncoder->ppiA1Mag[n] = (int32_t *) malloc( sizeof( int32_t ) * CQMF_BANDS ); + psPredictionEncoder->ppiA1Phase[n] = (int32_t *) malloc( sizeof( int32_t ) * CQMF_BANDS ); + for ( k = 0; k < CQMF_BANDS; k++ ) + { + psPredictionEncoder->ppiPredBandEnable[n][k] = 0; + psPredictionEncoder->ppfA1Real[n][k] = 0.0; + psPredictionEncoder->ppfA1Imag[n][k] = 0.0; + } + } + + return psPredictionEncoder; +} + +void DeletePredictionEncoder( PredictionEncoder *psPredictionEncoder ) +{ + int32_t n; + + free( psPredictionEncoder->pfWindow ); + free( psPredictionEncoder->pfRxxReal ); + free( psPredictionEncoder->pfRxxImag ); + + for ( n = 0; n < psPredictionEncoder->iChannels; n++ ) + { + free( psPredictionEncoder->ppfEstPredGain[n] ); + free( psPredictionEncoder->ppfEstPredBitGain[n] ); + free( psPredictionEncoder->ppiPredBandEnable[n] ); + free( psPredictionEncoder->ppfA1Real[n] ); + free( psPredictionEncoder->ppfA1Imag[n] ); + free( psPredictionEncoder->ppiA1Mag[n] ); + free( psPredictionEncoder->ppiA1Phase[n] ); + } + free( psPredictionEncoder->piPredChanEnable ); + free( psPredictionEncoder->piNumPredBands ); + free( psPredictionEncoder->ppfEstPredGain ); + free( psPredictionEncoder->ppfEstPredBitGain ); + free( psPredictionEncoder->ppiPredBandEnable ); + free( psPredictionEncoder->ppfA1Real ); + free( psPredictionEncoder->ppfA1Imag ); + free( psPredictionEncoder->ppiA1Mag ); + free( psPredictionEncoder->ppiA1Phase ); + + free( psPredictionEncoder ); +} +//#define USE_RXX_WINDOW +int32_t ComputePredictors( PredictionEncoder *psPredictionEncoder, + float ***pppfReal, + float ***pppfImag ) +{ + int32_t c; + int32_t iPredictionBits = 0; + + for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) + { + int32_t b; + float fChanPredictionGainBits; + psPredictionEncoder->piNumPredBands[c] = 50; + fChanPredictionGainBits = 0.0; + for ( b = 0; b < psPredictionEncoder->piNumPredBands[c]; b++ ) + { + int32_t n; + int32_t iNumBlocks; + float fGain = 0.0; + float fBitGain = 0.0; + float *pfRxxReal; + float *pfRxxImag; + float fA1Real; + float fA1Imag; + // int32_t iA1Real; + // int32_t iA1Imag; + int32_t iA1Mag; + int32_t iA1Phase; + + iNumBlocks = psPredictionEncoder->iNumBlocks; + + pfRxxReal = psPredictionEncoder->pfRxxReal; + pfRxxImag = psPredictionEncoder->pfRxxImag; + + pfRxxReal[0] = 0.0; + pfRxxImag[0] = 0.0; + for ( n = 0; n < iNumBlocks; n++ ) + { +#ifdef USE_RXX_WINDOW + float fReal; + float fImag; + fReal = psPredictionEncoder->pfWindow[n] * pppfReal[c][n][b]; + fImag = psPredictionEncoder->pfWindow[n] * pppfImag[c][n][b]; + pfRxxReal[0] += ( fReal * fReal + fImag * fImag ); +#else + pfRxxReal[0] += ( pppfReal[c][n][b] * pppfReal[c][n][b] + pppfImag[c][n][b] * pppfImag[c][n][b] ); +#endif + } + + pfRxxReal[1] = 0.0; + pfRxxImag[1] = 0.0; + for ( n = 1; n < iNumBlocks; n++ ) + { +#ifdef USE_RXX_WINDOW + float fReal1; + float fImag1; + float fReal2; + float fImag2; + fReal1 = psPredictionEncoder->pfWindow[n] * pppfReal[c][n][b]; + fImag1 = psPredictionEncoder->pfWindow[n] * pppfImag[c][n][b]; + fReal2 = psPredictionEncoder->pfWindow[n - 1] * pppfReal[c][n - 1][b]; + fImag2 = psPredictionEncoder->pfWindow[n - 1] * pppfImag[c][n - 1][b]; + pfRxxReal[1] += ( fReal1 * fReal2 + fImag1 * fImag2 ); + pfRxxImag[1] += ( fImag1 * fReal2 - fReal1 * fImag2 ); +#else + pfRxxReal[1] += ( pppfReal[c][n][b] * pppfReal[c][n - 1][b] + pppfImag[c][n][b] * pppfImag[c][n - 1][b] ); + pfRxxImag[1] += ( pppfImag[c][n][b] * pppfReal[c][n - 1][b] - pppfReal[c][n][b] * pppfImag[c][n - 1][b] ); +#endif + } + + if ( pfRxxReal[0] > 1e-12f ) + { + float fA1Mag; + float fA1Phase; + float fGain2; + float fBitGain2; + + const float fMagScale = ( 2.0f * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0f ) / M_PI; + const float fInvMagScale = M_PI / ( 2.0f * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0f ); + const float fPhaseScale = (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) ) / M_PI; + const float fInvPhaseScale = M_PI / (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) ); + + // Compute filter coefficeints + fA1Real = -pfRxxReal[1] / pfRxxReal[0]; + fA1Imag = -pfRxxImag[1] / pfRxxReal[0]; + + // compute these before quant + // Compute est coding gain based on quantized filter coefficients + fGain = 1.0f / ( 1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag ); + fBitGain = 0.6f * log2f( fGain ) * (float) ( iNumBlocks ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); // Wrong fix (iNumBlocks-1) + + fA1Mag = sqrtf( fA1Real * fA1Real + fA1Imag * fA1Imag ); + fA1Mag = fMagScale * asinf( fA1Mag ); + iA1Mag = (int32_t) ( fA1Mag + 0.5f ); + iA1Mag = ( iA1Mag > PRED_QUANT_FILTER_MAG_MIN ) ? iA1Mag : PRED_QUANT_FILTER_MAG_MIN; + iA1Mag = ( iA1Mag < PRED_QUANT_FILTER_MAG_MAX ) ? iA1Mag : PRED_QUANT_FILTER_MAG_MAX; + fA1Mag = sinf( fInvMagScale * (float) iA1Mag ); + + fA1Phase = atan2f( fA1Imag, fA1Real ); + fA1Phase = fPhaseScale * fA1Phase; + iA1Phase = ( fA1Phase > 0.0f ) ? (int32_t) ( fA1Phase + 0.5f ) : (int32_t) ( fA1Phase - 0.5f ); + iA1Phase = ( iA1Phase > PRED_QUANT_FILTER_PHASE_MIN ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MIN; + iA1Phase = ( iA1Phase < PRED_QUANT_FILTER_PHASE_MAX ) ? iA1Phase : PRED_QUANT_FILTER_PHASE_MAX; // Is this the correct way to deal with this? should wrap? + fA1Phase = fInvPhaseScale * (float) iA1Phase; + + fA1Real = fA1Mag * cosf( fA1Phase ); + fA1Imag = fA1Mag * sinf( fA1Phase ); + + fGain2 = 1.0f / ( 1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag ); + fBitGain2 = 0.6f * log2f( fGain ) * (float) ( iNumBlocks ) - (float) ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); // Wrong fix (iNumBlocks-1) + + fGain = ( fGain < fGain2 ) ? fGain : fGain2; + fBitGain = ( fBitGain < fBitGain2 ) ? fBitGain : fBitGain2; + } + else + { + psPredictionEncoder->ppfEstPredGain[c][b] = 0.0f; + fA1Real = 0.0f; + fA1Imag = 0.0f; + // iA1Real = 0; + // iA1Imag = 0; + iA1Mag = 0; + iA1Phase = 0; + fGain = -10.0f; // Fix this + } + + psPredictionEncoder->ppfEstPredGain[c][b] = fGain; + psPredictionEncoder->ppfEstPredBitGain[c][b] = fBitGain; + psPredictionEncoder->ppiPredBandEnable[c][b] = ( fBitGain > 0 ) ? 1 : 0; // Initial prediction enable + psPredictionEncoder->ppfA1Real[c][b] = fA1Real; + psPredictionEncoder->ppfA1Imag[c][b] = fA1Imag; + psPredictionEncoder->ppiA1Mag[c][b] = iA1Mag; + psPredictionEncoder->ppiA1Phase[c][b] = iA1Phase; + + if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) + { + fChanPredictionGainBits += fBitGain; // change this calculation + } + } +#if 0 + // Estimate if the savings outway the signaling cost + if(fChanPredictionGainBits > 1e20){//}(float)(psPredictionEncoder->piNumPredBands[c] + 6)){ + psPredictionEncoder->piPredChanEnable[c] = 1; + //printf("Prediction Enabled\n"); + iPredictionBits += 1; + iPredictionBits += 6; + for(b = 0; b < psPredictionEncoder->piNumPredBands[c]; b ++){ + iPredictionBits += 1; + if(psPredictionEncoder->ppiPredBandEnable[c][b] == 1){ + iPredictionBits += (PRED_QUANT_FILTER_BITS * 2); + printf("%f, ",(psPredictionEncoder->ppfEstPredGain[c][b])); + } + } + printf("\n"); + } + else{ + psPredictionEncoder->piPredChanEnable[c] = 0; + for(b = 0; b < psPredictionEncoder->piNumPredBands[c]; b ++){ + psPredictionEncoder->ppiPredBandEnable[c][b] = 0; + } + //printf("Prediction Disabled\n"); + iPredictionBits += 1; + } +#else + { + /*int32_t iDone; + int32_t iPredBands; + + iDone = 0; + iPredBands = 30; + while(iPredBands > 0 && iDone == 0){ + int32_t b; + float fBitGain; + + fBitGain = -7.0; + for(b = 0; b < iPredBands; b ++){ + fBitGain -= 1.0; + if(psPredictionEncoder->ppiPredBandEnable[c][b] == 1){ + fBitGain += psPredictionEncoder->ppfEstPredBitGain[c][b]; + } + } + if(fBitGain > 0.0){ //thresh + iDone ++; + } + else{ + iPredBands --; + } + }*/ + // int32_t b; + float fBestCost; + int32_t iPredBands; + float fBitGain; + + fBestCost = 0.0; + iPredBands = 0; + fBitGain = -7.0; + for ( b = 0; b < 30; b++ ) + { // still getting this decision wrong! + fBitGain -= 1.0; + if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) + { + fBitGain += psPredictionEncoder->ppfEstPredBitGain[c][b]; + } + if ( fBitGain > fBestCost ) + { + fBestCost = fBitGain; + iPredBands = b; + } + } + + // printf("%d\t%f\n",iPredBands,fBestCost); + /*if(fBestCost < 300.0){ + iPredBands = 0; + }*/ + + if ( iPredBands > 0 ) + { + // int32_t b; + iPredictionBits += 1; + iPredictionBits += 6; + for ( b = 0; b < iPredBands; b++ ) + { + iPredictionBits += 1; + if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) + { + iPredictionBits += ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); + } + } + for ( b = iPredBands; b < CQMF_BANDS; b++ ) + { + psPredictionEncoder->ppiPredBandEnable[c][b] = 0; + } + psPredictionEncoder->piPredChanEnable[c] = 1; + psPredictionEncoder->piNumPredBands[c] = iPredBands; + } + else + { + // int32_t b; + iPredictionBits += 1; + for ( b = 0; b < CQMF_BANDS; b++ ) + { + psPredictionEncoder->ppiPredBandEnable[c][b] = 0; + } + psPredictionEncoder->piPredChanEnable[c] = 0; + psPredictionEncoder->piNumPredBands[c] = 0; + } + } +#endif + } + + return iPredictionBits; +} + +void ApplyForwardPredictors( PredictionEncoder *psPredictionEncoder, + float ***pppfReal, + float ***pppfImag ) +{ + int32_t c; + for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) + { + int32_t b; + if ( psPredictionEncoder->piPredChanEnable[c] == 1 ) + { + for ( b = 0; b < psPredictionEncoder->piNumPredBands[c]; b++ ) + { + if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) + { + int32_t n; + float fOldReal; + float fOldImag; + float fA1Real; + float fA1Imag; + + fOldReal = pppfReal[c][0][b]; + fOldImag = pppfImag[c][0][b]; + fA1Real = psPredictionEncoder->ppfA1Real[c][b]; + fA1Imag = psPredictionEncoder->ppfA1Imag[c][b]; + for ( n = 1; n < psPredictionEncoder->iNumBlocks; n++ ) + { + float fReal; + float fImag; + + fReal = pppfReal[c][n][b] + fA1Real * fOldReal - fA1Imag * fOldImag; + fImag = pppfImag[c][n][b] + fA1Real * fOldImag + fA1Imag * fOldReal; + + fOldReal = pppfReal[c][n][b]; + fOldImag = pppfImag[c][n][b]; + + pppfReal[c][n][b] = fReal; + pppfImag[c][n][b] = fImag; + } + } + } + } + } +} + +int32_t WritePredictors( PredictionEncoder *psPredictionEncoder, + ivas_split_rend_bits_t *pBits ) +{ + int32_t iBitsWritten = 0; + int32_t c; + + for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) + { + int32_t b; + ivas_split_rend_bitstream_write_int32( + pBits, psPredictionEncoder->piPredChanEnable[c], + 1 ); + iBitsWritten += 1; + + if ( psPredictionEncoder->piPredChanEnable[c] == 1 ) + { + ivas_split_rend_bitstream_write_int32( + pBits, psPredictionEncoder->piNumPredBands[c], 6 ); + iBitsWritten += 6; + + for ( b = 0; b < psPredictionEncoder->piNumPredBands[c]; b++ ) + { + ivas_split_rend_bitstream_write_int32( + pBits, psPredictionEncoder->ppiPredBandEnable[c][b], 1 ); + iBitsWritten += 1; + + if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) + { + int32_t iA1Mag; + int32_t iA1Phase; + + iA1Mag = psPredictionEncoder->ppiA1Mag[c][b]; + iA1Phase = psPredictionEncoder->ppiA1Phase[c][b] - PRED_QUANT_FILTER_PHASE_MIN; + ivas_split_rend_bitstream_write_int32( + pBits, iA1Mag, PRED_QUNAT_FILTER_MAG_BITS ); + iBitsWritten += PRED_QUNAT_FILTER_MAG_BITS; + ivas_split_rend_bitstream_write_int32( + pBits, iA1Phase, PRED_QUANT_FILTER_PHASE_BITS ); + iBitsWritten += PRED_QUANT_FILTER_PHASE_BITS; + } + } + } + } + + return iBitsWritten; +} +#endif diff --git a/lib_rend/ivas_PredEncoder.h b/lib_rend/ivas_PredEncoder.h new file mode 100644 index 0000000000000000000000000000000000000000..e74c61d76b71c61a665cae3a8f743ba73aa47b48 --- /dev/null +++ b/lib_rend/ivas_PredEncoder.h @@ -0,0 +1,91 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef _IVAS_PRED_ENCODER_H_ +#define _IVAS_PRED_ENCODER_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT + +#include "ivas_cldfb_codec_bitstream.h" + + typedef struct PREDICTION_ENCODER + { + int32_t iChannels; + int32_t iNumBlocks; + + float *pfWindow; + float *pfRxxReal; + float *pfRxxImag; + + int32_t *piPredChanEnable; + int32_t *piNumPredBands; + + float **ppfEstPredGain; + float **ppfEstPredBitGain; + int32_t **ppiPredBandEnable; + + float **ppfA1Real; + float **ppfA1Imag; + + int32_t **ppiA1Mag; + int32_t **ppiA1Phase; + } PredictionEncoder; + + PredictionEncoder *CreatePredictionEncoder( const int32_t iChannels, + const int32_t iNumBlocks ); + + void DeletePredictionEncoder( PredictionEncoder *psPredictionEncoder ); + + int32_t ComputePredictors( PredictionEncoder *psPredictionEncoder, + float ***pppfReal, + float ***pppfImag ); + + void ApplyForwardPredictors( PredictionEncoder *psPredictionEncoder, + float ***pppfReal, + float ***pppfImag ); + + + int32_t WritePredictors( PredictionEncoder *psPredictionEncoder, + ivas_split_rend_bits_t *pBits ); + +#endif +#ifdef __cplusplus +} +#endif + +#endif /* _PRED_ENCODER_H_ */ diff --git a/lib_rend/ivas_PredTables.h b/lib_rend/ivas_PredTables.h new file mode 100644 index 0000000000000000000000000000000000000000..71bdf214374b16424ee4f1ccb51de89985f8c4eb --- /dev/null +++ b/lib_rend/ivas_PredTables.h @@ -0,0 +1,53 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef _IVAS_PRED_TABLE_H_ +#define _IVAS_PRED_TABLE_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + + +#define PRED_QUNAT_FILTER_MAG_BITS ( 3 ) +#define PRED_QUANT_FILTER_PHASE_BITS ( 5 ) +#define PRED_QUANT_FILTER_MAG_MIN ( 0 ) +#define PRED_QUANT_FILTER_MAG_MAX ( 7 ) +#define PRED_QUANT_FILTER_PHASE_MIN ( -16 ) +#define PRED_QUANT_FILTER_PHASE_MAX ( 15 ) + +#ifdef __cplusplus +} +#endif + +#endif /* _PRED_TABLE_H_ */ diff --git a/lib_rend/ivas_RMSEnvGrouping.c b/lib_rend/ivas_RMSEnvGrouping.c new file mode 100644 index 0000000000000000000000000000000000000000..f5e18c3c1c6957fb2573158ad766b91ba41a1f0b --- /dev/null +++ b/lib_rend/ivas_RMSEnvGrouping.c @@ -0,0 +1,922 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "ivas_RMSEnvGrouping.h" + +/* Double check cost function calculation */ + +#include +#include +#include +#include +#include "options.h" +#include "prot.h" +#include "ivas_prot_rend.h" +#include "ivas_lcld_tables.h" +#include "wmc_auto.h" + + +typedef struct GMNODE +{ + int32_t iGroupStart; + int32_t iGroupLength; + float *pfMergedEnergydB; + int32_t *piQRMSEnvelope; + + int32_t iGroupRMSEnvelopeCost; + float fGroupSNRPenalty; + + struct GMNODE *psNext; +} GMNode; + +struct RMS_ENVELOPE_GROUPING +{ + int32_t iNumBlocks; + int32_t iMaxGroups; + float **ppfBandEnergy; + float **ppfBandEnergydB; + float **ppfWeight; + GMNode *psGMNodes; +}; + +RMSEnvelopeGrouping *CreateRMSEnvelopeGrouping( int32_t iNumBlocks ) +{ + int32_t n; + // assert( ( iNumBlocks & 0x1 ) == 0 ); // remove this + + RMSEnvelopeGrouping *psRMSEnvelopeGrouping; + + psRMSEnvelopeGrouping = (RMSEnvelopeGrouping *) malloc( sizeof( RMSEnvelopeGrouping ) ); + psRMSEnvelopeGrouping->iNumBlocks = iNumBlocks; +#ifdef FORCE_GROUPS_OF_2 + psRMSEnvelopeGrouping->iMaxGroups = iNumBlocks >> 1; +#else + psRMSEnvelopeGrouping->iMaxGroups = iNumBlocks; +#endif + + psRMSEnvelopeGrouping->ppfBandEnergy = (float **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( float * ) ); + psRMSEnvelopeGrouping->ppfBandEnergydB = (float **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( float * ) ); + psRMSEnvelopeGrouping->ppfWeight = (float **) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( float * ) ); + for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ ) + { + psRMSEnvelopeGrouping->ppfBandEnergy[n] = (float *) malloc( MAX_BANDS * 2 * sizeof( float ) ); /* 2 for stereo joint group calc */ + psRMSEnvelopeGrouping->ppfBandEnergydB[n] = (float *) malloc( MAX_BANDS * 2 * sizeof( float ) ); + psRMSEnvelopeGrouping->ppfWeight[n] = (float *) malloc( MAX_BANDS * 2 * sizeof( float ) ); + } + + psRMSEnvelopeGrouping->psGMNodes = (GMNode *) malloc( psRMSEnvelopeGrouping->iNumBlocks * sizeof( GMNode ) ); + for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ ) + { + psRMSEnvelopeGrouping->psGMNodes[n].pfMergedEnergydB = (float *) malloc( MAX_BANDS * 2 * sizeof( float ) ); + psRMSEnvelopeGrouping->psGMNodes[n].piQRMSEnvelope = (int32_t *) malloc( MAX_BANDS * 2 * sizeof( int32_t ) ); + psRMSEnvelopeGrouping->psGMNodes[n].iGroupRMSEnvelopeCost = -1; + psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty = -1.0; + } + + return psRMSEnvelopeGrouping; +} + +void DeleteRMSEnvelopeGrouping( RMSEnvelopeGrouping *psRMSEnvelopeGrouping ) +{ + int32_t n; + + for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ ) + { + free( psRMSEnvelopeGrouping->ppfBandEnergy[n] ); + free( psRMSEnvelopeGrouping->ppfBandEnergydB[n] ); + free( psRMSEnvelopeGrouping->ppfWeight[n] ); + } + free( psRMSEnvelopeGrouping->ppfBandEnergy ); + free( psRMSEnvelopeGrouping->ppfBandEnergydB ); + free( psRMSEnvelopeGrouping->ppfWeight ); + + for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ ) + { + free( psRMSEnvelopeGrouping->psGMNodes[n].pfMergedEnergydB ); + free( psRMSEnvelopeGrouping->psGMNodes[n].piQRMSEnvelope ); + } + free( psRMSEnvelopeGrouping->psGMNodes ); + + free( psRMSEnvelopeGrouping ); +} + +const float c_afThreshQuiet48[23] = { + -8.40653699e+01f, + -8.40653699e+01f, + -8.40653699e+01f, + -8.40653699e+01f, + -8.40653699e+01f, + -8.40653699e+01f, + -8.40653699e+01f, + -8.40653699e+01f, + -8.38067304e+01f, + -8.28409495e+01f, + -8.17031225e+01f, + -7.89799501e+01f, + -7.70607916e+01f, + -7.58484320e+01f, + -7.47976303e+01f, + -7.37491303e+01f, + -7.13163746e+01f, + -6.86144293e+01f, + -6.56295695e+01f, + -6.06521800e+01f, + -3.15408065e+01f, + -1.92542188e+01f, + -1.88401753e+01f, +}; + +static void ComputeBandEnergy( const int32_t iChannels, + const int32_t iNumBlocks, + const int32_t iNumBands, + const int32_t *piBandwidths, + float ***pppfReal, + float ***pppfImag, + float **ppfBandEnergy, + float **ppfBandEnergydB, + float **ppfWeight ) +{ + int32_t n; + + for ( n = 0; n < iChannels; n++ ) + { + int32_t k; + int32_t iChanOffset; + + iChanOffset = n * iNumBands; + for ( k = 0; k < iNumBlocks; k++ ) + { + int32_t b; + int32_t iFBOffset; + float fMaxWeight; + + + iFBOffset = 0; + fMaxWeight = 0.0f; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t m; + float fEnergy = 1e-12f; + float fWeight; + + for ( m = 0; m < piBandwidths[b]; m++ ) + { + fEnergy += ( pppfReal[n][k][iFBOffset] * pppfReal[n][k][iFBOffset] + pppfImag[n][k][iFBOffset] * pppfImag[n][k][iFBOffset] ); + iFBOffset++; + } + fEnergy /= (float) ( piBandwidths[b] ); // Correction removed normalization by 2 + ppfBandEnergy[k][iChanOffset + b] = fEnergy; + + fWeight = 0.33f * powf( 10.0f, 0.0068f * ( 10.0f * log10f( fEnergy ) - c_afThreshQuiet48[b] ) ); + fWeight = ( fWeight > 0.33f ) ? fWeight : 0.33f; + fWeight = ( fWeight < 1.0f ) ? fWeight : 1.0f; + fMaxWeight = ( fMaxWeight > fWeight ) ? fMaxWeight : fWeight; + ppfWeight[k][iChanOffset + b] = fWeight; + +#ifdef APPLY_TEMPORAL_SMOOTHING + if ( k > 0 ) + { + float fSmoothEnergy; + fSmoothEnergy = 0.7f * ppfBandEnergy[k - 1][iChanOffset + b] + 0.3f * fEnergy; + + fEnergy = ( fEnergy > fSmoothEnergy ) ? fEnergy : fSmoothEnergy; + } +#endif + fEnergy = 10.0f * log10f( fEnergy ); + ppfBandEnergydB[k][iChanOffset + b] = fEnergy; + } + for ( b = 0; b < iNumBands; b++ ) + { + ppfWeight[k][iChanOffset + b] /= fMaxWeight; + } + } + } +} + +/* THis is temporary cost function */ +static float TryMerge( const int32_t iNumBands, + const int32_t iStartBlock, + const int32_t iGroupLength, + const float fMaxAllowedDiffdB, + float **ppfBandEnergy, + float **ppfBandEnergydB, +#ifdef APPLY_WEIGHT + float **ppfWeight, +#endif + float *pfMegredEnergydB ) +{ + int32_t b; + int32_t n; + float fMeanCost; + float fMaxCost; + float fMinDiffCost; + float fMaxDiffCost; + float fInvGroupSize = 1.0f / (float) iGroupLength; + float fInvNumBands = 1.0f / (float) iNumBands; + + for ( b = 0; b < iNumBands; b++ ) + { + float fGroupEnergy; + + + fGroupEnergy = 0.0; + for ( n = iStartBlock; n < ( iStartBlock + iGroupLength ); n++ ) + { + fGroupEnergy += ppfBandEnergy[n][b]; + } + fGroupEnergy *= fInvGroupSize; + fGroupEnergy = 10.0f * log10f( fGroupEnergy ); // Note epsolon was added when computing BandEnergy; + + pfMegredEnergydB[b] = fGroupEnergy; + } + + fMeanCost = 0.0; + fMaxCost = 0.0; + fMinDiffCost = 0.0; + fMaxDiffCost = 0.0; + for ( n = iStartBlock; n < ( iStartBlock + iGroupLength ); n++ ) + { + float fMeanAbsDiff; + float fMaxAbsDiff; + float fMaxDiff; + float fMinDiff; + + fMeanAbsDiff = 0.0; + fMaxAbsDiff = 0.0; + fMaxDiff = 0.0; + fMinDiff = 0.0; + for ( b = 0; b < iNumBands; b++ ) + { + float fDiff; + float fAbsDiff; + + fDiff = pfMegredEnergydB[b] - ppfBandEnergydB[n][b]; // Changed the order of this + fAbsDiff = fabsf( fDiff ); +#ifdef APPLY_WEIGHT + fAbsDiff *= ppfWeight[n][b]; +#endif + + fMeanAbsDiff += fAbsDiff; + fMaxAbsDiff = ( fMaxAbsDiff > fAbsDiff ) ? fMaxAbsDiff : fAbsDiff; + + + fMaxDiff = ( fMaxDiff > fDiff ) ? fMaxDiff : fDiff; + fMinDiff = ( fMinDiff < fDiff ) ? fMinDiff : fDiff; + } + fMeanAbsDiff *= fInvNumBands; + + fMeanCost = ( fMeanCost > fMeanAbsDiff ) ? fMeanCost : fMeanAbsDiff; + fMaxCost = ( fMaxCost > fMaxAbsDiff ) ? fMaxCost : fMaxAbsDiff; + + fMaxDiffCost = ( fMaxDiffCost > fMaxDiff ) ? fMaxDiffCost : fMaxDiff; + fMinDiffCost = ( fMinDiffCost < fMinDiff ) ? fMinDiffCost : fMinDiff; + } + + // printf("%f\t%f\t%f\t%f\n",fMeanCost,fMaxCost,fMaxDiffCost,fMinDiffCost); + + /*if(fMinDiffCost < -9.0){ // This prevents cliping + fMeanCost = 1e12; //Some large value + }*/ + + if ( fMaxCost > fMaxAllowedDiffdB ) + { + fMeanCost = 1e12f; // Some large value + } + + return fMeanCost; +} + +static void ComputeMergeRMS( const int32_t iNumBands, + const int32_t iStartBlock, + const int32_t iGroupLength, + float **ppfBandEnergy, + float *pfMergedEnergydB, + int32_t *piQRMSEnvelope ) +{ + int32_t b; + float fInvGroupSize = 1.0f / (float) iGroupLength; + + for ( b = 0; b < iNumBands; b++ ) + { + int32_t n; + float fGroupEnergy; + float fRMSEnvelope; + int32_t iQRMSEnvelope; + + fGroupEnergy = 0.0; + for ( n = iStartBlock; n < ( iStartBlock + iGroupLength ); n++ ) + { + fGroupEnergy += ppfBandEnergy[n][b]; + } + fGroupEnergy *= fInvGroupSize; + + fRMSEnvelope = log2f( fGroupEnergy ); + iQRMSEnvelope = ( fRMSEnvelope > 0.0 ) ? (int32_t) ( fRMSEnvelope + 0.5 ) : (int32_t) ( fRMSEnvelope - 0.5 ); + + fGroupEnergy = 10.0f * log10f( fGroupEnergy ); // Note epsolon was added when computing BandEnergy; + + pfMergedEnergydB[b] = fGroupEnergy; + piQRMSEnvelope[b] = iQRMSEnvelope; + } +} + + +static int32_t ComputeRMSEnvelopeBits( const int32_t iChannels, + const int32_t iNumBands, + const int32_t *piQRMSEnevelope ) +{ + int32_t n; + int32_t iRMSEnvelopeBits = 0; + int32_t iChanOffset = 0; + + for ( n = 0; n < iChannels; n++ ) + { + int32_t b; + int32_t iLastRMSVal; + + iRMSEnvelopeBits += ENV0_BITS; + iLastRMSVal = piQRMSEnevelope[iChanOffset]; + for ( b = 1; b < iNumBands; b++ ) + { + int32_t iDelta; + + iDelta = piQRMSEnevelope[iChanOffset + b] - iLastRMSVal; + iDelta = ( iDelta > ENV_DELTA_MIN ) ? iDelta : ENV_DELTA_MIN; + iDelta = ( iDelta < ENV_DELTA_MAX ) ? iDelta : ENV_DELTA_MAX; + iDelta -= ENV_DELTA_MIN; + iRMSEnvelopeBits += c_aaiRMSEnvHuffEnc[iDelta][0]; + + iLastRMSVal = piQRMSEnevelope[iChanOffset + b]; + } + iChanOffset += iNumBands; + } + + return iRMSEnvelopeBits; +} + +static const float c_fiDefaultTheta48[MAX_BANDS_48] = { + 0.4375, + 0.4375, + 0.375, + 0.3125, + 0.3125, + 0.25, + 0.25, + 0.25, + 0.25, + 0.25, + 0.25, + 0.25, + 0.25, + 0.25, + 0.25, + 0.25, + 0.25, + 0.25, + 0.25, + 0.25, + 0.25, + 0.25, + 0.25, +}; + +static float ComputeSNRPenalty( const int32_t iChannels, + const int32_t iNumBands, + const int32_t *piBandwidths, + const int32_t iStartBlock, + const int32_t iGroupLength, + float **ppfBandEnergydB, + const int32_t *piRMSEnvelope ) +{ + int32_t n; + int32_t iChanOffset; + float fSNRPenalty = 0.0; + + iChanOffset = 0; + for ( n = 0; n < iChannels; n++ ) + { + int32_t b; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t k; + float fRMSVal; + + fRMSVal = 3.0103f * (float) piRMSEnvelope[iChanOffset + b]; + + for ( k = iStartBlock; k < ( iStartBlock + iGroupLength ); k++ ) + { + float fDeltadB; + + fDeltadB = fRMSVal - ppfBandEnergydB[k][iChanOffset + b]; + if ( fDeltadB < -9.0309f ) + { + fSNRPenalty += 1e10f; // Some large number to prevent clipping + } + else /*if(fDeltadB < 0.0)*/ + { + fSNRPenalty += fabsf( c_fiDefaultTheta48[b] * fDeltadB - fDeltadB ) * 2.0f * (float) piBandwidths[b] / 6.0f; + } + } + } + iChanOffset += iNumBands; + } + + + return fSNRPenalty; +} + +static float TryMegre2( const int32_t iChannels, + const int32_t iNumBands, + const int32_t *piBandwidths, + float **ppfBandEnergy, + float **ppfBandEnergydB, + GMNode *psGMNode1, + GMNode *psGMNode2 ) +{ + int32_t iRMSEnvBits1; + int32_t iRMSEnvBits2; + int32_t iRMSEnvBitsMerged; + float fSNRPenalty1; + float fSNRPenalty2; + float fSNRPenaltyMerged; + float fMergedCost = 0.0; + + /* First compute current RMS Envelope for each group */ + if ( psGMNode1->iGroupRMSEnvelopeCost == -1 || psGMNode1->fGroupSNRPenalty == -1.0 ) + { + ComputeMergeRMS( iNumBands * iChannels, + psGMNode1->iGroupStart, + psGMNode1->iGroupLength, + ppfBandEnergy, + psGMNode1->pfMergedEnergydB, + psGMNode1->piQRMSEnvelope ); + + iRMSEnvBits1 = ComputeRMSEnvelopeBits( iChannels, + iNumBands, + psGMNode1->piQRMSEnvelope ); + + fSNRPenalty1 = ComputeSNRPenalty( iChannels, + iNumBands, + piBandwidths, + psGMNode1->iGroupStart, + psGMNode1->iGroupLength, + ppfBandEnergydB, + psGMNode1->piQRMSEnvelope ); + + psGMNode1->iGroupRMSEnvelopeCost = iRMSEnvBits1; + psGMNode1->fGroupSNRPenalty = fSNRPenalty1; + } + else + { + iRMSEnvBits1 = psGMNode1->iGroupRMSEnvelopeCost; + fSNRPenalty1 = psGMNode1->fGroupSNRPenalty; + } + + if ( psGMNode2->iGroupRMSEnvelopeCost == -1 || psGMNode2->fGroupSNRPenalty == -1.0 ) + { + ComputeMergeRMS( iNumBands * iChannels, + psGMNode2->iGroupStart, + psGMNode2->iGroupLength, + ppfBandEnergy, + psGMNode2->pfMergedEnergydB, + psGMNode2->piQRMSEnvelope ); + + iRMSEnvBits2 = ComputeRMSEnvelopeBits( iChannels, + iNumBands, + psGMNode2->piQRMSEnvelope ); + + fSNRPenalty2 = ComputeSNRPenalty( iChannels, + iNumBands, + piBandwidths, + psGMNode2->iGroupStart, + psGMNode2->iGroupLength, + ppfBandEnergydB, + psGMNode2->piQRMSEnvelope ); + + psGMNode2->iGroupRMSEnvelopeCost = iRMSEnvBits2; + psGMNode2->fGroupSNRPenalty = fSNRPenalty2; + } + else + { + iRMSEnvBits2 = psGMNode2->iGroupRMSEnvelopeCost; + fSNRPenalty2 = psGMNode2->fGroupSNRPenalty; + } + + /* Compute the merged group */ + ComputeMergeRMS( iNumBands * iChannels, + psGMNode1->iGroupStart, + psGMNode1->iGroupLength + psGMNode2->iGroupLength, + ppfBandEnergy, + psGMNode1->pfMergedEnergydB, + psGMNode1->piQRMSEnvelope ); + + /* Compute the RMS Envelope cost for merged group */ + iRMSEnvBitsMerged = ComputeRMSEnvelopeBits( iChannels, + iNumBands, + psGMNode1->piQRMSEnvelope ); + + /* Compute an approximation of the bit cost based on SNR increase/decrease due to merging */ + fSNRPenaltyMerged = ComputeSNRPenalty( iChannels, + iNumBands, + piBandwidths, + psGMNode1->iGroupStart, + psGMNode1->iGroupLength + psGMNode2->iGroupLength, + ppfBandEnergydB, + psGMNode1->piQRMSEnvelope ); + + + fMergedCost = fSNRPenaltyMerged - fSNRPenalty1 - fSNRPenalty2 + (float) iRMSEnvBitsMerged - (float) iRMSEnvBits1 - (float) iRMSEnvBits2; + + return fMergedCost; +} + +static void ComputeGreedyGroups( RMSEnvelopeGrouping *psRMSEnvelopeGrouping, + const int32_t iChannels, + const int32_t iNumBands, + const float fMeanAllowedDiffdB, + const float fMaxAllowedDiffdB ) +{ + float fBestMeanCost; + + fBestMeanCost = 0.0; + while ( fBestMeanCost < fMeanAllowedDiffdB ) + { + GMNode *psGMNode; + GMNode *psBestGMNode; + + fBestMeanCost = fMeanAllowedDiffdB; + psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; + psBestGMNode = NULL; + while ( psGMNode->psNext != NULL ) + { + float fMeanCost; + int32_t iGroupLength; + + iGroupLength = psGMNode->iGroupLength + psGMNode->psNext->iGroupLength; + + fMeanCost = TryMerge( iNumBands * iChannels, + psGMNode->iGroupStart, + iGroupLength, // psGMNode->iGroupLength, //Fix this bug + fMaxAllowedDiffdB, + psRMSEnvelopeGrouping->ppfBandEnergy, + psRMSEnvelopeGrouping->ppfBandEnergydB, +#ifdef APPLY_WEIGHT + psRMSEnvelopeGrouping->ppfWeight, +#endif + psGMNode->pfMergedEnergydB ); + + + if ( fMeanCost < fBestMeanCost ) + { + fBestMeanCost = fMeanCost; + psBestGMNode = psGMNode; + } + + psGMNode = psGMNode->psNext; + } + + if ( fBestMeanCost < fMeanAllowedDiffdB && psBestGMNode != NULL && psBestGMNode->psNext != NULL ) + { + psBestGMNode->iGroupLength += psBestGMNode->psNext->iGroupLength; + psBestGMNode->psNext = psBestGMNode->psNext->psNext; + } + } +} + +static void ComputeGreedyGroups2( RMSEnvelopeGrouping *psRMSEnvelopeGrouping, + const int32_t iChannels, + const int32_t iNumBands, + const int32_t *piBandwidths ) +{ + float fBestMergeCost; + // int32_t iDone = 0; + fBestMergeCost = -1.0; + + while ( fBestMergeCost < 0.0 ) + { + GMNode *psGMNode; + GMNode *psBestGMNode; + + fBestMergeCost = 0.0; + psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; + psBestGMNode = NULL; + while ( psGMNode->psNext != NULL ) + { + float fMergeCost; + + fMergeCost = TryMegre2( iChannels, + iNumBands, + piBandwidths, + psRMSEnvelopeGrouping->ppfBandEnergy, + psRMSEnvelopeGrouping->ppfBandEnergydB, + psGMNode, + psGMNode->psNext ); + + if ( fMergeCost < fBestMergeCost ) + { + fBestMergeCost = fMergeCost; + psBestGMNode = psGMNode; + } + + psGMNode = psGMNode->psNext; + } + if ( fBestMergeCost < 0.0 && psBestGMNode != NULL && psBestGMNode->psNext != NULL ) + { + psBestGMNode->iGroupLength += psBestGMNode->psNext->iGroupLength; + psBestGMNode->iGroupRMSEnvelopeCost = -1; + psBestGMNode->fGroupSNRPenalty = -1.0; + psBestGMNode->psNext = psBestGMNode->psNext->psNext; + } + } +} + +static void ComputeGreedyGroups3( RMSEnvelopeGrouping *psRMSEnvelopeGrouping, + const int32_t iChannels, + const int32_t iNumBands, + const int32_t *piBandwidths, + const int32_t iMaxGroups ) +{ + + int32_t iDone = 0; + int32_t iNumGroups = psRMSEnvelopeGrouping->iMaxGroups; + while ( iDone == 0 ) + { + GMNode *psGMNode; + GMNode *psBestGMNode; + float fBestMergeCost; + + fBestMergeCost = 1e20f; + psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; + psBestGMNode = NULL; + while ( psGMNode->psNext != NULL ) + { + float fMergeCost; + + fMergeCost = TryMegre2( iChannels, + iNumBands, + piBandwidths, + psRMSEnvelopeGrouping->ppfBandEnergy, + psRMSEnvelopeGrouping->ppfBandEnergydB, + psGMNode, + psGMNode->psNext ); + + if ( fMergeCost < fBestMergeCost ) + { + fBestMergeCost = fMergeCost; + psBestGMNode = psGMNode; + } + + psGMNode = psGMNode->psNext; + } + if ( fBestMergeCost > 0.0 && iNumGroups <= iMaxGroups ) + { + iDone++; + } + else if ( psBestGMNode != NULL && psBestGMNode->psNext != NULL ) + { + psBestGMNode->iGroupLength += psBestGMNode->psNext->iGroupLength; + psBestGMNode->iGroupRMSEnvelopeCost = -1; + psBestGMNode->fGroupSNRPenalty = -1.0; + psBestGMNode->psNext = psBestGMNode->psNext->psNext; + iNumGroups--; + } + else + { + iDone++; // This only catches a problem + } + } +} + +static void ComputeRMSEnvelope( const int32_t iChannels, + const int32_t iNumBands, + const int32_t iNumGroups, + const int32_t *piGroupLengths, + float **ppfBandEnergy, + int32_t ***pppiRMSEnvelope ) +{ + int32_t n; + + for ( n = 0; n < iChannels; n++ ) + { + int32_t b; + int32_t iChanOffset; + + iChanOffset = n * iNumBands; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t k; + int32_t iBlockOffset; + + iBlockOffset = 0; + for ( k = 0; k < iNumGroups; k++ ) + { + int32_t m; + float fGroupEnergy; + fGroupEnergy = 0.0; + for ( m = 0; m < piGroupLengths[k]; m++ ) + { + fGroupEnergy += ppfBandEnergy[iBlockOffset][b + iChanOffset]; + iBlockOffset++; + } + fGroupEnergy /= (float) piGroupLengths[k]; + + fGroupEnergy = log2f( fGroupEnergy ); + pppiRMSEnvelope[n][k][b] = ( fGroupEnergy > 0.0 ) ? (int32_t) ( fGroupEnergy + 0.5 ) : (int32_t) ( fGroupEnergy - 0.5 ); // Bug fix + pppiRMSEnvelope[n][k][b] = ( pppiRMSEnvelope[n][k][b] > ENV_MIN ) ? pppiRMSEnvelope[n][k][b] : ENV_MIN; + pppiRMSEnvelope[n][k][b] = ( pppiRMSEnvelope[n][k][b] < ENV_MAX ) ? pppiRMSEnvelope[n][k][b] : ENV_MAX; + } + } + } +} + +static void LimitRMSEnvelope( const int32_t iBandCount, + const int32_t iRMSDeltaMax, + const int32_t iRMSDeltaMin, + int32_t *piRMSEnvelope ) +{ + int32_t iBand; + int32_t iLastSCF; + + /* Increase low envelope values to ensure that the scale factors traces the large values correctly (checking for max deltas) */ + iLastSCF = piRMSEnvelope[iBandCount - 1]; + for ( iBand = iBandCount - 2; iBand > -1; iBand-- ) + { + int32_t iDelta; + + iDelta = iLastSCF - piRMSEnvelope[iBand]; + + if ( iDelta > iRMSDeltaMax ) + { +#ifdef DEBUG_VERBOSE + printf( "WARNING RMS envelope delta limited\n" ); +#endif + piRMSEnvelope[iBand] += ( iDelta - iRMSDeltaMax ); + } + + iLastSCF = piRMSEnvelope[iBand]; + } + + /* Increase low envelope values to ensure that the envelope traces the large values correctly (checking for min deltas)*/ + iLastSCF = piRMSEnvelope[0]; + for ( iBand = 1; iBand < iBandCount; iBand++ ) + { + int32_t iDelta; + + iDelta = piRMSEnvelope[iBand] - iLastSCF; + + if ( iDelta < iRMSDeltaMin ) + { +#ifdef DEBUG_VERBOSE + printf( "WARNING RMS envelope delta limited\n" ); +#endif + piRMSEnvelope[iBand] += ( iRMSDeltaMin - iDelta ); + } + + iLastSCF = piRMSEnvelope[iBand]; + } +} + +void ComputeEnvelopeGrouping( RMSEnvelopeGrouping *psRMSEnvelopeGrouping, + const int32_t iChannels, + const int32_t iNumBands, + const int32_t *piBandwidths, // pass in absolute thresh + float ***pppfReal, + float ***pppfImag, +#ifndef USE_BIT_COUNT_MERGE_COST + const float fMeanAllowedDiffdB, + const float fMaxAllowedDiffdB, +#endif + int32_t *piNumGroups, + int32_t *piGroupLengths, + int32_t ***pppiRMSEnvelope ) +{ + int32_t n; + GMNode *psGMNode; + + /* Compute Band Energies */ + ComputeBandEnergy( iChannels, + psRMSEnvelopeGrouping->iNumBlocks, + iNumBands, + piBandwidths, + pppfReal, + pppfImag, + psRMSEnvelopeGrouping->ppfBandEnergy, + psRMSEnvelopeGrouping->ppfBandEnergydB, + psRMSEnvelopeGrouping->ppfWeight ); + + /* Init GMNodes */ +#ifdef FORCE_GROUPS_OF_2 + psRMSEnvelopeGrouping->psGMNodes[0].iGroupStart = 0; + psRMSEnvelopeGrouping->psGMNodes[0].iGroupLength = 2; + psRMSEnvelopeGrouping->psGMNodes[0].psNext = NULL; +#ifdef BUG_FIX_03_15_23_INIT_GROUPING + psRMSEnvelopeGrouping->psGMNodes[0].iGroupRMSEnvelopeCost = -1; + psRMSEnvelopeGrouping->psGMNodes[0].fGroupSNRPenalty = -1.0f; +#endif + for ( n = 1; n < psRMSEnvelopeGrouping->iMaxGroups; n++ ) + { + psRMSEnvelopeGrouping->psGMNodes[n - 1].psNext = &psRMSEnvelopeGrouping->psGMNodes[n]; + psRMSEnvelopeGrouping->psGMNodes[n].iGroupStart = n * 2; + psRMSEnvelopeGrouping->psGMNodes[n].iGroupLength = 2; + psRMSEnvelopeGrouping->psGMNodes[n].iGroupRMSEnvelopeCost = -1; + psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty = -1.0; + psRMSEnvelopeGrouping->psGMNodes[n].psNext = NULL; + } +#else + psRMSEnvelopeGrouping->psGMNodes[0].iGroupStart = 0; + psRMSEnvelopeGrouping->psGMNodes[0].iGroupLength = 1; + psRMSEnvelopeGrouping->psGMNodes[0].psNext = NULL; +#ifdef BUG_FIX_03_15_23_INIT_GROUPING + psRMSEnvelopeGrouping->psGMNodes[0].iGroupRMSEnvelopeCost = -1; + psRMSEnvelopeGrouping->psGMNodes[0].fGroupSNRPenalty = -1.0f; +#endif + for ( n = 1; n < psRMSEnvelopeGrouping->iMaxGroups; n++ ) + { + psRMSEnvelopeGrouping->psGMNodes[n - 1].psNext = &psRMSEnvelopeGrouping->psGMNodes[n]; + psRMSEnvelopeGrouping->psGMNodes[n].iGroupStart = n; + psRMSEnvelopeGrouping->psGMNodes[n].iGroupLength = 1; + psRMSEnvelopeGrouping->psGMNodes[n].iGroupRMSEnvelopeCost = -1; + psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty = -1.0; + psRMSEnvelopeGrouping->psGMNodes[n].psNext = NULL; + } +#endif + /* Perform grouping via Greedy Merge */ +#ifndef USE_BIT_COUNT_MERGE_COST + ComputeGreedyGroups( psRMSEnvelopeGrouping, + iChannels, + iNumBands, + fMeanAllowedDiffdB, + fMaxAllowedDiffdB ); +#else + /*ComputeGreedyGroups2(psRMSEnvelopeGrouping, + iChannels, + iNumBands, + piBandwidths);*/ + // Allows control over max groups can call using 16 if want same as previous call + ComputeGreedyGroups3( psRMSEnvelopeGrouping, + iChannels, + iNumBands, + piBandwidths, + CQMF_BLOCKS_PER_FRAME ); +#endif + + /* Calc Groups from Merge Results */ + *piNumGroups = 0; + psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; + while ( psGMNode != NULL ) + { + piGroupLengths[*piNumGroups] = psGMNode->iGroupLength; + *piNumGroups += 1; + psGMNode = psGMNode->psNext; + } + + /* Compute RMS Envelope given group lengths */ + ComputeRMSEnvelope( iChannels, + iNumBands, + *piNumGroups, + piGroupLengths, + psRMSEnvelopeGrouping->ppfBandEnergy, + pppiRMSEnvelope ); + + /* Envelope Tenting */ + for ( n = 0; n < iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < *piNumGroups; k++ ) + { + LimitRMSEnvelope( iNumBands, + ENV_DELTA_MAX, + ENV_DELTA_MIN, + pppiRMSEnvelope[n][k] ); + } + } +} diff --git a/lib_rend/ivas_RMSEnvGrouping.h b/lib_rend/ivas_RMSEnvGrouping.h new file mode 100644 index 0000000000000000000000000000000000000000..fff7e99965975384f13efebdd34cc71805101160 --- /dev/null +++ b/lib_rend/ivas_RMSEnvGrouping.h @@ -0,0 +1,66 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef _IVAS_RMS_ENV_GROUPING_H_ +#define _IVAS_RMS_ENV_GROUPING_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif +#include +#include "options.h" + typedef struct RMS_ENVELOPE_GROUPING RMSEnvelopeGrouping; + + RMSEnvelopeGrouping *CreateRMSEnvelopeGrouping( int32_t iNumBlocks ); + + void DeleteRMSEnvelopeGrouping( RMSEnvelopeGrouping *psRMSEnvelopeGrouping ); + + void ComputeEnvelopeGrouping( RMSEnvelopeGrouping *psRMSEnvelopeGrouping, + const int32_t iChannels, + const int32_t iNumBands, + const int32_t *piBandwidths, + float ***pppfReal, + float ***pppfImag, +#ifndef USE_BIT_COUNT_MERGE_COST + const float fMeanAllowedDiffdB, + const float fMaxAllowedDiffdB, +#endif + int32_t *piNumGroups, + int32_t *piGroupLengths, + int32_t ***pppiRMSEnvelope ); + +#ifdef __cplusplus +} +#endif + +#endif /* _RMS_ENV_GROUPING_H_ */ diff --git a/lib_rend/ivas_cldfb_codec_bitstream.c b/lib_rend/ivas_cldfb_codec_bitstream.c new file mode 100644 index 0000000000000000000000000000000000000000..7e8950ab2884896b66ec75cae88350550fc086aa --- /dev/null +++ b/lib_rend/ivas_cldfb_codec_bitstream.c @@ -0,0 +1,307 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ +#include "ivas_cldfb_codec_bitstream.h" +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include +#include "prot.h" +#include "wmc_auto.h" + +#define MAX_BUFFER 1024 + +static const uint32_t MASKS[] = { + 0x00000000, + 0x00000001, + 0x00000003, + 0x00000007, + 0x0000000f, + 0x0000001f, + 0x0000003f, + 0x0000007f, + 0x000000ff, + 0x000001ff, + 0x000003ff, + 0x000007ff, + 0x00000fff, + 0x00001fff, + 0x00003fff, + 0x00007fff, + 0x0000ffff, + 0x0001ffff, + 0x0003ffff, + 0x0007ffff, + 0x000fffff, + 0x001fffff, + 0x003fffff, + 0x007fffff, + 0x00ffffff, + 0x01ffffff, + 0x03ffffff, + 0x07ffffff, + 0x0fffffff, + 0x1fffffff, + 0x3fffffff, + 0x7fffffff, +}; + +Bitstream *CreateBitstream( const int32_t iDirection, + const int32_t iMaxBuffer ) + +{ + + int32_t n; + Bitstream *psBitstream; + + psBitstream = (Bitstream *) malloc( sizeof( Bitstream ) ); + + psBitstream->iDirection = iDirection; + psBitstream->iMaxBuffer = iMaxBuffer; + psBitstream->iIndex = 0; + psBitstream->iBufferEnd = 0; + psBitstream->iBufferStart = 0; + psBitstream->iError = BS_ERROR_NONE; + + if ( psBitstream->iMaxBuffer == -1 ) + { + psBitstream->iMaxBuffer = 4096; + } + + psBitstream->puchBuffer = (uint8_t *) malloc( sizeof( uint8_t ) * psBitstream->iMaxBuffer ); + + for ( n = 0; n < psBitstream->iMaxBuffer; n++ ) + { + psBitstream->puchBuffer[n] = 0; + } + + return psBitstream; +} + +void DeleteBitstream( Bitstream *psBitstream ) +{ + free( psBitstream->puchBuffer ); + free( psBitstream ); +} + +void BSFlushBuffer( Bitstream *psBitstream ) +{ + memset( psBitstream->puchBuffer, 0, psBitstream->iMaxBuffer ); + psBitstream->iIndex = 0; + psBitstream->iBufferEnd = 0; + psBitstream->iBufferStart = 0; + psBitstream->iError = BS_ERROR_NONE; +} + +int32_t BSPutBytes( Bitstream *psBitstream, + const uint8_t *puchBytes, + const int32_t iByteCount ) +{ + int32_t n; + for ( n = 0; n < iByteCount; n++ ) + { + psBitstream->puchBuffer[psBitstream->iBufferEnd] = puchBytes[n]; + psBitstream->iBufferEnd++; + } + if ( psBitstream->iDirection != BS_READ ) + { + psBitstream->iError = BS_ERROR_FAIL; + } + + return psBitstream->iError; +} + +int32_t BSGetBytes( Bitstream *psBitstream, + uint8_t *puchBytes, + int32_t iByteCount ) +{ + int32_t n; + for ( n = 0; n < iByteCount; n++ ) + { + puchBytes[n] = psBitstream->puchBuffer[psBitstream->iBufferStart]; + psBitstream->puchBuffer[psBitstream->iBufferStart] = 0; + psBitstream->iBufferStart++; + } + if ( psBitstream->iDirection != BS_WRITE ) + { + psBitstream->iError = BS_ERROR_FAIL; + } + + return psBitstream->iError; +} + +int32_t BSByteAlign( Bitstream *psBitstream ) +{ + if ( psBitstream->iDirection == BS_WRITE ) + { + if ( psBitstream->iIndex & 0x7 ) + { + int32_t iByte; + int32_t iRem; + + iByte = psBitstream->iIndex >> 3; + iRem = 8 - ( psBitstream->iIndex - ( iByte << 3 ) ); + psBitstream->puchBuffer[iByte] &= ( 0xff ^ MASKS[iRem] ); + psBitstream->iIndex += iRem; + } + } + else + { + if ( psBitstream->iIndex & 0x7 ) + { + int32_t iByte; + int32_t iRem; + + iByte = psBitstream->iIndex >> 3; + iRem = 8 - ( psBitstream->iIndex - ( iByte << 3 ) ); + psBitstream->iIndex += iRem; + } + } + + return psBitstream->iError; +} + +int32_t BSPutBits( Bitstream *psBitstream, + int32_t iValue, + int32_t iBitCount ) +{ + iValue &= MASKS[iBitCount]; + while ( iBitCount ) + { + int32_t iByte; + int32_t iRem; + int32_t iShift; + + iByte = psBitstream->iIndex >> 3; + iRem = 8 - ( psBitstream->iIndex - ( iByte << 3 ) ); // 8 - psBitstream->iIndex & 0x7; + + iShift = iBitCount - iRem; + if ( iShift <= 0 ) + { + iShift *= -1; + psBitstream->puchBuffer[iByte] += (uint8_t) ( iValue << iShift ); + psBitstream->iIndex += iBitCount; + iBitCount = 0; + } + else + { + psBitstream->puchBuffer[iByte] += (uint8_t) ( iValue >> iShift ); + iValue &= MASKS[iShift]; + psBitstream->iIndex += iRem; + iBitCount -= iRem; + } + } + + if ( psBitstream->iDirection != BS_WRITE ) + { + psBitstream->iError = BS_ERROR_FAIL; + } + + return psBitstream->iError; +} + +int32_t BSGetBits( Bitstream *psBitstream, + int32_t iBitCount ) +{ + int32_t iValue = 0; + + while ( iBitCount ) + { + uint8_t uchByte; + int32_t iByte; + int32_t iRem; + int32_t iShift; + + iByte = psBitstream->iIndex >> 3; + iRem = 8 - ( psBitstream->iIndex - ( iByte << 3 ) ); // 8 - psBitstream->iIndex & 0x7; + uchByte = psBitstream->puchBuffer[iByte]; + iShift = iBitCount - iRem; + + if ( iShift <= 0 ) + { + iShift *= -1; + iValue += (int32_t) ( ( uchByte >> iShift ) & MASKS[iBitCount] ); + psBitstream->iIndex += iBitCount; + iBitCount = 0; + } + else + { + uchByte &= MASKS[iRem]; + iValue += ( ( (int32_t) uchByte ) << iShift ); + psBitstream->iIndex += iRem; + iBitCount -= iRem; + } + } + + if ( psBitstream->iDirection != BS_READ ) + { + psBitstream->iError = BS_ERROR_FAIL; + } + + return iValue; +} + +int32_t BSForceBack( + ivas_split_rend_bits_t *pBits, + int32_t iValue, + int32_t iBitCount ) +{ + pBits->bits_read -= iBitCount; + return ( iValue >> iBitCount ); +} + +int32_t BSGetByteCount( Bitstream *psBitstream ) +{ + int32_t iBytes; + iBytes = psBitstream->iIndex >> 3; + if ( ( iBytes << 3 ) != psBitstream->iIndex ) + { + iBytes++; + } + + return iBytes; +} + +uint8_t *BSGetBuffer( Bitstream *psBitstream ) +{ + return psBitstream->puchBuffer; +} + +int32_t BSGetAvailableBytes( Bitstream *psBitstream ) +{ + return psBitstream->iBufferEnd; +} + +int32_t BSGetError( Bitstream *psBitstream ) +{ + return psBitstream->iError; +} +#endif diff --git a/lib_rend/ivas_cldfb_codec_bitstream.h b/lib_rend/ivas_cldfb_codec_bitstream.h new file mode 100644 index 0000000000000000000000000000000000000000..a058b901eea432642e843de811317093fbfd77bf --- /dev/null +++ b/lib_rend/ivas_cldfb_codec_bitstream.h @@ -0,0 +1,106 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby +International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der +angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips +N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge +Corporation, and other contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, +Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung +e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph +and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings +Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their +respective contributions in the software. This notice grants no license of any +kind, including but not limited to patent license, nor is any license granted by +implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration +agreement before making contributions. + + This software is provided "AS IS", without any express or implied warranties. +The software is in the development stage. It is intended exclusively for experts +who have experience with such software and solely for the purpose of inspection. +All implied warranties of non-infringement, merchantability and fitness for a +particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing +this software shall be submitted to and settled by the final, binding +jurisdiction of the courts of Munich, Germany in accordance with the laws of the +Federal Republic of Germany excluding its conflict of law rules and the United +Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef _IVAS_CLDFB_CODEC_BITSTREAM_H_ +#define _IVAS_CLDFB_CODEC_BITSTREAM_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif +#include "lib_rend.h" +#include "ivas_prot_rend.h" +#include "options.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT + + enum + { + BS_READ, + BS_WRITE + }; + enum + { + BS_ERROR_NONE, + BS_ERROR_FAIL + }; + + typedef struct BITSTREAM + { + int32_t iMaxBuffer; + int32_t iDirection; + int32_t iBufferEnd; + int32_t iBufferStart; + int32_t iIndex; + int32_t iError; + uint8_t *puchBuffer; + } Bitstream; + + Bitstream *CreateBitstream( const int32_t iDirection, const int32_t iMaxBuffer ); + + void DeleteBitstream( Bitstream *psBitstream ); + + void BSFlushBuffer( Bitstream *psBitstream ); + + int32_t BSPutBytes( Bitstream *psBitstream, const uint8_t *puchBytes, const int32_t iByteCount ); + + int32_t BSGetBytes( Bitstream *psBitstream, uint8_t *puchBytes, int32_t iByteCount ); + + int32_t BSByteAlign( Bitstream *psBitstream ); + + int32_t BSPutBits( Bitstream *psBitstream, int32_t iValue, int32_t iBitCount ); + + int32_t BSGetBits( Bitstream *psBitstream, int32_t iBitCount ); + + int32_t BSForceBack( + ivas_split_rend_bits_t *pBits, + int32_t iValue, + int32_t iBitCount ); + + uint8_t *BSGetBuffer( Bitstream *psBitstream ); + + int32_t BSGetByteCount( Bitstream *psBitstream ); + + int32_t BSGetAvailableBytes( Bitstream *psBitstream ); + int32_t BSGetError( Bitstream *psBitstream ); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _BITSTREAM_H_ */ diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index b2b488749952f4a748bd0cab3d294e4849f31bb6..05c8945e3c3e2e7341697e37b3727f88d14124c8 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -180,7 +180,11 @@ static ivas_error ivas_rend_initCrend( return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Encountered unsupported input config in Crend" ); } - if ( outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL && outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_IR && outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) + if ( outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL && outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_IR && outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + && outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB && outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif + ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Encountered unsupported output type in Crend" ); } @@ -901,9 +905,18 @@ static ivas_error ivas_rend_initCrend( *------------------------------------------------------------------------*/ ivas_error ivas_rend_initCrendWrapper( - CREND_WRAPPER_HANDLE *pCrend ) + CREND_WRAPPER_HANDLE *pCrend +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + const int16_t num_poses +#endif +) { int16_t i; + CREND_HANDLE hCrend; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; +#endif if ( pCrend == NULL ) { @@ -916,39 +929,86 @@ ivas_error ivas_rend_initCrendWrapper( } ( *pCrend )->binaural_latency_ns = 0; - ( *pCrend )->hCrend = NULL; ( *pCrend )->hHrtfCrend = NULL; - if ( ( ( *pCrend )->hCrend = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) +#endif { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for renderer handle" ); - } + hCrend = NULL; + if ( ( hCrend = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for renderer handle" ); + } - ( *pCrend )->hCrend->lfe_delay_line = NULL; + hCrend->lfe_delay_line = NULL; - for ( i = 0; i < MAX_INTERN_CHANNELS; i++ ) - { - ( *pCrend )->hCrend->freq_buffer_re[i] = NULL; - ( *pCrend )->hCrend->freq_buffer_im[i] = NULL; - } + for ( i = 0; i < MAX_INTERN_CHANNELS; i++ ) + { + hCrend->freq_buffer_re[i] = NULL; + hCrend->freq_buffer_im[i] = NULL; + } - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - ( *pCrend )->hCrend->prev_out_buffer[i] = NULL; + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + hCrend->prev_out_buffer[i] = NULL; + } + + hCrend->freq_buffer_re_diffuse = NULL; + hCrend->freq_buffer_im_diffuse = NULL; + hCrend->hReverb = NULL; + hCrend->delay_line_rw_index = 0; + hCrend->diffuse_delay_line_rw_index = 0; + hCrend->hTrack = NULL; + hCrend->m_fYaw = 0; + hCrend->m_fPitch = 0; + hCrend->m_fRoll = 0; + +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( *pCrend )->hCrend[pos_idx] = hCrend; +#else + ( *pCrend )->hCrend = hCrend; +#endif } + return IVAS_ERR_OK; +} + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*------------------------------------------------------------------------- + * ivas_rend_openMultiBinCrend() + * + * Allocate and initialize crend renderer handle + *------------------------------------------------------------------------*/ - ( *pCrend )->hCrend->freq_buffer_re_diffuse = NULL; - ( *pCrend )->hCrend->freq_buffer_im_diffuse = NULL; - ( *pCrend )->hCrend->hReverb = NULL; - ( *pCrend )->hCrend->delay_line_rw_index = 0; - ( *pCrend )->hCrend->diffuse_delay_line_rw_index = 0; - ( *pCrend )->hCrend->hTrack = NULL; - ( *pCrend )->hCrend->m_fYaw = 0; - ( *pCrend )->hCrend->m_fPitch = 0; - ( *pCrend )->hCrend->m_fRoll = 0; +ivas_error ivas_rend_openMultiBinCrend( + CREND_WRAPPER_HANDLE *pCrend, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int32_t output_Fs ) +{ + ivas_error error; + error = IVAS_ERR_OK; - return IVAS_ERR_OK; + error = ivas_rend_openCrend( pCrend, + getIvasAudioConfigFromRendAudioConfig( inConfig ), + getIvasAudioConfigFromRendAudioConfig( outConfig ), + NULL /*hRendCfg*/, + NULL, + output_Fs +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + pMultiBinPoseData->num_poses +#endif + ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + return error; } +#endif + /*------------------------------------------------------------------------- * ivas_rend_openCrend() * @@ -961,20 +1021,32 @@ ivas_error ivas_rend_openCrend( const AUDIO_CONFIG outConfig, RENDER_CONFIG_DATA *hRendCfg, HRTFS_CREND_HANDLE hSetOfHRTF, - const int32_t output_Fs ) + const int32_t output_Fs +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + const int16_t num_poses +#endif +) { int16_t i, subframe_length; int16_t max_total_ir_len; HRTFS_HANDLE hHrtf; CREND_HANDLE hCrend; ivas_error error; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; +#endif error = IVAS_ERR_OK; - if ( ( error = ivas_rend_initCrendWrapper( pCrend ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_initCrendWrapper( pCrend +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + num_poses +#endif + ) ) != IVAS_ERR_OK ) { return error; } - hCrend = ( *pCrend )->hCrend; subframe_length = (int16_t) ( output_Fs / FRAMES_PER_SEC ) / MAX_PARAM_SPATIAL_SUBFRAMES; @@ -986,89 +1058,101 @@ ivas_error ivas_rend_openCrend( } } - hHrtf = ( *pCrend )->hHrtfCrend; - - if ( hHrtf != NULL ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) +#endif { - max_total_ir_len = hHrtf->max_num_iterations * subframe_length; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = ( *pCrend )->hCrend[pos_idx]; +#else + hCrend = ( *pCrend )->hCrend; +#endif + hHrtf = ( *pCrend )->hHrtfCrend; - for ( i = 0; i < hHrtf->max_num_ir; i++ ) + if ( hHrtf != NULL ) { - if ( ( hCrend->freq_buffer_re[i] = (float *) malloc( sizeof( float ) * max_total_ir_len ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); - } - set_zero( hCrend->freq_buffer_re[i], max_total_ir_len ); + max_total_ir_len = hHrtf->max_num_iterations * subframe_length; - if ( ( hCrend->freq_buffer_im[i] = (float *) malloc( sizeof( float ) * max_total_ir_len ) ) == NULL ) + for ( i = 0; i < hHrtf->max_num_ir; i++ ) { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + if ( ( hCrend->freq_buffer_re[i] = (float *) malloc( sizeof( float ) * max_total_ir_len ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + } + set_zero( hCrend->freq_buffer_re[i], max_total_ir_len ); + + if ( ( hCrend->freq_buffer_im[i] = (float *) malloc( sizeof( float ) * max_total_ir_len ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + } + set_zero( hCrend->freq_buffer_im[i], max_total_ir_len ); } - set_zero( hCrend->freq_buffer_im[i], max_total_ir_len ); - } - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - if ( ( hCrend->prev_out_buffer[i] = (float *) malloc( sizeof( float ) * subframe_length ) ) == NULL ) + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + if ( ( hCrend->prev_out_buffer[i] = (float *) malloc( sizeof( float ) * subframe_length ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + } + set_zero( hCrend->prev_out_buffer[i], subframe_length ); } - set_zero( hCrend->prev_out_buffer[i], subframe_length ); - } - max_total_ir_len = hHrtf->num_iterations_diffuse[0] * subframe_length; + max_total_ir_len = hHrtf->num_iterations_diffuse[0] * subframe_length; - if ( max_total_ir_len > 0 ) - { - if ( ( hCrend->freq_buffer_re_diffuse = (float *) malloc( sizeof( float ) * max_total_ir_len ) ) == NULL ) + if ( max_total_ir_len > 0 ) { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); - } - set_zero( hCrend->freq_buffer_re_diffuse, max_total_ir_len ); + if ( ( hCrend->freq_buffer_re_diffuse = (float *) malloc( sizeof( float ) * max_total_ir_len ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + } + set_zero( hCrend->freq_buffer_re_diffuse, max_total_ir_len ); - if ( ( hCrend->freq_buffer_im_diffuse = (float *) malloc( sizeof( float ) * max_total_ir_len ) ) == NULL ) + if ( ( hCrend->freq_buffer_im_diffuse = (float *) malloc( sizeof( float ) * max_total_ir_len ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + } + set_zero( hCrend->freq_buffer_im_diffuse, max_total_ir_len ); + } + else { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + hCrend->freq_buffer_re_diffuse = NULL; + hCrend->freq_buffer_im_diffuse = NULL; } - set_zero( hCrend->freq_buffer_im_diffuse, max_total_ir_len ); - } - else - { - hCrend->freq_buffer_re_diffuse = NULL; - hCrend->freq_buffer_im_diffuse = NULL; - } - max_total_ir_len = (int16_t) ( hHrtf->latency_s * output_Fs + 0.5f ) + subframe_length; - if ( max_total_ir_len > 0 ) - { - if ( ( hCrend->lfe_delay_line = (float *) malloc( sizeof( float ) * max_total_ir_len ) ) == NULL ) + max_total_ir_len = (int16_t) ( hHrtf->latency_s * output_Fs + 0.5f ) + subframe_length; + if ( max_total_ir_len > 0 ) + { + if ( ( hCrend->lfe_delay_line = (float *) malloc( sizeof( float ) * max_total_ir_len ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + } + set_zero( hCrend->lfe_delay_line, max_total_ir_len ); + } + else { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + hCrend->lfe_delay_line = NULL; } - set_zero( hCrend->lfe_delay_line, max_total_ir_len ); - } - else - { - hCrend->lfe_delay_line = NULL; - } - if ( outConfig == AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) - { - if ( ( error = ivas_reverb_open( &( hCrend->hReverb ), inConfig, ( *pCrend )->hHrtfCrend, hRendCfg, output_Fs ) ) != IVAS_ERR_OK ) + if ( outConfig == AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { - return error; + if ( ( error = ivas_reverb_open( &( hCrend->hReverb ), inConfig, ( *pCrend )->hHrtfCrend, hRendCfg, output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + hCrend->hReverb = NULL; } - } - else - { - hCrend->hReverb = NULL; - } - ( *pCrend )->binaural_latency_ns = (int32_t) ( ( *pCrend )->hHrtfCrend->latency_s * 1000000000.f ); + ( *pCrend )->binaural_latency_ns = (int32_t) ( ( *pCrend )->hHrtfCrend->latency_s * 1000000000.f ); + } +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( *pCrend )->hCrend[pos_idx] = hCrend; +#else + ( *pCrend )->hCrend = hCrend; +#endif } - - ( *pCrend )->hCrend = hCrend; - return IVAS_ERR_OK; } @@ -1080,10 +1164,18 @@ ivas_error ivas_rend_openCrend( *------------------------------------------------------------------------*/ void ivas_rend_closeCrend( - CREND_WRAPPER_HANDLE *pCrend ) + CREND_WRAPPER_HANDLE *pCrend +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + const int16_t num_poses +#endif +) { int16_t i; - +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; +#endif + CREND_HANDLE hCrend; if ( pCrend == NULL || *pCrend == NULL ) { return; @@ -1094,62 +1186,77 @@ void ivas_rend_closeCrend( ivas_hrtf_close( &( *pCrend )->hHrtfCrend ); } - if ( ( *pCrend )->hCrend != NULL ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) +#endif { - for ( i = 0; i < MAX_INTERN_CHANNELS; i++ ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = ( *pCrend )->hCrend[pos_idx]; +#else + hCrend = ( *pCrend )->hCrend; +#endif + if ( hCrend != NULL ) { - if ( ( *pCrend )->hCrend->freq_buffer_re[i] != NULL ) + for ( i = 0; i < MAX_INTERN_CHANNELS; i++ ) { - free( ( *pCrend )->hCrend->freq_buffer_re[i] ); - ( *pCrend )->hCrend->freq_buffer_re[i] = NULL; + if ( hCrend->freq_buffer_re[i] != NULL ) + { + free( hCrend->freq_buffer_re[i] ); + hCrend->freq_buffer_re[i] = NULL; + } + if ( hCrend->freq_buffer_im[i] != NULL ) + { + free( hCrend->freq_buffer_im[i] ); + hCrend->freq_buffer_im[i] = NULL; + } } - if ( ( *pCrend )->hCrend->freq_buffer_im[i] != NULL ) + + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) { - free( ( *pCrend )->hCrend->freq_buffer_im[i] ); - ( *pCrend )->hCrend->freq_buffer_im[i] = NULL; + if ( hCrend->prev_out_buffer[i] != NULL ) + { + free( hCrend->prev_out_buffer[i] ); + hCrend->prev_out_buffer[i] = NULL; + } } - } - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - if ( ( *pCrend )->hCrend->prev_out_buffer[i] != NULL ) + if ( hCrend->lfe_delay_line != NULL ) { - free( ( *pCrend )->hCrend->prev_out_buffer[i] ); - ( *pCrend )->hCrend->prev_out_buffer[i] = NULL; + free( hCrend->lfe_delay_line ); + hCrend->lfe_delay_line = NULL; } - } - - if ( ( *pCrend )->hCrend->lfe_delay_line != NULL ) - { - free( ( *pCrend )->hCrend->lfe_delay_line ); - ( *pCrend )->hCrend->lfe_delay_line = NULL; - } - if ( ( *pCrend )->hCrend->freq_buffer_re_diffuse != NULL ) - { - free( ( *pCrend )->hCrend->freq_buffer_re_diffuse ); - ( *pCrend )->hCrend->freq_buffer_re_diffuse = NULL; - } + if ( hCrend->freq_buffer_re_diffuse != NULL ) + { + free( hCrend->freq_buffer_re_diffuse ); + hCrend->freq_buffer_re_diffuse = NULL; + } - if ( ( *pCrend )->hCrend->freq_buffer_im_diffuse != NULL ) - { - free( ( *pCrend )->hCrend->freq_buffer_im_diffuse ); - ( *pCrend )->hCrend->freq_buffer_im_diffuse = NULL; - } + if ( hCrend->freq_buffer_im_diffuse != NULL ) + { + free( hCrend->freq_buffer_im_diffuse ); + hCrend->freq_buffer_im_diffuse = NULL; + } - if ( ( *pCrend )->hCrend->hTrack != NULL ) - { - free( ( *pCrend )->hCrend->hTrack ); - ( *pCrend )->hCrend->hTrack = NULL; - } + if ( hCrend->hTrack != NULL ) + { + free( hCrend->hTrack ); + hCrend->hTrack = NULL; + } - ivas_reverb_close( &( *pCrend )->hCrend->hReverb ); + ivas_reverb_close( &hCrend->hReverb ); - free( ( *pCrend )->hCrend ); - ( *pCrend )->hCrend = NULL; - free( *pCrend ); - *pCrend = NULL; + free( hCrend ); + hCrend = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( *pCrend )->hCrend[pos_idx] = hCrend; +#else + ( *pCrend )->hCrend = hCrend; +#endif + } } + free( *pCrend ); + *pCrend = NULL; return; } @@ -1168,7 +1275,12 @@ static ivas_error ivas_rend_crendConvolver( float *pcm_in[], float *pcm_out[], const int32_t output_Fs, - const int16_t i_ts ) + const int16_t i_ts +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + const int16_t pos_idx +#endif +) { int16_t i, j, k, m; int16_t subframe_length, idx_in; @@ -1180,6 +1292,12 @@ static ivas_error ivas_rend_crendConvolver( const float *pFreq_filt_re, *pFreq_filt_im; float pOut[L_FRAME48k * 2]; float tmp_out_re[L_FRAME48k], tmp_out_im[L_FRAME48k]; + CREND_HANDLE hCrend; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = pCrend->hCrend[pos_idx]; +#else + hCrend = pCrend->hCrend; +#endif ivas_error error; if ( ( error = getAudioConfigNumChannels( inConfig, &nchan_in ) ) != IVAS_ERR_OK ) @@ -1207,13 +1325,13 @@ static ivas_error ivas_rend_crendConvolver( } } - offset = pCrend->hCrend->delay_line_rw_index * subframe_length; /* subframe_length * ( pCrend->hHrtfCrend->max_num_iterations - 1 ); */ - offset_diffuse = pCrend->hCrend->diffuse_delay_line_rw_index * subframe_length; /* subframe_length *( pCrend->hHrtfCrend->num_iterations_diffuse[0] - 1 ); */ + offset = hCrend->delay_line_rw_index * subframe_length; /* subframe_length * ( pCrend->hHrtfCrend->max_num_iterations - 1 ); */ + offset_diffuse = hCrend->diffuse_delay_line_rw_index * subframe_length; /* subframe_length *( pCrend->hHrtfCrend->num_iterations_diffuse[0] - 1 ); */ if ( pCrend->hHrtfCrend->num_iterations_diffuse[0] > 0 ) { - set_zero( &pCrend->hCrend->freq_buffer_re_diffuse[offset_diffuse], subframe_length ); - set_zero( &pCrend->hCrend->freq_buffer_im_diffuse[offset_diffuse], subframe_length ); + set_zero( &hCrend->freq_buffer_re_diffuse[offset_diffuse], subframe_length ); + set_zero( &hCrend->freq_buffer_im_diffuse[offset_diffuse], subframe_length ); } i = 0; @@ -1224,10 +1342,10 @@ static ivas_error ivas_rend_crendConvolver( { if ( pCrend->hHrtfCrend->num_iterations_diffuse[0] > 0 ) { - pFreq_buf_re = &pCrend->hCrend->freq_buffer_re_diffuse[offset_diffuse]; - pFreq_buf_im = &pCrend->hCrend->freq_buffer_im_diffuse[offset_diffuse]; - pFreq_filt_re = &pCrend->hCrend->freq_buffer_re[i][offset]; - pFreq_filt_im = &pCrend->hCrend->freq_buffer_im[i][offset]; + pFreq_buf_re = &hCrend->freq_buffer_re_diffuse[offset_diffuse]; + pFreq_buf_im = &hCrend->freq_buffer_im_diffuse[offset_diffuse]; + pFreq_filt_re = &hCrend->freq_buffer_re[i][offset]; + pFreq_filt_im = &hCrend->freq_buffer_im[i][offset]; for ( k = 0; k < pCrend->hHrtfCrend->index_frequency_max_diffuse; k++ ) { @@ -1236,8 +1354,8 @@ static ivas_error ivas_rend_crendConvolver( } } - pFreq_buf_re = &pCrend->hCrend->freq_buffer_re[i][offset]; - pFreq_buf_im = &pCrend->hCrend->freq_buffer_im[i][offset]; + pFreq_buf_re = &hCrend->freq_buffer_re[i][offset]; + pFreq_buf_im = &hCrend->freq_buffer_im[i][offset]; ivas_mdft( pIn, pFreq_buf_re, pFreq_buf_im, subframe_length, subframe_length ); i++; @@ -1257,11 +1375,11 @@ static ivas_error ivas_rend_crendConvolver( offset = 0; for ( m = 0; m < pCrend->hHrtfCrend->num_iterations[i][j]; m++ ) { - offset_in = ( pCrend->hCrend->delay_line_rw_index + pCrend->hHrtfCrend->max_num_iterations - pCrend->hHrtfCrend->num_iterations[i][j] + m + 1 ); + offset_in = ( hCrend->delay_line_rw_index + pCrend->hHrtfCrend->max_num_iterations - pCrend->hHrtfCrend->num_iterations[i][j] + m + 1 ); offset_in = offset_in % ( pCrend->hHrtfCrend->max_num_iterations ); offset_in = offset_in * subframe_length; - pFreq_buf_re = &pCrend->hCrend->freq_buffer_re[i][offset_in]; - pFreq_buf_im = &pCrend->hCrend->freq_buffer_im[i][offset_in]; + pFreq_buf_re = &hCrend->freq_buffer_re[i][offset_in]; + pFreq_buf_im = &hCrend->freq_buffer_im[i][offset_in]; pFreq_filt_re = &pCrend->hHrtfCrend->pOut_to_bin_re[i][j][offset]; pFreq_filt_im = &pCrend->hHrtfCrend->pOut_to_bin_im[i][j][offset]; @@ -1279,11 +1397,11 @@ static ivas_error ivas_rend_crendConvolver( offset = 0; for ( m = 0; m < pCrend->hHrtfCrend->num_iterations_diffuse[j]; m++ ) { - offset_diffuse = ( pCrend->hCrend->diffuse_delay_line_rw_index + m + 1 ); + offset_diffuse = ( hCrend->diffuse_delay_line_rw_index + m + 1 ); offset_diffuse = offset_diffuse % pCrend->hHrtfCrend->num_iterations_diffuse[0]; offset_diffuse = offset_diffuse * subframe_length; - pFreq_buf_re = &pCrend->hCrend->freq_buffer_re_diffuse[offset_diffuse]; - pFreq_buf_im = &pCrend->hCrend->freq_buffer_im_diffuse[offset_diffuse]; + pFreq_buf_re = &hCrend->freq_buffer_re_diffuse[offset_diffuse]; + pFreq_buf_im = &hCrend->freq_buffer_im_diffuse[offset_diffuse]; pFreq_filt_re = &pCrend->hHrtfCrend->pOut_to_bin_diffuse_re[j][offset]; pFreq_filt_im = &pCrend->hHrtfCrend->pOut_to_bin_diffuse_im[j][offset]; @@ -1300,17 +1418,17 @@ static ivas_error ivas_rend_crendConvolver( pFreq_buf_re = &pcm_out[j][i_ts * subframe_length]; for ( k = 0; k < subframe_length; k++ ) { - pFreq_buf_re[k] = pOut[k] + pCrend->hCrend->prev_out_buffer[j][k]; - pCrend->hCrend->prev_out_buffer[j][k] = pOut[k + subframe_length]; + pFreq_buf_re[k] = pOut[k] + hCrend->prev_out_buffer[j][k]; + hCrend->prev_out_buffer[j][k] = pOut[k + subframe_length]; } } - pCrend->hCrend->delay_line_rw_index++; - pCrend->hCrend->delay_line_rw_index = pCrend->hCrend->delay_line_rw_index % ( pCrend->hHrtfCrend->max_num_iterations ); + hCrend->delay_line_rw_index++; + hCrend->delay_line_rw_index = hCrend->delay_line_rw_index % ( pCrend->hHrtfCrend->max_num_iterations ); if ( pCrend->hHrtfCrend->num_iterations_diffuse[0] > 0 ) { - pCrend->hCrend->diffuse_delay_line_rw_index++; - pCrend->hCrend->diffuse_delay_line_rw_index = pCrend->hCrend->diffuse_delay_line_rw_index % ( pCrend->hHrtfCrend->num_iterations_diffuse[0] ); + hCrend->diffuse_delay_line_rw_index++; + hCrend->diffuse_delay_line_rw_index = hCrend->diffuse_delay_line_rw_index % ( pCrend->hHrtfCrend->num_iterations_diffuse[0] ); } return IVAS_ERR_OK; @@ -1332,7 +1450,12 @@ ivas_error ivas_rend_crendProcess( IVAS_OUTPUT_SETUP_HANDLE hIntSetup, EFAP_HANDLE hEFAPdata, float *output[], /* i/o: input/output audio channels */ - const int32_t output_Fs ) + const int32_t output_Fs +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + const int16_t pos_idx +#endif +) { int16_t i, subframe_idx, output_frame, subframe_len; int16_t nchan_out; @@ -1343,6 +1466,14 @@ ivas_error ivas_rend_crendProcess( ivas_error error; IVAS_REND_AudioConfig inRendConfig; IVAS_REND_AudioConfig outRendConfig; + + CREND_HANDLE hCrend; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = pCrend->hCrend[pos_idx]; +#else + hCrend = pCrend->hCrend; +#endif + int8_t combinedOrientationEnabled; combinedOrientationEnabled = 0; @@ -1403,14 +1534,23 @@ ivas_error ivas_rend_crendProcess( if ( ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) || ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) ) { - if ( ( error = ivas_rend_crendConvolver( pCrend, inRendConfig, outRendConfig, output, p_pcm_tmp, output_Fs, subframe_idx ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendConvolver( pCrend, inRendConfig, outRendConfig, output, p_pcm_tmp, output_Fs, subframe_idx +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + pos_idx +#endif + ) ) != IVAS_ERR_OK ) { return error; } - if ( pCrend->hCrend->hReverb != NULL ) + if ( hCrend->hReverb != NULL ) { +#ifdef FIX_SPLIT_REND_MERGE + if ( ( error = ivas_reverb_process( pCrend->hCrend[pos_idx]->hReverb, in_config, 1, output, p_pcm_tmp, subframe_idx ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_reverb_process( pCrend->hCrend->hReverb, in_config, 1, output, p_pcm_tmp, subframe_idx ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1549,11 +1689,24 @@ ivas_error ivas_rend_crendProcessSubframe( if ( ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) || ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) ) { +#ifdef FIX_SPLIT_REND_MERGE + if ( ( error = ivas_rend_crendConvolver( pCrend, inRendConfig, outRendConfig, tc_local, p_pcm_tmp, output_Fs, 0, 0 ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendConvolver( pCrend, inRendConfig, outRendConfig, tc_local, p_pcm_tmp, output_Fs, 0 ) ) != IVAS_ERR_OK ) + +#endif { return error; } - +#ifdef FIX_SPLIT_REND_MERGE + if ( pCrend->hCrend[0]->hReverb != NULL ) + { + if ( ( error = ivas_reverb_process( pCrend->hCrend[0]->hReverb, in_config, 1, tc_local, p_pcm_tmp, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#else if ( pCrend->hCrend->hReverb != NULL ) { if ( ( error = ivas_reverb_process( pCrend->hCrend->hReverb, in_config, 1, tc_local, p_pcm_tmp, 0 ) ) != IVAS_ERR_OK ) @@ -1561,6 +1714,7 @@ ivas_error ivas_rend_crendProcessSubframe( return error; } } +#endif for ( ch = 0; ch < nchan_in; ch++ ) { tc_local[ch] += subframe_len; @@ -1587,3 +1741,124 @@ ivas_error ivas_rend_crendProcessSubframe( return IVAS_ERR_OK; } +#ifdef SPLIT_REND_LC3PLUS_MC + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_rend_crend_ProcessSplitBin() + * + * Process call for IVAS Crend renderer + *-----------------------------------------------------------------------------------------*/ + +ivas_error ivas_rend_crendProcessSplitBin( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float output[][L_FRAME48k], /* i/o: SCE channels / Binaural synthesis */ + const int16_t output_frame /* i : output frame length */ +) +{ + int16_t i, j, sf; + int16_t pos_idx; + ivas_error error; + float gain_lfe; + float tmpLfeBuffer[L_FRAME48k]; + float tmpInputBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float *p_tmpInputBuffer[MAX_OUTPUT_CHANNELS]; + float tmpSplitBinBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; + COMBINED_ORIENTATION_DATA combinedOrientationDataLocal; + COMBINED_ORIENTATION_HANDLE pCombinedOrientationDataLocal; + + pMultiBinPoseData = &st_ivas->splitBinRend.splitrend.multiBinPoseData; + + /* copy input */ + for ( i = 0; i < st_ivas->nchan_transport; ++i ) + { + mvr2r( output[i], tmpInputBuffer[i], output_frame ); + } + + for ( i = 0; i < MAX_OUTPUT_CHANNELS; ++i ) + { + p_tmpInputBuffer[i] = tmpInputBuffer[i]; + } + + /* save current head positions */ + pCombinedOrientationDataLocal = st_ivas->hCombinedOrientationData; + combinedOrientationDataLocal = *pCombinedOrientationDataLocal; + for ( sf = 1; sf < RENDERER_HEAD_POSITIONS_PER_FRAME; ++sf ) + { + combinedOrientationDataLocal.Quaternions[sf] = combinedOrientationDataLocal.Quaternions[0]; + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + combinedOrientationDataLocal.Rmat[sf][i][j] = combinedOrientationDataLocal.Rmat[0][i][j]; + } + } + } + + /* copy LFE to tmpLfeBuffer and apply gain only once */ + mvr2r( output[st_ivas->hIntSetup.index_lfe[0]], tmpLfeBuffer, output_frame ); + gain_lfe = ( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hHrtfCrend != NULL ) ) ? st_ivas->hCrendWrapper->hHrtfCrend->gain_lfe : GAIN_LFE; + v_multc( tmpLfeBuffer, gain_lfe, tmpLfeBuffer, output_frame ); + + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; ++pos_idx ) + { + /* Update head positions */ + IVAS_QUATERNION Quaternions_orig[RENDERER_HEAD_POSITIONS_PER_FRAME], Quaternions_abs; + for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) + { + Quaternions_orig[i] = combinedOrientationDataLocal.Quaternions[i]; + Quaternions_abs.w = -3.0f; + Quat2EulerDegree( combinedOrientationDataLocal.Quaternions[i], &Quaternions_abs.z, &Quaternions_abs.y, &Quaternions_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ + + Quaternions_abs.x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; + Quaternions_abs.y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; + Quaternions_abs.z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; + combinedOrientationDataLocal.Quaternions[i] = Quaternions_abs; + QuatToRotMat( combinedOrientationDataLocal.Quaternions[i], combinedOrientationDataLocal.Rmat[i] ); + } + + /* render inplace to first two channels of tmpInputBuffer */ + pCombinedOrientationDataLocal = &combinedOrientationDataLocal; + if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, + st_ivas->intern_config, + st_ivas->hOutSetup.output_config, + st_ivas->hDecoderConfig, + pCombinedOrientationDataLocal, + &st_ivas->hIntSetup, + st_ivas->hEFAPdata, + p_tmpInputBuffer, + st_ivas->hDecoderConfig->output_Fs, + pos_idx ) ) != IVAS_ERR_OK ) + { + return error; + } + + for ( i = 0; i < BINAURAL_CHANNELS; ++i ) + { + /* accumulate LFE to output */ + v_add( tmpInputBuffer[i], tmpLfeBuffer, tmpInputBuffer[i], output_frame ); + + /* move to split bin output buffer */ + mvr2r( tmpInputBuffer[i], tmpSplitBinBuffer[pos_idx * BINAURAL_CHANNELS + i], output_frame ); + + /* overwrite rendered channels with input again for next iteration */ + mvr2r( output[i], tmpInputBuffer[i], output_frame ); + } + + /* restore original headrotation data */ + for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) + { + combinedOrientationDataLocal.Quaternions[i] = Quaternions_orig[i]; + } + } + + /* copy split binaural rendered signals to final output */ + for ( i = 0; i < BINAURAL_CHANNELS * pMultiBinPoseData->num_poses; ++i ) + { + mvr2r( tmpSplitBinBuffer[i], output[i], output_frame ); + } + + return IVAS_ERR_OK; +} +#endif diff --git a/lib_rend/ivas_lc3plus_common.c b/lib_rend/ivas_lc3plus_common.c new file mode 100644 index 0000000000000000000000000000000000000000..1f0dea1043009afd8a9c08e7ff88b0b23727509b --- /dev/null +++ b/lib_rend/ivas_lc3plus_common.c @@ -0,0 +1,49 @@ +/****************************************************************************************************** + + (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "ivas_lc3plus_common.h" +#include "ivas_error.h" +#include "lc3.h" + +ivas_error IVAS_LC3PLUS_LC3plusErrToIvasErr( const LC3PLUS_Error lc3PlusError ) +{ + switch ( lc3PlusError ) + { + case LC3PLUS_OK: + return IVAS_ERR_OK; + case LC3PLUS_BITRATE_ERROR: + return IVAS_ERR_LC3PLUS_INVALID_BITRATE; + default: + break; + } + return IVAS_ERR_INTERNAL; +} diff --git a/lib_rend/ivas_lc3plus_common.h b/lib_rend/ivas_lc3plus_common.h new file mode 100644 index 0000000000000000000000000000000000000000..eae0a5396b8032be7a6f6b104f8a198b3fa18d93 --- /dev/null +++ b/lib_rend/ivas_lc3plus_common.h @@ -0,0 +1,53 @@ +/****************************************************************************************************** + + (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#pragma once + +#include +#include "ivas_error.h" +#include "lc3.h" + +/*! common configuration parameters between encoder and decoder */ +typedef struct LC3PLUS_CONFIG +{ + /*! frame duration in microseconds [10000, 5000, 2500] */ + uint32_t lc3plus_frame_duration_us; + /*! ivas frame duration in microseconds [20000, 5000] */ + uint32_t ivas_frame_duration_us; + /*! sampling rate*/ + uint32_t samplerate; + /*! number of channels */ + uint16_t channels; +} LC3PLUS_CONFIG; + +/*! utility function to convert LC3PLUS_Errors to the suitable ivas_error */ +ivas_error IVAS_LC3PLUS_LC3plusErrToIvasErr( const LC3PLUS_Error lc3PlusError ); diff --git a/lib_rend/ivas_lc3plus_dec.c b/lib_rend/ivas_lc3plus_dec.c new file mode 100644 index 0000000000000000000000000000000000000000..45d56d3c6391f5889a65d9579358768f3f5b7045 --- /dev/null +++ b/lib_rend/ivas_lc3plus_dec.c @@ -0,0 +1,673 @@ +/****************************************************************************************************** + + (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "prot.h" +#include "ivas_prot.h" +#include "ivas_lc3plus_dec.h" +#include "ivas_lc3plus_common.h" +#include "lc3.h" +#include "ivas_error_utils.h" +#include "wmc_auto.h" + +ivas_error IVAS_LC3PLUS_DEC_Open( + const LC3PLUS_CONFIG config, /* i: decoder configuration */ +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + const int16_t enableCaching, /* i: if set to 0, the decoder will NOT use cached frame to flush algorithmic delay after skipped frames */ +#endif + IVAS_LC3PLUS_DEC_HANDLE *handle /* o: decoder handle */ +) +{ + LC3PLUS_Error err; + int32_t decoder_size; + int16_t lc3plusFrameIdx; + int16_t numLC3plusFramesPerIvasFrame; + int16_t i; + + *handle = malloc( sizeof( struct IVAS_LC3PLUS_DEC_HANDLE ) ); + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + if ( 0 == config.lc3plus_frame_duration_us ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid lc3plus_frame_duration_us (0)\n" ); + } +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + ( *handle )->cachingEnabled = enableCaching; +#endif + numLC3plusFramesPerIvasFrame = config.ivas_frame_duration_us / config.lc3plus_frame_duration_us; + +#ifdef LC3PLUS_DEC_COLLECT_STATS + ( *handle )->stats.action_histogram[DEC_ACTION_DECODE_AND_DROP] = 0; + ( *handle )->stats.action_histogram[DEC_ACTION_DECODE_AND_USE] = 0; + ( *handle )->stats.action_histogram[DEC_ACTION_SKIP] = 0; + ( *handle )->stats.action_histogram[DEC_ACTION_CACHE] = 0; + ( *handle )->stats.num_cached_frames_decoded_and_dropped = 0; +#endif + + ( *handle )->num_decs = 0; + ( *handle )->pcm_conversion_buffer = NULL; + ( *handle )->handles = NULL; + ( *handle )->selective_decoding_states = NULL; + ( *handle )->bitstream_caches = NULL; + ( *handle )->handles = malloc( config.channels * sizeof( IVAS_LC3PLUS_DEC_HANDLE ) ); + ( *handle )->selective_decoding_states = malloc( config.channels * sizeof( IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE * ) ); + if ( NULL == ( *handle )->handles || NULL == ( *handle )->selective_decoding_states ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + for ( i = 0; i < config.channels; ++i ) + { + ( *handle )->handles[i] = NULL; + ( *handle )->selective_decoding_states[i] = NULL; + } + +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + if ( enableCaching ) + { +#endif + ( *handle )->bitstream_caches = malloc( config.channels * sizeof( IVAS_LC3PLUS_DEC_BITSTREAM_CACHE * ) ); + if ( NULL == ( *handle )->bitstream_caches ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + for ( i = 0; i < config.channels; ++i ) + { + ( *handle )->bitstream_caches[i] = NULL; + } +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + } +#endif + ( *handle )->num_decs = config.channels; + for ( int32_t iCh = 0; iCh < config.channels; iCh++ ) + { + ( *handle )->selective_decoding_states[iCh] = NULL; + if ( NULL != ( *handle )->bitstream_caches ) + { + ( *handle )->bitstream_caches[iCh] = NULL; + } + /* allocate and configure LC3plus decoder */ + decoder_size = lc3plus_dec_get_size( config.samplerate, 1 ); + if ( 0 == decoder_size ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_dec_get_size failed\n" ); + } + + ( *handle )->handles[iCh] = malloc( decoder_size ); + if ( NULL == ( *handle )->handles[iCh] ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } + + err = lc3plus_dec_init( ( *handle )->handles[iCh], config.samplerate, 1, LC3PLUS_PLC_ADVANCED, 0 ); + if ( LC3PLUS_OK != err ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_init failed\n" ); + } + + err = lc3plus_dec_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 ); + if ( LC3PLUS_OK != err ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_set_frame_dms failed\n" ); + } + + /* allocate and configure per LC3plus decoder skip state */ + ( *handle )->selective_decoding_states[iCh] = malloc( sizeof( IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE ) ); + if ( NULL == ( *handle )->selective_decoding_states[iCh] ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } + ( *handle )->selective_decoding_states[iCh]->frame_actions = malloc( numLC3plusFramesPerIvasFrame * sizeof( SelectiveDecAction ) ); + if ( NULL == ( *handle )->selective_decoding_states[iCh]->frame_actions ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } + ( *handle )->selective_decoding_states[iCh]->has_skipped_a_frame = 0; + ( *handle )->selective_decoding_states[iCh]->shall_decode_cached_frame = 0; + for ( lc3plusFrameIdx = 0; lc3plusFrameIdx < numLC3plusFramesPerIvasFrame; lc3plusFrameIdx++ ) + { + ( *handle )->selective_decoding_states[iCh]->frame_actions[lc3plusFrameIdx] = DEC_ACTION_DECODE_AND_USE; + } +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + if ( enableCaching ) + { +#endif + /* allocate and configure per LC3plus decoder bitstream cache */ + ( *handle )->bitstream_caches[iCh] = malloc( sizeof( IVAS_LC3PLUS_DEC_BITSTREAM_CACHE ) ); + if ( NULL == ( *handle )->bitstream_caches[iCh] ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } + ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity = 400 /*LC3plus max non-HR octet count*/ * numLC3plusFramesPerIvasFrame; + ( *handle )->bitstream_caches[iCh]->bitstream_cache = malloc( ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity ); + if ( NULL == ( *handle )->bitstream_caches[iCh]->bitstream_cache ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } + ( *handle )->bitstream_caches[iCh]->bitstream_cache_size = 0; +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + } +#endif + } + ( *handle )->config = config; + if ( config.ivas_frame_duration_us < config.lc3plus_frame_duration_us || config.ivas_frame_duration_us % config.lc3plus_frame_duration_us != 0 ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" ); + } + ( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 ); + if ( NULL == ( *handle )->pcm_conversion_buffer ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder wrapper pcm_conversion_buffer\n" ); + } + return IVAS_ERR_OK; +} + +ivas_error IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( int16_t ***subframeChannelMatrix, const uint32_t num_decs ) +{ + *subframeChannelMatrix = malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t * ) ); + if ( NULL == *subframeChannelMatrix ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" ); + } + for ( int i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + ( *subframeChannelMatrix )[i] = NULL; + } + for ( int i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + ( *subframeChannelMatrix )[i] = malloc( num_decs * sizeof( int16_t ) ); + if ( NULL == ( *subframeChannelMatrix )[i] ) + { + IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( *subframeChannelMatrix ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" ); + } + } + return IVAS_ERR_OK; +} + +void IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( int16_t **subframeChannelMatrix ) +{ + for ( int i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + free( subframeChannelMatrix[i] ); + } + free( subframeChannelMatrix ); +} + +ivas_error IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( + IVAS_LC3PLUS_DEC_HANDLE handle, /* i: decoder handle */ + int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] ) +{ + int16_t numIvasSubFramesPerLC3frame; + uint32_t decIdx; + int16_t ivasSubframeIdx; + int16_t effectiveIvasSubframeDuration; + int16_t actual_num_spatial_subframes; + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "IVAS_LC3PLUS_DEC_HANDLE is NULL\n" ); + } + if ( NULL == subframeChannelMatrix ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "subframeChannelMatrix is NULL\n" ); + } + if ( handle->config.lc3plus_frame_duration_us == 0 || handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "invalid ivas_frame_duration_us/lc3plus_frame_duration_us values\n" ); + } + + effectiveIvasSubframeDuration = handle->config.ivas_frame_duration_us == 20000 ? handle->config.ivas_frame_duration_us / MAX_PARAM_SPATIAL_SUBFRAMES : handle->config.ivas_frame_duration_us; + numIvasSubFramesPerLC3frame = handle->config.lc3plus_frame_duration_us / effectiveIvasSubframeDuration; + actual_num_spatial_subframes = handle->config.ivas_frame_duration_us / effectiveIvasSubframeDuration; + // 0.5(0) = 10ms lc3plus, 5ms subframe + if ( numIvasSubFramesPerLC3frame != 1 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Selective decoding is only implemented for aligned IVAS-Subframes & LC3plus \n" ); + } + + + /* map subframeChannelMatrix to lc3plus skip states */ + /* 1st pass: Flag the required frames */ + for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) + { + for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) + { + if ( 1 == subframeChannelMatrix[ivasSubframeIdx][decIdx] ) + { + /* subframe needed by the user, definitely decode */ + handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_USE; + } + else + { + + /* subframe not needed by the user, but might be required to re-initialize a decoder after inactivity */ + if ( +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + handle->cachingEnabled && +#endif + ( ivasSubframeIdx != actual_num_spatial_subframes - 1 ) && 1 == subframeChannelMatrix[ivasSubframeIdx + 1][decIdx] ) + { + /* ... but if the following subframe is required, it needs to be decoded and dropped */ + handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_DROP; + } + else + { + handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_SKIP; + } + } + } + } +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + if ( handle->cachingEnabled ) + { +#endif + /* if a decoder was paused before, it needs to either: + * - Decode the cached frame (if available) and the first required frame OR + * - Decode the previous LC3plus subframe, even if it isn't needed by the user */ + for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) + { + if ( handle->selective_decoding_states[decIdx]->has_skipped_a_frame ) + { + /* find the first frame required by the user */ + for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) + { + if ( DEC_ACTION_DECODE_AND_USE == handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] ) + { + /* The first required frame is the first subframe. To flush the decoder, the cached frame must be decoded and dropped */ + if ( 0 == ivasSubframeIdx ) + { + handle->selective_decoding_states[decIdx]->shall_decode_cached_frame = 1; + break; + } + /* The first required frame is not the first frame, so the cache is useless. Instead we decode & drop the previous frame*/ + else + { + handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx - 1] = DEC_ACTION_DECODE_AND_DROP; + break; + } + } + } + } + } + + /* if a dec gets paused & caching is activated we need to flag the last useful LC3plus frame for caching */ + for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) + { + for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) + { + if ( handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] == DEC_ACTION_SKIP && handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] != DEC_ACTION_DECODE_AND_USE ) + { + handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] = DEC_ACTION_CACHE; + } + } + } +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + } +#endif + return IVAS_ERR_OK; +} + +ivas_error IVAS_LC3PLUS_DEC_GetDelay( + IVAS_LC3PLUS_DEC_HANDLE handle, /* i: decoder handle */ + int32_t *delayInSamples /* o: decoder delay in number of samples per channel */ +) +{ + int32_t tmpDelayInSamples; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "IVAS_LC3PLUS_DEC_HANDLE is NULL\n" ); + } + if ( NULL == delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "delayInSamples is NULL\n" ); + } + + *delayInSamples = 0; + /* sanity check whether all encoders are actually configured identically */ + for ( uint32_t iDec = 0; iDec < handle->num_decs; iDec++ ) + { + if ( NULL == handle->handles[iDec] ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus decoder handle is NULL\n" ); + } + + tmpDelayInSamples = lc3plus_dec_get_delay( handle->handles[iDec] ); + if ( 0 != *delayInSamples && tmpDelayInSamples != *delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Not all mono LC3plus decoders are configured identically\n" ); + } + *delayInSamples = tmpDelayInSamples; + } + return IVAS_ERR_OK; +} + +void IVAS_LC3PLUS_DEC_Close( + IVAS_LC3PLUS_DEC_HANDLE *handle /* i/o: Pointer to decoder handle */ +) +{ + if ( NULL == handle || NULL == *handle ) + { + return; + } +#ifdef LC3PLUS_DEC_COLLECT_STATS + printLC3plusDecStats( &( *handle )->stats ); +#endif + for ( uint32_t iDec = 0; iDec < ( *handle )->num_decs; iDec++ ) + { + if ( NULL != ( *handle )->handles && NULL != ( *handle )->handles[iDec] ) + { + lc3plus_free_decoder_structs( ( *handle )->handles[iDec] ); + free( ( *handle )->handles[iDec] ); + } + + if ( NULL != ( *handle )->selective_decoding_states && NULL != ( *handle )->selective_decoding_states[iDec] ) + { + free( ( *handle )->selective_decoding_states[iDec]->frame_actions ); + free( ( *handle )->selective_decoding_states[iDec] ); + } + + if ( NULL != ( *handle )->bitstream_caches && NULL != ( *handle )->bitstream_caches[iDec] ) + { + free( ( *handle )->bitstream_caches[iDec]->bitstream_cache ); + free( ( *handle )->bitstream_caches[iDec] ); + } + } + if ( NULL != ( *handle )->pcm_conversion_buffer ) + { + free( ( *handle )->pcm_conversion_buffer ); + } + free( ( *handle )->handles ); + if ( NULL != ( *handle )->bitstream_caches ) + { + free( ( *handle )->bitstream_caches ); + } + free( ( *handle )->selective_decoding_states ); + free( *handle ); + *handle = NULL; +} + +static ivas_error decode_or_conceal_one_lc3plus_frame( + LC3PLUS_Dec *dec, + uint8_t *bitstream_in, + const int32_t bitstream_in_length, + int16_t **pcm_out_buffer, + const int32_t badFrameIndicator ) +{ + LC3PLUS_Error err; + push_wmops( "lc3plus_dec16" ); + err = lc3plus_dec16( dec, bitstream_in, bitstream_in_length, pcm_out_buffer, NULL, badFrameIndicator ); + pop_wmops(); + if ( err == LC3PLUS_DECODE_ERROR && 1 == badFrameIndicator ) + { + /* LC3PLUS_DECODE_ERROR && badFrameIndicator means that the decoder has successfully concealed, which is actually OK. */ + err = LC3PLUS_OK; + } + if ( err != LC3PLUS_OK ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec16 failed\n" ); + } + return IVAS_ERR_OK; +} + +static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( + IVAS_LC3PLUS_DEC_HANDLE handle, /* i: decoder configuration */ + uint8_t *bitstream_in, /* i: pointer to input bitstream */ + int32_t bitstream_in_size, /* i: size of bitstream_in */ + const int32_t badFrameIndicator, /* i: bad frame indicator. If set to 1, triggers concealment */ + float **pcm_out /* o: decoded samples */ +) +{ + uint32_t iDec; + int32_t iLc3plusFrame; + int32_t lc3framesPerIvasFrame; + int32_t ivasSampleIndex; + int16_t numSamplesPerLC3plusChannel; + int32_t bitstreamOffsetPerCoder; + ivas_error err; + uint8_t *bitstream_in_iter = bitstream_in; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Dec_Wrap_Handle is NULL\n" ); + } + if ( NULL == bitstream_in ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_in is NULL\n" ); + } + if ( NULL == pcm_out ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_out is NULL\n" ); + } + if ( badFrameIndicator != 0 && badFrameIndicator != 1 ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "badFrameIndicator must be 1 or 0\n" ); + } + if ( badFrameIndicator == 0 && bitstream_in_size <= 0 ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "bitstream_in_size must be positive\n" ); + } + + if ( handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "ivas_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } + lc3framesPerIvasFrame = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; + + numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.ivas_frame_duration_us ) / lc3framesPerIvasFrame; + bitstreamOffsetPerCoder = bitstream_in_size / handle->num_decs / lc3framesPerIvasFrame; + for ( iDec = 0; iDec < handle->num_decs; iDec++ ) + { + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + if ( handle->selective_decoding_states[iDec]->shall_decode_cached_frame ) + { + if ( 0 == handle->bitstream_caches[iDec]->bitstream_cache_size ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "LC3plus cache is empty\n" ); + } + err = decode_or_conceal_one_lc3plus_frame( + handle->handles[iDec], + handle->bitstream_caches[iDec]->bitstream_cache, + handle->bitstream_caches[iDec]->bitstream_cache_size, + &handle->pcm_conversion_buffer, + badFrameIndicator ); + if ( err != IVAS_ERR_OK ) + { + return IVAS_ERROR( err, "lc3plus decoding failed\n" ); + } + handle->selective_decoding_states[iDec]->shall_decode_cached_frame = 0; + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; +#ifdef LC3PLUS_DEC_COLLECT_STATS + handle->stats.num_cached_frames_decoded_and_dropped++; +#endif + } + /* reset cache if caching is enabled - it has either been decoded or is not needed */ + if ( NULL != handle->bitstream_caches ) + { + handle->bitstream_caches[iDec]->bitstream_cache_size = 0; + } +#ifdef LC3PLUS_DEC_COLLECT_STATS + handle->stats.action_histogram[handle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame]]++; +#endif + switch ( handle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] ) + { + case DEC_ACTION_DECODE_AND_DROP: + { + err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in_iter, bitstreamOffsetPerCoder, &handle->pcm_conversion_buffer, badFrameIndicator ); + if ( err != IVAS_ERR_OK ) + { + return IVAS_ERROR( err, "lc3plus decoding failed\n" ); + } + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; + break; + } + case DEC_ACTION_DECODE_AND_USE: + { + err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in_iter, bitstreamOffsetPerCoder, &handle->pcm_conversion_buffer, badFrameIndicator ); + if ( err != IVAS_ERR_OK ) + { + return IVAS_ERROR( err, "lc3plus decoding failed\n" ); + } + + for ( int32_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) + { + ivasSampleIndex = iSampleInt16 + iLc3plusFrame * numSamplesPerLC3plusChannel; + pcm_out[iDec][ivasSampleIndex] = (float) handle->pcm_conversion_buffer[iSampleInt16]; + } + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; + break; + } + case DEC_ACTION_SKIP: + { + /* log that this instance has skipped a frame and must decode twice once reactivated */ + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; + break; + } + case DEC_ACTION_CACHE: + { + if ( handle->bitstream_caches[iDec]->bitstream_cache_capacity < bitstreamOffsetPerCoder ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "bitstream_cache_capacity is too low for LC3plus frame size\n" ); + } + /* store bit rate of cached frame */ + mvc2c( bitstream_in_iter, handle->bitstream_caches[iDec]->bitstream_cache, bitstreamOffsetPerCoder ); + handle->bitstream_caches[iDec]->bitstream_cache_size = bitstreamOffsetPerCoder; + /* log that this instance has skipped a frame and must decode twice once reactivated */ + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; + break; + } + case DEC_ACTION_NUM_ENUMS: + default: + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid LC3plus decoder state\n" ); + } + bitstream_in_iter += bitstreamOffsetPerCoder; + } + /* reset skipping state, must be set by the user before each decode call*/ + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + handle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] = DEC_ACTION_DECODE_AND_USE; + } + } + return IVAS_ERR_OK; +} + +ivas_error IVAS_LC3PLUS_DEC_Decode( + IVAS_LC3PLUS_DEC_HANDLE handle, /* i: decoder configuration */ + uint8_t *bitstream_in, /* i: pointer to input bitstream */ + int32_t bitstream_in_size, /* i: size of bitstream_in */ + float **pcm_out /* o: decoded samples */ +) +{ + int32_t badFrameIndicator; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Dec_Wrap_Handle is NULL\n" ); + } + if ( NULL == bitstream_in ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_in is NULL\n" ); + } + if ( NULL == pcm_out ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_out is NULL\n" ); + } + badFrameIndicator = 0; + return IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, bitstream_in_size, badFrameIndicator, pcm_out ); +} + +ivas_error IVAS_LC3PLUS_DEC_Conceal( + IVAS_LC3PLUS_DEC_HANDLE handle, /* i: decoder handle */ + float **pcm_out /* o: concealed samples */ +) +{ + uint8_t bitstream_in[LC3PLUS_MAX_BYTES]; + int32_t badFrameIndicator; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Dec_Wrap_Handle is NULL\n" ); + } + if ( NULL == pcm_out ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_out is NULL\n" ); + } + /* LC3plus API requires a non-NULL bitstream pointer, even when triggering concealment */ + badFrameIndicator = 1; + return IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, 0, badFrameIndicator, pcm_out ); +} + + +#ifdef LC3PLUS_DEC_COLLECT_STATS +void printLC3plusDecStats( const IVAS_LC3PLUS_DEC_COLLECT_STATS *stats ) +{ + int32_t sum_pushed_frames = 0; + int32_t sum_decoded_and_dropped_frames, sum_skipped_frames; + + sum_pushed_frames = stats->action_histogram[DEC_ACTION_DECODE_AND_USE] + stats->action_histogram[DEC_ACTION_SKIP] + stats->action_histogram[DEC_ACTION_CACHE]; + + sum_decoded_and_dropped_frames = + stats->action_histogram[DEC_ACTION_DECODE_AND_DROP] + stats->num_cached_frames_decoded_and_dropped; + + sum_skipped_frames = stats->action_histogram[DEC_ACTION_SKIP] + stats->action_histogram[DEC_ACTION_CACHE]; + + if ( sum_pushed_frames == 0 ) + { + printf( "\n Dec didn't run" ); + return; + } + + printf( "\nsum_pushed_frames: %i\n", sum_pushed_frames ); + printf( " DECODE_AND_USE count: %i \n", stats->action_histogram[DEC_ACTION_DECODE_AND_USE] ); + printf( " SKIP count: %i\n", stats->action_histogram[DEC_ACTION_SKIP] ); + printf( " CACHE count: %i\n", stats->action_histogram[DEC_ACTION_CACHE] ); + printf( "Decoded-and-Dropped:\n" ); + printf( " DECODE_AND_DROP count: %i \n", stats->action_histogram[DEC_ACTION_DECODE_AND_DROP] ); + printf( " DEC_CACHE count: %i\n", stats->num_cached_frames_decoded_and_dropped ); + printf( " perc of req : %f\n", 100.f * (float) sum_decoded_and_dropped_frames / sum_pushed_frames ); + printf( "Workload saved: \n" ); + printf( " Skipped perc. of req %f\n", 100.f * (float) sum_skipped_frames / sum_pushed_frames ); +} +#endif diff --git a/lib_rend/ivas_lc3plus_dec.h b/lib_rend/ivas_lc3plus_dec.h new file mode 100644 index 0000000000000000000000000000000000000000..f834f4dcd8b963b9c5e24fd72e7df44c583bf3ac --- /dev/null +++ b/lib_rend/ivas_lc3plus_dec.h @@ -0,0 +1,138 @@ +/****************************************************************************************************** + + (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#pragma once + +#include +#include "lc3.h" +#include "ivas_error.h" +#include "ivas_lc3plus_common.h" +#include "ivas_cnst.h" + +#ifdef DEBUGGING +/* if defined, collects runtime stats and prints them in the DTOR */ +// #define LC3PLUS_DEC_COLLECT_STATS +/* if defined, caching can be disabled, otherwise it's always active */ +// #define LC3PLUS_DEC_ALLOW_DISABLE_CACHING +#endif + +typedef enum +{ + DEC_ACTION_DECODE_AND_DROP = 0, + DEC_ACTION_DECODE_AND_USE, + DEC_ACTION_SKIP, + DEC_ACTION_CACHE, + DEC_ACTION_NUM_ENUMS +} SelectiveDecAction; + +#ifdef LC3PLUS_DEC_COLLECT_STATS +typedef struct IVAS_LC3PLUS_DEC_COLLECT_STATS +{ + int32_t action_histogram[DEC_ACTION_NUM_ENUMS]; + int32_t num_cached_frames_decoded_and_dropped; +} IVAS_LC3PLUS_DEC_COLLECT_STATS; + +void printLC3plusDecStats( const IVAS_LC3PLUS_DEC_COLLECT_STATS *stats ); +#endif + +typedef struct IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE +{ + /*! indicates that the decoder has skipped one or more frames. This means it must decode two frames to flush algorithmic delay when re-activated */ + int16_t has_skipped_a_frame; + /*! if set to 1, decoder will skip decoding for the next frame */ + SelectiveDecAction *frame_actions; + /*! if set to 1, decoder will decode the cache before decoding any of current frames */ + int16_t shall_decode_cached_frame; +} IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE; + +typedef struct IVAS_LC3PLUS_DEC_BITSTREAM_CACHE +{ + uint8_t *bitstream_cache; + int32_t bitstream_cache_capacity; + int32_t bitstream_cache_size; +} IVAS_LC3PLUS_DEC_BITSTREAM_CACHE; + +/* decoder wrapper */ +typedef struct IVAS_LC3PLUS_DEC_HANDLE +{ + LC3PLUS_Dec **handles; + IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE **selective_decoding_states; + IVAS_LC3PLUS_DEC_BITSTREAM_CACHE **bitstream_caches; + uint32_t num_decs; + int16_t *pcm_conversion_buffer; + LC3PLUS_CONFIG config; +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + int16_t cachingEnabled; +#endif +#ifdef LC3PLUS_DEC_COLLECT_STATS + IVAS_LC3PLUS_DEC_COLLECT_STATS stats; +#endif +} * IVAS_LC3PLUS_DEC_HANDLE; + +ivas_error IVAS_LC3PLUS_DEC_Open( + const LC3PLUS_CONFIG config, /* i: decoder configuration */ +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + const int16_t enableCaching, /* i: if set to 0, the decoder will NOT use cached frame to flush algorithmic delay after skipped frames */ +#endif + IVAS_LC3PLUS_DEC_HANDLE *handle /* o: decoder handle */ +); + +ivas_error IVAS_LC3PLUS_DEC_GetDelay( + IVAS_LC3PLUS_DEC_HANDLE handle, /* i: decoder handle */ + int32_t *delayInSamples /* o: algorithmic delay of encoding and decoding in number of samples per channel */ +); + +void IVAS_LC3PLUS_DEC_Close( + IVAS_LC3PLUS_DEC_HANDLE *handle /* i/o: pointer to decoder handle */ +); + +/*! Sets a matrix[MAX_PARAM_SPATIAL_SUBFRAMES][numLC3plusDecoders] where all require subframes must be flagged with 1, frames that are not required with 0 */ +ivas_error IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( + IVAS_LC3PLUS_DEC_HANDLE handle, /* i: decoder handle */ + int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] /* i: */ +); + +ivas_error IVAS_LC3PLUS_DEC_Decode( + IVAS_LC3PLUS_DEC_HANDLE handle, /* i: decoder handle */ + uint8_t *bitstream_in, /* i: pointer to input bitstream */ + int32_t bitstream_in_size, /* i: size of bitstream_in */ + float **pcm_out /* o: decoded samples */ +); + +ivas_error IVAS_LC3PLUS_DEC_Conceal( + IVAS_LC3PLUS_DEC_HANDLE handle, /* i: decoder handle */ + float **pcm_out /* o: concealed samples */ +); + +ivas_error IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( int16_t ***subframeChannelMatrix, uint32_t num_decs ); + +void IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( int16_t **subframeChannelMatrix ); diff --git a/lib_rend/ivas_lc3plus_enc.c b/lib_rend/ivas_lc3plus_enc.c new file mode 100644 index 0000000000000000000000000000000000000000..1b655c6ce99ddad735d57e21481c7e55c7a3b354 --- /dev/null +++ b/lib_rend/ivas_lc3plus_enc.c @@ -0,0 +1,296 @@ +/****************************************************************************************************** + + (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "ivas_lc3plus_enc.h" +#include "ivas_lc3plus_common.h" +#include "lc3.h" +#include "ivas_error_utils.h" +#include "prot.h" +#include "wmc_auto.h" + +ivas_error IVAS_LC3PLUS_ENC_Open( + const LC3PLUS_CONFIG config, /* i: encoder configuration */ + const uint32_t bitsPerSecond, /* i: bit rate */ + IVAS_LC3PLUS_ENC_HANDLE *handle /* o: encoder handle */ +) +{ + int32_t bitsPerSecondPerChannel; + int32_t encoder_size; + LC3PLUS_Error err; + int32_t lfeChans[1] = { 0 }; + int16_t i; + + if ( 0U == config.channels ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid number of channels\n" ); + } + bitsPerSecondPerChannel = bitsPerSecond / config.channels; +#ifdef SPLIT_REND_LC3PLUS_HBR_DBG + if ( bitsPerSecond == (uint32_t) -1 ) + { + bitsPerSecondPerChannel = SPLIT_REND_LC3PLUS_HBR; + } +#endif + + encoder_size = lc3plus_enc_get_size( config.samplerate, 1 ); + if ( 0 == encoder_size ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_size failed\n" ); + } + + *handle = malloc( sizeof( struct IVAS_LC3PLUS_ENC_HANDLE ) ); + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + + ( *handle )->pcm_conversion_buffer = NULL; + ( *handle )->num_encs = 0; + ( *handle )->handles = malloc( config.channels * sizeof( IVAS_LC3PLUS_ENC_HANDLE ) ); + if ( NULL == ( *handle )->handles ) + { + IVAS_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + for ( i = 0; i < config.channels; ++i ) + { + ( *handle )->handles[i] = NULL; + } + ( *handle )->num_encs = config.channels; + + for ( int32_t iCh = 0; iCh < config.channels; iCh++ ) + { + ( *handle )->handles[iCh] = malloc( encoder_size ); + if ( NULL == ( *handle )->handles[iCh] ) + { + IVAS_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder\n" ); + } + + err = lc3plus_enc_init( ( *handle )->handles[iCh], config.samplerate, 1, 0, lfeChans ); + if ( err != LC3PLUS_OK ) + { + IVAS_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_init failed\n" ); + } + + err = lc3plus_enc_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 ); + if ( err != LC3PLUS_OK ) + { + IVAS_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_frame_dms failed\n" ); + } + + err = lc3plus_enc_set_bitrate( ( *handle )->handles[iCh], bitsPerSecondPerChannel ); + if ( err != LC3PLUS_OK ) + { + IVAS_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_bitrate failed\n" ); + } + } + + if ( config.ivas_frame_duration_us < config.lc3plus_frame_duration_us || config.ivas_frame_duration_us % config.lc3plus_frame_duration_us != 0 ) + { + IVAS_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" ); + } + ( *handle )->config = config; + ( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 ); + if ( NULL == ( *handle )->pcm_conversion_buffer ) + { + IVAS_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder wrapper pcm_conversion_buffer\n" ); + } + return IVAS_ERR_OK; +} + +ivas_error IVAS_LC3PLUS_ENC_GetDelay( + IVAS_LC3PLUS_ENC_HANDLE handle, /* i: encoder handle */ + int32_t *delayInSamples /* o: encoder delay in number of samples per channel */ +) +{ + int32_t tmpDelayInSamples; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + if ( NULL == delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "delayInSamples is NULL\n" ); + } + + *delayInSamples = 0; + /* sanity check whether all encoders are actually configured identically */ + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) + { + if ( NULL == handle->handles[iEnc] ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" ); + } + + tmpDelayInSamples = lc3plus_enc_get_delay( handle->handles[iEnc] ); + if ( 0 != *delayInSamples && tmpDelayInSamples != *delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Not all mono LC3plus encoders are configured identically\n" ); + } + *delayInSamples = tmpDelayInSamples; + } + return IVAS_ERR_OK; +} + +ivas_error IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( + IVAS_LC3PLUS_ENC_HANDLE handle, /* i: encoder handle */ + int32_t *bsSize /* o: size of each bitstream frame in bytes */ +) +{ + int32_t bitstreamSizeMultiplier; + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + if ( NULL == bsSize ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bsSize is NULL\n" ); + } + + *bsSize = 0; + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) + { + if ( NULL == handle->handles[iEnc] ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" ); + } + *bsSize += lc3plus_enc_get_num_bytes( handle->handles[iEnc] ); + } + + if ( handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "ivas_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } + bitstreamSizeMultiplier = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; + + *bsSize *= bitstreamSizeMultiplier; + return IVAS_ERR_OK; +} + +void IVAS_LC3PLUS_ENC_Close( + IVAS_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to encoder handle */ +) +{ + if ( NULL == handle || NULL == *handle ) + { + return; + } + for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; iEnc++ ) + { + if ( NULL != ( *handle )->handles[iEnc] ) + { + lc3plus_free_encoder_structs( ( *handle )->handles[iEnc] ); + free( ( *handle )->handles[iEnc] ); + } + } + if ( NULL != ( *handle )->pcm_conversion_buffer ) + { + free( ( *handle )->pcm_conversion_buffer ); + } + free( ( *handle )->handles ); + free( *handle ); + *handle = NULL; +} + +ivas_error IVAS_LC3PLUS_ENC_Encode( + IVAS_LC3PLUS_ENC_HANDLE handle, /* i: encoder handle */ + float **pcm_in, /* i: pointer input samples */ + void *bitstream_out /* o: pointer to bitstream frame */ +) +{ + uint32_t numSamplesPerLC3plusChannel; + uint32_t lc3framesPerIvasFrame; + int32_t ivasSampleIndex; + uint8_t *bitstream_out_iter = bitstream_out; + int32_t num_bytes = 0; + LC3PLUS_Error err; + + push_wmops( "IVAS_LC3PLUS_ENC_Encode" ); + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + if ( NULL == pcm_in ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_in is NULL\n" ); + } + if ( NULL == bitstream_out ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_out is NULL\n" ); + } + + if ( handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "ivas_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } + lc3framesPerIvasFrame = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; + + numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.ivas_frame_duration_us ) / lc3framesPerIvasFrame; + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) + { + for ( uint32_t iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + for ( uint32_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) + { + ivasSampleIndex = iSampleInt16 + iLc3plusFrame * numSamplesPerLC3plusChannel; + handle->pcm_conversion_buffer[iSampleInt16] = max( INT16_MIN, min( pcm_in[iEnc][ivasSampleIndex], INT16_MAX ) ); + } + + num_bytes = 0; + push_wmops( "lc3plus_enc16" ); + err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, bitstream_out_iter, &num_bytes, NULL ); + pop_wmops(); + if ( err != LC3PLUS_OK ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc16 failed\n" ); + } + if ( 0 == num_bytes ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc16 did not produce output\n" ); + } + + bitstream_out_iter += num_bytes; + } + } + + pop_wmops(); + + return IVAS_ERR_OK; +} diff --git a/lib_rend/ivas_lc3plus_enc.h b/lib_rend/ivas_lc3plus_enc.h new file mode 100644 index 0000000000000000000000000000000000000000..1eea994a7eac73a7d24fc065f7915e8b5956b6a5 --- /dev/null +++ b/lib_rend/ivas_lc3plus_enc.h @@ -0,0 +1,73 @@ +/****************************************************************************************************** + + (C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#pragma once + +#include +#include "lc3.h" +#include "ivas_error.h" +#include "ivas_lc3plus_common.h" + +/* encoder wrapper */ +typedef struct IVAS_LC3PLUS_ENC_HANDLE +{ + LC3PLUS_CONFIG config; + LC3PLUS_Enc **handles; + uint32_t num_encs; + int16_t *pcm_conversion_buffer; +} * IVAS_LC3PLUS_ENC_HANDLE; + +ivas_error IVAS_LC3PLUS_ENC_Open( + const LC3PLUS_CONFIG config, /* i: encoder configuration */ + const uint32_t bitsPerSecond, /* i: bit rate */ + IVAS_LC3PLUS_ENC_HANDLE *handle /* o: encoder handle */ +); + +ivas_error IVAS_LC3PLUS_ENC_GetDelay( + IVAS_LC3PLUS_ENC_HANDLE handle, /* i: encoder handle */ + int32_t *delayInSamples /* o: algorithmic delay of encoding and decoding in number of samples per channel */ +); + +ivas_error IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( + IVAS_LC3PLUS_ENC_HANDLE handle, /* i: encoder handle */ + int32_t *bsSize /* o: size of each bitstream frame in bytes */ +); + +void IVAS_LC3PLUS_ENC_Close( + IVAS_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to encoder handle */ +); + +ivas_error IVAS_LC3PLUS_ENC_Encode( + IVAS_LC3PLUS_ENC_HANDLE handle, /* i: encoder handle */ + float **pcm_in, /* i: pointer input samples */ + void *bitstream_out /* o: pointer to bitstream frame */ +); diff --git a/lib_rend/ivas_lcld_tables.c b/lib_rend/ivas_lcld_tables.c new file mode 100644 index 0000000000000000000000000000000000000000..834e0536af61f07e43dd20d2b735b62f4c2cc87e --- /dev/null +++ b/lib_rend/ivas_lcld_tables.c @@ -0,0 +1,53066 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "ivas_lcld_tables.h" +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "ivas_prot_rend.h" +#include "wmc_auto.h" +#include +#include "prot.h" +#include "ivas_PerceptualModel.h" + +/* clang-format off */ + +const float c_afRotRealImagSimple[SIMPLE_PHASE_MAX_VAL + 1][2] = { + { 1.0f, 0.0f }, /* zero */ + { 0.0f, 1.0f }, /* pi/2 */ + { -1.0f, 0.0f }, /* pi */ + { 0.0f, -1.0f }, /* 3*pi/2 */ +}; + +/* phi = (-12:12)'/12 *pi; tmp = [cos(phi),sin(phi)]; tmp = tmp';sprintf('{%.8ff, %.8ff},\n',tmp(:)) */ +const float c_afRotRealImag[PHASE_MAX_VAL - PHASE_MIN_VAL + 1][2] = { + { -1.00000000f, -0.00000000f }, + { -0.96592583f, -0.25881905f }, + { -0.86602540f, -0.50000000f }, + { -0.70710678f, -0.70710678f }, + { -0.50000000f, -0.86602540f }, + { -0.25881905f, -0.96592583f }, + { 0.00000000f, -1.00000000f }, + { 0.25881905f, -0.96592583f }, + { 0.50000000f, -0.86602540f }, + { 0.70710678f, -0.70710678f }, + { 0.86602540f, -0.50000000f }, + { 0.96592583f, -0.25881905f }, + { 1.00000000f, 0.00000000f }, + { 0.96592583f, 0.25881905f }, + { 0.86602540f, 0.50000000f }, + { 0.70710678f, 0.70710678f }, + { 0.50000000f, 0.86602540f }, + { 0.25881905f, 0.96592583f }, + { 0.00000000f, 1.00000000f }, + { -0.25881905f, 0.96592583f }, + { -0.50000000f, 0.86602540f }, + { -0.70710678f, 0.70710678f }, + { -0.86602540f, 0.50000000f }, + { -0.96592583f, 0.25881905f }, + { -1.00000000f, 0.00000000f } +}; + +/* Move this to perceptual model ? */ +const int32_t c_aiBandwidths48[MAX_BANDS_48] = { + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 2, + 2, + 2, + 2, + 2, + 3, + 3, + 4, + 6, + 6, + 7, + 10, +}; + + +const float c_afScaleFactor[ALLOC_TABLE_SIZE] = { + 0.0f, + 0.353553390593f, + 0.420448207627f, + 0.500000000000f, + 0.594603557501f, + 0.707106781187f, + 0.840896415254f, + 1.000000000000f, + 1.189207115003f, + 1.414213562373f, + 1.681792830507f, + 2.000000000000f, + 2.378414230005f, + 2.828427124746f, + 3.363585661015f, + 4.0f, + 4.756828460011f, + 5.656854249492f, + 6.727171322030f, + 8.0f, + 9.513656920022f, + 11.31370849898f, + 13.45434264406f, + 16.00000000000f, + 19.02731384004f, + 22.62741699797f, + 26.90868528812f, + 32.000000000000000f, + 38.054627680087073f, + 45.254833995939038f, + 53.817370576237735f, + 64.000000000000000f, +}; + +const float c_afInvScaleFactor[ALLOC_TABLE_SIZE] = { + 0.0f, + 2.367513562373095f, + 2.046407115002721f, + 1.775900000000000f, + 1.536446415253715f, + 1.323056781186548f, + 1.132903557501360f, + 0.965800000000000f, + 0.821348207626857f, + 0.695103390593274f, + 0.587801778750680f, + 0.495800000000000f, + 0.418124103813429f, + 0.352176695296637f, + 0.296200889375340f, + 0.249400000000000f, + 0.209812051906714f, + 0.176538347648318f, + 0.148525444687670f, + 0.124900000000000f, + 0.105056025953357f, + 0.088388347648318f, + 0.074325444687670f, + 0.062500000000000f, + 0.052556025953357f, + 0.044194173824159f, + 0.037162722343835f, + 0.031250000000000f, + 0.026278012976679f, + 0.022097086912080f, + 0.018581361171918f, + 0.015625000000000f, +}; + +const float c_afRMSEnvReconstructTable[ENV_RECONSTRUCT_TABLE_SIZE] = { + 2.32830644e-10f, + 3.29272254e-10f, + 4.65661287e-10f, + 6.58544508e-10f, + 9.31322575e-10f, + 1.31708902e-09f, + 1.86264515e-09f, + 2.63417803e-09f, + 3.72529030e-09f, + 5.26835606e-09f, + 7.45058060e-09f, + 1.05367121e-08f, + 1.49011612e-08f, + 2.10734243e-08f, + 2.98023224e-08f, + 4.21468485e-08f, + 5.96046448e-08f, + 8.42936970e-08f, + 1.19209290e-07f, + 1.68587394e-07f, + 2.38418579e-07f, + 3.37174788e-07f, + 4.76837158e-07f, + 6.74349576e-07f, + 9.53674316e-07f, + 1.34869915e-06f, + 1.90734863e-06f, + 2.69739830e-06f, + 3.81469727e-06f, + 5.39479661e-06f, + 7.62939453e-06f, + 1.07895932e-05f, + 1.52587891e-05f, + 2.15791864e-05f, + 3.05175781e-05f, + 4.31583729e-05f, + 6.10351562e-05f, + 8.63167458e-05f, + 1.22070312e-04f, + 1.72633492e-04f, + 2.44140625e-04f, + 3.45266983e-04f, + 4.88281250e-04f, + 6.90533966e-04f, + 9.76562500e-04f, + 1.38106793e-03f, + 1.95312500e-03f, + 2.76213586e-03f, + 3.90625000e-03f, + 5.52427173e-03f, + 7.81250000e-03f, + 1.10485435e-02f, + 1.56250000e-02f, + 2.20970869e-02f, + 3.12500000e-02f, + 4.41941738e-02f, + 6.25000000e-02f, + 8.83883476e-02f, + 1.25000000e-01f, + 1.76776695e-01f, + 2.50000000e-01f, + 3.53553391e-01f, + 5.00000000e-01f, + 7.07106781e-01f, + 1.00000000e+00f, + 1.41421356e+00f, + 2.00000000e+00f, + 2.82842712e+00f, + 4.00000000e+00f, + 5.65685425e+00f, + 8.00000000e+00f, + 1.13137085e+01f, + 1.60000000e+01f, + 2.26274170e+01f, + 3.20000000e+01f, + 4.52548340e+01f, + 6.40000000e+01f, + 9.05096680e+01f, + 1.28000000e+02f, + 1.81019336e+02f, + 2.56000000e+02f, + 3.62038672e+02f, + 5.12000000e+02f, + 7.24077344e+02f, + 1.02400000e+03f, + 1.44815469e+03f, + 2.04800000e+03f, + 2.89630938e+03f, + 4.09600000e+03f, + 5.79261875e+03f, + 8.19200000e+03f, + 1.15852375e+04f, + 1.63840000e+04f, + 2.31704750e+04f, + 3.27680000e+04f, + 4.63409500e+04f, + 6.55360000e+04f, + 9.26819000e+04f, + 1.31072000e+05f, + 1.85363800e+05f, + 2.62144000e+05f, + 3.70727600e+05f, + 5.24288000e+05f, + 7.41455200e+05f, + 1.04857600e+06f, + 1.48291040e+06f, + 2.09715200e+06f, + 2.96582080e+06f, + 4.19430400e+06f, + 5.93164160e+06f, + 8.38860800e+06f, + 1.18632832e+07f, + 1.67772160e+07f, + 2.37265664e+07f, + 3.35544320e+07f, + 4.74531328e+07f, + 6.71088640e+07f, + 9.49062656e+07f, + 1.34217728e+08f, + 1.89812531e+08f, + 2.68435456e+08f, + 3.79625062e+08f, + 5.36870912e+08f, + 7.59250125e+08f, + 1.07374182e+09f, + 1.51850025e+09f, + 2.14748365e+09f, + 3.03700050e+09f, + 4.29496730e+09f, +}; + +const int32_t c_aiQuantMaxValues[ALLOC_TABLE_SIZE] = { + 0, + 3, + 3, + 4, + 5, + 5, + 6, + 7, + 8, + 9, + 12, + 13, + 16, + 17, + 19, + 23, + 26, + 26, + 27, + 28, + 31, + 36, + 38, + 45, + 54, + 64, + 76, + 90, + 108, + 128, + 152, + 180, +}; + +const int32_t c_aiHuffmanDim[ALLOC_TABLE_SIZE] = { + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, +}; + +const int32_t c_aiHuffmanMod[ALLOC_TABLE_SIZE] = { + 0, + 4, + 4, + 5, + 6, + 6, + 7, + 8, + 9, + 10, + 13, + 14, + 17, + 18, + 20, + 24, + 27, + 27, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, +}; + +const int32_t c_aiHuffmanSize[ALLOC_TABLE_SIZE] = { + 1, + 16, + 16, + 25, + 36, + 36, + 49, + 64, + 81, + 100, + 169, + 196, + 289, + 324, + 400, + 576, + 729, + 729, + 28, + 29, + 32, + 37, + 39, + 46, + 55, + 65, + 77, + 91, + 109, + 129, + 153, + 181, +}; + +const uint32_t c_aaiRMSEnvHuffEnc[64][2] = { + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0012, 0x000b }, + { 0x000d, 0x0002 }, + { 0x000e, 0x0001 }, + { 0x000e, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0007, 0x0004 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0005, 0x0003 }, + { 0x0004, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0003 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0007 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x0010, 0x0003 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, +}; + +const uint32_t c_aaiRMSEnvHuffDec[13][HUFF_DEC_TABLE_SIZE] = { + { + 0x0002ffff, + 0x0001ffff, + 0x0000001d, + 0x00000022, + 0x0001001e, + 0x0001001e, + 0x00010021, + 0x00010021, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + }, + { + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020023, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + }, + { + 0x0006ffff, + 0x0007ffff, + 0x0003ffff, + 0x0004ffff, + 0x0005ffff, + 0x00000017, + 0x00000018, + 0x00000025, + 0x00010019, + 0x00010019, + 0x00010024, + 0x00010024, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001a, + }, + { + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + }, + { + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + }, + { + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + }, + { + 0x0009ffff, + 0x0008ffff, + 0x0000002c, + 0x0000002d, + 0x00010010, + 0x00010010, + 0x0001002b, + 0x0001002b, + 0x0001002e, + 0x0001002e, + 0x0001002f, + 0x0001002f, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + }, + { + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020029, + 0x00020029, + 0x00020029, + 0x00020029, + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x0002002a, + }, + { + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + }, + { + 0x000bffff, + 0x000cffff, + 0x000affff, + 0x00000031, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x00020030, + 0x00020030, + 0x00020030, + 0x00020030, + }, + { + 0x0001003a, + 0x0001003a, + 0x0001003b, + 0x0001003b, + 0x0001003c, + 0x0001003c, + 0x0001003d, + 0x0001003d, + 0x0001003e, + 0x0001003e, + 0x0001003f, + 0x0001003f, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000b, + }, + { + 0x00000000, + 0x00000001, + 0x00000002, + 0x00000003, + 0x00000004, + 0x00000005, + 0x00010006, + 0x00010006, + 0x00010007, + 0x00010007, + 0x00010008, + 0x00010008, + 0x00010009, + 0x00010009, + 0x0001000a, + 0x0001000a, + }, + { + 0x00010032, + 0x00010032, + 0x00010033, + 0x00010033, + 0x00010034, + 0x00010034, + 0x00010035, + 0x00010035, + 0x00010036, + 0x00010036, + 0x00010037, + 0x00010037, + 0x00010038, + 0x00010038, + 0x00010039, + 0x00010039, + }, +}; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc1[16][2] = +#else +const uint16_t c_aauiCQMFHuffEnc1[16][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0005, 0x0001 }, + { 0x000b, 0x0000 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec1[3][16] = { + { + 0x0001ffff, + 0x00000005, + 0x00010001, + 0x00010001, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x0002ffff, + 0x00000009, + 0x00010006, + 0x00010006, + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020008, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + }, + { + 0x00010003, + 0x00010003, + 0x00010007, + 0x00010007, + 0x0001000a, + 0x0001000a, + 0x0001000b, + 0x0001000b, + 0x0001000c, + 0x0001000c, + 0x0001000d, + 0x0001000d, + 0x0001000e, + 0x0001000e, + 0x0001000f, + 0x0001000f, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc2[16][2] = +#else +const uint16_t c_aauiCQMFHuffEnc2[16][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0005, 0x0001 }, + { 0x000c, 0x0000 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000b, 0x0003 }, + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec2[3][16] = { + { + 0x0001ffff, + 0x00000005, + 0x00010001, + 0x00010001, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x0002ffff, + 0x00000009, + 0x00010006, + 0x00010006, + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020008, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + }, + { + 0x00000003, + 0x00000007, + 0x0000000b, + 0x0000000c, + 0x0000000d, + 0x0000000e, + 0x0001000f, + 0x0001000f, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + }, +}; +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc3[25][2] = +#else +const uint16_t c_aauiCQMFHuffEnc3[25][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000d, 0x0000 }, + { 0x000d, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x0009, 0x0001 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec3[10][16] = { + { + 0x0001ffff, + 0x00000006, + 0x00010001, + 0x00010001, + 0x00020005, + 0x00020005, + 0x00020005, + 0x00020005, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x0002ffff, + 0x0000000c, + 0x00010007, + 0x00010007, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000b, + }, + { + 0x0003ffff, + 0x0004ffff, + 0x0005ffff, + 0x0006ffff, + 0x0007ffff, + 0x0008ffff, + 0x0009ffff, + 0x00000010, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + }, + { + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + }, + { + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + }, + { + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + }, + { + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + }, + { + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + }, + { + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + }, + { + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + }, +}; +#endif + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc4[36][2] = +#else +const uint16_t c_aauiCQMFHuffEnc4[36][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0010, 0x0000 }, + { 0x0010, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000e, 0x0006 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0010, 0x0008 }, + { 0x0010, 0x0009 }, + { 0x0010, 0x000a }, + { 0x0010, 0x000b }, + { 0x0010, 0x000c }, + { 0x0010, 0x000d }, + { 0x0010, 0x000e }, + { 0x0010, 0x000f }, + { 0x0010, 0x0010 }, + { 0x0010, 0x0011 }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec4[5][16] = { + { + 0x0001ffff, + 0x00000007, + 0x00010001, + 0x00010001, + 0x00020006, + 0x00020006, + 0x00020006, + 0x00020006, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x0002ffff, + 0x0000000e, + 0x00010008, + 0x00010008, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + }, + { + 0x0004ffff, + 0x0003ffff, + 0x00010003, + 0x00010003, + 0x00020009, + 0x00020009, + 0x00020009, + 0x00020009, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020013, + }, + { + 0x0000001f, + 0x00000020, + 0x00010021, + 0x00010021, + 0x00010022, + 0x00010022, + 0x00010023, + 0x00010023, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020014, + }, + { + 0x00000004, + 0x00000005, + 0x0000000a, + 0x0000000b, + 0x00000010, + 0x00000011, + 0x00000015, + 0x00000016, + 0x00000017, + 0x00000018, + 0x00000019, + 0x0000001a, + 0x0000001b, + 0x0000001c, + 0x0000001d, + 0x0000001e, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc5[36][2] = +#else +const uint16_t c_aauiCQMFHuffEnc5[36][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000f, 0x0003 }, + { 0x0012, 0x0000 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0011, 0x0008 }, + { 0x0012, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000d, 0x0001 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0011, 0x0009 }, + { 0x0011, 0x000a }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0012, 0x000f }, + { 0x0011, 0x000b }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec5[10][16] = { + { + 0x0001ffff, + 0x00000007, + 0x00010001, + 0x00010001, + 0x00020006, + 0x00020006, + 0x00020006, + 0x00020006, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x0002ffff, + 0x0000000e, + 0x00010008, + 0x00010008, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + }, + { + 0x0003ffff, + 0x0000000f, + 0x00010009, + 0x00010009, + 0x00020003, + 0x00020003, + 0x00020003, + 0x00020003, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020013, + }, + { + 0x0006ffff, + 0x0007ffff, + 0x0008ffff, + 0x0009ffff, + 0x0004ffff, + 0x0005ffff, + 0x00010004, + 0x00010004, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + }, + { + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + }, + { + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + }, + { + 0x00020005, + 0x00020005, + 0x00020005, + 0x00020005, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + }, + { + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020017, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001a, + }, + { + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001e, + }, + { + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020022, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc6[49][2] = +#else +const uint16_t c_aauiCQMFHuffEnc6[49][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x0010, 0x0003 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0002 }, + { 0x0010, 0x0004 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x0012, 0x0007 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x0011, 0x0004 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0010, 0x0005 }, + { 0x000f, 0x0003 }, + { 0x0011, 0x0005 }, + { 0x0014, 0x0009 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0013, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec6[7][16] = { + { + 0x0001ffff, + 0x00000008, + 0x00010001, + 0x00010001, + 0x00020007, + 0x00020007, + 0x00020007, + 0x00020007, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x0002ffff, + 0x00000010, + 0x00010009, + 0x00010009, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x0002000f, + }, + { + 0x0003ffff, + 0x00000017, + 0x00010016, + 0x00010016, + 0x00020003, + 0x00020003, + 0x00020003, + 0x00020003, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020015, + }, + { + 0x0006ffff, + 0x0005ffff, + 0x0004ffff, + 0x00000004, + 0x0000000b, + 0x0000001c, + 0x0001001d, + 0x0001001d, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + }, + { + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + }, + { + 0x00000027, + 0x00000028, + 0x00000029, + 0x0000002a, + 0x0000002b, + 0x0000002c, + 0x0000002d, + 0x0000002e, + 0x0000002f, + 0x00000030, + 0x00010024, + 0x00010024, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + }, + { + 0x00000005, + 0x00000006, + 0x0000000c, + 0x0000000d, + 0x00000013, + 0x00000014, + 0x00000019, + 0x0000001a, + 0x0000001b, + 0x0000001f, + 0x00000020, + 0x00000021, + 0x00000022, + 0x00000023, + 0x00000025, + 0x00000026, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc7[64][2] = +#else +const uint16_t c_aauiCQMFHuffEnc7[64][2] = +#endif + { + { 0x0002, 0x0001 }, + { 0x0002, 0x0002 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000f, 0x0002 }, + { 0x0015, 0x0000 }, + { 0x0015, 0x0001 }, + { 0x0015, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0014, 0x0011 }, + { 0x0015, 0x0003 }, + { 0x0015, 0x0004 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0010, 0x0002 }, + { 0x0015, 0x0005 }, + { 0x0015, 0x0006 }, + { 0x0015, 0x0007 }, + { 0x000a, 0x0001 }, + { 0x0009, 0x0003 }, + { 0x000c, 0x0001 }, + { 0x000f, 0x0004 }, + { 0x0012, 0x0006 }, + { 0x0015, 0x0008 }, + { 0x0015, 0x0009 }, + { 0x0015, 0x000a }, + { 0x000f, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x0010, 0x0003 }, + { 0x0012, 0x0007 }, + { 0x0014, 0x0012 }, + { 0x0015, 0x000b }, + { 0x0015, 0x000c }, + { 0x0015, 0x000d }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0013, 0x000b }, + { 0x0014, 0x0015 }, + { 0x0015, 0x000e }, + { 0x0015, 0x000f }, + { 0x0015, 0x0010 }, + { 0x0015, 0x0011 }, + { 0x0015, 0x0012 }, + { 0x0015, 0x0013 }, + { 0x0015, 0x0014 }, + { 0x0015, 0x0015 }, + { 0x0015, 0x0016 }, + { 0x0015, 0x0017 }, + { 0x0015, 0x0018 }, + { 0x0015, 0x0019 }, + { 0x0015, 0x001a }, + { 0x0015, 0x001b }, + { 0x0015, 0x001c }, + { 0x0015, 0x001d }, + { 0x0015, 0x001e }, + { 0x0015, 0x001f }, + { 0x0015, 0x0020 }, + { 0x0015, 0x0021 }, + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec7[25][16] = { + { + 0x0001ffff, + 0x0002ffff, + 0x00010009, + 0x00010009, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020008, + }, + { + 0x0003ffff, + 0x0004ffff, + 0x00010012, + 0x00010012, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + }, + { + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + }, + { + 0x0005ffff, + 0x0000001a, + 0x00010013, + 0x00010013, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + }, + { + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + }, + { + 0x0007ffff, + 0x0006ffff, + 0x00000014, + 0x00000022, + 0x00010004, + 0x00010004, + 0x0001000c, + 0x0001000c, + 0x0001001b, + 0x0001001b, + 0x00010020, + 0x00010020, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020021, + }, + { + 0x0018ffff, + 0x0000000d, + 0x00000024, + 0x00000028, + 0x00000029, + 0x0000002b, + 0x0001002a, + 0x0001002a, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020023, + }, + { + 0x000effff, + 0x000affff, + 0x000bffff, + 0x000cffff, + 0x0008ffff, + 0x0009ffff, + 0x000dffff, + 0x000fffff, + 0x0010ffff, + 0x0011ffff, + 0x0012ffff, + 0x0013ffff, + 0x0014ffff, + 0x0015ffff, + 0x0016ffff, + 0x0017ffff, + }, + { + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + }, + { + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + }, + { + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + }, + { + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + }, + { + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + }, + { + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + }, + { + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + }, + { + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + }, + { + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + }, + { + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + }, + { + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + }, + { + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + }, + { + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + }, + { + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + }, + { + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + }, + { + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + }, + { + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc8[81][2] = +#else +const uint16_t c_aauiCQMFHuffEnc8[81][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000f, 0x0002 }, + { 0x0014, 0x0008 }, + { 0x0017, 0x0000 }, + { 0x0017, 0x0001 }, + { 0x0017, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000f, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0015, 0x000d }, + { 0x0017, 0x0003 }, + { 0x0017, 0x0004 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x0010, 0x0002 }, + { 0x0013, 0x0005 }, + { 0x0017, 0x0005 }, + { 0x0017, 0x0006 }, + { 0x0017, 0x0007 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000b, 0x0001 }, + { 0x000f, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0016, 0x0015 }, + { 0x0017, 0x0008 }, + { 0x0017, 0x0009 }, + { 0x0017, 0x000a }, + { 0x000f, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x0010, 0x0003 }, + { 0x0012, 0x0006 }, + { 0x0014, 0x0009 }, + { 0x0017, 0x000b }, + { 0x0017, 0x000c }, + { 0x0017, 0x000d }, + { 0x0017, 0x000e }, + { 0x0013, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0013, 0x0007 }, + { 0x0015, 0x000e }, + { 0x0017, 0x000f }, + { 0x0017, 0x0010 }, + { 0x0017, 0x0011 }, + { 0x0017, 0x0012 }, + { 0x0017, 0x0013 }, + { 0x0016, 0x0016 }, + { 0x0016, 0x0017 }, + { 0x0015, 0x000f }, + { 0x0016, 0x0018 }, + { 0x0017, 0x0014 }, + { 0x0017, 0x0015 }, + { 0x0017, 0x0016 }, + { 0x0017, 0x0017 }, + { 0x0017, 0x0018 }, + { 0x0017, 0x0019 }, + { 0x0017, 0x001a }, + { 0x0017, 0x001b }, + { 0x0017, 0x001c }, + { 0x0017, 0x001d }, + { 0x0017, 0x001e }, + { 0x0017, 0x001f }, + { 0x0017, 0x0020 }, + { 0x0017, 0x0021 }, + { 0x0017, 0x0022 }, + { 0x0017, 0x0023 }, + { 0x0017, 0x0024 }, + { 0x0017, 0x0025 }, + { 0x0017, 0x0026 }, + { 0x0017, 0x0027 }, + { 0x0017, 0x0028 }, + { 0x0017, 0x0029 }, + { 0x0016, 0x0019 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec8[16][16] = { + { + 0x0001ffff, + 0x0002ffff, + 0x00010001, + 0x00010001, + 0x00010009, + 0x00010009, + 0x0001000a, + 0x0001000a, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x0003ffff, + 0x0004ffff, + 0x00010014, + 0x00010014, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + }, + { + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + }, + { + 0x0005ffff, + 0x00000015, + 0x0001001d, + 0x0001001d, + 0x00020003, + 0x00020003, + 0x00020003, + 0x00020003, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + }, + { + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + }, + { + 0x0007ffff, + 0x0006ffff, + 0x00000016, + 0x00000026, + 0x00010004, + 0x00010004, + 0x0001000d, + 0x0001000d, + 0x0001001e, + 0x0001001e, + 0x00010024, + 0x00010024, + 0x00020025, + 0x00020025, + 0x00020025, + 0x00020025, + }, + { + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x00020027, + 0x00020027, + 0x00020027, + 0x00020027, + 0x0002002e, + 0x0002002e, + 0x0002002e, + 0x0002002e, + }, + { + 0x000bffff, + 0x000cffff, + 0x000dffff, + 0x000effff, + 0x000fffff, + 0x000affff, + 0x0008ffff, + 0x0009ffff, + 0x00000005, + 0x00000028, + 0x00010017, + 0x00010017, + 0x0001002d, + 0x0001002d, + 0x0001002f, + 0x0001002f, + }, + { + 0x00020039, + 0x00020039, + 0x00020039, + 0x00020039, + 0x00020050, + 0x00020050, + 0x00020050, + 0x00020050, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + }, + { + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + }, + { + 0x0001004e, + 0x0001004e, + 0x0001004f, + 0x0001004f, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020036, + 0x00020036, + 0x00020036, + 0x00020036, + 0x00020037, + 0x00020037, + 0x00020037, + 0x00020037, + }, + { + 0x00010006, + 0x00010006, + 0x00010007, + 0x00010007, + 0x00010008, + 0x00010008, + 0x00010010, + 0x00010010, + 0x00010011, + 0x00010011, + 0x00010018, + 0x00010018, + 0x00010019, + 0x00010019, + 0x0001001a, + 0x0001001a, + }, + { + 0x00010021, + 0x00010021, + 0x00010022, + 0x00010022, + 0x00010023, + 0x00010023, + 0x00010029, + 0x00010029, + 0x0001002a, + 0x0001002a, + 0x0001002b, + 0x0001002b, + 0x0001002c, + 0x0001002c, + 0x00010031, + 0x00010031, + }, + { + 0x00010032, + 0x00010032, + 0x00010033, + 0x00010033, + 0x00010034, + 0x00010034, + 0x00010035, + 0x00010035, + 0x0001003a, + 0x0001003a, + 0x0001003b, + 0x0001003b, + 0x0001003c, + 0x0001003c, + 0x0001003d, + 0x0001003d, + }, + { + 0x0001003e, + 0x0001003e, + 0x0001003f, + 0x0001003f, + 0x00010040, + 0x00010040, + 0x00010041, + 0x00010041, + 0x00010042, + 0x00010042, + 0x00010043, + 0x00010043, + 0x00010044, + 0x00010044, + 0x00010045, + 0x00010045, + }, + { + 0x00010046, + 0x00010046, + 0x00010047, + 0x00010047, + 0x00010048, + 0x00010048, + 0x00010049, + 0x00010049, + 0x0001004a, + 0x0001004a, + 0x0001004b, + 0x0001004b, + 0x0001004c, + 0x0001004c, + 0x0001004d, + 0x0001004d, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc9[100][2] = +#else +const uint16_t c_aauiCQMFHuffEnc9[100][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000d, 0x0002 }, + { 0x0011, 0x0004 }, + { 0x0014, 0x000a }, + { 0x0017, 0x0000 }, + { 0x0017, 0x0001 }, + { 0x0017, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0013, 0x0007 }, + { 0x0016, 0x0018 }, + { 0x0017, 0x0003 }, + { 0x0017, 0x0004 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0002 }, + { 0x000e, 0x0002 }, + { 0x0011, 0x0005 }, + { 0x0014, 0x000b }, + { 0x0016, 0x0019 }, + { 0x0017, 0x0005 }, + { 0x0017, 0x0006 }, + { 0x0009, 0x0003 }, + { 0x0008, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0015, 0x000f }, + { 0x0017, 0x0007 }, + { 0x0017, 0x0008 }, + { 0x0017, 0x0009 }, + { 0x000d, 0x0005 }, + { 0x000c, 0x0003 }, + { 0x000e, 0x0003 }, + { 0x0010, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0014, 0x000c }, + { 0x0017, 0x000a }, + { 0x0016, 0x001a }, + { 0x0017, 0x000b }, + { 0x0017, 0x000c }, + { 0x0011, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0011, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0015, 0x0010 }, + { 0x0017, 0x000d }, + { 0x0017, 0x000e }, + { 0x0017, 0x000f }, + { 0x0017, 0x0010 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0014, 0x000d }, + { 0x0015, 0x0011 }, + { 0x0017, 0x0011 }, + { 0x0016, 0x001b }, + { 0x0017, 0x0012 }, + { 0x0017, 0x0013 }, + { 0x0017, 0x0014 }, + { 0x0017, 0x0015 }, + { 0x0017, 0x0016 }, + { 0x0015, 0x0012 }, + { 0x0015, 0x0013 }, + { 0x0017, 0x0017 }, + { 0x0016, 0x001c }, + { 0x0017, 0x0018 }, + { 0x0017, 0x0019 }, + { 0x0017, 0x001a }, + { 0x0017, 0x001b }, + { 0x0017, 0x001c }, + { 0x0017, 0x001d }, + { 0x0017, 0x001e }, + { 0x0017, 0x001f }, + { 0x0017, 0x0020 }, + { 0x0017, 0x0021 }, + { 0x0017, 0x0022 }, + { 0x0017, 0x0023 }, + { 0x0017, 0x0024 }, + { 0x0017, 0x0025 }, + { 0x0017, 0x0026 }, + { 0x0017, 0x0027 }, + { 0x0017, 0x0028 }, + { 0x0017, 0x0029 }, + { 0x0017, 0x002a }, + { 0x0017, 0x002b }, + { 0x0017, 0x002c }, + { 0x0017, 0x002d }, + { 0x0017, 0x002e }, + { 0x0017, 0x002f }, + { 0x0016, 0x001d }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec9[22][16] = { + { + 0x0001ffff, + 0x0002ffff, + 0x00010001, + 0x00010001, + 0x0001000a, + 0x0001000a, + 0x0001000b, + 0x0001000b, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x0003ffff, + 0x0004ffff, + 0x00000016, + 0x0000001f, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + }, + { + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + }, + { + 0x0007ffff, + 0x0005ffff, + 0x0006ffff, + 0x00000029, + 0x00010017, + 0x00010017, + 0x00010020, + 0x00010020, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + }, + { + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + }, + { + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + }, + { + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + }, + { + 0x000bffff, + 0x000affff, + 0x0008ffff, + 0x0009ffff, + 0x0000000f, + 0x00000022, + 0x0000002b, + 0x00000033, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020018, + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x0002002a, + }, + { + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + }, + { + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + }, + { + 0x00010035, + 0x00010035, + 0x00010036, + 0x00010036, + 0x0001003c, + 0x0001003c, + 0x0001003d, + 0x0001003d, + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020023, + 0x0002002c, + 0x0002002c, + 0x0002002c, + 0x0002002c, + }, + { + 0x0010ffff, + 0x0011ffff, + 0x0012ffff, + 0x0013ffff, + 0x0014ffff, + 0x0015ffff, + 0x000fffff, + 0x000dffff, + 0x000cffff, + 0x000effff, + 0x00000006, + 0x0000001a, + 0x0000002d, + 0x0000003e, + 0x00010010, + 0x00010010, + }, + { + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + }, + { + 0x0002004a, + 0x0002004a, + 0x0002004a, + 0x0002004a, + 0x00020063, + 0x00020063, + 0x00020063, + 0x00020063, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + }, + { + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + }, + { + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002002f, + 0x0002002f, + 0x0002002f, + 0x0002002f, + 0x00020041, + 0x00020041, + 0x00020041, + 0x00020041, + }, + { + 0x00010007, + 0x00010007, + 0x00010008, + 0x00010008, + 0x00010009, + 0x00010009, + 0x00010012, + 0x00010012, + 0x00010013, + 0x00010013, + 0x0001001c, + 0x0001001c, + 0x0001001d, + 0x0001001d, + 0x00010025, + 0x00010025, + }, + { + 0x00010026, + 0x00010026, + 0x00010027, + 0x00010027, + 0x0001002e, + 0x0001002e, + 0x00010030, + 0x00010030, + 0x00010031, + 0x00010031, + 0x00010038, + 0x00010038, + 0x00010039, + 0x00010039, + 0x0001003a, + 0x0001003a, + }, + { + 0x0001003b, + 0x0001003b, + 0x00010040, + 0x00010040, + 0x00010042, + 0x00010042, + 0x00010043, + 0x00010043, + 0x00010044, + 0x00010044, + 0x00010045, + 0x00010045, + 0x00010046, + 0x00010046, + 0x00010049, + 0x00010049, + }, + { + 0x0001004b, + 0x0001004b, + 0x0001004c, + 0x0001004c, + 0x0001004d, + 0x0001004d, + 0x0001004e, + 0x0001004e, + 0x0001004f, + 0x0001004f, + 0x00010050, + 0x00010050, + 0x00010051, + 0x00010051, + 0x00010052, + 0x00010052, + }, + { + 0x00010053, + 0x00010053, + 0x00010054, + 0x00010054, + 0x00010055, + 0x00010055, + 0x00010056, + 0x00010056, + 0x00010057, + 0x00010057, + 0x00010058, + 0x00010058, + 0x00010059, + 0x00010059, + 0x0001005a, + 0x0001005a, + }, + { + 0x0001005b, + 0x0001005b, + 0x0001005c, + 0x0001005c, + 0x0001005d, + 0x0001005d, + 0x0001005e, + 0x0001005e, + 0x0001005f, + 0x0001005f, + 0x00010060, + 0x00010060, + 0x00010061, + 0x00010061, + 0x00010062, + 0x00010062, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc10[169][2] = +#else +const uint16_t c_aauiCQMFHuffEnc10[169][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0004, 0x0002 }, + { 0x0005, 0x0002 }, + { 0x0007, 0x0002 }, + { 0x000a, 0x0002 }, + { 0x000e, 0x0004 }, + { 0x0011, 0x0007 }, + { 0x0013, 0x0012 }, + { 0x0016, 0x0000 }, + { 0x0016, 0x0001 }, + { 0x0016, 0x0002 }, + { 0x0016, 0x0003 }, + { 0x0016, 0x0004 }, + { 0x0004, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0007, 0x0003 }, + { 0x000a, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x0010, 0x0007 }, + { 0x0013, 0x0013 }, + { 0x0015, 0x0035 }, + { 0x0016, 0x0005 }, + { 0x0016, 0x0006 }, + { 0x0016, 0x0007 }, + { 0x0016, 0x0008 }, + { 0x0005, 0x0003 }, + { 0x0004, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0002 }, + { 0x000e, 0x0005 }, + { 0x0010, 0x0008 }, + { 0x0013, 0x0014 }, + { 0x0014, 0x001d }, + { 0x0016, 0x0009 }, + { 0x0016, 0x000a }, + { 0x0016, 0x000b }, + { 0x0016, 0x000c }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000f, 0x0005 }, + { 0x0011, 0x0008 }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0016, 0x000d }, + { 0x0016, 0x000e }, + { 0x0016, 0x000f }, + { 0x0016, 0x0010 }, + { 0x000a, 0x0005 }, + { 0x0009, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000d, 0x0006 }, + { 0x000f, 0x0006 }, + { 0x0011, 0x0009 }, + { 0x0013, 0x0015 }, + { 0x0014, 0x0020 }, + { 0x0016, 0x0011 }, + { 0x0016, 0x0012 }, + { 0x0016, 0x0013 }, + { 0x0016, 0x0014 }, + { 0x0016, 0x0015 }, + { 0x000e, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0007 }, + { 0x000f, 0x0007 }, + { 0x0011, 0x000a }, + { 0x0012, 0x000c }, + { 0x0016, 0x0016 }, + { 0x0016, 0x0017 }, + { 0x0016, 0x0018 }, + { 0x0016, 0x0019 }, + { 0x0016, 0x001a }, + { 0x0016, 0x001b }, + { 0x0016, 0x001c }, + { 0x0011, 0x000b }, + { 0x0010, 0x0009 }, + { 0x0011, 0x000c }, + { 0x0011, 0x000d }, + { 0x0013, 0x0016 }, + { 0x0016, 0x001d }, + { 0x0016, 0x001e }, + { 0x0016, 0x001f }, + { 0x0016, 0x0020 }, + { 0x0016, 0x0021 }, + { 0x0016, 0x0022 }, + { 0x0016, 0x0023 }, + { 0x0016, 0x0024 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0012, 0x000d }, + { 0x0013, 0x0017 }, + { 0x0016, 0x0025 }, + { 0x0016, 0x0026 }, + { 0x0016, 0x0027 }, + { 0x0016, 0x0028 }, + { 0x0016, 0x0029 }, + { 0x0016, 0x002a }, + { 0x0016, 0x002b }, + { 0x0016, 0x002c }, + { 0x0016, 0x002d }, + { 0x0015, 0x0036 }, + { 0x0015, 0x0037 }, + { 0x0014, 0x0023 }, + { 0x0015, 0x0038 }, + { 0x0016, 0x002e }, + { 0x0016, 0x002f }, + { 0x0016, 0x0030 }, + { 0x0016, 0x0031 }, + { 0x0016, 0x0032 }, + { 0x0016, 0x0033 }, + { 0x0016, 0x0034 }, + { 0x0016, 0x0035 }, + { 0x0016, 0x0036 }, + { 0x0016, 0x0037 }, + { 0x0016, 0x0038 }, + { 0x0016, 0x0039 }, + { 0x0016, 0x003a }, + { 0x0016, 0x003b }, + { 0x0016, 0x003c }, + { 0x0016, 0x003d }, + { 0x0016, 0x003e }, + { 0x0016, 0x003f }, + { 0x0016, 0x0040 }, + { 0x0016, 0x0041 }, + { 0x0016, 0x0042 }, + { 0x0016, 0x0043 }, + { 0x0016, 0x0044 }, + { 0x0016, 0x0045 }, + { 0x0016, 0x0046 }, + { 0x0016, 0x0047 }, + { 0x0016, 0x0048 }, + { 0x0016, 0x0049 }, + { 0x0016, 0x004a }, + { 0x0016, 0x004b }, + { 0x0016, 0x004c }, + { 0x0016, 0x004d }, + { 0x0016, 0x004e }, + { 0x0016, 0x004f }, + { 0x0016, 0x0050 }, + { 0x0016, 0x0051 }, + { 0x0016, 0x0052 }, + { 0x0016, 0x0053 }, + { 0x0016, 0x0054 }, + { 0x0016, 0x0055 }, + { 0x0016, 0x0056 }, + { 0x0016, 0x0057 }, + { 0x0016, 0x0058 }, + { 0x0016, 0x0059 }, + { 0x0016, 0x005a }, + { 0x0016, 0x005b }, + { 0x0016, 0x005c }, + { 0x0016, 0x005d }, + { 0x0016, 0x005e }, + { 0x0016, 0x005f }, + { 0x0016, 0x0060 }, + { 0x0016, 0x0061 }, + { 0x0016, 0x0062 }, + { 0x0016, 0x0063 }, + { 0x0016, 0x0064 }, + { 0x0016, 0x0065 }, + { 0x0016, 0x0066 }, + { 0x0016, 0x0067 }, + { 0x0016, 0x0068 }, + { 0x0016, 0x0069 }, + { 0x0015, 0x0039 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec10[45][16] = { + { + 0x0002ffff, + 0x0001ffff, + 0x00000001, + 0x0000000d, + 0x0000000f, + 0x0000001b, + 0x0001000e, + 0x0001000e, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + }, + { + 0x0004ffff, + 0x0003ffff, + 0x0000001d, + 0x00000029, + 0x00010003, + 0x00010003, + 0x00010010, + 0x00010010, + 0x00010027, + 0x00010027, + 0x00010028, + 0x00010028, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001c, + }, + { + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x00020034, + 0x00020034, + 0x00020034, + 0x00020034, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + }, + { + 0x0008ffff, + 0x0007ffff, + 0x0005ffff, + 0x0006ffff, + 0x0001001e, + 0x0001001e, + 0x00010036, + 0x00010036, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + }, + { + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + }, + { + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + }, + { + 0x00020005, + 0x00020005, + 0x00020005, + 0x00020005, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x00020041, + 0x00020041, + 0x00020041, + 0x00020041, + 0x00020043, + 0x00020043, + 0x00020043, + 0x00020043, + }, + { + 0x0012ffff, + 0x000effff, + 0x000dffff, + 0x000affff, + 0x0009ffff, + 0x000bffff, + 0x000cffff, + 0x00000013, + 0x00000020, + 0x0000004f, + 0x0001002c, + 0x0001002c, + 0x00010038, + 0x00010038, + 0x00010044, + 0x00010044, + }, + { + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + }, + { + 0x00020046, + 0x00020046, + 0x00020046, + 0x00020046, + 0x0002005d, + 0x0002005d, + 0x0002005d, + 0x0002005d, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + }, + { + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + }, + { + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + }, + { + 0x0000003b, + 0x0000005b, + 0x0000005c, + 0x0000006a, + 0x00010007, + 0x00010007, + 0x00010014, + 0x00010014, + 0x00010021, + 0x00010021, + 0x0001003a, + 0x0001003a, + 0x00010052, + 0x00010052, + 0x0001005e, + 0x0001005e, + }, + { + 0x0023ffff, + 0x0024ffff, + 0x0025ffff, + 0x0026ffff, + 0x0027ffff, + 0x0028ffff, + 0x0029ffff, + 0x002affff, + 0x002bffff, + 0x002cffff, + 0x000fffff, + 0x0010ffff, + 0x0011ffff, + 0x00000022, + 0x0000002e, + 0x0000002f, + }, + { + 0x000200a6, + 0x000200a6, + 0x000200a6, + 0x000200a6, + 0x000200a7, + 0x000200a7, + 0x000200a7, + 0x000200a7, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + }, + { + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + }, + { + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x000300a8, + 0x000300a8, + 0x000300a8, + 0x000300a8, + 0x000300a8, + 0x000300a8, + 0x000300a8, + 0x000300a8, + }, + { + 0x0014ffff, + 0x0017ffff, + 0x0015ffff, + 0x0016ffff, + 0x001cffff, + 0x0013ffff, + 0x0018ffff, + 0x0019ffff, + 0x001affff, + 0x001bffff, + 0x001dffff, + 0x001effff, + 0x001fffff, + 0x0020ffff, + 0x0021ffff, + 0x0022ffff, + }, + { + 0x0002003f, + 0x0002003f, + 0x0002003f, + 0x0002003f, + 0x00020040, + 0x00020040, + 0x00020040, + 0x00020040, + 0x00020047, + 0x00020047, + 0x00020047, + 0x00020047, + 0x00020048, + 0x00020048, + 0x00020048, + 0x00020048, + }, + { + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020009, + 0x00020009, + 0x00020009, + 0x00020009, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000b, + }, + { + 0x00020019, + 0x00020019, + 0x00020019, + 0x00020019, + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020024, + 0x00020024, + 0x00020024, + 0x00020024, + 0x00020025, + 0x00020025, + 0x00020025, + 0x00020025, + }, + { + 0x00020026, + 0x00020026, + 0x00020026, + 0x00020026, + 0x00020030, + 0x00020030, + 0x00020030, + 0x00020030, + 0x00020031, + 0x00020031, + 0x00020031, + 0x00020031, + 0x00020032, + 0x00020032, + 0x00020032, + 0x00020032, + }, + { + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020018, + }, + { + 0x00020049, + 0x00020049, + 0x00020049, + 0x00020049, + 0x0002004a, + 0x0002004a, + 0x0002004a, + 0x0002004a, + 0x0002004b, + 0x0002004b, + 0x0002004b, + 0x0002004b, + 0x0002004c, + 0x0002004c, + 0x0002004c, + 0x0002004c, + }, + { + 0x0002004d, + 0x0002004d, + 0x0002004d, + 0x0002004d, + 0x00020053, + 0x00020053, + 0x00020053, + 0x00020053, + 0x00020054, + 0x00020054, + 0x00020054, + 0x00020054, + 0x00020055, + 0x00020055, + 0x00020055, + 0x00020055, + }, + { + 0x00020056, + 0x00020056, + 0x00020056, + 0x00020056, + 0x00020057, + 0x00020057, + 0x00020057, + 0x00020057, + 0x00020058, + 0x00020058, + 0x00020058, + 0x00020058, + 0x00020059, + 0x00020059, + 0x00020059, + 0x00020059, + }, + { + 0x0002005a, + 0x0002005a, + 0x0002005a, + 0x0002005a, + 0x0002005f, + 0x0002005f, + 0x0002005f, + 0x0002005f, + 0x00020060, + 0x00020060, + 0x00020060, + 0x00020060, + 0x00020061, + 0x00020061, + 0x00020061, + 0x00020061, + }, + { + 0x00020033, + 0x00020033, + 0x00020033, + 0x00020033, + 0x0002003c, + 0x0002003c, + 0x0002003c, + 0x0002003c, + 0x0002003d, + 0x0002003d, + 0x0002003d, + 0x0002003d, + 0x0002003e, + 0x0002003e, + 0x0002003e, + 0x0002003e, + }, + { + 0x00020062, + 0x00020062, + 0x00020062, + 0x00020062, + 0x00020063, + 0x00020063, + 0x00020063, + 0x00020063, + 0x00020064, + 0x00020064, + 0x00020064, + 0x00020064, + 0x00020065, + 0x00020065, + 0x00020065, + 0x00020065, + }, + { + 0x00020066, + 0x00020066, + 0x00020066, + 0x00020066, + 0x00020067, + 0x00020067, + 0x00020067, + 0x00020067, + 0x0002006c, + 0x0002006c, + 0x0002006c, + 0x0002006c, + 0x0002006d, + 0x0002006d, + 0x0002006d, + 0x0002006d, + }, + { + 0x0002006e, + 0x0002006e, + 0x0002006e, + 0x0002006e, + 0x0002006f, + 0x0002006f, + 0x0002006f, + 0x0002006f, + 0x00020070, + 0x00020070, + 0x00020070, + 0x00020070, + 0x00020071, + 0x00020071, + 0x00020071, + 0x00020071, + }, + { + 0x00020072, + 0x00020072, + 0x00020072, + 0x00020072, + 0x00020073, + 0x00020073, + 0x00020073, + 0x00020073, + 0x00020074, + 0x00020074, + 0x00020074, + 0x00020074, + 0x00020075, + 0x00020075, + 0x00020075, + 0x00020075, + }, + { + 0x00020076, + 0x00020076, + 0x00020076, + 0x00020076, + 0x00020077, + 0x00020077, + 0x00020077, + 0x00020077, + 0x00020078, + 0x00020078, + 0x00020078, + 0x00020078, + 0x00020079, + 0x00020079, + 0x00020079, + 0x00020079, + }, + { + 0x0002007a, + 0x0002007a, + 0x0002007a, + 0x0002007a, + 0x0002007b, + 0x0002007b, + 0x0002007b, + 0x0002007b, + 0x0002007c, + 0x0002007c, + 0x0002007c, + 0x0002007c, + 0x0002007d, + 0x0002007d, + 0x0002007d, + 0x0002007d, + }, + { + 0x0002007e, + 0x0002007e, + 0x0002007e, + 0x0002007e, + 0x0002007f, + 0x0002007f, + 0x0002007f, + 0x0002007f, + 0x00020080, + 0x00020080, + 0x00020080, + 0x00020080, + 0x00020081, + 0x00020081, + 0x00020081, + 0x00020081, + }, + { + 0x00020082, + 0x00020082, + 0x00020082, + 0x00020082, + 0x00020083, + 0x00020083, + 0x00020083, + 0x00020083, + 0x00020084, + 0x00020084, + 0x00020084, + 0x00020084, + 0x00020085, + 0x00020085, + 0x00020085, + 0x00020085, + }, + { + 0x00020086, + 0x00020086, + 0x00020086, + 0x00020086, + 0x00020087, + 0x00020087, + 0x00020087, + 0x00020087, + 0x00020088, + 0x00020088, + 0x00020088, + 0x00020088, + 0x00020089, + 0x00020089, + 0x00020089, + 0x00020089, + }, + { + 0x0002008a, + 0x0002008a, + 0x0002008a, + 0x0002008a, + 0x0002008b, + 0x0002008b, + 0x0002008b, + 0x0002008b, + 0x0002008c, + 0x0002008c, + 0x0002008c, + 0x0002008c, + 0x0002008d, + 0x0002008d, + 0x0002008d, + 0x0002008d, + }, + { + 0x0002008e, + 0x0002008e, + 0x0002008e, + 0x0002008e, + 0x0002008f, + 0x0002008f, + 0x0002008f, + 0x0002008f, + 0x00020090, + 0x00020090, + 0x00020090, + 0x00020090, + 0x00020091, + 0x00020091, + 0x00020091, + 0x00020091, + }, + { + 0x00020092, + 0x00020092, + 0x00020092, + 0x00020092, + 0x00020093, + 0x00020093, + 0x00020093, + 0x00020093, + 0x00020094, + 0x00020094, + 0x00020094, + 0x00020094, + 0x00020095, + 0x00020095, + 0x00020095, + 0x00020095, + }, + { + 0x00020096, + 0x00020096, + 0x00020096, + 0x00020096, + 0x00020097, + 0x00020097, + 0x00020097, + 0x00020097, + 0x00020098, + 0x00020098, + 0x00020098, + 0x00020098, + 0x00020099, + 0x00020099, + 0x00020099, + 0x00020099, + }, + { + 0x0002009a, + 0x0002009a, + 0x0002009a, + 0x0002009a, + 0x0002009b, + 0x0002009b, + 0x0002009b, + 0x0002009b, + 0x0002009c, + 0x0002009c, + 0x0002009c, + 0x0002009c, + 0x0002009d, + 0x0002009d, + 0x0002009d, + 0x0002009d, + }, + { + 0x0002009e, + 0x0002009e, + 0x0002009e, + 0x0002009e, + 0x0002009f, + 0x0002009f, + 0x0002009f, + 0x0002009f, + 0x000200a0, + 0x000200a0, + 0x000200a0, + 0x000200a0, + 0x000200a1, + 0x000200a1, + 0x000200a1, + 0x000200a1, + }, + { + 0x000200a2, + 0x000200a2, + 0x000200a2, + 0x000200a2, + 0x000200a3, + 0x000200a3, + 0x000200a3, + 0x000200a3, + 0x000200a4, + 0x000200a4, + 0x000200a4, + 0x000200a4, + 0x000200a5, + 0x000200a5, + 0x000200a5, + 0x000200a5, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc11[196][2] = +#else +const uint16_t c_aauiCQMFHuffEnc11[196][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0012, 0x000d }, + { 0x0014, 0x001f }, + { 0x0016, 0x0000 }, + { 0x0016, 0x0001 }, + { 0x0016, 0x0002 }, + { 0x0016, 0x0003 }, + { 0x0016, 0x0004 }, + { 0x0004, 0x0004 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0006, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x000b, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x0010, 0x0007 }, + { 0x0012, 0x000e }, + { 0x0014, 0x0020 }, + { 0x0016, 0x0005 }, + { 0x0016, 0x0006 }, + { 0x0016, 0x0007 }, + { 0x0016, 0x0008 }, + { 0x0005, 0x0005 }, + { 0x0004, 0x0005 }, + { 0x0006, 0x0004 }, + { 0x0007, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x0011, 0x000a }, + { 0x0012, 0x000f }, + { 0x0015, 0x003b }, + { 0x0016, 0x0009 }, + { 0x0016, 0x000a }, + { 0x0016, 0x000b }, + { 0x0016, 0x000c }, + { 0x0007, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0005 }, + { 0x000b, 0x0005 }, + { 0x000d, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x0012, 0x0010 }, + { 0x0014, 0x0021 }, + { 0x0016, 0x000d }, + { 0x0016, 0x000e }, + { 0x0016, 0x000f }, + { 0x0016, 0x0010 }, + { 0x0016, 0x0011 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000d, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x0011, 0x000b }, + { 0x0013, 0x0017 }, + { 0x0014, 0x0022 }, + { 0x0016, 0x0012 }, + { 0x0016, 0x0013 }, + { 0x0016, 0x0014 }, + { 0x0016, 0x0015 }, + { 0x0016, 0x0016 }, + { 0x000c, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x0008 }, + { 0x0012, 0x0011 }, + { 0x0014, 0x0023 }, + { 0x0015, 0x003c }, + { 0x0016, 0x0017 }, + { 0x0016, 0x0018 }, + { 0x0016, 0x0019 }, + { 0x0016, 0x001a }, + { 0x0016, 0x001b }, + { 0x000f, 0x0008 }, + { 0x000e, 0x0008 }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0009 }, + { 0x0011, 0x000c }, + { 0x0013, 0x0018 }, + { 0x0014, 0x0024 }, + { 0x0016, 0x001c }, + { 0x0016, 0x001d }, + { 0x0016, 0x001e }, + { 0x0016, 0x001f }, + { 0x0016, 0x0020 }, + { 0x0016, 0x0021 }, + { 0x0016, 0x0022 }, + { 0x0011, 0x000d }, + { 0x0010, 0x0009 }, + { 0x0012, 0x0012 }, + { 0x0012, 0x0013 }, + { 0x0014, 0x0025 }, + { 0x0015, 0x003d }, + { 0x0014, 0x0026 }, + { 0x0016, 0x0023 }, + { 0x0016, 0x0024 }, + { 0x0016, 0x0025 }, + { 0x0016, 0x0026 }, + { 0x0016, 0x0027 }, + { 0x0016, 0x0028 }, + { 0x0016, 0x0029 }, + { 0x0014, 0x0027 }, + { 0x0013, 0x0019 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0016, 0x002a }, + { 0x0016, 0x002b }, + { 0x0016, 0x002c }, + { 0x0016, 0x002d }, + { 0x0016, 0x002e }, + { 0x0016, 0x002f }, + { 0x0016, 0x0030 }, + { 0x0016, 0x0031 }, + { 0x0016, 0x0032 }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0016, 0x0033 }, + { 0x0016, 0x0034 }, + { 0x0016, 0x0035 }, + { 0x0016, 0x0036 }, + { 0x0016, 0x0037 }, + { 0x0016, 0x0038 }, + { 0x0016, 0x0039 }, + { 0x0016, 0x003a }, + { 0x0016, 0x003b }, + { 0x0016, 0x003c }, + { 0x0016, 0x003d }, + { 0x0016, 0x003e }, + { 0x0016, 0x003f }, + { 0x0016, 0x0040 }, + { 0x0016, 0x0041 }, + { 0x0016, 0x0042 }, + { 0x0016, 0x0043 }, + { 0x0016, 0x0044 }, + { 0x0016, 0x0045 }, + { 0x0016, 0x0046 }, + { 0x0016, 0x0047 }, + { 0x0016, 0x0048 }, + { 0x0016, 0x0049 }, + { 0x0016, 0x004a }, + { 0x0016, 0x004b }, + { 0x0016, 0x004c }, + { 0x0016, 0x004d }, + { 0x0016, 0x004e }, + { 0x0016, 0x004f }, + { 0x0016, 0x0050 }, + { 0x0016, 0x0051 }, + { 0x0016, 0x0052 }, + { 0x0016, 0x0053 }, + { 0x0016, 0x0054 }, + { 0x0016, 0x0055 }, + { 0x0016, 0x0056 }, + { 0x0016, 0x0057 }, + { 0x0016, 0x0058 }, + { 0x0016, 0x0059 }, + { 0x0016, 0x005a }, + { 0x0016, 0x005b }, + { 0x0016, 0x005c }, + { 0x0016, 0x005d }, + { 0x0016, 0x005e }, + { 0x0016, 0x005f }, + { 0x0016, 0x0060 }, + { 0x0016, 0x0061 }, + { 0x0016, 0x0062 }, + { 0x0016, 0x0063 }, + { 0x0016, 0x0064 }, + { 0x0016, 0x0065 }, + { 0x0016, 0x0066 }, + { 0x0016, 0x0067 }, + { 0x0016, 0x0068 }, + { 0x0016, 0x0069 }, + { 0x0016, 0x006a }, + { 0x0016, 0x006b }, + { 0x0016, 0x006c }, + { 0x0016, 0x006d }, + { 0x0016, 0x006e }, + { 0x0016, 0x006f }, + { 0x0016, 0x0070 }, + { 0x0016, 0x0071 }, + { 0x0016, 0x0072 }, + { 0x0016, 0x0073 }, + { 0x0016, 0x0074 }, + { 0x0016, 0x0075 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec11[50][16] = { + { + 0x0003ffff, + 0x0001ffff, + 0x0002ffff, + 0x00000001, + 0x0000000e, + 0x0000001d, + 0x0001000f, + 0x0001000f, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002002b, + 0x0002002b, + 0x0002002b, + 0x0002002b, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + }, + { + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + }, + { + 0x0007ffff, + 0x0005ffff, + 0x0004ffff, + 0x0006ffff, + 0x00010003, + 0x00010003, + 0x0001001f, + 0x0001001f, + 0x0001002a, + 0x0001002a, + 0x0001002c, + 0x0001002c, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + }, + { + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + }, + { + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + 0x0002003a, + 0x0002003a, + 0x0002003a, + 0x0002003a, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + }, + { + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + }, + { + 0x000bffff, + 0x000affff, + 0x0008ffff, + 0x0009ffff, + 0x00000005, + 0x00000021, + 0x00000046, + 0x00000048, + 0x00010013, + 0x00010013, + 0x0001002e, + 0x0001002e, + 0x0001003b, + 0x0001003b, + 0x00010047, + 0x00010047, + }, + { + 0x00020055, + 0x00020055, + 0x00020055, + 0x00020055, + 0x00020056, + 0x00020056, + 0x00020056, + 0x00020056, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + }, + { + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + }, + { + 0x00010054, + 0x00010054, + 0x00010057, + 0x00010057, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020022, + 0x0002004a, + 0x0002004a, + 0x0002004a, + 0x0002004a, + }, + { + 0x0014ffff, + 0x0011ffff, + 0x0010ffff, + 0x000effff, + 0x000fffff, + 0x000cffff, + 0x000dffff, + 0x00000015, + 0x0000004b, + 0x00000063, + 0x00010006, + 0x00010006, + 0x00010030, + 0x00010030, + 0x0001003d, + 0x0001003d, + }, + { + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + }, + { + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030062, + 0x00030062, + 0x00030062, + 0x00030062, + 0x00030062, + 0x00030062, + 0x00030062, + 0x00030062, + }, + { + 0x00010059, + 0x00010059, + 0x00010071, + 0x00010071, + 0x00020007, + 0x00020007, + 0x00020007, + 0x00020007, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020024, + 0x00020024, + 0x00020024, + 0x00020024, + }, + { + 0x00020031, + 0x00020031, + 0x00020031, + 0x00020031, + 0x0002004c, + 0x0002004c, + 0x0002004c, + 0x0002004c, + 0x00020064, + 0x00020064, + 0x00020064, + 0x00020064, + 0x00020065, + 0x00020065, + 0x00020065, + 0x00020065, + }, + { + 0x00000017, + 0x00000032, + 0x00000040, + 0x0000004d, + 0x0000005a, + 0x00000066, + 0x00000068, + 0x00000070, + 0x00000072, + 0x00000073, + 0x00000074, + 0x0000007e, + 0x0000007f, + 0x00000080, + 0x0001003f, + 0x0001003f, + }, + { + 0x0025ffff, + 0x0026ffff, + 0x0027ffff, + 0x0028ffff, + 0x0029ffff, + 0x002affff, + 0x002bffff, + 0x002cffff, + 0x002dffff, + 0x002effff, + 0x002fffff, + 0x0030ffff, + 0x0031ffff, + 0x0013ffff, + 0x0012ffff, + 0x00000008, + }, + { + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + }, + { + 0x000200c2, + 0x000200c2, + 0x000200c2, + 0x000200c2, + 0x000200c3, + 0x000200c3, + 0x000200c3, + 0x000200c3, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + }, + { + 0x001affff, + 0x0019ffff, + 0x0015ffff, + 0x0018ffff, + 0x001dffff, + 0x0016ffff, + 0x0017ffff, + 0x001bffff, + 0x001cffff, + 0x001effff, + 0x001fffff, + 0x0020ffff, + 0x0021ffff, + 0x0022ffff, + 0x0023ffff, + 0x0024ffff, + }, + { + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x00020026, + 0x00020026, + 0x00020026, + 0x00020026, + 0x00020027, + 0x00020027, + 0x00020027, + 0x00020027, + 0x00020028, + 0x00020028, + 0x00020028, + 0x00020028, + }, + { + 0x00020043, + 0x00020043, + 0x00020043, + 0x00020043, + 0x00020044, + 0x00020044, + 0x00020044, + 0x00020044, + 0x00020045, + 0x00020045, + 0x00020045, + 0x00020045, + 0x0002004f, + 0x0002004f, + 0x0002004f, + 0x0002004f, + }, + { + 0x00020050, + 0x00020050, + 0x00020050, + 0x00020050, + 0x00020051, + 0x00020051, + 0x00020051, + 0x00020051, + 0x00020052, + 0x00020052, + 0x00020052, + 0x00020052, + 0x00020053, + 0x00020053, + 0x00020053, + 0x00020053, + }, + { + 0x00020029, + 0x00020029, + 0x00020029, + 0x00020029, + 0x00020033, + 0x00020033, + 0x00020033, + 0x00020033, + 0x00020034, + 0x00020034, + 0x00020034, + 0x00020034, + 0x00020035, + 0x00020035, + 0x00020035, + 0x00020035, + }, + { + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020019, + 0x00020019, + 0x00020019, + 0x00020019, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001a, + }, + { + 0x00020009, + 0x00020009, + 0x00020009, + 0x00020009, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000c, + }, + { + 0x0002005b, + 0x0002005b, + 0x0002005b, + 0x0002005b, + 0x0002005c, + 0x0002005c, + 0x0002005c, + 0x0002005c, + 0x0002005d, + 0x0002005d, + 0x0002005d, + 0x0002005d, + 0x0002005e, + 0x0002005e, + 0x0002005e, + 0x0002005e, + }, + { + 0x0002005f, + 0x0002005f, + 0x0002005f, + 0x0002005f, + 0x00020060, + 0x00020060, + 0x00020060, + 0x00020060, + 0x00020061, + 0x00020061, + 0x00020061, + 0x00020061, + 0x00020069, + 0x00020069, + 0x00020069, + 0x00020069, + }, + { + 0x00020036, + 0x00020036, + 0x00020036, + 0x00020036, + 0x00020037, + 0x00020037, + 0x00020037, + 0x00020037, + 0x00020041, + 0x00020041, + 0x00020041, + 0x00020041, + 0x00020042, + 0x00020042, + 0x00020042, + 0x00020042, + }, + { + 0x0002006a, + 0x0002006a, + 0x0002006a, + 0x0002006a, + 0x0002006b, + 0x0002006b, + 0x0002006b, + 0x0002006b, + 0x0002006c, + 0x0002006c, + 0x0002006c, + 0x0002006c, + 0x0002006d, + 0x0002006d, + 0x0002006d, + 0x0002006d, + }, + { + 0x0002006e, + 0x0002006e, + 0x0002006e, + 0x0002006e, + 0x0002006f, + 0x0002006f, + 0x0002006f, + 0x0002006f, + 0x00020075, + 0x00020075, + 0x00020075, + 0x00020075, + 0x00020076, + 0x00020076, + 0x00020076, + 0x00020076, + }, + { + 0x00020077, + 0x00020077, + 0x00020077, + 0x00020077, + 0x00020078, + 0x00020078, + 0x00020078, + 0x00020078, + 0x00020079, + 0x00020079, + 0x00020079, + 0x00020079, + 0x0002007a, + 0x0002007a, + 0x0002007a, + 0x0002007a, + }, + { + 0x0002007b, + 0x0002007b, + 0x0002007b, + 0x0002007b, + 0x0002007c, + 0x0002007c, + 0x0002007c, + 0x0002007c, + 0x0002007d, + 0x0002007d, + 0x0002007d, + 0x0002007d, + 0x00020081, + 0x00020081, + 0x00020081, + 0x00020081, + }, + { + 0x00020082, + 0x00020082, + 0x00020082, + 0x00020082, + 0x00020083, + 0x00020083, + 0x00020083, + 0x00020083, + 0x00020084, + 0x00020084, + 0x00020084, + 0x00020084, + 0x00020085, + 0x00020085, + 0x00020085, + 0x00020085, + }, + { + 0x00020086, + 0x00020086, + 0x00020086, + 0x00020086, + 0x00020087, + 0x00020087, + 0x00020087, + 0x00020087, + 0x00020088, + 0x00020088, + 0x00020088, + 0x00020088, + 0x00020089, + 0x00020089, + 0x00020089, + 0x00020089, + }, + { + 0x0002008a, + 0x0002008a, + 0x0002008a, + 0x0002008a, + 0x0002008b, + 0x0002008b, + 0x0002008b, + 0x0002008b, + 0x0002008c, + 0x0002008c, + 0x0002008c, + 0x0002008c, + 0x0002008d, + 0x0002008d, + 0x0002008d, + 0x0002008d, + }, + { + 0x0002008e, + 0x0002008e, + 0x0002008e, + 0x0002008e, + 0x0002008f, + 0x0002008f, + 0x0002008f, + 0x0002008f, + 0x00020090, + 0x00020090, + 0x00020090, + 0x00020090, + 0x00020091, + 0x00020091, + 0x00020091, + 0x00020091, + }, + { + 0x00020092, + 0x00020092, + 0x00020092, + 0x00020092, + 0x00020093, + 0x00020093, + 0x00020093, + 0x00020093, + 0x00020094, + 0x00020094, + 0x00020094, + 0x00020094, + 0x00020095, + 0x00020095, + 0x00020095, + 0x00020095, + }, + { + 0x00020096, + 0x00020096, + 0x00020096, + 0x00020096, + 0x00020097, + 0x00020097, + 0x00020097, + 0x00020097, + 0x00020098, + 0x00020098, + 0x00020098, + 0x00020098, + 0x00020099, + 0x00020099, + 0x00020099, + 0x00020099, + }, + { + 0x0002009a, + 0x0002009a, + 0x0002009a, + 0x0002009a, + 0x0002009b, + 0x0002009b, + 0x0002009b, + 0x0002009b, + 0x0002009c, + 0x0002009c, + 0x0002009c, + 0x0002009c, + 0x0002009d, + 0x0002009d, + 0x0002009d, + 0x0002009d, + }, + { + 0x0002009e, + 0x0002009e, + 0x0002009e, + 0x0002009e, + 0x0002009f, + 0x0002009f, + 0x0002009f, + 0x0002009f, + 0x000200a0, + 0x000200a0, + 0x000200a0, + 0x000200a0, + 0x000200a1, + 0x000200a1, + 0x000200a1, + 0x000200a1, + }, + { + 0x000200a2, + 0x000200a2, + 0x000200a2, + 0x000200a2, + 0x000200a3, + 0x000200a3, + 0x000200a3, + 0x000200a3, + 0x000200a4, + 0x000200a4, + 0x000200a4, + 0x000200a4, + 0x000200a5, + 0x000200a5, + 0x000200a5, + 0x000200a5, + }, + { + 0x000200a6, + 0x000200a6, + 0x000200a6, + 0x000200a6, + 0x000200a7, + 0x000200a7, + 0x000200a7, + 0x000200a7, + 0x000200a8, + 0x000200a8, + 0x000200a8, + 0x000200a8, + 0x000200a9, + 0x000200a9, + 0x000200a9, + 0x000200a9, + }, + { + 0x000200aa, + 0x000200aa, + 0x000200aa, + 0x000200aa, + 0x000200ab, + 0x000200ab, + 0x000200ab, + 0x000200ab, + 0x000200ac, + 0x000200ac, + 0x000200ac, + 0x000200ac, + 0x000200ad, + 0x000200ad, + 0x000200ad, + 0x000200ad, + }, + { + 0x000200ae, + 0x000200ae, + 0x000200ae, + 0x000200ae, + 0x000200af, + 0x000200af, + 0x000200af, + 0x000200af, + 0x000200b0, + 0x000200b0, + 0x000200b0, + 0x000200b0, + 0x000200b1, + 0x000200b1, + 0x000200b1, + 0x000200b1, + }, + { + 0x000200b2, + 0x000200b2, + 0x000200b2, + 0x000200b2, + 0x000200b3, + 0x000200b3, + 0x000200b3, + 0x000200b3, + 0x000200b4, + 0x000200b4, + 0x000200b4, + 0x000200b4, + 0x000200b5, + 0x000200b5, + 0x000200b5, + 0x000200b5, + }, + { + 0x000200b6, + 0x000200b6, + 0x000200b6, + 0x000200b6, + 0x000200b7, + 0x000200b7, + 0x000200b7, + 0x000200b7, + 0x000200b8, + 0x000200b8, + 0x000200b8, + 0x000200b8, + 0x000200b9, + 0x000200b9, + 0x000200b9, + 0x000200b9, + }, + { + 0x000200ba, + 0x000200ba, + 0x000200ba, + 0x000200ba, + 0x000200bb, + 0x000200bb, + 0x000200bb, + 0x000200bb, + 0x000200bc, + 0x000200bc, + 0x000200bc, + 0x000200bc, + 0x000200bd, + 0x000200bd, + 0x000200bd, + 0x000200bd, + }, + { + 0x000200be, + 0x000200be, + 0x000200be, + 0x000200be, + 0x000200bf, + 0x000200bf, + 0x000200bf, + 0x000200bf, + 0x000200c0, + 0x000200c0, + 0x000200c0, + 0x000200c0, + 0x000200c1, + 0x000200c1, + 0x000200c1, + 0x000200c1, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc12[289][2] = +#else +const uint16_t c_aauiCQMFHuffEnc12[289][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0004, 0x0004 }, + { 0x0005, 0x0004 }, + { 0x0007, 0x0004 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0004 }, + { 0x000e, 0x0006 }, + { 0x0010, 0x0009 }, + { 0x0012, 0x0014 }, + { 0x0013, 0x001f }, + { 0x0016, 0x0000 }, + { 0x0016, 0x0001 }, + { 0x0016, 0x0002 }, + { 0x0016, 0x0003 }, + { 0x0016, 0x0004 }, + { 0x0016, 0x0005 }, + { 0x0016, 0x0006 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000d, 0x0006 }, + { 0x000f, 0x0008 }, + { 0x0011, 0x000c }, + { 0x0013, 0x0020 }, + { 0x0016, 0x0007 }, + { 0x0015, 0x0063 }, + { 0x0016, 0x0008 }, + { 0x0016, 0x0009 }, + { 0x0016, 0x000a }, + { 0x0016, 0x000b }, + { 0x0016, 0x000c }, + { 0x0005, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0004 }, + { 0x0008, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000d, 0x0007 }, + { 0x0010, 0x000a }, + { 0x0012, 0x0015 }, + { 0x0015, 0x0064 }, + { 0x0016, 0x000d }, + { 0x0016, 0x000e }, + { 0x0016, 0x000f }, + { 0x0016, 0x0010 }, + { 0x0016, 0x0011 }, + { 0x0016, 0x0012 }, + { 0x0016, 0x0013 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0008, 0x0005 }, + { 0x000a, 0x0005 }, + { 0x000c, 0x0005 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x000b }, + { 0x0012, 0x0016 }, + { 0x0014, 0x0037 }, + { 0x0015, 0x0065 }, + { 0x0016, 0x0014 }, + { 0x0016, 0x0015 }, + { 0x0016, 0x0016 }, + { 0x0016, 0x0017 }, + { 0x0016, 0x0018 }, + { 0x0016, 0x0019 }, + { 0x0008, 0x0006 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0006 }, + { 0x000c, 0x0006 }, + { 0x000e, 0x0008 }, + { 0x0010, 0x000c }, + { 0x0011, 0x000d }, + { 0x0013, 0x0021 }, + { 0x0015, 0x0066 }, + { 0x0016, 0x001a }, + { 0x0016, 0x001b }, + { 0x0016, 0x001c }, + { 0x0016, 0x001d }, + { 0x0016, 0x001e }, + { 0x0016, 0x001f }, + { 0x0016, 0x0020 }, + { 0x000b, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0009 }, + { 0x0011, 0x000e }, + { 0x0013, 0x0022 }, + { 0x0015, 0x0067 }, + { 0x0015, 0x0068 }, + { 0x0016, 0x0021 }, + { 0x0016, 0x0022 }, + { 0x0016, 0x0023 }, + { 0x0016, 0x0024 }, + { 0x0016, 0x0025 }, + { 0x0016, 0x0026 }, + { 0x0016, 0x0027 }, + { 0x000e, 0x000a }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000e, 0x000b }, + { 0x000f, 0x000a }, + { 0x0011, 0x000f }, + { 0x0013, 0x0023 }, + { 0x0014, 0x0038 }, + { 0x0016, 0x0028 }, + { 0x0016, 0x0029 }, + { 0x0016, 0x002a }, + { 0x0016, 0x002b }, + { 0x0016, 0x002c }, + { 0x0016, 0x002d }, + { 0x0016, 0x002e }, + { 0x0016, 0x002f }, + { 0x0016, 0x0030 }, + { 0x0010, 0x000d }, + { 0x000f, 0x000b }, + { 0x0010, 0x000e }, + { 0x0010, 0x000f }, + { 0x0012, 0x0017 }, + { 0x0013, 0x0024 }, + { 0x0014, 0x0039 }, + { 0x0016, 0x0031 }, + { 0x0016, 0x0032 }, + { 0x0016, 0x0033 }, + { 0x0016, 0x0034 }, + { 0x0016, 0x0035 }, + { 0x0016, 0x0036 }, + { 0x0016, 0x0037 }, + { 0x0016, 0x0038 }, + { 0x0016, 0x0039 }, + { 0x0016, 0x003a }, + { 0x0013, 0x0025 }, + { 0x0011, 0x0010 }, + { 0x0011, 0x0011 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0016, 0x003b }, + { 0x0016, 0x003c }, + { 0x0016, 0x003d }, + { 0x0016, 0x003e }, + { 0x0016, 0x003f }, + { 0x0016, 0x0040 }, + { 0x0016, 0x0041 }, + { 0x0016, 0x0042 }, + { 0x0016, 0x0043 }, + { 0x0016, 0x0044 }, + { 0x0015, 0x0069 }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0015, 0x006a }, + { 0x0015, 0x006b }, + { 0x0015, 0x006c }, + { 0x0016, 0x0045 }, + { 0x0016, 0x0046 }, + { 0x0016, 0x0047 }, + { 0x0016, 0x0048 }, + { 0x0016, 0x0049 }, + { 0x0016, 0x004a }, + { 0x0016, 0x004b }, + { 0x0016, 0x004c }, + { 0x0016, 0x004d }, + { 0x0016, 0x004e }, + { 0x0016, 0x004f }, + { 0x0016, 0x0050 }, + { 0x0016, 0x0051 }, + { 0x0015, 0x006d }, + { 0x0016, 0x0052 }, + { 0x0016, 0x0053 }, + { 0x0016, 0x0054 }, + { 0x0016, 0x0055 }, + { 0x0016, 0x0056 }, + { 0x0016, 0x0057 }, + { 0x0016, 0x0058 }, + { 0x0016, 0x0059 }, + { 0x0016, 0x005a }, + { 0x0016, 0x005b }, + { 0x0016, 0x005c }, + { 0x0016, 0x005d }, + { 0x0016, 0x005e }, + { 0x0016, 0x005f }, + { 0x0016, 0x0060 }, + { 0x0016, 0x0061 }, + { 0x0016, 0x0062 }, + { 0x0016, 0x0063 }, + { 0x0016, 0x0064 }, + { 0x0016, 0x0065 }, + { 0x0016, 0x0066 }, + { 0x0016, 0x0067 }, + { 0x0016, 0x0068 }, + { 0x0016, 0x0069 }, + { 0x0016, 0x006a }, + { 0x0016, 0x006b }, + { 0x0016, 0x006c }, + { 0x0016, 0x006d }, + { 0x0016, 0x006e }, + { 0x0016, 0x006f }, + { 0x0016, 0x0070 }, + { 0x0016, 0x0071 }, + { 0x0016, 0x0072 }, + { 0x0016, 0x0073 }, + { 0x0016, 0x0074 }, + { 0x0016, 0x0075 }, + { 0x0016, 0x0076 }, + { 0x0016, 0x0077 }, + { 0x0016, 0x0078 }, + { 0x0016, 0x0079 }, + { 0x0016, 0x007a }, + { 0x0016, 0x007b }, + { 0x0016, 0x007c }, + { 0x0016, 0x007d }, + { 0x0016, 0x007e }, + { 0x0016, 0x007f }, + { 0x0016, 0x0080 }, + { 0x0016, 0x0081 }, + { 0x0016, 0x0082 }, + { 0x0016, 0x0083 }, + { 0x0016, 0x0084 }, + { 0x0016, 0x0085 }, + { 0x0016, 0x0086 }, + { 0x0016, 0x0087 }, + { 0x0016, 0x0088 }, + { 0x0016, 0x0089 }, + { 0x0016, 0x008a }, + { 0x0016, 0x008b }, + { 0x0016, 0x008c }, + { 0x0016, 0x008d }, + { 0x0016, 0x008e }, + { 0x0016, 0x008f }, + { 0x0016, 0x0090 }, + { 0x0016, 0x0091 }, + { 0x0016, 0x0092 }, + { 0x0016, 0x0093 }, + { 0x0016, 0x0094 }, + { 0x0016, 0x0095 }, + { 0x0016, 0x0096 }, + { 0x0016, 0x0097 }, + { 0x0016, 0x0098 }, + { 0x0016, 0x0099 }, + { 0x0016, 0x009a }, + { 0x0016, 0x009b }, + { 0x0016, 0x009c }, + { 0x0016, 0x009d }, + { 0x0016, 0x009e }, + { 0x0016, 0x009f }, + { 0x0016, 0x00a0 }, + { 0x0016, 0x00a1 }, + { 0x0016, 0x00a2 }, + { 0x0016, 0x00a3 }, + { 0x0016, 0x00a4 }, + { 0x0016, 0x00a5 }, + { 0x0016, 0x00a6 }, + { 0x0016, 0x00a7 }, + { 0x0016, 0x00a8 }, + { 0x0016, 0x00a9 }, + { 0x0016, 0x00aa }, + { 0x0016, 0x00ab }, + { 0x0016, 0x00ac }, + { 0x0016, 0x00ad }, + { 0x0016, 0x00ae }, + { 0x0016, 0x00af }, + { 0x0016, 0x00b0 }, + { 0x0016, 0x00b1 }, + { 0x0016, 0x00b2 }, + { 0x0016, 0x00b3 }, + { 0x0016, 0x00b4 }, + { 0x0016, 0x00b5 }, + { 0x0016, 0x00b6 }, + { 0x0016, 0x00b7 }, + { 0x0016, 0x00b8 }, + { 0x0016, 0x00b9 }, + { 0x0016, 0x00ba }, + { 0x0016, 0x00bb }, + { 0x0016, 0x00bc }, + { 0x0016, 0x00bd }, + { 0x0016, 0x00be }, + { 0x0016, 0x00bf }, + { 0x0016, 0x00c0 }, + { 0x0016, 0x00c1 }, + { 0x0016, 0x00c2 }, + { 0x0016, 0x00c3 }, + { 0x0016, 0x00c4 }, + { 0x0016, 0x00c5 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec12[76][16] = { + { + 0x0003ffff, + 0x0004ffff, + 0x0001ffff, + 0x0002ffff, + 0x00000001, + 0x00000011, + 0x00000012, + 0x00000023, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + }, + { + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + }, + { + 0x0006ffff, + 0x0005ffff, + 0x00000004, + 0x00000015, + 0x00000026, + 0x00000036, + 0x00000044, + 0x00000046, + 0x00010003, + 0x00010003, + 0x00010045, + 0x00010045, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020014, + }, + { + 0x00020025, + 0x00020025, + 0x00020025, + 0x00020025, + 0x00020033, + 0x00020033, + 0x00020033, + 0x00020033, + 0x00020034, + 0x00020034, + 0x00020034, + 0x00020034, + 0x00020035, + 0x00020035, + 0x00020035, + 0x00020035, + }, + { + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020037, + 0x00020037, + 0x00020037, + 0x00020037, + 0x00020047, + 0x00020047, + 0x00020047, + 0x00020047, + 0x00020056, + 0x00020056, + 0x00020056, + 0x00020056, + }, + { + 0x000bffff, + 0x0009ffff, + 0x000affff, + 0x0007ffff, + 0x0008ffff, + 0x00000038, + 0x00000048, + 0x00000058, + 0x00010005, + 0x00010005, + 0x00010027, + 0x00010027, + 0x00010055, + 0x00010055, + 0x00010057, + 0x00010057, + }, + { + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + }, + { + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + }, + { + 0x00010018, + 0x00010018, + 0x0001005a, + 0x0001005a, + 0x0001006a, + 0x0001006a, + 0x00010078, + 0x00010078, + 0x00020006, + 0x00020006, + 0x00020006, + 0x00020006, + 0x00020039, + 0x00020039, + 0x00020039, + 0x00020039, + }, + { + 0x00020049, + 0x00020049, + 0x00020049, + 0x00020049, + 0x00020059, + 0x00020059, + 0x00020059, + 0x00020059, + 0x00020066, + 0x00020066, + 0x00020066, + 0x00020066, + 0x00020069, + 0x00020069, + 0x00020069, + 0x00020069, + }, + { + 0x0018ffff, + 0x0029ffff, + 0x003affff, + 0x0010ffff, + 0x0011ffff, + 0x000fffff, + 0x000cffff, + 0x000dffff, + 0x000effff, + 0x00000007, + 0x00000029, + 0x0000003a, + 0x0000004a, + 0x00000077, + 0x00000079, + 0x0000007a, + }, + { + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + }, + { + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + }, + { + 0x00030089, + 0x00030089, + 0x00030089, + 0x00030089, + 0x00030089, + 0x00030089, + 0x00030089, + 0x00030089, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + }, + { + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020008, + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x0002003b, + 0x0002003b, + 0x0002003b, + 0x0002003b, + 0x0002007b, + 0x0002007b, + 0x0002007b, + 0x0002007b, + }, + { + 0x004bffff, + 0x0012ffff, + 0x0015ffff, + 0x0013ffff, + 0x0014ffff, + 0x0016ffff, + 0x0017ffff, + 0x0000003c, + 0x0000006d, + 0x0000007d, + 0x0000008d, + 0x0000008e, + 0x0000009a, + 0x0000009b, + 0x00010009, + 0x00010009, + }, + { + 0x0001001a, + 0x0001001a, + 0x0001004c, + 0x0001004c, + 0x0001005c, + 0x0001005c, + 0x0001006c, + 0x0001006c, + 0x0001007c, + 0x0001007c, + 0x00010088, + 0x00010088, + 0x0001008b, + 0x0001008b, + 0x0001008c, + 0x0001008c, + }, + { + 0x0002011f, + 0x0002011f, + 0x0002011f, + 0x0002011f, + 0x00020120, + 0x00020120, + 0x00020120, + 0x00020120, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + }, + { + 0x0003004d, + 0x0003004d, + 0x0003004d, + 0x0003004d, + 0x0003004d, + 0x0003004d, + 0x0003004d, + 0x0003004d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + }, + { + 0x0003005e, + 0x0003005e, + 0x0003005e, + 0x0003005e, + 0x0003005e, + 0x0003005e, + 0x0003005e, + 0x0003005e, + 0x00030099, + 0x00030099, + 0x00030099, + 0x00030099, + 0x00030099, + 0x00030099, + 0x00030099, + 0x00030099, + }, + { + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + }, + { + 0x0003009c, + 0x0003009c, + 0x0003009c, + 0x0003009c, + 0x0003009c, + 0x0003009c, + 0x0003009c, + 0x0003009c, + 0x0003009d, + 0x0003009d, + 0x0003009d, + 0x0003009d, + 0x0003009d, + 0x0003009d, + 0x0003009d, + 0x0003009d, + }, + { + 0x0003009e, + 0x0003009e, + 0x0003009e, + 0x0003009e, + 0x0003009e, + 0x0003009e, + 0x0003009e, + 0x0003009e, + 0x000300ac, + 0x000300ac, + 0x000300ac, + 0x000300ac, + 0x000300ac, + 0x000300ac, + 0x000300ac, + 0x000300ac, + }, + { + 0x0025ffff, + 0x001fffff, + 0x0019ffff, + 0x0020ffff, + 0x001effff, + 0x0021ffff, + 0x001affff, + 0x001bffff, + 0x001cffff, + 0x001dffff, + 0x0022ffff, + 0x0023ffff, + 0x0024ffff, + 0x0026ffff, + 0x0027ffff, + 0x0028ffff, + }, + { + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + }, + { + 0x00020042, + 0x00020042, + 0x00020042, + 0x00020042, + 0x00020043, + 0x00020043, + 0x00020043, + 0x00020043, + 0x0002004e, + 0x0002004e, + 0x0002004e, + 0x0002004e, + 0x0002004f, + 0x0002004f, + 0x0002004f, + 0x0002004f, + }, + { + 0x00020050, + 0x00020050, + 0x00020050, + 0x00020050, + 0x00020051, + 0x00020051, + 0x00020051, + 0x00020051, + 0x00020052, + 0x00020052, + 0x00020052, + 0x00020052, + 0x00020053, + 0x00020053, + 0x00020053, + 0x00020053, + }, + { + 0x00020054, + 0x00020054, + 0x00020054, + 0x00020054, + 0x0002005f, + 0x0002005f, + 0x0002005f, + 0x0002005f, + 0x00020060, + 0x00020060, + 0x00020060, + 0x00020060, + 0x00020061, + 0x00020061, + 0x00020061, + 0x00020061, + }, + { + 0x00020062, + 0x00020062, + 0x00020062, + 0x00020062, + 0x00020063, + 0x00020063, + 0x00020063, + 0x00020063, + 0x00020064, + 0x00020064, + 0x00020064, + 0x00020064, + 0x00020065, + 0x00020065, + 0x00020065, + 0x00020065, + }, + { + 0x0002002f, + 0x0002002f, + 0x0002002f, + 0x0002002f, + 0x00020030, + 0x00020030, + 0x00020030, + 0x00020030, + 0x00020031, + 0x00020031, + 0x00020031, + 0x00020031, + 0x00020032, + 0x00020032, + 0x00020032, + 0x00020032, + }, + { + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020010, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + }, + { + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020021, + 0x0002002c, + 0x0002002c, + 0x0002002c, + 0x0002002c, + 0x0002002d, + 0x0002002d, + 0x0002002d, + 0x0002002d, + 0x0002002e, + 0x0002002e, + 0x0002002e, + 0x0002002e, + }, + { + 0x0002003e, + 0x0002003e, + 0x0002003e, + 0x0002003e, + 0x0002003f, + 0x0002003f, + 0x0002003f, + 0x0002003f, + 0x00020040, + 0x00020040, + 0x00020040, + 0x00020040, + 0x00020041, + 0x00020041, + 0x00020041, + 0x00020041, + }, + { + 0x0002006e, + 0x0002006e, + 0x0002006e, + 0x0002006e, + 0x0002006f, + 0x0002006f, + 0x0002006f, + 0x0002006f, + 0x00020070, + 0x00020070, + 0x00020070, + 0x00020070, + 0x00020071, + 0x00020071, + 0x00020071, + 0x00020071, + }, + { + 0x00020072, + 0x00020072, + 0x00020072, + 0x00020072, + 0x00020073, + 0x00020073, + 0x00020073, + 0x00020073, + 0x00020074, + 0x00020074, + 0x00020074, + 0x00020074, + 0x00020075, + 0x00020075, + 0x00020075, + 0x00020075, + }, + { + 0x00020076, + 0x00020076, + 0x00020076, + 0x00020076, + 0x0002007e, + 0x0002007e, + 0x0002007e, + 0x0002007e, + 0x0002007f, + 0x0002007f, + 0x0002007f, + 0x0002007f, + 0x00020080, + 0x00020080, + 0x00020080, + 0x00020080, + }, + { + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + }, + { + 0x00020081, + 0x00020081, + 0x00020081, + 0x00020081, + 0x00020082, + 0x00020082, + 0x00020082, + 0x00020082, + 0x00020083, + 0x00020083, + 0x00020083, + 0x00020083, + 0x00020084, + 0x00020084, + 0x00020084, + 0x00020084, + }, + { + 0x00020085, + 0x00020085, + 0x00020085, + 0x00020085, + 0x00020086, + 0x00020086, + 0x00020086, + 0x00020086, + 0x00020087, + 0x00020087, + 0x00020087, + 0x00020087, + 0x0002008f, + 0x0002008f, + 0x0002008f, + 0x0002008f, + }, + { + 0x00020090, + 0x00020090, + 0x00020090, + 0x00020090, + 0x00020091, + 0x00020091, + 0x00020091, + 0x00020091, + 0x00020092, + 0x00020092, + 0x00020092, + 0x00020092, + 0x00020093, + 0x00020093, + 0x00020093, + 0x00020093, + }, + { + 0x002affff, + 0x002bffff, + 0x002cffff, + 0x002dffff, + 0x002effff, + 0x002fffff, + 0x0030ffff, + 0x0031ffff, + 0x0032ffff, + 0x0033ffff, + 0x0034ffff, + 0x0035ffff, + 0x0036ffff, + 0x0037ffff, + 0x0038ffff, + 0x0039ffff, + }, + { + 0x00020094, + 0x00020094, + 0x00020094, + 0x00020094, + 0x00020095, + 0x00020095, + 0x00020095, + 0x00020095, + 0x00020096, + 0x00020096, + 0x00020096, + 0x00020096, + 0x00020097, + 0x00020097, + 0x00020097, + 0x00020097, + }, + { + 0x00020098, + 0x00020098, + 0x00020098, + 0x00020098, + 0x0002009f, + 0x0002009f, + 0x0002009f, + 0x0002009f, + 0x000200a0, + 0x000200a0, + 0x000200a0, + 0x000200a0, + 0x000200a1, + 0x000200a1, + 0x000200a1, + 0x000200a1, + }, + { + 0x000200a2, + 0x000200a2, + 0x000200a2, + 0x000200a2, + 0x000200a3, + 0x000200a3, + 0x000200a3, + 0x000200a3, + 0x000200a4, + 0x000200a4, + 0x000200a4, + 0x000200a4, + 0x000200a5, + 0x000200a5, + 0x000200a5, + 0x000200a5, + }, + { + 0x000200a6, + 0x000200a6, + 0x000200a6, + 0x000200a6, + 0x000200a7, + 0x000200a7, + 0x000200a7, + 0x000200a7, + 0x000200a8, + 0x000200a8, + 0x000200a8, + 0x000200a8, + 0x000200a9, + 0x000200a9, + 0x000200a9, + 0x000200a9, + }, + { + 0x000200aa, + 0x000200aa, + 0x000200aa, + 0x000200aa, + 0x000200ab, + 0x000200ab, + 0x000200ab, + 0x000200ab, + 0x000200ad, + 0x000200ad, + 0x000200ad, + 0x000200ad, + 0x000200ae, + 0x000200ae, + 0x000200ae, + 0x000200ae, + }, + { + 0x000200af, + 0x000200af, + 0x000200af, + 0x000200af, + 0x000200b0, + 0x000200b0, + 0x000200b0, + 0x000200b0, + 0x000200b1, + 0x000200b1, + 0x000200b1, + 0x000200b1, + 0x000200b2, + 0x000200b2, + 0x000200b2, + 0x000200b2, + }, + { + 0x000200b3, + 0x000200b3, + 0x000200b3, + 0x000200b3, + 0x000200b4, + 0x000200b4, + 0x000200b4, + 0x000200b4, + 0x000200b5, + 0x000200b5, + 0x000200b5, + 0x000200b5, + 0x000200b6, + 0x000200b6, + 0x000200b6, + 0x000200b6, + }, + { + 0x000200b7, + 0x000200b7, + 0x000200b7, + 0x000200b7, + 0x000200b8, + 0x000200b8, + 0x000200b8, + 0x000200b8, + 0x000200b9, + 0x000200b9, + 0x000200b9, + 0x000200b9, + 0x000200ba, + 0x000200ba, + 0x000200ba, + 0x000200ba, + }, + { + 0x000200bb, + 0x000200bb, + 0x000200bb, + 0x000200bb, + 0x000200bc, + 0x000200bc, + 0x000200bc, + 0x000200bc, + 0x000200bd, + 0x000200bd, + 0x000200bd, + 0x000200bd, + 0x000200be, + 0x000200be, + 0x000200be, + 0x000200be, + }, + { + 0x000200bf, + 0x000200bf, + 0x000200bf, + 0x000200bf, + 0x000200c0, + 0x000200c0, + 0x000200c0, + 0x000200c0, + 0x000200c1, + 0x000200c1, + 0x000200c1, + 0x000200c1, + 0x000200c2, + 0x000200c2, + 0x000200c2, + 0x000200c2, + }, + { + 0x000200c3, + 0x000200c3, + 0x000200c3, + 0x000200c3, + 0x000200c4, + 0x000200c4, + 0x000200c4, + 0x000200c4, + 0x000200c5, + 0x000200c5, + 0x000200c5, + 0x000200c5, + 0x000200c6, + 0x000200c6, + 0x000200c6, + 0x000200c6, + }, + { + 0x000200c7, + 0x000200c7, + 0x000200c7, + 0x000200c7, + 0x000200c8, + 0x000200c8, + 0x000200c8, + 0x000200c8, + 0x000200c9, + 0x000200c9, + 0x000200c9, + 0x000200c9, + 0x000200ca, + 0x000200ca, + 0x000200ca, + 0x000200ca, + }, + { + 0x000200cb, + 0x000200cb, + 0x000200cb, + 0x000200cb, + 0x000200cc, + 0x000200cc, + 0x000200cc, + 0x000200cc, + 0x000200cd, + 0x000200cd, + 0x000200cd, + 0x000200cd, + 0x000200ce, + 0x000200ce, + 0x000200ce, + 0x000200ce, + }, + { + 0x000200cf, + 0x000200cf, + 0x000200cf, + 0x000200cf, + 0x000200d0, + 0x000200d0, + 0x000200d0, + 0x000200d0, + 0x000200d1, + 0x000200d1, + 0x000200d1, + 0x000200d1, + 0x000200d2, + 0x000200d2, + 0x000200d2, + 0x000200d2, + }, + { + 0x000200d3, + 0x000200d3, + 0x000200d3, + 0x000200d3, + 0x000200d4, + 0x000200d4, + 0x000200d4, + 0x000200d4, + 0x000200d5, + 0x000200d5, + 0x000200d5, + 0x000200d5, + 0x000200d6, + 0x000200d6, + 0x000200d6, + 0x000200d6, + }, + { + 0x000200d7, + 0x000200d7, + 0x000200d7, + 0x000200d7, + 0x000200d8, + 0x000200d8, + 0x000200d8, + 0x000200d8, + 0x000200d9, + 0x000200d9, + 0x000200d9, + 0x000200d9, + 0x000200da, + 0x000200da, + 0x000200da, + 0x000200da, + }, + { + 0x003bffff, + 0x003cffff, + 0x003dffff, + 0x003effff, + 0x003fffff, + 0x0040ffff, + 0x0041ffff, + 0x0042ffff, + 0x0043ffff, + 0x0044ffff, + 0x0045ffff, + 0x0046ffff, + 0x0047ffff, + 0x0048ffff, + 0x0049ffff, + 0x004affff, + }, + { + 0x000200db, + 0x000200db, + 0x000200db, + 0x000200db, + 0x000200dc, + 0x000200dc, + 0x000200dc, + 0x000200dc, + 0x000200dd, + 0x000200dd, + 0x000200dd, + 0x000200dd, + 0x000200de, + 0x000200de, + 0x000200de, + 0x000200de, + }, + { + 0x000200df, + 0x000200df, + 0x000200df, + 0x000200df, + 0x000200e0, + 0x000200e0, + 0x000200e0, + 0x000200e0, + 0x000200e1, + 0x000200e1, + 0x000200e1, + 0x000200e1, + 0x000200e2, + 0x000200e2, + 0x000200e2, + 0x000200e2, + }, + { + 0x000200e3, + 0x000200e3, + 0x000200e3, + 0x000200e3, + 0x000200e4, + 0x000200e4, + 0x000200e4, + 0x000200e4, + 0x000200e5, + 0x000200e5, + 0x000200e5, + 0x000200e5, + 0x000200e6, + 0x000200e6, + 0x000200e6, + 0x000200e6, + }, + { + 0x000200e7, + 0x000200e7, + 0x000200e7, + 0x000200e7, + 0x000200e8, + 0x000200e8, + 0x000200e8, + 0x000200e8, + 0x000200e9, + 0x000200e9, + 0x000200e9, + 0x000200e9, + 0x000200ea, + 0x000200ea, + 0x000200ea, + 0x000200ea, + }, + { + 0x000200eb, + 0x000200eb, + 0x000200eb, + 0x000200eb, + 0x000200ec, + 0x000200ec, + 0x000200ec, + 0x000200ec, + 0x000200ed, + 0x000200ed, + 0x000200ed, + 0x000200ed, + 0x000200ee, + 0x000200ee, + 0x000200ee, + 0x000200ee, + }, + { + 0x000200ef, + 0x000200ef, + 0x000200ef, + 0x000200ef, + 0x000200f0, + 0x000200f0, + 0x000200f0, + 0x000200f0, + 0x000200f1, + 0x000200f1, + 0x000200f1, + 0x000200f1, + 0x000200f2, + 0x000200f2, + 0x000200f2, + 0x000200f2, + }, + { + 0x000200f3, + 0x000200f3, + 0x000200f3, + 0x000200f3, + 0x000200f4, + 0x000200f4, + 0x000200f4, + 0x000200f4, + 0x000200f5, + 0x000200f5, + 0x000200f5, + 0x000200f5, + 0x000200f6, + 0x000200f6, + 0x000200f6, + 0x000200f6, + }, + { + 0x000200f7, + 0x000200f7, + 0x000200f7, + 0x000200f7, + 0x000200f8, + 0x000200f8, + 0x000200f8, + 0x000200f8, + 0x000200f9, + 0x000200f9, + 0x000200f9, + 0x000200f9, + 0x000200fa, + 0x000200fa, + 0x000200fa, + 0x000200fa, + }, + { + 0x000200fb, + 0x000200fb, + 0x000200fb, + 0x000200fb, + 0x000200fc, + 0x000200fc, + 0x000200fc, + 0x000200fc, + 0x000200fd, + 0x000200fd, + 0x000200fd, + 0x000200fd, + 0x000200fe, + 0x000200fe, + 0x000200fe, + 0x000200fe, + }, + { + 0x000200ff, + 0x000200ff, + 0x000200ff, + 0x000200ff, + 0x00020100, + 0x00020100, + 0x00020100, + 0x00020100, + 0x00020101, + 0x00020101, + 0x00020101, + 0x00020101, + 0x00020102, + 0x00020102, + 0x00020102, + 0x00020102, + }, + { + 0x00020103, + 0x00020103, + 0x00020103, + 0x00020103, + 0x00020104, + 0x00020104, + 0x00020104, + 0x00020104, + 0x00020105, + 0x00020105, + 0x00020105, + 0x00020105, + 0x00020106, + 0x00020106, + 0x00020106, + 0x00020106, + }, + { + 0x00020107, + 0x00020107, + 0x00020107, + 0x00020107, + 0x00020108, + 0x00020108, + 0x00020108, + 0x00020108, + 0x00020109, + 0x00020109, + 0x00020109, + 0x00020109, + 0x0002010a, + 0x0002010a, + 0x0002010a, + 0x0002010a, + }, + { + 0x0002010b, + 0x0002010b, + 0x0002010b, + 0x0002010b, + 0x0002010c, + 0x0002010c, + 0x0002010c, + 0x0002010c, + 0x0002010d, + 0x0002010d, + 0x0002010d, + 0x0002010d, + 0x0002010e, + 0x0002010e, + 0x0002010e, + 0x0002010e, + }, + { + 0x0002010f, + 0x0002010f, + 0x0002010f, + 0x0002010f, + 0x00020110, + 0x00020110, + 0x00020110, + 0x00020110, + 0x00020111, + 0x00020111, + 0x00020111, + 0x00020111, + 0x00020112, + 0x00020112, + 0x00020112, + 0x00020112, + }, + { + 0x00020113, + 0x00020113, + 0x00020113, + 0x00020113, + 0x00020114, + 0x00020114, + 0x00020114, + 0x00020114, + 0x00020115, + 0x00020115, + 0x00020115, + 0x00020115, + 0x00020116, + 0x00020116, + 0x00020116, + 0x00020116, + }, + { + 0x00020117, + 0x00020117, + 0x00020117, + 0x00020117, + 0x00020118, + 0x00020118, + 0x00020118, + 0x00020118, + 0x00020119, + 0x00020119, + 0x00020119, + 0x00020119, + 0x0002011a, + 0x0002011a, + 0x0002011a, + 0x0002011a, + }, + { + 0x0002011b, + 0x0002011b, + 0x0002011b, + 0x0002011b, + 0x0002011c, + 0x0002011c, + 0x0002011c, + 0x0002011c, + 0x0002011d, + 0x0002011d, + 0x0002011d, + 0x0002011d, + 0x0002011e, + 0x0002011e, + 0x0002011e, + 0x0002011e, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc13[324][2] = +#else +const uint16_t c_aauiCQMFHuffEnc13[324][2] = +#endif + { + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0006, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x000a, 0x0005 }, + { 0x000c, 0x0007 }, + { 0x000e, 0x000b }, + { 0x0010, 0x0011 }, + { 0x0012, 0x002d }, + { 0x0015, 0x0000 }, + { 0x0014, 0x0035 }, + { 0x0015, 0x0001 }, + { 0x0015, 0x0002 }, + { 0x0015, 0x0003 }, + { 0x0015, 0x0004 }, + { 0x0015, 0x0005 }, + { 0x0004, 0x0008 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0006, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0009, 0x0006 }, + { 0x000c, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x0010, 0x0012 }, + { 0x0011, 0x001a }, + { 0x0015, 0x0006 }, + { 0x0015, 0x0007 }, + { 0x0015, 0x0008 }, + { 0x0015, 0x0009 }, + { 0x0015, 0x000a }, + { 0x0015, 0x000b }, + { 0x0015, 0x000c }, + { 0x0005, 0x0007 }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0005, 0x0008 }, + { 0x0006, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0006 }, + { 0x000c, 0x0009 }, + { 0x000e, 0x000c }, + { 0x0010, 0x0013 }, + { 0x0012, 0x002e }, + { 0x0015, 0x000d }, + { 0x0015, 0x000e }, + { 0x0015, 0x000f }, + { 0x0015, 0x0010 }, + { 0x0015, 0x0011 }, + { 0x0015, 0x0012 }, + { 0x0015, 0x0013 }, + { 0x0005, 0x0009 }, + { 0x0004, 0x000d }, + { 0x0005, 0x000a }, + { 0x0006, 0x0007 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000d, 0x000a }, + { 0x000f, 0x000e }, + { 0x0010, 0x0014 }, + { 0x0011, 0x001b }, + { 0x0014, 0x0036 }, + { 0x0015, 0x0014 }, + { 0x0015, 0x0015 }, + { 0x0015, 0x0016 }, + { 0x0015, 0x0017 }, + { 0x0015, 0x0018 }, + { 0x0015, 0x0019 }, + { 0x0006, 0x0008 }, + { 0x0005, 0x000b }, + { 0x0006, 0x0009 }, + { 0x0007, 0x0006 }, + { 0x0009, 0x0008 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x000a }, + { 0x000e, 0x000d }, + { 0x0010, 0x0015 }, + { 0x0011, 0x001c }, + { 0x0013, 0x0053 }, + { 0x0015, 0x001a }, + { 0x0015, 0x001b }, + { 0x0015, 0x001c }, + { 0x0015, 0x001d }, + { 0x0015, 0x001e }, + { 0x0015, 0x001f }, + { 0x0015, 0x0020 }, + { 0x0008, 0x0008 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0009 }, + { 0x000a, 0x0008 }, + { 0x000c, 0x000b }, + { 0x000d, 0x000b }, + { 0x000f, 0x000f }, + { 0x0010, 0x0016 }, + { 0x0011, 0x001d }, + { 0x0014, 0x0037 }, + { 0x0015, 0x0021 }, + { 0x0015, 0x0022 }, + { 0x0015, 0x0023 }, + { 0x0015, 0x0024 }, + { 0x0015, 0x0025 }, + { 0x0015, 0x0026 }, + { 0x0015, 0x0027 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000b, 0x0009 }, + { 0x000c, 0x000c }, + { 0x000d, 0x000c }, + { 0x000f, 0x0010 }, + { 0x0010, 0x0017 }, + { 0x0012, 0x002f }, + { 0x0015, 0x0028 }, + { 0x0015, 0x0029 }, + { 0x0015, 0x002a }, + { 0x0015, 0x002b }, + { 0x0015, 0x002c }, + { 0x0015, 0x002d }, + { 0x0015, 0x002e }, + { 0x0015, 0x002f }, + { 0x0015, 0x0030 }, + { 0x000c, 0x000d }, + { 0x000c, 0x000e }, + { 0x000c, 0x000f }, + { 0x000d, 0x000d }, + { 0x000e, 0x000e }, + { 0x000f, 0x0011 }, + { 0x0010, 0x0018 }, + { 0x0011, 0x001e }, + { 0x0014, 0x0038 }, + { 0x0015, 0x0031 }, + { 0x0015, 0x0032 }, + { 0x0015, 0x0033 }, + { 0x0015, 0x0034 }, + { 0x0015, 0x0035 }, + { 0x0015, 0x0036 }, + { 0x0015, 0x0037 }, + { 0x0015, 0x0038 }, + { 0x0015, 0x0039 }, + { 0x000f, 0x0012 }, + { 0x000e, 0x000f }, + { 0x000e, 0x0010 }, + { 0x000e, 0x0011 }, + { 0x000f, 0x0013 }, + { 0x0010, 0x0019 }, + { 0x0011, 0x001f }, + { 0x0013, 0x0054 }, + { 0x0015, 0x003a }, + { 0x0014, 0x0039 }, + { 0x0015, 0x003b }, + { 0x0015, 0x003c }, + { 0x0015, 0x003d }, + { 0x0015, 0x003e }, + { 0x0015, 0x003f }, + { 0x0015, 0x0040 }, + { 0x0015, 0x0041 }, + { 0x0015, 0x0042 }, + { 0x0010, 0x001a }, + { 0x000f, 0x0014 }, + { 0x000f, 0x0015 }, + { 0x0010, 0x001b }, + { 0x0011, 0x0020 }, + { 0x0012, 0x0030 }, + { 0x0013, 0x0055 }, + { 0x0015, 0x0043 }, + { 0x0015, 0x0044 }, + { 0x0014, 0x003a }, + { 0x0015, 0x0045 }, + { 0x0015, 0x0046 }, + { 0x0015, 0x0047 }, + { 0x0015, 0x0048 }, + { 0x0015, 0x0049 }, + { 0x0015, 0x004a }, + { 0x0015, 0x004b }, + { 0x0015, 0x004c }, + { 0x0012, 0x0031 }, + { 0x0011, 0x0021 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0012, 0x0032 }, + { 0x0015, 0x004d }, + { 0x0015, 0x004e }, + { 0x0015, 0x004f }, + { 0x0015, 0x0050 }, + { 0x0015, 0x0051 }, + { 0x0015, 0x0052 }, + { 0x0015, 0x0053 }, + { 0x0015, 0x0054 }, + { 0x0015, 0x0055 }, + { 0x0015, 0x0056 }, + { 0x0015, 0x0057 }, + { 0x0015, 0x0058 }, + { 0x0015, 0x0059 }, + { 0x0015, 0x005a }, + { 0x0014, 0x003b }, + { 0x0012, 0x0033 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0015, 0x005b }, + { 0x0015, 0x005c }, + { 0x0015, 0x005d }, + { 0x0015, 0x005e }, + { 0x0015, 0x005f }, + { 0x0015, 0x0060 }, + { 0x0015, 0x0061 }, + { 0x0015, 0x0062 }, + { 0x0015, 0x0063 }, + { 0x0015, 0x0064 }, + { 0x0015, 0x0065 }, + { 0x0015, 0x0066 }, + { 0x0015, 0x0067 }, + { 0x0015, 0x0068 }, + { 0x0015, 0x0069 }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0014, 0x0047 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0014, 0x0052 }, + { 0x0014, 0x0053 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec13[89][16] = { + { + 0x0006ffff, + 0x0005ffff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x0004ffff, + 0x00000000, + 0x00000001, + 0x00000012, + 0x00000014, + 0x00000015, + 0x00000025, + 0x00000026, + 0x00000037, + 0x00010013, + 0x00010013, + }, + { + 0x00020048, + 0x00020048, + 0x00020048, + 0x00020048, + 0x0002004a, + 0x0002004a, + 0x0002004a, + 0x0002004a, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + }, + { + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + }, + { + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + }, + { + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + }, + { + 0x00020004, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020028, + 0x00020028, + 0x00020028, + 0x00020028, + 0x00020039, + 0x00020039, + 0x00020039, + 0x00020039, + }, + { + 0x000bffff, + 0x0009ffff, + 0x000affff, + 0x0007ffff, + 0x0008ffff, + 0x00000005, + 0x00000017, + 0x00000029, + 0x0000005a, + 0x0000005c, + 0x0001003a, + 0x0001003a, + 0x0001004b, + 0x0001004b, + 0x0001005b, + 0x0001005b, + }, + { + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + }, + { + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + }, + { + 0x0001003c, + 0x0001003c, + 0x0001006f, + 0x0001006f, + 0x00020006, + 0x00020006, + 0x00020006, + 0x00020006, + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x0002004d, + 0x0002004d, + 0x0002004d, + 0x0002004d, + }, + { + 0x0002005e, + 0x0002005e, + 0x0002005e, + 0x0002005e, + 0x0002006c, + 0x0002006c, + 0x0002006c, + 0x0002006c, + 0x0002006d, + 0x0002006d, + 0x0002006d, + 0x0002006d, + 0x0002006e, + 0x0002006e, + 0x0002006e, + 0x0002006e, + }, + { + 0x0012ffff, + 0x0011ffff, + 0x0010ffff, + 0x000fffff, + 0x000dffff, + 0x000cffff, + 0x000effff, + 0x00000007, + 0x00000019, + 0x0000002b, + 0x0000004e, + 0x0000005f, + 0x00000070, + 0x0000007e, + 0x0000007f, + 0x00000080, + }, + { + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x00030060, + 0x00030060, + 0x00030060, + 0x00030060, + 0x00030060, + 0x00030060, + 0x00030060, + 0x00030060, + }, + { + 0x00020092, + 0x00020092, + 0x00020092, + 0x00020092, + 0x00020093, + 0x00020093, + 0x00020093, + 0x00020093, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + }, + { + 0x00030071, + 0x00030071, + 0x00030071, + 0x00030071, + 0x00030071, + 0x00030071, + 0x00030071, + 0x00030071, + 0x00030081, + 0x00030081, + 0x00030081, + 0x00030081, + 0x00030081, + 0x00030081, + 0x00030081, + 0x00030081, + }, + { + 0x0002002c, + 0x0002002c, + 0x0002002c, + 0x0002002c, + 0x0002004f, + 0x0002004f, + 0x0002004f, + 0x0002004f, + 0x00020082, + 0x00020082, + 0x00020082, + 0x00020082, + 0x00020091, + 0x00020091, + 0x00020091, + 0x00020091, + }, + { + 0x00010072, + 0x00010072, + 0x00010083, + 0x00010083, + 0x00010090, + 0x00010090, + 0x00010094, + 0x00010094, + 0x000100a3, + 0x000100a3, + 0x000100a4, + 0x000100a4, + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020008, + }, + { + 0x0016ffff, + 0x00000009, + 0x0000001b, + 0x0000002d, + 0x0000003f, + 0x00000050, + 0x00000062, + 0x00000073, + 0x00000084, + 0x00000095, + 0x000000a2, + 0x000000a5, + 0x0001003e, + 0x0001003e, + 0x00010061, + 0x00010061, + }, + { + 0x0021ffff, + 0x0024ffff, + 0x003dffff, + 0x001affff, + 0x001bffff, + 0x001cffff, + 0x001dffff, + 0x001effff, + 0x001fffff, + 0x0020ffff, + 0x0019ffff, + 0x0017ffff, + 0x0018ffff, + 0x0013ffff, + 0x0014ffff, + 0x0015ffff, + }, + { + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + }, + { + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030063, + 0x00030063, + 0x00030063, + 0x00030063, + 0x00030063, + 0x00030063, + 0x00030063, + 0x00030063, + }, + { + 0x00030085, + 0x00030085, + 0x00030085, + 0x00030085, + 0x00030085, + 0x00030085, + 0x00030085, + 0x00030085, + 0x00030096, + 0x00030096, + 0x00030096, + 0x00030096, + 0x00030096, + 0x00030096, + 0x00030096, + 0x00030096, + }, + { + 0x000300a6, + 0x000300a6, + 0x000300a6, + 0x000300a6, + 0x000300a6, + 0x000300a6, + 0x000300a6, + 0x000300a6, + 0x000300b5, + 0x000300b5, + 0x000300b5, + 0x000300b5, + 0x000300b5, + 0x000300b5, + 0x000300b5, + 0x000300b5, + }, + { + 0x000100c9, + 0x000100c9, + 0x000100ca, + 0x000100ca, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002002e, + 0x0002002e, + 0x0002002e, + 0x0002002e, + 0x00020074, + 0x00020074, + 0x00020074, + 0x00020074, + }, + { + 0x000200a7, + 0x000200a7, + 0x000200a7, + 0x000200a7, + 0x000200b4, + 0x000200b4, + 0x000200b4, + 0x000200b4, + 0x000200b8, + 0x000200b8, + 0x000200b8, + 0x000200b8, + 0x000200c8, + 0x000200c8, + 0x000200c8, + 0x000200c8, + }, + { + 0x0000013e, + 0x0000013f, + 0x00000140, + 0x00000141, + 0x00000142, + 0x00000143, + 0x00010052, + 0x00010052, + 0x00010097, + 0x00010097, + 0x000100a8, + 0x000100a8, + 0x000100b6, + 0x000100b6, + 0x000100b7, + 0x000100b7, + }, + { + 0x0054ffff, + 0x0055ffff, + 0x0056ffff, + 0x0057ffff, + 0x0058ffff, + 0x0000000c, + 0x00000041, + 0x00000064, + 0x00000086, + 0x00000099, + 0x000000ab, + 0x000000c7, + 0x000000da, + 0x000000db, + 0x000000dc, + 0x000000dd, + }, + { + 0x000000de, + 0x000000df, + 0x000000e0, + 0x000000e1, + 0x000000e2, + 0x000000e3, + 0x000000e4, + 0x000000e5, + 0x000000e6, + 0x000000e7, + 0x000000e8, + 0x000000e9, + 0x000000ea, + 0x000000eb, + 0x000000ec, + 0x000000ed, + }, + { + 0x000000ee, + 0x000000ef, + 0x000000f0, + 0x000000f1, + 0x000000f2, + 0x000000f3, + 0x000000f4, + 0x000000f5, + 0x000000f6, + 0x000000f7, + 0x000000f8, + 0x000000f9, + 0x000000fa, + 0x000000fb, + 0x000000fc, + 0x000000fd, + }, + { + 0x000000fe, + 0x000000ff, + 0x00000100, + 0x00000101, + 0x00000102, + 0x00000103, + 0x00000104, + 0x00000105, + 0x00000106, + 0x00000107, + 0x00000108, + 0x00000109, + 0x0000010a, + 0x0000010b, + 0x0000010c, + 0x0000010d, + }, + { + 0x0000010e, + 0x0000010f, + 0x00000110, + 0x00000111, + 0x00000112, + 0x00000113, + 0x00000114, + 0x00000115, + 0x00000116, + 0x00000117, + 0x00000118, + 0x00000119, + 0x0000011a, + 0x0000011b, + 0x0000011c, + 0x0000011d, + }, + { + 0x0000011e, + 0x0000011f, + 0x00000120, + 0x00000121, + 0x00000122, + 0x00000123, + 0x00000124, + 0x00000125, + 0x00000126, + 0x00000127, + 0x00000128, + 0x00000129, + 0x0000012a, + 0x0000012b, + 0x0000012c, + 0x0000012d, + }, + { + 0x0000012e, + 0x0000012f, + 0x00000130, + 0x00000131, + 0x00000132, + 0x00000133, + 0x00000134, + 0x00000135, + 0x00000136, + 0x00000137, + 0x00000138, + 0x00000139, + 0x0000013a, + 0x0000013b, + 0x0000013c, + 0x0000013d, + }, + { + 0x0026ffff, + 0x002dffff, + 0x0037ffff, + 0x0023ffff, + 0x0044ffff, + 0x002effff, + 0x003affff, + 0x0022ffff, + 0x002cffff, + 0x0035ffff, + 0x002fffff, + 0x0036ffff, + 0x0040ffff, + 0x0049ffff, + 0x0030ffff, + 0x0038ffff, + }, + { + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + }, + { + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + }, + { + 0x0041ffff, + 0x004affff, + 0x0042ffff, + 0x0025ffff, + 0x0027ffff, + 0x0028ffff, + 0x0029ffff, + 0x002affff, + 0x002bffff, + 0x0031ffff, + 0x0032ffff, + 0x0033ffff, + 0x0034ffff, + 0x0039ffff, + 0x003bffff, + 0x003cffff, + }, + { + 0x0003006a, + 0x0003006a, + 0x0003006a, + 0x0003006a, + 0x0003006a, + 0x0003006a, + 0x0003006a, + 0x0003006a, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + }, + { + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + }, + { + 0x00030075, + 0x00030075, + 0x00030075, + 0x00030075, + 0x00030075, + 0x00030075, + 0x00030075, + 0x00030075, + 0x00030076, + 0x00030076, + 0x00030076, + 0x00030076, + 0x00030076, + 0x00030076, + 0x00030076, + 0x00030076, + }, + { + 0x00030077, + 0x00030077, + 0x00030077, + 0x00030077, + 0x00030077, + 0x00030077, + 0x00030077, + 0x00030077, + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + }, + { + 0x00030079, + 0x00030079, + 0x00030079, + 0x00030079, + 0x00030079, + 0x00030079, + 0x00030079, + 0x00030079, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + }, + { + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007c, + 0x0003007c, + 0x0003007c, + 0x0003007c, + 0x0003007c, + 0x0003007c, + 0x0003007c, + 0x0003007c, + }, + { + 0x0003007d, + 0x0003007d, + 0x0003007d, + 0x0003007d, + 0x0003007d, + 0x0003007d, + 0x0003007d, + 0x0003007d, + 0x00030087, + 0x00030087, + 0x00030087, + 0x00030087, + 0x00030087, + 0x00030087, + 0x00030087, + 0x00030087, + }, + { + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + }, + { + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + }, + { + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + }, + { + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + }, + { + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + }, + { + 0x00030088, + 0x00030088, + 0x00030088, + 0x00030088, + 0x00030088, + 0x00030088, + 0x00030088, + 0x00030088, + 0x00030089, + 0x00030089, + 0x00030089, + 0x00030089, + 0x00030089, + 0x00030089, + 0x00030089, + 0x00030089, + }, + { + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008b, + 0x0003008b, + 0x0003008b, + 0x0003008b, + 0x0003008b, + 0x0003008b, + 0x0003008b, + 0x0003008b, + }, + { + 0x0003008c, + 0x0003008c, + 0x0003008c, + 0x0003008c, + 0x0003008c, + 0x0003008c, + 0x0003008c, + 0x0003008c, + 0x0003008d, + 0x0003008d, + 0x0003008d, + 0x0003008d, + 0x0003008d, + 0x0003008d, + 0x0003008d, + 0x0003008d, + }, + { + 0x0003008e, + 0x0003008e, + 0x0003008e, + 0x0003008e, + 0x0003008e, + 0x0003008e, + 0x0003008e, + 0x0003008e, + 0x0003008f, + 0x0003008f, + 0x0003008f, + 0x0003008f, + 0x0003008f, + 0x0003008f, + 0x0003008f, + 0x0003008f, + }, + { + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + }, + { + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + }, + { + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + }, + { + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + }, + { + 0x00030098, + 0x00030098, + 0x00030098, + 0x00030098, + 0x00030098, + 0x00030098, + 0x00030098, + 0x00030098, + 0x0003009a, + 0x0003009a, + 0x0003009a, + 0x0003009a, + 0x0003009a, + 0x0003009a, + 0x0003009a, + 0x0003009a, + }, + { + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + }, + { + 0x0003009b, + 0x0003009b, + 0x0003009b, + 0x0003009b, + 0x0003009b, + 0x0003009b, + 0x0003009b, + 0x0003009b, + 0x0003009c, + 0x0003009c, + 0x0003009c, + 0x0003009c, + 0x0003009c, + 0x0003009c, + 0x0003009c, + 0x0003009c, + }, + { + 0x0003009d, + 0x0003009d, + 0x0003009d, + 0x0003009d, + 0x0003009d, + 0x0003009d, + 0x0003009d, + 0x0003009d, + 0x0003009e, + 0x0003009e, + 0x0003009e, + 0x0003009e, + 0x0003009e, + 0x0003009e, + 0x0003009e, + 0x0003009e, + }, + { + 0x003effff, + 0x003fffff, + 0x0043ffff, + 0x0045ffff, + 0x0046ffff, + 0x0047ffff, + 0x0048ffff, + 0x004bffff, + 0x004cffff, + 0x004dffff, + 0x004effff, + 0x004fffff, + 0x0050ffff, + 0x0051ffff, + 0x0052ffff, + 0x0053ffff, + }, + { + 0x0003009f, + 0x0003009f, + 0x0003009f, + 0x0003009f, + 0x0003009f, + 0x0003009f, + 0x0003009f, + 0x0003009f, + 0x000300a0, + 0x000300a0, + 0x000300a0, + 0x000300a0, + 0x000300a0, + 0x000300a0, + 0x000300a0, + 0x000300a0, + }, + { + 0x000300a1, + 0x000300a1, + 0x000300a1, + 0x000300a1, + 0x000300a1, + 0x000300a1, + 0x000300a1, + 0x000300a1, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + }, + { + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + }, + { + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030065, + 0x00030065, + 0x00030065, + 0x00030065, + 0x00030065, + 0x00030065, + 0x00030065, + 0x00030065, + }, + { + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + }, + { + 0x000300aa, + 0x000300aa, + 0x000300aa, + 0x000300aa, + 0x000300aa, + 0x000300aa, + 0x000300aa, + 0x000300aa, + 0x000300ac, + 0x000300ac, + 0x000300ac, + 0x000300ac, + 0x000300ac, + 0x000300ac, + 0x000300ac, + 0x000300ac, + }, + { + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + }, + { + 0x000300ad, + 0x000300ad, + 0x000300ad, + 0x000300ad, + 0x000300ad, + 0x000300ad, + 0x000300ad, + 0x000300ad, + 0x000300ae, + 0x000300ae, + 0x000300ae, + 0x000300ae, + 0x000300ae, + 0x000300ae, + 0x000300ae, + 0x000300ae, + }, + { + 0x000300af, + 0x000300af, + 0x000300af, + 0x000300af, + 0x000300af, + 0x000300af, + 0x000300af, + 0x000300af, + 0x000300b0, + 0x000300b0, + 0x000300b0, + 0x000300b0, + 0x000300b0, + 0x000300b0, + 0x000300b0, + 0x000300b0, + }, + { + 0x000300b1, + 0x000300b1, + 0x000300b1, + 0x000300b1, + 0x000300b1, + 0x000300b1, + 0x000300b1, + 0x000300b1, + 0x000300b2, + 0x000300b2, + 0x000300b2, + 0x000300b2, + 0x000300b2, + 0x000300b2, + 0x000300b2, + 0x000300b2, + }, + { + 0x000300b3, + 0x000300b3, + 0x000300b3, + 0x000300b3, + 0x000300b3, + 0x000300b3, + 0x000300b3, + 0x000300b3, + 0x000300b9, + 0x000300b9, + 0x000300b9, + 0x000300b9, + 0x000300b9, + 0x000300b9, + 0x000300b9, + 0x000300b9, + }, + { + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + }, + { + 0x00030066, + 0x00030066, + 0x00030066, + 0x00030066, + 0x00030066, + 0x00030066, + 0x00030066, + 0x00030066, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + }, + { + 0x000300ba, + 0x000300ba, + 0x000300ba, + 0x000300ba, + 0x000300ba, + 0x000300ba, + 0x000300ba, + 0x000300ba, + 0x000300bb, + 0x000300bb, + 0x000300bb, + 0x000300bb, + 0x000300bb, + 0x000300bb, + 0x000300bb, + 0x000300bb, + }, + { + 0x000300bc, + 0x000300bc, + 0x000300bc, + 0x000300bc, + 0x000300bc, + 0x000300bc, + 0x000300bc, + 0x000300bc, + 0x000300bd, + 0x000300bd, + 0x000300bd, + 0x000300bd, + 0x000300bd, + 0x000300bd, + 0x000300bd, + 0x000300bd, + }, + { + 0x000300be, + 0x000300be, + 0x000300be, + 0x000300be, + 0x000300be, + 0x000300be, + 0x000300be, + 0x000300be, + 0x000300bf, + 0x000300bf, + 0x000300bf, + 0x000300bf, + 0x000300bf, + 0x000300bf, + 0x000300bf, + 0x000300bf, + }, + { + 0x000300c0, + 0x000300c0, + 0x000300c0, + 0x000300c0, + 0x000300c0, + 0x000300c0, + 0x000300c0, + 0x000300c0, + 0x000300c1, + 0x000300c1, + 0x000300c1, + 0x000300c1, + 0x000300c1, + 0x000300c1, + 0x000300c1, + 0x000300c1, + }, + { + 0x000300c2, + 0x000300c2, + 0x000300c2, + 0x000300c2, + 0x000300c2, + 0x000300c2, + 0x000300c2, + 0x000300c2, + 0x000300c3, + 0x000300c3, + 0x000300c3, + 0x000300c3, + 0x000300c3, + 0x000300c3, + 0x000300c3, + 0x000300c3, + }, + { + 0x000300c4, + 0x000300c4, + 0x000300c4, + 0x000300c4, + 0x000300c4, + 0x000300c4, + 0x000300c4, + 0x000300c4, + 0x000300c5, + 0x000300c5, + 0x000300c5, + 0x000300c5, + 0x000300c5, + 0x000300c5, + 0x000300c5, + 0x000300c5, + }, + { + 0x000300c6, + 0x000300c6, + 0x000300c6, + 0x000300c6, + 0x000300c6, + 0x000300c6, + 0x000300c6, + 0x000300c6, + 0x000300cb, + 0x000300cb, + 0x000300cb, + 0x000300cb, + 0x000300cb, + 0x000300cb, + 0x000300cb, + 0x000300cb, + }, + { + 0x000300cc, + 0x000300cc, + 0x000300cc, + 0x000300cc, + 0x000300cc, + 0x000300cc, + 0x000300cc, + 0x000300cc, + 0x000300cd, + 0x000300cd, + 0x000300cd, + 0x000300cd, + 0x000300cd, + 0x000300cd, + 0x000300cd, + 0x000300cd, + }, + { + 0x000300ce, + 0x000300ce, + 0x000300ce, + 0x000300ce, + 0x000300ce, + 0x000300ce, + 0x000300ce, + 0x000300ce, + 0x000300cf, + 0x000300cf, + 0x000300cf, + 0x000300cf, + 0x000300cf, + 0x000300cf, + 0x000300cf, + 0x000300cf, + }, + { + 0x000300d0, + 0x000300d0, + 0x000300d0, + 0x000300d0, + 0x000300d0, + 0x000300d0, + 0x000300d0, + 0x000300d0, + 0x000300d1, + 0x000300d1, + 0x000300d1, + 0x000300d1, + 0x000300d1, + 0x000300d1, + 0x000300d1, + 0x000300d1, + }, + { + 0x000300d2, + 0x000300d2, + 0x000300d2, + 0x000300d2, + 0x000300d2, + 0x000300d2, + 0x000300d2, + 0x000300d2, + 0x000300d3, + 0x000300d3, + 0x000300d3, + 0x000300d3, + 0x000300d3, + 0x000300d3, + 0x000300d3, + 0x000300d3, + }, + { + 0x000300d4, + 0x000300d4, + 0x000300d4, + 0x000300d4, + 0x000300d4, + 0x000300d4, + 0x000300d4, + 0x000300d4, + 0x000300d5, + 0x000300d5, + 0x000300d5, + 0x000300d5, + 0x000300d5, + 0x000300d5, + 0x000300d5, + 0x000300d5, + }, + { + 0x000300d6, + 0x000300d6, + 0x000300d6, + 0x000300d6, + 0x000300d6, + 0x000300d6, + 0x000300d6, + 0x000300d6, + 0x000300d7, + 0x000300d7, + 0x000300d7, + 0x000300d7, + 0x000300d7, + 0x000300d7, + 0x000300d7, + 0x000300d7, + }, + { + 0x000300d8, + 0x000300d8, + 0x000300d8, + 0x000300d8, + 0x000300d8, + 0x000300d8, + 0x000300d8, + 0x000300d8, + 0x000300d9, + 0x000300d9, + 0x000300d9, + 0x000300d9, + 0x000300d9, + 0x000300d9, + 0x000300d9, + 0x000300d9, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc14[400][2] = +#else +const uint16_t c_aauiCQMFHuffEnc14[400][2] = +#endif + { + { 0x0005, 0x0007 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0006, 0x0006 }, + { 0x0007, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000d, 0x000c }, + { 0x000f, 0x0013 }, + { 0x0010, 0x001b }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0006, 0x0007 }, + { 0x0008, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x000a }, + { 0x000e, 0x000e }, + { 0x000f, 0x0014 }, + { 0x0011, 0x002a }, + { 0x0012, 0x004a }, + { 0x0013, 0x0084 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0005, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0005, 0x000d }, + { 0x0006, 0x0008 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000c, 0x000b }, + { 0x000e, 0x000f }, + { 0x000f, 0x0015 }, + { 0x0012, 0x004b }, + { 0x0013, 0x0085 }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0005, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0006, 0x0009 }, + { 0x0008, 0x0008 }, + { 0x0009, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000d, 0x000d }, + { 0x000e, 0x0010 }, + { 0x0010, 0x001c }, + { 0x0011, 0x002b }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0006, 0x000a }, + { 0x0005, 0x0011 }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0007, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x000a, 0x0009 }, + { 0x000c, 0x000c }, + { 0x000e, 0x0011 }, + { 0x000f, 0x0016 }, + { 0x0010, 0x001d }, + { 0x0012, 0x004c }, + { 0x0014, 0x001c }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0007, 0x0009 }, + { 0x0006, 0x000d }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0009, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000b, 0x000a }, + { 0x000d, 0x000e }, + { 0x000f, 0x0017 }, + { 0x0011, 0x002c }, + { 0x0010, 0x001e }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0014, 0x0026 }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0009, 0x000a }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0009, 0x000b }, + { 0x000a, 0x000b }, + { 0x000b, 0x000b }, + { 0x000d, 0x000f }, + { 0x000e, 0x0012 }, + { 0x000f, 0x0018 }, + { 0x0011, 0x002d }, + { 0x0011, 0x002e }, + { 0x0013, 0x0086 }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x000b, 0x000c }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000b, 0x000d }, + { 0x000c, 0x000d }, + { 0x000d, 0x0010 }, + { 0x000e, 0x0013 }, + { 0x000f, 0x0019 }, + { 0x0010, 0x001f }, + { 0x0013, 0x0087 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0013, 0x0088 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x000d, 0x0011 }, + { 0x000c, 0x000e }, + { 0x000c, 0x000f }, + { 0x000d, 0x0012 }, + { 0x000d, 0x0013 }, + { 0x000e, 0x0014 }, + { 0x0010, 0x0020 }, + { 0x0010, 0x0021 }, + { 0x0012, 0x004d }, + { 0x0011, 0x002f }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0014, 0x0047 }, + { 0x000f, 0x001a }, + { 0x000e, 0x0015 }, + { 0x000e, 0x0016 }, + { 0x000e, 0x0017 }, + { 0x000f, 0x001b }, + { 0x0011, 0x0030 }, + { 0x0011, 0x0031 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0010, 0x0022 }, + { 0x0010, 0x0023 }, + { 0x0010, 0x0024 }, + { 0x0010, 0x0025 }, + { 0x0011, 0x0032 }, + { 0x0011, 0x0033 }, + { 0x0012, 0x004e }, + { 0x0012, 0x004f }, + { 0x0014, 0x0052 }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0014, 0x0053 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0011, 0x0034 }, + { 0x0011, 0x0035 }, + { 0x0012, 0x0050 }, + { 0x0012, 0x0051 }, + { 0x0013, 0x008e }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0012, 0x0052 }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0014, 0x006b }, + { 0x0013, 0x0091 }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0013, 0x0092 }, + { 0x0012, 0x0053 }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0013, 0x0093 }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0014, 0x00c0 }, + { 0x0014, 0x00c1 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0014, 0x00f6 }, + { 0x0014, 0x00f7 }, + { 0x0014, 0x00f8 }, + { 0x0014, 0x00f9 }, + { 0x0014, 0x00fa }, + { 0x0014, 0x00fb }, + { 0x0014, 0x00fc }, + { 0x0014, 0x00fd }, + { 0x0014, 0x00fe }, + { 0x0014, 0x00ff }, + { 0x0014, 0x0100 }, + { 0x0014, 0x0101 }, + { 0x0014, 0x0102 }, + { 0x0014, 0x0103 }, + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec14[53][16] = { + { + 0x0009ffff, + 0x0007ffff, + 0x0008ffff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x0004ffff, + 0x0005ffff, + 0x0006ffff, + 0x00000001, + 0x00000014, + 0x00000015, + 0x00000016, + 0x00000029, + 0x0000002a, + 0x0000003d, + }, + { + 0x00020053, + 0x00020053, + 0x00020053, + 0x00020053, + 0x00020065, + 0x00020065, + 0x00020065, + 0x00020065, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + }, + { + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + }, + { + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + }, + { + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + }, + { + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + }, + { + 0x00010054, + 0x00010054, + 0x00010064, + 0x00010064, + 0x00010066, + 0x00010066, + 0x00010067, + 0x00010067, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00020019, + 0x00020019, + 0x00020019, + 0x00020019, + }, + { + 0x0002002c, + 0x0002002c, + 0x0002002c, + 0x0002002c, + 0x00020040, + 0x00020040, + 0x00020040, + 0x00020040, + 0x00020050, + 0x00020050, + 0x00020050, + 0x00020050, + 0x00020052, + 0x00020052, + 0x00020052, + 0x00020052, + }, + { + 0x000fffff, + 0x000dffff, + 0x000effff, + 0x000affff, + 0x000bffff, + 0x000cffff, + 0x0000001a, + 0x0000002e, + 0x00000041, + 0x00000055, + 0x00000079, + 0x0000007a, + 0x00010005, + 0x00010005, + 0x0001002d, + 0x0001002d, + }, + { + 0x0002008d, + 0x0002008d, + 0x0002008d, + 0x0002008d, + 0x0002008e, + 0x0002008e, + 0x0002008e, + 0x0002008e, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + }, + { + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + }, + { + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + }, + { + 0x00010007, + 0x00010007, + 0x00010043, + 0x00010043, + 0x0001006a, + 0x0001006a, + 0x0001007d, + 0x0001007d, + 0x0001008c, + 0x0001008c, + 0x0001008f, + 0x0001008f, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + }, + { + 0x0002002f, + 0x0002002f, + 0x0002002f, + 0x0002002f, + 0x00020056, + 0x00020056, + 0x00020056, + 0x00020056, + 0x00020069, + 0x00020069, + 0x00020069, + 0x00020069, + 0x0002007c, + 0x0002007c, + 0x0002007c, + 0x0002007c, + }, + { + 0x0024ffff, + 0x0018ffff, + 0x0017ffff, + 0x0015ffff, + 0x0014ffff, + 0x0016ffff, + 0x0010ffff, + 0x0011ffff, + 0x0012ffff, + 0x0013ffff, + 0x0000001c, + 0x00000030, + 0x00000057, + 0x00000090, + 0x000000a1, + 0x000000a2, + }, + { + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + }, + { + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003006b, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + }, + { + 0x00030091, + 0x00030091, + 0x00030091, + 0x00030091, + 0x00030091, + 0x00030091, + 0x00030091, + 0x00030091, + 0x000300a0, + 0x000300a0, + 0x000300a0, + 0x000300a0, + 0x000300a0, + 0x000300a0, + 0x000300a0, + 0x000300a0, + }, + { + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a4, + 0x000300a4, + 0x000300a4, + 0x000300a4, + 0x000300a4, + 0x000300a4, + 0x000300a4, + 0x000300a4, + }, + { + 0x00020045, + 0x00020045, + 0x00020045, + 0x00020045, + 0x00020058, + 0x00020058, + 0x00020058, + 0x00020058, + 0x0002007f, + 0x0002007f, + 0x0002007f, + 0x0002007f, + 0x00020092, + 0x00020092, + 0x00020092, + 0x00020092, + }, + { + 0x00010080, + 0x00010080, + 0x00010093, + 0x00010093, + 0x000100b4, + 0x000100b4, + 0x000100b8, + 0x000100b8, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x00020031, + 0x00020031, + 0x00020031, + 0x00020031, + }, + { + 0x000200a5, + 0x000200a5, + 0x000200a5, + 0x000200a5, + 0x000200b5, + 0x000200b5, + 0x000200b5, + 0x000200b5, + 0x000200b6, + 0x000200b6, + 0x000200b6, + 0x000200b6, + 0x000200b7, + 0x000200b7, + 0x000200b7, + 0x000200b7, + }, + { + 0x000000a6, + 0x000000a7, + 0x000000c8, + 0x000000c9, + 0x000000ca, + 0x000000cb, + 0x00010009, + 0x00010009, + 0x0001001e, + 0x0001001e, + 0x00010032, + 0x00010032, + 0x00010059, + 0x00010059, + 0x0001006c, + 0x0001006c, + }, + { + 0x0022ffff, + 0x0023ffff, + 0x001fffff, + 0x0020ffff, + 0x0021ffff, + 0x0019ffff, + 0x001affff, + 0x001bffff, + 0x001cffff, + 0x001dffff, + 0x001effff, + 0x0000000a, + 0x00000046, + 0x0000005a, + 0x0000006e, + 0x00000094, + }, + { + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + }, + { + 0x0003006d, + 0x0003006d, + 0x0003006d, + 0x0003006d, + 0x0003006d, + 0x0003006d, + 0x0003006d, + 0x0003006d, + 0x00030081, + 0x00030081, + 0x00030081, + 0x00030081, + 0x00030081, + 0x00030081, + 0x00030081, + 0x00030081, + }, + { + 0x00030082, + 0x00030082, + 0x00030082, + 0x00030082, + 0x00030082, + 0x00030082, + 0x00030082, + 0x00030082, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + }, + { + 0x000300b9, + 0x000300b9, + 0x000300b9, + 0x000300b9, + 0x000300b9, + 0x000300b9, + 0x000300b9, + 0x000300b9, + 0x000300ba, + 0x000300ba, + 0x000300ba, + 0x000300ba, + 0x000300ba, + 0x000300ba, + 0x000300ba, + 0x000300ba, + }, + { + 0x000300cc, + 0x000300cc, + 0x000300cc, + 0x000300cc, + 0x000300cc, + 0x000300cc, + 0x000300cc, + 0x000300cc, + 0x000300cd, + 0x000300cd, + 0x000300cd, + 0x000300cd, + 0x000300cd, + 0x000300cd, + 0x000300cd, + 0x000300cd, + }, + { + 0x000300dc, + 0x000300dc, + 0x000300dc, + 0x000300dc, + 0x000300dc, + 0x000300dc, + 0x000300dc, + 0x000300dc, + 0x000300dd, + 0x000300dd, + 0x000300dd, + 0x000300dd, + 0x000300dd, + 0x000300dd, + 0x000300dd, + 0x000300dd, + }, + { + 0x000100f2, + 0x000100f2, + 0x000100f4, + 0x000100f4, + 0x00010106, + 0x00010106, + 0x0001011a, + 0x0001011a, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020033, + 0x00020033, + 0x00020033, + 0x00020033, + }, + { + 0x0002005b, + 0x0002005b, + 0x0002005b, + 0x0002005b, + 0x000200a8, + 0x000200a8, + 0x000200a8, + 0x000200a8, + 0x000200ce, + 0x000200ce, + 0x000200ce, + 0x000200ce, + 0x000200cf, + 0x000200cf, + 0x000200cf, + 0x000200cf, + }, + { + 0x000200de, + 0x000200de, + 0x000200de, + 0x000200de, + 0x000200df, + 0x000200df, + 0x000200df, + 0x000200df, + 0x000200f0, + 0x000200f0, + 0x000200f0, + 0x000200f0, + 0x00020107, + 0x00020107, + 0x00020107, + 0x00020107, + }, + { + 0x0000018c, + 0x0000018d, + 0x0000018e, + 0x0000018f, + 0x0001000b, + 0x0001000b, + 0x0001000c, + 0x0001000c, + 0x00010021, + 0x00010021, + 0x00010034, + 0x00010034, + 0x00010083, + 0x00010083, + 0x00010095, + 0x00010095, + }, + { + 0x00010098, + 0x00010098, + 0x000100bb, + 0x000100bb, + 0x000100bc, + 0x000100bc, + 0x000100bd, + 0x000100bd, + 0x000100d1, + 0x000100d1, + 0x000100d2, + 0x000100d2, + 0x000100e0, + 0x000100e0, + 0x000100f1, + 0x000100f1, + }, + { + 0x0025ffff, + 0x0026ffff, + 0x0028ffff, + 0x0027ffff, + 0x0029ffff, + 0x002affff, + 0x002bffff, + 0x002cffff, + 0x002dffff, + 0x002effff, + 0x002fffff, + 0x0030ffff, + 0x0031ffff, + 0x0032ffff, + 0x0033ffff, + 0x0034ffff, + }, + { + 0x0000000d, + 0x0000000e, + 0x0000000f, + 0x00000010, + 0x00000011, + 0x00000012, + 0x00000013, + 0x00000022, + 0x00000023, + 0x00000024, + 0x00000025, + 0x00000026, + 0x00000027, + 0x00000035, + 0x00000036, + 0x00000037, + }, + { + 0x00000038, + 0x00000039, + 0x0000003a, + 0x0000003b, + 0x00000048, + 0x00000049, + 0x0000004a, + 0x0000004b, + 0x0000004c, + 0x0000004d, + 0x0000004e, + 0x0000004f, + 0x0000005c, + 0x0000005d, + 0x0000005e, + 0x0000005f, + }, + { + 0x00000087, + 0x00000088, + 0x00000089, + 0x0000008a, + 0x0000008b, + 0x00000096, + 0x00000097, + 0x00000099, + 0x0000009a, + 0x0000009b, + 0x0000009c, + 0x0000009d, + 0x0000009e, + 0x0000009f, + 0x000000aa, + 0x000000ab, + }, + { + 0x00000060, + 0x00000061, + 0x00000062, + 0x00000063, + 0x0000006f, + 0x00000070, + 0x00000071, + 0x00000072, + 0x00000073, + 0x00000074, + 0x00000075, + 0x00000076, + 0x00000077, + 0x00000084, + 0x00000085, + 0x00000086, + }, + { + 0x000000ac, + 0x000000ad, + 0x000000ae, + 0x000000af, + 0x000000b0, + 0x000000b1, + 0x000000b2, + 0x000000b3, + 0x000000be, + 0x000000bf, + 0x000000c0, + 0x000000c1, + 0x000000c2, + 0x000000c3, + 0x000000c4, + 0x000000c5, + }, + { + 0x000000c6, + 0x000000c7, + 0x000000d0, + 0x000000d3, + 0x000000d4, + 0x000000d5, + 0x000000d6, + 0x000000d7, + 0x000000d8, + 0x000000d9, + 0x000000da, + 0x000000db, + 0x000000e1, + 0x000000e2, + 0x000000e3, + 0x000000e4, + }, + { + 0x000000e5, + 0x000000e6, + 0x000000e7, + 0x000000e8, + 0x000000e9, + 0x000000ea, + 0x000000eb, + 0x000000ec, + 0x000000ed, + 0x000000ee, + 0x000000ef, + 0x000000f3, + 0x000000f5, + 0x000000f6, + 0x000000f7, + 0x000000f8, + }, + { + 0x000000f9, + 0x000000fa, + 0x000000fb, + 0x000000fc, + 0x000000fd, + 0x000000fe, + 0x000000ff, + 0x00000100, + 0x00000101, + 0x00000102, + 0x00000103, + 0x00000104, + 0x00000105, + 0x00000108, + 0x00000109, + 0x0000010a, + }, + { + 0x0000010b, + 0x0000010c, + 0x0000010d, + 0x0000010e, + 0x0000010f, + 0x00000110, + 0x00000111, + 0x00000112, + 0x00000113, + 0x00000114, + 0x00000115, + 0x00000116, + 0x00000117, + 0x00000118, + 0x00000119, + 0x0000011b, + }, + { + 0x0000011c, + 0x0000011d, + 0x0000011e, + 0x0000011f, + 0x00000120, + 0x00000121, + 0x00000122, + 0x00000123, + 0x00000124, + 0x00000125, + 0x00000126, + 0x00000127, + 0x00000128, + 0x00000129, + 0x0000012a, + 0x0000012b, + }, + { + 0x0000012c, + 0x0000012d, + 0x0000012e, + 0x0000012f, + 0x00000130, + 0x00000131, + 0x00000132, + 0x00000133, + 0x00000134, + 0x00000135, + 0x00000136, + 0x00000137, + 0x00000138, + 0x00000139, + 0x0000013a, + 0x0000013b, + }, + { + 0x0000013c, + 0x0000013d, + 0x0000013e, + 0x0000013f, + 0x00000140, + 0x00000141, + 0x00000142, + 0x00000143, + 0x00000144, + 0x00000145, + 0x00000146, + 0x00000147, + 0x00000148, + 0x00000149, + 0x0000014a, + 0x0000014b, + }, + { + 0x0000014c, + 0x0000014d, + 0x0000014e, + 0x0000014f, + 0x00000150, + 0x00000151, + 0x00000152, + 0x00000153, + 0x00000154, + 0x00000155, + 0x00000156, + 0x00000157, + 0x00000158, + 0x00000159, + 0x0000015a, + 0x0000015b, + }, + { + 0x0000015c, + 0x0000015d, + 0x0000015e, + 0x0000015f, + 0x00000160, + 0x00000161, + 0x00000162, + 0x00000163, + 0x00000164, + 0x00000165, + 0x00000166, + 0x00000167, + 0x00000168, + 0x00000169, + 0x0000016a, + 0x0000016b, + }, + { + 0x0000016c, + 0x0000016d, + 0x0000016e, + 0x0000016f, + 0x00000170, + 0x00000171, + 0x00000172, + 0x00000173, + 0x00000174, + 0x00000175, + 0x00000176, + 0x00000177, + 0x00000178, + 0x00000179, + 0x0000017a, + 0x0000017b, + }, + { + 0x0000017c, + 0x0000017d, + 0x0000017e, + 0x0000017f, + 0x00000180, + 0x00000181, + 0x00000182, + 0x00000183, + 0x00000184, + 0x00000185, + 0x00000186, + 0x00000187, + 0x00000188, + 0x00000189, + 0x0000018a, + 0x0000018b, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc15[576][2] = +#else +const uint16_t c_aauiCQMFHuffEnc15[576][2] = +#endif + { + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0007, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0008 }, + { 0x000b, 0x000b }, + { 0x000d, 0x000e }, + { 0x000e, 0x0011 }, + { 0x000f, 0x001a }, + { 0x0012, 0x006e }, + { 0x0014, 0x0000 }, + { 0x0013, 0x00cc }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0005, 0x000d }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0006, 0x000b }, + { 0x0007, 0x0009 }, + { 0x0008, 0x000a }, + { 0x000a, 0x000a }, + { 0x000c, 0x000c }, + { 0x000d, 0x000f }, + { 0x000f, 0x001b }, + { 0x0011, 0x003d }, + { 0x0011, 0x003e }, + { 0x0013, 0x00cd }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0005, 0x0010 }, + { 0x0004, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0006, 0x000c }, + { 0x0007, 0x000a }, + { 0x0009, 0x0009 }, + { 0x000a, 0x000b }, + { 0x000c, 0x000d }, + { 0x000e, 0x0012 }, + { 0x0010, 0x0027 }, + { 0x0011, 0x003f }, + { 0x0012, 0x006f }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0006, 0x000d }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0006, 0x000e }, + { 0x0007, 0x000b }, + { 0x0008, 0x000b }, + { 0x0009, 0x000a }, + { 0x000b, 0x000c }, + { 0x000c, 0x000e }, + { 0x000e, 0x0013 }, + { 0x000f, 0x001c }, + { 0x0011, 0x0040 }, + { 0x0012, 0x0070 }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0014, 0x0026 }, + { 0x0006, 0x000f }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0007, 0x000c }, + { 0x0009, 0x000b }, + { 0x000a, 0x000c }, + { 0x000b, 0x000d }, + { 0x000d, 0x0010 }, + { 0x000e, 0x0014 }, + { 0x0010, 0x0028 }, + { 0x0011, 0x0041 }, + { 0x0013, 0x00ce }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0007, 0x000d }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0008, 0x000c }, + { 0x0009, 0x000c }, + { 0x000b, 0x000e }, + { 0x000c, 0x000f }, + { 0x000e, 0x0015 }, + { 0x0010, 0x0029 }, + { 0x0011, 0x0042 }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0014, 0x003c }, + { 0x0008, 0x000d }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0008, 0x000e }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x000b, 0x000f }, + { 0x000c, 0x0010 }, + { 0x000d, 0x0011 }, + { 0x000f, 0x001d }, + { 0x0010, 0x002a }, + { 0x0011, 0x0043 }, + { 0x0014, 0x003d }, + { 0x0013, 0x00cf }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0014, 0x0047 }, + { 0x0009, 0x000f }, + { 0x0008, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x000d }, + { 0x000b, 0x0010 }, + { 0x000c, 0x0011 }, + { 0x000d, 0x0012 }, + { 0x000e, 0x0016 }, + { 0x0010, 0x002b }, + { 0x0011, 0x0044 }, + { 0x0012, 0x0071 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0014, 0x0052 }, + { 0x0014, 0x0053 }, + { 0x000b, 0x0011 }, + { 0x000a, 0x000e }, + { 0x000a, 0x000f }, + { 0x000b, 0x0012 }, + { 0x000b, 0x0013 }, + { 0x000c, 0x0012 }, + { 0x000d, 0x0013 }, + { 0x000e, 0x0017 }, + { 0x0010, 0x002c }, + { 0x0012, 0x0072 }, + { 0x0011, 0x0045 }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x000c, 0x0013 }, + { 0x000c, 0x0014 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x000e, 0x0018 }, + { 0x000f, 0x001e }, + { 0x0010, 0x002d }, + { 0x0011, 0x0046 }, + { 0x0011, 0x0047 }, + { 0x0011, 0x0048 }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x000e, 0x0019 }, + { 0x000d, 0x0016 }, + { 0x000d, 0x0017 }, + { 0x000e, 0x001a }, + { 0x000e, 0x001b }, + { 0x000f, 0x001f }, + { 0x0010, 0x002e }, + { 0x0011, 0x0049 }, + { 0x0012, 0x0073 }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0010, 0x002f }, + { 0x000f, 0x0020 }, + { 0x0010, 0x0030 }, + { 0x000f, 0x0021 }, + { 0x0010, 0x0031 }, + { 0x0011, 0x004a }, + { 0x0011, 0x004b }, + { 0x0012, 0x0074 }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0013, 0x00d2 }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0012, 0x0075 }, + { 0x0010, 0x0032 }, + { 0x0010, 0x0033 }, + { 0x0011, 0x004c }, + { 0x0011, 0x004d }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0012, 0x0076 }, + { 0x0013, 0x00d5 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0012, 0x0077 }, + { 0x0012, 0x0078 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0013, 0x00d8 }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0012, 0x0079 }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0014, 0x00c0 }, + { 0x0014, 0x00c1 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0014, 0x00f6 }, + { 0x0014, 0x00f7 }, + { 0x0014, 0x00f8 }, + { 0x0014, 0x00f9 }, + { 0x0014, 0x00fa }, + { 0x0014, 0x00fb }, + { 0x0014, 0x00fc }, + { 0x0014, 0x00fd }, + { 0x0014, 0x00fe }, + { 0x0014, 0x00ff }, + { 0x0014, 0x0100 }, + { 0x0014, 0x0101 }, + { 0x0014, 0x0102 }, + { 0x0014, 0x0103 }, + { 0x0014, 0x0104 }, + { 0x0014, 0x0105 }, + { 0x0014, 0x0106 }, + { 0x0014, 0x0107 }, + { 0x0014, 0x0108 }, + { 0x0014, 0x0109 }, + { 0x0014, 0x010a }, + { 0x0014, 0x010b }, + { 0x0014, 0x010c }, + { 0x0014, 0x010d }, + { 0x0014, 0x010e }, + { 0x0014, 0x010f }, + { 0x0014, 0x0110 }, + { 0x0014, 0x0111 }, + { 0x0014, 0x0112 }, + { 0x0014, 0x0113 }, + { 0x0014, 0x0114 }, + { 0x0014, 0x0115 }, + { 0x0014, 0x0116 }, + { 0x0014, 0x0117 }, + { 0x0014, 0x0118 }, + { 0x0014, 0x0119 }, + { 0x0014, 0x011a }, + { 0x0014, 0x011b }, + { 0x0014, 0x011c }, + { 0x0014, 0x011d }, + { 0x0014, 0x011e }, + { 0x0014, 0x011f }, + { 0x0014, 0x0120 }, + { 0x0014, 0x0121 }, + { 0x0014, 0x0122 }, + { 0x0014, 0x0123 }, + { 0x0014, 0x0124 }, + { 0x0014, 0x0125 }, + { 0x0014, 0x0126 }, + { 0x0014, 0x0127 }, + { 0x0014, 0x0128 }, + { 0x0014, 0x0129 }, + { 0x0014, 0x012a }, + { 0x0014, 0x012b }, + { 0x0014, 0x012c }, + { 0x0014, 0x012d }, + { 0x0014, 0x012e }, + { 0x0014, 0x012f }, + { 0x0014, 0x0130 }, + { 0x0014, 0x0131 }, + { 0x0014, 0x0132 }, + { 0x0014, 0x0133 }, + { 0x0014, 0x0134 }, + { 0x0014, 0x0135 }, + { 0x0014, 0x0136 }, + { 0x0014, 0x0137 }, + { 0x0014, 0x0138 }, + { 0x0014, 0x0139 }, + { 0x0014, 0x013a }, + { 0x0014, 0x013b }, + { 0x0014, 0x013c }, + { 0x0014, 0x013d }, + { 0x0014, 0x013e }, + { 0x0014, 0x013f }, + { 0x0014, 0x0140 }, + { 0x0014, 0x0141 }, + { 0x0014, 0x0142 }, + { 0x0014, 0x0143 }, + { 0x0014, 0x0144 }, + { 0x0014, 0x0145 }, + { 0x0014, 0x0146 }, + { 0x0014, 0x0147 }, + { 0x0014, 0x0148 }, + { 0x0014, 0x0149 }, + { 0x0014, 0x014a }, + { 0x0014, 0x014b }, + { 0x0014, 0x014c }, + { 0x0014, 0x014d }, + { 0x0014, 0x014e }, + { 0x0014, 0x014f }, + { 0x0014, 0x0150 }, + { 0x0014, 0x0151 }, + { 0x0014, 0x0152 }, + { 0x0014, 0x0153 }, + { 0x0014, 0x0154 }, + { 0x0014, 0x0155 }, + { 0x0014, 0x0156 }, + { 0x0014, 0x0157 }, + { 0x0014, 0x0158 }, + { 0x0014, 0x0159 }, + { 0x0014, 0x015a }, + { 0x0014, 0x015b }, + { 0x0014, 0x015c }, + { 0x0014, 0x015d }, + { 0x0014, 0x015e }, + { 0x0014, 0x015f }, + { 0x0014, 0x0160 }, + { 0x0014, 0x0161 }, + { 0x0014, 0x0162 }, + { 0x0014, 0x0163 }, + { 0x0014, 0x0164 }, + { 0x0014, 0x0165 }, + { 0x0014, 0x0166 }, + { 0x0014, 0x0167 }, + { 0x0014, 0x0168 }, + { 0x0014, 0x0169 }, + { 0x0014, 0x016a }, + { 0x0014, 0x016b }, + { 0x0014, 0x016c }, + { 0x0014, 0x016d }, + { 0x0014, 0x016e }, + { 0x0014, 0x016f }, + { 0x0014, 0x0170 }, + { 0x0014, 0x0171 }, + { 0x0014, 0x0172 }, + { 0x0014, 0x0173 }, + { 0x0014, 0x0174 }, + { 0x0014, 0x0175 }, + { 0x0014, 0x0176 }, + { 0x0014, 0x0177 }, + { 0x0014, 0x0178 }, + { 0x0014, 0x0179 }, + { 0x0014, 0x017a }, + { 0x0014, 0x017b }, + { 0x0014, 0x017c }, + { 0x0014, 0x017d }, + { 0x0014, 0x017e }, + { 0x0014, 0x017f }, + { 0x0014, 0x0180 }, + { 0x0014, 0x0181 }, + { 0x0014, 0x0182 }, + { 0x0014, 0x0183 }, + { 0x0014, 0x0184 }, + { 0x0014, 0x0185 }, + { 0x0014, 0x0186 }, + { 0x0014, 0x0187 }, + { 0x0014, 0x0188 }, + { 0x0014, 0x0189 }, + { 0x0014, 0x018a }, + { 0x0014, 0x018b }, + { 0x0014, 0x018c }, + { 0x0014, 0x018d }, + { 0x0014, 0x018e }, + { 0x0014, 0x018f }, + { 0x0014, 0x0190 }, + { 0x0014, 0x0191 }, + { 0x0014, 0x0192 }, + { 0x0014, 0x0193 }, + { 0x0014, 0x0194 }, + { 0x0014, 0x0195 }, + { 0x0014, 0x0196 }, + { 0x0014, 0x0197 }, + { 0x0013, 0x00db }, + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec15[73][16] = { + { + 0x000cffff, + 0x000bffff, + 0x0008ffff, + 0x0009ffff, + 0x000affff, + 0x0002ffff, + 0x0001ffff, + 0x0003ffff, + 0x0004ffff, + 0x0005ffff, + 0x0006ffff, + 0x0007ffff, + 0x00000019, + 0x0000001a, + 0x00000031, + 0x00000032, + }, + { + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + }, + { + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + }, + { + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + }, + { + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + }, + { + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + }, + { + 0x0003004a, + 0x0003004a, + 0x0003004a, + 0x0003004a, + 0x0003004a, + 0x0003004a, + 0x0003004a, + 0x0003004a, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + }, + { + 0x00030061, + 0x00030061, + 0x00030061, + 0x00030061, + 0x00030061, + 0x00030061, + 0x00030061, + 0x00030061, + 0x00030062, + 0x00030062, + 0x00030062, + 0x00030062, + 0x00030062, + 0x00030062, + 0x00030062, + 0x00030062, + }, + { + 0x00010091, + 0x00010091, + 0x00010092, + 0x00010092, + 0x00020003, + 0x00020003, + 0x00020003, + 0x00020003, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00020004, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001d, + }, + { + 0x00020035, + 0x00020035, + 0x00020035, + 0x00020035, + 0x00020048, + 0x00020048, + 0x00020048, + 0x00020048, + 0x0002004c, + 0x0002004c, + 0x0002004c, + 0x0002004c, + 0x00020060, + 0x00020060, + 0x00020060, + 0x00020060, + }, + { + 0x00020063, + 0x00020063, + 0x00020063, + 0x00020063, + 0x00020064, + 0x00020064, + 0x00020064, + 0x00020064, + 0x00020079, + 0x00020079, + 0x00020079, + 0x00020079, + 0x0002007a, + 0x0002007a, + 0x0002007a, + 0x0002007a, + }, + { + 0x00010005, + 0x00010005, + 0x0001001e, + 0x0001001e, + 0x00010036, + 0x00010036, + 0x0001004d, + 0x0001004d, + 0x00010065, + 0x00010065, + 0x00010078, + 0x00010078, + 0x0001007b, + 0x0001007b, + 0x0001007c, + 0x0001007c, + }, + { + 0x0015ffff, + 0x0014ffff, + 0x0012ffff, + 0x0013ffff, + 0x000dffff, + 0x000effff, + 0x000fffff, + 0x0010ffff, + 0x0011ffff, + 0x00000006, + 0x0000001f, + 0x0000004e, + 0x0000007d, + 0x00000090, + 0x00000093, + 0x000000a9, + }, + { + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + }, + { + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x00030066, + 0x00030066, + 0x00030066, + 0x00030066, + 0x00030066, + 0x00030066, + 0x00030066, + 0x00030066, + }, + { + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + }, + { + 0x00030095, + 0x00030095, + 0x00030095, + 0x00030095, + 0x00030095, + 0x00030095, + 0x00030095, + 0x00030095, + 0x000300a8, + 0x000300a8, + 0x000300a8, + 0x000300a8, + 0x000300a8, + 0x000300a8, + 0x000300a8, + 0x000300a8, + }, + { + 0x000300aa, + 0x000300aa, + 0x000300aa, + 0x000300aa, + 0x000300aa, + 0x000300aa, + 0x000300aa, + 0x000300aa, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + }, + { + 0x000100ad, + 0x000100ad, + 0x000100c0, + 0x000100c0, + 0x000100c3, + 0x000100c3, + 0x000100c4, + 0x000100c4, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020038, + 0x00020038, + 0x00020038, + 0x00020038, + }, + { + 0x00020067, + 0x00020067, + 0x00020067, + 0x00020067, + 0x000200ac, + 0x000200ac, + 0x000200ac, + 0x000200ac, + 0x000200c1, + 0x000200c1, + 0x000200c1, + 0x000200c1, + 0x000200c2, + 0x000200c2, + 0x000200c2, + 0x000200c2, + }, + { + 0x00000097, + 0x000000ae, + 0x000000c5, + 0x000000d8, + 0x000000d9, + 0x000000da, + 0x00010008, + 0x00010008, + 0x00010050, + 0x00010050, + 0x00010068, + 0x00010068, + 0x0001007f, + 0x0001007f, + 0x00010096, + 0x00010096, + }, + { + 0x002fffff, + 0x0020ffff, + 0x001fffff, + 0x001effff, + 0x001bffff, + 0x001cffff, + 0x001dffff, + 0x0016ffff, + 0x0017ffff, + 0x0018ffff, + 0x0019ffff, + 0x001affff, + 0x00000021, + 0x00000039, + 0x00000051, + 0x00000080, + }, + { + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + }, + { + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030098, + 0x00030098, + 0x00030098, + 0x00030098, + 0x00030098, + 0x00030098, + 0x00030098, + 0x00030098, + }, + { + 0x000300af, + 0x000300af, + 0x000300af, + 0x000300af, + 0x000300af, + 0x000300af, + 0x000300af, + 0x000300af, + 0x000300c6, + 0x000300c6, + 0x000300c6, + 0x000300c6, + 0x000300c6, + 0x000300c6, + 0x000300c6, + 0x000300c6, + }, + { + 0x000300db, + 0x000300db, + 0x000300db, + 0x000300db, + 0x000300db, + 0x000300db, + 0x000300db, + 0x000300db, + 0x000300dc, + 0x000300dc, + 0x000300dc, + 0x000300dc, + 0x000300dc, + 0x000300dc, + 0x000300dc, + 0x000300dc, + }, + { + 0x000300f1, + 0x000300f1, + 0x000300f1, + 0x000300f1, + 0x000300f1, + 0x000300f1, + 0x000300f1, + 0x000300f1, + 0x000300f2, + 0x000300f2, + 0x000300f2, + 0x000300f2, + 0x000300f2, + 0x000300f2, + 0x000300f2, + 0x000300f2, + }, + { + 0x00010109, + 0x00010109, + 0x0001010b, + 0x0001010b, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002003a, + 0x0002003a, + 0x0002003a, + 0x0002003a, + 0x00020052, + 0x00020052, + 0x00020052, + 0x00020052, + }, + { + 0x0002006a, + 0x0002006a, + 0x0002006a, + 0x0002006a, + 0x00020081, + 0x00020081, + 0x00020081, + 0x00020081, + 0x000200b0, + 0x000200b0, + 0x000200b0, + 0x000200b0, + 0x000200c7, + 0x000200c7, + 0x000200c7, + 0x000200c7, + }, + { + 0x000200dd, + 0x000200dd, + 0x000200dd, + 0x000200dd, + 0x000200f0, + 0x000200f0, + 0x000200f0, + 0x000200f0, + 0x000200f3, + 0x000200f3, + 0x000200f3, + 0x000200f3, + 0x000200f4, + 0x000200f4, + 0x000200f4, + 0x000200f4, + }, + { + 0x0000010a, + 0x0000010c, + 0x00000121, + 0x00000122, + 0x0001000b, + 0x0001000b, + 0x00010023, + 0x00010023, + 0x00010053, + 0x00010053, + 0x00010099, + 0x00010099, + 0x000100de, + 0x000100de, + 0x000100f5, + 0x000100f5, + }, + { + 0x0024ffff, + 0x0022ffff, + 0x0025ffff, + 0x0026ffff, + 0x0027ffff, + 0x0028ffff, + 0x0029ffff, + 0x0000003b, + 0x0000006b, + 0x00000082, + 0x0000009a, + 0x000000b1, + 0x000000c8, + 0x000000df, + 0x000000f6, + 0x00000108, + }, + { + 0x0040ffff, + 0x0041ffff, + 0x0042ffff, + 0x0043ffff, + 0x0044ffff, + 0x0045ffff, + 0x0046ffff, + 0x0047ffff, + 0x0048ffff, + 0x002dffff, + 0x002effff, + 0x002affff, + 0x002bffff, + 0x002cffff, + 0x0021ffff, + 0x0023ffff, + }, + { + 0x0002013b, + 0x0002013b, + 0x0002013b, + 0x0002013b, + 0x00020154, + 0x00020154, + 0x00020154, + 0x00020154, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + }, + { + 0x00030083, + 0x00030083, + 0x00030083, + 0x00030083, + 0x00030083, + 0x00030083, + 0x00030083, + 0x00030083, + 0x0003009b, + 0x0003009b, + 0x0003009b, + 0x0003009b, + 0x0003009b, + 0x0003009b, + 0x0003009b, + 0x0003009b, + }, + { + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + }, + { + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x0003006c, + 0x0003006c, + 0x0003006c, + 0x0003006c, + 0x0003006c, + 0x0003006c, + 0x0003006c, + 0x0003006c, + }, + { + 0x000300b2, + 0x000300b2, + 0x000300b2, + 0x000300b2, + 0x000300b2, + 0x000300b2, + 0x000300b2, + 0x000300b2, + 0x000300ca, + 0x000300ca, + 0x000300ca, + 0x000300ca, + 0x000300ca, + 0x000300ca, + 0x000300ca, + 0x000300ca, + }, + { + 0x000300e0, + 0x000300e0, + 0x000300e0, + 0x000300e0, + 0x000300e0, + 0x000300e0, + 0x000300e0, + 0x000300e0, + 0x000300e1, + 0x000300e1, + 0x000300e1, + 0x000300e1, + 0x000300e1, + 0x000300e1, + 0x000300e1, + 0x000300e1, + }, + { + 0x000300e2, + 0x000300e2, + 0x000300e2, + 0x000300e2, + 0x000300e2, + 0x000300e2, + 0x000300e2, + 0x000300e2, + 0x000300f7, + 0x000300f7, + 0x000300f7, + 0x000300f7, + 0x000300f7, + 0x000300f7, + 0x000300f7, + 0x000300f7, + }, + { + 0x0003010d, + 0x0003010d, + 0x0003010d, + 0x0003010d, + 0x0003010d, + 0x0003010d, + 0x0003010d, + 0x0003010d, + 0x0003010e, + 0x0003010e, + 0x0003010e, + 0x0003010e, + 0x0003010e, + 0x0003010e, + 0x0003010e, + 0x0003010e, + }, + { + 0x00030123, + 0x00030123, + 0x00030123, + 0x00030123, + 0x00030123, + 0x00030123, + 0x00030123, + 0x00030123, + 0x00030124, + 0x00030124, + 0x00030124, + 0x00030124, + 0x00030124, + 0x00030124, + 0x00030124, + 0x00030124, + }, + { + 0x0001013e, + 0x0001013e, + 0x0001016c, + 0x0001016c, + 0x0001016d, + 0x0001016d, + 0x0001023f, + 0x0001023f, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002003d, + 0x0002003d, + 0x0002003d, + 0x0002003d, + }, + { + 0x00020055, + 0x00020055, + 0x00020055, + 0x00020055, + 0x000200b3, + 0x000200b3, + 0x000200b3, + 0x000200b3, + 0x000200c9, + 0x000200c9, + 0x000200c9, + 0x000200c9, + 0x000200f8, + 0x000200f8, + 0x000200f8, + 0x000200f8, + }, + { + 0x0002010f, + 0x0002010f, + 0x0002010f, + 0x0002010f, + 0x00020120, + 0x00020120, + 0x00020120, + 0x00020120, + 0x00020127, + 0x00020127, + 0x00020127, + 0x00020127, + 0x0002013a, + 0x0002013a, + 0x0002013a, + 0x0002013a, + }, + { + 0x00000237, + 0x00000238, + 0x00000239, + 0x0000023a, + 0x0000023b, + 0x0000023c, + 0x0000023d, + 0x0000023e, + 0x0001000e, + 0x0001000e, + 0x00010026, + 0x00010026, + 0x0001006d, + 0x0001006d, + 0x0001009d, + 0x0001009d, + }, + { + 0x000100cb, + 0x000100cb, + 0x000100cc, + 0x000100cc, + 0x00010112, + 0x00010112, + 0x00010125, + 0x00010125, + 0x00010126, + 0x00010126, + 0x00010128, + 0x00010128, + 0x00010138, + 0x00010138, + 0x00010139, + 0x00010139, + }, + { + 0x0030ffff, + 0x0031ffff, + 0x0032ffff, + 0x0033ffff, + 0x0034ffff, + 0x0035ffff, + 0x0036ffff, + 0x0037ffff, + 0x0038ffff, + 0x0039ffff, + 0x003affff, + 0x003bffff, + 0x003cffff, + 0x003dffff, + 0x003effff, + 0x003fffff, + }, + { + 0x0000000d, + 0x0000000f, + 0x00000010, + 0x00000011, + 0x00000012, + 0x00000013, + 0x00000014, + 0x00000015, + 0x00000016, + 0x00000017, + 0x00000027, + 0x00000028, + 0x00000029, + 0x0000002a, + 0x0000002b, + 0x0000002c, + }, + { + 0x0000002d, + 0x0000002e, + 0x0000002f, + 0x0000003e, + 0x0000003f, + 0x00000040, + 0x00000041, + 0x00000042, + 0x00000043, + 0x00000044, + 0x00000045, + 0x00000046, + 0x00000047, + 0x00000056, + 0x00000057, + 0x00000058, + }, + { + 0x00000059, + 0x0000005a, + 0x0000005b, + 0x0000005c, + 0x0000005d, + 0x0000005e, + 0x0000005f, + 0x0000006e, + 0x0000006f, + 0x00000070, + 0x00000071, + 0x00000072, + 0x00000073, + 0x00000074, + 0x00000075, + 0x00000076, + }, + { + 0x00000077, + 0x00000084, + 0x00000085, + 0x00000086, + 0x00000087, + 0x00000088, + 0x00000089, + 0x0000008a, + 0x0000008b, + 0x0000008c, + 0x0000008d, + 0x0000008e, + 0x0000008f, + 0x0000009c, + 0x0000009e, + 0x0000009f, + }, + { + 0x000000a0, + 0x000000a1, + 0x000000a2, + 0x000000a3, + 0x000000a4, + 0x000000a5, + 0x000000a6, + 0x000000a7, + 0x000000b4, + 0x000000b5, + 0x000000b6, + 0x000000b7, + 0x000000b8, + 0x000000b9, + 0x000000ba, + 0x000000bb, + }, + { + 0x000000bc, + 0x000000bd, + 0x000000be, + 0x000000bf, + 0x000000cd, + 0x000000ce, + 0x000000cf, + 0x000000d0, + 0x000000d1, + 0x000000d2, + 0x000000d3, + 0x000000d4, + 0x000000d5, + 0x000000d6, + 0x000000d7, + 0x000000e3, + }, + { + 0x000000e4, + 0x000000e5, + 0x000000e6, + 0x000000e7, + 0x000000e8, + 0x000000e9, + 0x000000ea, + 0x000000eb, + 0x000000ec, + 0x000000ed, + 0x000000ee, + 0x000000ef, + 0x000000f9, + 0x000000fa, + 0x000000fb, + 0x000000fc, + }, + { + 0x000000fd, + 0x000000fe, + 0x000000ff, + 0x00000100, + 0x00000101, + 0x00000102, + 0x00000103, + 0x00000104, + 0x00000105, + 0x00000106, + 0x00000107, + 0x00000110, + 0x00000111, + 0x00000113, + 0x00000114, + 0x00000115, + }, + { + 0x00000116, + 0x00000117, + 0x00000118, + 0x00000119, + 0x0000011a, + 0x0000011b, + 0x0000011c, + 0x0000011d, + 0x0000011e, + 0x0000011f, + 0x00000129, + 0x0000012a, + 0x0000012b, + 0x0000012c, + 0x0000012d, + 0x0000012e, + }, + { + 0x0000012f, + 0x00000130, + 0x00000131, + 0x00000132, + 0x00000133, + 0x00000134, + 0x00000135, + 0x00000136, + 0x00000137, + 0x0000013c, + 0x0000013d, + 0x0000013f, + 0x00000140, + 0x00000141, + 0x00000142, + 0x00000143, + }, + { + 0x00000144, + 0x00000145, + 0x00000146, + 0x00000147, + 0x00000148, + 0x00000149, + 0x0000014a, + 0x0000014b, + 0x0000014c, + 0x0000014d, + 0x0000014e, + 0x0000014f, + 0x00000150, + 0x00000151, + 0x00000152, + 0x00000153, + }, + { + 0x00000155, + 0x00000156, + 0x00000157, + 0x00000158, + 0x00000159, + 0x0000015a, + 0x0000015b, + 0x0000015c, + 0x0000015d, + 0x0000015e, + 0x0000015f, + 0x00000160, + 0x00000161, + 0x00000162, + 0x00000163, + 0x00000164, + }, + { + 0x00000165, + 0x00000166, + 0x00000167, + 0x00000168, + 0x00000169, + 0x0000016a, + 0x0000016b, + 0x0000016e, + 0x0000016f, + 0x00000170, + 0x00000171, + 0x00000172, + 0x00000173, + 0x00000174, + 0x00000175, + 0x00000176, + }, + { + 0x00000177, + 0x00000178, + 0x00000179, + 0x0000017a, + 0x0000017b, + 0x0000017c, + 0x0000017d, + 0x0000017e, + 0x0000017f, + 0x00000180, + 0x00000181, + 0x00000182, + 0x00000183, + 0x00000184, + 0x00000185, + 0x00000186, + }, + { + 0x00000187, + 0x00000188, + 0x00000189, + 0x0000018a, + 0x0000018b, + 0x0000018c, + 0x0000018d, + 0x0000018e, + 0x0000018f, + 0x00000190, + 0x00000191, + 0x00000192, + 0x00000193, + 0x00000194, + 0x00000195, + 0x00000196, + }, + { + 0x00000197, + 0x00000198, + 0x00000199, + 0x0000019a, + 0x0000019b, + 0x0000019c, + 0x0000019d, + 0x0000019e, + 0x0000019f, + 0x000001a0, + 0x000001a1, + 0x000001a2, + 0x000001a3, + 0x000001a4, + 0x000001a5, + 0x000001a6, + }, + { + 0x000001a7, + 0x000001a8, + 0x000001a9, + 0x000001aa, + 0x000001ab, + 0x000001ac, + 0x000001ad, + 0x000001ae, + 0x000001af, + 0x000001b0, + 0x000001b1, + 0x000001b2, + 0x000001b3, + 0x000001b4, + 0x000001b5, + 0x000001b6, + }, + { + 0x000001b7, + 0x000001b8, + 0x000001b9, + 0x000001ba, + 0x000001bb, + 0x000001bc, + 0x000001bd, + 0x000001be, + 0x000001bf, + 0x000001c0, + 0x000001c1, + 0x000001c2, + 0x000001c3, + 0x000001c4, + 0x000001c5, + 0x000001c6, + }, + { + 0x000001c7, + 0x000001c8, + 0x000001c9, + 0x000001ca, + 0x000001cb, + 0x000001cc, + 0x000001cd, + 0x000001ce, + 0x000001cf, + 0x000001d0, + 0x000001d1, + 0x000001d2, + 0x000001d3, + 0x000001d4, + 0x000001d5, + 0x000001d6, + }, + { + 0x000001d7, + 0x000001d8, + 0x000001d9, + 0x000001da, + 0x000001db, + 0x000001dc, + 0x000001dd, + 0x000001de, + 0x000001df, + 0x000001e0, + 0x000001e1, + 0x000001e2, + 0x000001e3, + 0x000001e4, + 0x000001e5, + 0x000001e6, + }, + { + 0x000001e7, + 0x000001e8, + 0x000001e9, + 0x000001ea, + 0x000001eb, + 0x000001ec, + 0x000001ed, + 0x000001ee, + 0x000001ef, + 0x000001f0, + 0x000001f1, + 0x000001f2, + 0x000001f3, + 0x000001f4, + 0x000001f5, + 0x000001f6, + }, + { + 0x000001f7, + 0x000001f8, + 0x000001f9, + 0x000001fa, + 0x000001fb, + 0x000001fc, + 0x000001fd, + 0x000001fe, + 0x000001ff, + 0x00000200, + 0x00000201, + 0x00000202, + 0x00000203, + 0x00000204, + 0x00000205, + 0x00000206, + }, + { + 0x00000207, + 0x00000208, + 0x00000209, + 0x0000020a, + 0x0000020b, + 0x0000020c, + 0x0000020d, + 0x0000020e, + 0x0000020f, + 0x00000210, + 0x00000211, + 0x00000212, + 0x00000213, + 0x00000214, + 0x00000215, + 0x00000216, + }, + { + 0x00000217, + 0x00000218, + 0x00000219, + 0x0000021a, + 0x0000021b, + 0x0000021c, + 0x0000021d, + 0x0000021e, + 0x0000021f, + 0x00000220, + 0x00000221, + 0x00000222, + 0x00000223, + 0x00000224, + 0x00000225, + 0x00000226, + }, + { + 0x00000227, + 0x00000228, + 0x00000229, + 0x0000022a, + 0x0000022b, + 0x0000022c, + 0x0000022d, + 0x0000022e, + 0x0000022f, + 0x00000230, + 0x00000231, + 0x00000232, + 0x00000233, + 0x00000234, + 0x00000235, + 0x00000236, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc16[729][2] = +#else +const uint16_t c_aauiCQMFHuffEnc16[729][2] = +#endif + { + { 0x0006, 0x000d }, + { 0x0005, 0x0010 }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x000a }, + { 0x0009, 0x000b }, + { 0x000b, 0x000d }, + { 0x000c, 0x000e }, + { 0x000e, 0x0016 }, + { 0x0010, 0x002d }, + { 0x0011, 0x0051 }, + { 0x0012, 0x008c }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0005, 0x0011 }, + { 0x0004, 0x000f }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0007, 0x000c }, + { 0x0008, 0x000b }, + { 0x000a, 0x000c }, + { 0x000b, 0x000e }, + { 0x000d, 0x0010 }, + { 0x000e, 0x0017 }, + { 0x000f, 0x001c }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0006, 0x0013 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0005, 0x0018 }, + { 0x0006, 0x0014 }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0009, 0x000c }, + { 0x000a, 0x000d }, + { 0x000c, 0x000f }, + { 0x000d, 0x0011 }, + { 0x000f, 0x001d }, + { 0x0011, 0x0052 }, + { 0x0012, 0x008d }, + { 0x0012, 0x008e }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0006, 0x0015 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0007, 0x000f }, + { 0x0008, 0x000c }, + { 0x0009, 0x000d }, + { 0x000b, 0x000f }, + { 0x000c, 0x0010 }, + { 0x000d, 0x0012 }, + { 0x000f, 0x001e }, + { 0x0012, 0x008f }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0014, 0x0026 }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0006, 0x0018 }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0008, 0x000d }, + { 0x000a, 0x000e }, + { 0x000b, 0x0010 }, + { 0x000c, 0x0011 }, + { 0x000e, 0x0018 }, + { 0x0010, 0x002e }, + { 0x0012, 0x0090 }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0007, 0x0012 }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0007, 0x0013 }, + { 0x0007, 0x0014 }, + { 0x0008, 0x000e }, + { 0x0009, 0x000e }, + { 0x000b, 0x0011 }, + { 0x000c, 0x0012 }, + { 0x000d, 0x0013 }, + { 0x000e, 0x0019 }, + { 0x0010, 0x002f }, + { 0x0012, 0x0091 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0007, 0x0015 }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0008, 0x000f }, + { 0x0009, 0x000f }, + { 0x000a, 0x000f }, + { 0x000b, 0x0012 }, + { 0x000d, 0x0014 }, + { 0x000e, 0x001a }, + { 0x000f, 0x001f }, + { 0x0013, 0x010f }, + { 0x0011, 0x0053 }, + { 0x0014, 0x0047 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0014, 0x0052 }, + { 0x0014, 0x0053 }, + { 0x0008, 0x0010 }, + { 0x0007, 0x0018 }, + { 0x0007, 0x0019 }, + { 0x0008, 0x0011 }, + { 0x0008, 0x0012 }, + { 0x0009, 0x0010 }, + { 0x000a, 0x0010 }, + { 0x000b, 0x0013 }, + { 0x000c, 0x0013 }, + { 0x000e, 0x001b }, + { 0x000f, 0x0020 }, + { 0x0010, 0x0030 }, + { 0x0012, 0x0092 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0009, 0x0011 }, + { 0x0008, 0x0013 }, + { 0x0009, 0x0012 }, + { 0x0009, 0x0013 }, + { 0x000a, 0x0011 }, + { 0x000a, 0x0012 }, + { 0x000b, 0x0014 }, + { 0x000c, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x000e, 0x001c }, + { 0x000f, 0x0021 }, + { 0x0013, 0x0110 }, + { 0x0012, 0x0093 }, + { 0x0012, 0x0094 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x000b, 0x0015 }, + { 0x000a, 0x0013 }, + { 0x000a, 0x0014 }, + { 0x000a, 0x0015 }, + { 0x000b, 0x0016 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x0016 }, + { 0x000d, 0x0017 }, + { 0x000f, 0x0022 }, + { 0x0010, 0x0031 }, + { 0x0012, 0x0095 }, + { 0x0012, 0x0096 }, + { 0x0014, 0x006f }, + { 0x0013, 0x0111 }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x000c, 0x0016 }, + { 0x000b, 0x0017 }, + { 0x000c, 0x0017 }, + { 0x000c, 0x0018 }, + { 0x000c, 0x0019 }, + { 0x000d, 0x0018 }, + { 0x000e, 0x001d }, + { 0x000f, 0x0023 }, + { 0x000f, 0x0024 }, + { 0x0011, 0x0054 }, + { 0x0012, 0x0097 }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x000e, 0x001e }, + { 0x000d, 0x0019 }, + { 0x000d, 0x001a }, + { 0x000d, 0x001b }, + { 0x000e, 0x001f }, + { 0x000f, 0x0025 }, + { 0x000f, 0x0026 }, + { 0x0010, 0x0032 }, + { 0x0010, 0x0033 }, + { 0x0012, 0x0098 }, + { 0x0013, 0x0112 }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x000f, 0x0027 }, + { 0x000f, 0x0028 }, + { 0x000f, 0x0029 }, + { 0x000f, 0x002a }, + { 0x0010, 0x0034 }, + { 0x000f, 0x002b }, + { 0x0011, 0x0055 }, + { 0x0012, 0x0099 }, + { 0x0012, 0x009a }, + { 0x0012, 0x009b }, + { 0x0014, 0x009d }, + { 0x0013, 0x0113 }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0011, 0x0056 }, + { 0x0010, 0x0035 }, + { 0x0010, 0x0036 }, + { 0x0010, 0x0037 }, + { 0x0011, 0x0057 }, + { 0x0012, 0x009c }, + { 0x0012, 0x009d }, + { 0x0012, 0x009e }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0012, 0x009f }, + { 0x0011, 0x0058 }, + { 0x0012, 0x00a0 }, + { 0x0014, 0x00c0 }, + { 0x0011, 0x0059 }, + { 0x0013, 0x0114 }, + { 0x0012, 0x00a1 }, + { 0x0014, 0x00c1 }, + { 0x0013, 0x0115 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0014, 0x00f6 }, + { 0x0014, 0x00f7 }, + { 0x0014, 0x00f8 }, + { 0x0014, 0x00f9 }, + { 0x0014, 0x00fa }, + { 0x0014, 0x00fb }, + { 0x0014, 0x00fc }, + { 0x0014, 0x00fd }, + { 0x0014, 0x00fe }, + { 0x0014, 0x00ff }, + { 0x0014, 0x0100 }, + { 0x0014, 0x0101 }, + { 0x0014, 0x0102 }, + { 0x0014, 0x0103 }, + { 0x0014, 0x0104 }, + { 0x0014, 0x0105 }, + { 0x0014, 0x0106 }, + { 0x0014, 0x0107 }, + { 0x0014, 0x0108 }, + { 0x0014, 0x0109 }, + { 0x0014, 0x010a }, + { 0x0014, 0x010b }, + { 0x0014, 0x010c }, + { 0x0014, 0x010d }, + { 0x0014, 0x010e }, + { 0x0014, 0x010f }, + { 0x0014, 0x0110 }, + { 0x0014, 0x0111 }, + { 0x0014, 0x0112 }, + { 0x0014, 0x0113 }, + { 0x0014, 0x0114 }, + { 0x0014, 0x0115 }, + { 0x0014, 0x0116 }, + { 0x0014, 0x0117 }, + { 0x0014, 0x0118 }, + { 0x0014, 0x0119 }, + { 0x0014, 0x011a }, + { 0x0014, 0x011b }, + { 0x0014, 0x011c }, + { 0x0014, 0x011d }, + { 0x0014, 0x011e }, + { 0x0014, 0x011f }, + { 0x0014, 0x0120 }, + { 0x0014, 0x0121 }, + { 0x0014, 0x0122 }, + { 0x0014, 0x0123 }, + { 0x0014, 0x0124 }, + { 0x0014, 0x0125 }, + { 0x0013, 0x0116 }, + { 0x0014, 0x0126 }, + { 0x0014, 0x0127 }, + { 0x0014, 0x0128 }, + { 0x0014, 0x0129 }, + { 0x0014, 0x012a }, + { 0x0014, 0x012b }, + { 0x0014, 0x012c }, + { 0x0014, 0x012d }, + { 0x0014, 0x012e }, + { 0x0014, 0x012f }, + { 0x0014, 0x0130 }, + { 0x0014, 0x0131 }, + { 0x0014, 0x0132 }, + { 0x0014, 0x0133 }, + { 0x0014, 0x0134 }, + { 0x0014, 0x0135 }, + { 0x0014, 0x0136 }, + { 0x0014, 0x0137 }, + { 0x0014, 0x0138 }, + { 0x0014, 0x0139 }, + { 0x0014, 0x013a }, + { 0x0014, 0x013b }, + { 0x0014, 0x013c }, + { 0x0014, 0x013d }, + { 0x0014, 0x013e }, + { 0x0014, 0x013f }, + { 0x0014, 0x0140 }, + { 0x0014, 0x0141 }, + { 0x0014, 0x0142 }, + { 0x0014, 0x0143 }, + { 0x0014, 0x0144 }, + { 0x0014, 0x0145 }, + { 0x0014, 0x0146 }, + { 0x0014, 0x0147 }, + { 0x0014, 0x0148 }, + { 0x0014, 0x0149 }, + { 0x0014, 0x014a }, + { 0x0014, 0x014b }, + { 0x0014, 0x014c }, + { 0x0014, 0x014d }, + { 0x0014, 0x014e }, + { 0x0014, 0x014f }, + { 0x0014, 0x0150 }, + { 0x0014, 0x0151 }, + { 0x0014, 0x0152 }, + { 0x0014, 0x0153 }, + { 0x0014, 0x0154 }, + { 0x0014, 0x0155 }, + { 0x0014, 0x0156 }, + { 0x0014, 0x0157 }, + { 0x0014, 0x0158 }, + { 0x0014, 0x0159 }, + { 0x0014, 0x015a }, + { 0x0014, 0x015b }, + { 0x0014, 0x015c }, + { 0x0014, 0x015d }, + { 0x0014, 0x015e }, + { 0x0014, 0x015f }, + { 0x0014, 0x0160 }, + { 0x0014, 0x0161 }, + { 0x0014, 0x0162 }, + { 0x0014, 0x0163 }, + { 0x0014, 0x0164 }, + { 0x0014, 0x0165 }, + { 0x0014, 0x0166 }, + { 0x0014, 0x0167 }, + { 0x0014, 0x0168 }, + { 0x0014, 0x0169 }, + { 0x0014, 0x016a }, + { 0x0014, 0x016b }, + { 0x0014, 0x016c }, + { 0x0014, 0x016d }, + { 0x0014, 0x016e }, + { 0x0014, 0x016f }, + { 0x0014, 0x0170 }, + { 0x0014, 0x0171 }, + { 0x0014, 0x0172 }, + { 0x0014, 0x0173 }, + { 0x0014, 0x0174 }, + { 0x0014, 0x0175 }, + { 0x0014, 0x0176 }, + { 0x0014, 0x0177 }, + { 0x0014, 0x0178 }, + { 0x0014, 0x0179 }, + { 0x0014, 0x017a }, + { 0x0014, 0x017b }, + { 0x0014, 0x017c }, + { 0x0014, 0x017d }, + { 0x0014, 0x017e }, + { 0x0014, 0x017f }, + { 0x0014, 0x0180 }, + { 0x0014, 0x0181 }, + { 0x0014, 0x0182 }, + { 0x0014, 0x0183 }, + { 0x0014, 0x0184 }, + { 0x0014, 0x0185 }, + { 0x0014, 0x0186 }, + { 0x0014, 0x0187 }, + { 0x0014, 0x0188 }, + { 0x0014, 0x0189 }, + { 0x0014, 0x018a }, + { 0x0014, 0x018b }, + { 0x0014, 0x018c }, + { 0x0014, 0x018d }, + { 0x0014, 0x018e }, + { 0x0014, 0x018f }, + { 0x0014, 0x0190 }, + { 0x0014, 0x0191 }, + { 0x0014, 0x0192 }, + { 0x0014, 0x0193 }, + { 0x0014, 0x0194 }, + { 0x0014, 0x0195 }, + { 0x0014, 0x0196 }, + { 0x0014, 0x0197 }, + { 0x0014, 0x0198 }, + { 0x0014, 0x0199 }, + { 0x0014, 0x019a }, + { 0x0014, 0x019b }, + { 0x0014, 0x019c }, + { 0x0014, 0x019d }, + { 0x0014, 0x019e }, + { 0x0014, 0x019f }, + { 0x0014, 0x01a0 }, + { 0x0014, 0x01a1 }, + { 0x0014, 0x01a2 }, + { 0x0014, 0x01a3 }, + { 0x0014, 0x01a4 }, + { 0x0014, 0x01a5 }, + { 0x0014, 0x01a6 }, + { 0x0014, 0x01a7 }, + { 0x0014, 0x01a8 }, + { 0x0014, 0x01a9 }, + { 0x0014, 0x01aa }, + { 0x0014, 0x01ab }, + { 0x0014, 0x01ac }, + { 0x0014, 0x01ad }, + { 0x0014, 0x01ae }, + { 0x0014, 0x01af }, + { 0x0014, 0x01b0 }, + { 0x0014, 0x01b1 }, + { 0x0014, 0x01b2 }, + { 0x0014, 0x01b3 }, + { 0x0014, 0x01b4 }, + { 0x0014, 0x01b5 }, + { 0x0014, 0x01b6 }, + { 0x0014, 0x01b7 }, + { 0x0014, 0x01b8 }, + { 0x0014, 0x01b9 }, + { 0x0014, 0x01ba }, + { 0x0014, 0x01bb }, + { 0x0014, 0x01bc }, + { 0x0014, 0x01bd }, + { 0x0014, 0x01be }, + { 0x0014, 0x01bf }, + { 0x0014, 0x01c0 }, + { 0x0014, 0x01c1 }, + { 0x0014, 0x01c2 }, + { 0x0014, 0x01c3 }, + { 0x0014, 0x01c4 }, + { 0x0014, 0x01c5 }, + { 0x0014, 0x01c6 }, + { 0x0014, 0x01c7 }, + { 0x0014, 0x01c8 }, + { 0x0014, 0x01c9 }, + { 0x0014, 0x01ca }, + { 0x0014, 0x01cb }, + { 0x0014, 0x01cc }, + { 0x0014, 0x01cd }, + { 0x0014, 0x01ce }, + { 0x0014, 0x01cf }, + { 0x0014, 0x01d0 }, + { 0x0014, 0x01d1 }, + { 0x0014, 0x01d2 }, + { 0x0014, 0x01d3 }, + { 0x0014, 0x01d4 }, + { 0x0014, 0x01d5 }, + { 0x0014, 0x01d6 }, + { 0x0014, 0x01d7 }, + { 0x0014, 0x01d8 }, + { 0x0014, 0x01d9 }, + { 0x0014, 0x01da }, + { 0x0014, 0x01db }, + { 0x0014, 0x01dc }, + { 0x0014, 0x01dd }, + { 0x0014, 0x01de }, + { 0x0014, 0x01df }, + { 0x0014, 0x01e0 }, + { 0x0014, 0x01e1 }, + { 0x0014, 0x01e2 }, + { 0x0014, 0x01e3 }, + { 0x0014, 0x01e4 }, + { 0x0014, 0x01e5 }, + { 0x0014, 0x01e6 }, + { 0x0014, 0x01e7 }, + { 0x0014, 0x01e8 }, + { 0x0014, 0x01e9 }, + { 0x0014, 0x01ea }, + { 0x0014, 0x01eb }, + { 0x0014, 0x01ec }, + { 0x0014, 0x01ed }, + { 0x0014, 0x01ee }, + { 0x0014, 0x01ef }, + { 0x0014, 0x01f0 }, + { 0x0014, 0x01f1 }, + { 0x0014, 0x01f2 }, + { 0x0014, 0x01f3 }, + { 0x0014, 0x01f4 }, + { 0x0014, 0x01f5 }, + { 0x0014, 0x01f6 }, + { 0x0014, 0x01f7 }, + { 0x0014, 0x01f8 }, + { 0x0014, 0x01f9 }, + { 0x0014, 0x01fa }, + { 0x0014, 0x01fb }, + { 0x0014, 0x01fc }, + { 0x0014, 0x01fd }, + { 0x0014, 0x01fe }, + { 0x0014, 0x01ff }, + { 0x0014, 0x0200 }, + { 0x0014, 0x0201 }, + { 0x0014, 0x0202 }, + { 0x0014, 0x0203 }, + { 0x0014, 0x0204 }, + { 0x0014, 0x0205 }, + { 0x0014, 0x0206 }, + { 0x0014, 0x0207 }, + { 0x0014, 0x0208 }, + { 0x0014, 0x0209 }, + { 0x0014, 0x020a }, + { 0x0014, 0x020b }, + { 0x0014, 0x020c }, + { 0x0014, 0x020d }, + { 0x0014, 0x020e }, + { 0x0014, 0x020f }, + { 0x0014, 0x0210 }, + { 0x0014, 0x0211 }, + { 0x0014, 0x0212 }, + { 0x0014, 0x0213 }, + { 0x0014, 0x0214 }, + { 0x0014, 0x0215 }, + { 0x0013, 0x0117 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec16[85][16] = { + { + 0x000fffff, + 0x000dffff, + 0x000effff, + 0x0008ffff, + 0x0009ffff, + 0x000affff, + 0x000bffff, + 0x000cffff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x0004ffff, + 0x0005ffff, + 0x0006ffff, + 0x0007ffff, + 0x0000001c, + }, + { + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + }, + { + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + }, + { + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + }, + { + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + }, + { + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + }, + { + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + }, + { + 0x0003006d, + 0x0003006d, + 0x0003006d, + 0x0003006d, + 0x0003006d, + 0x0003006d, + 0x0003006d, + 0x0003006d, + 0x0003006e, + 0x0003006e, + 0x0003006e, + 0x0003006e, + 0x0003006e, + 0x0003006e, + 0x0003006e, + 0x0003006e, + }, + { + 0x000100be, + 0x000100be, + 0x000100bf, + 0x000100bf, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020003, + 0x00020003, + 0x00020003, + 0x00020003, + }, + { + 0x00020004, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020036, + 0x00020036, + 0x00020036, + 0x00020036, + }, + { + 0x0002003b, + 0x0002003b, + 0x0002003b, + 0x0002003b, + 0x00020051, + 0x00020051, + 0x00020051, + 0x00020051, + 0x00020055, + 0x00020055, + 0x00020055, + 0x00020055, + 0x00020056, + 0x00020056, + 0x00020056, + 0x00020056, + }, + { + 0x0002006c, + 0x0002006c, + 0x0002006c, + 0x0002006c, + 0x0002006f, + 0x0002006f, + 0x0002006f, + 0x0002006f, + 0x00020070, + 0x00020070, + 0x00020070, + 0x00020070, + 0x00020088, + 0x00020088, + 0x00020088, + 0x00020088, + }, + { + 0x00020089, + 0x00020089, + 0x00020089, + 0x00020089, + 0x0002008a, + 0x0002008a, + 0x0002008a, + 0x0002008a, + 0x000200a3, + 0x000200a3, + 0x000200a3, + 0x000200a3, + 0x000200a4, + 0x000200a4, + 0x000200a4, + 0x000200a4, + }, + { + 0x000000bd, + 0x000000c0, + 0x000000c1, + 0x000000d9, + 0x00010005, + 0x00010005, + 0x00010006, + 0x00010006, + 0x00010022, + 0x00010022, + 0x0001003c, + 0x0001003c, + 0x0001003d, + 0x0001003d, + 0x00010057, + 0x00010057, + }, + { + 0x00010071, + 0x00010071, + 0x00010072, + 0x00010072, + 0x00010087, + 0x00010087, + 0x0001008b, + 0x0001008b, + 0x0001008c, + 0x0001008c, + 0x000100a2, + 0x000100a2, + 0x000100a5, + 0x000100a5, + 0x000100a6, + 0x000100a6, + }, + { + 0x0019ffff, + 0x0017ffff, + 0x0018ffff, + 0x0015ffff, + 0x0016ffff, + 0x0012ffff, + 0x0010ffff, + 0x0011ffff, + 0x0013ffff, + 0x0014ffff, + 0x00000007, + 0x00000023, + 0x00000058, + 0x00000073, + 0x0000008d, + 0x000000a7, + }, + { + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + }, + { + 0x0003008e, + 0x0003008e, + 0x0003008e, + 0x0003008e, + 0x0003008e, + 0x0003008e, + 0x0003008e, + 0x0003008e, + 0x000300a8, + 0x000300a8, + 0x000300a8, + 0x000300a8, + 0x000300a8, + 0x000300a8, + 0x000300a8, + 0x000300a8, + }, + { + 0x000200f5, + 0x000200f5, + 0x000200f5, + 0x000200f5, + 0x000200f6, + 0x000200f6, + 0x000200f6, + 0x000200f6, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + }, + { + 0x000300c2, + 0x000300c2, + 0x000300c2, + 0x000300c2, + 0x000300c2, + 0x000300c2, + 0x000300c2, + 0x000300c2, + 0x000300d8, + 0x000300d8, + 0x000300d8, + 0x000300d8, + 0x000300d8, + 0x000300d8, + 0x000300d8, + 0x000300d8, + }, + { + 0x000300da, + 0x000300da, + 0x000300da, + 0x000300da, + 0x000300da, + 0x000300da, + 0x000300da, + 0x000300da, + 0x000300db, + 0x000300db, + 0x000300db, + 0x000300db, + 0x000300db, + 0x000300db, + 0x000300db, + 0x000300db, + }, + { + 0x00020024, + 0x00020024, + 0x00020024, + 0x00020024, + 0x0002003f, + 0x0002003f, + 0x0002003f, + 0x0002003f, + 0x00020074, + 0x00020074, + 0x00020074, + 0x00020074, + 0x000200a9, + 0x000200a9, + 0x000200a9, + 0x000200a9, + }, + { + 0x000200c3, + 0x000200c3, + 0x000200c3, + 0x000200c3, + 0x000200dc, + 0x000200dc, + 0x000200dc, + 0x000200dc, + 0x000200dd, + 0x000200dd, + 0x000200dd, + 0x000200dd, + 0x000200f4, + 0x000200f4, + 0x000200f4, + 0x000200f4, + }, + { + 0x0000005b, + 0x00000076, + 0x00000090, + 0x000000c5, + 0x000000df, + 0x000000f8, + 0x0000010e, + 0x00000110, + 0x00000111, + 0x00000112, + 0x00010009, + 0x00010009, + 0x00010025, + 0x00010025, + 0x0001005a, + 0x0001005a, + }, + { + 0x00010075, + 0x00010075, + 0x0001008f, + 0x0001008f, + 0x000100aa, + 0x000100aa, + 0x000100c4, + 0x000100c4, + 0x000100de, + 0x000100de, + 0x000100f3, + 0x000100f3, + 0x000100f7, + 0x000100f7, + 0x0001010f, + 0x0001010f, + }, + { + 0x0032ffff, + 0x0043ffff, + 0x0025ffff, + 0x0023ffff, + 0x0024ffff, + 0x0021ffff, + 0x0020ffff, + 0x0022ffff, + 0x001cffff, + 0x001affff, + 0x001bffff, + 0x001dffff, + 0x001effff, + 0x001fffff, + 0x0000000a, + 0x00000040, + }, + { + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x00030091, + 0x00030091, + 0x00030091, + 0x00030091, + 0x00030091, + 0x00030091, + 0x00030091, + 0x00030091, + }, + { + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300e0, + 0x000300e0, + 0x000300e0, + 0x000300e0, + 0x000300e0, + 0x000300e0, + 0x000300e0, + 0x000300e0, + }, + { + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030041, + 0x00030041, + 0x00030041, + 0x00030041, + 0x00030041, + 0x00030041, + 0x00030041, + 0x00030041, + }, + { + 0x000300f9, + 0x000300f9, + 0x000300f9, + 0x000300f9, + 0x000300f9, + 0x000300f9, + 0x000300f9, + 0x000300f9, + 0x000300fa, + 0x000300fa, + 0x000300fa, + 0x000300fa, + 0x000300fa, + 0x000300fa, + 0x000300fa, + 0x000300fa, + }, + { + 0x00030113, + 0x00030113, + 0x00030113, + 0x00030113, + 0x00030113, + 0x00030113, + 0x00030113, + 0x00030113, + 0x0003012a, + 0x0003012a, + 0x0003012a, + 0x0003012a, + 0x0003012a, + 0x0003012a, + 0x0003012a, + 0x0003012a, + }, + { + 0x0003012b, + 0x0003012b, + 0x0003012b, + 0x0003012b, + 0x0003012b, + 0x0003012b, + 0x0003012b, + 0x0003012b, + 0x0003012c, + 0x0003012c, + 0x0003012c, + 0x0003012c, + 0x0003012c, + 0x0003012c, + 0x0003012c, + 0x0003012c, + }, + { + 0x00020077, + 0x00020077, + 0x00020077, + 0x00020077, + 0x00020092, + 0x00020092, + 0x00020092, + 0x00020092, + 0x000200ac, + 0x000200ac, + 0x000200ac, + 0x000200ac, + 0x000200c6, + 0x000200c6, + 0x000200c6, + 0x000200c6, + }, + { + 0x00010145, + 0x00010145, + 0x00010146, + 0x00010146, + 0x00010147, + 0x00010147, + 0x00010149, + 0x00010149, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x00020027, + 0x00020027, + 0x00020027, + 0x00020027, + }, + { + 0x000200e1, + 0x000200e1, + 0x000200e1, + 0x000200e1, + 0x00020114, + 0x00020114, + 0x00020114, + 0x00020114, + 0x00020129, + 0x00020129, + 0x00020129, + 0x00020129, + 0x0002012d, + 0x0002012d, + 0x0002012d, + 0x0002012d, + }, + { + 0x000000c8, + 0x000000fc, + 0x00000130, + 0x00000131, + 0x00000148, + 0x00000160, + 0x00000161, + 0x00000162, + 0x00010028, + 0x00010028, + 0x00010042, + 0x00010042, + 0x0001005d, + 0x0001005d, + 0x000100ad, + 0x000100ad, + }, + { + 0x000100c7, + 0x000100c7, + 0x000100e2, + 0x000100e2, + 0x000100fb, + 0x000100fb, + 0x00010115, + 0x00010115, + 0x00010116, + 0x00010116, + 0x0001012e, + 0x0001012e, + 0x0001012f, + 0x0001012f, + 0x00010144, + 0x00010144, + }, + { + 0x0054ffff, + 0x0031ffff, + 0x0030ffff, + 0x002bffff, + 0x002cffff, + 0x002dffff, + 0x002effff, + 0x002fffff, + 0x0027ffff, + 0x0026ffff, + 0x0028ffff, + 0x0029ffff, + 0x002affff, + 0x0000000c, + 0x00000078, + 0x00000093, + }, + { + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x000300af, + 0x000300af, + 0x000300af, + 0x000300af, + 0x000300af, + 0x000300af, + 0x000300af, + 0x000300af, + }, + { + 0x0002017c, + 0x0002017c, + 0x0002017c, + 0x0002017c, + 0x00020180, + 0x00020180, + 0x00020180, + 0x00020180, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + }, + { + 0x00030117, + 0x00030117, + 0x00030117, + 0x00030117, + 0x00030117, + 0x00030117, + 0x00030117, + 0x00030117, + 0x0003014a, + 0x0003014a, + 0x0003014a, + 0x0003014a, + 0x0003014a, + 0x0003014a, + 0x0003014a, + 0x0003014a, + }, + { + 0x0003015f, + 0x0003015f, + 0x0003015f, + 0x0003015f, + 0x0003015f, + 0x0003015f, + 0x0003015f, + 0x0003015f, + 0x00030163, + 0x00030163, + 0x00030163, + 0x00030163, + 0x00030163, + 0x00030163, + 0x00030163, + 0x00030163, + }, + { + 0x0003017b, + 0x0003017b, + 0x0003017b, + 0x0003017b, + 0x0003017b, + 0x0003017b, + 0x0003017b, + 0x0003017b, + 0x0003017e, + 0x0003017e, + 0x0003017e, + 0x0003017e, + 0x0003017e, + 0x0003017e, + 0x0003017e, + 0x0003017e, + }, + { + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x00020044, + 0x00020044, + 0x00020044, + 0x00020044, + 0x00020045, + 0x00020045, + 0x00020045, + 0x00020045, + 0x0002005e, + 0x0002005e, + 0x0002005e, + 0x0002005e, + }, + { + 0x00020079, + 0x00020079, + 0x00020079, + 0x00020079, + 0x00020094, + 0x00020094, + 0x00020094, + 0x00020094, + 0x000200c9, + 0x000200c9, + 0x000200c9, + 0x000200c9, + 0x000200e4, + 0x000200e4, + 0x000200e4, + 0x000200e4, + }, + { + 0x000200e5, + 0x000200e5, + 0x000200e5, + 0x000200e5, + 0x000200fd, + 0x000200fd, + 0x000200fd, + 0x000200fd, + 0x000200fe, + 0x000200fe, + 0x000200fe, + 0x000200fe, + 0x00020118, + 0x00020118, + 0x00020118, + 0x00020118, + }, + { + 0x00020132, + 0x00020132, + 0x00020132, + 0x00020132, + 0x0002014b, + 0x0002014b, + 0x0002014b, + 0x0002014b, + 0x0002014c, + 0x0002014c, + 0x0002014c, + 0x0002014c, + 0x0002014d, + 0x0002014d, + 0x0002014d, + 0x0002014d, + }, + { + 0x00020164, + 0x00020164, + 0x00020164, + 0x00020164, + 0x00020165, + 0x00020165, + 0x00020165, + 0x00020165, + 0x00020166, + 0x00020166, + 0x00020166, + 0x00020166, + 0x0002017a, + 0x0002017a, + 0x0002017a, + 0x0002017a, + }, + { + 0x000100e3, + 0x000100e3, + 0x00010100, + 0x00010100, + 0x00010133, + 0x00010133, + 0x0001014f, + 0x0001014f, + 0x0001017f, + 0x0001017f, + 0x00010182, + 0x00010182, + 0x000101e7, + 0x000101e7, + 0x000102d8, + 0x000102d8, + }, + { + 0x000002d2, + 0x000002d3, + 0x000002d4, + 0x000002d5, + 0x000002d6, + 0x000002d7, + 0x00010029, + 0x00010029, + 0x0001002a, + 0x0001002a, + 0x0001007a, + 0x0001007a, + 0x0001007b, + 0x0001007b, + 0x000100ae, + 0x000100ae, + }, + { + 0x0034ffff, + 0x0033ffff, + 0x0035ffff, + 0x0036ffff, + 0x0039ffff, + 0x0037ffff, + 0x0038ffff, + 0x003affff, + 0x003bffff, + 0x003cffff, + 0x003dffff, + 0x003effff, + 0x003fffff, + 0x0040ffff, + 0x0041ffff, + 0x0042ffff, + }, + { + 0x0000002f, + 0x00000030, + 0x00000031, + 0x00000032, + 0x00000033, + 0x00000034, + 0x00000035, + 0x00000046, + 0x00000047, + 0x00000048, + 0x00000049, + 0x0000004a, + 0x0000004b, + 0x0000004c, + 0x0000004d, + 0x0000004e, + }, + { + 0x0000000f, + 0x00000010, + 0x00000011, + 0x00000012, + 0x00000013, + 0x00000014, + 0x00000015, + 0x00000016, + 0x00000017, + 0x00000018, + 0x00000019, + 0x0000001a, + 0x0000002b, + 0x0000002c, + 0x0000002d, + 0x0000002e, + }, + { + 0x0000004f, + 0x00000050, + 0x0000005f, + 0x00000060, + 0x00000061, + 0x00000062, + 0x00000063, + 0x00000064, + 0x00000065, + 0x00000066, + 0x00000067, + 0x00000068, + 0x00000069, + 0x0000006a, + 0x0000006b, + 0x0000007c, + }, + { + 0x0000007d, + 0x0000007e, + 0x0000007f, + 0x00000080, + 0x00000081, + 0x00000082, + 0x00000083, + 0x00000084, + 0x00000085, + 0x00000086, + 0x00000095, + 0x00000096, + 0x00000097, + 0x00000098, + 0x00000099, + 0x0000009a, + }, + { + 0x000000b9, + 0x000000ba, + 0x000000bb, + 0x000000bc, + 0x000000ca, + 0x000000cb, + 0x000000cc, + 0x000000cd, + 0x000000ce, + 0x000000cf, + 0x000000d0, + 0x000000d1, + 0x000000d2, + 0x000000d3, + 0x000000d4, + 0x000000d5, + }, + { + 0x000000d6, + 0x000000d7, + 0x000000e6, + 0x000000e7, + 0x000000e8, + 0x000000e9, + 0x000000ea, + 0x000000eb, + 0x000000ec, + 0x000000ed, + 0x000000ee, + 0x000000ef, + 0x000000f0, + 0x000000f1, + 0x000000f2, + 0x000000ff, + }, + { + 0x0000009b, + 0x0000009c, + 0x0000009d, + 0x0000009e, + 0x0000009f, + 0x000000a0, + 0x000000a1, + 0x000000b0, + 0x000000b1, + 0x000000b2, + 0x000000b3, + 0x000000b4, + 0x000000b5, + 0x000000b6, + 0x000000b7, + 0x000000b8, + }, + { + 0x00000101, + 0x00000102, + 0x00000103, + 0x00000104, + 0x00000105, + 0x00000106, + 0x00000107, + 0x00000108, + 0x00000109, + 0x0000010a, + 0x0000010b, + 0x0000010c, + 0x0000010d, + 0x00000119, + 0x0000011a, + 0x0000011b, + }, + { + 0x0000011c, + 0x0000011d, + 0x0000011e, + 0x0000011f, + 0x00000120, + 0x00000121, + 0x00000122, + 0x00000123, + 0x00000124, + 0x00000125, + 0x00000126, + 0x00000127, + 0x00000128, + 0x00000134, + 0x00000135, + 0x00000136, + }, + { + 0x00000137, + 0x00000138, + 0x00000139, + 0x0000013a, + 0x0000013b, + 0x0000013c, + 0x0000013d, + 0x0000013e, + 0x0000013f, + 0x00000140, + 0x00000141, + 0x00000142, + 0x00000143, + 0x0000014e, + 0x00000150, + 0x00000151, + }, + { + 0x00000152, + 0x00000153, + 0x00000154, + 0x00000155, + 0x00000156, + 0x00000157, + 0x00000158, + 0x00000159, + 0x0000015a, + 0x0000015b, + 0x0000015c, + 0x0000015d, + 0x0000015e, + 0x00000167, + 0x00000168, + 0x00000169, + }, + { + 0x0000016a, + 0x0000016b, + 0x0000016c, + 0x0000016d, + 0x0000016e, + 0x0000016f, + 0x00000170, + 0x00000171, + 0x00000172, + 0x00000173, + 0x00000174, + 0x00000175, + 0x00000176, + 0x00000177, + 0x00000178, + 0x00000179, + }, + { + 0x0000017d, + 0x00000181, + 0x00000183, + 0x00000184, + 0x00000185, + 0x00000186, + 0x00000187, + 0x00000188, + 0x00000189, + 0x0000018a, + 0x0000018b, + 0x0000018c, + 0x0000018d, + 0x0000018e, + 0x0000018f, + 0x00000190, + }, + { + 0x00000191, + 0x00000192, + 0x00000193, + 0x00000194, + 0x00000195, + 0x00000196, + 0x00000197, + 0x00000198, + 0x00000199, + 0x0000019a, + 0x0000019b, + 0x0000019c, + 0x0000019d, + 0x0000019e, + 0x0000019f, + 0x000001a0, + }, + { + 0x000001a1, + 0x000001a2, + 0x000001a3, + 0x000001a4, + 0x000001a5, + 0x000001a6, + 0x000001a7, + 0x000001a8, + 0x000001a9, + 0x000001aa, + 0x000001ab, + 0x000001ac, + 0x000001ad, + 0x000001ae, + 0x000001af, + 0x000001b0, + }, + { + 0x000001b1, + 0x000001b2, + 0x000001b3, + 0x000001b4, + 0x000001b5, + 0x000001b6, + 0x000001b7, + 0x000001b8, + 0x000001b9, + 0x000001ba, + 0x000001bb, + 0x000001bc, + 0x000001bd, + 0x000001be, + 0x000001bf, + 0x000001c0, + }, + { + 0x0044ffff, + 0x0045ffff, + 0x0046ffff, + 0x0047ffff, + 0x0048ffff, + 0x0049ffff, + 0x004affff, + 0x004bffff, + 0x004cffff, + 0x004dffff, + 0x004effff, + 0x004fffff, + 0x0050ffff, + 0x0051ffff, + 0x0052ffff, + 0x0053ffff, + }, + { + 0x000001c1, + 0x000001c2, + 0x000001c3, + 0x000001c4, + 0x000001c5, + 0x000001c6, + 0x000001c7, + 0x000001c8, + 0x000001c9, + 0x000001ca, + 0x000001cb, + 0x000001cc, + 0x000001cd, + 0x000001ce, + 0x000001cf, + 0x000001d0, + }, + { + 0x000001d1, + 0x000001d2, + 0x000001d3, + 0x000001d4, + 0x000001d5, + 0x000001d6, + 0x000001d7, + 0x000001d8, + 0x000001d9, + 0x000001da, + 0x000001db, + 0x000001dc, + 0x000001dd, + 0x000001de, + 0x000001df, + 0x000001e0, + }, + { + 0x000001e1, + 0x000001e2, + 0x000001e3, + 0x000001e4, + 0x000001e5, + 0x000001e6, + 0x000001e8, + 0x000001e9, + 0x000001ea, + 0x000001eb, + 0x000001ec, + 0x000001ed, + 0x000001ee, + 0x000001ef, + 0x000001f0, + 0x000001f1, + }, + { + 0x000001f2, + 0x000001f3, + 0x000001f4, + 0x000001f5, + 0x000001f6, + 0x000001f7, + 0x000001f8, + 0x000001f9, + 0x000001fa, + 0x000001fb, + 0x000001fc, + 0x000001fd, + 0x000001fe, + 0x000001ff, + 0x00000200, + 0x00000201, + }, + { + 0x00000202, + 0x00000203, + 0x00000204, + 0x00000205, + 0x00000206, + 0x00000207, + 0x00000208, + 0x00000209, + 0x0000020a, + 0x0000020b, + 0x0000020c, + 0x0000020d, + 0x0000020e, + 0x0000020f, + 0x00000210, + 0x00000211, + }, + { + 0x00000212, + 0x00000213, + 0x00000214, + 0x00000215, + 0x00000216, + 0x00000217, + 0x00000218, + 0x00000219, + 0x0000021a, + 0x0000021b, + 0x0000021c, + 0x0000021d, + 0x0000021e, + 0x0000021f, + 0x00000220, + 0x00000221, + }, + { + 0x00000222, + 0x00000223, + 0x00000224, + 0x00000225, + 0x00000226, + 0x00000227, + 0x00000228, + 0x00000229, + 0x0000022a, + 0x0000022b, + 0x0000022c, + 0x0000022d, + 0x0000022e, + 0x0000022f, + 0x00000230, + 0x00000231, + }, + { + 0x00000232, + 0x00000233, + 0x00000234, + 0x00000235, + 0x00000236, + 0x00000237, + 0x00000238, + 0x00000239, + 0x0000023a, + 0x0000023b, + 0x0000023c, + 0x0000023d, + 0x0000023e, + 0x0000023f, + 0x00000240, + 0x00000241, + }, + { + 0x00000242, + 0x00000243, + 0x00000244, + 0x00000245, + 0x00000246, + 0x00000247, + 0x00000248, + 0x00000249, + 0x0000024a, + 0x0000024b, + 0x0000024c, + 0x0000024d, + 0x0000024e, + 0x0000024f, + 0x00000250, + 0x00000251, + }, + { + 0x00000252, + 0x00000253, + 0x00000254, + 0x00000255, + 0x00000256, + 0x00000257, + 0x00000258, + 0x00000259, + 0x0000025a, + 0x0000025b, + 0x0000025c, + 0x0000025d, + 0x0000025e, + 0x0000025f, + 0x00000260, + 0x00000261, + }, + { + 0x00000262, + 0x00000263, + 0x00000264, + 0x00000265, + 0x00000266, + 0x00000267, + 0x00000268, + 0x00000269, + 0x0000026a, + 0x0000026b, + 0x0000026c, + 0x0000026d, + 0x0000026e, + 0x0000026f, + 0x00000270, + 0x00000271, + }, + { + 0x00000272, + 0x00000273, + 0x00000274, + 0x00000275, + 0x00000276, + 0x00000277, + 0x00000278, + 0x00000279, + 0x0000027a, + 0x0000027b, + 0x0000027c, + 0x0000027d, + 0x0000027e, + 0x0000027f, + 0x00000280, + 0x00000281, + }, + { + 0x00000282, + 0x00000283, + 0x00000284, + 0x00000285, + 0x00000286, + 0x00000287, + 0x00000288, + 0x00000289, + 0x0000028a, + 0x0000028b, + 0x0000028c, + 0x0000028d, + 0x0000028e, + 0x0000028f, + 0x00000290, + 0x00000291, + }, + { + 0x00000292, + 0x00000293, + 0x00000294, + 0x00000295, + 0x00000296, + 0x00000297, + 0x00000298, + 0x00000299, + 0x0000029a, + 0x0000029b, + 0x0000029c, + 0x0000029d, + 0x0000029e, + 0x0000029f, + 0x000002a0, + 0x000002a1, + }, + { + 0x000002a2, + 0x000002a3, + 0x000002a4, + 0x000002a5, + 0x000002a6, + 0x000002a7, + 0x000002a8, + 0x000002a9, + 0x000002aa, + 0x000002ab, + 0x000002ac, + 0x000002ad, + 0x000002ae, + 0x000002af, + 0x000002b0, + 0x000002b1, + }, + { + 0x000002b2, + 0x000002b3, + 0x000002b4, + 0x000002b5, + 0x000002b6, + 0x000002b7, + 0x000002b8, + 0x000002b9, + 0x000002ba, + 0x000002bb, + 0x000002bc, + 0x000002bd, + 0x000002be, + 0x000002bf, + 0x000002c0, + 0x000002c1, + }, + { + 0x000002c2, + 0x000002c3, + 0x000002c4, + 0x000002c5, + 0x000002c6, + 0x000002c7, + 0x000002c8, + 0x000002c9, + 0x000002ca, + 0x000002cb, + 0x000002cc, + 0x000002cd, + 0x000002ce, + 0x000002cf, + 0x000002d0, + 0x000002d1, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc17[729][2] = +#else +const uint16_t c_aauiCQMFHuffEnc17[729][2] = +#endif + { + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0009, 0x000f }, + { 0x000a, 0x000f }, + { 0x000c, 0x0011 }, + { 0x000d, 0x0014 }, + { 0x000e, 0x0017 }, + { 0x0010, 0x002d }, + { 0x0011, 0x004c }, + { 0x0012, 0x008a }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0006, 0x0016 }, + { 0x0005, 0x0018 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0008, 0x0010 }, + { 0x000a, 0x0010 }, + { 0x000b, 0x0011 }, + { 0x000c, 0x0012 }, + { 0x000e, 0x0018 }, + { 0x000f, 0x0020 }, + { 0x0011, 0x004d }, + { 0x0013, 0x00e4 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0006, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0007, 0x0014 }, + { 0x0008, 0x0011 }, + { 0x0009, 0x0010 }, + { 0x000a, 0x0011 }, + { 0x000b, 0x0012 }, + { 0x000c, 0x0013 }, + { 0x000e, 0x0019 }, + { 0x000f, 0x0021 }, + { 0x0010, 0x002e }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0006, 0x001e }, + { 0x0005, 0x001e }, + { 0x0005, 0x001f }, + { 0x0006, 0x001f }, + { 0x0006, 0x0020 }, + { 0x0006, 0x0021 }, + { 0x0006, 0x0022 }, + { 0x0007, 0x0015 }, + { 0x0008, 0x0012 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x0012 }, + { 0x000b, 0x0013 }, + { 0x000c, 0x0014 }, + { 0x000e, 0x001a }, + { 0x000f, 0x0022 }, + { 0x0010, 0x002f }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0006, 0x0023 }, + { 0x0006, 0x0024 }, + { 0x0006, 0x0025 }, + { 0x0006, 0x0026 }, + { 0x0006, 0x0027 }, + { 0x0006, 0x0028 }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0008, 0x0013 }, + { 0x0009, 0x0012 }, + { 0x000a, 0x0013 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x0015 }, + { 0x000f, 0x0023 }, + { 0x0010, 0x0030 }, + { 0x0011, 0x004e }, + { 0x0014, 0x0026 }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0007, 0x0018 }, + { 0x0006, 0x0029 }, + { 0x0006, 0x002a }, + { 0x0006, 0x002b }, + { 0x0006, 0x002c }, + { 0x0007, 0x0019 }, + { 0x0007, 0x001a }, + { 0x0008, 0x0014 }, + { 0x0009, 0x0013 }, + { 0x000a, 0x0014 }, + { 0x000b, 0x0014 }, + { 0x000c, 0x0016 }, + { 0x000d, 0x0016 }, + { 0x000f, 0x0024 }, + { 0x0010, 0x0031 }, + { 0x0011, 0x004f }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0007, 0x001b }, + { 0x0006, 0x002d }, + { 0x0006, 0x002e }, + { 0x0006, 0x002f }, + { 0x0007, 0x001c }, + { 0x0007, 0x001d }, + { 0x0008, 0x0015 }, + { 0x0009, 0x0014 }, + { 0x000a, 0x0015 }, + { 0x000a, 0x0016 }, + { 0x000c, 0x0017 }, + { 0x000d, 0x0017 }, + { 0x000e, 0x001b }, + { 0x000f, 0x0025 }, + { 0x0011, 0x0050 }, + { 0x0011, 0x0051 }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0008, 0x0016 }, + { 0x0007, 0x001e }, + { 0x0007, 0x001f }, + { 0x0007, 0x0020 }, + { 0x0007, 0x0021 }, + { 0x0008, 0x0017 }, + { 0x0008, 0x0018 }, + { 0x0009, 0x0015 }, + { 0x000a, 0x0017 }, + { 0x000b, 0x0015 }, + { 0x000c, 0x0018 }, + { 0x000e, 0x001c }, + { 0x000e, 0x001d }, + { 0x0010, 0x0032 }, + { 0x0012, 0x008b }, + { 0x0012, 0x008c }, + { 0x0014, 0x0047 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0008, 0x0019 }, + { 0x0007, 0x0022 }, + { 0x0007, 0x0023 }, + { 0x0008, 0x001a }, + { 0x0008, 0x001b }, + { 0x0009, 0x0016 }, + { 0x0009, 0x0017 }, + { 0x000a, 0x0018 }, + { 0x000b, 0x0016 }, + { 0x000c, 0x0019 }, + { 0x000d, 0x0018 }, + { 0x000e, 0x001e }, + { 0x0010, 0x0033 }, + { 0x0011, 0x0052 }, + { 0x0014, 0x0052 }, + { 0x0013, 0x00e9 }, + { 0x0014, 0x0053 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0009, 0x0018 }, + { 0x0008, 0x001c }, + { 0x0008, 0x001d }, + { 0x0009, 0x0019 }, + { 0x0009, 0x001a }, + { 0x000a, 0x0019 }, + { 0x000a, 0x001a }, + { 0x000b, 0x0017 }, + { 0x000c, 0x001a }, + { 0x000d, 0x0019 }, + { 0x000e, 0x001f }, + { 0x000f, 0x0026 }, + { 0x0010, 0x0034 }, + { 0x0012, 0x008d }, + { 0x0013, 0x00ea }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x000b, 0x0018 }, + { 0x0009, 0x001b }, + { 0x000a, 0x001b }, + { 0x000a, 0x001c }, + { 0x000a, 0x001d }, + { 0x000b, 0x0019 }, + { 0x000b, 0x001a }, + { 0x000c, 0x001b }, + { 0x000d, 0x001a }, + { 0x000e, 0x0020 }, + { 0x000f, 0x0027 }, + { 0x0012, 0x008e }, + { 0x0011, 0x0053 }, + { 0x0013, 0x00eb }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x000c, 0x001c }, + { 0x000b, 0x001b }, + { 0x000b, 0x001c }, + { 0x000b, 0x001d }, + { 0x000c, 0x001d }, + { 0x000c, 0x001e }, + { 0x000d, 0x001b }, + { 0x000d, 0x001c }, + { 0x000e, 0x0021 }, + { 0x0010, 0x0035 }, + { 0x0010, 0x0036 }, + { 0x0011, 0x0054 }, + { 0x0013, 0x00ec }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x000d, 0x001d }, + { 0x000c, 0x001f }, + { 0x000c, 0x0020 }, + { 0x000c, 0x0021 }, + { 0x000d, 0x001e }, + { 0x000d, 0x001f }, + { 0x000e, 0x0022 }, + { 0x000f, 0x0028 }, + { 0x0010, 0x0037 }, + { 0x0010, 0x0038 }, + { 0x0010, 0x0039 }, + { 0x0012, 0x008f }, + { 0x0013, 0x00ed }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x000e, 0x0023 }, + { 0x000d, 0x0020 }, + { 0x000d, 0x0021 }, + { 0x000e, 0x0024 }, + { 0x000e, 0x0025 }, + { 0x000e, 0x0026 }, + { 0x000f, 0x0029 }, + { 0x0010, 0x003a }, + { 0x0010, 0x003b }, + { 0x0012, 0x0090 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x000f, 0x002a }, + { 0x000e, 0x0027 }, + { 0x000f, 0x002b }, + { 0x000f, 0x002c }, + { 0x000f, 0x002d }, + { 0x0010, 0x003c }, + { 0x0010, 0x003d }, + { 0x0011, 0x0055 }, + { 0x0011, 0x0056 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0012, 0x0091 }, + { 0x0010, 0x003e }, + { 0x0010, 0x003f }, + { 0x0011, 0x0057 }, + { 0x0011, 0x0058 }, + { 0x0011, 0x0059 }, + { 0x0012, 0x0092 }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0012, 0x0093 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0014, 0x00c0 }, + { 0x0014, 0x00c1 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0013, 0x00f0 }, + { 0x0012, 0x0094 }, + { 0x0012, 0x0095 }, + { 0x0012, 0x0096 }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0012, 0x0097 }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0014, 0x00f6 }, + { 0x0014, 0x00f7 }, + { 0x0014, 0x00f8 }, + { 0x0014, 0x00f9 }, + { 0x0014, 0x00fa }, + { 0x0014, 0x00fb }, + { 0x0014, 0x00fc }, + { 0x0014, 0x00fd }, + { 0x0014, 0x00fe }, + { 0x0014, 0x00ff }, + { 0x0014, 0x0100 }, + { 0x0014, 0x0101 }, + { 0x0014, 0x0102 }, + { 0x0014, 0x0103 }, + { 0x0014, 0x0104 }, + { 0x0014, 0x0105 }, + { 0x0014, 0x0106 }, + { 0x0014, 0x0107 }, + { 0x0014, 0x0108 }, + { 0x0014, 0x0109 }, + { 0x0014, 0x010a }, + { 0x0014, 0x010b }, + { 0x0014, 0x010c }, + { 0x0014, 0x010d }, + { 0x0014, 0x010e }, + { 0x0014, 0x010f }, + { 0x0014, 0x0110 }, + { 0x0014, 0x0111 }, + { 0x0014, 0x0112 }, + { 0x0014, 0x0113 }, + { 0x0014, 0x0114 }, + { 0x0014, 0x0115 }, + { 0x0014, 0x0116 }, + { 0x0014, 0x0117 }, + { 0x0014, 0x0118 }, + { 0x0014, 0x0119 }, + { 0x0014, 0x011a }, + { 0x0014, 0x011b }, + { 0x0014, 0x011c }, + { 0x0014, 0x011d }, + { 0x0014, 0x011e }, + { 0x0014, 0x011f }, + { 0x0014, 0x0120 }, + { 0x0014, 0x0121 }, + { 0x0014, 0x0122 }, + { 0x0014, 0x0123 }, + { 0x0014, 0x0124 }, + { 0x0014, 0x0125 }, + { 0x0014, 0x0126 }, + { 0x0014, 0x0127 }, + { 0x0014, 0x0128 }, + { 0x0014, 0x0129 }, + { 0x0014, 0x012a }, + { 0x0014, 0x012b }, + { 0x0014, 0x012c }, + { 0x0014, 0x012d }, + { 0x0014, 0x012e }, + { 0x0014, 0x012f }, + { 0x0014, 0x0130 }, + { 0x0014, 0x0131 }, + { 0x0014, 0x0132 }, + { 0x0014, 0x0133 }, + { 0x0014, 0x0134 }, + { 0x0014, 0x0135 }, + { 0x0014, 0x0136 }, + { 0x0014, 0x0137 }, + { 0x0014, 0x0138 }, + { 0x0014, 0x0139 }, + { 0x0014, 0x013a }, + { 0x0014, 0x013b }, + { 0x0014, 0x013c }, + { 0x0014, 0x013d }, + { 0x0014, 0x013e }, + { 0x0014, 0x013f }, + { 0x0014, 0x0140 }, + { 0x0014, 0x0141 }, + { 0x0014, 0x0142 }, + { 0x0014, 0x0143 }, + { 0x0014, 0x0144 }, + { 0x0014, 0x0145 }, + { 0x0014, 0x0146 }, + { 0x0014, 0x0147 }, + { 0x0014, 0x0148 }, + { 0x0014, 0x0149 }, + { 0x0014, 0x014a }, + { 0x0014, 0x014b }, + { 0x0014, 0x014c }, + { 0x0014, 0x014d }, + { 0x0014, 0x014e }, + { 0x0014, 0x014f }, + { 0x0014, 0x0150 }, + { 0x0014, 0x0151 }, + { 0x0014, 0x0152 }, + { 0x0014, 0x0153 }, + { 0x0014, 0x0154 }, + { 0x0014, 0x0155 }, + { 0x0014, 0x0156 }, + { 0x0014, 0x0157 }, + { 0x0014, 0x0158 }, + { 0x0014, 0x0159 }, + { 0x0014, 0x015a }, + { 0x0014, 0x015b }, + { 0x0014, 0x015c }, + { 0x0014, 0x015d }, + { 0x0014, 0x015e }, + { 0x0014, 0x015f }, + { 0x0014, 0x0160 }, + { 0x0014, 0x0161 }, + { 0x0014, 0x0162 }, + { 0x0014, 0x0163 }, + { 0x0014, 0x0164 }, + { 0x0014, 0x0165 }, + { 0x0014, 0x0166 }, + { 0x0014, 0x0167 }, + { 0x0014, 0x0168 }, + { 0x0014, 0x0169 }, + { 0x0014, 0x016a }, + { 0x0014, 0x016b }, + { 0x0014, 0x016c }, + { 0x0014, 0x016d }, + { 0x0014, 0x016e }, + { 0x0014, 0x016f }, + { 0x0014, 0x0170 }, + { 0x0014, 0x0171 }, + { 0x0014, 0x0172 }, + { 0x0014, 0x0173 }, + { 0x0014, 0x0174 }, + { 0x0014, 0x0175 }, + { 0x0014, 0x0176 }, + { 0x0014, 0x0177 }, + { 0x0014, 0x0178 }, + { 0x0014, 0x0179 }, + { 0x0014, 0x017a }, + { 0x0014, 0x017b }, + { 0x0014, 0x017c }, + { 0x0014, 0x017d }, + { 0x0014, 0x017e }, + { 0x0014, 0x017f }, + { 0x0014, 0x0180 }, + { 0x0014, 0x0181 }, + { 0x0014, 0x0182 }, + { 0x0014, 0x0183 }, + { 0x0014, 0x0184 }, + { 0x0014, 0x0185 }, + { 0x0014, 0x0186 }, + { 0x0014, 0x0187 }, + { 0x0014, 0x0188 }, + { 0x0014, 0x0189 }, + { 0x0014, 0x018a }, + { 0x0014, 0x018b }, + { 0x0014, 0x018c }, + { 0x0014, 0x018d }, + { 0x0014, 0x018e }, + { 0x0014, 0x018f }, + { 0x0014, 0x0190 }, + { 0x0014, 0x0191 }, + { 0x0014, 0x0192 }, + { 0x0014, 0x0193 }, + { 0x0014, 0x0194 }, + { 0x0014, 0x0195 }, + { 0x0014, 0x0196 }, + { 0x0014, 0x0197 }, + { 0x0014, 0x0198 }, + { 0x0014, 0x0199 }, + { 0x0014, 0x019a }, + { 0x0014, 0x019b }, + { 0x0014, 0x019c }, + { 0x0014, 0x019d }, + { 0x0014, 0x019e }, + { 0x0014, 0x019f }, + { 0x0014, 0x01a0 }, + { 0x0014, 0x01a1 }, + { 0x0014, 0x01a2 }, + { 0x0014, 0x01a3 }, + { 0x0014, 0x01a4 }, + { 0x0014, 0x01a5 }, + { 0x0014, 0x01a6 }, + { 0x0014, 0x01a7 }, + { 0x0014, 0x01a8 }, + { 0x0014, 0x01a9 }, + { 0x0014, 0x01aa }, + { 0x0014, 0x01ab }, + { 0x0014, 0x01ac }, + { 0x0014, 0x01ad }, + { 0x0014, 0x01ae }, + { 0x0014, 0x01af }, + { 0x0014, 0x01b0 }, + { 0x0014, 0x01b1 }, + { 0x0014, 0x01b2 }, + { 0x0014, 0x01b3 }, + { 0x0014, 0x01b4 }, + { 0x0014, 0x01b5 }, + { 0x0014, 0x01b6 }, + { 0x0014, 0x01b7 }, + { 0x0014, 0x01b8 }, + { 0x0014, 0x01b9 }, + { 0x0014, 0x01ba }, + { 0x0014, 0x01bb }, + { 0x0014, 0x01bc }, + { 0x0014, 0x01bd }, + { 0x0014, 0x01be }, + { 0x0014, 0x01bf }, + { 0x0014, 0x01c0 }, + { 0x0014, 0x01c1 }, + { 0x0014, 0x01c2 }, + { 0x0014, 0x01c3 }, + { 0x0014, 0x01c4 }, + { 0x0014, 0x01c5 }, + { 0x0014, 0x01c6 }, + { 0x0014, 0x01c7 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec17[93][16] = { + { + 0x0010ffff, + 0x000dffff, + 0x000effff, + 0x000fffff, + 0x0006ffff, + 0x0005ffff, + 0x0007ffff, + 0x0008ffff, + 0x0009ffff, + 0x000affff, + 0x000bffff, + 0x000cffff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x0004ffff, + }, + { + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + }, + { + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + }, + { + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + }, + { + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + }, + { + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020003, + 0x00020003, + 0x00020003, + 0x00020003, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + }, + { + 0x000100c0, + 0x000100c0, + 0x000100c1, + 0x000100c1, + 0x000100d9, + 0x000100d9, + 0x000100da, + 0x000100da, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020001, + }, + { + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020036, + 0x00020036, + 0x00020036, + 0x00020036, + 0x0002003a, + 0x0002003a, + 0x0002003a, + 0x0002003a, + }, + { + 0x0002003b, + 0x0002003b, + 0x0002003b, + 0x0002003b, + 0x0002003c, + 0x0002003c, + 0x0002003c, + 0x0002003c, + 0x00020051, + 0x00020051, + 0x00020051, + 0x00020051, + 0x00020054, + 0x00020054, + 0x00020054, + 0x00020054, + }, + { + 0x00020055, + 0x00020055, + 0x00020055, + 0x00020055, + 0x00020056, + 0x00020056, + 0x00020056, + 0x00020056, + 0x00020057, + 0x00020057, + 0x00020057, + 0x00020057, + 0x0002006c, + 0x0002006c, + 0x0002006c, + 0x0002006c, + }, + { + 0x0002006d, + 0x0002006d, + 0x0002006d, + 0x0002006d, + 0x0002006e, + 0x0002006e, + 0x0002006e, + 0x0002006e, + 0x0002006f, + 0x0002006f, + 0x0002006f, + 0x0002006f, + 0x00020070, + 0x00020070, + 0x00020070, + 0x00020070, + }, + { + 0x00020071, + 0x00020071, + 0x00020071, + 0x00020071, + 0x00020088, + 0x00020088, + 0x00020088, + 0x00020088, + 0x00020089, + 0x00020089, + 0x00020089, + 0x00020089, + 0x0002008a, + 0x0002008a, + 0x0002008a, + 0x0002008a, + }, + { + 0x0002008b, + 0x0002008b, + 0x0002008b, + 0x0002008b, + 0x000200a3, + 0x000200a3, + 0x000200a3, + 0x000200a3, + 0x000200a4, + 0x000200a4, + 0x000200a4, + 0x000200a4, + 0x000200a5, + 0x000200a5, + 0x000200a5, + 0x000200a5, + }, + { + 0x00000024, + 0x0000003e, + 0x00000059, + 0x00000074, + 0x0000008e, + 0x000000a8, + 0x000000bd, + 0x000000c2, + 0x000000c3, + 0x000000d8, + 0x000000db, + 0x000000dc, + 0x000000f4, + 0x000000f5, + 0x00010004, + 0x00010004, + }, + { + 0x00010005, + 0x00010005, + 0x00010006, + 0x00010006, + 0x00010022, + 0x00010022, + 0x00010023, + 0x00010023, + 0x0001003d, + 0x0001003d, + 0x00010058, + 0x00010058, + 0x00010072, + 0x00010072, + 0x00010073, + 0x00010073, + }, + { + 0x00010087, + 0x00010087, + 0x0001008c, + 0x0001008c, + 0x0001008d, + 0x0001008d, + 0x000100a2, + 0x000100a2, + 0x000100a6, + 0x000100a6, + 0x000100a7, + 0x000100a7, + 0x000100be, + 0x000100be, + 0x000100bf, + 0x000100bf, + }, + { + 0x001effff, + 0x001dffff, + 0x001cffff, + 0x0019ffff, + 0x0018ffff, + 0x001affff, + 0x001bffff, + 0x0012ffff, + 0x0011ffff, + 0x0013ffff, + 0x0014ffff, + 0x0015ffff, + 0x0016ffff, + 0x0017ffff, + 0x00000007, + 0x00000008, + }, + { + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + }, + { + 0x00020111, + 0x00020111, + 0x00020111, + 0x00020111, + 0x00020112, + 0x00020112, + 0x00020112, + 0x00020112, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + }, + { + 0x00030075, + 0x00030075, + 0x00030075, + 0x00030075, + 0x00030075, + 0x00030075, + 0x00030075, + 0x00030075, + 0x0003008f, + 0x0003008f, + 0x0003008f, + 0x0003008f, + 0x0003008f, + 0x0003008f, + 0x0003008f, + 0x0003008f, + }, + { + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300c4, + 0x000300c4, + 0x000300c4, + 0x000300c4, + 0x000300c4, + 0x000300c4, + 0x000300c4, + 0x000300c4, + }, + { + 0x000300dd, + 0x000300dd, + 0x000300dd, + 0x000300dd, + 0x000300dd, + 0x000300dd, + 0x000300dd, + 0x000300dd, + 0x000300de, + 0x000300de, + 0x000300de, + 0x000300de, + 0x000300de, + 0x000300de, + 0x000300de, + 0x000300de, + }, + { + 0x000300f3, + 0x000300f3, + 0x000300f3, + 0x000300f3, + 0x000300f3, + 0x000300f3, + 0x000300f3, + 0x000300f3, + 0x000300f6, + 0x000300f6, + 0x000300f6, + 0x000300f6, + 0x000300f6, + 0x000300f6, + 0x000300f6, + 0x000300f6, + }, + { + 0x000300f7, + 0x000300f7, + 0x000300f7, + 0x000300f7, + 0x000300f7, + 0x000300f7, + 0x000300f7, + 0x000300f7, + 0x0003010f, + 0x0003010f, + 0x0003010f, + 0x0003010f, + 0x0003010f, + 0x0003010f, + 0x0003010f, + 0x0003010f, + }, + { + 0x00020025, + 0x00020025, + 0x00020025, + 0x00020025, + 0x00020040, + 0x00020040, + 0x00020040, + 0x00020040, + 0x0002005b, + 0x0002005b, + 0x0002005b, + 0x0002005b, + 0x00020076, + 0x00020076, + 0x00020076, + 0x00020076, + }, + { + 0x0001010e, + 0x0001010e, + 0x00010113, + 0x00010113, + 0x00010114, + 0x00010114, + 0x0001012a, + 0x0001012a, + 0x0001012b, + 0x0001012b, + 0x0001012c, + 0x0001012c, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000a, + }, + { + 0x00020090, + 0x00020090, + 0x00020090, + 0x00020090, + 0x000200aa, + 0x000200aa, + 0x000200aa, + 0x000200aa, + 0x000200ab, + 0x000200ab, + 0x000200ab, + 0x000200ab, + 0x000200c5, + 0x000200c5, + 0x000200c5, + 0x000200c5, + }, + { + 0x000200df, + 0x000200df, + 0x000200df, + 0x000200df, + 0x000200f8, + 0x000200f8, + 0x000200f8, + 0x000200f8, + 0x000200f9, + 0x000200f9, + 0x000200f9, + 0x000200f9, + 0x00020110, + 0x00020110, + 0x00020110, + 0x00020110, + }, + { + 0x00000146, + 0x00000147, + 0x00010026, + 0x00010026, + 0x00010041, + 0x00010041, + 0x0001005c, + 0x0001005c, + 0x00010091, + 0x00010091, + 0x000100c6, + 0x000100c6, + 0x000100e0, + 0x000100e0, + 0x000100fa, + 0x000100fa, + }, + { + 0x0025ffff, + 0x0000000b, + 0x00000027, + 0x00000042, + 0x0000005d, + 0x00000077, + 0x00000092, + 0x000000ac, + 0x000000c7, + 0x000000e1, + 0x000000fb, + 0x00000115, + 0x00000129, + 0x0000012d, + 0x0000012e, + 0x00000145, + }, + { + 0x0040ffff, + 0x0039ffff, + 0x002dffff, + 0x002cffff, + 0x002bffff, + 0x0028ffff, + 0x0026ffff, + 0x0027ffff, + 0x0029ffff, + 0x002affff, + 0x001fffff, + 0x0020ffff, + 0x0021ffff, + 0x0022ffff, + 0x0023ffff, + 0x0024ffff, + }, + { + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + }, + { + 0x00030093, + 0x00030093, + 0x00030093, + 0x00030093, + 0x00030093, + 0x00030093, + 0x00030093, + 0x00030093, + 0x000300ad, + 0x000300ad, + 0x000300ad, + 0x000300ad, + 0x000300ad, + 0x000300ad, + 0x000300ad, + 0x000300ad, + }, + { + 0x000300e2, + 0x000300e2, + 0x000300e2, + 0x000300e2, + 0x000300e2, + 0x000300e2, + 0x000300e2, + 0x000300e2, + 0x000300fc, + 0x000300fc, + 0x000300fc, + 0x000300fc, + 0x000300fc, + 0x000300fc, + 0x000300fc, + 0x000300fc, + }, + { + 0x00030116, + 0x00030116, + 0x00030116, + 0x00030116, + 0x00030116, + 0x00030116, + 0x00030116, + 0x00030116, + 0x0003012f, + 0x0003012f, + 0x0003012f, + 0x0003012f, + 0x0003012f, + 0x0003012f, + 0x0003012f, + 0x0003012f, + }, + { + 0x00030130, + 0x00030130, + 0x00030130, + 0x00030130, + 0x00030130, + 0x00030130, + 0x00030130, + 0x00030130, + 0x00030144, + 0x00030144, + 0x00030144, + 0x00030144, + 0x00030144, + 0x00030144, + 0x00030144, + 0x00030144, + }, + { + 0x00030148, + 0x00030148, + 0x00030148, + 0x00030148, + 0x00030148, + 0x00030148, + 0x00030148, + 0x00030148, + 0x00030149, + 0x00030149, + 0x00030149, + 0x00030149, + 0x00030149, + 0x00030149, + 0x00030149, + 0x00030149, + }, + { + 0x00030160, + 0x00030160, + 0x00030160, + 0x00030160, + 0x00030160, + 0x00030160, + 0x00030160, + 0x00030160, + 0x00030161, + 0x00030161, + 0x00030161, + 0x00030161, + 0x00030161, + 0x00030161, + 0x00030161, + 0x00030161, + }, + { + 0x00020028, + 0x00020028, + 0x00020028, + 0x00020028, + 0x00020043, + 0x00020043, + 0x00020043, + 0x00020043, + 0x0002005e, + 0x0002005e, + 0x0002005e, + 0x0002005e, + 0x000200ae, + 0x000200ae, + 0x000200ae, + 0x000200ae, + }, + { + 0x000200c8, + 0x000200c8, + 0x000200c8, + 0x000200c8, + 0x000200c9, + 0x000200c9, + 0x000200c9, + 0x000200c9, + 0x000200e3, + 0x000200e3, + 0x000200e3, + 0x000200e3, + 0x000200fd, + 0x000200fd, + 0x000200fd, + 0x000200fd, + }, + { + 0x0001014b, + 0x0001014b, + 0x00010165, + 0x00010165, + 0x0001017a, + 0x0001017a, + 0x0001017c, + 0x0001017c, + 0x0001017d, + 0x0001017d, + 0x0001017e, + 0x0001017e, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + }, + { + 0x00020117, + 0x00020117, + 0x00020117, + 0x00020117, + 0x00020131, + 0x00020131, + 0x00020131, + 0x00020131, + 0x0002014a, + 0x0002014a, + 0x0002014a, + 0x0002014a, + 0x0002015f, + 0x0002015f, + 0x0002015f, + 0x0002015f, + }, + { + 0x00020162, + 0x00020162, + 0x00020162, + 0x00020162, + 0x00020163, + 0x00020163, + 0x00020163, + 0x00020163, + 0x00020164, + 0x00020164, + 0x00020164, + 0x00020164, + 0x0002017b, + 0x0002017b, + 0x0002017b, + 0x0002017b, + }, + { + 0x00010029, + 0x00010029, + 0x00010044, + 0x00010044, + 0x0001005f, + 0x0001005f, + 0x00010079, + 0x00010079, + 0x00010094, + 0x00010094, + 0x000100af, + 0x000100af, + 0x000100fe, + 0x000100fe, + 0x00010118, + 0x00010118, + }, + { + 0x0000007a, + 0x00000095, + 0x000000ca, + 0x000000e4, + 0x000000ff, + 0x00000132, + 0x00000133, + 0x0000014c, + 0x0000014d, + 0x0000014e, + 0x00000166, + 0x00000167, + 0x0000017f, + 0x00000180, + 0x00000196, + 0x00000197, + }, + { + 0x003effff, + 0x003fffff, + 0x0036ffff, + 0x0035ffff, + 0x0037ffff, + 0x0038ffff, + 0x0031ffff, + 0x002effff, + 0x0032ffff, + 0x002fffff, + 0x0030ffff, + 0x0033ffff, + 0x0034ffff, + 0x0000000e, + 0x00000045, + 0x00000060, + }, + { + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x00030096, + 0x00030096, + 0x00030096, + 0x00030096, + 0x00030096, + 0x00030096, + 0x00030096, + 0x00030096, + }, + { + 0x000300e5, + 0x000300e5, + 0x000300e5, + 0x000300e5, + 0x000300e5, + 0x000300e5, + 0x000300e5, + 0x000300e5, + 0x0003011a, + 0x0003011a, + 0x0003011a, + 0x0003011a, + 0x0003011a, + 0x0003011a, + 0x0003011a, + 0x0003011a, + }, + { + 0x00030134, + 0x00030134, + 0x00030134, + 0x00030134, + 0x00030134, + 0x00030134, + 0x00030134, + 0x00030134, + 0x00030181, + 0x00030181, + 0x00030181, + 0x00030181, + 0x00030181, + 0x00030181, + 0x00030181, + 0x00030181, + }, + { + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + }, + { + 0x000300b0, + 0x000300b0, + 0x000300b0, + 0x000300b0, + 0x000300b0, + 0x000300b0, + 0x000300b0, + 0x000300b0, + 0x000300b1, + 0x000300b1, + 0x000300b1, + 0x000300b1, + 0x000300b1, + 0x000300b1, + 0x000300b1, + 0x000300b1, + }, + { + 0x00030182, + 0x00030182, + 0x00030182, + 0x00030182, + 0x00030182, + 0x00030182, + 0x00030182, + 0x00030182, + 0x00030198, + 0x00030198, + 0x00030198, + 0x00030198, + 0x00030198, + 0x00030198, + 0x00030198, + 0x00030198, + }, + { + 0x00030199, + 0x00030199, + 0x00030199, + 0x00030199, + 0x00030199, + 0x00030199, + 0x00030199, + 0x00030199, + 0x0003019a, + 0x0003019a, + 0x0003019a, + 0x0003019a, + 0x0003019a, + 0x0003019a, + 0x0003019a, + 0x0003019a, + }, + { + 0x000200cc, + 0x000200cc, + 0x000200cc, + 0x000200cc, + 0x00020100, + 0x00020100, + 0x00020100, + 0x00020100, + 0x00020119, + 0x00020119, + 0x00020119, + 0x00020119, + 0x0002014f, + 0x0002014f, + 0x0002014f, + 0x0002014f, + }, + { + 0x000102d5, + 0x000102d5, + 0x000102d6, + 0x000102d6, + 0x000102d7, + 0x000102d7, + 0x000102d8, + 0x000102d8, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020010, + 0x000200cb, + 0x000200cb, + 0x000200cb, + 0x000200cb, + }, + { + 0x00020168, + 0x00020168, + 0x00020168, + 0x00020168, + 0x00020195, + 0x00020195, + 0x00020195, + 0x00020195, + 0x0002019b, + 0x0002019b, + 0x0002019b, + 0x0002019b, + 0x0002019e, + 0x0002019e, + 0x0002019e, + 0x0002019e, + }, + { + 0x000201b1, + 0x000201b1, + 0x000201b1, + 0x000201b1, + 0x000201b2, + 0x000201b2, + 0x000201b2, + 0x000201b2, + 0x000201b3, + 0x000201b3, + 0x000201b3, + 0x000201b3, + 0x000201cc, + 0x000201cc, + 0x000201cc, + 0x000201cc, + }, + { + 0x0051ffff, + 0x0052ffff, + 0x0053ffff, + 0x0054ffff, + 0x0055ffff, + 0x0056ffff, + 0x0057ffff, + 0x0058ffff, + 0x0059ffff, + 0x005affff, + 0x005bffff, + 0x005cffff, + 0x003bffff, + 0x003affff, + 0x003cffff, + 0x003dffff, + }, + { + 0x00010062, + 0x00010062, + 0x000100e7, + 0x000100e7, + 0x00010101, + 0x00010101, + 0x0001011b, + 0x0001011b, + 0x00010135, + 0x00010135, + 0x00010150, + 0x00010150, + 0x0001019c, + 0x0001019c, + 0x0001019d, + 0x0001019d, + }, + { + 0x000002ae, + 0x000002af, + 0x000002b0, + 0x000002b1, + 0x000002b2, + 0x000002b3, + 0x000002b4, + 0x000002b5, + 0x0001002b, + 0x0001002b, + 0x00010046, + 0x00010046, + 0x00010047, + 0x00010047, + 0x00010061, + 0x00010061, + }, + { + 0x000101b0, + 0x000101b0, + 0x000102b6, + 0x000102b6, + 0x000102b7, + 0x000102b7, + 0x000102b8, + 0x000102b8, + 0x000102b9, + 0x000102b9, + 0x000102ba, + 0x000102ba, + 0x000102bb, + 0x000102bb, + 0x000102bc, + 0x000102bc, + }, + { + 0x000102bd, + 0x000102bd, + 0x000102be, + 0x000102be, + 0x000102bf, + 0x000102bf, + 0x000102c0, + 0x000102c0, + 0x000102c1, + 0x000102c1, + 0x000102c2, + 0x000102c2, + 0x000102c3, + 0x000102c3, + 0x000102c4, + 0x000102c4, + }, + { + 0x000102c5, + 0x000102c5, + 0x000102c6, + 0x000102c6, + 0x000102c7, + 0x000102c7, + 0x000102c8, + 0x000102c8, + 0x000102c9, + 0x000102c9, + 0x000102ca, + 0x000102ca, + 0x000102cb, + 0x000102cb, + 0x000102cc, + 0x000102cc, + }, + { + 0x000102cd, + 0x000102cd, + 0x000102ce, + 0x000102ce, + 0x000102cf, + 0x000102cf, + 0x000102d0, + 0x000102d0, + 0x000102d1, + 0x000102d1, + 0x000102d2, + 0x000102d2, + 0x000102d3, + 0x000102d3, + 0x000102d4, + 0x000102d4, + }, + { + 0x0044ffff, + 0x0041ffff, + 0x0042ffff, + 0x0043ffff, + 0x0045ffff, + 0x0048ffff, + 0x0046ffff, + 0x0047ffff, + 0x0049ffff, + 0x004affff, + 0x004bffff, + 0x004cffff, + 0x004dffff, + 0x004effff, + 0x004fffff, + 0x0050ffff, + }, + { + 0x00000032, + 0x00000033, + 0x00000034, + 0x00000035, + 0x00000048, + 0x00000049, + 0x0000004a, + 0x0000004b, + 0x0000004c, + 0x0000004d, + 0x0000004e, + 0x0000004f, + 0x00000050, + 0x00000063, + 0x00000064, + 0x00000065, + }, + { + 0x00000066, + 0x00000067, + 0x00000068, + 0x00000069, + 0x0000006a, + 0x0000006b, + 0x0000007c, + 0x0000007d, + 0x0000007e, + 0x0000007f, + 0x00000080, + 0x00000081, + 0x00000082, + 0x00000083, + 0x00000084, + 0x00000085, + }, + { + 0x00000086, + 0x00000097, + 0x00000098, + 0x00000099, + 0x0000009a, + 0x0000009b, + 0x0000009c, + 0x0000009d, + 0x0000009e, + 0x0000009f, + 0x000000a0, + 0x000000a1, + 0x000000b2, + 0x000000b3, + 0x000000b4, + 0x000000b5, + }, + { + 0x00000011, + 0x00000012, + 0x00000013, + 0x00000014, + 0x00000015, + 0x00000016, + 0x00000017, + 0x00000018, + 0x00000019, + 0x0000001a, + 0x0000002c, + 0x0000002d, + 0x0000002e, + 0x0000002f, + 0x00000030, + 0x00000031, + }, + { + 0x000000b6, + 0x000000b7, + 0x000000b8, + 0x000000b9, + 0x000000ba, + 0x000000bb, + 0x000000bc, + 0x000000cd, + 0x000000ce, + 0x000000cf, + 0x000000d0, + 0x000000d1, + 0x000000d2, + 0x000000d3, + 0x000000d4, + 0x000000d5, + }, + { + 0x00000104, + 0x00000105, + 0x00000106, + 0x00000107, + 0x00000108, + 0x00000109, + 0x0000010a, + 0x0000010b, + 0x0000010c, + 0x0000010d, + 0x0000011c, + 0x0000011d, + 0x0000011e, + 0x0000011f, + 0x00000120, + 0x00000121, + }, + { + 0x00000122, + 0x00000123, + 0x00000124, + 0x00000125, + 0x00000126, + 0x00000127, + 0x00000128, + 0x00000136, + 0x00000137, + 0x00000138, + 0x00000139, + 0x0000013a, + 0x0000013b, + 0x0000013c, + 0x0000013d, + 0x0000013e, + }, + { + 0x000000d6, + 0x000000d7, + 0x000000e6, + 0x000000e8, + 0x000000e9, + 0x000000ea, + 0x000000eb, + 0x000000ec, + 0x000000ed, + 0x000000ee, + 0x000000ef, + 0x000000f0, + 0x000000f1, + 0x000000f2, + 0x00000102, + 0x00000103, + }, + { + 0x0000013f, + 0x00000140, + 0x00000141, + 0x00000142, + 0x00000143, + 0x00000151, + 0x00000152, + 0x00000153, + 0x00000154, + 0x00000155, + 0x00000156, + 0x00000157, + 0x00000158, + 0x00000159, + 0x0000015a, + 0x0000015b, + }, + { + 0x0000015c, + 0x0000015d, + 0x0000015e, + 0x00000169, + 0x0000016a, + 0x0000016b, + 0x0000016c, + 0x0000016d, + 0x0000016e, + 0x0000016f, + 0x00000170, + 0x00000171, + 0x00000172, + 0x00000173, + 0x00000174, + 0x00000175, + }, + { + 0x00000176, + 0x00000177, + 0x00000178, + 0x00000179, + 0x00000183, + 0x00000184, + 0x00000185, + 0x00000186, + 0x00000187, + 0x00000188, + 0x00000189, + 0x0000018a, + 0x0000018b, + 0x0000018c, + 0x0000018d, + 0x0000018e, + }, + { + 0x0000018f, + 0x00000190, + 0x00000191, + 0x00000192, + 0x00000193, + 0x00000194, + 0x0000019f, + 0x000001a0, + 0x000001a1, + 0x000001a2, + 0x000001a3, + 0x000001a4, + 0x000001a5, + 0x000001a6, + 0x000001a7, + 0x000001a8, + }, + { + 0x000001a9, + 0x000001aa, + 0x000001ab, + 0x000001ac, + 0x000001ad, + 0x000001ae, + 0x000001af, + 0x000001b4, + 0x000001b5, + 0x000001b6, + 0x000001b7, + 0x000001b8, + 0x000001b9, + 0x000001ba, + 0x000001bb, + 0x000001bc, + }, + { + 0x000001bd, + 0x000001be, + 0x000001bf, + 0x000001c0, + 0x000001c1, + 0x000001c2, + 0x000001c3, + 0x000001c4, + 0x000001c5, + 0x000001c6, + 0x000001c7, + 0x000001c8, + 0x000001c9, + 0x000001ca, + 0x000001cb, + 0x000001cd, + }, + { + 0x000001ce, + 0x000001cf, + 0x000001d0, + 0x000001d1, + 0x000001d2, + 0x000001d3, + 0x000001d4, + 0x000001d5, + 0x000001d6, + 0x000001d7, + 0x000001d8, + 0x000001d9, + 0x000001da, + 0x000001db, + 0x000001dc, + 0x000001dd, + }, + { + 0x000001de, + 0x000001df, + 0x000001e0, + 0x000001e1, + 0x000001e2, + 0x000001e3, + 0x000001e4, + 0x000001e5, + 0x000001e6, + 0x000001e7, + 0x000001e8, + 0x000001e9, + 0x000001ea, + 0x000001eb, + 0x000001ec, + 0x000001ed, + }, + { + 0x000001ee, + 0x000001ef, + 0x000001f0, + 0x000001f1, + 0x000001f2, + 0x000001f3, + 0x000001f4, + 0x000001f5, + 0x000001f6, + 0x000001f7, + 0x000001f8, + 0x000001f9, + 0x000001fa, + 0x000001fb, + 0x000001fc, + 0x000001fd, + }, + { + 0x000001fe, + 0x000001ff, + 0x00000200, + 0x00000201, + 0x00000202, + 0x00000203, + 0x00000204, + 0x00000205, + 0x00000206, + 0x00000207, + 0x00000208, + 0x00000209, + 0x0000020a, + 0x0000020b, + 0x0000020c, + 0x0000020d, + }, + { + 0x0000020e, + 0x0000020f, + 0x00000210, + 0x00000211, + 0x00000212, + 0x00000213, + 0x00000214, + 0x00000215, + 0x00000216, + 0x00000217, + 0x00000218, + 0x00000219, + 0x0000021a, + 0x0000021b, + 0x0000021c, + 0x0000021d, + }, + { + 0x0000021e, + 0x0000021f, + 0x00000220, + 0x00000221, + 0x00000222, + 0x00000223, + 0x00000224, + 0x00000225, + 0x00000226, + 0x00000227, + 0x00000228, + 0x00000229, + 0x0000022a, + 0x0000022b, + 0x0000022c, + 0x0000022d, + }, + { + 0x0000022e, + 0x0000022f, + 0x00000230, + 0x00000231, + 0x00000232, + 0x00000233, + 0x00000234, + 0x00000235, + 0x00000236, + 0x00000237, + 0x00000238, + 0x00000239, + 0x0000023a, + 0x0000023b, + 0x0000023c, + 0x0000023d, + }, + { + 0x0000023e, + 0x0000023f, + 0x00000240, + 0x00000241, + 0x00000242, + 0x00000243, + 0x00000244, + 0x00000245, + 0x00000246, + 0x00000247, + 0x00000248, + 0x00000249, + 0x0000024a, + 0x0000024b, + 0x0000024c, + 0x0000024d, + }, + { + 0x0000024e, + 0x0000024f, + 0x00000250, + 0x00000251, + 0x00000252, + 0x00000253, + 0x00000254, + 0x00000255, + 0x00000256, + 0x00000257, + 0x00000258, + 0x00000259, + 0x0000025a, + 0x0000025b, + 0x0000025c, + 0x0000025d, + }, + { + 0x0000025e, + 0x0000025f, + 0x00000260, + 0x00000261, + 0x00000262, + 0x00000263, + 0x00000264, + 0x00000265, + 0x00000266, + 0x00000267, + 0x00000268, + 0x00000269, + 0x0000026a, + 0x0000026b, + 0x0000026c, + 0x0000026d, + }, + { + 0x0000026e, + 0x0000026f, + 0x00000270, + 0x00000271, + 0x00000272, + 0x00000273, + 0x00000274, + 0x00000275, + 0x00000276, + 0x00000277, + 0x00000278, + 0x00000279, + 0x0000027a, + 0x0000027b, + 0x0000027c, + 0x0000027d, + }, + { + 0x0000027e, + 0x0000027f, + 0x00000280, + 0x00000281, + 0x00000282, + 0x00000283, + 0x00000284, + 0x00000285, + 0x00000286, + 0x00000287, + 0x00000288, + 0x00000289, + 0x0000028a, + 0x0000028b, + 0x0000028c, + 0x0000028d, + }, + { + 0x0000028e, + 0x0000028f, + 0x00000290, + 0x00000291, + 0x00000292, + 0x00000293, + 0x00000294, + 0x00000295, + 0x00000296, + 0x00000297, + 0x00000298, + 0x00000299, + 0x0000029a, + 0x0000029b, + 0x0000029c, + 0x0000029d, + }, + { + 0x0000029e, + 0x0000029f, + 0x000002a0, + 0x000002a1, + 0x000002a2, + 0x000002a3, + 0x000002a4, + 0x000002a5, + 0x000002a6, + 0x000002a7, + 0x000002a8, + 0x000002a9, + 0x000002aa, + 0x000002ab, + 0x000002ac, + 0x000002ad, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc18[28][2] = +#else +const uint16_t c_aauiCQMFHuffEnc18[28][2] = +#endif + { + { 0x0004, 0x0001 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0002 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec18[6][16] = { + { + 0x0001ffff, + 0x00000000, + 0x00000007, + 0x00000008, + 0x00010001, + 0x00010001, + 0x00010002, + 0x00010002, + 0x00010003, + 0x00010003, + 0x00010004, + 0x00010004, + 0x00010005, + 0x00010005, + 0x00010006, + 0x00010006, + }, + { + 0x0002ffff, + 0x0000000c, + 0x0001000b, + 0x0001000b, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + }, + { + 0x0003ffff, + 0x00000010, + 0x0001000f, + 0x0001000f, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + }, + { + 0x0005ffff, + 0x0004ffff, + 0x00010013, + 0x00010013, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + }, + { + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + }, + { + 0x00010018, + 0x00010018, + 0x00010019, + 0x00010019, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020017, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc19[29][2] = +#else +const uint16_t c_aauiCQMFHuffEnc19[29][2] = +#endif + { + { 0x0004, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0001 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0010, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0012, 0x0003 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec19[6][16] = { + { + 0x0001ffff, + 0x0002ffff, + 0x00000000, + 0x00000006, + 0x00000007, + 0x00000008, + 0x00010001, + 0x00010001, + 0x00010002, + 0x00010002, + 0x00010003, + 0x00010003, + 0x00010004, + 0x00010004, + 0x00010005, + 0x00010005, + }, + { + 0x0003ffff, + 0x0000000e, + 0x0001000d, + 0x0001000d, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + }, + { + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + }, + { + 0x0004ffff, + 0x00000012, + 0x00010011, + 0x00010011, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020010, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + }, + { + 0x0005ffff, + 0x00000016, + 0x00010015, + 0x00010015, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + }, + { + 0x00010018, + 0x00010018, + 0x00010019, + 0x00010019, + 0x0001001a, + 0x0001001a, + 0x0001001b, + 0x0001001b, + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020017, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001c, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc20[32][2] = +#else +const uint16_t c_aauiCQMFHuffEnc20[32][2] = +#endif + { + { 0x0004, 0x0002 }, + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0006, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0010, 0x0001 }, + { 0x0011, 0x0001 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec20[6][16] = { + { + 0x0002ffff, + 0x0001ffff, + 0x00000000, + 0x00000004, + 0x00000005, + 0x00000006, + 0x00000007, + 0x00000008, + 0x00000009, + 0x0000000a, + 0x00010001, + 0x00010001, + 0x00010002, + 0x00010002, + 0x00010003, + 0x00010003, + }, + { + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + }, + { + 0x0003ffff, + 0x00000011, + 0x00010010, + 0x00010010, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x0002000f, + }, + { + 0x0004ffff, + 0x00000015, + 0x00010014, + 0x00010014, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + }, + { + 0x0005ffff, + 0x00000019, + 0x00010018, + 0x00010018, + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020017, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + }, + { + 0x0000001b, + 0x0000001c, + 0x0001001d, + 0x0001001d, + 0x0001001e, + 0x0001001e, + 0x0001001f, + 0x0001001f, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc21[37][2] = +#else +const uint16_t c_aauiCQMFHuffEnc21[37][2] = +#endif + { + { 0x0005, 0x0002 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0009, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0010, 0x0001 }, + { 0x0011, 0x0001 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec21[7][16] = { + { + 0x0003ffff, + 0x0001ffff, + 0x0002ffff, + 0x00000003, + 0x00000004, + 0x00000005, + 0x00000006, + 0x00000007, + 0x00000008, + 0x00000009, + 0x0000000a, + 0x0000000b, + 0x00010001, + 0x00010001, + 0x00010002, + 0x00010002, + }, + { + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + }, + { + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + }, + { + 0x0004ffff, + 0x00000013, + 0x00000014, + 0x00000015, + 0x00010011, + 0x00010011, + 0x00010012, + 0x00010012, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020010, + }, + { + 0x0005ffff, + 0x0000001a, + 0x00010017, + 0x00010017, + 0x00010018, + 0x00010018, + 0x00010019, + 0x00010019, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + }, + { + 0x0006ffff, + 0x0000001e, + 0x0001001d, + 0x0001001d, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + }, + { + 0x00000020, + 0x00000021, + 0x00010022, + 0x00010022, + 0x00010023, + 0x00010023, + 0x00010024, + 0x00010024, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc22[39][2] = +#else +const uint16_t c_aauiCQMFHuffEnc22[39][2] = +#endif + { + { 0x0005, 0x0002 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000a, 0x0001 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000c, 0x0001 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000e, 0x0001 }, + { 0x000e, 0x0002 }, + { 0x000f, 0x0001 }, + { 0x000e, 0x0003 }, + { 0x0011, 0x0000 }, + { 0x0010, 0x0001 }, + { 0x0011, 0x0001 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec22[9][16] = { + { + 0x0004ffff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x00000001, + 0x00000002, + 0x00000003, + 0x00000004, + 0x00000005, + 0x00000006, + 0x00000007, + 0x00000008, + 0x00000009, + 0x0000000a, + 0x0000000b, + 0x0000000c, + }, + { + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + }, + { + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + }, + { + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + }, + { + 0x0006ffff, + 0x0005ffff, + 0x00000016, + 0x00000017, + 0x00010014, + 0x00010014, + 0x00010015, + 0x00010015, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020013, + }, + { + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + }, + { + 0x0007ffff, + 0x0000001d, + 0x0000001e, + 0x0000001f, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001c, + }, + { + 0x0008ffff, + 0x00000025, + 0x00010022, + 0x00010022, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020023, + }, + { + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc23[46][2] = +#else +const uint16_t c_aauiCQMFHuffEnc23[46][2] = +#endif + { + { 0x0005, 0x0003 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0001 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0001 }, + { 0x0010, 0x0001 }, + { 0x0012, 0x0000 }, + { 0x0012, 0x0001 }, + { 0x0011, 0x0001 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec23[12][16] = { + { + 0x0006ffff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x0004ffff, + 0x0005ffff, + 0x00000001, + 0x00000002, + 0x00000003, + 0x00000004, + 0x00000005, + 0x00000006, + 0x00000007, + 0x00000008, + 0x00000009, + 0x0000000a, + }, + { + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + }, + { + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + }, + { + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + }, + { + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + }, + { + 0x0008ffff, + 0x0007ffff, + 0x0000001a, + 0x0000001b, + 0x00010016, + 0x00010016, + 0x00010017, + 0x00010017, + 0x00010018, + 0x00010018, + 0x00010019, + 0x00010019, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020013, + }, + { + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + }, + { + 0x000affff, + 0x0009ffff, + 0x00000022, + 0x00000023, + 0x00010020, + 0x00010020, + 0x00010021, + 0x00010021, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + }, + { + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + }, + { + 0x000bffff, + 0x0000002a, + 0x00010029, + 0x00010029, + 0x00020026, + 0x00020026, + 0x00020026, + 0x00020026, + 0x00020027, + 0x00020027, + 0x00020027, + 0x00020027, + 0x00020028, + 0x00020028, + 0x00020028, + 0x00020028, + }, + { + 0x0002002b, + 0x0002002b, + 0x0002002b, + 0x0002002b, + 0x0002002c, + 0x0002002c, + 0x0002002c, + 0x0002002c, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc24[55][2] = +#else +const uint16_t c_aauiCQMFHuffEnc24[55][2] = +#endif + { + { 0x0005, 0x0004 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0001 }, + { 0x000f, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0010, 0x0001 }, + { 0x0011, 0x0001 }, + { 0x0013, 0x0000 }, + { 0x0012, 0x0001 }, + { 0x0013, 0x0001 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec24[17][16] = { + { + 0x0008ffff, + 0x0009ffff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x0004ffff, + 0x0005ffff, + 0x0006ffff, + 0x0007ffff, + 0x00000001, + 0x00000002, + 0x00000003, + 0x00000004, + 0x00000005, + 0x00000006, + 0x00000007, + }, + { + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + }, + { + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + }, + { + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + }, + { + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + }, + { + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + }, + { + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + }, + { + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + }, + { + 0x000cffff, + 0x000affff, + 0x000bffff, + 0x0000001d, + 0x0000001e, + 0x0000001f, + 0x0001001a, + 0x0001001a, + 0x0001001b, + 0x0001001b, + 0x0001001c, + 0x0001001c, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020015, + }, + { + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020019, + 0x00020019, + 0x00020019, + 0x00020019, + }, + { + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + }, + { + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + }, + { + 0x000fffff, + 0x000dffff, + 0x000effff, + 0x00000028, + 0x00010026, + 0x00010026, + 0x00010027, + 0x00010027, + 0x00020024, + 0x00020024, + 0x00020024, + 0x00020024, + 0x00020025, + 0x00020025, + 0x00020025, + 0x00020025, + }, + { + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + }, + { + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + }, + { + 0x0010ffff, + 0x00000032, + 0x0001002f, + 0x0001002f, + 0x00010030, + 0x00010030, + 0x00010031, + 0x00010031, + 0x0002002d, + 0x0002002d, + 0x0002002d, + 0x0002002d, + 0x0002002e, + 0x0002002e, + 0x0002002e, + 0x0002002e, + }, + { + 0x00010034, + 0x00010034, + 0x00010036, + 0x00010036, + 0x00020035, + 0x00020035, + 0x00020035, + 0x00020035, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc25[65][2] = +#else +const uint16_t c_aauiCQMFHuffEnc25[65][2] = +#endif + { + { 0x0005, 0x0005 }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0005, 0x0006 }, + { 0x0004, 0x000f }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000f, 0x0003 }, + { 0x000e, 0x0005 }, + { 0x000f, 0x0004 }, + { 0x0010, 0x0001 }, + { 0x000f, 0x0005 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0011, 0x0001 }, + { 0x0012, 0x0000 }, + { 0x0012, 0x0001 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec25[19][16] = { + { + 0x000cffff, + 0x000bffff, + 0x0002ffff, + 0x0001ffff, + 0x0003ffff, + 0x0004ffff, + 0x0005ffff, + 0x0006ffff, + 0x0007ffff, + 0x0008ffff, + 0x0009ffff, + 0x000affff, + 0x00000001, + 0x00000002, + 0x00000003, + 0x00000005, + }, + { + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + }, + { + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + }, + { + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + }, + { + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + }, + { + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + }, + { + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + }, + { + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + }, + { + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + }, + { + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + }, + { + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020019, + 0x00020019, + 0x00020019, + 0x00020019, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001a, + }, + { + 0x000fffff, + 0x000dffff, + 0x000effff, + 0x00000022, + 0x00000023, + 0x00000024, + 0x0001001d, + 0x0001001d, + 0x0001001e, + 0x0001001e, + 0x0001001f, + 0x0001001f, + 0x00010020, + 0x00010020, + 0x00010021, + 0x00010021, + }, + { + 0x00020029, + 0x00020029, + 0x00020029, + 0x00020029, + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + }, + { + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + }, + { + 0x0011ffff, + 0x0010ffff, + 0x0000002e, + 0x0000002f, + 0x00000030, + 0x00000031, + 0x0001002b, + 0x0001002b, + 0x0001002c, + 0x0001002c, + 0x0001002d, + 0x0001002d, + 0x00020028, + 0x00020028, + 0x00020028, + 0x00020028, + }, + { + 0x00020034, + 0x00020034, + 0x00020034, + 0x00020034, + 0x00020036, + 0x00020036, + 0x00020036, + 0x00020036, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + }, + { + 0x0012ffff, + 0x00000038, + 0x0000003a, + 0x0000003b, + 0x0000003c, + 0x0000003d, + 0x00010035, + 0x00010035, + 0x00010037, + 0x00010037, + 0x00010039, + 0x00010039, + 0x00020033, + 0x00020033, + 0x00020033, + 0x00020033, + }, + { + 0x0002003f, + 0x0002003f, + 0x0002003f, + 0x0002003f, + 0x00020040, + 0x00020040, + 0x00020040, + 0x00020040, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc26[77][2] = +#else +const uint16_t c_aauiCQMFHuffEnc26[77][2] = +#endif + { + { 0x0006, 0x0004 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0005, 0x0018 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0005, 0x001e }, + { 0x0005, 0x001f }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000e, 0x0002 }, + { 0x000d, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000f, 0x0003 }, + { 0x000e, 0x0005 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0011, 0x0002 }, + { 0x0012, 0x0001 }, + { 0x0010, 0x0005 }, + { 0x0012, 0x0002 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0003 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec26[26][16] = { + { + 0x0010ffff, + 0x000effff, + 0x000fffff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x0004ffff, + 0x0005ffff, + 0x0006ffff, + 0x0007ffff, + 0x0008ffff, + 0x0009ffff, + 0x000affff, + 0x000bffff, + 0x000cffff, + 0x000dffff, + }, + { + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + }, + { + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + }, + { + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + }, + { + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + }, + { + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + }, + { + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + }, + { + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + }, + { + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + }, + { + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + }, + { + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + }, + { + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + }, + { + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + }, + { + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + }, + { + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001c, + }, + { + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + }, + { + 0x0014ffff, + 0x0011ffff, + 0x0012ffff, + 0x0013ffff, + 0x00000027, + 0x00000028, + 0x00000029, + 0x0000002a, + 0x00010023, + 0x00010023, + 0x00010024, + 0x00010024, + 0x00010025, + 0x00010025, + 0x00010026, + 0x00010026, + }, + { + 0x00020031, + 0x00020031, + 0x00020031, + 0x00020031, + 0x00020032, + 0x00020032, + 0x00020032, + 0x00020032, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + }, + { + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + }, + { + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + }, + { + 0x0017ffff, + 0x0015ffff, + 0x0016ffff, + 0x00000035, + 0x00000036, + 0x00000037, + 0x00000038, + 0x00000039, + 0x00010033, + 0x00010033, + 0x00010034, + 0x00010034, + 0x00020030, + 0x00020030, + 0x00020030, + 0x00020030, + }, + { + 0x0002003f, + 0x0002003f, + 0x0002003f, + 0x0002003f, + 0x00020041, + 0x00020041, + 0x00020041, + 0x00020041, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + }, + { + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + }, + { + 0x0019ffff, + 0x0018ffff, + 0x00000042, + 0x00000043, + 0x00000044, + 0x00000047, + 0x00010040, + 0x00010040, + 0x0002003c, + 0x0002003c, + 0x0002003c, + 0x0002003c, + 0x0002003e, + 0x0002003e, + 0x0002003e, + 0x0002003e, + }, + { + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + }, + { + 0x0001004b, + 0x0001004b, + 0x0001004c, + 0x0001004c, + 0x00020046, + 0x00020046, + 0x00020046, + 0x00020046, + 0x00020048, + 0x00020048, + 0x00020048, + 0x00020048, + 0x0002004a, + 0x0002004a, + 0x0002004a, + 0x0002004a, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc27[91][2] = +#else +const uint16_t c_aauiCQMFHuffEnc27[91][2] = +#endif + { + { 0x0006, 0x0006 }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0005, 0x0018 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0005, 0x001e }, + { 0x0005, 0x001f }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x000f, 0x0003 }, + { 0x000f, 0x0004 }, + { 0x0010, 0x0003 }, + { 0x000f, 0x0005 }, + { 0x0012, 0x0000 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0011, 0x0004 }, + { 0x0011, 0x0005 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec27[28][16] = { + { + 0x0010ffff, + 0x000cffff, + 0x000dffff, + 0x000effff, + 0x000fffff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x0004ffff, + 0x0005ffff, + 0x0006ffff, + 0x0007ffff, + 0x0008ffff, + 0x0009ffff, + 0x000affff, + 0x000bffff, + }, + { + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020024, + 0x00020024, + 0x00020024, + 0x00020024, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + }, + { + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + }, + { + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + }, + { + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + }, + { + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + }, + { + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + }, + { + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + }, + { + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + }, + { + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + }, + { + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + }, + { + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + }, + { + 0x00010028, + 0x00010028, + 0x00010029, + 0x00010029, + 0x0001002a, + 0x0001002a, + 0x0001002b, + 0x0001002b, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020016, + }, + { + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020019, + 0x00020019, + 0x00020019, + 0x00020019, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001a, + }, + { + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001e, + }, + { + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020022, + }, + { + 0x0014ffff, + 0x0013ffff, + 0x0011ffff, + 0x0012ffff, + 0x0000002c, + 0x0000002d, + 0x0000002e, + 0x0000002f, + 0x00000030, + 0x00000031, + 0x00010025, + 0x00010025, + 0x00010026, + 0x00010026, + 0x00010027, + 0x00010027, + }, + { + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + }, + { + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + }, + { + 0x00020036, + 0x00020036, + 0x00020036, + 0x00020036, + 0x00020037, + 0x00020037, + 0x00020037, + 0x00020037, + 0x00020038, + 0x00020038, + 0x00020038, + 0x00020038, + 0x00020039, + 0x00020039, + 0x00020039, + 0x00020039, + }, + { + 0x0017ffff, + 0x0018ffff, + 0x0015ffff, + 0x0016ffff, + 0x0000003e, + 0x0000003f, + 0x00000040, + 0x00000041, + 0x0001003a, + 0x0001003a, + 0x0001003b, + 0x0001003b, + 0x0001003c, + 0x0001003c, + 0x0001003d, + 0x0001003d, + }, + { + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + }, + { + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + }, + { + 0x001affff, + 0x001bffff, + 0x0019ffff, + 0x0000004d, + 0x00000050, + 0x00000051, + 0x0001004b, + 0x0001004b, + 0x0001004c, + 0x0001004c, + 0x0001004e, + 0x0001004e, + 0x00020046, + 0x00020046, + 0x00020046, + 0x00020046, + }, + { + 0x00020047, + 0x00020047, + 0x00020047, + 0x00020047, + 0x00020048, + 0x00020048, + 0x00020048, + 0x00020048, + 0x00020049, + 0x00020049, + 0x00020049, + 0x00020049, + 0x0002004a, + 0x0002004a, + 0x0002004a, + 0x0002004a, + }, + { + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + }, + { + 0x0002004f, + 0x0002004f, + 0x0002004f, + 0x0002004f, + 0x00020052, + 0x00020052, + 0x00020052, + 0x00020052, + 0x00020053, + 0x00020053, + 0x00020053, + 0x00020053, + 0x00020056, + 0x00020056, + 0x00020056, + 0x00020056, + }, + { + 0x00020057, + 0x00020057, + 0x00020057, + 0x00020057, + 0x00020058, + 0x00020058, + 0x00020058, + 0x00020058, + 0x00020059, + 0x00020059, + 0x00020059, + 0x00020059, + 0x0002005a, + 0x0002005a, + 0x0002005a, + 0x0002005a, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc28[109][2] = +#else +const uint16_t c_aauiCQMFHuffEnc28[109][2] = +#endif + { + { 0x0006, 0x0008 }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0005, 0x0018 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0005, 0x001e }, + { 0x0006, 0x0009 }, + { 0x0005, 0x001f }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0010, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x0010, 0x0006 }, + { 0x0011, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0013, 0x0000 }, + { 0x0010, 0x0008 }, + { 0x0010, 0x0009 }, + { 0x0013, 0x0001 }, + { 0x0011, 0x0007 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec28[30][16] = { + { + 0x000fffff, + 0x0010ffff, + 0x0009ffff, + 0x000affff, + 0x000bffff, + 0x000cffff, + 0x000dffff, + 0x000effff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x0004ffff, + 0x0005ffff, + 0x0006ffff, + 0x0007ffff, + 0x0008ffff, + }, + { + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + }, + { + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + }, + { + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + }, + { + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + }, + { + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + }, + { + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + }, + { + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + }, + { + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + }, + { + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020013, + }, + { + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020017, + }, + { + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020019, + 0x00020019, + 0x00020019, + 0x00020019, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + }, + { + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + }, + { + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020023, + }, + { + 0x00020024, + 0x00020024, + 0x00020024, + 0x00020024, + 0x00020025, + 0x00020025, + 0x00020025, + 0x00020025, + 0x00020026, + 0x00020026, + 0x00020026, + 0x00020026, + 0x00020027, + 0x00020027, + 0x00020027, + 0x00020027, + }, + { + 0x0015ffff, + 0x0014ffff, + 0x0011ffff, + 0x0012ffff, + 0x0013ffff, + 0x00000032, + 0x00000033, + 0x00000034, + 0x00000035, + 0x00000036, + 0x00000037, + 0x00000038, + 0x00010028, + 0x00010028, + 0x00010029, + 0x00010029, + }, + { + 0x0001002a, + 0x0001002a, + 0x0001002b, + 0x0001002b, + 0x0001002c, + 0x0001002c, + 0x0001002d, + 0x0001002d, + 0x0001002e, + 0x0001002e, + 0x0001002f, + 0x0001002f, + 0x00010030, + 0x00010030, + 0x00010031, + 0x00010031, + }, + { + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + }, + { + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + }, + { + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + }, + { + 0x00010045, + 0x00010045, + 0x00010046, + 0x00010046, + 0x0002003f, + 0x0002003f, + 0x0002003f, + 0x0002003f, + 0x00020040, + 0x00020040, + 0x00020040, + 0x00020040, + 0x00020041, + 0x00020041, + 0x00020041, + 0x00020041, + }, + { + 0x0019ffff, + 0x0018ffff, + 0x0016ffff, + 0x0017ffff, + 0x00000047, + 0x00000048, + 0x00000049, + 0x0000004a, + 0x0000004b, + 0x0000004c, + 0x00010042, + 0x00010042, + 0x00010043, + 0x00010043, + 0x00010044, + 0x00010044, + }, + { + 0x0003004d, + 0x0003004d, + 0x0003004d, + 0x0003004d, + 0x0003004d, + 0x0003004d, + 0x0003004d, + 0x0003004d, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + }, + { + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + }, + { + 0x00020051, + 0x00020051, + 0x00020051, + 0x00020051, + 0x00020052, + 0x00020052, + 0x00020052, + 0x00020052, + 0x00020053, + 0x00020053, + 0x00020053, + 0x00020053, + 0x00020054, + 0x00020054, + 0x00020054, + 0x00020054, + }, + { + 0x001bffff, + 0x001cffff, + 0x001dffff, + 0x001affff, + 0x00000055, + 0x00000057, + 0x0000005a, + 0x0000005c, + 0x0000005e, + 0x0000005f, + 0x00010056, + 0x00010056, + 0x00010058, + 0x00010058, + 0x00010059, + 0x00010059, + }, + { + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x00030061, + 0x00030061, + 0x00030061, + 0x00030061, + 0x00030061, + 0x00030061, + 0x00030061, + 0x00030061, + }, + { + 0x0001005d, + 0x0001005d, + 0x00010060, + 0x00010060, + 0x00020062, + 0x00020062, + 0x00020062, + 0x00020062, + 0x00020063, + 0x00020063, + 0x00020063, + 0x00020063, + 0x00020064, + 0x00020064, + 0x00020064, + 0x00020064, + }, + { + 0x00020065, + 0x00020065, + 0x00020065, + 0x00020065, + 0x00020066, + 0x00020066, + 0x00020066, + 0x00020066, + 0x00020067, + 0x00020067, + 0x00020067, + 0x00020067, + 0x00020068, + 0x00020068, + 0x00020068, + 0x00020068, + }, + { + 0x00020069, + 0x00020069, + 0x00020069, + 0x00020069, + 0x0002006a, + 0x0002006a, + 0x0002006a, + 0x0002006a, + 0x0002006b, + 0x0002006b, + 0x0002006b, + 0x0002006b, + 0x0002006c, + 0x0002006c, + 0x0002006c, + 0x0002006c, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc29[129][2] = +#else +const uint16_t c_aauiCQMFHuffEnc29[129][2] = +#endif + { + { 0x0006, 0x0009 }, + { 0x0005, 0x0019 }, + { 0x0006, 0x000a }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0006, 0x000b }, + { 0x0005, 0x001d }, + { 0x0005, 0x001e }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0005, 0x001f }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0006, 0x0020 }, + { 0x0006, 0x0021 }, + { 0x0006, 0x0022 }, + { 0x0006, 0x0023 }, + { 0x0006, 0x0024 }, + { 0x0006, 0x0025 }, + { 0x0006, 0x0026 }, + { 0x0006, 0x0027 }, + { 0x0006, 0x0028 }, + { 0x0006, 0x0029 }, + { 0x0006, 0x002a }, + { 0x0006, 0x002b }, + { 0x0006, 0x002c }, + { 0x0006, 0x002d }, + { 0x0006, 0x002e }, + { 0x0006, 0x002f }, + { 0x0006, 0x0030 }, + { 0x0006, 0x0031 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x000e, 0x0008 }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x0011, 0x0007 }, + { 0x000f, 0x0008 }, + { 0x0012, 0x0000 }, + { 0x000f, 0x0009 }, + { 0x0010, 0x0005 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x0012, 0x0001 }, + { 0x0010, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0011, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0011, 0x0009 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec29[34][16] = { + { + 0x000fffff, + 0x0010ffff, + 0x0005ffff, + 0x0006ffff, + 0x0007ffff, + 0x0008ffff, + 0x0009ffff, + 0x000affff, + 0x000bffff, + 0x000cffff, + 0x000dffff, + 0x000effff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x0004ffff, + }, + { + 0x0002002e, + 0x0002002e, + 0x0002002e, + 0x0002002e, + 0x0002002f, + 0x0002002f, + 0x0002002f, + 0x0002002f, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + 0x00030001, + }, + { + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + }, + { + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + }, + { + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + }, + { + 0x00010039, + 0x00010039, + 0x0001003a, + 0x0001003a, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020006, + 0x00020006, + 0x00020006, + 0x00020006, + }, + { + 0x00020009, + 0x00020009, + 0x00020009, + 0x00020009, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + }, + { + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + }, + { + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020015, + }, + { + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020019, + 0x00020019, + 0x00020019, + 0x00020019, + }, + { + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001d, + }, + { + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020021, + }, + { + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020024, + 0x00020024, + 0x00020024, + 0x00020024, + 0x00020025, + 0x00020025, + 0x00020025, + 0x00020025, + }, + { + 0x00020026, + 0x00020026, + 0x00020026, + 0x00020026, + 0x00020027, + 0x00020027, + 0x00020027, + 0x00020027, + 0x00020028, + 0x00020028, + 0x00020028, + 0x00020028, + 0x00020029, + 0x00020029, + 0x00020029, + 0x00020029, + }, + { + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x0002002b, + 0x0002002b, + 0x0002002b, + 0x0002002b, + 0x0002002c, + 0x0002002c, + 0x0002002c, + 0x0002002c, + 0x0002002d, + 0x0002002d, + 0x0002002d, + 0x0002002d, + }, + { + 0x0016ffff, + 0x0014ffff, + 0x0015ffff, + 0x0011ffff, + 0x0012ffff, + 0x0013ffff, + 0x0000003b, + 0x0000003c, + 0x0000003d, + 0x0000003e, + 0x0000003f, + 0x00000040, + 0x00000041, + 0x00000042, + 0x00010030, + 0x00010030, + }, + { + 0x00010031, + 0x00010031, + 0x00010032, + 0x00010032, + 0x00010033, + 0x00010033, + 0x00010034, + 0x00010034, + 0x00010035, + 0x00010035, + 0x00010036, + 0x00010036, + 0x00010037, + 0x00010037, + 0x00010038, + 0x00010038, + }, + { + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + }, + { + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + }, + { + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + }, + { + 0x00010052, + 0x00010052, + 0x00010053, + 0x00010053, + 0x00020049, + 0x00020049, + 0x00020049, + 0x00020049, + 0x0002004a, + 0x0002004a, + 0x0002004a, + 0x0002004a, + 0x0002004b, + 0x0002004b, + 0x0002004b, + 0x0002004b, + }, + { + 0x0002004c, + 0x0002004c, + 0x0002004c, + 0x0002004c, + 0x0002004d, + 0x0002004d, + 0x0002004d, + 0x0002004d, + 0x0002004e, + 0x0002004e, + 0x0002004e, + 0x0002004e, + 0x0002004f, + 0x0002004f, + 0x0002004f, + 0x0002004f, + }, + { + 0x001cffff, + 0x001bffff, + 0x0017ffff, + 0x0018ffff, + 0x0019ffff, + 0x001affff, + 0x00000054, + 0x00000055, + 0x00000056, + 0x00000057, + 0x00000058, + 0x00000059, + 0x00010050, + 0x00010050, + 0x00010051, + 0x00010051, + }, + { + 0x00020063, + 0x00020063, + 0x00020063, + 0x00020063, + 0x00020064, + 0x00020064, + 0x00020064, + 0x00020064, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + }, + { + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + }, + { + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005e, + 0x0003005e, + 0x0003005e, + 0x0003005e, + 0x0003005e, + 0x0003005e, + 0x0003005e, + 0x0003005e, + }, + { + 0x0003005f, + 0x0003005f, + 0x0003005f, + 0x0003005f, + 0x0003005f, + 0x0003005f, + 0x0003005f, + 0x0003005f, + 0x00030060, + 0x00030060, + 0x00030060, + 0x00030060, + 0x00030060, + 0x00030060, + 0x00030060, + 0x00030060, + }, + { + 0x0001006a, + 0x0001006a, + 0x0001006c, + 0x0001006c, + 0x0001006e, + 0x0001006e, + 0x0001006f, + 0x0001006f, + 0x00020061, + 0x00020061, + 0x00020061, + 0x00020061, + 0x00020062, + 0x00020062, + 0x00020062, + 0x00020062, + }, + { + 0x001fffff, + 0x0020ffff, + 0x0021ffff, + 0x001dffff, + 0x001effff, + 0x0000006d, + 0x00000071, + 0x00000072, + 0x00010065, + 0x00010065, + 0x00010066, + 0x00010066, + 0x00010067, + 0x00010067, + 0x00010068, + 0x00010068, + }, + { + 0x0002007e, + 0x0002007e, + 0x0002007e, + 0x0002007e, + 0x0002007f, + 0x0002007f, + 0x0002007f, + 0x0002007f, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + }, + { + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x00030080, + 0x00030080, + 0x00030080, + 0x00030080, + 0x00030080, + 0x00030080, + 0x00030080, + 0x00030080, + }, + { + 0x0002006b, + 0x0002006b, + 0x0002006b, + 0x0002006b, + 0x00020070, + 0x00020070, + 0x00020070, + 0x00020070, + 0x00020073, + 0x00020073, + 0x00020073, + 0x00020073, + 0x00020074, + 0x00020074, + 0x00020074, + 0x00020074, + }, + { + 0x00020075, + 0x00020075, + 0x00020075, + 0x00020075, + 0x00020076, + 0x00020076, + 0x00020076, + 0x00020076, + 0x00020077, + 0x00020077, + 0x00020077, + 0x00020077, + 0x00020078, + 0x00020078, + 0x00020078, + 0x00020078, + }, + { + 0x00020079, + 0x00020079, + 0x00020079, + 0x00020079, + 0x0002007b, + 0x0002007b, + 0x0002007b, + 0x0002007b, + 0x0002007c, + 0x0002007c, + 0x0002007c, + 0x0002007c, + 0x0002007d, + 0x0002007d, + 0x0002007d, + 0x0002007d, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc30[153][2] = +#else +const uint16_t c_aauiCQMFHuffEnc30[153][2] = +#endif + { + { 0x0007, 0x0009 }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0006, 0x0020 }, + { 0x0006, 0x0021 }, + { 0x0006, 0x0022 }, + { 0x0006, 0x0023 }, + { 0x0006, 0x0024 }, + { 0x0006, 0x0025 }, + { 0x0006, 0x0026 }, + { 0x0006, 0x0027 }, + { 0x0006, 0x0028 }, + { 0x0006, 0x0029 }, + { 0x0006, 0x002a }, + { 0x0006, 0x002b }, + { 0x0006, 0x002c }, + { 0x0006, 0x002d }, + { 0x0006, 0x002e }, + { 0x0006, 0x002f }, + { 0x0006, 0x0030 }, + { 0x0006, 0x0031 }, + { 0x0006, 0x0032 }, + { 0x0006, 0x0033 }, + { 0x0006, 0x0034 }, + { 0x0006, 0x0035 }, + { 0x0006, 0x0036 }, + { 0x0006, 0x0037 }, + { 0x0006, 0x0038 }, + { 0x0006, 0x0039 }, + { 0x0006, 0x003a }, + { 0x0006, 0x003b }, + { 0x0006, 0x003c }, + { 0x0006, 0x003d }, + { 0x0006, 0x003e }, + { 0x0006, 0x003f }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0007, 0x0014 }, + { 0x0007, 0x0015 }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0007, 0x0018 }, + { 0x0007, 0x0019 }, + { 0x0007, 0x001a }, + { 0x0007, 0x001b }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0008, 0x0010 }, + { 0x0008, 0x0011 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x000a, 0x0008 }, + { 0x0009, 0x000f }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000c, 0x0008 }, + { 0x000b, 0x000e }, + { 0x000b, 0x000f }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000d, 0x0008 }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000d, 0x0009 }, + { 0x000c, 0x000d }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000e, 0x0008 }, + { 0x000d, 0x000e }, + { 0x000d, 0x000f }, + { 0x000e, 0x0009 }, + { 0x000e, 0x000a }, + { 0x000e, 0x000b }, + { 0x000e, 0x000c }, + { 0x000f, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x000f, 0x0008 }, + { 0x0010, 0x0006 }, + { 0x000e, 0x000d }, + { 0x000e, 0x000e }, + { 0x000e, 0x000f }, + { 0x0010, 0x0007 }, + { 0x000f, 0x0009 }, + { 0x0010, 0x0008 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000f, 0x000c }, + { 0x000f, 0x000d }, + { 0x0010, 0x0009 }, + { 0x0011, 0x0000 }, + { 0x0011, 0x0001 }, + { 0x0011, 0x0002 }, + { 0x000f, 0x000e }, + { 0x0010, 0x000a }, + { 0x0011, 0x0003 }, + { 0x0011, 0x0004 }, + { 0x0011, 0x0005 }, + { 0x000f, 0x000f }, + { 0x0011, 0x0006 }, + { 0x0011, 0x0007 }, + { 0x0011, 0x0008 }, + { 0x0011, 0x0009 }, + { 0x0011, 0x000a }, + { 0x0011, 0x000b }, + { 0x0010, 0x000b }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec30[39][16] = { + { + 0x0010ffff, + 0x000effff, + 0x000fffff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x0004ffff, + 0x0005ffff, + 0x0006ffff, + 0x0007ffff, + 0x0008ffff, + 0x0009ffff, + 0x000affff, + 0x000bffff, + 0x000cffff, + 0x000dffff, + }, + { + 0x00010041, + 0x00010041, + 0x00010042, + 0x00010042, + 0x00010043, + 0x00010043, + 0x00010044, + 0x00010044, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + }, + { + 0x00020003, + 0x00020003, + 0x00020003, + 0x00020003, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00020005, + 0x00020005, + 0x00020005, + 0x00020005, + 0x00020006, + 0x00020006, + 0x00020006, + 0x00020006, + }, + { + 0x00020007, + 0x00020007, + 0x00020007, + 0x00020007, + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020009, + 0x00020009, + 0x00020009, + 0x00020009, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000a, + }, + { + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + }, + { + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + }, + { + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020016, + }, + { + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020019, + 0x00020019, + 0x00020019, + 0x00020019, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001a, + }, + { + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001e, + }, + { + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020022, + }, + { + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020024, + 0x00020024, + 0x00020024, + 0x00020024, + 0x00020025, + 0x00020025, + 0x00020025, + 0x00020025, + 0x00020026, + 0x00020026, + 0x00020026, + 0x00020026, + }, + { + 0x00020027, + 0x00020027, + 0x00020027, + 0x00020027, + 0x00020028, + 0x00020028, + 0x00020028, + 0x00020028, + 0x00020029, + 0x00020029, + 0x00020029, + 0x00020029, + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x0002002a, + }, + { + 0x0002002b, + 0x0002002b, + 0x0002002b, + 0x0002002b, + 0x0002002c, + 0x0002002c, + 0x0002002c, + 0x0002002c, + 0x0002002d, + 0x0002002d, + 0x0002002d, + 0x0002002d, + 0x0002002e, + 0x0002002e, + 0x0002002e, + 0x0002002e, + }, + { + 0x0002002f, + 0x0002002f, + 0x0002002f, + 0x0002002f, + 0x00020030, + 0x00020030, + 0x00020030, + 0x00020030, + 0x00020031, + 0x00020031, + 0x00020031, + 0x00020031, + 0x00020032, + 0x00020032, + 0x00020032, + 0x00020032, + }, + { + 0x0000004d, + 0x0000004e, + 0x00010000, + 0x00010000, + 0x00010033, + 0x00010033, + 0x00010034, + 0x00010034, + 0x00010035, + 0x00010035, + 0x00010036, + 0x00010036, + 0x00010037, + 0x00010037, + 0x00010038, + 0x00010038, + }, + { + 0x00010039, + 0x00010039, + 0x0001003a, + 0x0001003a, + 0x0001003b, + 0x0001003b, + 0x0001003c, + 0x0001003c, + 0x0001003d, + 0x0001003d, + 0x0001003e, + 0x0001003e, + 0x0001003f, + 0x0001003f, + 0x00010040, + 0x00010040, + }, + { + 0x0017ffff, + 0x0018ffff, + 0x0016ffff, + 0x0011ffff, + 0x0012ffff, + 0x0013ffff, + 0x0014ffff, + 0x0015ffff, + 0x00000045, + 0x00000046, + 0x00000047, + 0x00000048, + 0x00000049, + 0x0000004a, + 0x0000004b, + 0x0000004c, + }, + { + 0x0002005c, + 0x0002005c, + 0x0002005c, + 0x0002005c, + 0x0002005d, + 0x0002005d, + 0x0002005d, + 0x0002005d, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + }, + { + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + }, + { + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + }, + { + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + }, + { + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + }, + { + 0x00020057, + 0x00020057, + 0x00020057, + 0x00020057, + 0x00020059, + 0x00020059, + 0x00020059, + 0x00020059, + 0x0002005a, + 0x0002005a, + 0x0002005a, + 0x0002005a, + 0x0002005b, + 0x0002005b, + 0x0002005b, + 0x0002005b, + }, + { + 0x001fffff, + 0x0020ffff, + 0x001dffff, + 0x001effff, + 0x0019ffff, + 0x001affff, + 0x001bffff, + 0x001cffff, + 0x00000065, + 0x00000068, + 0x00000069, + 0x0000006b, + 0x0000006c, + 0x0000006e, + 0x0001005e, + 0x0001005e, + }, + { + 0x0001005f, + 0x0001005f, + 0x00010060, + 0x00010060, + 0x00010061, + 0x00010061, + 0x00010062, + 0x00010062, + 0x00010063, + 0x00010063, + 0x00010064, + 0x00010064, + 0x00010066, + 0x00010066, + 0x00010067, + 0x00010067, + }, + { + 0x0003006a, + 0x0003006a, + 0x0003006a, + 0x0003006a, + 0x0003006a, + 0x0003006a, + 0x0003006a, + 0x0003006a, + 0x0003006d, + 0x0003006d, + 0x0003006d, + 0x0003006d, + 0x0003006d, + 0x0003006d, + 0x0003006d, + 0x0003006d, + }, + { + 0x0003006f, + 0x0003006f, + 0x0003006f, + 0x0003006f, + 0x0003006f, + 0x0003006f, + 0x0003006f, + 0x0003006f, + 0x00030070, + 0x00030070, + 0x00030070, + 0x00030070, + 0x00030070, + 0x00030070, + 0x00030070, + 0x00030070, + }, + { + 0x00030071, + 0x00030071, + 0x00030071, + 0x00030071, + 0x00030071, + 0x00030071, + 0x00030071, + 0x00030071, + 0x00030072, + 0x00030072, + 0x00030072, + 0x00030072, + 0x00030072, + 0x00030072, + 0x00030072, + 0x00030072, + }, + { + 0x00030074, + 0x00030074, + 0x00030074, + 0x00030074, + 0x00030074, + 0x00030074, + 0x00030074, + 0x00030074, + 0x00030075, + 0x00030075, + 0x00030075, + 0x00030075, + 0x00030075, + 0x00030075, + 0x00030075, + 0x00030075, + }, + { + 0x00020073, + 0x00020073, + 0x00020073, + 0x00020073, + 0x00020076, + 0x00020076, + 0x00020076, + 0x00020076, + 0x00020077, + 0x00020077, + 0x00020077, + 0x00020077, + 0x00020078, + 0x00020078, + 0x00020078, + 0x00020078, + }, + { + 0x00020079, + 0x00020079, + 0x00020079, + 0x00020079, + 0x0002007e, + 0x0002007e, + 0x0002007e, + 0x0002007e, + 0x0002007f, + 0x0002007f, + 0x0002007f, + 0x0002007f, + 0x00020080, + 0x00020080, + 0x00020080, + 0x00020080, + }, + { + 0x0021ffff, + 0x0022ffff, + 0x0023ffff, + 0x0024ffff, + 0x0025ffff, + 0x0026ffff, + 0x0000007d, + 0x00000081, + 0x00000083, + 0x00000088, + 0x0000008d, + 0x00000098, + 0x0001007a, + 0x0001007a, + 0x0001007b, + 0x0001007b, + }, + { + 0x0001007c, + 0x0001007c, + 0x00010082, + 0x00010082, + 0x00010084, + 0x00010084, + 0x00010085, + 0x00010085, + 0x00010086, + 0x00010086, + 0x00010087, + 0x00010087, + 0x0001008c, + 0x0001008c, + 0x00010091, + 0x00010091, + }, + { + 0x00030089, + 0x00030089, + 0x00030089, + 0x00030089, + 0x00030089, + 0x00030089, + 0x00030089, + 0x00030089, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + }, + { + 0x0003008b, + 0x0003008b, + 0x0003008b, + 0x0003008b, + 0x0003008b, + 0x0003008b, + 0x0003008b, + 0x0003008b, + 0x0003008e, + 0x0003008e, + 0x0003008e, + 0x0003008e, + 0x0003008e, + 0x0003008e, + 0x0003008e, + 0x0003008e, + }, + { + 0x0003008f, + 0x0003008f, + 0x0003008f, + 0x0003008f, + 0x0003008f, + 0x0003008f, + 0x0003008f, + 0x0003008f, + 0x00030090, + 0x00030090, + 0x00030090, + 0x00030090, + 0x00030090, + 0x00030090, + 0x00030090, + 0x00030090, + }, + { + 0x00030092, + 0x00030092, + 0x00030092, + 0x00030092, + 0x00030092, + 0x00030092, + 0x00030092, + 0x00030092, + 0x00030093, + 0x00030093, + 0x00030093, + 0x00030093, + 0x00030093, + 0x00030093, + 0x00030093, + 0x00030093, + }, + { + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030095, + 0x00030095, + 0x00030095, + 0x00030095, + 0x00030095, + 0x00030095, + 0x00030095, + 0x00030095, + }, + { + 0x00030096, + 0x00030096, + 0x00030096, + 0x00030096, + 0x00030096, + 0x00030096, + 0x00030096, + 0x00030096, + 0x00030097, + 0x00030097, + 0x00030097, + 0x00030097, + 0x00030097, + 0x00030097, + 0x00030097, + 0x00030097, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc31[181][2] = +#else +const uint16_t c_aauiCQMFHuffEnc31[181][2] = +#endif + { + { 0x0007, 0x000b }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0006, 0x0020 }, + { 0x0006, 0x0021 }, + { 0x0006, 0x0022 }, + { 0x0006, 0x0023 }, + { 0x0006, 0x0024 }, + { 0x0006, 0x0025 }, + { 0x0006, 0x0026 }, + { 0x0006, 0x0027 }, + { 0x0006, 0x0028 }, + { 0x0006, 0x0029 }, + { 0x0006, 0x002a }, + { 0x0006, 0x002b }, + { 0x0006, 0x002c }, + { 0x0006, 0x002d }, + { 0x0006, 0x002e }, + { 0x0006, 0x002f }, + { 0x0006, 0x0030 }, + { 0x0006, 0x0031 }, + { 0x0006, 0x0032 }, + { 0x0006, 0x0033 }, + { 0x0006, 0x0034 }, + { 0x0006, 0x0035 }, + { 0x0006, 0x0036 }, + { 0x0006, 0x0037 }, + { 0x0006, 0x0038 }, + { 0x0006, 0x0039 }, + { 0x0006, 0x003a }, + { 0x0006, 0x003b }, + { 0x0006, 0x003c }, + { 0x0006, 0x003d }, + { 0x0006, 0x003e }, + { 0x0007, 0x000c }, + { 0x0006, 0x003f }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0007, 0x0014 }, + { 0x0007, 0x0015 }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0007, 0x0018 }, + { 0x0007, 0x0019 }, + { 0x0007, 0x001a }, + { 0x0007, 0x001b }, + { 0x0007, 0x001c }, + { 0x0007, 0x001d }, + { 0x0007, 0x001e }, + { 0x0007, 0x001f }, + { 0x0007, 0x0020 }, + { 0x0007, 0x0021 }, + { 0x0007, 0x0022 }, + { 0x0007, 0x0023 }, + { 0x0007, 0x0024 }, + { 0x0007, 0x0025 }, + { 0x0007, 0x0026 }, + { 0x0007, 0x0027 }, + { 0x0007, 0x0028 }, + { 0x0007, 0x0029 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0008, 0x0010 }, + { 0x0008, 0x0011 }, + { 0x0008, 0x0012 }, + { 0x0008, 0x0013 }, + { 0x0008, 0x0014 }, + { 0x0008, 0x0015 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x0009, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000a, 0x000e }, + { 0x000a, 0x000f }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000b, 0x000e }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000b, 0x000f }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000c, 0x000d }, + { 0x000d, 0x0008 }, + { 0x000c, 0x000e }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000c, 0x000f }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000d, 0x000e }, + { 0x000d, 0x000f }, + { 0x000e, 0x0008 }, + { 0x000e, 0x0009 }, + { 0x000e, 0x000a }, + { 0x000e, 0x000b }, + { 0x000e, 0x000c }, + { 0x000e, 0x000d }, + { 0x000e, 0x000e }, + { 0x000e, 0x000f }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000f, 0x000c }, + { 0x0010, 0x0009 }, + { 0x000f, 0x000d }, + { 0x000f, 0x000e }, + { 0x0010, 0x000a }, + { 0x0010, 0x000b }, + { 0x0010, 0x000c }, + { 0x0010, 0x000d }, + { 0x0011, 0x000a }, + { 0x0010, 0x000e }, + { 0x000f, 0x000f }, + { 0x0010, 0x000f }, + { 0x0012, 0x0000 }, + { 0x0012, 0x0001 }, + { 0x0011, 0x000b }, + { 0x0011, 0x000c }, + { 0x0010, 0x0010 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0011, 0x000d }, + { 0x0011, 0x000e }, + { 0x0011, 0x000f }, + { 0x0011, 0x0010 }, + { 0x0011, 0x0011 }, + { 0x0010, 0x0011 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0012, 0x000f }, + { 0x0012, 0x0010 }, + { 0x0012, 0x0011 }, + { 0x0012, 0x0012 }, + { 0x0012, 0x0013 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec31[43][16] = { + { + 0x0010ffff, + 0x000cffff, + 0x000dffff, + 0x000effff, + 0x000fffff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x0004ffff, + 0x0005ffff, + 0x0006ffff, + 0x0007ffff, + 0x0008ffff, + 0x0009ffff, + 0x000affff, + 0x000bffff, + }, + { + 0x00010048, + 0x00010048, + 0x00010049, + 0x00010049, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020003, + 0x00020003, + 0x00020003, + 0x00020003, + }, + { + 0x00020004, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00020005, + 0x00020005, + 0x00020005, + 0x00020005, + 0x00020006, + 0x00020006, + 0x00020006, + 0x00020006, + 0x00020007, + 0x00020007, + 0x00020007, + 0x00020007, + }, + { + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020009, + 0x00020009, + 0x00020009, + 0x00020009, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000b, + }, + { + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x0002000f, + }, + { + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020013, + }, + { + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020017, + }, + { + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020019, + 0x00020019, + 0x00020019, + 0x00020019, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + }, + { + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + }, + { + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020023, + }, + { + 0x00020024, + 0x00020024, + 0x00020024, + 0x00020024, + 0x00020025, + 0x00020025, + 0x00020025, + 0x00020025, + 0x00020026, + 0x00020026, + 0x00020026, + 0x00020026, + 0x00020027, + 0x00020027, + 0x00020027, + 0x00020027, + }, + { + 0x00020028, + 0x00020028, + 0x00020028, + 0x00020028, + 0x00020029, + 0x00020029, + 0x00020029, + 0x00020029, + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x0002002c, + 0x0002002c, + 0x0002002c, + 0x0002002c, + }, + { + 0x00000051, + 0x00000052, + 0x00000053, + 0x00000054, + 0x00000055, + 0x00000056, + 0x00010000, + 0x00010000, + 0x0001002b, + 0x0001002b, + 0x0001002d, + 0x0001002d, + 0x0001002e, + 0x0001002e, + 0x0001002f, + 0x0001002f, + }, + { + 0x00010030, + 0x00010030, + 0x00010031, + 0x00010031, + 0x00010032, + 0x00010032, + 0x00010033, + 0x00010033, + 0x00010034, + 0x00010034, + 0x00010035, + 0x00010035, + 0x00010036, + 0x00010036, + 0x00010037, + 0x00010037, + }, + { + 0x00010038, + 0x00010038, + 0x00010039, + 0x00010039, + 0x0001003a, + 0x0001003a, + 0x0001003b, + 0x0001003b, + 0x0001003c, + 0x0001003c, + 0x0001003d, + 0x0001003d, + 0x0001003e, + 0x0001003e, + 0x0001003f, + 0x0001003f, + }, + { + 0x00010040, + 0x00010040, + 0x00010041, + 0x00010041, + 0x00010042, + 0x00010042, + 0x00010043, + 0x00010043, + 0x00010044, + 0x00010044, + 0x00010045, + 0x00010045, + 0x00010046, + 0x00010046, + 0x00010047, + 0x00010047, + }, + { + 0x0019ffff, + 0x0018ffff, + 0x0016ffff, + 0x0017ffff, + 0x0011ffff, + 0x0012ffff, + 0x0013ffff, + 0x0014ffff, + 0x0015ffff, + 0x0000004a, + 0x0000004b, + 0x0000004c, + 0x0000004d, + 0x0000004e, + 0x0000004f, + 0x00000050, + }, + { + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + }, + { + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + }, + { + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + }, + { + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005d, + 0x0003005e, + 0x0003005e, + 0x0003005e, + 0x0003005e, + 0x0003005e, + 0x0003005e, + 0x0003005e, + 0x0003005e, + }, + { + 0x0003005f, + 0x0003005f, + 0x0003005f, + 0x0003005f, + 0x0003005f, + 0x0003005f, + 0x0003005f, + 0x0003005f, + 0x00030060, + 0x00030060, + 0x00030060, + 0x00030060, + 0x00030060, + 0x00030060, + 0x00030060, + 0x00030060, + }, + { + 0x00020061, + 0x00020061, + 0x00020061, + 0x00020061, + 0x00020062, + 0x00020062, + 0x00020062, + 0x00020062, + 0x00020063, + 0x00020063, + 0x00020063, + 0x00020063, + 0x00020064, + 0x00020064, + 0x00020064, + 0x00020064, + }, + { + 0x00020065, + 0x00020065, + 0x00020065, + 0x00020065, + 0x00020066, + 0x00020066, + 0x00020066, + 0x00020066, + 0x00020067, + 0x00020067, + 0x00020067, + 0x00020067, + 0x00020068, + 0x00020068, + 0x00020068, + 0x00020068, + }, + { + 0x00010069, + 0x00010069, + 0x0001006a, + 0x0001006a, + 0x0001006b, + 0x0001006b, + 0x0001006c, + 0x0001006c, + 0x0001006d, + 0x0001006d, + 0x0001006e, + 0x0001006e, + 0x0001006f, + 0x0001006f, + 0x00010072, + 0x00010072, + }, + { + 0x0021ffff, + 0x0020ffff, + 0x001effff, + 0x001fffff, + 0x001affff, + 0x001bffff, + 0x001cffff, + 0x001dffff, + 0x00000070, + 0x00000071, + 0x00000073, + 0x00000074, + 0x00000075, + 0x00000076, + 0x00000078, + 0x0000007b, + }, + { + 0x00030077, + 0x00030077, + 0x00030077, + 0x00030077, + 0x00030077, + 0x00030077, + 0x00030077, + 0x00030077, + 0x00030079, + 0x00030079, + 0x00030079, + 0x00030079, + 0x00030079, + 0x00030079, + 0x00030079, + 0x00030079, + }, + { + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007c, + 0x0003007c, + 0x0003007c, + 0x0003007c, + 0x0003007c, + 0x0003007c, + 0x0003007c, + 0x0003007c, + }, + { + 0x0003007d, + 0x0003007d, + 0x0003007d, + 0x0003007d, + 0x0003007d, + 0x0003007d, + 0x0003007d, + 0x0003007d, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + }, + { + 0x0003007f, + 0x0003007f, + 0x0003007f, + 0x0003007f, + 0x0003007f, + 0x0003007f, + 0x0003007f, + 0x0003007f, + 0x00030080, + 0x00030080, + 0x00030080, + 0x00030080, + 0x00030080, + 0x00030080, + 0x00030080, + 0x00030080, + }, + { + 0x00020081, + 0x00020081, + 0x00020081, + 0x00020081, + 0x00020082, + 0x00020082, + 0x00020082, + 0x00020082, + 0x00020083, + 0x00020083, + 0x00020083, + 0x00020083, + 0x00020084, + 0x00020084, + 0x00020084, + 0x00020084, + }, + { + 0x00020085, + 0x00020085, + 0x00020085, + 0x00020085, + 0x00020086, + 0x00020086, + 0x00020086, + 0x00020086, + 0x00020087, + 0x00020087, + 0x00020087, + 0x00020087, + 0x00020088, + 0x00020088, + 0x00020088, + 0x00020088, + }, + { + 0x0000009c, + 0x000000a4, + 0x00010089, + 0x00010089, + 0x0001008a, + 0x0001008a, + 0x0001008b, + 0x0001008b, + 0x0001008c, + 0x0001008c, + 0x0001008e, + 0x0001008e, + 0x0001008f, + 0x0001008f, + 0x00010096, + 0x00010096, + }, + { + 0x0026ffff, + 0x0027ffff, + 0x0028ffff, + 0x0029ffff, + 0x002affff, + 0x0022ffff, + 0x0023ffff, + 0x0024ffff, + 0x0025ffff, + 0x0000008d, + 0x00000090, + 0x00000091, + 0x00000092, + 0x00000093, + 0x00000095, + 0x00000097, + }, + { + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + 0x0003009a, + 0x0003009a, + 0x0003009a, + 0x0003009a, + 0x0003009a, + 0x0003009a, + 0x0003009a, + 0x0003009a, + }, + { + 0x0003009b, + 0x0003009b, + 0x0003009b, + 0x0003009b, + 0x0003009b, + 0x0003009b, + 0x0003009b, + 0x0003009b, + 0x0003009f, + 0x0003009f, + 0x0003009f, + 0x0003009f, + 0x0003009f, + 0x0003009f, + 0x0003009f, + 0x0003009f, + }, + { + 0x000300a0, + 0x000300a0, + 0x000300a0, + 0x000300a0, + 0x000300a0, + 0x000300a0, + 0x000300a0, + 0x000300a0, + 0x000300a1, + 0x000300a1, + 0x000300a1, + 0x000300a1, + 0x000300a1, + 0x000300a1, + 0x000300a1, + 0x000300a1, + }, + { + 0x000300a2, + 0x000300a2, + 0x000300a2, + 0x000300a2, + 0x000300a2, + 0x000300a2, + 0x000300a2, + 0x000300a2, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + }, + { + 0x00020098, + 0x00020098, + 0x00020098, + 0x00020098, + 0x00020099, + 0x00020099, + 0x00020099, + 0x00020099, + 0x0002009d, + 0x0002009d, + 0x0002009d, + 0x0002009d, + 0x0002009e, + 0x0002009e, + 0x0002009e, + 0x0002009e, + }, + { + 0x000200a5, + 0x000200a5, + 0x000200a5, + 0x000200a5, + 0x000200a6, + 0x000200a6, + 0x000200a6, + 0x000200a6, + 0x000200a7, + 0x000200a7, + 0x000200a7, + 0x000200a7, + 0x000200a8, + 0x000200a8, + 0x000200a8, + 0x000200a8, + }, + { + 0x000200a9, + 0x000200a9, + 0x000200a9, + 0x000200a9, + 0x000200aa, + 0x000200aa, + 0x000200aa, + 0x000200aa, + 0x000200ab, + 0x000200ab, + 0x000200ab, + 0x000200ab, + 0x000200ac, + 0x000200ac, + 0x000200ac, + 0x000200ac, + }, + { + 0x000200ad, + 0x000200ad, + 0x000200ad, + 0x000200ad, + 0x000200ae, + 0x000200ae, + 0x000200ae, + 0x000200ae, + 0x000200af, + 0x000200af, + 0x000200af, + 0x000200af, + 0x000200b0, + 0x000200b0, + 0x000200b0, + 0x000200b0, + }, + { + 0x000200b1, + 0x000200b1, + 0x000200b1, + 0x000200b1, + 0x000200b2, + 0x000200b2, + 0x000200b2, + 0x000200b2, + 0x000200b3, + 0x000200b3, + 0x000200b3, + 0x000200b3, + 0x000200b4, + 0x000200b4, + 0x000200b4, + 0x000200b4, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc33[16][2] = +#else +const uint16_t c_aauiCQMFHuffEnc33[16][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0008, 0x0000 }, + { 0x0008, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec33[2][16] = { + { + 0x0001ffff, + 0x00000005, + 0x00010001, + 0x00010001, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x00000002, + 0x00000003, + 0x00000006, + 0x00000007, + 0x00000008, + 0x00000009, + 0x0000000a, + 0x0000000b, + 0x0001000c, + 0x0001000c, + 0x0001000d, + 0x0001000d, + 0x0001000e, + 0x0001000e, + 0x0001000f, + 0x0001000f, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc34[16][2] = +#else +const uint16_t c_aauiCQMFHuffEnc34[16][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0008, 0x0000 }, + { 0x0008, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec34[2][16] = { + { + 0x0001ffff, + 0x00000005, + 0x00010001, + 0x00010001, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x00000002, + 0x00000003, + 0x00000006, + 0x00000007, + 0x00000008, + 0x00000009, + 0x0000000a, + 0x0000000b, + 0x0001000c, + 0x0001000c, + 0x0001000d, + 0x0001000d, + 0x0001000e, + 0x0001000e, + 0x0001000f, + 0x0001000f, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc35[25][2] = +#else +const uint16_t c_aauiCQMFHuffEnc35[25][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0007, 0x0006 }, + { 0x0009, 0x0000 }, + { 0x0009, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0007, 0x0007 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec35[9][16] = { + { + 0x0001ffff, + 0x00000006, + 0x00010001, + 0x00010001, + 0x00020005, + 0x00020005, + 0x00020005, + 0x00020005, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x0007ffff, + 0x0008ffff, + 0x0002ffff, + 0x0003ffff, + 0x0004ffff, + 0x0005ffff, + 0x0006ffff, + 0x00000014, + 0x00000015, + 0x00000016, + 0x00000017, + 0x00000018, + 0x00010002, + 0x00010002, + 0x0001000a, + 0x0001000a, + }, + { + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + }, + { + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + }, + { + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + }, + { + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + }, + { + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + }, + { + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + }, + { + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc36[36][2] = +#else +const uint16_t c_aauiCQMFHuffEnc36[36][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x000b, 0x0000 }, + { 0x000b, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0008, 0x0005 }, + { 0x000b, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0003 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000b, 0x000e }, + { 0x000b, 0x000f }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000a, 0x000e }, + { 0x000a, 0x000f }, + { 0x000a, 0x0010 }, + { 0x000a, 0x0011 }, + { 0x000a, 0x0012 }, + { 0x000a, 0x0013 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec36[7][16] = { + { + 0x0001ffff, + 0x00000007, + 0x00010006, + 0x00010006, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x0006ffff, + 0x0005ffff, + 0x0002ffff, + 0x0003ffff, + 0x0004ffff, + 0x00000008, + 0x0001000d, + 0x0001000d, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000c, + }, + { + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020019, + 0x00020019, + 0x00020019, + 0x00020019, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + }, + { + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + }, + { + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020023, + }, + { + 0x00010010, + 0x00010010, + 0x00010011, + 0x00010011, + 0x00010012, + 0x00010012, + 0x00010013, + 0x00010013, + 0x00010014, + 0x00010014, + 0x00010015, + 0x00010015, + 0x00010016, + 0x00010016, + 0x00010017, + 0x00010017, + }, + { + 0x00010003, + 0x00010003, + 0x00010004, + 0x00010004, + 0x00010005, + 0x00010005, + 0x00010009, + 0x00010009, + 0x0001000a, + 0x0001000a, + 0x0001000b, + 0x0001000b, + 0x0001000e, + 0x0001000e, + 0x0001000f, + 0x0001000f, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc37[36][2] = +#else +const uint16_t c_aauiCQMFHuffEnc37[36][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000c, 0x0000 }, + { 0x000c, 0x0001 }, + { 0x000c, 0x0002 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000c, 0x000d }, + { 0x000c, 0x000e }, + { 0x000c, 0x000f }, + { 0x000c, 0x0010 }, + { 0x000c, 0x0011 }, + { 0x000c, 0x0012 }, + { 0x000c, 0x0013 }, + { 0x000c, 0x0014 }, + { 0x000c, 0x0015 }, + { 0x000c, 0x0016 }, + { 0x000c, 0x0017 }, + { 0x000c, 0x0018 }, + { 0x000c, 0x0019 }, + { 0x000b, 0x000d }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec37[4][16] = { + { + 0x0001ffff, + 0x00000007, + 0x00010006, + 0x00010006, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x0003ffff, + 0x0002ffff, + 0x0001000d, + 0x0001000d, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020008, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000c, + }, + { + 0x00000019, + 0x0000001a, + 0x0000001b, + 0x0000001c, + 0x0000001d, + 0x0000001e, + 0x0000001f, + 0x00000020, + 0x00000021, + 0x00000022, + 0x00010023, + 0x00010023, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + }, + { + 0x00000003, + 0x00000004, + 0x00000005, + 0x00000009, + 0x0000000a, + 0x0000000b, + 0x0000000f, + 0x00000010, + 0x00000011, + 0x00000012, + 0x00000013, + 0x00000014, + 0x00000015, + 0x00000016, + 0x00000017, + 0x00000018, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc38[49][2] = +#else +const uint16_t c_aauiCQMFHuffEnc38[49][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000c, 0x0012 }, + { 0x000d, 0x0000 }, + { 0x000d, 0x0001 }, + { 0x000d, 0x0002 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000b, 0x000a }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0009, 0x0003 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000c, 0x0013 }, + { 0x000b, 0x000b }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000d, 0x000e }, + { 0x000d, 0x000f }, + { 0x000d, 0x0010 }, + { 0x000d, 0x0011 }, + { 0x000d, 0x0012 }, + { 0x000d, 0x0013 }, + { 0x000d, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x000d, 0x0016 }, + { 0x000d, 0x0017 }, + { 0x000d, 0x0018 }, + { 0x000d, 0x0019 }, + { 0x000d, 0x001a }, + { 0x000d, 0x001b }, + { 0x000d, 0x001c }, + { 0x000d, 0x001d }, + { 0x000d, 0x001e }, + { 0x000d, 0x001f }, + { 0x000d, 0x0020 }, + { 0x000d, 0x0021 }, + { 0x000d, 0x0022 }, + { 0x000d, 0x0023 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec38[22][16] = { + { + 0x0001ffff, + 0x00000008, + 0x00010001, + 0x00010001, + 0x00020007, + 0x00020007, + 0x00020007, + 0x00020007, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x0003ffff, + 0x0002ffff, + 0x00010009, + 0x00010009, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x0002000f, + }, + { + 0x0014ffff, + 0x0015ffff, + 0x00000003, + 0x00000015, + 0x0001000a, + 0x0001000a, + 0x00010016, + 0x00010016, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + }, + { + 0x0005ffff, + 0x0006ffff, + 0x0004ffff, + 0x0007ffff, + 0x0008ffff, + 0x0009ffff, + 0x000affff, + 0x000bffff, + 0x000cffff, + 0x000dffff, + 0x000effff, + 0x000fffff, + 0x0010ffff, + 0x0011ffff, + 0x0012ffff, + 0x0013ffff, + }, + { + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + }, + { + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + }, + { + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + }, + { + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + }, + { + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + }, + { + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + }, + { + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + }, + { + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + }, + { + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + }, + { + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + }, + { + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + }, + { + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + }, + { + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + }, + { + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + }, + { + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + }, + { + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + }, + { + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + }, + { + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc39[64][2] = +#else +const uint16_t c_aauiCQMFHuffEnc39[64][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000a, 0x0002 }, + { 0x000f, 0x0000 }, + { 0x000f, 0x0001 }, + { 0x000f, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0003 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0009, 0x0003 }, + { 0x000d, 0x000e }, + { 0x000f, 0x0008 }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000d, 0x000f }, + { 0x000f, 0x000c }, + { 0x000f, 0x000d }, + { 0x000f, 0x000e }, + { 0x000f, 0x000f }, + { 0x000f, 0x0010 }, + { 0x000f, 0x0011 }, + { 0x000f, 0x0012 }, + { 0x000f, 0x0013 }, + { 0x000f, 0x0014 }, + { 0x000f, 0x0015 }, + { 0x000f, 0x0016 }, + { 0x000f, 0x0017 }, + { 0x000f, 0x0018 }, + { 0x000f, 0x0019 }, + { 0x000f, 0x001a }, + { 0x000f, 0x001b }, + { 0x000f, 0x001c }, + { 0x000f, 0x001d }, + { 0x000f, 0x001e }, + { 0x000f, 0x001f }, + { 0x000f, 0x0020 }, + { 0x000f, 0x0021 }, + { 0x000f, 0x0022 }, + { 0x000f, 0x0023 }, + { 0x000f, 0x0024 }, + { 0x000f, 0x0025 }, + { 0x000f, 0x0026 }, + { 0x000f, 0x0027 }, + { 0x000f, 0x0028 }, + { 0x000f, 0x0029 }, + { 0x000e, 0x0015 }, + { 0x000e, 0x0016 }, + { 0x000e, 0x0017 }, + { 0x000e, 0x0018 }, + { 0x000e, 0x0019 }, + { 0x000e, 0x001a }, + { 0x000e, 0x001b }, + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec39[12][16] = { + { + 0x0001ffff, + 0x00000009, + 0x00010008, + 0x00010008, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x0003ffff, + 0x0002ffff, + 0x0001000a, + 0x0001000a, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + }, + { + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020019, + 0x00020019, + 0x00020019, + 0x00020019, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + 0x00030012, + }, + { + 0x0008ffff, + 0x0007ffff, + 0x0009ffff, + 0x000affff, + 0x000bffff, + 0x0005ffff, + 0x0006ffff, + 0x0004ffff, + 0x00020003, + 0x00020003, + 0x00020003, + 0x00020003, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000b, + }, + { + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + }, + { + 0x00010037, + 0x00010037, + 0x00010038, + 0x00010038, + 0x00020039, + 0x00020039, + 0x00020039, + 0x00020039, + 0x0002003a, + 0x0002003a, + 0x0002003a, + 0x0002003a, + 0x0002003b, + 0x0002003b, + 0x0002003b, + 0x0002003b, + }, + { + 0x0002003c, + 0x0002003c, + 0x0002003c, + 0x0002003c, + 0x0002003d, + 0x0002003d, + 0x0002003d, + 0x0002003d, + 0x0002003e, + 0x0002003e, + 0x0002003e, + 0x0002003e, + 0x0002003f, + 0x0002003f, + 0x0002003f, + 0x0002003f, + }, + { + 0x00010014, + 0x00010014, + 0x00010015, + 0x00010015, + 0x00010016, + 0x00010016, + 0x00010017, + 0x00010017, + 0x0001001b, + 0x0001001b, + 0x0001001c, + 0x0001001c, + 0x0001001d, + 0x0001001d, + 0x0001001e, + 0x0001001e, + }, + { + 0x00010004, + 0x00010004, + 0x00010005, + 0x00010005, + 0x00010006, + 0x00010006, + 0x00010007, + 0x00010007, + 0x0001000c, + 0x0001000c, + 0x0001000d, + 0x0001000d, + 0x0001000e, + 0x0001000e, + 0x0001000f, + 0x0001000f, + }, + { + 0x0001001f, + 0x0001001f, + 0x00010020, + 0x00010020, + 0x00010021, + 0x00010021, + 0x00010022, + 0x00010022, + 0x00010023, + 0x00010023, + 0x00010024, + 0x00010024, + 0x00010025, + 0x00010025, + 0x00010026, + 0x00010026, + }, + { + 0x00010027, + 0x00010027, + 0x00010028, + 0x00010028, + 0x00010029, + 0x00010029, + 0x0001002a, + 0x0001002a, + 0x0001002b, + 0x0001002b, + 0x0001002c, + 0x0001002c, + 0x0001002d, + 0x0001002d, + 0x0001002e, + 0x0001002e, + }, + { + 0x0001002f, + 0x0001002f, + 0x00010030, + 0x00010030, + 0x00010031, + 0x00010031, + 0x00010032, + 0x00010032, + 0x00010033, + 0x00010033, + 0x00010034, + 0x00010034, + 0x00010035, + 0x00010035, + 0x00010036, + 0x00010036, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc40[81][2] = +#else +const uint16_t c_aauiCQMFHuffEnc40[81][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x000f, 0x0011 }, + { 0x0011, 0x0000 }, + { 0x0011, 0x0001 }, + { 0x0011, 0x0002 }, + { 0x0011, 0x0003 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0002 }, + { 0x000e, 0x0009 }, + { 0x0011, 0x0004 }, + { 0x0011, 0x0005 }, + { 0x0011, 0x0006 }, + { 0x0011, 0x0007 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000d, 0x0005 }, + { 0x0011, 0x0008 }, + { 0x0011, 0x0009 }, + { 0x0011, 0x000a }, + { 0x0011, 0x000b }, + { 0x0011, 0x000c }, + { 0x000b, 0x0003 }, + { 0x000a, 0x0003 }, + { 0x000c, 0x0003 }, + { 0x0011, 0x000d }, + { 0x0011, 0x000e }, + { 0x0011, 0x000f }, + { 0x0011, 0x0010 }, + { 0x0011, 0x0011 }, + { 0x0011, 0x0012 }, + { 0x0011, 0x0013 }, + { 0x0011, 0x0014 }, + { 0x0011, 0x0015 }, + { 0x0011, 0x0016 }, + { 0x0011, 0x0017 }, + { 0x0011, 0x0018 }, + { 0x0011, 0x0019 }, + { 0x0011, 0x001a }, + { 0x0011, 0x001b }, + { 0x0011, 0x001c }, + { 0x0011, 0x001d }, + { 0x0011, 0x001e }, + { 0x0011, 0x001f }, + { 0x0011, 0x0020 }, + { 0x0011, 0x0021 }, + { 0x0011, 0x0022 }, + { 0x0011, 0x0023 }, + { 0x0011, 0x0024 }, + { 0x0011, 0x0025 }, + { 0x0011, 0x0026 }, + { 0x0011, 0x0027 }, + { 0x0011, 0x0028 }, + { 0x0011, 0x0029 }, + { 0x0011, 0x002a }, + { 0x0011, 0x002b }, + { 0x0011, 0x002c }, + { 0x0011, 0x002d }, + { 0x0011, 0x002e }, + { 0x0011, 0x002f }, + { 0x0011, 0x0030 }, + { 0x0011, 0x0031 }, + { 0x0011, 0x0032 }, + { 0x0011, 0x0033 }, + { 0x0011, 0x0034 }, + { 0x0011, 0x0035 }, + { 0x0011, 0x0036 }, + { 0x0011, 0x0037 }, + { 0x0011, 0x0038 }, + { 0x0011, 0x0039 }, + { 0x0011, 0x003a }, + { 0x0011, 0x003b }, + { 0x0010, 0x001e }, + { 0x0010, 0x001f }, + { 0x0010, 0x0020 }, + { 0x0010, 0x0021 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec40[36][16] = { + { + 0x0001ffff, + 0x0000000a, + 0x00010009, + 0x00010009, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x0002ffff, + 0x00000014, + 0x0001000b, + 0x0001000b, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020013, + }, + { + 0x0005ffff, + 0x0004ffff, + 0x0003ffff, + 0x0000001d, + 0x00010003, + 0x00010003, + 0x0001001b, + 0x0001001b, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001c, + }, + { + 0x0000004f, + 0x00000050, + 0x00010004, + 0x00010004, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + }, + { + 0x0015ffff, + 0x0016ffff, + 0x0017ffff, + 0x0018ffff, + 0x0019ffff, + 0x001affff, + 0x001bffff, + 0x001cffff, + 0x001dffff, + 0x001effff, + 0x001fffff, + 0x0020ffff, + 0x0021ffff, + 0x0022ffff, + 0x0000004d, + 0x0000004e, + }, + { + 0x0023ffff, + 0x000affff, + 0x0006ffff, + 0x000bffff, + 0x0007ffff, + 0x0008ffff, + 0x0009ffff, + 0x000cffff, + 0x000dffff, + 0x000effff, + 0x000fffff, + 0x0010ffff, + 0x0011ffff, + 0x0012ffff, + 0x0013ffff, + 0x0014ffff, + }, + { + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + }, + { + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + }, + { + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + }, + { + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + }, + { + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + }, + { + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + }, + { + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + }, + { + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + }, + { + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + }, + { + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + }, + { + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + }, + { + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + }, + { + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + }, + { + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + }, + { + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + }, + { + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + }, + { + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + }, + { + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + }, + { + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + }, + { + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + }, + { + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + }, + { + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + }, + { + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + }, + { + 0x00030041, + 0x00030041, + 0x00030041, + 0x00030041, + 0x00030041, + 0x00030041, + 0x00030041, + 0x00030041, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + }, + { + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + 0x00030044, + }, + { + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + }, + { + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + }, + { + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x0003004a, + 0x0003004a, + 0x0003004a, + 0x0003004a, + 0x0003004a, + 0x0003004a, + 0x0003004a, + 0x0003004a, + }, + { + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + }, + { + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc41[100][2] = +#else +const uint16_t c_aauiCQMFHuffEnc41[100][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0011, 0x0014 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x0010, 0x000b }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000d, 0x0002 }, + { 0x0011, 0x0015 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000d, 0x0003 }, + { 0x0010, 0x000c }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0010, 0x000d }, + { 0x000f, 0x0007 }, + { 0x0012, 0x0027 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec41[16][16] = { + { + 0x0001ffff, + 0x0000000b, + 0x00010001, + 0x00010001, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x0002ffff, + 0x00000016, + 0x0001000c, + 0x0001000c, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020015, + }, + { + 0x0004ffff, + 0x0003ffff, + 0x00010003, + 0x00010003, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + }, + { + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + }, + { + 0x0007ffff, + 0x0008ffff, + 0x0009ffff, + 0x000affff, + 0x000bffff, + 0x000cffff, + 0x000dffff, + 0x000effff, + 0x000fffff, + 0x0006ffff, + 0x0005ffff, + 0x0000000e, + 0x00000021, + 0x00000028, + 0x00010029, + 0x00010029, + }, + { + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + }, + { + 0x0001005e, + 0x0001005e, + 0x0001005f, + 0x0001005f, + 0x00010060, + 0x00010060, + 0x00010061, + 0x00010061, + 0x00010062, + 0x00010062, + 0x00010063, + 0x00010063, + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x0002002a, + }, + { + 0x00010005, + 0x00010005, + 0x00010006, + 0x00010006, + 0x00010007, + 0x00010007, + 0x00010008, + 0x00010008, + 0x00010009, + 0x00010009, + 0x0001000f, + 0x0001000f, + 0x00010010, + 0x00010010, + 0x00010011, + 0x00010011, + }, + { + 0x00010012, + 0x00010012, + 0x00010013, + 0x00010013, + 0x00010019, + 0x00010019, + 0x0001001a, + 0x0001001a, + 0x0001001b, + 0x0001001b, + 0x0001001c, + 0x0001001c, + 0x0001001d, + 0x0001001d, + 0x00010022, + 0x00010022, + }, + { + 0x00010023, + 0x00010023, + 0x00010024, + 0x00010024, + 0x00010025, + 0x00010025, + 0x00010026, + 0x00010026, + 0x00010027, + 0x00010027, + 0x0001002b, + 0x0001002b, + 0x0001002c, + 0x0001002c, + 0x0001002d, + 0x0001002d, + }, + { + 0x0001002e, + 0x0001002e, + 0x0001002f, + 0x0001002f, + 0x00010030, + 0x00010030, + 0x00010031, + 0x00010031, + 0x00010032, + 0x00010032, + 0x00010033, + 0x00010033, + 0x00010034, + 0x00010034, + 0x00010035, + 0x00010035, + }, + { + 0x00010036, + 0x00010036, + 0x00010037, + 0x00010037, + 0x00010038, + 0x00010038, + 0x00010039, + 0x00010039, + 0x0001003a, + 0x0001003a, + 0x0001003b, + 0x0001003b, + 0x0001003c, + 0x0001003c, + 0x0001003d, + 0x0001003d, + }, + { + 0x0001003e, + 0x0001003e, + 0x0001003f, + 0x0001003f, + 0x00010040, + 0x00010040, + 0x00010041, + 0x00010041, + 0x00010042, + 0x00010042, + 0x00010043, + 0x00010043, + 0x00010044, + 0x00010044, + 0x00010045, + 0x00010045, + }, + { + 0x00010046, + 0x00010046, + 0x00010047, + 0x00010047, + 0x00010048, + 0x00010048, + 0x00010049, + 0x00010049, + 0x0001004a, + 0x0001004a, + 0x0001004b, + 0x0001004b, + 0x0001004c, + 0x0001004c, + 0x0001004d, + 0x0001004d, + }, + { + 0x0001004e, + 0x0001004e, + 0x0001004f, + 0x0001004f, + 0x00010050, + 0x00010050, + 0x00010051, + 0x00010051, + 0x00010052, + 0x00010052, + 0x00010053, + 0x00010053, + 0x00010054, + 0x00010054, + 0x00010055, + 0x00010055, + }, + { + 0x00010056, + 0x00010056, + 0x00010057, + 0x00010057, + 0x00010058, + 0x00010058, + 0x00010059, + 0x00010059, + 0x0001005a, + 0x0001005a, + 0x0001005b, + 0x0001005b, + 0x0001005c, + 0x0001005c, + 0x0001005d, + 0x0001005d, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc42[169][2] = +#else +const uint16_t c_aauiCQMFHuffEnc42[169][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000e, 0x0006 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x000d, 0x0004 }, + { 0x0010, 0x0013 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0002 }, + { 0x000f, 0x000b }, + { 0x0011, 0x0025 }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0009, 0x0003 }, + { 0x0008, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000d, 0x0005 }, + { 0x0010, 0x0014 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x0015 }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0012, 0x0045 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0012, 0x0046 }, + { 0x0012, 0x0047 }, + { 0x0012, 0x0048 }, + { 0x0012, 0x0049 }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec42[28][16] = { + { + 0x0001ffff, + 0x0002ffff, + 0x00010001, + 0x00010001, + 0x0001000d, + 0x0001000d, + 0x0001000e, + 0x0001000e, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x0003ffff, + 0x0004ffff, + 0x0000001c, + 0x00000028, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + }, + { + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001a, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + }, + { + 0x000affff, + 0x0007ffff, + 0x0005ffff, + 0x0006ffff, + 0x0001001d, + 0x0001001d, + 0x00010029, + 0x00010029, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + }, + { + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + }, + { + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + }, + { + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + }, + { + 0x001bffff, + 0x0009ffff, + 0x0008ffff, + 0x00000012, + 0x0000002b, + 0x00000037, + 0x0001001e, + 0x0001001e, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00020004, + 0x00020036, + 0x00020036, + 0x00020036, + 0x00020036, + }, + { + 0x000200a7, + 0x000200a7, + 0x000200a7, + 0x000200a7, + 0x000200a8, + 0x000200a8, + 0x000200a8, + 0x000200a8, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + }, + { + 0x000100a3, + 0x000100a3, + 0x000100a4, + 0x000100a4, + 0x00020041, + 0x00020041, + 0x00020041, + 0x00020041, + 0x000200a5, + 0x000200a5, + 0x000200a5, + 0x000200a5, + 0x000200a6, + 0x000200a6, + 0x000200a6, + 0x000200a6, + }, + { + 0x000dffff, + 0x000bffff, + 0x000cffff, + 0x000effff, + 0x000fffff, + 0x0010ffff, + 0x0011ffff, + 0x0012ffff, + 0x0013ffff, + 0x0014ffff, + 0x0015ffff, + 0x0016ffff, + 0x0017ffff, + 0x0018ffff, + 0x0019ffff, + 0x001affff, + }, + { + 0x00010013, + 0x00010013, + 0x00010014, + 0x00010014, + 0x00010015, + 0x00010015, + 0x00010016, + 0x00010016, + 0x00010017, + 0x00010017, + 0x00010018, + 0x00010018, + 0x00010019, + 0x00010019, + 0x00010020, + 0x00010020, + }, + { + 0x00010021, + 0x00010021, + 0x00010022, + 0x00010022, + 0x00010023, + 0x00010023, + 0x00010024, + 0x00010024, + 0x00010025, + 0x00010025, + 0x00010026, + 0x00010026, + 0x0001002c, + 0x0001002c, + 0x0001002d, + 0x0001002d, + }, + { + 0x00010005, + 0x00010005, + 0x00010006, + 0x00010006, + 0x00010007, + 0x00010007, + 0x00010008, + 0x00010008, + 0x00010009, + 0x00010009, + 0x0001000a, + 0x0001000a, + 0x0001000b, + 0x0001000b, + 0x0001000c, + 0x0001000c, + }, + { + 0x0001002e, + 0x0001002e, + 0x0001002f, + 0x0001002f, + 0x00010030, + 0x00010030, + 0x00010031, + 0x00010031, + 0x00010032, + 0x00010032, + 0x00010033, + 0x00010033, + 0x00010038, + 0x00010038, + 0x00010039, + 0x00010039, + }, + { + 0x0001003a, + 0x0001003a, + 0x0001003b, + 0x0001003b, + 0x0001003c, + 0x0001003c, + 0x0001003d, + 0x0001003d, + 0x0001003e, + 0x0001003e, + 0x0001003f, + 0x0001003f, + 0x00010040, + 0x00010040, + 0x00010042, + 0x00010042, + }, + { + 0x00010043, + 0x00010043, + 0x00010044, + 0x00010044, + 0x00010045, + 0x00010045, + 0x00010046, + 0x00010046, + 0x00010047, + 0x00010047, + 0x00010048, + 0x00010048, + 0x00010049, + 0x00010049, + 0x0001004a, + 0x0001004a, + }, + { + 0x0001004b, + 0x0001004b, + 0x0001004c, + 0x0001004c, + 0x0001004d, + 0x0001004d, + 0x0001004e, + 0x0001004e, + 0x0001004f, + 0x0001004f, + 0x00010050, + 0x00010050, + 0x00010051, + 0x00010051, + 0x00010052, + 0x00010052, + }, + { + 0x00010053, + 0x00010053, + 0x00010054, + 0x00010054, + 0x00010055, + 0x00010055, + 0x00010056, + 0x00010056, + 0x00010057, + 0x00010057, + 0x00010058, + 0x00010058, + 0x00010059, + 0x00010059, + 0x0001005a, + 0x0001005a, + }, + { + 0x0001005b, + 0x0001005b, + 0x0001005c, + 0x0001005c, + 0x0001005d, + 0x0001005d, + 0x0001005e, + 0x0001005e, + 0x0001005f, + 0x0001005f, + 0x00010060, + 0x00010060, + 0x00010061, + 0x00010061, + 0x00010062, + 0x00010062, + }, + { + 0x00010063, + 0x00010063, + 0x00010064, + 0x00010064, + 0x00010065, + 0x00010065, + 0x00010066, + 0x00010066, + 0x00010067, + 0x00010067, + 0x00010068, + 0x00010068, + 0x00010069, + 0x00010069, + 0x0001006a, + 0x0001006a, + }, + { + 0x0001006b, + 0x0001006b, + 0x0001006c, + 0x0001006c, + 0x0001006d, + 0x0001006d, + 0x0001006e, + 0x0001006e, + 0x0001006f, + 0x0001006f, + 0x00010070, + 0x00010070, + 0x00010071, + 0x00010071, + 0x00010072, + 0x00010072, + }, + { + 0x00010073, + 0x00010073, + 0x00010074, + 0x00010074, + 0x00010075, + 0x00010075, + 0x00010076, + 0x00010076, + 0x00010077, + 0x00010077, + 0x00010078, + 0x00010078, + 0x00010079, + 0x00010079, + 0x0001007a, + 0x0001007a, + }, + { + 0x0001007b, + 0x0001007b, + 0x0001007c, + 0x0001007c, + 0x0001007d, + 0x0001007d, + 0x0001007e, + 0x0001007e, + 0x0001007f, + 0x0001007f, + 0x00010080, + 0x00010080, + 0x00010081, + 0x00010081, + 0x00010082, + 0x00010082, + }, + { + 0x00010083, + 0x00010083, + 0x00010084, + 0x00010084, + 0x00010085, + 0x00010085, + 0x00010086, + 0x00010086, + 0x00010087, + 0x00010087, + 0x00010088, + 0x00010088, + 0x00010089, + 0x00010089, + 0x0001008a, + 0x0001008a, + }, + { + 0x0001008b, + 0x0001008b, + 0x0001008c, + 0x0001008c, + 0x0001008d, + 0x0001008d, + 0x0001008e, + 0x0001008e, + 0x0001008f, + 0x0001008f, + 0x00010090, + 0x00010090, + 0x00010091, + 0x00010091, + 0x00010092, + 0x00010092, + }, + { + 0x00010093, + 0x00010093, + 0x00010094, + 0x00010094, + 0x00010095, + 0x00010095, + 0x00010096, + 0x00010096, + 0x00010097, + 0x00010097, + 0x00010098, + 0x00010098, + 0x00010099, + 0x00010099, + 0x0001009a, + 0x0001009a, + }, + { + 0x0001009b, + 0x0001009b, + 0x0001009c, + 0x0001009c, + 0x0001009d, + 0x0001009d, + 0x0001009e, + 0x0001009e, + 0x0001009f, + 0x0001009f, + 0x000100a0, + 0x000100a0, + 0x000100a1, + 0x000100a1, + 0x000100a2, + 0x000100a2, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc43[196][2] = +#else +const uint16_t c_aauiCQMFHuffEnc43[196][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x0010, 0x0017 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x0010, 0x0018 }, + { 0x0012, 0x0050 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0008, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000d, 0x0004 }, + { 0x0011, 0x002a }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000c, 0x0005 }, + { 0x000f, 0x000d }, + { 0x0012, 0x0051 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0005 }, + { 0x000f, 0x000e }, + { 0x0011, 0x002b }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0011, 0x002c }, + { 0x000f, 0x000f }, + { 0x0010, 0x0019 }, + { 0x0012, 0x0052 }, + { 0x0012, 0x0053 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0011, 0x002d }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec43[32][16] = { + { + 0x0001ffff, + 0x0002ffff, + 0x00010001, + 0x00010001, + 0x0001000e, + 0x0001000e, + 0x0001000f, + 0x0001000f, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x0005ffff, + 0x0003ffff, + 0x0004ffff, + 0x0000001e, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + }, + { + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + }, + { + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030003, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + 0x00030011, + }, + { + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + }, + { + 0x000bffff, + 0x0007ffff, + 0x0006ffff, + 0x00000004, + 0x00000012, + 0x0000002d, + 0x00000038, + 0x00000039, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002002c, + 0x0002002c, + 0x0002002c, + 0x0002002c, + }, + { + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + }, + { + 0x001cffff, + 0x001dffff, + 0x001effff, + 0x001fffff, + 0x000affff, + 0x0008ffff, + 0x0009ffff, + 0x00000005, + 0x00000013, + 0x00000048, + 0x0001002e, + 0x0001002e, + 0x0001003b, + 0x0001003b, + 0x00010047, + 0x00010047, + }, + { + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + }, + { + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + }, + { + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020014, + 0x0002002f, + 0x0002002f, + 0x0002002f, + 0x0002002f, + 0x00020049, + 0x00020049, + 0x00020049, + 0x00020049, + 0x0002004a, + 0x0002004a, + 0x0002004a, + 0x0002004a, + }, + { + 0x000dffff, + 0x000effff, + 0x000cffff, + 0x000fffff, + 0x0010ffff, + 0x0011ffff, + 0x0012ffff, + 0x0013ffff, + 0x0014ffff, + 0x0015ffff, + 0x0016ffff, + 0x0017ffff, + 0x0018ffff, + 0x0019ffff, + 0x001affff, + 0x001bffff, + }, + { + 0x00010023, + 0x00010023, + 0x00010024, + 0x00010024, + 0x00010025, + 0x00010025, + 0x00010026, + 0x00010026, + 0x00010027, + 0x00010027, + 0x00010028, + 0x00010028, + 0x00010029, + 0x00010029, + 0x00010030, + 0x00010030, + }, + { + 0x00010006, + 0x00010006, + 0x00010007, + 0x00010007, + 0x00010008, + 0x00010008, + 0x00010009, + 0x00010009, + 0x0001000a, + 0x0001000a, + 0x0001000b, + 0x0001000b, + 0x0001000c, + 0x0001000c, + 0x0001000d, + 0x0001000d, + }, + { + 0x00010015, + 0x00010015, + 0x00010016, + 0x00010016, + 0x00010017, + 0x00010017, + 0x00010018, + 0x00010018, + 0x00010019, + 0x00010019, + 0x0001001a, + 0x0001001a, + 0x0001001b, + 0x0001001b, + 0x00010022, + 0x00010022, + }, + { + 0x00010031, + 0x00010031, + 0x00010032, + 0x00010032, + 0x00010033, + 0x00010033, + 0x00010034, + 0x00010034, + 0x00010035, + 0x00010035, + 0x00010036, + 0x00010036, + 0x00010037, + 0x00010037, + 0x0001003d, + 0x0001003d, + }, + { + 0x0001003e, + 0x0001003e, + 0x0001003f, + 0x0001003f, + 0x00010040, + 0x00010040, + 0x00010041, + 0x00010041, + 0x00010042, + 0x00010042, + 0x00010043, + 0x00010043, + 0x00010044, + 0x00010044, + 0x00010045, + 0x00010045, + }, + { + 0x0001004b, + 0x0001004b, + 0x0001004c, + 0x0001004c, + 0x0001004d, + 0x0001004d, + 0x0001004e, + 0x0001004e, + 0x0001004f, + 0x0001004f, + 0x00010050, + 0x00010050, + 0x00010051, + 0x00010051, + 0x00010052, + 0x00010052, + }, + { + 0x00010053, + 0x00010053, + 0x00010054, + 0x00010054, + 0x00010056, + 0x00010056, + 0x00010057, + 0x00010057, + 0x00010058, + 0x00010058, + 0x00010059, + 0x00010059, + 0x0001005a, + 0x0001005a, + 0x0001005b, + 0x0001005b, + }, + { + 0x0001005c, + 0x0001005c, + 0x0001005d, + 0x0001005d, + 0x0001005e, + 0x0001005e, + 0x0001005f, + 0x0001005f, + 0x00010060, + 0x00010060, + 0x00010061, + 0x00010061, + 0x00010062, + 0x00010062, + 0x00010063, + 0x00010063, + }, + { + 0x00010064, + 0x00010064, + 0x00010065, + 0x00010065, + 0x00010066, + 0x00010066, + 0x00010067, + 0x00010067, + 0x00010068, + 0x00010068, + 0x00010069, + 0x00010069, + 0x0001006a, + 0x0001006a, + 0x0001006b, + 0x0001006b, + }, + { + 0x0001006c, + 0x0001006c, + 0x0001006d, + 0x0001006d, + 0x0001006e, + 0x0001006e, + 0x0001006f, + 0x0001006f, + 0x00010070, + 0x00010070, + 0x00010071, + 0x00010071, + 0x00010072, + 0x00010072, + 0x00010073, + 0x00010073, + }, + { + 0x00010074, + 0x00010074, + 0x00010075, + 0x00010075, + 0x00010076, + 0x00010076, + 0x00010077, + 0x00010077, + 0x00010078, + 0x00010078, + 0x00010079, + 0x00010079, + 0x0001007a, + 0x0001007a, + 0x0001007b, + 0x0001007b, + }, + { + 0x0001007c, + 0x0001007c, + 0x0001007d, + 0x0001007d, + 0x0001007e, + 0x0001007e, + 0x0001007f, + 0x0001007f, + 0x00010080, + 0x00010080, + 0x00010081, + 0x00010081, + 0x00010082, + 0x00010082, + 0x00010083, + 0x00010083, + }, + { + 0x00010084, + 0x00010084, + 0x00010085, + 0x00010085, + 0x00010086, + 0x00010086, + 0x00010087, + 0x00010087, + 0x00010088, + 0x00010088, + 0x00010089, + 0x00010089, + 0x0001008a, + 0x0001008a, + 0x0001008b, + 0x0001008b, + }, + { + 0x0001008c, + 0x0001008c, + 0x0001008d, + 0x0001008d, + 0x0001008e, + 0x0001008e, + 0x0001008f, + 0x0001008f, + 0x00010090, + 0x00010090, + 0x00010091, + 0x00010091, + 0x00010092, + 0x00010092, + 0x00010093, + 0x00010093, + }, + { + 0x00010094, + 0x00010094, + 0x00010095, + 0x00010095, + 0x00010096, + 0x00010096, + 0x00010097, + 0x00010097, + 0x00010098, + 0x00010098, + 0x00010099, + 0x00010099, + 0x0001009a, + 0x0001009a, + 0x0001009b, + 0x0001009b, + }, + { + 0x0001009c, + 0x0001009c, + 0x0001009d, + 0x0001009d, + 0x0001009e, + 0x0001009e, + 0x0001009f, + 0x0001009f, + 0x000100a0, + 0x000100a0, + 0x000100a1, + 0x000100a1, + 0x000100a2, + 0x000100a2, + 0x000100a3, + 0x000100a3, + }, + { + 0x000100a4, + 0x000100a4, + 0x000100a5, + 0x000100a5, + 0x000100a6, + 0x000100a6, + 0x000100a7, + 0x000100a7, + 0x000100a8, + 0x000100a8, + 0x000100a9, + 0x000100a9, + 0x000100aa, + 0x000100aa, + 0x000100ab, + 0x000100ab, + }, + { + 0x000100ac, + 0x000100ac, + 0x000100ad, + 0x000100ad, + 0x000100ae, + 0x000100ae, + 0x000100af, + 0x000100af, + 0x000100b0, + 0x000100b0, + 0x000100b1, + 0x000100b1, + 0x000100b2, + 0x000100b2, + 0x000100b3, + 0x000100b3, + }, + { + 0x000100b4, + 0x000100b4, + 0x000100b5, + 0x000100b5, + 0x000100b6, + 0x000100b6, + 0x000100b7, + 0x000100b7, + 0x000100b8, + 0x000100b8, + 0x000100b9, + 0x000100b9, + 0x000100ba, + 0x000100ba, + 0x000100bb, + 0x000100bb, + }, + { + 0x000100bc, + 0x000100bc, + 0x000100bd, + 0x000100bd, + 0x000100be, + 0x000100be, + 0x000100bf, + 0x000100bf, + 0x000100c0, + 0x000100c0, + 0x000100c1, + 0x000100c1, + 0x000100c2, + 0x000100c2, + 0x000100c3, + 0x000100c3, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc44[289][2] = +#else +const uint16_t c_aauiCQMFHuffEnc44[289][2] = +#endif + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0002 }, + { 0x000f, 0x000a }, + { 0x0011, 0x0022 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000e, 0x0007 }, + { 0x0012, 0x003f }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0006, 0x0003 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0003 }, + { 0x0009, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000f, 0x000b }, + { 0x0012, 0x0040 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0014, 0x001d }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x0010, 0x0013 }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0014, 0x0026 }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000e, 0x0008 }, + { 0x0011, 0x0023 }, + { 0x0012, 0x0041 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0013, 0x007b }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x000f, 0x000c }, + { 0x000e, 0x0009 }, + { 0x000f, 0x000d }, + { 0x0011, 0x0024 }, + { 0x0012, 0x0042 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0014, 0x003e }, + { 0x0013, 0x007c }, + { 0x0011, 0x0025 }, + { 0x0012, 0x0043 }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0014, 0x0047 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0014, 0x0052 }, + { 0x0014, 0x0053 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0014, 0x00c0 }, + { 0x0014, 0x00c1 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0013, 0x007d }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec44[27][16] = { + { + 0x0002ffff, + 0x0001ffff, + 0x00010001, + 0x00010001, + 0x00010011, + 0x00010011, + 0x00010012, + 0x00010012, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + 0x00030000, + }, + { + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + }, + { + 0x0004ffff, + 0x0003ffff, + 0x00000003, + 0x00000014, + 0x00000033, + 0x00000034, + 0x00010024, + 0x00010024, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020022, + }, + { + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + }, + { + 0x000affff, + 0x0006ffff, + 0x0005ffff, + 0x00000026, + 0x00010004, + 0x00010004, + 0x00010015, + 0x00010015, + 0x00010036, + 0x00010036, + 0x00010044, + 0x00010044, + 0x00010045, + 0x00010045, + 0x00010046, + 0x00010046, + }, + { + 0x00020047, + 0x00020047, + 0x00020047, + 0x00020047, + 0x00020056, + 0x00020056, + 0x00020056, + 0x00020056, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + }, + { + 0x0009ffff, + 0x0007ffff, + 0x0008ffff, + 0x00000038, + 0x00010005, + 0x00010005, + 0x00010027, + 0x00010027, + 0x00010055, + 0x00010055, + 0x00010057, + 0x00010057, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020016, + }, + { + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + }, + { + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + 0x00030067, + }, + { + 0x00020028, + 0x00020028, + 0x00020028, + 0x00020028, + 0x00020049, + 0x00020049, + 0x00020049, + 0x00020049, + 0x00020059, + 0x00020059, + 0x00020059, + 0x00020059, + 0x00020068, + 0x00020068, + 0x00020068, + 0x00020068, + }, + { + 0x000dffff, + 0x000cffff, + 0x000effff, + 0x000fffff, + 0x0010ffff, + 0x0011ffff, + 0x0012ffff, + 0x0013ffff, + 0x0014ffff, + 0x0015ffff, + 0x0016ffff, + 0x0017ffff, + 0x0018ffff, + 0x0019ffff, + 0x001affff, + 0x000bffff, + }, + { + 0x0000011a, + 0x0000011b, + 0x0000011c, + 0x0000011d, + 0x0000011e, + 0x0000011f, + 0x0001004c, + 0x0001004c, + 0x00010066, + 0x00010066, + 0x00010120, + 0x00010120, + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020017, + }, + { + 0x0000001e, + 0x0000001f, + 0x00000020, + 0x00000021, + 0x00000029, + 0x0000002a, + 0x0000002b, + 0x0000002c, + 0x0000002d, + 0x0000002e, + 0x0000002f, + 0x00000030, + 0x00000031, + 0x00000032, + 0x00000039, + 0x0000003a, + }, + { + 0x00000007, + 0x00000008, + 0x00000009, + 0x0000000a, + 0x0000000b, + 0x0000000c, + 0x0000000d, + 0x0000000e, + 0x0000000f, + 0x00000010, + 0x00000018, + 0x00000019, + 0x0000001a, + 0x0000001b, + 0x0000001c, + 0x0000001d, + }, + { + 0x0000003b, + 0x0000003c, + 0x0000003d, + 0x0000003e, + 0x0000003f, + 0x00000040, + 0x00000041, + 0x00000042, + 0x00000043, + 0x0000004a, + 0x0000004b, + 0x0000004d, + 0x0000004e, + 0x0000004f, + 0x00000050, + 0x00000051, + }, + { + 0x00000052, + 0x00000053, + 0x00000054, + 0x0000005a, + 0x0000005b, + 0x0000005c, + 0x0000005d, + 0x0000005e, + 0x0000005f, + 0x00000060, + 0x00000061, + 0x00000062, + 0x00000063, + 0x00000064, + 0x00000065, + 0x00000069, + }, + { + 0x0000006a, + 0x0000006b, + 0x0000006c, + 0x0000006d, + 0x0000006e, + 0x0000006f, + 0x00000070, + 0x00000071, + 0x00000072, + 0x00000073, + 0x00000074, + 0x00000075, + 0x00000076, + 0x00000077, + 0x00000078, + 0x00000079, + }, + { + 0x0000007a, + 0x0000007b, + 0x0000007c, + 0x0000007d, + 0x0000007e, + 0x0000007f, + 0x00000080, + 0x00000081, + 0x00000082, + 0x00000083, + 0x00000084, + 0x00000085, + 0x00000086, + 0x00000087, + 0x00000088, + 0x00000089, + }, + { + 0x0000008a, + 0x0000008b, + 0x0000008c, + 0x0000008d, + 0x0000008e, + 0x0000008f, + 0x00000090, + 0x00000091, + 0x00000092, + 0x00000093, + 0x00000094, + 0x00000095, + 0x00000096, + 0x00000097, + 0x00000098, + 0x00000099, + }, + { + 0x0000009a, + 0x0000009b, + 0x0000009c, + 0x0000009d, + 0x0000009e, + 0x0000009f, + 0x000000a0, + 0x000000a1, + 0x000000a2, + 0x000000a3, + 0x000000a4, + 0x000000a5, + 0x000000a6, + 0x000000a7, + 0x000000a8, + 0x000000a9, + }, + { + 0x000000aa, + 0x000000ab, + 0x000000ac, + 0x000000ad, + 0x000000ae, + 0x000000af, + 0x000000b0, + 0x000000b1, + 0x000000b2, + 0x000000b3, + 0x000000b4, + 0x000000b5, + 0x000000b6, + 0x000000b7, + 0x000000b8, + 0x000000b9, + }, + { + 0x000000ba, + 0x000000bb, + 0x000000bc, + 0x000000bd, + 0x000000be, + 0x000000bf, + 0x000000c0, + 0x000000c1, + 0x000000c2, + 0x000000c3, + 0x000000c4, + 0x000000c5, + 0x000000c6, + 0x000000c7, + 0x000000c8, + 0x000000c9, + }, + { + 0x000000ca, + 0x000000cb, + 0x000000cc, + 0x000000cd, + 0x000000ce, + 0x000000cf, + 0x000000d0, + 0x000000d1, + 0x000000d2, + 0x000000d3, + 0x000000d4, + 0x000000d5, + 0x000000d6, + 0x000000d7, + 0x000000d8, + 0x000000d9, + }, + { + 0x000000da, + 0x000000db, + 0x000000dc, + 0x000000dd, + 0x000000de, + 0x000000df, + 0x000000e0, + 0x000000e1, + 0x000000e2, + 0x000000e3, + 0x000000e4, + 0x000000e5, + 0x000000e6, + 0x000000e7, + 0x000000e8, + 0x000000e9, + }, + { + 0x000000ea, + 0x000000eb, + 0x000000ec, + 0x000000ed, + 0x000000ee, + 0x000000ef, + 0x000000f0, + 0x000000f1, + 0x000000f2, + 0x000000f3, + 0x000000f4, + 0x000000f5, + 0x000000f6, + 0x000000f7, + 0x000000f8, + 0x000000f9, + }, + { + 0x000000fa, + 0x000000fb, + 0x000000fc, + 0x000000fd, + 0x000000fe, + 0x000000ff, + 0x00000100, + 0x00000101, + 0x00000102, + 0x00000103, + 0x00000104, + 0x00000105, + 0x00000106, + 0x00000107, + 0x00000108, + 0x00000109, + }, + { + 0x0000010a, + 0x0000010b, + 0x0000010c, + 0x0000010d, + 0x0000010e, + 0x0000010f, + 0x00000110, + 0x00000111, + 0x00000112, + 0x00000113, + 0x00000114, + 0x00000115, + 0x00000116, + 0x00000117, + 0x00000118, + 0x00000119, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc45[324][2] = +#else +const uint16_t c_aauiCQMFHuffEnc45[324][2] = +#endif + { + { 0x0002, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000c, 0x0005 }, + { 0x0010, 0x0025 }, + { 0x0012, 0x0088 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0006, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x000b, 0x0004 }, + { 0x000f, 0x0014 }, + { 0x0011, 0x0048 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0005, 0x0005 }, + { 0x0004, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0007, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000d, 0x0007 }, + { 0x000f, 0x0015 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0007, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0005 }, + { 0x000b, 0x0005 }, + { 0x000d, 0x0008 }, + { 0x0010, 0x0026 }, + { 0x0012, 0x0089 }, + { 0x0012, 0x008a }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000d, 0x0009 }, + { 0x000f, 0x0016 }, + { 0x0011, 0x0049 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x000c, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000e, 0x000d }, + { 0x0010, 0x0027 }, + { 0x0012, 0x008b }, + { 0x0012, 0x008c }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x000f, 0x0017 }, + { 0x000f, 0x0018 }, + { 0x000f, 0x0019 }, + { 0x0012, 0x008d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0012, 0x008e }, + { 0x0012, 0x008f }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0013, 0x00a9 }, + { 0x0013, 0x00aa }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0013, 0x00c1 }, + { 0x0013, 0x00c2 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec45[50][16] = { + { + 0x0003ffff, + 0x0001ffff, + 0x0002ffff, + 0x00000025, + 0x00010001, + 0x00010001, + 0x00010013, + 0x00010013, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + }, + { + 0x00020026, + 0x00020026, + 0x00020026, + 0x00020026, + 0x00020037, + 0x00020037, + 0x00020037, + 0x00020037, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + }, + { + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + }, + { + 0x0007ffff, + 0x0005ffff, + 0x0004ffff, + 0x0006ffff, + 0x00010003, + 0x00010003, + 0x00010027, + 0x00010027, + 0x00010036, + 0x00010036, + 0x00010038, + 0x00010038, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020015, + }, + { + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + 0x00030039, + }, + { + 0x00020028, + 0x00020028, + 0x00020028, + 0x00020028, + 0x0002004a, + 0x0002004a, + 0x0002004a, + 0x0002004a, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + }, + { + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + }, + { + 0x000effff, + 0x001fffff, + 0x000affff, + 0x0008ffff, + 0x0009ffff, + 0x00000005, + 0x0000005a, + 0x0000005c, + 0x00010017, + 0x00010017, + 0x0001003a, + 0x0001003a, + 0x0001004b, + 0x0001004b, + 0x0001005b, + 0x0001005b, + }, + { + 0x0001006d, + 0x0001006d, + 0x0001006e, + 0x0001006e, + 0x0002005d, + 0x0002005d, + 0x0002005d, + 0x0002005d, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + }, + { + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + }, + { + 0x0030ffff, + 0x0031ffff, + 0x000cffff, + 0x000dffff, + 0x000bffff, + 0x00000006, + 0x0000003c, + 0x0000005e, + 0x00010018, + 0x00010018, + 0x0001002a, + 0x0001002a, + 0x0001004d, + 0x0001004d, + 0x0001006c, + 0x0001006c, + }, + { + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + }, + { + 0x00020007, + 0x00020007, + 0x00020007, + 0x00020007, + 0x0002003d, + 0x0002003d, + 0x0002003d, + 0x0002003d, + 0x0002003e, + 0x0002003e, + 0x0002003e, + 0x0002003e, + 0x0002005f, + 0x0002005f, + 0x0002005f, + 0x0002005f, + }, + { + 0x00020060, + 0x00020060, + 0x00020060, + 0x00020060, + 0x0002006f, + 0x0002006f, + 0x0002006f, + 0x0002006f, + 0x0002007f, + 0x0002007f, + 0x0002007f, + 0x0002007f, + 0x00020080, + 0x00020080, + 0x00020080, + 0x00020080, + }, + { + 0x0010ffff, + 0x0011ffff, + 0x0012ffff, + 0x000fffff, + 0x0013ffff, + 0x0014ffff, + 0x0015ffff, + 0x0016ffff, + 0x0017ffff, + 0x0018ffff, + 0x0019ffff, + 0x001affff, + 0x001bffff, + 0x001cffff, + 0x001dffff, + 0x001effff, + }, + { + 0x0001002f, + 0x0001002f, + 0x00010030, + 0x00010030, + 0x00010031, + 0x00010031, + 0x00010032, + 0x00010032, + 0x00010033, + 0x00010033, + 0x00010034, + 0x00010034, + 0x00010035, + 0x00010035, + 0x0001003f, + 0x0001003f, + }, + { + 0x00010008, + 0x00010008, + 0x00010009, + 0x00010009, + 0x0001000a, + 0x0001000a, + 0x0001000b, + 0x0001000b, + 0x0001000c, + 0x0001000c, + 0x0001000d, + 0x0001000d, + 0x0001000e, + 0x0001000e, + 0x0001000f, + 0x0001000f, + }, + { + 0x00010010, + 0x00010010, + 0x00010011, + 0x00010011, + 0x0001001a, + 0x0001001a, + 0x0001001b, + 0x0001001b, + 0x0001001c, + 0x0001001c, + 0x0001001d, + 0x0001001d, + 0x0001001e, + 0x0001001e, + 0x0001001f, + 0x0001001f, + }, + { + 0x00010020, + 0x00010020, + 0x00010021, + 0x00010021, + 0x00010022, + 0x00010022, + 0x00010023, + 0x00010023, + 0x0001002b, + 0x0001002b, + 0x0001002c, + 0x0001002c, + 0x0001002d, + 0x0001002d, + 0x0001002e, + 0x0001002e, + }, + { + 0x00010040, + 0x00010040, + 0x00010041, + 0x00010041, + 0x00010042, + 0x00010042, + 0x00010043, + 0x00010043, + 0x00010044, + 0x00010044, + 0x00010045, + 0x00010045, + 0x00010046, + 0x00010046, + 0x00010047, + 0x00010047, + }, + { + 0x0001004f, + 0x0001004f, + 0x00010050, + 0x00010050, + 0x00010051, + 0x00010051, + 0x00010052, + 0x00010052, + 0x00010053, + 0x00010053, + 0x00010054, + 0x00010054, + 0x00010055, + 0x00010055, + 0x00010056, + 0x00010056, + }, + { + 0x00010057, + 0x00010057, + 0x00010058, + 0x00010058, + 0x00010059, + 0x00010059, + 0x00010061, + 0x00010061, + 0x00010062, + 0x00010062, + 0x00010063, + 0x00010063, + 0x00010064, + 0x00010064, + 0x00010065, + 0x00010065, + }, + { + 0x00010066, + 0x00010066, + 0x00010067, + 0x00010067, + 0x00010068, + 0x00010068, + 0x00010069, + 0x00010069, + 0x0001006a, + 0x0001006a, + 0x0001006b, + 0x0001006b, + 0x00010070, + 0x00010070, + 0x00010071, + 0x00010071, + }, + { + 0x00010072, + 0x00010072, + 0x00010073, + 0x00010073, + 0x00010074, + 0x00010074, + 0x00010075, + 0x00010075, + 0x00010076, + 0x00010076, + 0x00010077, + 0x00010077, + 0x00010078, + 0x00010078, + 0x00010079, + 0x00010079, + }, + { + 0x0001007a, + 0x0001007a, + 0x0001007b, + 0x0001007b, + 0x0001007c, + 0x0001007c, + 0x0001007d, + 0x0001007d, + 0x0001007e, + 0x0001007e, + 0x00010081, + 0x00010081, + 0x00010082, + 0x00010082, + 0x00010083, + 0x00010083, + }, + { + 0x00010084, + 0x00010084, + 0x00010085, + 0x00010085, + 0x00010086, + 0x00010086, + 0x00010087, + 0x00010087, + 0x00010088, + 0x00010088, + 0x00010089, + 0x00010089, + 0x0001008a, + 0x0001008a, + 0x0001008b, + 0x0001008b, + }, + { + 0x0001008c, + 0x0001008c, + 0x0001008d, + 0x0001008d, + 0x0001008e, + 0x0001008e, + 0x0001008f, + 0x0001008f, + 0x00010090, + 0x00010090, + 0x00010091, + 0x00010091, + 0x00010092, + 0x00010092, + 0x00010093, + 0x00010093, + }, + { + 0x00010094, + 0x00010094, + 0x00010095, + 0x00010095, + 0x00010096, + 0x00010096, + 0x00010097, + 0x00010097, + 0x00010098, + 0x00010098, + 0x00010099, + 0x00010099, + 0x0001009a, + 0x0001009a, + 0x0001009b, + 0x0001009b, + }, + { + 0x0001009c, + 0x0001009c, + 0x0001009d, + 0x0001009d, + 0x0001009e, + 0x0001009e, + 0x0001009f, + 0x0001009f, + 0x000100a0, + 0x000100a0, + 0x000100a1, + 0x000100a1, + 0x000100a2, + 0x000100a2, + 0x000100a3, + 0x000100a3, + }, + { + 0x000100a4, + 0x000100a4, + 0x000100a5, + 0x000100a5, + 0x000100a6, + 0x000100a6, + 0x000100a7, + 0x000100a7, + 0x000100a8, + 0x000100a8, + 0x000100a9, + 0x000100a9, + 0x000100aa, + 0x000100aa, + 0x000100ab, + 0x000100ab, + }, + { + 0x000100ac, + 0x000100ac, + 0x000100ad, + 0x000100ad, + 0x000100ae, + 0x000100ae, + 0x000100af, + 0x000100af, + 0x000100b0, + 0x000100b0, + 0x000100b1, + 0x000100b1, + 0x000100b2, + 0x000100b2, + 0x000100b3, + 0x000100b3, + }, + { + 0x0020ffff, + 0x0021ffff, + 0x0022ffff, + 0x0023ffff, + 0x0024ffff, + 0x0025ffff, + 0x0026ffff, + 0x0027ffff, + 0x0028ffff, + 0x0029ffff, + 0x002affff, + 0x002bffff, + 0x002cffff, + 0x002dffff, + 0x002effff, + 0x002fffff, + }, + { + 0x000100b4, + 0x000100b4, + 0x000100b5, + 0x000100b5, + 0x000100b6, + 0x000100b6, + 0x000100b7, + 0x000100b7, + 0x000100b8, + 0x000100b8, + 0x000100b9, + 0x000100b9, + 0x000100ba, + 0x000100ba, + 0x000100bb, + 0x000100bb, + }, + { + 0x000100bc, + 0x000100bc, + 0x000100bd, + 0x000100bd, + 0x000100be, + 0x000100be, + 0x000100bf, + 0x000100bf, + 0x000100c0, + 0x000100c0, + 0x000100c1, + 0x000100c1, + 0x000100c2, + 0x000100c2, + 0x000100c3, + 0x000100c3, + }, + { + 0x000100c4, + 0x000100c4, + 0x000100c5, + 0x000100c5, + 0x000100c6, + 0x000100c6, + 0x000100c7, + 0x000100c7, + 0x000100c8, + 0x000100c8, + 0x000100c9, + 0x000100c9, + 0x000100ca, + 0x000100ca, + 0x000100cb, + 0x000100cb, + }, + { + 0x000100cc, + 0x000100cc, + 0x000100cd, + 0x000100cd, + 0x000100ce, + 0x000100ce, + 0x000100cf, + 0x000100cf, + 0x000100d0, + 0x000100d0, + 0x000100d1, + 0x000100d1, + 0x000100d2, + 0x000100d2, + 0x000100d3, + 0x000100d3, + }, + { + 0x000100d4, + 0x000100d4, + 0x000100d5, + 0x000100d5, + 0x000100d6, + 0x000100d6, + 0x000100d7, + 0x000100d7, + 0x000100d8, + 0x000100d8, + 0x000100d9, + 0x000100d9, + 0x000100da, + 0x000100da, + 0x000100db, + 0x000100db, + }, + { + 0x000100dc, + 0x000100dc, + 0x000100dd, + 0x000100dd, + 0x000100de, + 0x000100de, + 0x000100df, + 0x000100df, + 0x000100e0, + 0x000100e0, + 0x000100e1, + 0x000100e1, + 0x000100e2, + 0x000100e2, + 0x000100e3, + 0x000100e3, + }, + { + 0x000100e4, + 0x000100e4, + 0x000100e5, + 0x000100e5, + 0x000100e6, + 0x000100e6, + 0x000100e7, + 0x000100e7, + 0x000100e8, + 0x000100e8, + 0x000100e9, + 0x000100e9, + 0x000100ea, + 0x000100ea, + 0x000100eb, + 0x000100eb, + }, + { + 0x000100ec, + 0x000100ec, + 0x000100ed, + 0x000100ed, + 0x000100ee, + 0x000100ee, + 0x000100ef, + 0x000100ef, + 0x000100f0, + 0x000100f0, + 0x000100f1, + 0x000100f1, + 0x000100f2, + 0x000100f2, + 0x000100f3, + 0x000100f3, + }, + { + 0x000100f4, + 0x000100f4, + 0x000100f5, + 0x000100f5, + 0x000100f6, + 0x000100f6, + 0x000100f7, + 0x000100f7, + 0x000100f8, + 0x000100f8, + 0x000100f9, + 0x000100f9, + 0x000100fa, + 0x000100fa, + 0x000100fb, + 0x000100fb, + }, + { + 0x000100fc, + 0x000100fc, + 0x000100fd, + 0x000100fd, + 0x000100fe, + 0x000100fe, + 0x000100ff, + 0x000100ff, + 0x00010100, + 0x00010100, + 0x00010101, + 0x00010101, + 0x00010102, + 0x00010102, + 0x00010103, + 0x00010103, + }, + { + 0x00010104, + 0x00010104, + 0x00010105, + 0x00010105, + 0x00010106, + 0x00010106, + 0x00010107, + 0x00010107, + 0x00010108, + 0x00010108, + 0x00010109, + 0x00010109, + 0x0001010a, + 0x0001010a, + 0x0001010b, + 0x0001010b, + }, + { + 0x0001010c, + 0x0001010c, + 0x0001010d, + 0x0001010d, + 0x0001010e, + 0x0001010e, + 0x0001010f, + 0x0001010f, + 0x00010110, + 0x00010110, + 0x00010111, + 0x00010111, + 0x00010112, + 0x00010112, + 0x00010113, + 0x00010113, + }, + { + 0x00010114, + 0x00010114, + 0x00010115, + 0x00010115, + 0x00010116, + 0x00010116, + 0x00010117, + 0x00010117, + 0x00010118, + 0x00010118, + 0x00010119, + 0x00010119, + 0x0001011a, + 0x0001011a, + 0x0001011b, + 0x0001011b, + }, + { + 0x0001011c, + 0x0001011c, + 0x0001011d, + 0x0001011d, + 0x0001011e, + 0x0001011e, + 0x0001011f, + 0x0001011f, + 0x00010120, + 0x00010120, + 0x00010121, + 0x00010121, + 0x00010122, + 0x00010122, + 0x00010123, + 0x00010123, + }, + { + 0x00010124, + 0x00010124, + 0x00010125, + 0x00010125, + 0x00010126, + 0x00010126, + 0x00010127, + 0x00010127, + 0x00010128, + 0x00010128, + 0x00010129, + 0x00010129, + 0x0001012a, + 0x0001012a, + 0x0001012b, + 0x0001012b, + }, + { + 0x0001012c, + 0x0001012c, + 0x0001012d, + 0x0001012d, + 0x0001012e, + 0x0001012e, + 0x0001012f, + 0x0001012f, + 0x00010130, + 0x00010130, + 0x00010131, + 0x00010131, + 0x00010132, + 0x00010132, + 0x00010133, + 0x00010133, + }, + { + 0x00010134, + 0x00010134, + 0x00010135, + 0x00010135, + 0x00010136, + 0x00010136, + 0x00010137, + 0x00010137, + 0x00010138, + 0x00010138, + 0x00010139, + 0x00010139, + 0x0001013a, + 0x0001013a, + 0x0001013b, + 0x0001013b, + }, + { + 0x0001013c, + 0x0001013c, + 0x0001013d, + 0x0001013d, + 0x0001013e, + 0x0001013e, + 0x0001013f, + 0x0001013f, + 0x00010140, + 0x00010140, + 0x00010141, + 0x00010141, + 0x00010142, + 0x00010142, + 0x00010143, + 0x00010143, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc46[400][2] = +#else +const uint16_t c_aauiCQMFHuffEnc46[400][2] = +#endif + { + { 0x0002, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000d, 0x000a }, + { 0x000f, 0x0018 }, + { 0x0012, 0x00a6 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0006, 0x0004 }, + { 0x0008, 0x0004 }, + { 0x000a, 0x0006 }, + { 0x000c, 0x0008 }, + { 0x000e, 0x0011 }, + { 0x0012, 0x00a7 }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000d, 0x000b }, + { 0x000f, 0x0019 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0007, 0x0006 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0005 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x0009 }, + { 0x000e, 0x0012 }, + { 0x000f, 0x001a }, + { 0x0012, 0x00a8 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0009, 0x0007 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000b, 0x0008 }, + { 0x000d, 0x000c }, + { 0x000e, 0x0013 }, + { 0x0010, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x000b, 0x0009 }, + { 0x000a, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000b, 0x000b }, + { 0x000d, 0x000d }, + { 0x000f, 0x001b }, + { 0x0010, 0x002d }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x000d, 0x000e }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000d, 0x000f }, + { 0x000f, 0x001c }, + { 0x000f, 0x001d }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x000f, 0x001e }, + { 0x000f, 0x001f }, + { 0x000f, 0x0020 }, + { 0x000f, 0x0021 }, + { 0x0010, 0x002e }, + { 0x0012, 0x00a9 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0012, 0x00aa }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0010, 0x002f }, + { 0x0013, 0x0062 }, + { 0x0011, 0x0057 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0013, 0x00a9 }, + { 0x0013, 0x00aa }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0013, 0x00c1 }, + { 0x0013, 0x00c2 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + { 0x0013, 0x0114 }, + { 0x0013, 0x0115 }, + { 0x0013, 0x0116 }, + { 0x0013, 0x0117 }, + { 0x0013, 0x0118 }, + { 0x0013, 0x0119 }, + { 0x0013, 0x011a }, + { 0x0013, 0x011b }, + { 0x0013, 0x011c }, + { 0x0013, 0x011d }, + { 0x0013, 0x011e }, + { 0x0013, 0x011f }, + { 0x0013, 0x0120 }, + { 0x0013, 0x0121 }, + { 0x0013, 0x0122 }, + { 0x0013, 0x0123 }, + { 0x0013, 0x0124 }, + { 0x0013, 0x0125 }, + { 0x0013, 0x0126 }, + { 0x0013, 0x0127 }, + { 0x0013, 0x0128 }, + { 0x0013, 0x0129 }, + { 0x0013, 0x012a }, + { 0x0013, 0x012b }, + { 0x0013, 0x012c }, + { 0x0013, 0x012d }, + { 0x0013, 0x012e }, + { 0x0013, 0x012f }, + { 0x0013, 0x0130 }, + { 0x0013, 0x0131 }, + { 0x0013, 0x0132 }, + { 0x0013, 0x0133 }, + { 0x0013, 0x0134 }, + { 0x0013, 0x0135 }, + { 0x0013, 0x0136 }, + { 0x0013, 0x0137 }, + { 0x0013, 0x0138 }, + { 0x0013, 0x0139 }, + { 0x0013, 0x013a }, + { 0x0013, 0x013b }, + { 0x0013, 0x013c }, + { 0x0013, 0x013d }, + { 0x0013, 0x013e }, + { 0x0013, 0x013f }, + { 0x0013, 0x0140 }, + { 0x0013, 0x0141 }, + { 0x0013, 0x0142 }, + { 0x0013, 0x0143 }, + { 0x0013, 0x0144 }, + { 0x0013, 0x0145 }, + { 0x0013, 0x0146 }, + { 0x0013, 0x0147 }, + { 0x0013, 0x0148 }, + { 0x0013, 0x0149 }, + { 0x0013, 0x014a }, + { 0x0013, 0x014b }, + { 0x0012, 0x00ab }, + { 0x0012, 0x00ac }, + { 0x0012, 0x00ad }, + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec46[61][16] = { + { + 0x0004ffff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x00010001, + 0x00010001, + 0x00010015, + 0x00010015, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020014, + }, + { + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020017, + 0x0002003d, + 0x0002003d, + 0x0002003d, + 0x0002003d, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + }, + { + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + }, + { + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + }, + { + 0x0008ffff, + 0x0007ffff, + 0x0005ffff, + 0x0006ffff, + 0x00000018, + 0x0000003f, + 0x00000051, + 0x00000052, + 0x00010003, + 0x00010003, + 0x0001002b, + 0x0001002b, + 0x0001003c, + 0x0001003c, + 0x0001003e, + 0x0001003e, + }, + { + 0x00020053, + 0x00020053, + 0x00020053, + 0x00020053, + 0x00020065, + 0x00020065, + 0x00020065, + 0x00020065, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + }, + { + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + 0x00030050, + }, + { + 0x00010054, + 0x00010054, + 0x00010064, + 0x00010064, + 0x00010066, + 0x00010066, + 0x00010067, + 0x00010067, + 0x00020019, + 0x00020019, + 0x00020019, + 0x00020019, + 0x00020040, + 0x00020040, + 0x00020040, + 0x00020040, + }, + { + 0x0012ffff, + 0x0023ffff, + 0x000effff, + 0x000dffff, + 0x000cffff, + 0x0009ffff, + 0x000affff, + 0x000bffff, + 0x0000001a, + 0x00000041, + 0x00000079, + 0x0000007a, + 0x00010005, + 0x00010005, + 0x0001002d, + 0x0001002d, + }, + { + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + }, + { + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + }, + { + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + 0x00030078, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + 0x0003007b, + }, + { + 0x0001008e, + 0x0001008e, + 0x0001008f, + 0x0001008f, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x00020042, + 0x00020042, + 0x00020042, + 0x00020042, + 0x00020056, + 0x00020056, + 0x00020056, + 0x00020056, + }, + { + 0x00010007, + 0x00010007, + 0x0001002f, + 0x0001002f, + 0x00010043, + 0x00010043, + 0x00010069, + 0x00010069, + 0x0001007c, + 0x0001007c, + 0x0001007d, + 0x0001007d, + 0x0001008c, + 0x0001008c, + 0x0001008d, + 0x0001008d, + }, + { + 0x0034ffff, + 0x0035ffff, + 0x0036ffff, + 0x0037ffff, + 0x0038ffff, + 0x0039ffff, + 0x003affff, + 0x003bffff, + 0x003cffff, + 0x0010ffff, + 0x0011ffff, + 0x000fffff, + 0x00000057, + 0x0000006a, + 0x00000090, + 0x000000a1, + }, + { + 0x0002018e, + 0x0002018e, + 0x0002018e, + 0x0002018e, + 0x0002018f, + 0x0002018f, + 0x0002018f, + 0x0002018f, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + }, + { + 0x00010189, + 0x00010189, + 0x0001018a, + 0x0001018a, + 0x0001018b, + 0x0001018b, + 0x0001018c, + 0x0001018c, + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020008, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001c, + }, + { + 0x00020044, + 0x00020044, + 0x00020044, + 0x00020044, + 0x00020091, + 0x00020091, + 0x00020091, + 0x00020091, + 0x00020094, + 0x00020094, + 0x00020094, + 0x00020094, + 0x0002018d, + 0x0002018d, + 0x0002018d, + 0x0002018d, + }, + { + 0x0013ffff, + 0x0016ffff, + 0x0017ffff, + 0x0018ffff, + 0x0014ffff, + 0x0015ffff, + 0x0019ffff, + 0x001affff, + 0x001bffff, + 0x001cffff, + 0x001dffff, + 0x001effff, + 0x001fffff, + 0x0020ffff, + 0x0021ffff, + 0x0022ffff, + }, + { + 0x00010009, + 0x00010009, + 0x0001000a, + 0x0001000a, + 0x0001000b, + 0x0001000b, + 0x0001000c, + 0x0001000c, + 0x0001000d, + 0x0001000d, + 0x0001000e, + 0x0001000e, + 0x0001000f, + 0x0001000f, + 0x00010010, + 0x00010010, + }, + { + 0x0001003a, + 0x0001003a, + 0x0001003b, + 0x0001003b, + 0x00010045, + 0x00010045, + 0x00010046, + 0x00010046, + 0x00010047, + 0x00010047, + 0x00010048, + 0x00010048, + 0x00010049, + 0x00010049, + 0x0001004a, + 0x0001004a, + }, + { + 0x0001004b, + 0x0001004b, + 0x0001004c, + 0x0001004c, + 0x0001004d, + 0x0001004d, + 0x0001004e, + 0x0001004e, + 0x0001004f, + 0x0001004f, + 0x00010058, + 0x00010058, + 0x00010059, + 0x00010059, + 0x0001005a, + 0x0001005a, + }, + { + 0x00010011, + 0x00010011, + 0x00010012, + 0x00010012, + 0x00010013, + 0x00010013, + 0x0001001d, + 0x0001001d, + 0x0001001e, + 0x0001001e, + 0x0001001f, + 0x0001001f, + 0x00010020, + 0x00010020, + 0x00010021, + 0x00010021, + }, + { + 0x00010022, + 0x00010022, + 0x00010023, + 0x00010023, + 0x00010024, + 0x00010024, + 0x00010025, + 0x00010025, + 0x00010026, + 0x00010026, + 0x00010027, + 0x00010027, + 0x00010030, + 0x00010030, + 0x00010031, + 0x00010031, + }, + { + 0x00010032, + 0x00010032, + 0x00010033, + 0x00010033, + 0x00010034, + 0x00010034, + 0x00010035, + 0x00010035, + 0x00010036, + 0x00010036, + 0x00010037, + 0x00010037, + 0x00010038, + 0x00010038, + 0x00010039, + 0x00010039, + }, + { + 0x0001005b, + 0x0001005b, + 0x0001005c, + 0x0001005c, + 0x0001005d, + 0x0001005d, + 0x0001005e, + 0x0001005e, + 0x0001005f, + 0x0001005f, + 0x00010060, + 0x00010060, + 0x00010061, + 0x00010061, + 0x00010062, + 0x00010062, + }, + { + 0x00010063, + 0x00010063, + 0x0001006b, + 0x0001006b, + 0x0001006c, + 0x0001006c, + 0x0001006d, + 0x0001006d, + 0x0001006e, + 0x0001006e, + 0x0001006f, + 0x0001006f, + 0x00010070, + 0x00010070, + 0x00010071, + 0x00010071, + }, + { + 0x00010072, + 0x00010072, + 0x00010073, + 0x00010073, + 0x00010074, + 0x00010074, + 0x00010075, + 0x00010075, + 0x00010076, + 0x00010076, + 0x00010077, + 0x00010077, + 0x0001007e, + 0x0001007e, + 0x0001007f, + 0x0001007f, + }, + { + 0x00010080, + 0x00010080, + 0x00010081, + 0x00010081, + 0x00010082, + 0x00010082, + 0x00010083, + 0x00010083, + 0x00010084, + 0x00010084, + 0x00010085, + 0x00010085, + 0x00010086, + 0x00010086, + 0x00010087, + 0x00010087, + }, + { + 0x00010088, + 0x00010088, + 0x00010089, + 0x00010089, + 0x0001008a, + 0x0001008a, + 0x0001008b, + 0x0001008b, + 0x00010092, + 0x00010092, + 0x00010093, + 0x00010093, + 0x00010095, + 0x00010095, + 0x00010096, + 0x00010096, + }, + { + 0x00010097, + 0x00010097, + 0x00010098, + 0x00010098, + 0x00010099, + 0x00010099, + 0x0001009a, + 0x0001009a, + 0x0001009b, + 0x0001009b, + 0x0001009c, + 0x0001009c, + 0x0001009d, + 0x0001009d, + 0x0001009e, + 0x0001009e, + }, + { + 0x0001009f, + 0x0001009f, + 0x000100a0, + 0x000100a0, + 0x000100a2, + 0x000100a2, + 0x000100a4, + 0x000100a4, + 0x000100a5, + 0x000100a5, + 0x000100a6, + 0x000100a6, + 0x000100a7, + 0x000100a7, + 0x000100a8, + 0x000100a8, + }, + { + 0x000100a9, + 0x000100a9, + 0x000100aa, + 0x000100aa, + 0x000100ab, + 0x000100ab, + 0x000100ac, + 0x000100ac, + 0x000100ad, + 0x000100ad, + 0x000100ae, + 0x000100ae, + 0x000100af, + 0x000100af, + 0x000100b0, + 0x000100b0, + }, + { + 0x000100b1, + 0x000100b1, + 0x000100b2, + 0x000100b2, + 0x000100b3, + 0x000100b3, + 0x000100b4, + 0x000100b4, + 0x000100b5, + 0x000100b5, + 0x000100b6, + 0x000100b6, + 0x000100b7, + 0x000100b7, + 0x000100b8, + 0x000100b8, + }, + { + 0x000100b9, + 0x000100b9, + 0x000100ba, + 0x000100ba, + 0x000100bb, + 0x000100bb, + 0x000100bc, + 0x000100bc, + 0x000100bd, + 0x000100bd, + 0x000100be, + 0x000100be, + 0x000100bf, + 0x000100bf, + 0x000100c0, + 0x000100c0, + }, + { + 0x0024ffff, + 0x0025ffff, + 0x0026ffff, + 0x0027ffff, + 0x0028ffff, + 0x0029ffff, + 0x002affff, + 0x002bffff, + 0x002cffff, + 0x002dffff, + 0x002effff, + 0x002fffff, + 0x0030ffff, + 0x0031ffff, + 0x0032ffff, + 0x0033ffff, + }, + { + 0x000100c1, + 0x000100c1, + 0x000100c2, + 0x000100c2, + 0x000100c3, + 0x000100c3, + 0x000100c4, + 0x000100c4, + 0x000100c5, + 0x000100c5, + 0x000100c6, + 0x000100c6, + 0x000100c7, + 0x000100c7, + 0x000100c8, + 0x000100c8, + }, + { + 0x000100c9, + 0x000100c9, + 0x000100ca, + 0x000100ca, + 0x000100cb, + 0x000100cb, + 0x000100cc, + 0x000100cc, + 0x000100cd, + 0x000100cd, + 0x000100ce, + 0x000100ce, + 0x000100cf, + 0x000100cf, + 0x000100d0, + 0x000100d0, + }, + { + 0x000100d1, + 0x000100d1, + 0x000100d2, + 0x000100d2, + 0x000100d3, + 0x000100d3, + 0x000100d4, + 0x000100d4, + 0x000100d5, + 0x000100d5, + 0x000100d6, + 0x000100d6, + 0x000100d7, + 0x000100d7, + 0x000100d8, + 0x000100d8, + }, + { + 0x000100d9, + 0x000100d9, + 0x000100da, + 0x000100da, + 0x000100db, + 0x000100db, + 0x000100dc, + 0x000100dc, + 0x000100dd, + 0x000100dd, + 0x000100de, + 0x000100de, + 0x000100df, + 0x000100df, + 0x000100e0, + 0x000100e0, + }, + { + 0x000100e1, + 0x000100e1, + 0x000100e2, + 0x000100e2, + 0x000100e3, + 0x000100e3, + 0x000100e4, + 0x000100e4, + 0x000100e5, + 0x000100e5, + 0x000100e6, + 0x000100e6, + 0x000100e7, + 0x000100e7, + 0x000100e8, + 0x000100e8, + }, + { + 0x000100e9, + 0x000100e9, + 0x000100ea, + 0x000100ea, + 0x000100eb, + 0x000100eb, + 0x000100ec, + 0x000100ec, + 0x000100ed, + 0x000100ed, + 0x000100ee, + 0x000100ee, + 0x000100ef, + 0x000100ef, + 0x000100f0, + 0x000100f0, + }, + { + 0x000100f1, + 0x000100f1, + 0x000100f2, + 0x000100f2, + 0x000100f3, + 0x000100f3, + 0x000100f4, + 0x000100f4, + 0x000100f5, + 0x000100f5, + 0x000100f6, + 0x000100f6, + 0x000100f7, + 0x000100f7, + 0x000100f8, + 0x000100f8, + }, + { + 0x000100f9, + 0x000100f9, + 0x000100fa, + 0x000100fa, + 0x000100fb, + 0x000100fb, + 0x000100fc, + 0x000100fc, + 0x000100fd, + 0x000100fd, + 0x000100fe, + 0x000100fe, + 0x000100ff, + 0x000100ff, + 0x00010100, + 0x00010100, + }, + { + 0x00010101, + 0x00010101, + 0x00010102, + 0x00010102, + 0x00010103, + 0x00010103, + 0x00010104, + 0x00010104, + 0x00010105, + 0x00010105, + 0x00010106, + 0x00010106, + 0x00010107, + 0x00010107, + 0x00010108, + 0x00010108, + }, + { + 0x00010109, + 0x00010109, + 0x0001010a, + 0x0001010a, + 0x0001010b, + 0x0001010b, + 0x0001010c, + 0x0001010c, + 0x0001010d, + 0x0001010d, + 0x0001010e, + 0x0001010e, + 0x0001010f, + 0x0001010f, + 0x00010110, + 0x00010110, + }, + { + 0x00010111, + 0x00010111, + 0x00010112, + 0x00010112, + 0x00010113, + 0x00010113, + 0x00010114, + 0x00010114, + 0x00010115, + 0x00010115, + 0x00010116, + 0x00010116, + 0x00010117, + 0x00010117, + 0x00010118, + 0x00010118, + }, + { + 0x00010119, + 0x00010119, + 0x0001011a, + 0x0001011a, + 0x0001011b, + 0x0001011b, + 0x0001011c, + 0x0001011c, + 0x0001011d, + 0x0001011d, + 0x0001011e, + 0x0001011e, + 0x0001011f, + 0x0001011f, + 0x00010120, + 0x00010120, + }, + { + 0x00010121, + 0x00010121, + 0x00010122, + 0x00010122, + 0x00010123, + 0x00010123, + 0x00010124, + 0x00010124, + 0x00010125, + 0x00010125, + 0x00010126, + 0x00010126, + 0x00010127, + 0x00010127, + 0x00010128, + 0x00010128, + }, + { + 0x00010129, + 0x00010129, + 0x0001012a, + 0x0001012a, + 0x0001012b, + 0x0001012b, + 0x0001012c, + 0x0001012c, + 0x0001012d, + 0x0001012d, + 0x0001012e, + 0x0001012e, + 0x0001012f, + 0x0001012f, + 0x00010130, + 0x00010130, + }, + { + 0x00010131, + 0x00010131, + 0x00010132, + 0x00010132, + 0x00010133, + 0x00010133, + 0x00010134, + 0x00010134, + 0x00010135, + 0x00010135, + 0x00010136, + 0x00010136, + 0x00010137, + 0x00010137, + 0x00010138, + 0x00010138, + }, + { + 0x00010139, + 0x00010139, + 0x0001013a, + 0x0001013a, + 0x0001013b, + 0x0001013b, + 0x0001013c, + 0x0001013c, + 0x0001013d, + 0x0001013d, + 0x0001013e, + 0x0001013e, + 0x0001013f, + 0x0001013f, + 0x00010140, + 0x00010140, + }, + { + 0x00010141, + 0x00010141, + 0x00010142, + 0x00010142, + 0x00010143, + 0x00010143, + 0x00010144, + 0x00010144, + 0x00010145, + 0x00010145, + 0x00010146, + 0x00010146, + 0x00010147, + 0x00010147, + 0x00010148, + 0x00010148, + }, + { + 0x00010149, + 0x00010149, + 0x0001014a, + 0x0001014a, + 0x0001014b, + 0x0001014b, + 0x0001014c, + 0x0001014c, + 0x0001014d, + 0x0001014d, + 0x0001014e, + 0x0001014e, + 0x0001014f, + 0x0001014f, + 0x00010150, + 0x00010150, + }, + { + 0x00010151, + 0x00010151, + 0x00010152, + 0x00010152, + 0x00010153, + 0x00010153, + 0x00010154, + 0x00010154, + 0x00010155, + 0x00010155, + 0x00010156, + 0x00010156, + 0x00010157, + 0x00010157, + 0x00010158, + 0x00010158, + }, + { + 0x00010159, + 0x00010159, + 0x0001015a, + 0x0001015a, + 0x0001015b, + 0x0001015b, + 0x0001015c, + 0x0001015c, + 0x0001015d, + 0x0001015d, + 0x0001015e, + 0x0001015e, + 0x0001015f, + 0x0001015f, + 0x00010160, + 0x00010160, + }, + { + 0x00010161, + 0x00010161, + 0x00010162, + 0x00010162, + 0x00010163, + 0x00010163, + 0x00010164, + 0x00010164, + 0x00010165, + 0x00010165, + 0x00010166, + 0x00010166, + 0x00010167, + 0x00010167, + 0x00010168, + 0x00010168, + }, + { + 0x00010169, + 0x00010169, + 0x0001016a, + 0x0001016a, + 0x0001016b, + 0x0001016b, + 0x0001016c, + 0x0001016c, + 0x0001016d, + 0x0001016d, + 0x0001016e, + 0x0001016e, + 0x0001016f, + 0x0001016f, + 0x00010170, + 0x00010170, + }, + { + 0x00010171, + 0x00010171, + 0x00010172, + 0x00010172, + 0x00010173, + 0x00010173, + 0x00010174, + 0x00010174, + 0x00010175, + 0x00010175, + 0x00010176, + 0x00010176, + 0x00010177, + 0x00010177, + 0x00010178, + 0x00010178, + }, + { + 0x00010179, + 0x00010179, + 0x0001017a, + 0x0001017a, + 0x0001017b, + 0x0001017b, + 0x0001017c, + 0x0001017c, + 0x0001017d, + 0x0001017d, + 0x0001017e, + 0x0001017e, + 0x0001017f, + 0x0001017f, + 0x00010180, + 0x00010180, + }, + { + 0x00010181, + 0x00010181, + 0x00010182, + 0x00010182, + 0x00010183, + 0x00010183, + 0x00010184, + 0x00010184, + 0x00010185, + 0x00010185, + 0x00010186, + 0x00010186, + 0x00010187, + 0x00010187, + 0x00010188, + 0x00010188, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc47[576][2] = +#else +const uint16_t c_aauiCQMFHuffEnc47[576][2] = +#endif + { + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0004 }, + { 0x0008, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x000b }, + { 0x000d, 0x000d }, + { 0x0010, 0x0041 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000d, 0x000e }, + { 0x000f, 0x0025 }, + { 0x000f, 0x0026 }, + { 0x0012, 0x00f6 }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0005, 0x0006 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0009, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000d, 0x000f }, + { 0x000f, 0x0027 }, + { 0x0012, 0x00f7 }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0007, 0x0006 }, + { 0x0009, 0x0008 }, + { 0x000a, 0x0008 }, + { 0x000c, 0x000c }, + { 0x000e, 0x0017 }, + { 0x0010, 0x0042 }, + { 0x0012, 0x00f8 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0008, 0x0008 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0009 }, + { 0x000a, 0x0009 }, + { 0x000b, 0x0009 }, + { 0x000d, 0x0010 }, + { 0x000f, 0x0028 }, + { 0x000f, 0x0029 }, + { 0x0011, 0x007f }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x000a, 0x000a }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x000a, 0x000b }, + { 0x000b, 0x000a }, + { 0x000d, 0x0011 }, + { 0x000f, 0x002a }, + { 0x0010, 0x0043 }, + { 0x0012, 0x00f9 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000c, 0x000d }, + { 0x000d, 0x0012 }, + { 0x000e, 0x0018 }, + { 0x0010, 0x0044 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x000e, 0x0019 }, + { 0x000d, 0x0013 }, + { 0x000d, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x000f, 0x002b }, + { 0x0010, 0x0045 }, + { 0x0013, 0x0066 }, + { 0x0012, 0x00fa }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0010, 0x0046 }, + { 0x000f, 0x002c }, + { 0x000f, 0x002d }, + { 0x0010, 0x0047 }, + { 0x0011, 0x0080 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0010, 0x0048 }, + { 0x0010, 0x0049 }, + { 0x0011, 0x0081 }, + { 0x0013, 0x008b }, + { 0x0012, 0x00fb }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0012, 0x00fc }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0013, 0x00a9 }, + { 0x0013, 0x00aa }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0013, 0x00c1 }, + { 0x0013, 0x00c2 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + { 0x0013, 0x0114 }, + { 0x0013, 0x0115 }, + { 0x0013, 0x0116 }, + { 0x0013, 0x0117 }, + { 0x0013, 0x0118 }, + { 0x0013, 0x0119 }, + { 0x0013, 0x011a }, + { 0x0013, 0x011b }, + { 0x0013, 0x011c }, + { 0x0013, 0x011d }, + { 0x0013, 0x011e }, + { 0x0013, 0x011f }, + { 0x0013, 0x0120 }, + { 0x0013, 0x0121 }, + { 0x0013, 0x0122 }, + { 0x0013, 0x0123 }, + { 0x0013, 0x0124 }, + { 0x0013, 0x0125 }, + { 0x0013, 0x0126 }, + { 0x0013, 0x0127 }, + { 0x0013, 0x0128 }, + { 0x0013, 0x0129 }, + { 0x0013, 0x012a }, + { 0x0013, 0x012b }, + { 0x0013, 0x012c }, + { 0x0013, 0x012d }, + { 0x0013, 0x012e }, + { 0x0013, 0x012f }, + { 0x0013, 0x0130 }, + { 0x0013, 0x0131 }, + { 0x0013, 0x0132 }, + { 0x0013, 0x0133 }, + { 0x0013, 0x0134 }, + { 0x0013, 0x0135 }, + { 0x0013, 0x0136 }, + { 0x0013, 0x0137 }, + { 0x0013, 0x0138 }, + { 0x0013, 0x0139 }, + { 0x0013, 0x013a }, + { 0x0013, 0x013b }, + { 0x0013, 0x013c }, + { 0x0013, 0x013d }, + { 0x0013, 0x013e }, + { 0x0013, 0x013f }, + { 0x0013, 0x0140 }, + { 0x0013, 0x0141 }, + { 0x0013, 0x0142 }, + { 0x0013, 0x0143 }, + { 0x0013, 0x0144 }, + { 0x0013, 0x0145 }, + { 0x0013, 0x0146 }, + { 0x0013, 0x0147 }, + { 0x0013, 0x0148 }, + { 0x0013, 0x0149 }, + { 0x0013, 0x014a }, + { 0x0013, 0x014b }, + { 0x0013, 0x014c }, + { 0x0013, 0x014d }, + { 0x0013, 0x014e }, + { 0x0013, 0x014f }, + { 0x0013, 0x0150 }, + { 0x0013, 0x0151 }, + { 0x0013, 0x0152 }, + { 0x0013, 0x0153 }, + { 0x0013, 0x0154 }, + { 0x0013, 0x0155 }, + { 0x0013, 0x0156 }, + { 0x0013, 0x0157 }, + { 0x0013, 0x0158 }, + { 0x0013, 0x0159 }, + { 0x0013, 0x015a }, + { 0x0013, 0x015b }, + { 0x0013, 0x015c }, + { 0x0013, 0x015d }, + { 0x0013, 0x015e }, + { 0x0013, 0x015f }, + { 0x0013, 0x0160 }, + { 0x0013, 0x0161 }, + { 0x0013, 0x0162 }, + { 0x0013, 0x0163 }, + { 0x0013, 0x0164 }, + { 0x0013, 0x0165 }, + { 0x0013, 0x0166 }, + { 0x0013, 0x0167 }, + { 0x0013, 0x0168 }, + { 0x0013, 0x0169 }, + { 0x0013, 0x016a }, + { 0x0013, 0x016b }, + { 0x0013, 0x016c }, + { 0x0013, 0x016d }, + { 0x0013, 0x016e }, + { 0x0013, 0x016f }, + { 0x0013, 0x0170 }, + { 0x0013, 0x0171 }, + { 0x0013, 0x0172 }, + { 0x0013, 0x0173 }, + { 0x0013, 0x0174 }, + { 0x0013, 0x0175 }, + { 0x0013, 0x0176 }, + { 0x0013, 0x0177 }, + { 0x0013, 0x0178 }, + { 0x0013, 0x0179 }, + { 0x0013, 0x017a }, + { 0x0013, 0x017b }, + { 0x0013, 0x017c }, + { 0x0013, 0x017d }, + { 0x0013, 0x017e }, + { 0x0013, 0x017f }, + { 0x0013, 0x0180 }, + { 0x0013, 0x0181 }, + { 0x0013, 0x0182 }, + { 0x0013, 0x0183 }, + { 0x0013, 0x0184 }, + { 0x0013, 0x0185 }, + { 0x0013, 0x0186 }, + { 0x0013, 0x0187 }, + { 0x0013, 0x0188 }, + { 0x0013, 0x0189 }, + { 0x0013, 0x018a }, + { 0x0013, 0x018b }, + { 0x0013, 0x018c }, + { 0x0013, 0x018d }, + { 0x0013, 0x018e }, + { 0x0013, 0x018f }, + { 0x0013, 0x0190 }, + { 0x0013, 0x0191 }, + { 0x0013, 0x0192 }, + { 0x0013, 0x0193 }, + { 0x0013, 0x0194 }, + { 0x0013, 0x0195 }, + { 0x0013, 0x0196 }, + { 0x0013, 0x0197 }, + { 0x0013, 0x0198 }, + { 0x0013, 0x0199 }, + { 0x0013, 0x019a }, + { 0x0013, 0x019b }, + { 0x0013, 0x019c }, + { 0x0013, 0x019d }, + { 0x0013, 0x019e }, + { 0x0013, 0x019f }, + { 0x0013, 0x01a0 }, + { 0x0013, 0x01a1 }, + { 0x0013, 0x01a2 }, + { 0x0013, 0x01a3 }, + { 0x0013, 0x01a4 }, + { 0x0013, 0x01a5 }, + { 0x0013, 0x01a6 }, + { 0x0013, 0x01a7 }, + { 0x0013, 0x01a8 }, + { 0x0013, 0x01a9 }, + { 0x0013, 0x01aa }, + { 0x0013, 0x01ab }, + { 0x0013, 0x01ac }, + { 0x0013, 0x01ad }, + { 0x0013, 0x01ae }, + { 0x0013, 0x01af }, + { 0x0013, 0x01b0 }, + { 0x0013, 0x01b1 }, + { 0x0013, 0x01b2 }, + { 0x0013, 0x01b3 }, + { 0x0013, 0x01b4 }, + { 0x0013, 0x01b5 }, + { 0x0013, 0x01b6 }, + { 0x0013, 0x01b7 }, + { 0x0013, 0x01b8 }, + { 0x0013, 0x01b9 }, + { 0x0013, 0x01ba }, + { 0x0013, 0x01bb }, + { 0x0013, 0x01bc }, + { 0x0013, 0x01bd }, + { 0x0013, 0x01be }, + { 0x0013, 0x01bf }, + { 0x0013, 0x01c0 }, + { 0x0013, 0x01c1 }, + { 0x0013, 0x01c2 }, + { 0x0013, 0x01c3 }, + { 0x0013, 0x01c4 }, + { 0x0013, 0x01c5 }, + { 0x0013, 0x01c6 }, + { 0x0013, 0x01c7 }, + { 0x0013, 0x01c8 }, + { 0x0013, 0x01c9 }, + { 0x0013, 0x01ca }, + { 0x0013, 0x01cb }, + { 0x0013, 0x01cc }, + { 0x0013, 0x01cd }, + { 0x0013, 0x01ce }, + { 0x0013, 0x01cf }, + { 0x0013, 0x01d0 }, + { 0x0013, 0x01d1 }, + { 0x0013, 0x01d2 }, + { 0x0013, 0x01d3 }, + { 0x0013, 0x01d4 }, + { 0x0013, 0x01d5 }, + { 0x0013, 0x01d6 }, + { 0x0013, 0x01d7 }, + { 0x0013, 0x01d8 }, + { 0x0013, 0x01d9 }, + { 0x0013, 0x01da }, + { 0x0013, 0x01db }, + { 0x0013, 0x01dc }, + { 0x0013, 0x01dd }, + { 0x0013, 0x01de }, + { 0x0013, 0x01df }, + { 0x0013, 0x01e0 }, + { 0x0013, 0x01e1 }, + { 0x0013, 0x01e2 }, + { 0x0013, 0x01e3 }, + { 0x0013, 0x01e4 }, + { 0x0013, 0x01e5 }, + { 0x0013, 0x01e6 }, + { 0x0013, 0x01e7 }, + { 0x0013, 0x01e8 }, + { 0x0013, 0x01e9 }, + { 0x0013, 0x01ea }, + { 0x0013, 0x01eb }, + { 0x0012, 0x00fd }, + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec47[87][16] = { + { + 0x0004ffff, + 0x0003ffff, + 0x0001ffff, + 0x0002ffff, + 0x0000001a, + 0x00000031, + 0x00010001, + 0x00010001, + 0x00010018, + 0x00010018, + 0x00010019, + 0x00010019, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + }, + { + 0x00020049, + 0x00020049, + 0x00020049, + 0x00020049, + 0x0002004a, + 0x0002004a, + 0x0002004a, + 0x0002004a, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + }, + { + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + }, + { + 0x00020003, + 0x00020003, + 0x00020003, + 0x00020003, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x00020033, + 0x00020033, + 0x00020033, + 0x00020033, + 0x00020048, + 0x00020048, + 0x00020048, + 0x00020048, + }, + { + 0x000affff, + 0x0008ffff, + 0x0009ffff, + 0x0005ffff, + 0x0006ffff, + 0x0007ffff, + 0x00000004, + 0x00000034, + 0x00000060, + 0x00000062, + 0x0001001c, + 0x0001001c, + 0x0001004b, + 0x0001004b, + 0x00010061, + 0x00010061, + }, + { + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + }, + { + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x00030063, + 0x00030063, + 0x00030063, + 0x00030063, + 0x00030063, + 0x00030063, + 0x00030063, + 0x00030063, + }, + { + 0x00030079, + 0x00030079, + 0x00030079, + 0x00030079, + 0x00030079, + 0x00030079, + 0x00030079, + 0x00030079, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + 0x0003007a, + }, + { + 0x00010036, + 0x00010036, + 0x00010065, + 0x00010065, + 0x0001007c, + 0x0001007c, + 0x00010090, + 0x00010090, + 0x00010091, + 0x00010091, + 0x00010092, + 0x00010092, + 0x00020005, + 0x00020005, + 0x00020005, + 0x00020005, + }, + { + 0x0002004d, + 0x0002004d, + 0x0002004d, + 0x0002004d, + 0x00020064, + 0x00020064, + 0x00020064, + 0x00020064, + 0x00020078, + 0x00020078, + 0x00020078, + 0x00020078, + 0x0002007b, + 0x0002007b, + 0x0002007b, + 0x0002007b, + }, + { + 0x0017ffff, + 0x0028ffff, + 0x0039ffff, + 0x0012ffff, + 0x0011ffff, + 0x0010ffff, + 0x000bffff, + 0x000cffff, + 0x000dffff, + 0x000effff, + 0x000fffff, + 0x00000006, + 0x0000004e, + 0x00000093, + 0x0001001e, + 0x0001001e, + }, + { + 0x00020095, + 0x00020095, + 0x00020095, + 0x00020095, + 0x000200a8, + 0x000200a8, + 0x000200a8, + 0x000200a8, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + }, + { + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + }, + { + 0x00030066, + 0x00030066, + 0x00030066, + 0x00030066, + 0x00030066, + 0x00030066, + 0x00030066, + 0x00030066, + 0x0003007d, + 0x0003007d, + 0x0003007d, + 0x0003007d, + 0x0003007d, + 0x0003007d, + 0x0003007d, + 0x0003007d, + }, + { + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + 0x00030094, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + }, + { + 0x000300aa, + 0x000300aa, + 0x000300aa, + 0x000300aa, + 0x000300aa, + 0x000300aa, + 0x000300aa, + 0x000300aa, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + }, + { + 0x00010067, + 0x00010067, + 0x00010068, + 0x00010068, + 0x0001007e, + 0x0001007e, + 0x000100ac, + 0x000100ac, + 0x000100c1, + 0x000100c1, + 0x000100c2, + 0x000100c2, + 0x0002004f, + 0x0002004f, + 0x0002004f, + 0x0002004f, + }, + { + 0x0014ffff, + 0x00000008, + 0x00000050, + 0x0000007f, + 0x00000096, + 0x000000ad, + 0x000000c0, + 0x000000c3, + 0x000000d9, + 0x000000da, + 0x00010020, + 0x00010020, + 0x00010021, + 0x00010021, + 0x00010038, + 0x00010038, + }, + { + 0x004affff, + 0x004bffff, + 0x004cffff, + 0x004dffff, + 0x004effff, + 0x004fffff, + 0x0050ffff, + 0x0051ffff, + 0x0052ffff, + 0x0053ffff, + 0x0054ffff, + 0x0055ffff, + 0x0056ffff, + 0x0016ffff, + 0x0015ffff, + 0x0013ffff, + }, + { + 0x000200f3, + 0x000200f3, + 0x000200f3, + 0x000200f3, + 0x0002023f, + 0x0002023f, + 0x0002023f, + 0x0002023f, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + 0x00030069, + }, + { + 0x000300c4, + 0x000300c4, + 0x000300c4, + 0x000300c4, + 0x000300c4, + 0x000300c4, + 0x000300c4, + 0x000300c4, + 0x000300db, + 0x000300db, + 0x000300db, + 0x000300db, + 0x000300db, + 0x000300db, + 0x000300db, + 0x000300db, + }, + { + 0x00020051, + 0x00020051, + 0x00020051, + 0x00020051, + 0x00020080, + 0x00020080, + 0x00020080, + 0x00020080, + 0x000200af, + 0x000200af, + 0x000200af, + 0x000200af, + 0x000200dd, + 0x000200dd, + 0x000200dd, + 0x000200dd, + }, + { + 0x0001023b, + 0x0001023b, + 0x0001023c, + 0x0001023c, + 0x0001023d, + 0x0001023d, + 0x0001023e, + 0x0001023e, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020039, + 0x00020039, + 0x00020039, + 0x00020039, + }, + { + 0x001bffff, + 0x001affff, + 0x001dffff, + 0x001cffff, + 0x0020ffff, + 0x0018ffff, + 0x0019ffff, + 0x001effff, + 0x001fffff, + 0x0021ffff, + 0x0022ffff, + 0x0023ffff, + 0x0024ffff, + 0x0025ffff, + 0x0026ffff, + 0x0027ffff, + }, + { + 0x00010046, + 0x00010046, + 0x00010047, + 0x00010047, + 0x00010052, + 0x00010052, + 0x00010053, + 0x00010053, + 0x00010054, + 0x00010054, + 0x00010055, + 0x00010055, + 0x00010056, + 0x00010056, + 0x00010057, + 0x00010057, + }, + { + 0x00010058, + 0x00010058, + 0x00010059, + 0x00010059, + 0x0001005a, + 0x0001005a, + 0x0001005b, + 0x0001005b, + 0x0001005c, + 0x0001005c, + 0x0001005d, + 0x0001005d, + 0x0001005e, + 0x0001005e, + 0x0001005f, + 0x0001005f, + }, + { + 0x00010011, + 0x00010011, + 0x00010012, + 0x00010012, + 0x00010013, + 0x00010013, + 0x00010014, + 0x00010014, + 0x00010015, + 0x00010015, + 0x00010016, + 0x00010016, + 0x00010017, + 0x00010017, + 0x00010023, + 0x00010023, + }, + { + 0x00010009, + 0x00010009, + 0x0001000a, + 0x0001000a, + 0x0001000b, + 0x0001000b, + 0x0001000c, + 0x0001000c, + 0x0001000d, + 0x0001000d, + 0x0001000e, + 0x0001000e, + 0x0001000f, + 0x0001000f, + 0x00010010, + 0x00010010, + }, + { + 0x0001002c, + 0x0001002c, + 0x0001002d, + 0x0001002d, + 0x0001002e, + 0x0001002e, + 0x0001002f, + 0x0001002f, + 0x0001003a, + 0x0001003a, + 0x0001003b, + 0x0001003b, + 0x0001003c, + 0x0001003c, + 0x0001003d, + 0x0001003d, + }, + { + 0x00010024, + 0x00010024, + 0x00010025, + 0x00010025, + 0x00010026, + 0x00010026, + 0x00010027, + 0x00010027, + 0x00010028, + 0x00010028, + 0x00010029, + 0x00010029, + 0x0001002a, + 0x0001002a, + 0x0001002b, + 0x0001002b, + }, + { + 0x0001006a, + 0x0001006a, + 0x0001006b, + 0x0001006b, + 0x0001006c, + 0x0001006c, + 0x0001006d, + 0x0001006d, + 0x0001006e, + 0x0001006e, + 0x0001006f, + 0x0001006f, + 0x00010070, + 0x00010070, + 0x00010071, + 0x00010071, + }, + { + 0x00010072, + 0x00010072, + 0x00010073, + 0x00010073, + 0x00010074, + 0x00010074, + 0x00010075, + 0x00010075, + 0x00010076, + 0x00010076, + 0x00010077, + 0x00010077, + 0x00010081, + 0x00010081, + 0x00010082, + 0x00010082, + }, + { + 0x0001003e, + 0x0001003e, + 0x0001003f, + 0x0001003f, + 0x00010040, + 0x00010040, + 0x00010041, + 0x00010041, + 0x00010042, + 0x00010042, + 0x00010043, + 0x00010043, + 0x00010044, + 0x00010044, + 0x00010045, + 0x00010045, + }, + { + 0x00010083, + 0x00010083, + 0x00010084, + 0x00010084, + 0x00010085, + 0x00010085, + 0x00010086, + 0x00010086, + 0x00010087, + 0x00010087, + 0x00010088, + 0x00010088, + 0x00010089, + 0x00010089, + 0x0001008a, + 0x0001008a, + }, + { + 0x0001008b, + 0x0001008b, + 0x0001008c, + 0x0001008c, + 0x0001008d, + 0x0001008d, + 0x0001008e, + 0x0001008e, + 0x0001008f, + 0x0001008f, + 0x00010097, + 0x00010097, + 0x00010098, + 0x00010098, + 0x00010099, + 0x00010099, + }, + { + 0x0001009a, + 0x0001009a, + 0x0001009b, + 0x0001009b, + 0x0001009c, + 0x0001009c, + 0x0001009d, + 0x0001009d, + 0x0001009e, + 0x0001009e, + 0x0001009f, + 0x0001009f, + 0x000100a0, + 0x000100a0, + 0x000100a1, + 0x000100a1, + }, + { + 0x000100a2, + 0x000100a2, + 0x000100a3, + 0x000100a3, + 0x000100a4, + 0x000100a4, + 0x000100a5, + 0x000100a5, + 0x000100a6, + 0x000100a6, + 0x000100a7, + 0x000100a7, + 0x000100ae, + 0x000100ae, + 0x000100b0, + 0x000100b0, + }, + { + 0x000100b1, + 0x000100b1, + 0x000100b2, + 0x000100b2, + 0x000100b3, + 0x000100b3, + 0x000100b4, + 0x000100b4, + 0x000100b5, + 0x000100b5, + 0x000100b6, + 0x000100b6, + 0x000100b7, + 0x000100b7, + 0x000100b8, + 0x000100b8, + }, + { + 0x000100b9, + 0x000100b9, + 0x000100ba, + 0x000100ba, + 0x000100bb, + 0x000100bb, + 0x000100bc, + 0x000100bc, + 0x000100bd, + 0x000100bd, + 0x000100be, + 0x000100be, + 0x000100bf, + 0x000100bf, + 0x000100c5, + 0x000100c5, + }, + { + 0x000100c6, + 0x000100c6, + 0x000100c7, + 0x000100c7, + 0x000100c8, + 0x000100c8, + 0x000100c9, + 0x000100c9, + 0x000100ca, + 0x000100ca, + 0x000100cb, + 0x000100cb, + 0x000100cc, + 0x000100cc, + 0x000100cd, + 0x000100cd, + }, + { + 0x0029ffff, + 0x002affff, + 0x002bffff, + 0x002cffff, + 0x002dffff, + 0x002effff, + 0x002fffff, + 0x0030ffff, + 0x0031ffff, + 0x0032ffff, + 0x0033ffff, + 0x0034ffff, + 0x0035ffff, + 0x0036ffff, + 0x0037ffff, + 0x0038ffff, + }, + { + 0x000100ce, + 0x000100ce, + 0x000100cf, + 0x000100cf, + 0x000100d0, + 0x000100d0, + 0x000100d1, + 0x000100d1, + 0x000100d2, + 0x000100d2, + 0x000100d3, + 0x000100d3, + 0x000100d4, + 0x000100d4, + 0x000100d5, + 0x000100d5, + }, + { + 0x000100d6, + 0x000100d6, + 0x000100d7, + 0x000100d7, + 0x000100d8, + 0x000100d8, + 0x000100dc, + 0x000100dc, + 0x000100de, + 0x000100de, + 0x000100df, + 0x000100df, + 0x000100e0, + 0x000100e0, + 0x000100e1, + 0x000100e1, + }, + { + 0x000100e2, + 0x000100e2, + 0x000100e3, + 0x000100e3, + 0x000100e4, + 0x000100e4, + 0x000100e5, + 0x000100e5, + 0x000100e6, + 0x000100e6, + 0x000100e7, + 0x000100e7, + 0x000100e8, + 0x000100e8, + 0x000100e9, + 0x000100e9, + }, + { + 0x000100ea, + 0x000100ea, + 0x000100eb, + 0x000100eb, + 0x000100ec, + 0x000100ec, + 0x000100ed, + 0x000100ed, + 0x000100ee, + 0x000100ee, + 0x000100ef, + 0x000100ef, + 0x000100f0, + 0x000100f0, + 0x000100f1, + 0x000100f1, + }, + { + 0x000100f2, + 0x000100f2, + 0x000100f4, + 0x000100f4, + 0x000100f5, + 0x000100f5, + 0x000100f6, + 0x000100f6, + 0x000100f7, + 0x000100f7, + 0x000100f8, + 0x000100f8, + 0x000100f9, + 0x000100f9, + 0x000100fa, + 0x000100fa, + }, + { + 0x000100fb, + 0x000100fb, + 0x000100fc, + 0x000100fc, + 0x000100fd, + 0x000100fd, + 0x000100fe, + 0x000100fe, + 0x000100ff, + 0x000100ff, + 0x00010100, + 0x00010100, + 0x00010101, + 0x00010101, + 0x00010102, + 0x00010102, + }, + { + 0x00010103, + 0x00010103, + 0x00010104, + 0x00010104, + 0x00010105, + 0x00010105, + 0x00010106, + 0x00010106, + 0x00010107, + 0x00010107, + 0x00010108, + 0x00010108, + 0x00010109, + 0x00010109, + 0x0001010a, + 0x0001010a, + }, + { + 0x0001010b, + 0x0001010b, + 0x0001010c, + 0x0001010c, + 0x0001010d, + 0x0001010d, + 0x0001010e, + 0x0001010e, + 0x0001010f, + 0x0001010f, + 0x00010110, + 0x00010110, + 0x00010111, + 0x00010111, + 0x00010112, + 0x00010112, + }, + { + 0x00010113, + 0x00010113, + 0x00010114, + 0x00010114, + 0x00010115, + 0x00010115, + 0x00010116, + 0x00010116, + 0x00010117, + 0x00010117, + 0x00010118, + 0x00010118, + 0x00010119, + 0x00010119, + 0x0001011a, + 0x0001011a, + }, + { + 0x0001011b, + 0x0001011b, + 0x0001011c, + 0x0001011c, + 0x0001011d, + 0x0001011d, + 0x0001011e, + 0x0001011e, + 0x0001011f, + 0x0001011f, + 0x00010120, + 0x00010120, + 0x00010121, + 0x00010121, + 0x00010122, + 0x00010122, + }, + { + 0x00010123, + 0x00010123, + 0x00010124, + 0x00010124, + 0x00010125, + 0x00010125, + 0x00010126, + 0x00010126, + 0x00010127, + 0x00010127, + 0x00010128, + 0x00010128, + 0x00010129, + 0x00010129, + 0x0001012a, + 0x0001012a, + }, + { + 0x0001012b, + 0x0001012b, + 0x0001012c, + 0x0001012c, + 0x0001012d, + 0x0001012d, + 0x0001012e, + 0x0001012e, + 0x0001012f, + 0x0001012f, + 0x00010130, + 0x00010130, + 0x00010131, + 0x00010131, + 0x00010132, + 0x00010132, + }, + { + 0x00010133, + 0x00010133, + 0x00010134, + 0x00010134, + 0x00010135, + 0x00010135, + 0x00010136, + 0x00010136, + 0x00010137, + 0x00010137, + 0x00010138, + 0x00010138, + 0x00010139, + 0x00010139, + 0x0001013a, + 0x0001013a, + }, + { + 0x0001013b, + 0x0001013b, + 0x0001013c, + 0x0001013c, + 0x0001013d, + 0x0001013d, + 0x0001013e, + 0x0001013e, + 0x0001013f, + 0x0001013f, + 0x00010140, + 0x00010140, + 0x00010141, + 0x00010141, + 0x00010142, + 0x00010142, + }, + { + 0x00010143, + 0x00010143, + 0x00010144, + 0x00010144, + 0x00010145, + 0x00010145, + 0x00010146, + 0x00010146, + 0x00010147, + 0x00010147, + 0x00010148, + 0x00010148, + 0x00010149, + 0x00010149, + 0x0001014a, + 0x0001014a, + }, + { + 0x0001014b, + 0x0001014b, + 0x0001014c, + 0x0001014c, + 0x0001014d, + 0x0001014d, + 0x0001014e, + 0x0001014e, + 0x0001014f, + 0x0001014f, + 0x00010150, + 0x00010150, + 0x00010151, + 0x00010151, + 0x00010152, + 0x00010152, + }, + { + 0x003affff, + 0x003bffff, + 0x003cffff, + 0x003dffff, + 0x003effff, + 0x003fffff, + 0x0040ffff, + 0x0041ffff, + 0x0042ffff, + 0x0043ffff, + 0x0044ffff, + 0x0045ffff, + 0x0046ffff, + 0x0047ffff, + 0x0048ffff, + 0x0049ffff, + }, + { + 0x00010153, + 0x00010153, + 0x00010154, + 0x00010154, + 0x00010155, + 0x00010155, + 0x00010156, + 0x00010156, + 0x00010157, + 0x00010157, + 0x00010158, + 0x00010158, + 0x00010159, + 0x00010159, + 0x0001015a, + 0x0001015a, + }, + { + 0x0001015b, + 0x0001015b, + 0x0001015c, + 0x0001015c, + 0x0001015d, + 0x0001015d, + 0x0001015e, + 0x0001015e, + 0x0001015f, + 0x0001015f, + 0x00010160, + 0x00010160, + 0x00010161, + 0x00010161, + 0x00010162, + 0x00010162, + }, + { + 0x00010163, + 0x00010163, + 0x00010164, + 0x00010164, + 0x00010165, + 0x00010165, + 0x00010166, + 0x00010166, + 0x00010167, + 0x00010167, + 0x00010168, + 0x00010168, + 0x00010169, + 0x00010169, + 0x0001016a, + 0x0001016a, + }, + { + 0x0001016b, + 0x0001016b, + 0x0001016c, + 0x0001016c, + 0x0001016d, + 0x0001016d, + 0x0001016e, + 0x0001016e, + 0x0001016f, + 0x0001016f, + 0x00010170, + 0x00010170, + 0x00010171, + 0x00010171, + 0x00010172, + 0x00010172, + }, + { + 0x00010173, + 0x00010173, + 0x00010174, + 0x00010174, + 0x00010175, + 0x00010175, + 0x00010176, + 0x00010176, + 0x00010177, + 0x00010177, + 0x00010178, + 0x00010178, + 0x00010179, + 0x00010179, + 0x0001017a, + 0x0001017a, + }, + { + 0x0001017b, + 0x0001017b, + 0x0001017c, + 0x0001017c, + 0x0001017d, + 0x0001017d, + 0x0001017e, + 0x0001017e, + 0x0001017f, + 0x0001017f, + 0x00010180, + 0x00010180, + 0x00010181, + 0x00010181, + 0x00010182, + 0x00010182, + }, + { + 0x00010183, + 0x00010183, + 0x00010184, + 0x00010184, + 0x00010185, + 0x00010185, + 0x00010186, + 0x00010186, + 0x00010187, + 0x00010187, + 0x00010188, + 0x00010188, + 0x00010189, + 0x00010189, + 0x0001018a, + 0x0001018a, + }, + { + 0x0001018b, + 0x0001018b, + 0x0001018c, + 0x0001018c, + 0x0001018d, + 0x0001018d, + 0x0001018e, + 0x0001018e, + 0x0001018f, + 0x0001018f, + 0x00010190, + 0x00010190, + 0x00010191, + 0x00010191, + 0x00010192, + 0x00010192, + }, + { + 0x00010193, + 0x00010193, + 0x00010194, + 0x00010194, + 0x00010195, + 0x00010195, + 0x00010196, + 0x00010196, + 0x00010197, + 0x00010197, + 0x00010198, + 0x00010198, + 0x00010199, + 0x00010199, + 0x0001019a, + 0x0001019a, + }, + { + 0x0001019b, + 0x0001019b, + 0x0001019c, + 0x0001019c, + 0x0001019d, + 0x0001019d, + 0x0001019e, + 0x0001019e, + 0x0001019f, + 0x0001019f, + 0x000101a0, + 0x000101a0, + 0x000101a1, + 0x000101a1, + 0x000101a2, + 0x000101a2, + }, + { + 0x000101a3, + 0x000101a3, + 0x000101a4, + 0x000101a4, + 0x000101a5, + 0x000101a5, + 0x000101a6, + 0x000101a6, + 0x000101a7, + 0x000101a7, + 0x000101a8, + 0x000101a8, + 0x000101a9, + 0x000101a9, + 0x000101aa, + 0x000101aa, + }, + { + 0x000101ab, + 0x000101ab, + 0x000101ac, + 0x000101ac, + 0x000101ad, + 0x000101ad, + 0x000101ae, + 0x000101ae, + 0x000101af, + 0x000101af, + 0x000101b0, + 0x000101b0, + 0x000101b1, + 0x000101b1, + 0x000101b2, + 0x000101b2, + }, + { + 0x000101b3, + 0x000101b3, + 0x000101b4, + 0x000101b4, + 0x000101b5, + 0x000101b5, + 0x000101b6, + 0x000101b6, + 0x000101b7, + 0x000101b7, + 0x000101b8, + 0x000101b8, + 0x000101b9, + 0x000101b9, + 0x000101ba, + 0x000101ba, + }, + { + 0x000101bb, + 0x000101bb, + 0x000101bc, + 0x000101bc, + 0x000101bd, + 0x000101bd, + 0x000101be, + 0x000101be, + 0x000101bf, + 0x000101bf, + 0x000101c0, + 0x000101c0, + 0x000101c1, + 0x000101c1, + 0x000101c2, + 0x000101c2, + }, + { + 0x000101c3, + 0x000101c3, + 0x000101c4, + 0x000101c4, + 0x000101c5, + 0x000101c5, + 0x000101c6, + 0x000101c6, + 0x000101c7, + 0x000101c7, + 0x000101c8, + 0x000101c8, + 0x000101c9, + 0x000101c9, + 0x000101ca, + 0x000101ca, + }, + { + 0x000101cb, + 0x000101cb, + 0x000101cc, + 0x000101cc, + 0x000101cd, + 0x000101cd, + 0x000101ce, + 0x000101ce, + 0x000101cf, + 0x000101cf, + 0x000101d0, + 0x000101d0, + 0x000101d1, + 0x000101d1, + 0x000101d2, + 0x000101d2, + }, + { + 0x000101d3, + 0x000101d3, + 0x000101d4, + 0x000101d4, + 0x000101d5, + 0x000101d5, + 0x000101d6, + 0x000101d6, + 0x000101d7, + 0x000101d7, + 0x000101d8, + 0x000101d8, + 0x000101d9, + 0x000101d9, + 0x000101da, + 0x000101da, + }, + { + 0x000101db, + 0x000101db, + 0x000101dc, + 0x000101dc, + 0x000101dd, + 0x000101dd, + 0x000101de, + 0x000101de, + 0x000101df, + 0x000101df, + 0x000101e0, + 0x000101e0, + 0x000101e1, + 0x000101e1, + 0x000101e2, + 0x000101e2, + }, + { + 0x000101e3, + 0x000101e3, + 0x000101e4, + 0x000101e4, + 0x000101e5, + 0x000101e5, + 0x000101e6, + 0x000101e6, + 0x000101e7, + 0x000101e7, + 0x000101e8, + 0x000101e8, + 0x000101e9, + 0x000101e9, + 0x000101ea, + 0x000101ea, + }, + { + 0x000101eb, + 0x000101eb, + 0x000101ec, + 0x000101ec, + 0x000101ed, + 0x000101ed, + 0x000101ee, + 0x000101ee, + 0x000101ef, + 0x000101ef, + 0x000101f0, + 0x000101f0, + 0x000101f1, + 0x000101f1, + 0x000101f2, + 0x000101f2, + }, + { + 0x000101f3, + 0x000101f3, + 0x000101f4, + 0x000101f4, + 0x000101f5, + 0x000101f5, + 0x000101f6, + 0x000101f6, + 0x000101f7, + 0x000101f7, + 0x000101f8, + 0x000101f8, + 0x000101f9, + 0x000101f9, + 0x000101fa, + 0x000101fa, + }, + { + 0x000101fb, + 0x000101fb, + 0x000101fc, + 0x000101fc, + 0x000101fd, + 0x000101fd, + 0x000101fe, + 0x000101fe, + 0x000101ff, + 0x000101ff, + 0x00010200, + 0x00010200, + 0x00010201, + 0x00010201, + 0x00010202, + 0x00010202, + }, + { + 0x00010203, + 0x00010203, + 0x00010204, + 0x00010204, + 0x00010205, + 0x00010205, + 0x00010206, + 0x00010206, + 0x00010207, + 0x00010207, + 0x00010208, + 0x00010208, + 0x00010209, + 0x00010209, + 0x0001020a, + 0x0001020a, + }, + { + 0x0001020b, + 0x0001020b, + 0x0001020c, + 0x0001020c, + 0x0001020d, + 0x0001020d, + 0x0001020e, + 0x0001020e, + 0x0001020f, + 0x0001020f, + 0x00010210, + 0x00010210, + 0x00010211, + 0x00010211, + 0x00010212, + 0x00010212, + }, + { + 0x00010213, + 0x00010213, + 0x00010214, + 0x00010214, + 0x00010215, + 0x00010215, + 0x00010216, + 0x00010216, + 0x00010217, + 0x00010217, + 0x00010218, + 0x00010218, + 0x00010219, + 0x00010219, + 0x0001021a, + 0x0001021a, + }, + { + 0x0001021b, + 0x0001021b, + 0x0001021c, + 0x0001021c, + 0x0001021d, + 0x0001021d, + 0x0001021e, + 0x0001021e, + 0x0001021f, + 0x0001021f, + 0x00010220, + 0x00010220, + 0x00010221, + 0x00010221, + 0x00010222, + 0x00010222, + }, + { + 0x00010223, + 0x00010223, + 0x00010224, + 0x00010224, + 0x00010225, + 0x00010225, + 0x00010226, + 0x00010226, + 0x00010227, + 0x00010227, + 0x00010228, + 0x00010228, + 0x00010229, + 0x00010229, + 0x0001022a, + 0x0001022a, + }, + { + 0x0001022b, + 0x0001022b, + 0x0001022c, + 0x0001022c, + 0x0001022d, + 0x0001022d, + 0x0001022e, + 0x0001022e, + 0x0001022f, + 0x0001022f, + 0x00010230, + 0x00010230, + 0x00010231, + 0x00010231, + 0x00010232, + 0x00010232, + }, + { + 0x00010233, + 0x00010233, + 0x00010234, + 0x00010234, + 0x00010235, + 0x00010235, + 0x00010236, + 0x00010236, + 0x00010237, + 0x00010237, + 0x00010238, + 0x00010238, + 0x00010239, + 0x00010239, + 0x0001023a, + 0x0001023a, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc48[729][2] = +#else +const uint16_t c_aauiCQMFHuffEnc48[729][2] = +#endif + { + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0006 }, + { 0x0006, 0x0006 }, + { 0x0008, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000b, 0x000b }, + { 0x000c, 0x000d }, + { 0x000f, 0x0030 }, + { 0x0010, 0x0055 }, + { 0x0012, 0x0136 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0007 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000c, 0x000e }, + { 0x000d, 0x0012 }, + { 0x000f, 0x0031 }, + { 0x0011, 0x00a0 }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0005, 0x0008 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0009 }, + { 0x0006, 0x0008 }, + { 0x0007, 0x0008 }, + { 0x0008, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000c, 0x000f }, + { 0x000d, 0x0013 }, + { 0x000f, 0x0032 }, + { 0x0011, 0x00a1 }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0007, 0x0009 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0008 }, + { 0x000b, 0x000c }, + { 0x000d, 0x0014 }, + { 0x000e, 0x001d }, + { 0x000f, 0x0033 }, + { 0x0012, 0x0137 }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0008, 0x000a }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x000b }, + { 0x0009, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000c, 0x0010 }, + { 0x000d, 0x0015 }, + { 0x000f, 0x0034 }, + { 0x0010, 0x0056 }, + { 0x0012, 0x0138 }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0009, 0x000a }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0009, 0x000b }, + { 0x000a, 0x000b }, + { 0x000c, 0x0011 }, + { 0x000d, 0x0016 }, + { 0x000e, 0x001e }, + { 0x0010, 0x0057 }, + { 0x0011, 0x00a2 }, + { 0x0011, 0x00a3 }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x000b, 0x000d }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000b, 0x000e }, + { 0x000c, 0x0012 }, + { 0x000d, 0x0017 }, + { 0x000e, 0x001f }, + { 0x0010, 0x0058 }, + { 0x0012, 0x0139 }, + { 0x0011, 0x00a4 }, + { 0x0012, 0x013a }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x000c, 0x0013 }, + { 0x000b, 0x000f }, + { 0x000c, 0x0014 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x0018 }, + { 0x000e, 0x0020 }, + { 0x000f, 0x0035 }, + { 0x0012, 0x013b }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x000e, 0x0021 }, + { 0x000d, 0x0019 }, + { 0x000e, 0x0022 }, + { 0x000e, 0x0023 }, + { 0x000f, 0x0036 }, + { 0x0010, 0x0059 }, + { 0x0011, 0x00a5 }, + { 0x0013, 0x0083 }, + { 0x0011, 0x00a6 }, + { 0x0012, 0x013c }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0010, 0x005a }, + { 0x000f, 0x0037 }, + { 0x000f, 0x0038 }, + { 0x000f, 0x0039 }, + { 0x0010, 0x005b }, + { 0x0010, 0x005c }, + { 0x0013, 0x0095 }, + { 0x0011, 0x00a7 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0010, 0x005d }, + { 0x0010, 0x005e }, + { 0x0013, 0x00a9 }, + { 0x0010, 0x005f }, + { 0x0013, 0x00aa }, + { 0x0012, 0x013d }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0011, 0x00a8 }, + { 0x0013, 0x00c1 }, + { 0x0011, 0x00a9 }, + { 0x0013, 0x00c2 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0012, 0x013e }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + { 0x0013, 0x0114 }, + { 0x0013, 0x0115 }, + { 0x0013, 0x0116 }, + { 0x0013, 0x0117 }, + { 0x0013, 0x0118 }, + { 0x0013, 0x0119 }, + { 0x0013, 0x011a }, + { 0x0013, 0x011b }, + { 0x0013, 0x011c }, + { 0x0013, 0x011d }, + { 0x0013, 0x011e }, + { 0x0013, 0x011f }, + { 0x0013, 0x0120 }, + { 0x0013, 0x0121 }, + { 0x0013, 0x0122 }, + { 0x0013, 0x0123 }, + { 0x0013, 0x0124 }, + { 0x0013, 0x0125 }, + { 0x0013, 0x0126 }, + { 0x0013, 0x0127 }, + { 0x0013, 0x0128 }, + { 0x0013, 0x0129 }, + { 0x0013, 0x012a }, + { 0x0013, 0x012b }, + { 0x0013, 0x012c }, + { 0x0013, 0x012d }, + { 0x0013, 0x012e }, + { 0x0013, 0x012f }, + { 0x0013, 0x0130 }, + { 0x0013, 0x0131 }, + { 0x0013, 0x0132 }, + { 0x0013, 0x0133 }, + { 0x0013, 0x0134 }, + { 0x0013, 0x0135 }, + { 0x0013, 0x0136 }, + { 0x0013, 0x0137 }, + { 0x0013, 0x0138 }, + { 0x0013, 0x0139 }, + { 0x0013, 0x013a }, + { 0x0013, 0x013b }, + { 0x0013, 0x013c }, + { 0x0013, 0x013d }, + { 0x0013, 0x013e }, + { 0x0013, 0x013f }, + { 0x0013, 0x0140 }, + { 0x0013, 0x0141 }, + { 0x0013, 0x0142 }, + { 0x0013, 0x0143 }, + { 0x0013, 0x0144 }, + { 0x0013, 0x0145 }, + { 0x0013, 0x0146 }, + { 0x0013, 0x0147 }, + { 0x0013, 0x0148 }, + { 0x0013, 0x0149 }, + { 0x0013, 0x014a }, + { 0x0013, 0x014b }, + { 0x0013, 0x014c }, + { 0x0013, 0x014d }, + { 0x0013, 0x014e }, + { 0x0013, 0x014f }, + { 0x0013, 0x0150 }, + { 0x0013, 0x0151 }, + { 0x0013, 0x0152 }, + { 0x0013, 0x0153 }, + { 0x0013, 0x0154 }, + { 0x0013, 0x0155 }, + { 0x0013, 0x0156 }, + { 0x0013, 0x0157 }, + { 0x0013, 0x0158 }, + { 0x0013, 0x0159 }, + { 0x0013, 0x015a }, + { 0x0013, 0x015b }, + { 0x0013, 0x015c }, + { 0x0013, 0x015d }, + { 0x0013, 0x015e }, + { 0x0013, 0x015f }, + { 0x0013, 0x0160 }, + { 0x0013, 0x0161 }, + { 0x0013, 0x0162 }, + { 0x0013, 0x0163 }, + { 0x0013, 0x0164 }, + { 0x0013, 0x0165 }, + { 0x0013, 0x0166 }, + { 0x0013, 0x0167 }, + { 0x0013, 0x0168 }, + { 0x0013, 0x0169 }, + { 0x0013, 0x016a }, + { 0x0013, 0x016b }, + { 0x0013, 0x016c }, + { 0x0013, 0x016d }, + { 0x0013, 0x016e }, + { 0x0013, 0x016f }, + { 0x0013, 0x0170 }, + { 0x0013, 0x0171 }, + { 0x0013, 0x0172 }, + { 0x0013, 0x0173 }, + { 0x0013, 0x0174 }, + { 0x0013, 0x0175 }, + { 0x0013, 0x0176 }, + { 0x0013, 0x0177 }, + { 0x0013, 0x0178 }, + { 0x0013, 0x0179 }, + { 0x0013, 0x017a }, + { 0x0013, 0x017b }, + { 0x0013, 0x017c }, + { 0x0013, 0x017d }, + { 0x0013, 0x017e }, + { 0x0013, 0x017f }, + { 0x0013, 0x0180 }, + { 0x0013, 0x0181 }, + { 0x0013, 0x0182 }, + { 0x0013, 0x0183 }, + { 0x0013, 0x0184 }, + { 0x0013, 0x0185 }, + { 0x0013, 0x0186 }, + { 0x0013, 0x0187 }, + { 0x0013, 0x0188 }, + { 0x0013, 0x0189 }, + { 0x0013, 0x018a }, + { 0x0013, 0x018b }, + { 0x0013, 0x018c }, + { 0x0013, 0x018d }, + { 0x0013, 0x018e }, + { 0x0013, 0x018f }, + { 0x0013, 0x0190 }, + { 0x0013, 0x0191 }, + { 0x0013, 0x0192 }, + { 0x0013, 0x0193 }, + { 0x0013, 0x0194 }, + { 0x0013, 0x0195 }, + { 0x0013, 0x0196 }, + { 0x0013, 0x0197 }, + { 0x0013, 0x0198 }, + { 0x0013, 0x0199 }, + { 0x0013, 0x019a }, + { 0x0013, 0x019b }, + { 0x0013, 0x019c }, + { 0x0013, 0x019d }, + { 0x0013, 0x019e }, + { 0x0013, 0x019f }, + { 0x0013, 0x01a0 }, + { 0x0013, 0x01a1 }, + { 0x0013, 0x01a2 }, + { 0x0013, 0x01a3 }, + { 0x0013, 0x01a4 }, + { 0x0013, 0x01a5 }, + { 0x0013, 0x01a6 }, + { 0x0013, 0x01a7 }, + { 0x0013, 0x01a8 }, + { 0x0013, 0x01a9 }, + { 0x0013, 0x01aa }, + { 0x0013, 0x01ab }, + { 0x0013, 0x01ac }, + { 0x0013, 0x01ad }, + { 0x0013, 0x01ae }, + { 0x0013, 0x01af }, + { 0x0013, 0x01b0 }, + { 0x0013, 0x01b1 }, + { 0x0013, 0x01b2 }, + { 0x0013, 0x01b3 }, + { 0x0013, 0x01b4 }, + { 0x0013, 0x01b5 }, + { 0x0013, 0x01b6 }, + { 0x0013, 0x01b7 }, + { 0x0013, 0x01b8 }, + { 0x0013, 0x01b9 }, + { 0x0013, 0x01ba }, + { 0x0013, 0x01bb }, + { 0x0013, 0x01bc }, + { 0x0013, 0x01bd }, + { 0x0013, 0x01be }, + { 0x0013, 0x01bf }, + { 0x0013, 0x01c0 }, + { 0x0013, 0x01c1 }, + { 0x0013, 0x01c2 }, + { 0x0013, 0x01c3 }, + { 0x0013, 0x01c4 }, + { 0x0013, 0x01c5 }, + { 0x0013, 0x01c6 }, + { 0x0013, 0x01c7 }, + { 0x0013, 0x01c8 }, + { 0x0013, 0x01c9 }, + { 0x0013, 0x01ca }, + { 0x0013, 0x01cb }, + { 0x0013, 0x01cc }, + { 0x0013, 0x01cd }, + { 0x0013, 0x01ce }, + { 0x0013, 0x01cf }, + { 0x0013, 0x01d0 }, + { 0x0013, 0x01d1 }, + { 0x0013, 0x01d2 }, + { 0x0013, 0x01d3 }, + { 0x0013, 0x01d4 }, + { 0x0013, 0x01d5 }, + { 0x0013, 0x01d6 }, + { 0x0013, 0x01d7 }, + { 0x0013, 0x01d8 }, + { 0x0013, 0x01d9 }, + { 0x0013, 0x01da }, + { 0x0013, 0x01db }, + { 0x0013, 0x01dc }, + { 0x0013, 0x01dd }, + { 0x0013, 0x01de }, + { 0x0013, 0x01df }, + { 0x0013, 0x01e0 }, + { 0x0013, 0x01e1 }, + { 0x0013, 0x01e2 }, + { 0x0013, 0x01e3 }, + { 0x0013, 0x01e4 }, + { 0x0013, 0x01e5 }, + { 0x0013, 0x01e6 }, + { 0x0013, 0x01e7 }, + { 0x0013, 0x01e8 }, + { 0x0013, 0x01e9 }, + { 0x0013, 0x01ea }, + { 0x0013, 0x01eb }, + { 0x0013, 0x01ec }, + { 0x0013, 0x01ed }, + { 0x0013, 0x01ee }, + { 0x0013, 0x01ef }, + { 0x0013, 0x01f0 }, + { 0x0013, 0x01f1 }, + { 0x0013, 0x01f2 }, + { 0x0013, 0x01f3 }, + { 0x0013, 0x01f4 }, + { 0x0013, 0x01f5 }, + { 0x0013, 0x01f6 }, + { 0x0013, 0x01f7 }, + { 0x0013, 0x01f8 }, + { 0x0013, 0x01f9 }, + { 0x0013, 0x01fa }, + { 0x0013, 0x01fb }, + { 0x0013, 0x01fc }, + { 0x0013, 0x01fd }, + { 0x0013, 0x01fe }, + { 0x0013, 0x01ff }, + { 0x0013, 0x0200 }, + { 0x0013, 0x0201 }, + { 0x0013, 0x0202 }, + { 0x0013, 0x0203 }, + { 0x0013, 0x0204 }, + { 0x0013, 0x0205 }, + { 0x0013, 0x0206 }, + { 0x0013, 0x0207 }, + { 0x0013, 0x0208 }, + { 0x0013, 0x0209 }, + { 0x0013, 0x020a }, + { 0x0013, 0x020b }, + { 0x0013, 0x020c }, + { 0x0013, 0x020d }, + { 0x0013, 0x020e }, + { 0x0013, 0x020f }, + { 0x0013, 0x0210 }, + { 0x0013, 0x0211 }, + { 0x0013, 0x0212 }, + { 0x0013, 0x0213 }, + { 0x0013, 0x0214 }, + { 0x0013, 0x0215 }, + { 0x0013, 0x0216 }, + { 0x0013, 0x0217 }, + { 0x0013, 0x0218 }, + { 0x0013, 0x0219 }, + { 0x0013, 0x021a }, + { 0x0013, 0x021b }, + { 0x0013, 0x021c }, + { 0x0013, 0x021d }, + { 0x0013, 0x021e }, + { 0x0013, 0x021f }, + { 0x0013, 0x0220 }, + { 0x0013, 0x0221 }, + { 0x0013, 0x0222 }, + { 0x0013, 0x0223 }, + { 0x0013, 0x0224 }, + { 0x0013, 0x0225 }, + { 0x0013, 0x0226 }, + { 0x0013, 0x0227 }, + { 0x0013, 0x0228 }, + { 0x0013, 0x0229 }, + { 0x0013, 0x022a }, + { 0x0013, 0x022b }, + { 0x0013, 0x022c }, + { 0x0013, 0x022d }, + { 0x0013, 0x022e }, + { 0x0013, 0x022f }, + { 0x0013, 0x0230 }, + { 0x0013, 0x0231 }, + { 0x0013, 0x0232 }, + { 0x0013, 0x0233 }, + { 0x0013, 0x0234 }, + { 0x0013, 0x0235 }, + { 0x0013, 0x0236 }, + { 0x0013, 0x0237 }, + { 0x0013, 0x0238 }, + { 0x0013, 0x0239 }, + { 0x0013, 0x023a }, + { 0x0013, 0x023b }, + { 0x0013, 0x023c }, + { 0x0013, 0x023d }, + { 0x0013, 0x023e }, + { 0x0013, 0x023f }, + { 0x0013, 0x0240 }, + { 0x0013, 0x0241 }, + { 0x0013, 0x0242 }, + { 0x0013, 0x0243 }, + { 0x0013, 0x0244 }, + { 0x0013, 0x0245 }, + { 0x0013, 0x0246 }, + { 0x0013, 0x0247 }, + { 0x0013, 0x0248 }, + { 0x0013, 0x0249 }, + { 0x0013, 0x024a }, + { 0x0013, 0x024b }, + { 0x0013, 0x024c }, + { 0x0013, 0x024d }, + { 0x0013, 0x024e }, + { 0x0013, 0x024f }, + { 0x0013, 0x0250 }, + { 0x0013, 0x0251 }, + { 0x0013, 0x0252 }, + { 0x0013, 0x0253 }, + { 0x0013, 0x0254 }, + { 0x0013, 0x0255 }, + { 0x0013, 0x0256 }, + { 0x0013, 0x0257 }, + { 0x0013, 0x0258 }, + { 0x0013, 0x0259 }, + { 0x0013, 0x025a }, + { 0x0013, 0x025b }, + { 0x0013, 0x025c }, + { 0x0013, 0x025d }, + { 0x0013, 0x025e }, + { 0x0013, 0x025f }, + { 0x0013, 0x0260 }, + { 0x0013, 0x0261 }, + { 0x0013, 0x0262 }, + { 0x0013, 0x0263 }, + { 0x0013, 0x0264 }, + { 0x0013, 0x0265 }, + { 0x0013, 0x0266 }, + { 0x0013, 0x0267 }, + { 0x0013, 0x0268 }, + { 0x0013, 0x0269 }, + { 0x0013, 0x026a }, + { 0x0013, 0x026b }, + { 0x0012, 0x013f }, + + }; + +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec48[110][16] = { + { + 0x0005ffff, + 0x0003ffff, + 0x0004ffff, + 0x0001ffff, + 0x0002ffff, + 0x00000037, + 0x00010001, + 0x00010001, + 0x0001001b, + 0x0001001b, + 0x0001001c, + 0x0001001c, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + }, + { + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + }, + { + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + }, + { + 0x0001003a, + 0x0001003a, + 0x00010054, + 0x00010054, + 0x0001006d, + 0x0001006d, + 0x0001006e, + 0x0001006e, + 0x00020003, + 0x00020003, + 0x00020003, + 0x00020003, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001e, + }, + { + 0x00020039, + 0x00020039, + 0x00020039, + 0x00020039, + 0x00020051, + 0x00020051, + 0x00020051, + 0x00020051, + 0x00020052, + 0x00020052, + 0x00020052, + 0x00020052, + 0x00020053, + 0x00020053, + 0x00020053, + 0x00020053, + }, + { + 0x000bffff, + 0x000affff, + 0x0009ffff, + 0x0008ffff, + 0x0006ffff, + 0x0007ffff, + 0x00000004, + 0x00000020, + 0x0000003b, + 0x00000055, + 0x0000006c, + 0x0000006f, + 0x00000088, + 0x00000089, + 0x0001001f, + 0x0001001f, + }, + { + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030070, + 0x00030070, + 0x00030070, + 0x00030070, + 0x00030070, + 0x00030070, + 0x00030070, + 0x00030070, + }, + { + 0x00030087, + 0x00030087, + 0x00030087, + 0x00030087, + 0x00030087, + 0x00030087, + 0x00030087, + 0x00030087, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + 0x0003008a, + }, + { + 0x000200a3, + 0x000200a3, + 0x000200a3, + 0x000200a3, + 0x000200a4, + 0x000200a4, + 0x000200a4, + 0x000200a4, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + }, + { + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020021, + 0x0002003c, + 0x0002003c, + 0x0002003c, + 0x0002003c, + 0x00020071, + 0x00020071, + 0x00020071, + 0x00020071, + 0x0002008b, + 0x0002008b, + 0x0002008b, + 0x0002008b, + }, + { + 0x00000072, + 0x0000008c, + 0x000000a6, + 0x000000bd, + 0x000000bf, + 0x000000c0, + 0x00010006, + 0x00010006, + 0x00010057, + 0x00010057, + 0x000100a2, + 0x000100a2, + 0x000100a5, + 0x000100a5, + 0x000100be, + 0x000100be, + }, + { + 0x001dffff, + 0x002effff, + 0x003fffff, + 0x0050ffff, + 0x0019ffff, + 0x0013ffff, + 0x0012ffff, + 0x0010ffff, + 0x0011ffff, + 0x000cffff, + 0x000dffff, + 0x000effff, + 0x000fffff, + 0x00000007, + 0x00000022, + 0x0000003d, + }, + { + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + }, + { + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030073, + 0x00030073, + 0x00030073, + 0x00030073, + 0x00030073, + 0x00030073, + 0x00030073, + 0x00030073, + }, + { + 0x0003008d, + 0x0003008d, + 0x0003008d, + 0x0003008d, + 0x0003008d, + 0x0003008d, + 0x0003008d, + 0x0003008d, + 0x000300a7, + 0x000300a7, + 0x000300a7, + 0x000300a7, + 0x000300a7, + 0x000300a7, + 0x000300a7, + 0x000300a7, + }, + { + 0x000300c1, + 0x000300c1, + 0x000300c1, + 0x000300c1, + 0x000300c1, + 0x000300c1, + 0x000300c1, + 0x000300c1, + 0x000300d9, + 0x000300d9, + 0x000300d9, + 0x000300d9, + 0x000300d9, + 0x000300d9, + 0x000300d9, + 0x000300d9, + }, + { + 0x000100f5, + 0x000100f5, + 0x000100f6, + 0x000100f6, + 0x00020059, + 0x00020059, + 0x00020059, + 0x00020059, + 0x0002008e, + 0x0002008e, + 0x0002008e, + 0x0002008e, + 0x000200a8, + 0x000200a8, + 0x000200a8, + 0x000200a8, + }, + { + 0x000200c2, + 0x000200c2, + 0x000200c2, + 0x000200c2, + 0x000200d8, + 0x000200d8, + 0x000200d8, + 0x000200d8, + 0x000200da, + 0x000200da, + 0x000200da, + 0x000200da, + 0x000200db, + 0x000200db, + 0x000200db, + 0x000200db, + }, + { + 0x00010008, + 0x00010008, + 0x00010024, + 0x00010024, + 0x0001003f, + 0x0001003f, + 0x0001005a, + 0x0001005a, + 0x00010074, + 0x00010074, + 0x000100c3, + 0x000100c3, + 0x000100dc, + 0x000100dc, + 0x000100f4, + 0x000100f4, + }, + { + 0x0015ffff, + 0x0014ffff, + 0x0016ffff, + 0x0017ffff, + 0x0018ffff, + 0x00000009, + 0x00000075, + 0x0000008f, + 0x000000a9, + 0x000000dd, + 0x000000f3, + 0x000000f7, + 0x000000f8, + 0x0000010e, + 0x0000010f, + 0x00000111, + }, + { + 0x00030090, + 0x00030090, + 0x00030090, + 0x00030090, + 0x00030090, + 0x00030090, + 0x00030090, + 0x00030090, + 0x00030091, + 0x00030091, + 0x00030091, + 0x00030091, + 0x00030091, + 0x00030091, + 0x00030091, + 0x00030091, + }, + { + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + }, + { + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300ab, + 0x000300de, + 0x000300de, + 0x000300de, + 0x000300de, + 0x000300de, + 0x000300de, + 0x000300de, + 0x000300de, + }, + { + 0x000300e0, + 0x000300e0, + 0x000300e0, + 0x000300e0, + 0x000300e0, + 0x000300e0, + 0x000300e0, + 0x000300e0, + 0x000300fa, + 0x000300fa, + 0x000300fa, + 0x000300fa, + 0x000300fa, + 0x000300fa, + 0x000300fa, + 0x000300fa, + }, + { + 0x0003012a, + 0x0003012a, + 0x0003012a, + 0x0003012a, + 0x0003012a, + 0x0003012a, + 0x0003012a, + 0x0003012a, + 0x0003012c, + 0x0003012c, + 0x0003012c, + 0x0003012c, + 0x0003012c, + 0x0003012c, + 0x0003012c, + 0x0003012c, + }, + { + 0x0061ffff, + 0x0062ffff, + 0x0063ffff, + 0x0064ffff, + 0x0065ffff, + 0x0066ffff, + 0x0067ffff, + 0x0068ffff, + 0x0069ffff, + 0x006affff, + 0x006bffff, + 0x006cffff, + 0x006dffff, + 0x001bffff, + 0x001affff, + 0x001cffff, + }, + { + 0x00020076, + 0x00020076, + 0x00020076, + 0x00020076, + 0x000200aa, + 0x000200aa, + 0x000200aa, + 0x000200aa, + 0x000200ac, + 0x000200ac, + 0x000200ac, + 0x000200ac, + 0x000200c4, + 0x000200c4, + 0x000200c4, + 0x000200c4, + }, + { + 0x000102d4, + 0x000102d4, + 0x000102d5, + 0x000102d5, + 0x000102d6, + 0x000102d6, + 0x000102d7, + 0x000102d7, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002005b, + 0x0002005b, + 0x0002005b, + 0x0002005b, + }, + { + 0x000200e1, + 0x000200e1, + 0x000200e1, + 0x000200e1, + 0x00020113, + 0x00020113, + 0x00020113, + 0x00020113, + 0x00020146, + 0x00020146, + 0x00020146, + 0x00020146, + 0x000202d8, + 0x000202d8, + 0x000202d8, + 0x000202d8, + }, + { + 0x001effff, + 0x001fffff, + 0x0020ffff, + 0x0021ffff, + 0x0022ffff, + 0x0023ffff, + 0x0024ffff, + 0x0027ffff, + 0x0025ffff, + 0x0026ffff, + 0x0028ffff, + 0x0029ffff, + 0x002affff, + 0x002bffff, + 0x002cffff, + 0x002dffff, + }, + { + 0x0001000b, + 0x0001000b, + 0x0001000c, + 0x0001000c, + 0x0001000d, + 0x0001000d, + 0x0001000e, + 0x0001000e, + 0x0001000f, + 0x0001000f, + 0x00010010, + 0x00010010, + 0x00010011, + 0x00010011, + 0x00010012, + 0x00010012, + }, + { + 0x00010013, + 0x00010013, + 0x00010014, + 0x00010014, + 0x00010015, + 0x00010015, + 0x00010016, + 0x00010016, + 0x00010017, + 0x00010017, + 0x00010018, + 0x00010018, + 0x00010019, + 0x00010019, + 0x0001001a, + 0x0001001a, + }, + { + 0x00010026, + 0x00010026, + 0x00010027, + 0x00010027, + 0x00010028, + 0x00010028, + 0x00010029, + 0x00010029, + 0x0001002a, + 0x0001002a, + 0x0001002b, + 0x0001002b, + 0x0001002c, + 0x0001002c, + 0x0001002d, + 0x0001002d, + }, + { + 0x0001002e, + 0x0001002e, + 0x0001002f, + 0x0001002f, + 0x00010030, + 0x00010030, + 0x00010031, + 0x00010031, + 0x00010032, + 0x00010032, + 0x00010033, + 0x00010033, + 0x00010034, + 0x00010034, + 0x00010035, + 0x00010035, + }, + { + 0x00010041, + 0x00010041, + 0x00010042, + 0x00010042, + 0x00010043, + 0x00010043, + 0x00010044, + 0x00010044, + 0x00010045, + 0x00010045, + 0x00010046, + 0x00010046, + 0x00010047, + 0x00010047, + 0x00010048, + 0x00010048, + }, + { + 0x00010049, + 0x00010049, + 0x0001004a, + 0x0001004a, + 0x0001004b, + 0x0001004b, + 0x0001004c, + 0x0001004c, + 0x0001004d, + 0x0001004d, + 0x0001004e, + 0x0001004e, + 0x0001004f, + 0x0001004f, + 0x00010050, + 0x00010050, + }, + { + 0x0001005c, + 0x0001005c, + 0x0001005d, + 0x0001005d, + 0x0001005e, + 0x0001005e, + 0x0001005f, + 0x0001005f, + 0x00010060, + 0x00010060, + 0x00010061, + 0x00010061, + 0x00010062, + 0x00010062, + 0x00010063, + 0x00010063, + }, + { + 0x00010077, + 0x00010077, + 0x00010078, + 0x00010078, + 0x00010079, + 0x00010079, + 0x0001007a, + 0x0001007a, + 0x0001007b, + 0x0001007b, + 0x0001007c, + 0x0001007c, + 0x0001007d, + 0x0001007d, + 0x0001007e, + 0x0001007e, + }, + { + 0x0001007f, + 0x0001007f, + 0x00010080, + 0x00010080, + 0x00010081, + 0x00010081, + 0x00010082, + 0x00010082, + 0x00010083, + 0x00010083, + 0x00010084, + 0x00010084, + 0x00010085, + 0x00010085, + 0x00010086, + 0x00010086, + }, + { + 0x00010064, + 0x00010064, + 0x00010065, + 0x00010065, + 0x00010066, + 0x00010066, + 0x00010067, + 0x00010067, + 0x00010068, + 0x00010068, + 0x00010069, + 0x00010069, + 0x0001006a, + 0x0001006a, + 0x0001006b, + 0x0001006b, + }, + { + 0x00010092, + 0x00010092, + 0x00010093, + 0x00010093, + 0x00010094, + 0x00010094, + 0x00010095, + 0x00010095, + 0x00010096, + 0x00010096, + 0x00010097, + 0x00010097, + 0x00010098, + 0x00010098, + 0x00010099, + 0x00010099, + }, + { + 0x0001009a, + 0x0001009a, + 0x0001009b, + 0x0001009b, + 0x0001009c, + 0x0001009c, + 0x0001009d, + 0x0001009d, + 0x0001009e, + 0x0001009e, + 0x0001009f, + 0x0001009f, + 0x000100a0, + 0x000100a0, + 0x000100a1, + 0x000100a1, + }, + { + 0x000100ad, + 0x000100ad, + 0x000100ae, + 0x000100ae, + 0x000100af, + 0x000100af, + 0x000100b0, + 0x000100b0, + 0x000100b1, + 0x000100b1, + 0x000100b2, + 0x000100b2, + 0x000100b3, + 0x000100b3, + 0x000100b4, + 0x000100b4, + }, + { + 0x000100b5, + 0x000100b5, + 0x000100b6, + 0x000100b6, + 0x000100b7, + 0x000100b7, + 0x000100b8, + 0x000100b8, + 0x000100b9, + 0x000100b9, + 0x000100ba, + 0x000100ba, + 0x000100bb, + 0x000100bb, + 0x000100bc, + 0x000100bc, + }, + { + 0x000100c5, + 0x000100c5, + 0x000100c6, + 0x000100c6, + 0x000100c7, + 0x000100c7, + 0x000100c8, + 0x000100c8, + 0x000100c9, + 0x000100c9, + 0x000100ca, + 0x000100ca, + 0x000100cb, + 0x000100cb, + 0x000100cc, + 0x000100cc, + }, + { + 0x000100cd, + 0x000100cd, + 0x000100ce, + 0x000100ce, + 0x000100cf, + 0x000100cf, + 0x000100d0, + 0x000100d0, + 0x000100d1, + 0x000100d1, + 0x000100d2, + 0x000100d2, + 0x000100d3, + 0x000100d3, + 0x000100d4, + 0x000100d4, + }, + { + 0x002fffff, + 0x0030ffff, + 0x0031ffff, + 0x0032ffff, + 0x0033ffff, + 0x0034ffff, + 0x0035ffff, + 0x0036ffff, + 0x0037ffff, + 0x0038ffff, + 0x0039ffff, + 0x003affff, + 0x003bffff, + 0x003cffff, + 0x003dffff, + 0x003effff, + }, + { + 0x000100d5, + 0x000100d5, + 0x000100d6, + 0x000100d6, + 0x000100d7, + 0x000100d7, + 0x000100df, + 0x000100df, + 0x000100e2, + 0x000100e2, + 0x000100e3, + 0x000100e3, + 0x000100e4, + 0x000100e4, + 0x000100e5, + 0x000100e5, + }, + { + 0x000100e6, + 0x000100e6, + 0x000100e7, + 0x000100e7, + 0x000100e8, + 0x000100e8, + 0x000100e9, + 0x000100e9, + 0x000100ea, + 0x000100ea, + 0x000100eb, + 0x000100eb, + 0x000100ec, + 0x000100ec, + 0x000100ed, + 0x000100ed, + }, + { + 0x000100ee, + 0x000100ee, + 0x000100ef, + 0x000100ef, + 0x000100f0, + 0x000100f0, + 0x000100f1, + 0x000100f1, + 0x000100f2, + 0x000100f2, + 0x000100f9, + 0x000100f9, + 0x000100fb, + 0x000100fb, + 0x000100fc, + 0x000100fc, + }, + { + 0x000100fd, + 0x000100fd, + 0x000100fe, + 0x000100fe, + 0x000100ff, + 0x000100ff, + 0x00010100, + 0x00010100, + 0x00010101, + 0x00010101, + 0x00010102, + 0x00010102, + 0x00010103, + 0x00010103, + 0x00010104, + 0x00010104, + }, + { + 0x00010105, + 0x00010105, + 0x00010106, + 0x00010106, + 0x00010107, + 0x00010107, + 0x00010108, + 0x00010108, + 0x00010109, + 0x00010109, + 0x0001010a, + 0x0001010a, + 0x0001010b, + 0x0001010b, + 0x0001010c, + 0x0001010c, + }, + { + 0x0001010d, + 0x0001010d, + 0x00010110, + 0x00010110, + 0x00010112, + 0x00010112, + 0x00010114, + 0x00010114, + 0x00010115, + 0x00010115, + 0x00010116, + 0x00010116, + 0x00010117, + 0x00010117, + 0x00010118, + 0x00010118, + }, + { + 0x00010119, + 0x00010119, + 0x0001011a, + 0x0001011a, + 0x0001011b, + 0x0001011b, + 0x0001011c, + 0x0001011c, + 0x0001011d, + 0x0001011d, + 0x0001011e, + 0x0001011e, + 0x0001011f, + 0x0001011f, + 0x00010120, + 0x00010120, + }, + { + 0x00010121, + 0x00010121, + 0x00010122, + 0x00010122, + 0x00010123, + 0x00010123, + 0x00010124, + 0x00010124, + 0x00010125, + 0x00010125, + 0x00010126, + 0x00010126, + 0x00010127, + 0x00010127, + 0x00010128, + 0x00010128, + }, + { + 0x00010129, + 0x00010129, + 0x0001012b, + 0x0001012b, + 0x0001012d, + 0x0001012d, + 0x0001012e, + 0x0001012e, + 0x0001012f, + 0x0001012f, + 0x00010130, + 0x00010130, + 0x00010131, + 0x00010131, + 0x00010132, + 0x00010132, + }, + { + 0x00010133, + 0x00010133, + 0x00010134, + 0x00010134, + 0x00010135, + 0x00010135, + 0x00010136, + 0x00010136, + 0x00010137, + 0x00010137, + 0x00010138, + 0x00010138, + 0x00010139, + 0x00010139, + 0x0001013a, + 0x0001013a, + }, + { + 0x0001013b, + 0x0001013b, + 0x0001013c, + 0x0001013c, + 0x0001013d, + 0x0001013d, + 0x0001013e, + 0x0001013e, + 0x0001013f, + 0x0001013f, + 0x00010140, + 0x00010140, + 0x00010141, + 0x00010141, + 0x00010142, + 0x00010142, + }, + { + 0x00010143, + 0x00010143, + 0x00010144, + 0x00010144, + 0x00010145, + 0x00010145, + 0x00010147, + 0x00010147, + 0x00010148, + 0x00010148, + 0x00010149, + 0x00010149, + 0x0001014a, + 0x0001014a, + 0x0001014b, + 0x0001014b, + }, + { + 0x0001014c, + 0x0001014c, + 0x0001014d, + 0x0001014d, + 0x0001014e, + 0x0001014e, + 0x0001014f, + 0x0001014f, + 0x00010150, + 0x00010150, + 0x00010151, + 0x00010151, + 0x00010152, + 0x00010152, + 0x00010153, + 0x00010153, + }, + { + 0x00010154, + 0x00010154, + 0x00010155, + 0x00010155, + 0x00010156, + 0x00010156, + 0x00010157, + 0x00010157, + 0x00010158, + 0x00010158, + 0x00010159, + 0x00010159, + 0x0001015a, + 0x0001015a, + 0x0001015b, + 0x0001015b, + }, + { + 0x0001015c, + 0x0001015c, + 0x0001015d, + 0x0001015d, + 0x0001015e, + 0x0001015e, + 0x0001015f, + 0x0001015f, + 0x00010160, + 0x00010160, + 0x00010161, + 0x00010161, + 0x00010162, + 0x00010162, + 0x00010163, + 0x00010163, + }, + { + 0x00010164, + 0x00010164, + 0x00010165, + 0x00010165, + 0x00010166, + 0x00010166, + 0x00010167, + 0x00010167, + 0x00010168, + 0x00010168, + 0x00010169, + 0x00010169, + 0x0001016a, + 0x0001016a, + 0x0001016b, + 0x0001016b, + }, + { + 0x0040ffff, + 0x0041ffff, + 0x0042ffff, + 0x0043ffff, + 0x0044ffff, + 0x0045ffff, + 0x0046ffff, + 0x0047ffff, + 0x0048ffff, + 0x0049ffff, + 0x004affff, + 0x004bffff, + 0x004cffff, + 0x004dffff, + 0x004effff, + 0x004fffff, + }, + { + 0x0001016c, + 0x0001016c, + 0x0001016d, + 0x0001016d, + 0x0001016e, + 0x0001016e, + 0x0001016f, + 0x0001016f, + 0x00010170, + 0x00010170, + 0x00010171, + 0x00010171, + 0x00010172, + 0x00010172, + 0x00010173, + 0x00010173, + }, + { + 0x00010174, + 0x00010174, + 0x00010175, + 0x00010175, + 0x00010176, + 0x00010176, + 0x00010177, + 0x00010177, + 0x00010178, + 0x00010178, + 0x00010179, + 0x00010179, + 0x0001017a, + 0x0001017a, + 0x0001017b, + 0x0001017b, + }, + { + 0x0001017c, + 0x0001017c, + 0x0001017d, + 0x0001017d, + 0x0001017e, + 0x0001017e, + 0x0001017f, + 0x0001017f, + 0x00010180, + 0x00010180, + 0x00010181, + 0x00010181, + 0x00010182, + 0x00010182, + 0x00010183, + 0x00010183, + }, + { + 0x00010184, + 0x00010184, + 0x00010185, + 0x00010185, + 0x00010186, + 0x00010186, + 0x00010187, + 0x00010187, + 0x00010188, + 0x00010188, + 0x00010189, + 0x00010189, + 0x0001018a, + 0x0001018a, + 0x0001018b, + 0x0001018b, + }, + { + 0x0001018c, + 0x0001018c, + 0x0001018d, + 0x0001018d, + 0x0001018e, + 0x0001018e, + 0x0001018f, + 0x0001018f, + 0x00010190, + 0x00010190, + 0x00010191, + 0x00010191, + 0x00010192, + 0x00010192, + 0x00010193, + 0x00010193, + }, + { + 0x00010194, + 0x00010194, + 0x00010195, + 0x00010195, + 0x00010196, + 0x00010196, + 0x00010197, + 0x00010197, + 0x00010198, + 0x00010198, + 0x00010199, + 0x00010199, + 0x0001019a, + 0x0001019a, + 0x0001019b, + 0x0001019b, + }, + { + 0x0001019c, + 0x0001019c, + 0x0001019d, + 0x0001019d, + 0x0001019e, + 0x0001019e, + 0x0001019f, + 0x0001019f, + 0x000101a0, + 0x000101a0, + 0x000101a1, + 0x000101a1, + 0x000101a2, + 0x000101a2, + 0x000101a3, + 0x000101a3, + }, + { + 0x000101a4, + 0x000101a4, + 0x000101a5, + 0x000101a5, + 0x000101a6, + 0x000101a6, + 0x000101a7, + 0x000101a7, + 0x000101a8, + 0x000101a8, + 0x000101a9, + 0x000101a9, + 0x000101aa, + 0x000101aa, + 0x000101ab, + 0x000101ab, + }, + { + 0x000101ac, + 0x000101ac, + 0x000101ad, + 0x000101ad, + 0x000101ae, + 0x000101ae, + 0x000101af, + 0x000101af, + 0x000101b0, + 0x000101b0, + 0x000101b1, + 0x000101b1, + 0x000101b2, + 0x000101b2, + 0x000101b3, + 0x000101b3, + }, + { + 0x000101b4, + 0x000101b4, + 0x000101b5, + 0x000101b5, + 0x000101b6, + 0x000101b6, + 0x000101b7, + 0x000101b7, + 0x000101b8, + 0x000101b8, + 0x000101b9, + 0x000101b9, + 0x000101ba, + 0x000101ba, + 0x000101bb, + 0x000101bb, + }, + { + 0x000101bc, + 0x000101bc, + 0x000101bd, + 0x000101bd, + 0x000101be, + 0x000101be, + 0x000101bf, + 0x000101bf, + 0x000101c0, + 0x000101c0, + 0x000101c1, + 0x000101c1, + 0x000101c2, + 0x000101c2, + 0x000101c3, + 0x000101c3, + }, + { + 0x000101c4, + 0x000101c4, + 0x000101c5, + 0x000101c5, + 0x000101c6, + 0x000101c6, + 0x000101c7, + 0x000101c7, + 0x000101c8, + 0x000101c8, + 0x000101c9, + 0x000101c9, + 0x000101ca, + 0x000101ca, + 0x000101cb, + 0x000101cb, + }, + { + 0x000101cc, + 0x000101cc, + 0x000101cd, + 0x000101cd, + 0x000101ce, + 0x000101ce, + 0x000101cf, + 0x000101cf, + 0x000101d0, + 0x000101d0, + 0x000101d1, + 0x000101d1, + 0x000101d2, + 0x000101d2, + 0x000101d3, + 0x000101d3, + }, + { + 0x000101d4, + 0x000101d4, + 0x000101d5, + 0x000101d5, + 0x000101d6, + 0x000101d6, + 0x000101d7, + 0x000101d7, + 0x000101d8, + 0x000101d8, + 0x000101d9, + 0x000101d9, + 0x000101da, + 0x000101da, + 0x000101db, + 0x000101db, + }, + { + 0x000101dc, + 0x000101dc, + 0x000101dd, + 0x000101dd, + 0x000101de, + 0x000101de, + 0x000101df, + 0x000101df, + 0x000101e0, + 0x000101e0, + 0x000101e1, + 0x000101e1, + 0x000101e2, + 0x000101e2, + 0x000101e3, + 0x000101e3, + }, + { + 0x000101e4, + 0x000101e4, + 0x000101e5, + 0x000101e5, + 0x000101e6, + 0x000101e6, + 0x000101e7, + 0x000101e7, + 0x000101e8, + 0x000101e8, + 0x000101e9, + 0x000101e9, + 0x000101ea, + 0x000101ea, + 0x000101eb, + 0x000101eb, + }, + { + 0x0051ffff, + 0x0052ffff, + 0x0053ffff, + 0x0054ffff, + 0x0055ffff, + 0x0056ffff, + 0x0057ffff, + 0x0058ffff, + 0x0059ffff, + 0x005affff, + 0x005bffff, + 0x005cffff, + 0x005dffff, + 0x005effff, + 0x005fffff, + 0x0060ffff, + }, + { + 0x000101ec, + 0x000101ec, + 0x000101ed, + 0x000101ed, + 0x000101ee, + 0x000101ee, + 0x000101ef, + 0x000101ef, + 0x000101f0, + 0x000101f0, + 0x000101f1, + 0x000101f1, + 0x000101f2, + 0x000101f2, + 0x000101f3, + 0x000101f3, + }, + { + 0x000101f4, + 0x000101f4, + 0x000101f5, + 0x000101f5, + 0x000101f6, + 0x000101f6, + 0x000101f7, + 0x000101f7, + 0x000101f8, + 0x000101f8, + 0x000101f9, + 0x000101f9, + 0x000101fa, + 0x000101fa, + 0x000101fb, + 0x000101fb, + }, + { + 0x000101fc, + 0x000101fc, + 0x000101fd, + 0x000101fd, + 0x000101fe, + 0x000101fe, + 0x000101ff, + 0x000101ff, + 0x00010200, + 0x00010200, + 0x00010201, + 0x00010201, + 0x00010202, + 0x00010202, + 0x00010203, + 0x00010203, + }, + { + 0x00010204, + 0x00010204, + 0x00010205, + 0x00010205, + 0x00010206, + 0x00010206, + 0x00010207, + 0x00010207, + 0x00010208, + 0x00010208, + 0x00010209, + 0x00010209, + 0x0001020a, + 0x0001020a, + 0x0001020b, + 0x0001020b, + }, + { + 0x0001020c, + 0x0001020c, + 0x0001020d, + 0x0001020d, + 0x0001020e, + 0x0001020e, + 0x0001020f, + 0x0001020f, + 0x00010210, + 0x00010210, + 0x00010211, + 0x00010211, + 0x00010212, + 0x00010212, + 0x00010213, + 0x00010213, + }, + { + 0x00010214, + 0x00010214, + 0x00010215, + 0x00010215, + 0x00010216, + 0x00010216, + 0x00010217, + 0x00010217, + 0x00010218, + 0x00010218, + 0x00010219, + 0x00010219, + 0x0001021a, + 0x0001021a, + 0x0001021b, + 0x0001021b, + }, + { + 0x0001021c, + 0x0001021c, + 0x0001021d, + 0x0001021d, + 0x0001021e, + 0x0001021e, + 0x0001021f, + 0x0001021f, + 0x00010220, + 0x00010220, + 0x00010221, + 0x00010221, + 0x00010222, + 0x00010222, + 0x00010223, + 0x00010223, + }, + { + 0x00010224, + 0x00010224, + 0x00010225, + 0x00010225, + 0x00010226, + 0x00010226, + 0x00010227, + 0x00010227, + 0x00010228, + 0x00010228, + 0x00010229, + 0x00010229, + 0x0001022a, + 0x0001022a, + 0x0001022b, + 0x0001022b, + }, + { + 0x0001022c, + 0x0001022c, + 0x0001022d, + 0x0001022d, + 0x0001022e, + 0x0001022e, + 0x0001022f, + 0x0001022f, + 0x00010230, + 0x00010230, + 0x00010231, + 0x00010231, + 0x00010232, + 0x00010232, + 0x00010233, + 0x00010233, + }, + { + 0x00010234, + 0x00010234, + 0x00010235, + 0x00010235, + 0x00010236, + 0x00010236, + 0x00010237, + 0x00010237, + 0x00010238, + 0x00010238, + 0x00010239, + 0x00010239, + 0x0001023a, + 0x0001023a, + 0x0001023b, + 0x0001023b, + }, + { + 0x0001023c, + 0x0001023c, + 0x0001023d, + 0x0001023d, + 0x0001023e, + 0x0001023e, + 0x0001023f, + 0x0001023f, + 0x00010240, + 0x00010240, + 0x00010241, + 0x00010241, + 0x00010242, + 0x00010242, + 0x00010243, + 0x00010243, + }, + { + 0x00010244, + 0x00010244, + 0x00010245, + 0x00010245, + 0x00010246, + 0x00010246, + 0x00010247, + 0x00010247, + 0x00010248, + 0x00010248, + 0x00010249, + 0x00010249, + 0x0001024a, + 0x0001024a, + 0x0001024b, + 0x0001024b, + }, + { + 0x0001024c, + 0x0001024c, + 0x0001024d, + 0x0001024d, + 0x0001024e, + 0x0001024e, + 0x0001024f, + 0x0001024f, + 0x00010250, + 0x00010250, + 0x00010251, + 0x00010251, + 0x00010252, + 0x00010252, + 0x00010253, + 0x00010253, + }, + { + 0x00010254, + 0x00010254, + 0x00010255, + 0x00010255, + 0x00010256, + 0x00010256, + 0x00010257, + 0x00010257, + 0x00010258, + 0x00010258, + 0x00010259, + 0x00010259, + 0x0001025a, + 0x0001025a, + 0x0001025b, + 0x0001025b, + }, + { + 0x0001025c, + 0x0001025c, + 0x0001025d, + 0x0001025d, + 0x0001025e, + 0x0001025e, + 0x0001025f, + 0x0001025f, + 0x00010260, + 0x00010260, + 0x00010261, + 0x00010261, + 0x00010262, + 0x00010262, + 0x00010263, + 0x00010263, + }, + { + 0x00010264, + 0x00010264, + 0x00010265, + 0x00010265, + 0x00010266, + 0x00010266, + 0x00010267, + 0x00010267, + 0x00010268, + 0x00010268, + 0x00010269, + 0x00010269, + 0x0001026a, + 0x0001026a, + 0x0001026b, + 0x0001026b, + }, + { + 0x0001026c, + 0x0001026c, + 0x0001026d, + 0x0001026d, + 0x0001026e, + 0x0001026e, + 0x0001026f, + 0x0001026f, + 0x00010270, + 0x00010270, + 0x00010271, + 0x00010271, + 0x00010272, + 0x00010272, + 0x00010273, + 0x00010273, + }, + { + 0x00010274, + 0x00010274, + 0x00010275, + 0x00010275, + 0x00010276, + 0x00010276, + 0x00010277, + 0x00010277, + 0x00010278, + 0x00010278, + 0x00010279, + 0x00010279, + 0x0001027a, + 0x0001027a, + 0x0001027b, + 0x0001027b, + }, + { + 0x0001027c, + 0x0001027c, + 0x0001027d, + 0x0001027d, + 0x0001027e, + 0x0001027e, + 0x0001027f, + 0x0001027f, + 0x00010280, + 0x00010280, + 0x00010281, + 0x00010281, + 0x00010282, + 0x00010282, + 0x00010283, + 0x00010283, + }, + { + 0x00010284, + 0x00010284, + 0x00010285, + 0x00010285, + 0x00010286, + 0x00010286, + 0x00010287, + 0x00010287, + 0x00010288, + 0x00010288, + 0x00010289, + 0x00010289, + 0x0001028a, + 0x0001028a, + 0x0001028b, + 0x0001028b, + }, + { + 0x0001028c, + 0x0001028c, + 0x0001028d, + 0x0001028d, + 0x0001028e, + 0x0001028e, + 0x0001028f, + 0x0001028f, + 0x00010290, + 0x00010290, + 0x00010291, + 0x00010291, + 0x00010292, + 0x00010292, + 0x00010293, + 0x00010293, + }, + { + 0x00010294, + 0x00010294, + 0x00010295, + 0x00010295, + 0x00010296, + 0x00010296, + 0x00010297, + 0x00010297, + 0x00010298, + 0x00010298, + 0x00010299, + 0x00010299, + 0x0001029a, + 0x0001029a, + 0x0001029b, + 0x0001029b, + }, + { + 0x0001029c, + 0x0001029c, + 0x0001029d, + 0x0001029d, + 0x0001029e, + 0x0001029e, + 0x0001029f, + 0x0001029f, + 0x000102a0, + 0x000102a0, + 0x000102a1, + 0x000102a1, + 0x000102a2, + 0x000102a2, + 0x000102a3, + 0x000102a3, + }, + { + 0x000102a4, + 0x000102a4, + 0x000102a5, + 0x000102a5, + 0x000102a6, + 0x000102a6, + 0x000102a7, + 0x000102a7, + 0x000102a8, + 0x000102a8, + 0x000102a9, + 0x000102a9, + 0x000102aa, + 0x000102aa, + 0x000102ab, + 0x000102ab, + }, + { + 0x000102ac, + 0x000102ac, + 0x000102ad, + 0x000102ad, + 0x000102ae, + 0x000102ae, + 0x000102af, + 0x000102af, + 0x000102b0, + 0x000102b0, + 0x000102b1, + 0x000102b1, + 0x000102b2, + 0x000102b2, + 0x000102b3, + 0x000102b3, + }, + { + 0x000102b4, + 0x000102b4, + 0x000102b5, + 0x000102b5, + 0x000102b6, + 0x000102b6, + 0x000102b7, + 0x000102b7, + 0x000102b8, + 0x000102b8, + 0x000102b9, + 0x000102b9, + 0x000102ba, + 0x000102ba, + 0x000102bb, + 0x000102bb, + }, + { + 0x000102bc, + 0x000102bc, + 0x000102bd, + 0x000102bd, + 0x000102be, + 0x000102be, + 0x000102bf, + 0x000102bf, + 0x000102c0, + 0x000102c0, + 0x000102c1, + 0x000102c1, + 0x000102c2, + 0x000102c2, + 0x000102c3, + 0x000102c3, + }, + { + 0x000102c4, + 0x000102c4, + 0x000102c5, + 0x000102c5, + 0x000102c6, + 0x000102c6, + 0x000102c7, + 0x000102c7, + 0x000102c8, + 0x000102c8, + 0x000102c9, + 0x000102c9, + 0x000102ca, + 0x000102ca, + 0x000102cb, + 0x000102cb, + }, + { + 0x000102cc, + 0x000102cc, + 0x000102cd, + 0x000102cd, + 0x000102ce, + 0x000102ce, + 0x000102cf, + 0x000102cf, + 0x000102d0, + 0x000102d0, + 0x000102d1, + 0x000102d1, + 0x000102d2, + 0x000102d2, + 0x000102d3, + 0x000102d3, + }, +}; + +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc49[729][2] = +#else +const uint16_t c_aauiCQMFHuffEnc49[729][2] = +#endif + { + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0007 }, + { 0x0007, 0x000a }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0009, 0x0009 }, + { 0x000b, 0x000d }, + { 0x000d, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x0010, 0x0052 }, + { 0x0011, 0x0098 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0005, 0x0008 }, + { 0x0006, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x000a, 0x000a }, + { 0x000b, 0x000e }, + { 0x000d, 0x0016 }, + { 0x000f, 0x0031 }, + { 0x0010, 0x0053 }, + { 0x0012, 0x012a }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0006, 0x000b }, + { 0x0007, 0x000c }, + { 0x0008, 0x000d }, + { 0x0009, 0x000a }, + { 0x000a, 0x000b }, + { 0x000c, 0x000f }, + { 0x000d, 0x0017 }, + { 0x000f, 0x0032 }, + { 0x0010, 0x0054 }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0007, 0x000d }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0008, 0x000e }, + { 0x0009, 0x000b }, + { 0x000b, 0x000f }, + { 0x000c, 0x0010 }, + { 0x000e, 0x001d }, + { 0x000f, 0x0033 }, + { 0x0011, 0x0099 }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0008, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0008, 0x0010 }, + { 0x0009, 0x000c }, + { 0x000a, 0x000c }, + { 0x000c, 0x0011 }, + { 0x000d, 0x0018 }, + { 0x000e, 0x001e }, + { 0x0011, 0x009a }, + { 0x0011, 0x009b }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0008, 0x0011 }, + { 0x0007, 0x0013 }, + { 0x0008, 0x0012 }, + { 0x0008, 0x0013 }, + { 0x0009, 0x000d }, + { 0x000a, 0x000d }, + { 0x000b, 0x0010 }, + { 0x000c, 0x0012 }, + { 0x000e, 0x001f }, + { 0x000e, 0x0020 }, + { 0x0010, 0x0055 }, + { 0x0011, 0x009c }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0009, 0x000e }, + { 0x0009, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x000e }, + { 0x000b, 0x0011 }, + { 0x000c, 0x0013 }, + { 0x000d, 0x0019 }, + { 0x000e, 0x0021 }, + { 0x0010, 0x0056 }, + { 0x0010, 0x0057 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x000b, 0x0012 }, + { 0x000a, 0x000f }, + { 0x000a, 0x0010 }, + { 0x000a, 0x0011 }, + { 0x000c, 0x0014 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x001a }, + { 0x000e, 0x0022 }, + { 0x0010, 0x0058 }, + { 0x0010, 0x0059 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x000c, 0x0016 }, + { 0x000b, 0x0013 }, + { 0x000c, 0x0017 }, + { 0x000c, 0x0018 }, + { 0x000c, 0x0019 }, + { 0x000e, 0x0023 }, + { 0x000e, 0x0024 }, + { 0x000f, 0x0034 }, + { 0x0010, 0x005a }, + { 0x0011, 0x009d }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x000e, 0x0025 }, + { 0x000d, 0x001b }, + { 0x000d, 0x001c }, + { 0x000d, 0x001d }, + { 0x000e, 0x0026 }, + { 0x000f, 0x0035 }, + { 0x0010, 0x005b }, + { 0x0011, 0x009e }, + { 0x0011, 0x009f }, + { 0x0012, 0x012b }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0010, 0x005c }, + { 0x000f, 0x0036 }, + { 0x000e, 0x0027 }, + { 0x000f, 0x0037 }, + { 0x000f, 0x0038 }, + { 0x0010, 0x005d }, + { 0x0011, 0x00a0 }, + { 0x0013, 0x009c }, + { 0x0012, 0x012c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0013, 0x00a9 }, + { 0x0013, 0x00aa }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0010, 0x005e }, + { 0x000f, 0x0039 }, + { 0x0010, 0x005f }, + { 0x0010, 0x0060 }, + { 0x0011, 0x00a1 }, + { 0x0010, 0x0061 }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0012, 0x012d }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0013, 0x00c1 }, + { 0x0013, 0x00c2 }, + { 0x0012, 0x012e }, + { 0x0011, 0x00a2 }, + { 0x0011, 0x00a3 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0012, 0x012f }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + { 0x0013, 0x0114 }, + { 0x0013, 0x0115 }, + { 0x0013, 0x0116 }, + { 0x0013, 0x0117 }, + { 0x0013, 0x0118 }, + { 0x0013, 0x0119 }, + { 0x0013, 0x011a }, + { 0x0013, 0x011b }, + { 0x0013, 0x011c }, + { 0x0013, 0x011d }, + { 0x0013, 0x011e }, + { 0x0013, 0x011f }, + { 0x0013, 0x0120 }, + { 0x0013, 0x0121 }, + { 0x0013, 0x0122 }, + { 0x0013, 0x0123 }, + { 0x0013, 0x0124 }, + { 0x0013, 0x0125 }, + { 0x0013, 0x0126 }, + { 0x0013, 0x0127 }, + { 0x0013, 0x0128 }, + { 0x0013, 0x0129 }, + { 0x0013, 0x012a }, + { 0x0013, 0x012b }, + { 0x0013, 0x012c }, + { 0x0013, 0x012d }, + { 0x0013, 0x012e }, + { 0x0013, 0x012f }, + { 0x0013, 0x0130 }, + { 0x0013, 0x0131 }, + { 0x0013, 0x0132 }, + { 0x0013, 0x0133 }, + { 0x0013, 0x0134 }, + { 0x0013, 0x0135 }, + { 0x0013, 0x0136 }, + { 0x0013, 0x0137 }, + { 0x0013, 0x0138 }, + { 0x0013, 0x0139 }, + { 0x0013, 0x013a }, + { 0x0013, 0x013b }, + { 0x0013, 0x013c }, + { 0x0013, 0x013d }, + { 0x0013, 0x013e }, + { 0x0013, 0x013f }, + { 0x0013, 0x0140 }, + { 0x0013, 0x0141 }, + { 0x0013, 0x0142 }, + { 0x0013, 0x0143 }, + { 0x0013, 0x0144 }, + { 0x0013, 0x0145 }, + { 0x0013, 0x0146 }, + { 0x0013, 0x0147 }, + { 0x0013, 0x0148 }, + { 0x0013, 0x0149 }, + { 0x0013, 0x014a }, + { 0x0013, 0x014b }, + { 0x0013, 0x014c }, + { 0x0013, 0x014d }, + { 0x0013, 0x014e }, + { 0x0013, 0x014f }, + { 0x0013, 0x0150 }, + { 0x0013, 0x0151 }, + { 0x0013, 0x0152 }, + { 0x0013, 0x0153 }, + { 0x0013, 0x0154 }, + { 0x0013, 0x0155 }, + { 0x0013, 0x0156 }, + { 0x0013, 0x0157 }, + { 0x0013, 0x0158 }, + { 0x0013, 0x0159 }, + { 0x0013, 0x015a }, + { 0x0013, 0x015b }, + { 0x0013, 0x015c }, + { 0x0013, 0x015d }, + { 0x0013, 0x015e }, + { 0x0013, 0x015f }, + { 0x0013, 0x0160 }, + { 0x0013, 0x0161 }, + { 0x0013, 0x0162 }, + { 0x0013, 0x0163 }, + { 0x0013, 0x0164 }, + { 0x0013, 0x0165 }, + { 0x0013, 0x0166 }, + { 0x0013, 0x0167 }, + { 0x0013, 0x0168 }, + { 0x0013, 0x0169 }, + { 0x0013, 0x016a }, + { 0x0013, 0x016b }, + { 0x0013, 0x016c }, + { 0x0013, 0x016d }, + { 0x0013, 0x016e }, + { 0x0013, 0x016f }, + { 0x0013, 0x0170 }, + { 0x0013, 0x0171 }, + { 0x0013, 0x0172 }, + { 0x0013, 0x0173 }, + { 0x0013, 0x0174 }, + { 0x0013, 0x0175 }, + { 0x0013, 0x0176 }, + { 0x0013, 0x0177 }, + { 0x0013, 0x0178 }, + { 0x0013, 0x0179 }, + { 0x0013, 0x017a }, + { 0x0013, 0x017b }, + { 0x0013, 0x017c }, + { 0x0013, 0x017d }, + { 0x0013, 0x017e }, + { 0x0013, 0x017f }, + { 0x0013, 0x0180 }, + { 0x0013, 0x0181 }, + { 0x0013, 0x0182 }, + { 0x0013, 0x0183 }, + { 0x0013, 0x0184 }, + { 0x0013, 0x0185 }, + { 0x0013, 0x0186 }, + { 0x0013, 0x0187 }, + { 0x0013, 0x0188 }, + { 0x0013, 0x0189 }, + { 0x0013, 0x018a }, + { 0x0013, 0x018b }, + { 0x0013, 0x018c }, + { 0x0013, 0x018d }, + { 0x0013, 0x018e }, + { 0x0013, 0x018f }, + { 0x0013, 0x0190 }, + { 0x0013, 0x0191 }, + { 0x0013, 0x0192 }, + { 0x0013, 0x0193 }, + { 0x0013, 0x0194 }, + { 0x0013, 0x0195 }, + { 0x0013, 0x0196 }, + { 0x0013, 0x0197 }, + { 0x0013, 0x0198 }, + { 0x0013, 0x0199 }, + { 0x0013, 0x019a }, + { 0x0013, 0x019b }, + { 0x0013, 0x019c }, + { 0x0013, 0x019d }, + { 0x0013, 0x019e }, + { 0x0013, 0x019f }, + { 0x0013, 0x01a0 }, + { 0x0013, 0x01a1 }, + { 0x0013, 0x01a2 }, + { 0x0013, 0x01a3 }, + { 0x0013, 0x01a4 }, + { 0x0013, 0x01a5 }, + { 0x0013, 0x01a6 }, + { 0x0013, 0x01a7 }, + { 0x0013, 0x01a8 }, + { 0x0013, 0x01a9 }, + { 0x0013, 0x01aa }, + { 0x0013, 0x01ab }, + { 0x0013, 0x01ac }, + { 0x0013, 0x01ad }, + { 0x0013, 0x01ae }, + { 0x0013, 0x01af }, + { 0x0013, 0x01b0 }, + { 0x0013, 0x01b1 }, + { 0x0013, 0x01b2 }, + { 0x0013, 0x01b3 }, + { 0x0013, 0x01b4 }, + { 0x0013, 0x01b5 }, + { 0x0013, 0x01b6 }, + { 0x0013, 0x01b7 }, + { 0x0013, 0x01b8 }, + { 0x0013, 0x01b9 }, + { 0x0013, 0x01ba }, + { 0x0013, 0x01bb }, + { 0x0013, 0x01bc }, + { 0x0013, 0x01bd }, + { 0x0013, 0x01be }, + { 0x0013, 0x01bf }, + { 0x0013, 0x01c0 }, + { 0x0013, 0x01c1 }, + { 0x0013, 0x01c2 }, + { 0x0013, 0x01c3 }, + { 0x0013, 0x01c4 }, + { 0x0013, 0x01c5 }, + { 0x0013, 0x01c6 }, + { 0x0013, 0x01c7 }, + { 0x0013, 0x01c8 }, + { 0x0013, 0x01c9 }, + { 0x0013, 0x01ca }, + { 0x0013, 0x01cb }, + { 0x0013, 0x01cc }, + { 0x0013, 0x01cd }, + { 0x0013, 0x01ce }, + { 0x0013, 0x01cf }, + { 0x0013, 0x01d0 }, + { 0x0013, 0x01d1 }, + { 0x0013, 0x01d2 }, + { 0x0013, 0x01d3 }, + { 0x0013, 0x01d4 }, + { 0x0013, 0x01d5 }, + { 0x0013, 0x01d6 }, + { 0x0013, 0x01d7 }, + { 0x0013, 0x01d8 }, + { 0x0013, 0x01d9 }, + { 0x0013, 0x01da }, + { 0x0013, 0x01db }, + { 0x0013, 0x01dc }, + { 0x0013, 0x01dd }, + { 0x0013, 0x01de }, + { 0x0013, 0x01df }, + { 0x0013, 0x01e0 }, + { 0x0013, 0x01e1 }, + { 0x0013, 0x01e2 }, + { 0x0013, 0x01e3 }, + { 0x0013, 0x01e4 }, + { 0x0013, 0x01e5 }, + { 0x0013, 0x01e6 }, + { 0x0013, 0x01e7 }, + { 0x0013, 0x01e8 }, + { 0x0013, 0x01e9 }, + { 0x0013, 0x01ea }, + { 0x0013, 0x01eb }, + { 0x0013, 0x01ec }, + { 0x0013, 0x01ed }, + { 0x0013, 0x01ee }, + { 0x0013, 0x01ef }, + { 0x0013, 0x01f0 }, + { 0x0013, 0x01f1 }, + { 0x0013, 0x01f2 }, + { 0x0013, 0x01f3 }, + { 0x0013, 0x01f4 }, + { 0x0013, 0x01f5 }, + { 0x0013, 0x01f6 }, + { 0x0013, 0x01f7 }, + { 0x0013, 0x01f8 }, + { 0x0013, 0x01f9 }, + { 0x0013, 0x01fa }, + { 0x0013, 0x01fb }, + { 0x0013, 0x01fc }, + { 0x0013, 0x01fd }, + { 0x0013, 0x01fe }, + { 0x0013, 0x01ff }, + { 0x0013, 0x0200 }, + { 0x0013, 0x0201 }, + { 0x0013, 0x0202 }, + { 0x0013, 0x0203 }, + { 0x0013, 0x0204 }, + { 0x0013, 0x0205 }, + { 0x0013, 0x0206 }, + { 0x0013, 0x0207 }, + { 0x0013, 0x0208 }, + { 0x0013, 0x0209 }, + { 0x0013, 0x020a }, + { 0x0013, 0x020b }, + { 0x0013, 0x020c }, + { 0x0013, 0x020d }, + { 0x0013, 0x020e }, + { 0x0013, 0x020f }, + { 0x0013, 0x0210 }, + { 0x0013, 0x0211 }, + { 0x0013, 0x0212 }, + { 0x0013, 0x0213 }, + { 0x0013, 0x0214 }, + { 0x0013, 0x0215 }, + { 0x0013, 0x0216 }, + { 0x0013, 0x0217 }, + { 0x0013, 0x0218 }, + { 0x0013, 0x0219 }, + { 0x0013, 0x021a }, + { 0x0013, 0x021b }, + { 0x0013, 0x021c }, + { 0x0013, 0x021d }, + { 0x0013, 0x021e }, + { 0x0013, 0x021f }, + { 0x0013, 0x0220 }, + { 0x0013, 0x0221 }, + { 0x0013, 0x0222 }, + { 0x0013, 0x0223 }, + { 0x0013, 0x0224 }, + { 0x0013, 0x0225 }, + { 0x0013, 0x0226 }, + { 0x0013, 0x0227 }, + { 0x0013, 0x0228 }, + { 0x0013, 0x0229 }, + { 0x0013, 0x022a }, + { 0x0013, 0x022b }, + { 0x0013, 0x022c }, + { 0x0013, 0x022d }, + { 0x0013, 0x022e }, + { 0x0013, 0x022f }, + { 0x0013, 0x0230 }, + { 0x0013, 0x0231 }, + { 0x0013, 0x0232 }, + { 0x0013, 0x0233 }, + { 0x0013, 0x0234 }, + { 0x0013, 0x0235 }, + { 0x0013, 0x0236 }, + { 0x0013, 0x0237 }, + { 0x0013, 0x0238 }, + { 0x0013, 0x0239 }, + { 0x0013, 0x023a }, + { 0x0013, 0x023b }, + { 0x0013, 0x023c }, + { 0x0013, 0x023d }, + { 0x0013, 0x023e }, + { 0x0013, 0x023f }, + { 0x0013, 0x0240 }, + { 0x0013, 0x0241 }, + { 0x0013, 0x0242 }, + { 0x0013, 0x0243 }, + { 0x0013, 0x0244 }, + { 0x0013, 0x0245 }, + { 0x0013, 0x0246 }, + { 0x0013, 0x0247 }, + { 0x0013, 0x0248 }, + { 0x0013, 0x0249 }, + { 0x0013, 0x024a }, + { 0x0013, 0x024b }, + { 0x0013, 0x024c }, + { 0x0013, 0x024d }, + { 0x0013, 0x024e }, + { 0x0013, 0x024f }, + { 0x0013, 0x0250 }, + { 0x0013, 0x0251 }, + { 0x0013, 0x0252 }, + { 0x0013, 0x0253 }, + + }; +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec49[113][16] = { + { + 0x0006ffff, + 0x0005ffff, + 0x0004ffff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x00010001, + 0x00010001, + 0x0001001b, + 0x0001001b, + 0x0001001c, + 0x0001001c, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + }, + { + 0x00020052, + 0x00020052, + 0x00020052, + 0x00020052, + 0x00020053, + 0x00020053, + 0x00020053, + 0x00020053, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + 0x00030002, + }, + { + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + }, + { + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + }, + { + 0x0001006d, + 0x0001006d, + 0x0001006e, + 0x0001006e, + 0x0001006f, + 0x0001006f, + 0x00010088, + 0x00010088, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x00020039, + 0x00020039, + 0x00020039, + 0x00020039, + }, + { + 0x00000070, + 0x00000087, + 0x00000089, + 0x0000008a, + 0x00010003, + 0x00010003, + 0x0001001f, + 0x0001001f, + 0x0001003a, + 0x0001003a, + 0x00010051, + 0x00010051, + 0x00010054, + 0x00010054, + 0x00010055, + 0x00010055, + }, + { + 0x000fffff, + 0x000effff, + 0x000cffff, + 0x000dffff, + 0x0007ffff, + 0x0008ffff, + 0x0009ffff, + 0x000affff, + 0x000bffff, + 0x00000004, + 0x00000005, + 0x00000020, + 0x00000021, + 0x0000003b, + 0x00000056, + 0x0000006c, + }, + { + 0x000200bf, + 0x000200bf, + 0x000200bf, + 0x000200bf, + 0x000200c0, + 0x000200c0, + 0x000200c0, + 0x000200c0, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + }, + { + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x0003003c, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + }, + { + 0x00030071, + 0x00030071, + 0x00030071, + 0x00030071, + 0x00030071, + 0x00030071, + 0x00030071, + 0x00030071, + 0x0003008b, + 0x0003008b, + 0x0003008b, + 0x0003008b, + 0x0003008b, + 0x0003008b, + 0x0003008b, + 0x0003008b, + }, + { + 0x000300a2, + 0x000300a2, + 0x000300a2, + 0x000300a2, + 0x000300a2, + 0x000300a2, + 0x000300a2, + 0x000300a2, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + 0x000300a3, + }, + { + 0x000300a4, + 0x000300a4, + 0x000300a4, + 0x000300a4, + 0x000300a4, + 0x000300a4, + 0x000300a4, + 0x000300a4, + 0x000300a5, + 0x000300a5, + 0x000300a5, + 0x000300a5, + 0x000300a5, + 0x000300a5, + 0x000300a5, + 0x000300a5, + }, + { + 0x0001008d, + 0x0001008d, + 0x000100a7, + 0x000100a7, + 0x000100bd, + 0x000100bd, + 0x000100d9, + 0x000100d9, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020022, + 0x0002003d, + 0x0002003d, + 0x0002003d, + 0x0002003d, + }, + { + 0x00020072, + 0x00020072, + 0x00020072, + 0x00020072, + 0x0002008c, + 0x0002008c, + 0x0002008c, + 0x0002008c, + 0x000200a6, + 0x000200a6, + 0x000200a6, + 0x000200a6, + 0x000200be, + 0x000200be, + 0x000200be, + 0x000200be, + }, + { + 0x00000059, + 0x00000073, + 0x0000008e, + 0x000000a8, + 0x000000c1, + 0x000000c2, + 0x000000d8, + 0x000000da, + 0x000000db, + 0x000000dc, + 0x00010007, + 0x00010007, + 0x00010023, + 0x00010023, + 0x00010058, + 0x00010058, + }, + { + 0x0023ffff, + 0x0034ffff, + 0x0045ffff, + 0x0056ffff, + 0x001affff, + 0x0019ffff, + 0x0018ffff, + 0x0015ffff, + 0x0016ffff, + 0x0017ffff, + 0x0011ffff, + 0x0010ffff, + 0x0012ffff, + 0x0013ffff, + 0x0014ffff, + 0x0000003e, + }, + { + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + }, + { + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + }, + { + 0x00030074, + 0x00030074, + 0x00030074, + 0x00030074, + 0x00030074, + 0x00030074, + 0x00030074, + 0x00030074, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + 0x000300a9, + }, + { + 0x000300c3, + 0x000300c3, + 0x000300c3, + 0x000300c3, + 0x000300c3, + 0x000300c3, + 0x000300c3, + 0x000300c3, + 0x000300f4, + 0x000300f4, + 0x000300f4, + 0x000300f4, + 0x000300f4, + 0x000300f4, + 0x000300f4, + 0x000300f4, + }, + { + 0x000300f5, + 0x000300f5, + 0x000300f5, + 0x000300f5, + 0x000300f5, + 0x000300f5, + 0x000300f5, + 0x000300f5, + 0x000300f6, + 0x000300f6, + 0x000300f6, + 0x000300f6, + 0x000300f6, + 0x000300f6, + 0x000300f6, + 0x000300f6, + }, + { + 0x00010112, + 0x00010112, + 0x0001012a, + 0x0001012a, + 0x0002005a, + 0x0002005a, + 0x0002005a, + 0x0002005a, + 0x00020075, + 0x00020075, + 0x00020075, + 0x00020075, + 0x0002008f, + 0x0002008f, + 0x0002008f, + 0x0002008f, + }, + { + 0x00020090, + 0x00020090, + 0x00020090, + 0x00020090, + 0x000200aa, + 0x000200aa, + 0x000200aa, + 0x000200aa, + 0x000200c4, + 0x000200c4, + 0x000200c4, + 0x000200c4, + 0x000200dd, + 0x000200dd, + 0x000200dd, + 0x000200dd, + }, + { + 0x000200de, + 0x000200de, + 0x000200de, + 0x000200de, + 0x000200f3, + 0x000200f3, + 0x000200f3, + 0x000200f3, + 0x000200f7, + 0x000200f7, + 0x000200f7, + 0x000200f7, + 0x00020110, + 0x00020110, + 0x00020110, + 0x00020110, + }, + { + 0x0000012c, + 0x0000012e, + 0x00010025, + 0x00010025, + 0x00010040, + 0x00010040, + 0x0001005b, + 0x0001005b, + 0x000100df, + 0x000100df, + 0x000100f8, + 0x000100f8, + 0x0001010f, + 0x0001010f, + 0x00010111, + 0x00010111, + }, + { + 0x001fffff, + 0x0020ffff, + 0x0000000a, + 0x00000026, + 0x00000041, + 0x00000091, + 0x000000ab, + 0x000000ac, + 0x000000c5, + 0x000000c6, + 0x000000e0, + 0x000000f9, + 0x0000010e, + 0x00000113, + 0x00000129, + 0x0000012b, + }, + { + 0x0067ffff, + 0x0068ffff, + 0x0069ffff, + 0x006affff, + 0x006bffff, + 0x006cffff, + 0x006dffff, + 0x006effff, + 0x006fffff, + 0x0070ffff, + 0x0021ffff, + 0x0022ffff, + 0x001cffff, + 0x001bffff, + 0x001dffff, + 0x001effff, + }, + { + 0x00030076, + 0x00030076, + 0x00030076, + 0x00030076, + 0x00030076, + 0x00030076, + 0x00030076, + 0x00030076, + 0x00030077, + 0x00030077, + 0x00030077, + 0x00030077, + 0x00030077, + 0x00030077, + 0x00030077, + 0x00030077, + }, + { + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + 0x0003005c, + }, + { + 0x00030092, + 0x00030092, + 0x00030092, + 0x00030092, + 0x00030092, + 0x00030092, + 0x00030092, + 0x00030092, + 0x000300e1, + 0x000300e1, + 0x000300e1, + 0x000300e1, + 0x000300e1, + 0x000300e1, + 0x000300e1, + 0x000300e1, + }, + { + 0x000300fa, + 0x000300fa, + 0x000300fa, + 0x000300fa, + 0x000300fa, + 0x000300fa, + 0x000300fa, + 0x000300fa, + 0x000300fb, + 0x000300fb, + 0x000300fb, + 0x000300fb, + 0x000300fb, + 0x000300fb, + 0x000300fb, + 0x000300fb, + }, + { + 0x00030114, + 0x00030114, + 0x00030114, + 0x00030114, + 0x00030114, + 0x00030114, + 0x00030114, + 0x00030114, + 0x0003012d, + 0x0003012d, + 0x0003012d, + 0x0003012d, + 0x0003012d, + 0x0003012d, + 0x0003012d, + 0x0003012d, + }, + { + 0x00030145, + 0x00030145, + 0x00030145, + 0x00030145, + 0x00030145, + 0x00030145, + 0x00030145, + 0x00030145, + 0x00030146, + 0x00030146, + 0x00030146, + 0x00030146, + 0x00030146, + 0x00030146, + 0x00030146, + 0x00030146, + }, + { + 0x000102d5, + 0x000102d5, + 0x000102d6, + 0x000102d6, + 0x000102d7, + 0x000102d7, + 0x000102d8, + 0x000102d8, + 0x00020027, + 0x00020027, + 0x00020027, + 0x00020027, + 0x000200fc, + 0x000200fc, + 0x000200fc, + 0x000200fc, + }, + { + 0x00020116, + 0x00020116, + 0x00020116, + 0x00020116, + 0x00020131, + 0x00020131, + 0x00020131, + 0x00020131, + 0x00020144, + 0x00020144, + 0x00020144, + 0x00020144, + 0x00020164, + 0x00020164, + 0x00020164, + 0x00020164, + }, + { + 0x0025ffff, + 0x0026ffff, + 0x0028ffff, + 0x002affff, + 0x002effff, + 0x0029ffff, + 0x0027ffff, + 0x0033ffff, + 0x002dffff, + 0x0024ffff, + 0x002bffff, + 0x002cffff, + 0x002fffff, + 0x0030ffff, + 0x0031ffff, + 0x0032ffff, + }, + { + 0x00010085, + 0x00010085, + 0x00010086, + 0x00010086, + 0x00010093, + 0x00010093, + 0x00010094, + 0x00010094, + 0x00010095, + 0x00010095, + 0x00010096, + 0x00010096, + 0x00010097, + 0x00010097, + 0x00010098, + 0x00010098, + }, + { + 0x0001000c, + 0x0001000c, + 0x0001000d, + 0x0001000d, + 0x0001000e, + 0x0001000e, + 0x0001000f, + 0x0001000f, + 0x00010010, + 0x00010010, + 0x00010011, + 0x00010011, + 0x00010012, + 0x00010012, + 0x00010013, + 0x00010013, + }, + { + 0x00010014, + 0x00010014, + 0x00010015, + 0x00010015, + 0x00010016, + 0x00010016, + 0x00010017, + 0x00010017, + 0x00010018, + 0x00010018, + 0x00010019, + 0x00010019, + 0x0001001a, + 0x0001001a, + 0x00010028, + 0x00010028, + }, + { + 0x00010061, + 0x00010061, + 0x00010062, + 0x00010062, + 0x00010063, + 0x00010063, + 0x00010064, + 0x00010064, + 0x00010065, + 0x00010065, + 0x00010066, + 0x00010066, + 0x00010067, + 0x00010067, + 0x00010068, + 0x00010068, + }, + { + 0x00010029, + 0x00010029, + 0x0001002a, + 0x0001002a, + 0x0001002b, + 0x0001002b, + 0x0001002c, + 0x0001002c, + 0x0001002d, + 0x0001002d, + 0x0001002e, + 0x0001002e, + 0x0001002f, + 0x0001002f, + 0x00010030, + 0x00010030, + }, + { + 0x0001004d, + 0x0001004d, + 0x0001004e, + 0x0001004e, + 0x0001004f, + 0x0001004f, + 0x00010050, + 0x00010050, + 0x0001005d, + 0x0001005d, + 0x0001005e, + 0x0001005e, + 0x0001005f, + 0x0001005f, + 0x00010060, + 0x00010060, + }, + { + 0x00010031, + 0x00010031, + 0x00010032, + 0x00010032, + 0x00010033, + 0x00010033, + 0x00010034, + 0x00010034, + 0x00010035, + 0x00010035, + 0x00010042, + 0x00010042, + 0x00010043, + 0x00010043, + 0x00010044, + 0x00010044, + }, + { + 0x00010099, + 0x00010099, + 0x0001009a, + 0x0001009a, + 0x0001009b, + 0x0001009b, + 0x0001009c, + 0x0001009c, + 0x0001009d, + 0x0001009d, + 0x0001009e, + 0x0001009e, + 0x0001009f, + 0x0001009f, + 0x000100a0, + 0x000100a0, + }, + { + 0x000100a1, + 0x000100a1, + 0x000100ad, + 0x000100ad, + 0x000100ae, + 0x000100ae, + 0x000100af, + 0x000100af, + 0x000100b0, + 0x000100b0, + 0x000100b1, + 0x000100b1, + 0x000100b2, + 0x000100b2, + 0x000100b3, + 0x000100b3, + }, + { + 0x0001007d, + 0x0001007d, + 0x0001007e, + 0x0001007e, + 0x0001007f, + 0x0001007f, + 0x00010080, + 0x00010080, + 0x00010081, + 0x00010081, + 0x00010082, + 0x00010082, + 0x00010083, + 0x00010083, + 0x00010084, + 0x00010084, + }, + { + 0x00010045, + 0x00010045, + 0x00010046, + 0x00010046, + 0x00010047, + 0x00010047, + 0x00010048, + 0x00010048, + 0x00010049, + 0x00010049, + 0x0001004a, + 0x0001004a, + 0x0001004b, + 0x0001004b, + 0x0001004c, + 0x0001004c, + }, + { + 0x000100b4, + 0x000100b4, + 0x000100b5, + 0x000100b5, + 0x000100b6, + 0x000100b6, + 0x000100b7, + 0x000100b7, + 0x000100b8, + 0x000100b8, + 0x000100b9, + 0x000100b9, + 0x000100ba, + 0x000100ba, + 0x000100bb, + 0x000100bb, + }, + { + 0x000100bc, + 0x000100bc, + 0x000100c7, + 0x000100c7, + 0x000100c8, + 0x000100c8, + 0x000100c9, + 0x000100c9, + 0x000100ca, + 0x000100ca, + 0x000100cb, + 0x000100cb, + 0x000100cc, + 0x000100cc, + 0x000100cd, + 0x000100cd, + }, + { + 0x000100ce, + 0x000100ce, + 0x000100cf, + 0x000100cf, + 0x000100d0, + 0x000100d0, + 0x000100d1, + 0x000100d1, + 0x000100d2, + 0x000100d2, + 0x000100d3, + 0x000100d3, + 0x000100d4, + 0x000100d4, + 0x000100d5, + 0x000100d5, + }, + { + 0x000100d6, + 0x000100d6, + 0x000100d7, + 0x000100d7, + 0x000100e2, + 0x000100e2, + 0x000100e3, + 0x000100e3, + 0x000100e4, + 0x000100e4, + 0x000100e5, + 0x000100e5, + 0x000100e6, + 0x000100e6, + 0x000100e7, + 0x000100e7, + }, + { + 0x00010069, + 0x00010069, + 0x0001006a, + 0x0001006a, + 0x0001006b, + 0x0001006b, + 0x00010078, + 0x00010078, + 0x00010079, + 0x00010079, + 0x0001007a, + 0x0001007a, + 0x0001007b, + 0x0001007b, + 0x0001007c, + 0x0001007c, + }, + { + 0x0035ffff, + 0x0036ffff, + 0x0037ffff, + 0x0038ffff, + 0x0039ffff, + 0x003affff, + 0x003bffff, + 0x003cffff, + 0x003dffff, + 0x003effff, + 0x003fffff, + 0x0040ffff, + 0x0041ffff, + 0x0042ffff, + 0x0043ffff, + 0x0044ffff, + }, + { + 0x000100e8, + 0x000100e8, + 0x000100e9, + 0x000100e9, + 0x000100ea, + 0x000100ea, + 0x000100eb, + 0x000100eb, + 0x000100ec, + 0x000100ec, + 0x000100ed, + 0x000100ed, + 0x000100ee, + 0x000100ee, + 0x000100ef, + 0x000100ef, + }, + { + 0x000100f0, + 0x000100f0, + 0x000100f1, + 0x000100f1, + 0x000100f2, + 0x000100f2, + 0x000100fd, + 0x000100fd, + 0x000100fe, + 0x000100fe, + 0x000100ff, + 0x000100ff, + 0x00010100, + 0x00010100, + 0x00010101, + 0x00010101, + }, + { + 0x00010102, + 0x00010102, + 0x00010103, + 0x00010103, + 0x00010104, + 0x00010104, + 0x00010105, + 0x00010105, + 0x00010106, + 0x00010106, + 0x00010107, + 0x00010107, + 0x00010108, + 0x00010108, + 0x00010109, + 0x00010109, + }, + { + 0x0001010a, + 0x0001010a, + 0x0001010b, + 0x0001010b, + 0x0001010c, + 0x0001010c, + 0x0001010d, + 0x0001010d, + 0x00010115, + 0x00010115, + 0x00010117, + 0x00010117, + 0x00010118, + 0x00010118, + 0x00010119, + 0x00010119, + }, + { + 0x0001011a, + 0x0001011a, + 0x0001011b, + 0x0001011b, + 0x0001011c, + 0x0001011c, + 0x0001011d, + 0x0001011d, + 0x0001011e, + 0x0001011e, + 0x0001011f, + 0x0001011f, + 0x00010120, + 0x00010120, + 0x00010121, + 0x00010121, + }, + { + 0x00010122, + 0x00010122, + 0x00010123, + 0x00010123, + 0x00010124, + 0x00010124, + 0x00010125, + 0x00010125, + 0x00010126, + 0x00010126, + 0x00010127, + 0x00010127, + 0x00010128, + 0x00010128, + 0x0001012f, + 0x0001012f, + }, + { + 0x00010130, + 0x00010130, + 0x00010132, + 0x00010132, + 0x00010133, + 0x00010133, + 0x00010134, + 0x00010134, + 0x00010135, + 0x00010135, + 0x00010136, + 0x00010136, + 0x00010137, + 0x00010137, + 0x00010138, + 0x00010138, + }, + { + 0x00010139, + 0x00010139, + 0x0001013a, + 0x0001013a, + 0x0001013b, + 0x0001013b, + 0x0001013c, + 0x0001013c, + 0x0001013d, + 0x0001013d, + 0x0001013e, + 0x0001013e, + 0x0001013f, + 0x0001013f, + 0x00010140, + 0x00010140, + }, + { + 0x00010141, + 0x00010141, + 0x00010142, + 0x00010142, + 0x00010143, + 0x00010143, + 0x00010147, + 0x00010147, + 0x00010148, + 0x00010148, + 0x00010149, + 0x00010149, + 0x0001014a, + 0x0001014a, + 0x0001014b, + 0x0001014b, + }, + { + 0x0001014c, + 0x0001014c, + 0x0001014d, + 0x0001014d, + 0x0001014e, + 0x0001014e, + 0x0001014f, + 0x0001014f, + 0x00010150, + 0x00010150, + 0x00010151, + 0x00010151, + 0x00010152, + 0x00010152, + 0x00010153, + 0x00010153, + }, + { + 0x00010154, + 0x00010154, + 0x00010155, + 0x00010155, + 0x00010156, + 0x00010156, + 0x00010157, + 0x00010157, + 0x00010158, + 0x00010158, + 0x00010159, + 0x00010159, + 0x0001015a, + 0x0001015a, + 0x0001015b, + 0x0001015b, + }, + { + 0x0001015c, + 0x0001015c, + 0x0001015d, + 0x0001015d, + 0x0001015e, + 0x0001015e, + 0x0001015f, + 0x0001015f, + 0x00010160, + 0x00010160, + 0x00010161, + 0x00010161, + 0x00010162, + 0x00010162, + 0x00010163, + 0x00010163, + }, + { + 0x00010165, + 0x00010165, + 0x00010166, + 0x00010166, + 0x00010167, + 0x00010167, + 0x00010168, + 0x00010168, + 0x00010169, + 0x00010169, + 0x0001016a, + 0x0001016a, + 0x0001016b, + 0x0001016b, + 0x0001016c, + 0x0001016c, + }, + { + 0x0001016d, + 0x0001016d, + 0x0001016e, + 0x0001016e, + 0x0001016f, + 0x0001016f, + 0x00010170, + 0x00010170, + 0x00010171, + 0x00010171, + 0x00010172, + 0x00010172, + 0x00010173, + 0x00010173, + 0x00010174, + 0x00010174, + }, + { + 0x00010175, + 0x00010175, + 0x00010176, + 0x00010176, + 0x00010177, + 0x00010177, + 0x00010178, + 0x00010178, + 0x00010179, + 0x00010179, + 0x0001017a, + 0x0001017a, + 0x0001017b, + 0x0001017b, + 0x0001017c, + 0x0001017c, + }, + { + 0x0001017d, + 0x0001017d, + 0x0001017e, + 0x0001017e, + 0x0001017f, + 0x0001017f, + 0x00010180, + 0x00010180, + 0x00010181, + 0x00010181, + 0x00010182, + 0x00010182, + 0x00010183, + 0x00010183, + 0x00010184, + 0x00010184, + }, + { + 0x0046ffff, + 0x0047ffff, + 0x0048ffff, + 0x0049ffff, + 0x004affff, + 0x004bffff, + 0x004cffff, + 0x004dffff, + 0x004effff, + 0x004fffff, + 0x0050ffff, + 0x0051ffff, + 0x0052ffff, + 0x0053ffff, + 0x0054ffff, + 0x0055ffff, + }, + { + 0x00010185, + 0x00010185, + 0x00010186, + 0x00010186, + 0x00010187, + 0x00010187, + 0x00010188, + 0x00010188, + 0x00010189, + 0x00010189, + 0x0001018a, + 0x0001018a, + 0x0001018b, + 0x0001018b, + 0x0001018c, + 0x0001018c, + }, + { + 0x0001018d, + 0x0001018d, + 0x0001018e, + 0x0001018e, + 0x0001018f, + 0x0001018f, + 0x00010190, + 0x00010190, + 0x00010191, + 0x00010191, + 0x00010192, + 0x00010192, + 0x00010193, + 0x00010193, + 0x00010194, + 0x00010194, + }, + { + 0x00010195, + 0x00010195, + 0x00010196, + 0x00010196, + 0x00010197, + 0x00010197, + 0x00010198, + 0x00010198, + 0x00010199, + 0x00010199, + 0x0001019a, + 0x0001019a, + 0x0001019b, + 0x0001019b, + 0x0001019c, + 0x0001019c, + }, + { + 0x0001019d, + 0x0001019d, + 0x0001019e, + 0x0001019e, + 0x0001019f, + 0x0001019f, + 0x000101a0, + 0x000101a0, + 0x000101a1, + 0x000101a1, + 0x000101a2, + 0x000101a2, + 0x000101a3, + 0x000101a3, + 0x000101a4, + 0x000101a4, + }, + { + 0x000101a5, + 0x000101a5, + 0x000101a6, + 0x000101a6, + 0x000101a7, + 0x000101a7, + 0x000101a8, + 0x000101a8, + 0x000101a9, + 0x000101a9, + 0x000101aa, + 0x000101aa, + 0x000101ab, + 0x000101ab, + 0x000101ac, + 0x000101ac, + }, + { + 0x000101ad, + 0x000101ad, + 0x000101ae, + 0x000101ae, + 0x000101af, + 0x000101af, + 0x000101b0, + 0x000101b0, + 0x000101b1, + 0x000101b1, + 0x000101b2, + 0x000101b2, + 0x000101b3, + 0x000101b3, + 0x000101b4, + 0x000101b4, + }, + { + 0x000101b5, + 0x000101b5, + 0x000101b6, + 0x000101b6, + 0x000101b7, + 0x000101b7, + 0x000101b8, + 0x000101b8, + 0x000101b9, + 0x000101b9, + 0x000101ba, + 0x000101ba, + 0x000101bb, + 0x000101bb, + 0x000101bc, + 0x000101bc, + }, + { + 0x000101bd, + 0x000101bd, + 0x000101be, + 0x000101be, + 0x000101bf, + 0x000101bf, + 0x000101c0, + 0x000101c0, + 0x000101c1, + 0x000101c1, + 0x000101c2, + 0x000101c2, + 0x000101c3, + 0x000101c3, + 0x000101c4, + 0x000101c4, + }, + { + 0x000101c5, + 0x000101c5, + 0x000101c6, + 0x000101c6, + 0x000101c7, + 0x000101c7, + 0x000101c8, + 0x000101c8, + 0x000101c9, + 0x000101c9, + 0x000101ca, + 0x000101ca, + 0x000101cb, + 0x000101cb, + 0x000101cc, + 0x000101cc, + }, + { + 0x000101cd, + 0x000101cd, + 0x000101ce, + 0x000101ce, + 0x000101cf, + 0x000101cf, + 0x000101d0, + 0x000101d0, + 0x000101d1, + 0x000101d1, + 0x000101d2, + 0x000101d2, + 0x000101d3, + 0x000101d3, + 0x000101d4, + 0x000101d4, + }, + { + 0x000101d5, + 0x000101d5, + 0x000101d6, + 0x000101d6, + 0x000101d7, + 0x000101d7, + 0x000101d8, + 0x000101d8, + 0x000101d9, + 0x000101d9, + 0x000101da, + 0x000101da, + 0x000101db, + 0x000101db, + 0x000101dc, + 0x000101dc, + }, + { + 0x000101dd, + 0x000101dd, + 0x000101de, + 0x000101de, + 0x000101df, + 0x000101df, + 0x000101e0, + 0x000101e0, + 0x000101e1, + 0x000101e1, + 0x000101e2, + 0x000101e2, + 0x000101e3, + 0x000101e3, + 0x000101e4, + 0x000101e4, + }, + { + 0x000101e5, + 0x000101e5, + 0x000101e6, + 0x000101e6, + 0x000101e7, + 0x000101e7, + 0x000101e8, + 0x000101e8, + 0x000101e9, + 0x000101e9, + 0x000101ea, + 0x000101ea, + 0x000101eb, + 0x000101eb, + 0x000101ec, + 0x000101ec, + }, + { + 0x000101ed, + 0x000101ed, + 0x000101ee, + 0x000101ee, + 0x000101ef, + 0x000101ef, + 0x000101f0, + 0x000101f0, + 0x000101f1, + 0x000101f1, + 0x000101f2, + 0x000101f2, + 0x000101f3, + 0x000101f3, + 0x000101f4, + 0x000101f4, + }, + { + 0x000101f5, + 0x000101f5, + 0x000101f6, + 0x000101f6, + 0x000101f7, + 0x000101f7, + 0x000101f8, + 0x000101f8, + 0x000101f9, + 0x000101f9, + 0x000101fa, + 0x000101fa, + 0x000101fb, + 0x000101fb, + 0x000101fc, + 0x000101fc, + }, + { + 0x000101fd, + 0x000101fd, + 0x000101fe, + 0x000101fe, + 0x000101ff, + 0x000101ff, + 0x00010200, + 0x00010200, + 0x00010201, + 0x00010201, + 0x00010202, + 0x00010202, + 0x00010203, + 0x00010203, + 0x00010204, + 0x00010204, + }, + { + 0x0057ffff, + 0x0058ffff, + 0x0059ffff, + 0x005affff, + 0x005bffff, + 0x005cffff, + 0x005dffff, + 0x005effff, + 0x005fffff, + 0x0060ffff, + 0x0061ffff, + 0x0062ffff, + 0x0063ffff, + 0x0064ffff, + 0x0065ffff, + 0x0066ffff, + }, + { + 0x00010205, + 0x00010205, + 0x00010206, + 0x00010206, + 0x00010207, + 0x00010207, + 0x00010208, + 0x00010208, + 0x00010209, + 0x00010209, + 0x0001020a, + 0x0001020a, + 0x0001020b, + 0x0001020b, + 0x0001020c, + 0x0001020c, + }, + { + 0x0001020d, + 0x0001020d, + 0x0001020e, + 0x0001020e, + 0x0001020f, + 0x0001020f, + 0x00010210, + 0x00010210, + 0x00010211, + 0x00010211, + 0x00010212, + 0x00010212, + 0x00010213, + 0x00010213, + 0x00010214, + 0x00010214, + }, + { + 0x00010215, + 0x00010215, + 0x00010216, + 0x00010216, + 0x00010217, + 0x00010217, + 0x00010218, + 0x00010218, + 0x00010219, + 0x00010219, + 0x0001021a, + 0x0001021a, + 0x0001021b, + 0x0001021b, + 0x0001021c, + 0x0001021c, + }, + { + 0x0001021d, + 0x0001021d, + 0x0001021e, + 0x0001021e, + 0x0001021f, + 0x0001021f, + 0x00010220, + 0x00010220, + 0x00010221, + 0x00010221, + 0x00010222, + 0x00010222, + 0x00010223, + 0x00010223, + 0x00010224, + 0x00010224, + }, + { + 0x00010225, + 0x00010225, + 0x00010226, + 0x00010226, + 0x00010227, + 0x00010227, + 0x00010228, + 0x00010228, + 0x00010229, + 0x00010229, + 0x0001022a, + 0x0001022a, + 0x0001022b, + 0x0001022b, + 0x0001022c, + 0x0001022c, + }, + { + 0x0001022d, + 0x0001022d, + 0x0001022e, + 0x0001022e, + 0x0001022f, + 0x0001022f, + 0x00010230, + 0x00010230, + 0x00010231, + 0x00010231, + 0x00010232, + 0x00010232, + 0x00010233, + 0x00010233, + 0x00010234, + 0x00010234, + }, + { + 0x00010235, + 0x00010235, + 0x00010236, + 0x00010236, + 0x00010237, + 0x00010237, + 0x00010238, + 0x00010238, + 0x00010239, + 0x00010239, + 0x0001023a, + 0x0001023a, + 0x0001023b, + 0x0001023b, + 0x0001023c, + 0x0001023c, + }, + { + 0x0001023d, + 0x0001023d, + 0x0001023e, + 0x0001023e, + 0x0001023f, + 0x0001023f, + 0x00010240, + 0x00010240, + 0x00010241, + 0x00010241, + 0x00010242, + 0x00010242, + 0x00010243, + 0x00010243, + 0x00010244, + 0x00010244, + }, + { + 0x00010245, + 0x00010245, + 0x00010246, + 0x00010246, + 0x00010247, + 0x00010247, + 0x00010248, + 0x00010248, + 0x00010249, + 0x00010249, + 0x0001024a, + 0x0001024a, + 0x0001024b, + 0x0001024b, + 0x0001024c, + 0x0001024c, + }, + { + 0x0001024d, + 0x0001024d, + 0x0001024e, + 0x0001024e, + 0x0001024f, + 0x0001024f, + 0x00010250, + 0x00010250, + 0x00010251, + 0x00010251, + 0x00010252, + 0x00010252, + 0x00010253, + 0x00010253, + 0x00010254, + 0x00010254, + }, + { + 0x00010255, + 0x00010255, + 0x00010256, + 0x00010256, + 0x00010257, + 0x00010257, + 0x00010258, + 0x00010258, + 0x00010259, + 0x00010259, + 0x0001025a, + 0x0001025a, + 0x0001025b, + 0x0001025b, + 0x0001025c, + 0x0001025c, + }, + { + 0x0001025d, + 0x0001025d, + 0x0001025e, + 0x0001025e, + 0x0001025f, + 0x0001025f, + 0x00010260, + 0x00010260, + 0x00010261, + 0x00010261, + 0x00010262, + 0x00010262, + 0x00010263, + 0x00010263, + 0x00010264, + 0x00010264, + }, + { + 0x00010265, + 0x00010265, + 0x00010266, + 0x00010266, + 0x00010267, + 0x00010267, + 0x00010268, + 0x00010268, + 0x00010269, + 0x00010269, + 0x0001026a, + 0x0001026a, + 0x0001026b, + 0x0001026b, + 0x0001026c, + 0x0001026c, + }, + { + 0x0001026d, + 0x0001026d, + 0x0001026e, + 0x0001026e, + 0x0001026f, + 0x0001026f, + 0x00010270, + 0x00010270, + 0x00010271, + 0x00010271, + 0x00010272, + 0x00010272, + 0x00010273, + 0x00010273, + 0x00010274, + 0x00010274, + }, + { + 0x00010275, + 0x00010275, + 0x00010276, + 0x00010276, + 0x00010277, + 0x00010277, + 0x00010278, + 0x00010278, + 0x00010279, + 0x00010279, + 0x0001027a, + 0x0001027a, + 0x0001027b, + 0x0001027b, + 0x0001027c, + 0x0001027c, + }, + { + 0x0001027d, + 0x0001027d, + 0x0001027e, + 0x0001027e, + 0x0001027f, + 0x0001027f, + 0x00010280, + 0x00010280, + 0x00010281, + 0x00010281, + 0x00010282, + 0x00010282, + 0x00010283, + 0x00010283, + 0x00010284, + 0x00010284, + }, + { + 0x00010285, + 0x00010285, + 0x00010286, + 0x00010286, + 0x00010287, + 0x00010287, + 0x00010288, + 0x00010288, + 0x00010289, + 0x00010289, + 0x0001028a, + 0x0001028a, + 0x0001028b, + 0x0001028b, + 0x0001028c, + 0x0001028c, + }, + { + 0x0001028d, + 0x0001028d, + 0x0001028e, + 0x0001028e, + 0x0001028f, + 0x0001028f, + 0x00010290, + 0x00010290, + 0x00010291, + 0x00010291, + 0x00010292, + 0x00010292, + 0x00010293, + 0x00010293, + 0x00010294, + 0x00010294, + }, + { + 0x00010295, + 0x00010295, + 0x00010296, + 0x00010296, + 0x00010297, + 0x00010297, + 0x00010298, + 0x00010298, + 0x00010299, + 0x00010299, + 0x0001029a, + 0x0001029a, + 0x0001029b, + 0x0001029b, + 0x0001029c, + 0x0001029c, + }, + { + 0x0001029d, + 0x0001029d, + 0x0001029e, + 0x0001029e, + 0x0001029f, + 0x0001029f, + 0x000102a0, + 0x000102a0, + 0x000102a1, + 0x000102a1, + 0x000102a2, + 0x000102a2, + 0x000102a3, + 0x000102a3, + 0x000102a4, + 0x000102a4, + }, + { + 0x000102a5, + 0x000102a5, + 0x000102a6, + 0x000102a6, + 0x000102a7, + 0x000102a7, + 0x000102a8, + 0x000102a8, + 0x000102a9, + 0x000102a9, + 0x000102aa, + 0x000102aa, + 0x000102ab, + 0x000102ab, + 0x000102ac, + 0x000102ac, + }, + { + 0x000102ad, + 0x000102ad, + 0x000102ae, + 0x000102ae, + 0x000102af, + 0x000102af, + 0x000102b0, + 0x000102b0, + 0x000102b1, + 0x000102b1, + 0x000102b2, + 0x000102b2, + 0x000102b3, + 0x000102b3, + 0x000102b4, + 0x000102b4, + }, + { + 0x000102b5, + 0x000102b5, + 0x000102b6, + 0x000102b6, + 0x000102b7, + 0x000102b7, + 0x000102b8, + 0x000102b8, + 0x000102b9, + 0x000102b9, + 0x000102ba, + 0x000102ba, + 0x000102bb, + 0x000102bb, + 0x000102bc, + 0x000102bc, + }, + { + 0x000102bd, + 0x000102bd, + 0x000102be, + 0x000102be, + 0x000102bf, + 0x000102bf, + 0x000102c0, + 0x000102c0, + 0x000102c1, + 0x000102c1, + 0x000102c2, + 0x000102c2, + 0x000102c3, + 0x000102c3, + 0x000102c4, + 0x000102c4, + }, + { + 0x000102c5, + 0x000102c5, + 0x000102c6, + 0x000102c6, + 0x000102c7, + 0x000102c7, + 0x000102c8, + 0x000102c8, + 0x000102c9, + 0x000102c9, + 0x000102ca, + 0x000102ca, + 0x000102cb, + 0x000102cb, + 0x000102cc, + 0x000102cc, + }, + { + 0x000102cd, + 0x000102cd, + 0x000102ce, + 0x000102ce, + 0x000102cf, + 0x000102cf, + 0x000102d0, + 0x000102d0, + 0x000102d1, + 0x000102d1, + 0x000102d2, + 0x000102d2, + 0x000102d3, + 0x000102d3, + 0x000102d4, + 0x000102d4, + }, +}; +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc50[28][2] = +#else +const uint16_t c_aauiCQMFHuffEnc50[28][2] = +#endif + { + { 0x0002, 0x0001 }, + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0005, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0005 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + + }; +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec50[6][16] = { + { + 0x0001ffff, + 0x00000004, + 0x00010003, + 0x00010003, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + }, + { + 0x0002ffff, + 0x00000008, + 0x00010007, + 0x00010007, + 0x00020006, + 0x00020006, + 0x00020006, + 0x00020006, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + }, + { + 0x0003ffff, + 0x0000000c, + 0x0001000b, + 0x0001000b, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + }, + { + 0x0005ffff, + 0x0004ffff, + 0x0001000f, + 0x0001000f, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + }, + { + 0x0001001a, + 0x0001001a, + 0x0001001b, + 0x0001001b, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + 0x00030010, + }, + { + 0x00010012, + 0x00010012, + 0x00010013, + 0x00010013, + 0x00010014, + 0x00010014, + 0x00010015, + 0x00010015, + 0x00010016, + 0x00010016, + 0x00010017, + 0x00010017, + 0x00010018, + 0x00010018, + 0x00010019, + 0x00010019, + }, +}; +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc51[29][2] = +#else +const uint16_t c_aauiCQMFHuffEnc51[29][2] = +#endif + { + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0001 }, + { 0x0004, 0x0002 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + + }; +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec51[6][16] = { + { + 0x0001ffff, + 0x00000004, + 0x00000005, + 0x00000006, + 0x00010002, + 0x00010002, + 0x00010003, + 0x00010003, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020001, + }, + { + 0x0002ffff, + 0x0000000a, + 0x00010009, + 0x00010009, + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020008, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + }, + { + 0x0003ffff, + 0x0000000e, + 0x0001000d, + 0x0001000d, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + }, + { + 0x0004ffff, + 0x0005ffff, + 0x00000011, + 0x00000012, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020010, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + }, + { + 0x00010015, + 0x00010015, + 0x00010016, + 0x00010016, + 0x00010017, + 0x00010017, + 0x00010018, + 0x00010018, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020014, + }, + { + 0x00020019, + 0x00020019, + 0x00020019, + 0x00020019, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001c, + }, +}; +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc52[32][2] = +#else +const uint16_t c_aauiCQMFHuffEnc52[32][2] = +#endif + { + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0002 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0001 }, + { 0x0011, 0x0002 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0003 }, + { 0x0014, 0x0000 }, + { 0x0013, 0x0003 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + }; +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec52[7][16] = { + { + 0x0001ffff, + 0x0002ffff, + 0x00000004, + 0x00000005, + 0x00010002, + 0x00010002, + 0x00010003, + 0x00010003, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020001, + }, + { + 0x0003ffff, + 0x0000000b, + 0x0001000a, + 0x0001000a, + 0x00020009, + 0x00020009, + 0x00020009, + 0x00020009, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + }, + { + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + }, + { + 0x0004ffff, + 0x0000000f, + 0x0001000e, + 0x0001000e, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + }, + { + 0x0006ffff, + 0x0005ffff, + 0x00010013, + 0x00010013, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + }, + { + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + }, + { + 0x00000017, + 0x00000019, + 0x0000001a, + 0x0000001b, + 0x0000001c, + 0x0000001d, + 0x00010018, + 0x00010018, + 0x0001001e, + 0x0001001e, + 0x0001001f, + 0x0001001f, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020016, + }, +}; +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc53[37][2] = +#else +const uint16_t c_aauiCQMFHuffEnc53[37][2] = +#endif + { + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0002 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0011, 0x0004 }, + { 0x0010, 0x0003 }, + { 0x0011, 0x0005 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + + }; +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec53[9][16] = { + { + 0x0002ffff, + 0x0001ffff, + 0x00000004, + 0x00000005, + 0x00010002, + 0x00010002, + 0x00010003, + 0x00010003, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020001, + }, + { + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + }, + { + 0x0003ffff, + 0x0000000d, + 0x0001000a, + 0x0001000a, + 0x0001000b, + 0x0001000b, + 0x0001000c, + 0x0001000c, + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020009, + 0x00020009, + 0x00020009, + 0x00020009, + }, + { + 0x0005ffff, + 0x0004ffff, + 0x00000011, + 0x00000012, + 0x0001000f, + 0x0001000f, + 0x00010010, + 0x00010010, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + 0x0003000e, + }, + { + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + }, + { + 0x0007ffff, + 0x0008ffff, + 0x0006ffff, + 0x0000001a, + 0x00010017, + 0x00010017, + 0x00010018, + 0x00010018, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020016, + }, + { + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + }, + { + 0x0001001c, + 0x0001001c, + 0x0001001d, + 0x0001001d, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + }, + { + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020024, + 0x00020024, + 0x00020024, + 0x00020024, + }, +}; +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc54[39][2] = +#else +const uint16_t c_aauiCQMFHuffEnc54[39][2] = +#endif + { + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0011, 0x0002 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + + }; +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec54[9][16] = { + { + 0x0003ffff, + 0x0001ffff, + 0x0002ffff, + 0x00000004, + 0x00010002, + 0x00010002, + 0x00010003, + 0x00010003, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020000, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020001, + }, + { + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + }, + { + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + }, + { + 0x0004ffff, + 0x0000000e, + 0x0000000f, + 0x00000010, + 0x0001000c, + 0x0001000c, + 0x0001000d, + 0x0001000d, + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020009, + 0x00020009, + 0x00020009, + 0x00020009, + }, + { + 0x0006ffff, + 0x0005ffff, + 0x00000015, + 0x00000016, + 0x00010013, + 0x00010013, + 0x00010014, + 0x00010014, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + }, + { + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + }, + { + 0x0008ffff, + 0x0007ffff, + 0x0000001e, + 0x0000001f, + 0x0001001b, + 0x0001001b, + 0x0001001c, + 0x0001001c, + 0x00020019, + 0x00020019, + 0x00020019, + 0x00020019, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001a, + }, + { + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + 0x00030020, + }, + { + 0x00010023, + 0x00010023, + 0x00010024, + 0x00010024, + 0x00010025, + 0x00010025, + 0x00010026, + 0x00010026, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020022, + }, +}; +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc55[46][2] = +#else +const uint16_t c_aauiCQMFHuffEnc55[46][2] = +#endif + { + { 0x0003, 0x0003 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0003 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + + }; +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec55[10][16] = { + { + 0x0003ffff, + 0x0001ffff, + 0x0002ffff, + 0x00000004, + 0x00000005, + 0x00000006, + 0x00010000, + 0x00010000, + 0x00010002, + 0x00010002, + 0x00010003, + 0x00010003, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020001, + }, + { + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + }, + { + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + }, + { + 0x0005ffff, + 0x0004ffff, + 0x00000011, + 0x00000012, + 0x0001000d, + 0x0001000d, + 0x0001000e, + 0x0001000e, + 0x0001000f, + 0x0001000f, + 0x00010010, + 0x00010010, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000a, + }, + { + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030013, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + }, + { + 0x0007ffff, + 0x0006ffff, + 0x00000019, + 0x0000001a, + 0x00010017, + 0x00010017, + 0x00010018, + 0x00010018, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020016, + }, + { + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001b, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + }, + { + 0x0009ffff, + 0x0008ffff, + 0x00000020, + 0x00000021, + 0x00000022, + 0x00000023, + 0x0001001f, + 0x0001001f, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001d, + 0x0002001e, + 0x0002001e, + 0x0002001e, + 0x0002001e, + }, + { + 0x00020026, + 0x00020026, + 0x00020026, + 0x00020026, + 0x00020027, + 0x00020027, + 0x00020027, + 0x00020027, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + }, + { + 0x00010028, + 0x00010028, + 0x00010029, + 0x00010029, + 0x0001002a, + 0x0001002a, + 0x0001002b, + 0x0001002b, + 0x0001002c, + 0x0001002c, + 0x0001002d, + 0x0001002d, + 0x00020025, + 0x00020025, + 0x00020025, + 0x00020025, + }, +}; +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc56[55][2] = +#else +const uint16_t c_aauiCQMFHuffEnc56[55][2] = +#endif + { + { 0x0003, 0x0003 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0010, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0013, 0x0000 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0005 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + + }; +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec56[12][16] = { + { + 0x0004ffff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x00000004, + 0x00000005, + 0x00010000, + 0x00010000, + 0x00010002, + 0x00010002, + 0x00010003, + 0x00010003, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020001, + }, + { + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + }, + { + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + }, + { + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + }, + { + 0x0006ffff, + 0x0005ffff, + 0x00000011, + 0x00000012, + 0x00000013, + 0x00000014, + 0x0001000e, + 0x0001000e, + 0x0001000f, + 0x0001000f, + 0x00010010, + 0x00010010, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000b, + }, + { + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + }, + { + 0x0009ffff, + 0x0007ffff, + 0x0008ffff, + 0x0000001a, + 0x0000001b, + 0x0000001c, + 0x00010019, + 0x00010019, + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020017, + 0x00020018, + 0x00020018, + 0x00020018, + 0x00020018, + }, + { + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020022, + 0x00020022, + 0x00020022, + 0x00020022, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + }, + { + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + 0x0003001f, + }, + { + 0x000bffff, + 0x000affff, + 0x00000025, + 0x00000026, + 0x00000027, + 0x00000028, + 0x00000029, + 0x0000002a, + 0x00010023, + 0x00010023, + 0x00010024, + 0x00010024, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + }, + { + 0x00010035, + 0x00010035, + 0x00010036, + 0x00010036, + 0x0002002d, + 0x0002002d, + 0x0002002d, + 0x0002002d, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + }, + { + 0x0001002b, + 0x0001002b, + 0x0001002e, + 0x0001002e, + 0x0001002f, + 0x0001002f, + 0x00010030, + 0x00010030, + 0x00010031, + 0x00010031, + 0x00010032, + 0x00010032, + 0x00010033, + 0x00010033, + 0x00010034, + 0x00010034, + }, +}; +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc57[65][2] = +#else +const uint16_t c_aauiCQMFHuffEnc57[65][2] = +#endif + { + { 0x0003, 0x0004 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000d, 0x0003 }, + { 0x000c, 0x0005 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000f, 0x0003 }, + { 0x0010, 0x0003 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0013, 0x0000 }, + { 0x0011, 0x0005 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0012, 0x0007 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + + }; +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec57[14][16] = { + { + 0x0004ffff, + 0x0003ffff, + 0x0001ffff, + 0x0002ffff, + 0x00000003, + 0x00000004, + 0x00000005, + 0x00000006, + 0x00010000, + 0x00010000, + 0x00010002, + 0x00010002, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020001, + }, + { + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + }, + { + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + }, + { + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + }, + { + 0x0007ffff, + 0x0005ffff, + 0x0006ffff, + 0x00000014, + 0x00000015, + 0x00000016, + 0x0001000f, + 0x0001000f, + 0x00010010, + 0x00010010, + 0x00010011, + 0x00010011, + 0x00010012, + 0x00010012, + 0x00010013, + 0x00010013, + }, + { + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x0002001c, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + 0x00030017, + }, + { + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030018, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + 0x00030019, + }, + { + 0x000affff, + 0x0008ffff, + 0x0009ffff, + 0x00000020, + 0x00000021, + 0x00000023, + 0x0001001d, + 0x0001001d, + 0x0001001e, + 0x0001001e, + 0x0001001f, + 0x0001001f, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001a, + }, + { + 0x00020027, + 0x00020027, + 0x00020027, + 0x00020027, + 0x00020028, + 0x00020028, + 0x00020028, + 0x00020028, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + }, + { + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + }, + { + 0x000dffff, + 0x000cffff, + 0x000bffff, + 0x0000002a, + 0x0000002d, + 0x0000002e, + 0x00010029, + 0x00010029, + 0x0001002b, + 0x0001002b, + 0x0001002c, + 0x0001002c, + 0x00020026, + 0x00020026, + 0x00020026, + 0x00020026, + }, + { + 0x00020036, + 0x00020036, + 0x00020036, + 0x00020036, + 0x00020037, + 0x00020037, + 0x00020037, + 0x00020037, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + }, + { + 0x0001003b, + 0x0001003b, + 0x0001003c, + 0x0001003c, + 0x0001003d, + 0x0001003d, + 0x0001003e, + 0x0001003e, + 0x0001003f, + 0x0001003f, + 0x00010040, + 0x00010040, + 0x00020033, + 0x00020033, + 0x00020033, + 0x00020033, + }, + { + 0x0001002f, + 0x0001002f, + 0x00010031, + 0x00010031, + 0x00010032, + 0x00010032, + 0x00010034, + 0x00010034, + 0x00010035, + 0x00010035, + 0x00010038, + 0x00010038, + 0x00010039, + 0x00010039, + 0x0001003a, + 0x0001003a, + }, +}; +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc58[77][2] = +#else +const uint16_t c_aauiCQMFHuffEnc58[77][2] = +#endif + { + { 0x0004, 0x0005 }, + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x0010, 0x0004 }, + { 0x000f, 0x0007 }, + { 0x0010, 0x0005 }, + { 0x0010, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0012, 0x0006 }, + { 0x0011, 0x0007 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0012, 0x0007 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + + }; +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec58[17][16] = { + { + 0x0005ffff, + 0x0004ffff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x00000000, + 0x00000004, + 0x00000005, + 0x00000006, + 0x00000007, + 0x00010001, + 0x00010001, + 0x00010002, + 0x00010002, + 0x00010003, + 0x00010003, + }, + { + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + }, + { + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + }, + { + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + }, + { + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020010, + }, + { + 0x0008ffff, + 0x0006ffff, + 0x0007ffff, + 0x00000017, + 0x00000018, + 0x00000019, + 0x0000001a, + 0x0000001b, + 0x00010013, + 0x00010013, + 0x00010014, + 0x00010014, + 0x00010015, + 0x00010015, + 0x00010016, + 0x00010016, + }, + { + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020021, + 0x00020021, + 0x00020021, + 0x00020021, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + }, + { + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001d, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + 0x0003001e, + }, + { + 0x000cffff, + 0x000bffff, + 0x0009ffff, + 0x000affff, + 0x00000024, + 0x00000025, + 0x00000026, + 0x00000027, + 0x00010022, + 0x00010022, + 0x00010023, + 0x00010023, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + }, + { + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + }, + { + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + }, + { + 0x0002002c, + 0x0002002c, + 0x0002002c, + 0x0002002c, + 0x0002002d, + 0x0002002d, + 0x0002002d, + 0x0002002d, + 0x0002002e, + 0x0002002e, + 0x0002002e, + 0x0002002e, + 0x0002002f, + 0x0002002f, + 0x0002002f, + 0x0002002f, + }, + { + 0x0010ffff, + 0x000effff, + 0x000fffff, + 0x000dffff, + 0x00000033, + 0x00000035, + 0x00000036, + 0x00000037, + 0x00010030, + 0x00010030, + 0x00010031, + 0x00010031, + 0x00010032, + 0x00010032, + 0x00010034, + 0x00010034, + }, + { + 0x0002004b, + 0x0002004b, + 0x0002004b, + 0x0002004b, + 0x0002004c, + 0x0002004c, + 0x0002004c, + 0x0002004c, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + }, + { + 0x00010043, + 0x00010043, + 0x00010044, + 0x00010044, + 0x00010045, + 0x00010045, + 0x00010046, + 0x00010046, + 0x0002003a, + 0x0002003a, + 0x0002003a, + 0x0002003a, + 0x00020040, + 0x00020040, + 0x00020040, + 0x00020040, + }, + { + 0x00020047, + 0x00020047, + 0x00020047, + 0x00020047, + 0x00020048, + 0x00020048, + 0x00020048, + 0x00020048, + 0x00020049, + 0x00020049, + 0x00020049, + 0x00020049, + 0x0002004a, + 0x0002004a, + 0x0002004a, + 0x0002004a, + }, + { + 0x00010038, + 0x00010038, + 0x00010039, + 0x00010039, + 0x0001003c, + 0x0001003c, + 0x0001003d, + 0x0001003d, + 0x0001003e, + 0x0001003e, + 0x0001003f, + 0x0001003f, + 0x00010041, + 0x00010041, + 0x00010042, + 0x00010042, + }, +}; +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc59[91][2] = +#else +const uint16_t c_aauiCQMFHuffEnc59[91][2] = +#endif + { + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000f, 0x0003 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0011, 0x0008 }, + { 0x0011, 0x0009 }, + { 0x0013, 0x0000 }, + { 0x0011, 0x000a }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0011, 0x000b }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0012, 0x000f }, + + }; +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec59[20][16] = { + { + 0x0006ffff, + 0x0004ffff, + 0x0005ffff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x00000003, + 0x00000004, + 0x00000005, + 0x00000006, + 0x00010000, + 0x00010000, + 0x00010001, + 0x00010001, + 0x00010002, + 0x00010002, + }, + { + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + }, + { + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + }, + { + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + }, + { + 0x00010016, + 0x00010016, + 0x00010017, + 0x00010017, + 0x00010018, + 0x00010018, + 0x00010019, + 0x00010019, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + }, + { + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + }, + { + 0x0009ffff, + 0x0008ffff, + 0x0007ffff, + 0x0000001a, + 0x0000001b, + 0x0000001c, + 0x0000001d, + 0x0000001e, + 0x0000001f, + 0x00000020, + 0x00010013, + 0x00010013, + 0x00010014, + 0x00010014, + 0x00010015, + 0x00010015, + }, + { + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + }, + { + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020024, + 0x00020024, + 0x00020024, + 0x00020024, + 0x00020025, + 0x00020025, + 0x00020025, + 0x00020025, + 0x00020026, + 0x00020026, + 0x00020026, + 0x00020026, + }, + { + 0x000dffff, + 0x000affff, + 0x000bffff, + 0x000cffff, + 0x0000002b, + 0x0000002c, + 0x0000002d, + 0x0000002e, + 0x00010027, + 0x00010027, + 0x00010028, + 0x00010028, + 0x00010029, + 0x00010029, + 0x0001002a, + 0x0001002a, + }, + { + 0x00020035, + 0x00020035, + 0x00020035, + 0x00020035, + 0x00020036, + 0x00020036, + 0x00020036, + 0x00020036, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + }, + { + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + }, + { + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + }, + { + 0x0011ffff, + 0x0012ffff, + 0x0013ffff, + 0x0010ffff, + 0x000effff, + 0x000fffff, + 0x00010037, + 0x00010037, + 0x00010038, + 0x00010038, + 0x00010039, + 0x00010039, + 0x00020034, + 0x00020034, + 0x00020034, + 0x00020034, + }, + { + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + }, + { + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x0003003d, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + }, + { + 0x00010058, + 0x00010058, + 0x00010059, + 0x00010059, + 0x00020040, + 0x00020040, + 0x00020040, + 0x00020040, + 0x00020041, + 0x00020041, + 0x00020041, + 0x00020041, + 0x0002005a, + 0x0002005a, + 0x0002005a, + 0x0002005a, + }, + { + 0x0001003c, + 0x0001003c, + 0x0001003e, + 0x0001003e, + 0x0001003f, + 0x0001003f, + 0x00010042, + 0x00010042, + 0x00010043, + 0x00010043, + 0x00010044, + 0x00010044, + 0x00010046, + 0x00010046, + 0x00010047, + 0x00010047, + }, + { + 0x00010048, + 0x00010048, + 0x00010049, + 0x00010049, + 0x0001004a, + 0x0001004a, + 0x0001004b, + 0x0001004b, + 0x0001004c, + 0x0001004c, + 0x0001004d, + 0x0001004d, + 0x0001004e, + 0x0001004e, + 0x0001004f, + 0x0001004f, + }, + { + 0x00010050, + 0x00010050, + 0x00010051, + 0x00010051, + 0x00010052, + 0x00010052, + 0x00010053, + 0x00010053, + 0x00010054, + 0x00010054, + 0x00010055, + 0x00010055, + 0x00010056, + 0x00010056, + 0x00010057, + 0x00010057, + }, +}; +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc60[109][2] = +#else +const uint16_t c_aauiCQMFHuffEnc60[109][2] = +#endif + { + { 0x0004, 0x0007 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000e, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x000e, 0x0008 }, + { 0x000f, 0x0005 }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0006 }, + { 0x0010, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x000f, 0x0008 }, + { 0x000f, 0x0009 }, + { 0x0010, 0x0007 }, + { 0x0010, 0x0008 }, + { 0x0010, 0x0009 }, + { 0x0011, 0x000a }, + { 0x0013, 0x0000 }, + { 0x0011, 0x000b }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0012, 0x0011 }, + { 0x0012, 0x0012 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0012, 0x0013 }, + + }; +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec60[24][16] = { + { + 0x0007ffff, + 0x0005ffff, + 0x0006ffff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x0004ffff, + 0x00000000, + 0x00000003, + 0x00000004, + 0x00010002, + 0x00010002, + 0x00020001, + 0x00020001, + 0x00020001, + 0x00020001, + }, + { + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + }, + { + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + }, + { + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + }, + { + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + }, + { + 0x00010015, + 0x00010015, + 0x00010016, + 0x00010016, + 0x00010017, + 0x00010017, + 0x00010018, + 0x00010018, + 0x00010019, + 0x00010019, + 0x0001001a, + 0x0001001a, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000c, + }, + { + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020010, + }, + { + 0x000dffff, + 0x000cffff, + 0x0008ffff, + 0x0009ffff, + 0x000affff, + 0x000bffff, + 0x0000001b, + 0x0000001c, + 0x0000001d, + 0x0000001e, + 0x0000001f, + 0x00000020, + 0x00010013, + 0x00010013, + 0x00010014, + 0x00010014, + }, + { + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030021, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + 0x00030022, + }, + { + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030023, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + 0x00030024, + }, + { + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030025, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + }, + { + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + }, + { + 0x00020029, + 0x00020029, + 0x00020029, + 0x00020029, + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x0002002b, + 0x0002002b, + 0x0002002b, + 0x0002002b, + 0x0002002c, + 0x0002002c, + 0x0002002c, + 0x0002002c, + }, + { + 0x0011ffff, + 0x0010ffff, + 0x000fffff, + 0x000effff, + 0x00000031, + 0x00000032, + 0x00000033, + 0x00000037, + 0x0001002d, + 0x0001002d, + 0x0001002e, + 0x0001002e, + 0x0001002f, + 0x0001002f, + 0x00010030, + 0x00010030, + }, + { + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + }, + { + 0x0002003b, + 0x0002003b, + 0x0002003b, + 0x0002003b, + 0x0002003d, + 0x0002003d, + 0x0002003d, + 0x0002003d, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + }, + { + 0x00010041, + 0x00010041, + 0x00010042, + 0x00010042, + 0x00020038, + 0x00020038, + 0x00020038, + 0x00020038, + 0x00020039, + 0x00020039, + 0x00020039, + 0x00020039, + 0x0002003a, + 0x0002003a, + 0x0002003a, + 0x0002003a, + }, + { + 0x0014ffff, + 0x0015ffff, + 0x0016ffff, + 0x0017ffff, + 0x0013ffff, + 0x0012ffff, + 0x0000003f, + 0x00000043, + 0x00000044, + 0x00000045, + 0x0001003c, + 0x0001003c, + 0x0001003e, + 0x0001003e, + 0x00010040, + 0x00010040, + }, + { + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030046, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + 0x00030048, + }, + { + 0x0001006a, + 0x0001006a, + 0x0001006b, + 0x0001006b, + 0x0002004b, + 0x0002004b, + 0x0002004b, + 0x0002004b, + 0x0002004c, + 0x0002004c, + 0x0002004c, + 0x0002004c, + 0x0002006c, + 0x0002006c, + 0x0002006c, + 0x0002006c, + }, + { + 0x00010047, + 0x00010047, + 0x00010049, + 0x00010049, + 0x0001004a, + 0x0001004a, + 0x0001004d, + 0x0001004d, + 0x0001004e, + 0x0001004e, + 0x0001004f, + 0x0001004f, + 0x00010050, + 0x00010050, + 0x00010051, + 0x00010051, + }, + { + 0x00010052, + 0x00010052, + 0x00010053, + 0x00010053, + 0x00010054, + 0x00010054, + 0x00010055, + 0x00010055, + 0x00010056, + 0x00010056, + 0x00010057, + 0x00010057, + 0x00010058, + 0x00010058, + 0x00010059, + 0x00010059, + }, + { + 0x0001005a, + 0x0001005a, + 0x0001005b, + 0x0001005b, + 0x0001005c, + 0x0001005c, + 0x0001005d, + 0x0001005d, + 0x0001005e, + 0x0001005e, + 0x0001005f, + 0x0001005f, + 0x00010060, + 0x00010060, + 0x00010061, + 0x00010061, + }, + { + 0x00010062, + 0x00010062, + 0x00010063, + 0x00010063, + 0x00010064, + 0x00010064, + 0x00010065, + 0x00010065, + 0x00010066, + 0x00010066, + 0x00010067, + 0x00010067, + 0x00010068, + 0x00010068, + 0x00010069, + 0x00010069, + }, +}; +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc61[129][2] = +#else +const uint16_t c_aauiCQMFHuffEnc61[129][2] = +#endif + { + { 0x0004, 0x0008 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000e, 0x0008 }, + { 0x000d, 0x000b }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000f, 0x000c }, + { 0x000f, 0x000d }, + { 0x000f, 0x000e }, + { 0x0010, 0x000c }, + { 0x0011, 0x0015 }, + { 0x0010, 0x000d }, + { 0x000f, 0x000f }, + { 0x0010, 0x000e }, + { 0x0010, 0x000f }, + { 0x0012, 0x0000 }, + { 0x0011, 0x0016 }, + { 0x0010, 0x0010 }, + { 0x0010, 0x0011 }, + { 0x0011, 0x0017 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0012, 0x000f }, + { 0x0012, 0x0010 }, + { 0x0012, 0x0011 }, + { 0x0012, 0x0012 }, + { 0x0012, 0x0013 }, + { 0x0012, 0x0014 }, + { 0x0012, 0x0015 }, + { 0x0012, 0x0016 }, + { 0x0012, 0x0017 }, + { 0x0012, 0x0018 }, + { 0x0012, 0x0019 }, + { 0x0012, 0x001a }, + { 0x0012, 0x001b }, + { 0x0012, 0x001c }, + { 0x0012, 0x001d }, + { 0x0012, 0x001e }, + { 0x0012, 0x001f }, + { 0x0012, 0x0020 }, + { 0x0012, 0x0021 }, + { 0x0012, 0x0022 }, + { 0x0012, 0x0023 }, + { 0x0012, 0x0024 }, + { 0x0012, 0x0025 }, + { 0x0012, 0x0026 }, + { 0x0012, 0x0027 }, + { 0x0012, 0x0028 }, + { 0x0012, 0x0029 }, + + }; +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec61[33][16] = { + { + 0x0008ffff, + 0x0007ffff, + 0x0005ffff, + 0x0006ffff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x0004ffff, + 0x00000000, + 0x00000003, + 0x00000004, + 0x00000005, + 0x00010001, + 0x00010001, + 0x00010002, + 0x00010002, + }, + { + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + }, + { + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + }, + { + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + }, + { + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + 0x0003000d, + }, + { + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + }, + { + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020015, + }, + { + 0x00010016, + 0x00010016, + 0x00010017, + 0x00010017, + 0x00010018, + 0x00010018, + 0x00010019, + 0x00010019, + 0x0001001a, + 0x0001001a, + 0x0001001b, + 0x0001001b, + 0x0001001c, + 0x0001001c, + 0x0001001d, + 0x0001001d, + }, + { + 0x000effff, + 0x000cffff, + 0x000dffff, + 0x0009ffff, + 0x000affff, + 0x000bffff, + 0x0000001e, + 0x0000001f, + 0x00000020, + 0x00000021, + 0x00000022, + 0x00000023, + 0x00000024, + 0x00000025, + 0x00000026, + 0x00000027, + }, + { + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + 0x00030029, + }, + { + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002a, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + }, + { + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + }, + { + 0x00010038, + 0x00010038, + 0x00010039, + 0x00010039, + 0x0002002e, + 0x0002002e, + 0x0002002e, + 0x0002002e, + 0x0002002f, + 0x0002002f, + 0x0002002f, + 0x0002002f, + 0x00020030, + 0x00020030, + 0x00020030, + 0x00020030, + }, + { + 0x00020031, + 0x00020031, + 0x00020031, + 0x00020031, + 0x00020032, + 0x00020032, + 0x00020032, + 0x00020032, + 0x00020033, + 0x00020033, + 0x00020033, + 0x00020033, + 0x00020034, + 0x00020034, + 0x00020034, + 0x00020034, + }, + { + 0x0014ffff, + 0x0013ffff, + 0x000fffff, + 0x0010ffff, + 0x0011ffff, + 0x0012ffff, + 0x0000003a, + 0x0000003b, + 0x0000003c, + 0x0000003d, + 0x00010035, + 0x00010035, + 0x00010036, + 0x00010036, + 0x00010037, + 0x00010037, + }, + { + 0x00020044, + 0x00020044, + 0x00020044, + 0x00020044, + 0x00020046, + 0x00020046, + 0x00020046, + 0x00020046, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + 0x0003003e, + }, + { + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x0003003f, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + 0x00030040, + }, + { + 0x00030041, + 0x00030041, + 0x00030041, + 0x00030041, + 0x00030041, + 0x00030041, + 0x00030041, + 0x00030041, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + 0x00030042, + }, + { + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030043, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + 0x00030045, + }, + { + 0x00000055, + 0x00000056, + 0x00010047, + 0x00010047, + 0x00010048, + 0x00010048, + 0x00010049, + 0x00010049, + 0x0001004a, + 0x0001004a, + 0x0001004b, + 0x0001004b, + 0x0001004c, + 0x0001004c, + 0x00010050, + 0x00010050, + }, + { + 0x0017ffff, + 0x0018ffff, + 0x0019ffff, + 0x001affff, + 0x001bffff, + 0x001cffff, + 0x001dffff, + 0x001effff, + 0x001fffff, + 0x0020ffff, + 0x0016ffff, + 0x0015ffff, + 0x0000004d, + 0x0000004f, + 0x00000051, + 0x00000052, + }, + { + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + }, + { + 0x0002007f, + 0x0002007f, + 0x0002007f, + 0x0002007f, + 0x00020080, + 0x00020080, + 0x00020080, + 0x00020080, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + }, + { + 0x00020053, + 0x00020053, + 0x00020053, + 0x00020053, + 0x00020058, + 0x00020058, + 0x00020058, + 0x00020058, + 0x00020059, + 0x00020059, + 0x00020059, + 0x00020059, + 0x0002005a, + 0x0002005a, + 0x0002005a, + 0x0002005a, + }, + { + 0x0002005b, + 0x0002005b, + 0x0002005b, + 0x0002005b, + 0x0002005c, + 0x0002005c, + 0x0002005c, + 0x0002005c, + 0x0002005d, + 0x0002005d, + 0x0002005d, + 0x0002005d, + 0x0002005e, + 0x0002005e, + 0x0002005e, + 0x0002005e, + }, + { + 0x0002005f, + 0x0002005f, + 0x0002005f, + 0x0002005f, + 0x00020060, + 0x00020060, + 0x00020060, + 0x00020060, + 0x00020061, + 0x00020061, + 0x00020061, + 0x00020061, + 0x00020062, + 0x00020062, + 0x00020062, + 0x00020062, + }, + { + 0x00020063, + 0x00020063, + 0x00020063, + 0x00020063, + 0x00020064, + 0x00020064, + 0x00020064, + 0x00020064, + 0x00020065, + 0x00020065, + 0x00020065, + 0x00020065, + 0x00020066, + 0x00020066, + 0x00020066, + 0x00020066, + }, + { + 0x00020067, + 0x00020067, + 0x00020067, + 0x00020067, + 0x00020068, + 0x00020068, + 0x00020068, + 0x00020068, + 0x00020069, + 0x00020069, + 0x00020069, + 0x00020069, + 0x0002006a, + 0x0002006a, + 0x0002006a, + 0x0002006a, + }, + { + 0x0002006b, + 0x0002006b, + 0x0002006b, + 0x0002006b, + 0x0002006c, + 0x0002006c, + 0x0002006c, + 0x0002006c, + 0x0002006d, + 0x0002006d, + 0x0002006d, + 0x0002006d, + 0x0002006e, + 0x0002006e, + 0x0002006e, + 0x0002006e, + }, + { + 0x0002006f, + 0x0002006f, + 0x0002006f, + 0x0002006f, + 0x00020070, + 0x00020070, + 0x00020070, + 0x00020070, + 0x00020071, + 0x00020071, + 0x00020071, + 0x00020071, + 0x00020072, + 0x00020072, + 0x00020072, + 0x00020072, + }, + { + 0x00020073, + 0x00020073, + 0x00020073, + 0x00020073, + 0x00020074, + 0x00020074, + 0x00020074, + 0x00020074, + 0x00020075, + 0x00020075, + 0x00020075, + 0x00020075, + 0x00020076, + 0x00020076, + 0x00020076, + 0x00020076, + }, + { + 0x00020077, + 0x00020077, + 0x00020077, + 0x00020077, + 0x00020078, + 0x00020078, + 0x00020078, + 0x00020078, + 0x00020079, + 0x00020079, + 0x00020079, + 0x00020079, + 0x0002007a, + 0x0002007a, + 0x0002007a, + 0x0002007a, + }, + { + 0x0002007b, + 0x0002007b, + 0x0002007b, + 0x0002007b, + 0x0002007c, + 0x0002007c, + 0x0002007c, + 0x0002007c, + 0x0002007d, + 0x0002007d, + 0x0002007d, + 0x0002007d, + 0x0002007e, + 0x0002007e, + 0x0002007e, + 0x0002007e, + }, +}; +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc62[153][2] = +#else +const uint16_t c_aauiCQMFHuffEnc62[153][2] = +#endif + { + { 0x0004, 0x0009 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0008, 0x0010 }, + { 0x0008, 0x0011 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x0009, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000d, 0x0007 }, + { 0x000c, 0x000d }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000e, 0x0008 }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000e, 0x0009 }, + { 0x000e, 0x000a }, + { 0x000e, 0x000b }, + { 0x000e, 0x000c }, + { 0x000f, 0x000c }, + { 0x000e, 0x000d }, + { 0x000f, 0x000d }, + { 0x000f, 0x000e }, + { 0x000f, 0x000f }, + { 0x0010, 0x000f }, + { 0x0010, 0x0010 }, + { 0x0011, 0x0019 }, + { 0x0010, 0x0011 }, + { 0x0010, 0x0012 }, + { 0x0010, 0x0013 }, + { 0x0010, 0x0014 }, + { 0x0010, 0x0015 }, + { 0x0012, 0x0000 }, + { 0x0010, 0x0016 }, + { 0x0011, 0x001a }, + { 0x0010, 0x0017 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0011, 0x001b }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0012, 0x000f }, + { 0x0012, 0x0010 }, + { 0x0012, 0x0011 }, + { 0x0012, 0x0012 }, + { 0x0012, 0x0013 }, + { 0x0012, 0x0014 }, + { 0x0012, 0x0015 }, + { 0x0012, 0x0016 }, + { 0x0012, 0x0017 }, + { 0x0012, 0x0018 }, + { 0x0011, 0x001c }, + { 0x0012, 0x0019 }, + { 0x0012, 0x001a }, + { 0x0012, 0x001b }, + { 0x0012, 0x001c }, + { 0x0012, 0x001d }, + { 0x0012, 0x001e }, + { 0x0012, 0x001f }, + { 0x0012, 0x0020 }, + { 0x0012, 0x0021 }, + { 0x0012, 0x0022 }, + { 0x0012, 0x0023 }, + { 0x0012, 0x0024 }, + { 0x0012, 0x0025 }, + { 0x0012, 0x0026 }, + { 0x0012, 0x0027 }, + { 0x0012, 0x0028 }, + { 0x0012, 0x0029 }, + { 0x0012, 0x002a }, + { 0x0012, 0x002b }, + { 0x0012, 0x002c }, + { 0x0012, 0x002d }, + { 0x0012, 0x002e }, + { 0x0012, 0x002f }, + { 0x0012, 0x0030 }, + { 0x0012, 0x0031 }, + { 0x0011, 0x001d }, + + }; +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec62[41][16] = { + { + 0x0009ffff, + 0x0008ffff, + 0x0005ffff, + 0x0006ffff, + 0x0007ffff, + 0x0001ffff, + 0x0002ffff, + 0x0003ffff, + 0x0004ffff, + 0x00000000, + 0x00000003, + 0x00000004, + 0x00010001, + 0x00010001, + 0x00010002, + 0x00010002, + }, + { + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + }, + { + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + 0x00030008, + }, + { + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x00030009, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + 0x0003000a, + }, + { + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000b, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + }, + { + 0x0001001e, + 0x0001001e, + 0x0001001f, + 0x0001001f, + 0x00010020, + 0x00010020, + 0x00010021, + 0x00010021, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + }, + { + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + }, + { + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020014, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020015, + 0x00020016, + 0x00020016, + 0x00020016, + 0x00020016, + }, + { + 0x00000029, + 0x0000002a, + 0x00010017, + 0x00010017, + 0x00010018, + 0x00010018, + 0x00010019, + 0x00010019, + 0x0001001a, + 0x0001001a, + 0x0001001b, + 0x0001001b, + 0x0001001c, + 0x0001001c, + 0x0001001d, + 0x0001001d, + }, + { + 0x0012ffff, + 0x0010ffff, + 0x0011ffff, + 0x000affff, + 0x000bffff, + 0x000cffff, + 0x000dffff, + 0x000effff, + 0x000fffff, + 0x00000022, + 0x00000023, + 0x00000024, + 0x00000025, + 0x00000026, + 0x00000027, + 0x00000028, + }, + { + 0x0002003e, + 0x0002003e, + 0x0002003e, + 0x0002003e, + 0x0002003f, + 0x0002003f, + 0x0002003f, + 0x0002003f, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + }, + { + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + }, + { + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + }, + { + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + }, + { + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + }, + { + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + }, + { + 0x00020036, + 0x00020036, + 0x00020036, + 0x00020036, + 0x00020037, + 0x00020037, + 0x00020037, + 0x00020037, + 0x00020038, + 0x00020038, + 0x00020038, + 0x00020038, + 0x00020039, + 0x00020039, + 0x00020039, + 0x00020039, + }, + { + 0x0002003a, + 0x0002003a, + 0x0002003a, + 0x0002003a, + 0x0002003b, + 0x0002003b, + 0x0002003b, + 0x0002003b, + 0x0002003c, + 0x0002003c, + 0x0002003c, + 0x0002003c, + 0x0002003d, + 0x0002003d, + 0x0002003d, + 0x0002003d, + }, + { + 0x0019ffff, + 0x0018ffff, + 0x0017ffff, + 0x0013ffff, + 0x0014ffff, + 0x0015ffff, + 0x0016ffff, + 0x00000041, + 0x00000042, + 0x00000043, + 0x00000044, + 0x00000045, + 0x00000046, + 0x00000048, + 0x00010040, + 0x00010040, + }, + { + 0x00020053, + 0x00020053, + 0x00020053, + 0x00020053, + 0x00020055, + 0x00020055, + 0x00020055, + 0x00020055, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + 0x00030047, + }, + { + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x00030049, + 0x0003004a, + 0x0003004a, + 0x0003004a, + 0x0003004a, + 0x0003004a, + 0x0003004a, + 0x0003004a, + 0x0003004a, + }, + { + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004b, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + 0x0003004c, + }, + { + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004e, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + 0x0003004f, + }, + { + 0x0002004d, + 0x0002004d, + 0x0002004d, + 0x0002004d, + 0x00020050, + 0x00020050, + 0x00020050, + 0x00020050, + 0x00020051, + 0x00020051, + 0x00020051, + 0x00020051, + 0x00020052, + 0x00020052, + 0x00020052, + 0x00020052, + }, + { + 0x0000005a, + 0x0000005c, + 0x0000005d, + 0x0000005e, + 0x0000005f, + 0x00000060, + 0x00000062, + 0x00000064, + 0x00010054, + 0x00010054, + 0x00010056, + 0x00010056, + 0x00010057, + 0x00010057, + 0x00010058, + 0x00010058, + }, + { + 0x001dffff, + 0x001effff, + 0x001fffff, + 0x0020ffff, + 0x0021ffff, + 0x0022ffff, + 0x0023ffff, + 0x0024ffff, + 0x0025ffff, + 0x0026ffff, + 0x0027ffff, + 0x0028ffff, + 0x001affff, + 0x001bffff, + 0x001cffff, + 0x00000059, + }, + { + 0x00020096, + 0x00020096, + 0x00020096, + 0x00020096, + 0x00020097, + 0x00020097, + 0x00020097, + 0x00020097, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + 0x0003005b, + }, + { + 0x00030063, + 0x00030063, + 0x00030063, + 0x00030063, + 0x00030063, + 0x00030063, + 0x00030063, + 0x00030063, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + 0x00030068, + }, + { + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x0003007e, + 0x00030098, + 0x00030098, + 0x00030098, + 0x00030098, + 0x00030098, + 0x00030098, + 0x00030098, + 0x00030098, + }, + { + 0x00020061, + 0x00020061, + 0x00020061, + 0x00020061, + 0x00020065, + 0x00020065, + 0x00020065, + 0x00020065, + 0x00020066, + 0x00020066, + 0x00020066, + 0x00020066, + 0x00020067, + 0x00020067, + 0x00020067, + 0x00020067, + }, + { + 0x00020069, + 0x00020069, + 0x00020069, + 0x00020069, + 0x0002006a, + 0x0002006a, + 0x0002006a, + 0x0002006a, + 0x0002006b, + 0x0002006b, + 0x0002006b, + 0x0002006b, + 0x0002006c, + 0x0002006c, + 0x0002006c, + 0x0002006c, + }, + { + 0x0002006d, + 0x0002006d, + 0x0002006d, + 0x0002006d, + 0x0002006e, + 0x0002006e, + 0x0002006e, + 0x0002006e, + 0x0002006f, + 0x0002006f, + 0x0002006f, + 0x0002006f, + 0x00020070, + 0x00020070, + 0x00020070, + 0x00020070, + }, + { + 0x00020071, + 0x00020071, + 0x00020071, + 0x00020071, + 0x00020072, + 0x00020072, + 0x00020072, + 0x00020072, + 0x00020073, + 0x00020073, + 0x00020073, + 0x00020073, + 0x00020074, + 0x00020074, + 0x00020074, + 0x00020074, + }, + { + 0x00020075, + 0x00020075, + 0x00020075, + 0x00020075, + 0x00020076, + 0x00020076, + 0x00020076, + 0x00020076, + 0x00020077, + 0x00020077, + 0x00020077, + 0x00020077, + 0x00020078, + 0x00020078, + 0x00020078, + 0x00020078, + }, + { + 0x00020079, + 0x00020079, + 0x00020079, + 0x00020079, + 0x0002007a, + 0x0002007a, + 0x0002007a, + 0x0002007a, + 0x0002007b, + 0x0002007b, + 0x0002007b, + 0x0002007b, + 0x0002007c, + 0x0002007c, + 0x0002007c, + 0x0002007c, + }, + { + 0x0002007d, + 0x0002007d, + 0x0002007d, + 0x0002007d, + 0x0002007f, + 0x0002007f, + 0x0002007f, + 0x0002007f, + 0x00020080, + 0x00020080, + 0x00020080, + 0x00020080, + 0x00020081, + 0x00020081, + 0x00020081, + 0x00020081, + }, + { + 0x00020082, + 0x00020082, + 0x00020082, + 0x00020082, + 0x00020083, + 0x00020083, + 0x00020083, + 0x00020083, + 0x00020084, + 0x00020084, + 0x00020084, + 0x00020084, + 0x00020085, + 0x00020085, + 0x00020085, + 0x00020085, + }, + { + 0x00020086, + 0x00020086, + 0x00020086, + 0x00020086, + 0x00020087, + 0x00020087, + 0x00020087, + 0x00020087, + 0x00020088, + 0x00020088, + 0x00020088, + 0x00020088, + 0x00020089, + 0x00020089, + 0x00020089, + 0x00020089, + }, + { + 0x0002008a, + 0x0002008a, + 0x0002008a, + 0x0002008a, + 0x0002008b, + 0x0002008b, + 0x0002008b, + 0x0002008b, + 0x0002008c, + 0x0002008c, + 0x0002008c, + 0x0002008c, + 0x0002008d, + 0x0002008d, + 0x0002008d, + 0x0002008d, + }, + { + 0x0002008e, + 0x0002008e, + 0x0002008e, + 0x0002008e, + 0x0002008f, + 0x0002008f, + 0x0002008f, + 0x0002008f, + 0x00020090, + 0x00020090, + 0x00020090, + 0x00020090, + 0x00020091, + 0x00020091, + 0x00020091, + 0x00020091, + }, + { + 0x00020092, + 0x00020092, + 0x00020092, + 0x00020092, + 0x00020093, + 0x00020093, + 0x00020093, + 0x00020093, + 0x00020094, + 0x00020094, + 0x00020094, + 0x00020094, + 0x00020095, + 0x00020095, + 0x00020095, + 0x00020095, + }, +}; +#endif +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffEnc63[181][2] = +#else +const uint16_t c_aauiCQMFHuffEnc63[181][2] = +#endif + { + { 0x0004, 0x0008 }, + { 0x0003, 0x0005 }, + { 0x0002, 0x0003 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0007, 0x0014 }, + { 0x0007, 0x0015 }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0008, 0x0010 }, + { 0x0008, 0x0011 }, + { 0x0008, 0x0012 }, + { 0x0008, 0x0013 }, + { 0x0008, 0x0014 }, + { 0x0008, 0x0015 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x0009, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x0009, 0x0012 }, + { 0x0009, 0x0013 }, + { 0x0009, 0x0014 }, + { 0x0009, 0x0015 }, + { 0x000a, 0x0007 }, + { 0x0009, 0x0016 }, + { 0x0009, 0x0017 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000a, 0x000e }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000a, 0x000f }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000c, 0x000d }, + { 0x000c, 0x000e }, + { 0x000c, 0x000f }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000d, 0x000e }, + { 0x000d, 0x000f }, + { 0x000d, 0x0010 }, + { 0x000d, 0x0011 }, + { 0x000e, 0x0007 }, + { 0x000e, 0x0008 }, + { 0x000e, 0x0009 }, + { 0x000e, 0x000a }, + { 0x000e, 0x000b }, + { 0x000e, 0x000c }, + { 0x000e, 0x000d }, + { 0x000e, 0x000e }, + { 0x000e, 0x000f }, + { 0x000f, 0x0008 }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000f, 0x000c }, + { 0x0010, 0x0009 }, + { 0x0010, 0x000a }, + { 0x000f, 0x000d }, + { 0x0010, 0x000b }, + { 0x0010, 0x000c }, + { 0x0010, 0x000d }, + { 0x0011, 0x000e }, + { 0x0011, 0x000f }, + { 0x0010, 0x000e }, + { 0x0011, 0x0010 }, + { 0x0011, 0x0011 }, + { 0x0012, 0x0014 }, + { 0x0014, 0x0000 }, + { 0x0010, 0x000f }, + { 0x0012, 0x0015 }, + { 0x0012, 0x0016 }, + { 0x0014, 0x0001 }, + { 0x0012, 0x0017 }, + { 0x0012, 0x0018 }, + { 0x0012, 0x0019 }, + { 0x0013, 0x0010 }, + { 0x0012, 0x001a }, + { 0x0014, 0x0002 }, + { 0x0012, 0x001b }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0013, 0x0011 }, + { 0x0014, 0x0006 }, + { 0x0013, 0x0012 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0013, 0x0013 }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + + }; +#ifndef ROM_TO_RAM +const uint32_t c_aauiCQMFHuffDec63[39][16] = { + { + 0x0008ffff, + 0x0006ffff, + 0x0007ffff, + 0x0003ffff, + 0x0004ffff, + 0x0005ffff, + 0x0001ffff, + 0x0002ffff, + 0x00000000, + 0x00000003, + 0x00010001, + 0x00010001, + 0x00020002, + 0x00020002, + 0x00020002, + 0x00020002, + }, + { + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030004, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + 0x00030005, + }, + { + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030006, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + 0x00030007, + }, + { + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020008, + 0x00020009, + 0x00020009, + 0x00020009, + 0x00020009, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000a, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000b, + }, + { + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000c, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000f, + 0x0002000f, + 0x0002000f, + 0x0002000f, + }, + { + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020010, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020013, + }, + { + 0x00000025, + 0x00000026, + 0x00000027, + 0x00000028, + 0x00000029, + 0x0000002a, + 0x00010014, + 0x00010014, + 0x00010015, + 0x00010015, + 0x00010016, + 0x00010016, + 0x00010017, + 0x00010017, + 0x00010018, + 0x00010018, + }, + { + 0x00010019, + 0x00010019, + 0x0001001a, + 0x0001001a, + 0x0001001b, + 0x0001001b, + 0x0001001c, + 0x0001001c, + 0x0001001d, + 0x0001001d, + 0x0001001e, + 0x0001001e, + 0x0001001f, + 0x0001001f, + 0x00010020, + 0x00010020, + }, + { + 0x0014ffff, + 0x0011ffff, + 0x0012ffff, + 0x0013ffff, + 0x0009ffff, + 0x000affff, + 0x000bffff, + 0x000cffff, + 0x000dffff, + 0x000effff, + 0x000fffff, + 0x0010ffff, + 0x00000021, + 0x00000022, + 0x00000023, + 0x00000024, + }, + { + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002b, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + 0x0003002c, + }, + { + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002d, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + 0x0003002e, + }, + { + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x0003002f, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + 0x00030030, + }, + { + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030031, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + 0x00030032, + }, + { + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030033, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + 0x00030034, + }, + { + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030035, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + 0x00030036, + }, + { + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030037, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + 0x00030038, + }, + { + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003a, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + 0x0003003b, + }, + { + 0x00010043, + 0x00010043, + 0x00010044, + 0x00010044, + 0x00010045, + 0x00010045, + 0x00010047, + 0x00010047, + 0x00010048, + 0x00010048, + 0x00010049, + 0x00010049, + 0x00020039, + 0x00020039, + 0x00020039, + 0x00020039, + }, + { + 0x0002003c, + 0x0002003c, + 0x0002003c, + 0x0002003c, + 0x0002003d, + 0x0002003d, + 0x0002003d, + 0x0002003d, + 0x0002003e, + 0x0002003e, + 0x0002003e, + 0x0002003e, + 0x0002003f, + 0x0002003f, + 0x0002003f, + 0x0002003f, + }, + { + 0x00020040, + 0x00020040, + 0x00020040, + 0x00020040, + 0x00020041, + 0x00020041, + 0x00020041, + 0x00020041, + 0x00020042, + 0x00020042, + 0x00020042, + 0x00020042, + 0x00020046, + 0x00020046, + 0x00020046, + 0x00020046, + }, + { + 0x001dffff, + 0x001affff, + 0x001bffff, + 0x001cffff, + 0x0015ffff, + 0x0016ffff, + 0x0017ffff, + 0x0018ffff, + 0x0019ffff, + 0x0000004a, + 0x0000004b, + 0x0000004c, + 0x0000004d, + 0x0000004e, + 0x0000004f, + 0x00000050, + }, + { + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030051, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + 0x00030052, + }, + { + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030053, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + 0x00030054, + }, + { + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030055, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + 0x00030056, + }, + { + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030057, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + 0x00030058, + }, + { + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + 0x00030059, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + 0x0003005a, + }, + { + 0x00010064, + 0x00010064, + 0x00010065, + 0x00010065, + 0x00010066, + 0x00010066, + 0x00010067, + 0x00010067, + 0x00010068, + 0x00010068, + 0x0001006b, + 0x0001006b, + 0x0002005b, + 0x0002005b, + 0x0002005b, + 0x0002005b, + }, + { + 0x0002005c, + 0x0002005c, + 0x0002005c, + 0x0002005c, + 0x0002005d, + 0x0002005d, + 0x0002005d, + 0x0002005d, + 0x0002005e, + 0x0002005e, + 0x0002005e, + 0x0002005e, + 0x0002005f, + 0x0002005f, + 0x0002005f, + 0x0002005f, + }, + { + 0x00020060, + 0x00020060, + 0x00020060, + 0x00020060, + 0x00020061, + 0x00020061, + 0x00020061, + 0x00020061, + 0x00020062, + 0x00020062, + 0x00020062, + 0x00020062, + 0x00020063, + 0x00020063, + 0x00020063, + 0x00020063, + }, + { + 0x0026ffff, + 0x0025ffff, + 0x0022ffff, + 0x0023ffff, + 0x0024ffff, + 0x0020ffff, + 0x0021ffff, + 0x001effff, + 0x001fffff, + 0x00000069, + 0x0000006a, + 0x0000006c, + 0x0000006d, + 0x0000006e, + 0x00000071, + 0x00000076, + }, + { + 0x0003006f, + 0x0003006f, + 0x0003006f, + 0x0003006f, + 0x0003006f, + 0x0003006f, + 0x0003006f, + 0x0003006f, + 0x00030070, + 0x00030070, + 0x00030070, + 0x00030070, + 0x00030070, + 0x00030070, + 0x00030070, + 0x00030070, + }, + { + 0x00030072, + 0x00030072, + 0x00030072, + 0x00030072, + 0x00030072, + 0x00030072, + 0x00030072, + 0x00030072, + 0x00030073, + 0x00030073, + 0x00030073, + 0x00030073, + 0x00030073, + 0x00030073, + 0x00030073, + 0x00030073, + }, + { + 0x00020074, + 0x00020074, + 0x00020074, + 0x00020074, + 0x00020077, + 0x00020077, + 0x00020077, + 0x00020077, + 0x00020078, + 0x00020078, + 0x00020078, + 0x00020078, + 0x0002007a, + 0x0002007a, + 0x0002007a, + 0x0002007a, + }, + { + 0x0002007b, + 0x0002007b, + 0x0002007b, + 0x0002007b, + 0x0002007c, + 0x0002007c, + 0x0002007c, + 0x0002007c, + 0x0002007e, + 0x0002007e, + 0x0002007e, + 0x0002007e, + 0x00020080, + 0x00020080, + 0x00020080, + 0x00020080, + }, + { + 0x0001007d, + 0x0001007d, + 0x00010084, + 0x00010084, + 0x00010086, + 0x00010086, + 0x0001008f, + 0x0001008f, + 0x000100a1, + 0x000100a1, + 0x000100a2, + 0x000100a2, + 0x000100a3, + 0x000100a3, + 0x000100a4, + 0x000100a4, + }, + { + 0x000100a5, + 0x000100a5, + 0x000100a6, + 0x000100a6, + 0x000100a7, + 0x000100a7, + 0x000100a8, + 0x000100a8, + 0x000100a9, + 0x000100a9, + 0x000100aa, + 0x000100aa, + 0x000100ab, + 0x000100ab, + 0x000100ac, + 0x000100ac, + }, + { + 0x000100ad, + 0x000100ad, + 0x000100ae, + 0x000100ae, + 0x000100af, + 0x000100af, + 0x000100b0, + 0x000100b0, + 0x000100b1, + 0x000100b1, + 0x000100b2, + 0x000100b2, + 0x000100b3, + 0x000100b3, + 0x000100b4, + 0x000100b4, + }, + { + 0x00000091, + 0x00000092, + 0x00000093, + 0x00000094, + 0x00000095, + 0x00000096, + 0x00000097, + 0x00000098, + 0x00000099, + 0x0000009a, + 0x0000009b, + 0x0000009c, + 0x0000009d, + 0x0000009e, + 0x0000009f, + 0x000000a0, + }, + { + 0x00000075, + 0x00000079, + 0x0000007f, + 0x00000081, + 0x00000082, + 0x00000083, + 0x00000085, + 0x00000087, + 0x00000088, + 0x00000089, + 0x0000008a, + 0x0000008b, + 0x0000008c, + 0x0000008d, + 0x0000008e, + 0x00000090, + }, +}; +#endif + +#ifndef ROM_TO_RAM +const uint32_t ( *c_apauiHuffEncTabels[2 * ALLOC_TABLE_SIZE] )[2] = +#else +const uint16_t ( *c_apauiHuffEncTabels[2 * ALLOC_TABLE_SIZE] )[2] = +#endif + { + NULL, + c_aauiCQMFHuffEnc1, + c_aauiCQMFHuffEnc2, + c_aauiCQMFHuffEnc3, + c_aauiCQMFHuffEnc4, + c_aauiCQMFHuffEnc5, + c_aauiCQMFHuffEnc6, + c_aauiCQMFHuffEnc7, + c_aauiCQMFHuffEnc8, + c_aauiCQMFHuffEnc9, + c_aauiCQMFHuffEnc10, + c_aauiCQMFHuffEnc11, + c_aauiCQMFHuffEnc12, + c_aauiCQMFHuffEnc13, + c_aauiCQMFHuffEnc14, + c_aauiCQMFHuffEnc15, + c_aauiCQMFHuffEnc16, + c_aauiCQMFHuffEnc17, + c_aauiCQMFHuffEnc18, + c_aauiCQMFHuffEnc19, + c_aauiCQMFHuffEnc20, + c_aauiCQMFHuffEnc21, + c_aauiCQMFHuffEnc22, + c_aauiCQMFHuffEnc23, + c_aauiCQMFHuffEnc24, + c_aauiCQMFHuffEnc25, + c_aauiCQMFHuffEnc26, + c_aauiCQMFHuffEnc27, + c_aauiCQMFHuffEnc28, + c_aauiCQMFHuffEnc29, + c_aauiCQMFHuffEnc30, + c_aauiCQMFHuffEnc31, + NULL, + c_aauiCQMFHuffEnc33, + c_aauiCQMFHuffEnc34, + c_aauiCQMFHuffEnc35, + c_aauiCQMFHuffEnc36, + c_aauiCQMFHuffEnc37, + c_aauiCQMFHuffEnc38, + c_aauiCQMFHuffEnc39, + c_aauiCQMFHuffEnc40, + c_aauiCQMFHuffEnc41, + c_aauiCQMFHuffEnc42, + c_aauiCQMFHuffEnc43, + c_aauiCQMFHuffEnc44, + c_aauiCQMFHuffEnc45, + c_aauiCQMFHuffEnc46, + c_aauiCQMFHuffEnc47, + c_aauiCQMFHuffEnc48, + c_aauiCQMFHuffEnc49, + c_aauiCQMFHuffEnc50, + c_aauiCQMFHuffEnc51, + c_aauiCQMFHuffEnc52, + c_aauiCQMFHuffEnc53, + c_aauiCQMFHuffEnc54, + c_aauiCQMFHuffEnc55, + c_aauiCQMFHuffEnc56, + c_aauiCQMFHuffEnc57, + c_aauiCQMFHuffEnc58, + c_aauiCQMFHuffEnc59, + c_aauiCQMFHuffEnc60, + c_aauiCQMFHuffEnc61, + c_aauiCQMFHuffEnc62, + c_aauiCQMFHuffEnc63, + }; +#ifndef ROM_TO_RAM +const uint32_t ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] = { + NULL, + c_aauiCQMFHuffDec1, + c_aauiCQMFHuffDec2, + c_aauiCQMFHuffDec3, + c_aauiCQMFHuffDec4, + c_aauiCQMFHuffDec5, + c_aauiCQMFHuffDec6, + c_aauiCQMFHuffDec7, + c_aauiCQMFHuffDec8, + c_aauiCQMFHuffDec9, + c_aauiCQMFHuffDec10, + c_aauiCQMFHuffDec11, + c_aauiCQMFHuffDec12, + c_aauiCQMFHuffDec13, + c_aauiCQMFHuffDec14, + c_aauiCQMFHuffDec15, + c_aauiCQMFHuffDec16, + c_aauiCQMFHuffDec17, + c_aauiCQMFHuffDec18, + c_aauiCQMFHuffDec19, + c_aauiCQMFHuffDec20, + c_aauiCQMFHuffDec21, + c_aauiCQMFHuffDec22, + c_aauiCQMFHuffDec23, + c_aauiCQMFHuffDec24, + c_aauiCQMFHuffDec25, + c_aauiCQMFHuffDec26, + c_aauiCQMFHuffDec27, + c_aauiCQMFHuffDec28, + c_aauiCQMFHuffDec29, + c_aauiCQMFHuffDec30, + c_aauiCQMFHuffDec31, + NULL, + c_aauiCQMFHuffDec33, + c_aauiCQMFHuffDec34, + c_aauiCQMFHuffDec35, + c_aauiCQMFHuffDec36, + c_aauiCQMFHuffDec37, + c_aauiCQMFHuffDec38, + c_aauiCQMFHuffDec39, + c_aauiCQMFHuffDec40, + c_aauiCQMFHuffDec41, + c_aauiCQMFHuffDec42, + c_aauiCQMFHuffDec43, + c_aauiCQMFHuffDec44, + c_aauiCQMFHuffDec45, + c_aauiCQMFHuffDec46, + c_aauiCQMFHuffDec47, + c_aauiCQMFHuffDec48, + c_aauiCQMFHuffDec49, + c_aauiCQMFHuffDec50, + c_aauiCQMFHuffDec51, + c_aauiCQMFHuffDec52, + c_aauiCQMFHuffDec53, + c_aauiCQMFHuffDec54, + c_aauiCQMFHuffDec55, + c_aauiCQMFHuffDec56, + c_aauiCQMFHuffDec57, + c_aauiCQMFHuffDec58, + c_aauiCQMFHuffDec59, + c_aauiCQMFHuffDec60, + c_aauiCQMFHuffDec61, + c_aauiCQMFHuffDec62, + c_aauiCQMFHuffDec63, +}; +#else +const uint32_t num_row_aauiCQMFHuff[2 * ALLOC_TABLE_SIZE] = { 0, 16, 16, 25, 36, 36, 49, 64, 81, 100, + 169, 196, 289, 324, 400, 576, 729, 729, 28, 29, + 32, 37, 39, 46, 55, 65, 77, 91, 109, 129, + 153, 181, 0, 16, 16, 25, 36, 36, 49, 64, 81, + 100, 169, 196, 289, 324, 400, 576, 729, 729, 28, + 29, 32, 37, 39, 46, 55, 65, 77, 91, 109, + 129, 153, 181 }; +#endif +#ifdef USE_DEMOD_TABLES +const int32_t c_aaiHuffDemod1[16][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, +}; + +const int32_t c_aaiHuffDemod2[16][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, +}; + +const int32_t c_aaiHuffDemod3[25][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, +}; + +const int32_t c_aaiHuffDemod4[36][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, +}; + +const int32_t c_aaiHuffDemod5[36][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, +}; + +const int32_t c_aaiHuffDemod6[49][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, +}; + +const int32_t c_aaiHuffDemod7[64][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, +}; + +const int32_t c_aaiHuffDemod8[81][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, +}; + +const int32_t c_aaiHuffDemod9[100][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, +}; + +const int32_t c_aaiHuffDemod10[169][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, +}; + +const int32_t c_aaiHuffDemod11[196][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, +}; + +const int32_t c_aaiHuffDemod12[289][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 0, + 14, + 0, + 15, + 0, + 16, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 1, + 14, + 1, + 15, + 1, + 16, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 2, + 14, + 2, + 15, + 2, + 16, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 3, + 14, + 3, + 15, + 3, + 16, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 4, + 14, + 4, + 15, + 4, + 16, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 5, + 14, + 5, + 15, + 5, + 16, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 6, + 14, + 6, + 15, + 6, + 16, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 7, + 14, + 7, + 15, + 7, + 16, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 8, + 14, + 8, + 15, + 8, + 16, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 9, + 14, + 9, + 15, + 9, + 16, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 10, + 14, + 10, + 15, + 10, + 16, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 11, + 14, + 11, + 15, + 11, + 16, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 12, + 14, + 12, + 15, + 12, + 16, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, + 13, + 14, + 13, + 15, + 13, + 16, + 14, + 0, + 14, + 1, + 14, + 2, + 14, + 3, + 14, + 4, + 14, + 5, + 14, + 6, + 14, + 7, + 14, + 8, + 14, + 9, + 14, + 10, + 14, + 11, + 14, + 12, + 14, + 13, + 14, + 14, + 14, + 15, + 14, + 16, + 15, + 0, + 15, + 1, + 15, + 2, + 15, + 3, + 15, + 4, + 15, + 5, + 15, + 6, + 15, + 7, + 15, + 8, + 15, + 9, + 15, + 10, + 15, + 11, + 15, + 12, + 15, + 13, + 15, + 14, + 15, + 15, + 15, + 16, + 16, + 0, + 16, + 1, + 16, + 2, + 16, + 3, + 16, + 4, + 16, + 5, + 16, + 6, + 16, + 7, + 16, + 8, + 16, + 9, + 16, + 10, + 16, + 11, + 16, + 12, + 16, + 13, + 16, + 14, + 16, + 15, + 16, + 16, +}; + +const int32_t c_aaiHuffDemod13[324][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 0, + 14, + 0, + 15, + 0, + 16, + 0, + 17, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 1, + 14, + 1, + 15, + 1, + 16, + 1, + 17, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 2, + 14, + 2, + 15, + 2, + 16, + 2, + 17, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 3, + 14, + 3, + 15, + 3, + 16, + 3, + 17, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 4, + 14, + 4, + 15, + 4, + 16, + 4, + 17, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 5, + 14, + 5, + 15, + 5, + 16, + 5, + 17, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 6, + 14, + 6, + 15, + 6, + 16, + 6, + 17, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 7, + 14, + 7, + 15, + 7, + 16, + 7, + 17, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 8, + 14, + 8, + 15, + 8, + 16, + 8, + 17, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 9, + 14, + 9, + 15, + 9, + 16, + 9, + 17, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 10, + 14, + 10, + 15, + 10, + 16, + 10, + 17, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 11, + 14, + 11, + 15, + 11, + 16, + 11, + 17, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 12, + 14, + 12, + 15, + 12, + 16, + 12, + 17, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, + 13, + 14, + 13, + 15, + 13, + 16, + 13, + 17, + 14, + 0, + 14, + 1, + 14, + 2, + 14, + 3, + 14, + 4, + 14, + 5, + 14, + 6, + 14, + 7, + 14, + 8, + 14, + 9, + 14, + 10, + 14, + 11, + 14, + 12, + 14, + 13, + 14, + 14, + 14, + 15, + 14, + 16, + 14, + 17, + 15, + 0, + 15, + 1, + 15, + 2, + 15, + 3, + 15, + 4, + 15, + 5, + 15, + 6, + 15, + 7, + 15, + 8, + 15, + 9, + 15, + 10, + 15, + 11, + 15, + 12, + 15, + 13, + 15, + 14, + 15, + 15, + 15, + 16, + 15, + 17, + 16, + 0, + 16, + 1, + 16, + 2, + 16, + 3, + 16, + 4, + 16, + 5, + 16, + 6, + 16, + 7, + 16, + 8, + 16, + 9, + 16, + 10, + 16, + 11, + 16, + 12, + 16, + 13, + 16, + 14, + 16, + 15, + 16, + 16, + 16, + 17, + 17, + 0, + 17, + 1, + 17, + 2, + 17, + 3, + 17, + 4, + 17, + 5, + 17, + 6, + 17, + 7, + 17, + 8, + 17, + 9, + 17, + 10, + 17, + 11, + 17, + 12, + 17, + 13, + 17, + 14, + 17, + 15, + 17, + 16, + 17, + 17, +}; + +const int32_t c_aaiHuffDemod14[400][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 0, + 14, + 0, + 15, + 0, + 16, + 0, + 17, + 0, + 18, + 0, + 19, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 1, + 14, + 1, + 15, + 1, + 16, + 1, + 17, + 1, + 18, + 1, + 19, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 2, + 14, + 2, + 15, + 2, + 16, + 2, + 17, + 2, + 18, + 2, + 19, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 3, + 14, + 3, + 15, + 3, + 16, + 3, + 17, + 3, + 18, + 3, + 19, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 4, + 14, + 4, + 15, + 4, + 16, + 4, + 17, + 4, + 18, + 4, + 19, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 5, + 14, + 5, + 15, + 5, + 16, + 5, + 17, + 5, + 18, + 5, + 19, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 6, + 14, + 6, + 15, + 6, + 16, + 6, + 17, + 6, + 18, + 6, + 19, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 7, + 14, + 7, + 15, + 7, + 16, + 7, + 17, + 7, + 18, + 7, + 19, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 8, + 14, + 8, + 15, + 8, + 16, + 8, + 17, + 8, + 18, + 8, + 19, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 9, + 14, + 9, + 15, + 9, + 16, + 9, + 17, + 9, + 18, + 9, + 19, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 10, + 14, + 10, + 15, + 10, + 16, + 10, + 17, + 10, + 18, + 10, + 19, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 11, + 14, + 11, + 15, + 11, + 16, + 11, + 17, + 11, + 18, + 11, + 19, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 12, + 14, + 12, + 15, + 12, + 16, + 12, + 17, + 12, + 18, + 12, + 19, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, + 13, + 14, + 13, + 15, + 13, + 16, + 13, + 17, + 13, + 18, + 13, + 19, + 14, + 0, + 14, + 1, + 14, + 2, + 14, + 3, + 14, + 4, + 14, + 5, + 14, + 6, + 14, + 7, + 14, + 8, + 14, + 9, + 14, + 10, + 14, + 11, + 14, + 12, + 14, + 13, + 14, + 14, + 14, + 15, + 14, + 16, + 14, + 17, + 14, + 18, + 14, + 19, + 15, + 0, + 15, + 1, + 15, + 2, + 15, + 3, + 15, + 4, + 15, + 5, + 15, + 6, + 15, + 7, + 15, + 8, + 15, + 9, + 15, + 10, + 15, + 11, + 15, + 12, + 15, + 13, + 15, + 14, + 15, + 15, + 15, + 16, + 15, + 17, + 15, + 18, + 15, + 19, + 16, + 0, + 16, + 1, + 16, + 2, + 16, + 3, + 16, + 4, + 16, + 5, + 16, + 6, + 16, + 7, + 16, + 8, + 16, + 9, + 16, + 10, + 16, + 11, + 16, + 12, + 16, + 13, + 16, + 14, + 16, + 15, + 16, + 16, + 16, + 17, + 16, + 18, + 16, + 19, + 17, + 0, + 17, + 1, + 17, + 2, + 17, + 3, + 17, + 4, + 17, + 5, + 17, + 6, + 17, + 7, + 17, + 8, + 17, + 9, + 17, + 10, + 17, + 11, + 17, + 12, + 17, + 13, + 17, + 14, + 17, + 15, + 17, + 16, + 17, + 17, + 17, + 18, + 17, + 19, + 18, + 0, + 18, + 1, + 18, + 2, + 18, + 3, + 18, + 4, + 18, + 5, + 18, + 6, + 18, + 7, + 18, + 8, + 18, + 9, + 18, + 10, + 18, + 11, + 18, + 12, + 18, + 13, + 18, + 14, + 18, + 15, + 18, + 16, + 18, + 17, + 18, + 18, + 18, + 19, + 19, + 0, + 19, + 1, + 19, + 2, + 19, + 3, + 19, + 4, + 19, + 5, + 19, + 6, + 19, + 7, + 19, + 8, + 19, + 9, + 19, + 10, + 19, + 11, + 19, + 12, + 19, + 13, + 19, + 14, + 19, + 15, + 19, + 16, + 19, + 17, + 19, + 18, + 19, + 19, +}; + +const int32_t c_aaiHuffDemod15[576][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 0, + 14, + 0, + 15, + 0, + 16, + 0, + 17, + 0, + 18, + 0, + 19, + 0, + 20, + 0, + 21, + 0, + 22, + 0, + 23, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 1, + 14, + 1, + 15, + 1, + 16, + 1, + 17, + 1, + 18, + 1, + 19, + 1, + 20, + 1, + 21, + 1, + 22, + 1, + 23, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 2, + 14, + 2, + 15, + 2, + 16, + 2, + 17, + 2, + 18, + 2, + 19, + 2, + 20, + 2, + 21, + 2, + 22, + 2, + 23, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 3, + 14, + 3, + 15, + 3, + 16, + 3, + 17, + 3, + 18, + 3, + 19, + 3, + 20, + 3, + 21, + 3, + 22, + 3, + 23, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 4, + 14, + 4, + 15, + 4, + 16, + 4, + 17, + 4, + 18, + 4, + 19, + 4, + 20, + 4, + 21, + 4, + 22, + 4, + 23, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 5, + 14, + 5, + 15, + 5, + 16, + 5, + 17, + 5, + 18, + 5, + 19, + 5, + 20, + 5, + 21, + 5, + 22, + 5, + 23, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 6, + 14, + 6, + 15, + 6, + 16, + 6, + 17, + 6, + 18, + 6, + 19, + 6, + 20, + 6, + 21, + 6, + 22, + 6, + 23, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 7, + 14, + 7, + 15, + 7, + 16, + 7, + 17, + 7, + 18, + 7, + 19, + 7, + 20, + 7, + 21, + 7, + 22, + 7, + 23, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 8, + 14, + 8, + 15, + 8, + 16, + 8, + 17, + 8, + 18, + 8, + 19, + 8, + 20, + 8, + 21, + 8, + 22, + 8, + 23, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 9, + 14, + 9, + 15, + 9, + 16, + 9, + 17, + 9, + 18, + 9, + 19, + 9, + 20, + 9, + 21, + 9, + 22, + 9, + 23, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 10, + 14, + 10, + 15, + 10, + 16, + 10, + 17, + 10, + 18, + 10, + 19, + 10, + 20, + 10, + 21, + 10, + 22, + 10, + 23, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 11, + 14, + 11, + 15, + 11, + 16, + 11, + 17, + 11, + 18, + 11, + 19, + 11, + 20, + 11, + 21, + 11, + 22, + 11, + 23, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 12, + 14, + 12, + 15, + 12, + 16, + 12, + 17, + 12, + 18, + 12, + 19, + 12, + 20, + 12, + 21, + 12, + 22, + 12, + 23, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, + 13, + 14, + 13, + 15, + 13, + 16, + 13, + 17, + 13, + 18, + 13, + 19, + 13, + 20, + 13, + 21, + 13, + 22, + 13, + 23, + 14, + 0, + 14, + 1, + 14, + 2, + 14, + 3, + 14, + 4, + 14, + 5, + 14, + 6, + 14, + 7, + 14, + 8, + 14, + 9, + 14, + 10, + 14, + 11, + 14, + 12, + 14, + 13, + 14, + 14, + 14, + 15, + 14, + 16, + 14, + 17, + 14, + 18, + 14, + 19, + 14, + 20, + 14, + 21, + 14, + 22, + 14, + 23, + 15, + 0, + 15, + 1, + 15, + 2, + 15, + 3, + 15, + 4, + 15, + 5, + 15, + 6, + 15, + 7, + 15, + 8, + 15, + 9, + 15, + 10, + 15, + 11, + 15, + 12, + 15, + 13, + 15, + 14, + 15, + 15, + 15, + 16, + 15, + 17, + 15, + 18, + 15, + 19, + 15, + 20, + 15, + 21, + 15, + 22, + 15, + 23, + 16, + 0, + 16, + 1, + 16, + 2, + 16, + 3, + 16, + 4, + 16, + 5, + 16, + 6, + 16, + 7, + 16, + 8, + 16, + 9, + 16, + 10, + 16, + 11, + 16, + 12, + 16, + 13, + 16, + 14, + 16, + 15, + 16, + 16, + 16, + 17, + 16, + 18, + 16, + 19, + 16, + 20, + 16, + 21, + 16, + 22, + 16, + 23, + 17, + 0, + 17, + 1, + 17, + 2, + 17, + 3, + 17, + 4, + 17, + 5, + 17, + 6, + 17, + 7, + 17, + 8, + 17, + 9, + 17, + 10, + 17, + 11, + 17, + 12, + 17, + 13, + 17, + 14, + 17, + 15, + 17, + 16, + 17, + 17, + 17, + 18, + 17, + 19, + 17, + 20, + 17, + 21, + 17, + 22, + 17, + 23, + 18, + 0, + 18, + 1, + 18, + 2, + 18, + 3, + 18, + 4, + 18, + 5, + 18, + 6, + 18, + 7, + 18, + 8, + 18, + 9, + 18, + 10, + 18, + 11, + 18, + 12, + 18, + 13, + 18, + 14, + 18, + 15, + 18, + 16, + 18, + 17, + 18, + 18, + 18, + 19, + 18, + 20, + 18, + 21, + 18, + 22, + 18, + 23, + 19, + 0, + 19, + 1, + 19, + 2, + 19, + 3, + 19, + 4, + 19, + 5, + 19, + 6, + 19, + 7, + 19, + 8, + 19, + 9, + 19, + 10, + 19, + 11, + 19, + 12, + 19, + 13, + 19, + 14, + 19, + 15, + 19, + 16, + 19, + 17, + 19, + 18, + 19, + 19, + 19, + 20, + 19, + 21, + 19, + 22, + 19, + 23, + 20, + 0, + 20, + 1, + 20, + 2, + 20, + 3, + 20, + 4, + 20, + 5, + 20, + 6, + 20, + 7, + 20, + 8, + 20, + 9, + 20, + 10, + 20, + 11, + 20, + 12, + 20, + 13, + 20, + 14, + 20, + 15, + 20, + 16, + 20, + 17, + 20, + 18, + 20, + 19, + 20, + 20, + 20, + 21, + 20, + 22, + 20, + 23, + 21, + 0, + 21, + 1, + 21, + 2, + 21, + 3, + 21, + 4, + 21, + 5, + 21, + 6, + 21, + 7, + 21, + 8, + 21, + 9, + 21, + 10, + 21, + 11, + 21, + 12, + 21, + 13, + 21, + 14, + 21, + 15, + 21, + 16, + 21, + 17, + 21, + 18, + 21, + 19, + 21, + 20, + 21, + 21, + 21, + 22, + 21, + 23, + 22, + 0, + 22, + 1, + 22, + 2, + 22, + 3, + 22, + 4, + 22, + 5, + 22, + 6, + 22, + 7, + 22, + 8, + 22, + 9, + 22, + 10, + 22, + 11, + 22, + 12, + 22, + 13, + 22, + 14, + 22, + 15, + 22, + 16, + 22, + 17, + 22, + 18, + 22, + 19, + 22, + 20, + 22, + 21, + 22, + 22, + 22, + 23, + 23, + 0, + 23, + 1, + 23, + 2, + 23, + 3, + 23, + 4, + 23, + 5, + 23, + 6, + 23, + 7, + 23, + 8, + 23, + 9, + 23, + 10, + 23, + 11, + 23, + 12, + 23, + 13, + 23, + 14, + 23, + 15, + 23, + 16, + 23, + 17, + 23, + 18, + 23, + 19, + 23, + 20, + 23, + 21, + 23, + 22, + 23, + 23, +}; + +const int32_t c_aaiHuffDemod16[729][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 0, + 14, + 0, + 15, + 0, + 16, + 0, + 17, + 0, + 18, + 0, + 19, + 0, + 20, + 0, + 21, + 0, + 22, + 0, + 23, + 0, + 24, + 0, + 25, + 0, + 26, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 1, + 14, + 1, + 15, + 1, + 16, + 1, + 17, + 1, + 18, + 1, + 19, + 1, + 20, + 1, + 21, + 1, + 22, + 1, + 23, + 1, + 24, + 1, + 25, + 1, + 26, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 2, + 14, + 2, + 15, + 2, + 16, + 2, + 17, + 2, + 18, + 2, + 19, + 2, + 20, + 2, + 21, + 2, + 22, + 2, + 23, + 2, + 24, + 2, + 25, + 2, + 26, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 3, + 14, + 3, + 15, + 3, + 16, + 3, + 17, + 3, + 18, + 3, + 19, + 3, + 20, + 3, + 21, + 3, + 22, + 3, + 23, + 3, + 24, + 3, + 25, + 3, + 26, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 4, + 14, + 4, + 15, + 4, + 16, + 4, + 17, + 4, + 18, + 4, + 19, + 4, + 20, + 4, + 21, + 4, + 22, + 4, + 23, + 4, + 24, + 4, + 25, + 4, + 26, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 5, + 14, + 5, + 15, + 5, + 16, + 5, + 17, + 5, + 18, + 5, + 19, + 5, + 20, + 5, + 21, + 5, + 22, + 5, + 23, + 5, + 24, + 5, + 25, + 5, + 26, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 6, + 14, + 6, + 15, + 6, + 16, + 6, + 17, + 6, + 18, + 6, + 19, + 6, + 20, + 6, + 21, + 6, + 22, + 6, + 23, + 6, + 24, + 6, + 25, + 6, + 26, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 7, + 14, + 7, + 15, + 7, + 16, + 7, + 17, + 7, + 18, + 7, + 19, + 7, + 20, + 7, + 21, + 7, + 22, + 7, + 23, + 7, + 24, + 7, + 25, + 7, + 26, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 8, + 14, + 8, + 15, + 8, + 16, + 8, + 17, + 8, + 18, + 8, + 19, + 8, + 20, + 8, + 21, + 8, + 22, + 8, + 23, + 8, + 24, + 8, + 25, + 8, + 26, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 9, + 14, + 9, + 15, + 9, + 16, + 9, + 17, + 9, + 18, + 9, + 19, + 9, + 20, + 9, + 21, + 9, + 22, + 9, + 23, + 9, + 24, + 9, + 25, + 9, + 26, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 10, + 14, + 10, + 15, + 10, + 16, + 10, + 17, + 10, + 18, + 10, + 19, + 10, + 20, + 10, + 21, + 10, + 22, + 10, + 23, + 10, + 24, + 10, + 25, + 10, + 26, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 11, + 14, + 11, + 15, + 11, + 16, + 11, + 17, + 11, + 18, + 11, + 19, + 11, + 20, + 11, + 21, + 11, + 22, + 11, + 23, + 11, + 24, + 11, + 25, + 11, + 26, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 12, + 14, + 12, + 15, + 12, + 16, + 12, + 17, + 12, + 18, + 12, + 19, + 12, + 20, + 12, + 21, + 12, + 22, + 12, + 23, + 12, + 24, + 12, + 25, + 12, + 26, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, + 13, + 14, + 13, + 15, + 13, + 16, + 13, + 17, + 13, + 18, + 13, + 19, + 13, + 20, + 13, + 21, + 13, + 22, + 13, + 23, + 13, + 24, + 13, + 25, + 13, + 26, + 14, + 0, + 14, + 1, + 14, + 2, + 14, + 3, + 14, + 4, + 14, + 5, + 14, + 6, + 14, + 7, + 14, + 8, + 14, + 9, + 14, + 10, + 14, + 11, + 14, + 12, + 14, + 13, + 14, + 14, + 14, + 15, + 14, + 16, + 14, + 17, + 14, + 18, + 14, + 19, + 14, + 20, + 14, + 21, + 14, + 22, + 14, + 23, + 14, + 24, + 14, + 25, + 14, + 26, + 15, + 0, + 15, + 1, + 15, + 2, + 15, + 3, + 15, + 4, + 15, + 5, + 15, + 6, + 15, + 7, + 15, + 8, + 15, + 9, + 15, + 10, + 15, + 11, + 15, + 12, + 15, + 13, + 15, + 14, + 15, + 15, + 15, + 16, + 15, + 17, + 15, + 18, + 15, + 19, + 15, + 20, + 15, + 21, + 15, + 22, + 15, + 23, + 15, + 24, + 15, + 25, + 15, + 26, + 16, + 0, + 16, + 1, + 16, + 2, + 16, + 3, + 16, + 4, + 16, + 5, + 16, + 6, + 16, + 7, + 16, + 8, + 16, + 9, + 16, + 10, + 16, + 11, + 16, + 12, + 16, + 13, + 16, + 14, + 16, + 15, + 16, + 16, + 16, + 17, + 16, + 18, + 16, + 19, + 16, + 20, + 16, + 21, + 16, + 22, + 16, + 23, + 16, + 24, + 16, + 25, + 16, + 26, + 17, + 0, + 17, + 1, + 17, + 2, + 17, + 3, + 17, + 4, + 17, + 5, + 17, + 6, + 17, + 7, + 17, + 8, + 17, + 9, + 17, + 10, + 17, + 11, + 17, + 12, + 17, + 13, + 17, + 14, + 17, + 15, + 17, + 16, + 17, + 17, + 17, + 18, + 17, + 19, + 17, + 20, + 17, + 21, + 17, + 22, + 17, + 23, + 17, + 24, + 17, + 25, + 17, + 26, + 18, + 0, + 18, + 1, + 18, + 2, + 18, + 3, + 18, + 4, + 18, + 5, + 18, + 6, + 18, + 7, + 18, + 8, + 18, + 9, + 18, + 10, + 18, + 11, + 18, + 12, + 18, + 13, + 18, + 14, + 18, + 15, + 18, + 16, + 18, + 17, + 18, + 18, + 18, + 19, + 18, + 20, + 18, + 21, + 18, + 22, + 18, + 23, + 18, + 24, + 18, + 25, + 18, + 26, + 19, + 0, + 19, + 1, + 19, + 2, + 19, + 3, + 19, + 4, + 19, + 5, + 19, + 6, + 19, + 7, + 19, + 8, + 19, + 9, + 19, + 10, + 19, + 11, + 19, + 12, + 19, + 13, + 19, + 14, + 19, + 15, + 19, + 16, + 19, + 17, + 19, + 18, + 19, + 19, + 19, + 20, + 19, + 21, + 19, + 22, + 19, + 23, + 19, + 24, + 19, + 25, + 19, + 26, + 20, + 0, + 20, + 1, + 20, + 2, + 20, + 3, + 20, + 4, + 20, + 5, + 20, + 6, + 20, + 7, + 20, + 8, + 20, + 9, + 20, + 10, + 20, + 11, + 20, + 12, + 20, + 13, + 20, + 14, + 20, + 15, + 20, + 16, + 20, + 17, + 20, + 18, + 20, + 19, + 20, + 20, + 20, + 21, + 20, + 22, + 20, + 23, + 20, + 24, + 20, + 25, + 20, + 26, + 21, + 0, + 21, + 1, + 21, + 2, + 21, + 3, + 21, + 4, + 21, + 5, + 21, + 6, + 21, + 7, + 21, + 8, + 21, + 9, + 21, + 10, + 21, + 11, + 21, + 12, + 21, + 13, + 21, + 14, + 21, + 15, + 21, + 16, + 21, + 17, + 21, + 18, + 21, + 19, + 21, + 20, + 21, + 21, + 21, + 22, + 21, + 23, + 21, + 24, + 21, + 25, + 21, + 26, + 22, + 0, + 22, + 1, + 22, + 2, + 22, + 3, + 22, + 4, + 22, + 5, + 22, + 6, + 22, + 7, + 22, + 8, + 22, + 9, + 22, + 10, + 22, + 11, + 22, + 12, + 22, + 13, + 22, + 14, + 22, + 15, + 22, + 16, + 22, + 17, + 22, + 18, + 22, + 19, + 22, + 20, + 22, + 21, + 22, + 22, + 22, + 23, + 22, + 24, + 22, + 25, + 22, + 26, + 23, + 0, + 23, + 1, + 23, + 2, + 23, + 3, + 23, + 4, + 23, + 5, + 23, + 6, + 23, + 7, + 23, + 8, + 23, + 9, + 23, + 10, + 23, + 11, + 23, + 12, + 23, + 13, + 23, + 14, + 23, + 15, + 23, + 16, + 23, + 17, + 23, + 18, + 23, + 19, + 23, + 20, + 23, + 21, + 23, + 22, + 23, + 23, + 23, + 24, + 23, + 25, + 23, + 26, + 24, + 0, + 24, + 1, + 24, + 2, + 24, + 3, + 24, + 4, + 24, + 5, + 24, + 6, + 24, + 7, + 24, + 8, + 24, + 9, + 24, + 10, + 24, + 11, + 24, + 12, + 24, + 13, + 24, + 14, + 24, + 15, + 24, + 16, + 24, + 17, + 24, + 18, + 24, + 19, + 24, + 20, + 24, + 21, + 24, + 22, + 24, + 23, + 24, + 24, + 24, + 25, + 24, + 26, + 25, + 0, + 25, + 1, + 25, + 2, + 25, + 3, + 25, + 4, + 25, + 5, + 25, + 6, + 25, + 7, + 25, + 8, + 25, + 9, + 25, + 10, + 25, + 11, + 25, + 12, + 25, + 13, + 25, + 14, + 25, + 15, + 25, + 16, + 25, + 17, + 25, + 18, + 25, + 19, + 25, + 20, + 25, + 21, + 25, + 22, + 25, + 23, + 25, + 24, + 25, + 25, + 25, + 26, + 26, + 0, + 26, + 1, + 26, + 2, + 26, + 3, + 26, + 4, + 26, + 5, + 26, + 6, + 26, + 7, + 26, + 8, + 26, + 9, + 26, + 10, + 26, + 11, + 26, + 12, + 26, + 13, + 26, + 14, + 26, + 15, + 26, + 16, + 26, + 17, + 26, + 18, + 26, + 19, + 26, + 20, + 26, + 21, + 26, + 22, + 26, + 23, + 26, + 24, + 26, + 25, + 26, + 26, +}; + +const int32_t c_aaiHuffDemod17[729][2] = { + 0, + 0, + 0, + 1, + 0, + 2, + 0, + 3, + 0, + 4, + 0, + 5, + 0, + 6, + 0, + 7, + 0, + 8, + 0, + 9, + 0, + 10, + 0, + 11, + 0, + 12, + 0, + 13, + 0, + 14, + 0, + 15, + 0, + 16, + 0, + 17, + 0, + 18, + 0, + 19, + 0, + 20, + 0, + 21, + 0, + 22, + 0, + 23, + 0, + 24, + 0, + 25, + 0, + 26, + 1, + 0, + 1, + 1, + 1, + 2, + 1, + 3, + 1, + 4, + 1, + 5, + 1, + 6, + 1, + 7, + 1, + 8, + 1, + 9, + 1, + 10, + 1, + 11, + 1, + 12, + 1, + 13, + 1, + 14, + 1, + 15, + 1, + 16, + 1, + 17, + 1, + 18, + 1, + 19, + 1, + 20, + 1, + 21, + 1, + 22, + 1, + 23, + 1, + 24, + 1, + 25, + 1, + 26, + 2, + 0, + 2, + 1, + 2, + 2, + 2, + 3, + 2, + 4, + 2, + 5, + 2, + 6, + 2, + 7, + 2, + 8, + 2, + 9, + 2, + 10, + 2, + 11, + 2, + 12, + 2, + 13, + 2, + 14, + 2, + 15, + 2, + 16, + 2, + 17, + 2, + 18, + 2, + 19, + 2, + 20, + 2, + 21, + 2, + 22, + 2, + 23, + 2, + 24, + 2, + 25, + 2, + 26, + 3, + 0, + 3, + 1, + 3, + 2, + 3, + 3, + 3, + 4, + 3, + 5, + 3, + 6, + 3, + 7, + 3, + 8, + 3, + 9, + 3, + 10, + 3, + 11, + 3, + 12, + 3, + 13, + 3, + 14, + 3, + 15, + 3, + 16, + 3, + 17, + 3, + 18, + 3, + 19, + 3, + 20, + 3, + 21, + 3, + 22, + 3, + 23, + 3, + 24, + 3, + 25, + 3, + 26, + 4, + 0, + 4, + 1, + 4, + 2, + 4, + 3, + 4, + 4, + 4, + 5, + 4, + 6, + 4, + 7, + 4, + 8, + 4, + 9, + 4, + 10, + 4, + 11, + 4, + 12, + 4, + 13, + 4, + 14, + 4, + 15, + 4, + 16, + 4, + 17, + 4, + 18, + 4, + 19, + 4, + 20, + 4, + 21, + 4, + 22, + 4, + 23, + 4, + 24, + 4, + 25, + 4, + 26, + 5, + 0, + 5, + 1, + 5, + 2, + 5, + 3, + 5, + 4, + 5, + 5, + 5, + 6, + 5, + 7, + 5, + 8, + 5, + 9, + 5, + 10, + 5, + 11, + 5, + 12, + 5, + 13, + 5, + 14, + 5, + 15, + 5, + 16, + 5, + 17, + 5, + 18, + 5, + 19, + 5, + 20, + 5, + 21, + 5, + 22, + 5, + 23, + 5, + 24, + 5, + 25, + 5, + 26, + 6, + 0, + 6, + 1, + 6, + 2, + 6, + 3, + 6, + 4, + 6, + 5, + 6, + 6, + 6, + 7, + 6, + 8, + 6, + 9, + 6, + 10, + 6, + 11, + 6, + 12, + 6, + 13, + 6, + 14, + 6, + 15, + 6, + 16, + 6, + 17, + 6, + 18, + 6, + 19, + 6, + 20, + 6, + 21, + 6, + 22, + 6, + 23, + 6, + 24, + 6, + 25, + 6, + 26, + 7, + 0, + 7, + 1, + 7, + 2, + 7, + 3, + 7, + 4, + 7, + 5, + 7, + 6, + 7, + 7, + 7, + 8, + 7, + 9, + 7, + 10, + 7, + 11, + 7, + 12, + 7, + 13, + 7, + 14, + 7, + 15, + 7, + 16, + 7, + 17, + 7, + 18, + 7, + 19, + 7, + 20, + 7, + 21, + 7, + 22, + 7, + 23, + 7, + 24, + 7, + 25, + 7, + 26, + 8, + 0, + 8, + 1, + 8, + 2, + 8, + 3, + 8, + 4, + 8, + 5, + 8, + 6, + 8, + 7, + 8, + 8, + 8, + 9, + 8, + 10, + 8, + 11, + 8, + 12, + 8, + 13, + 8, + 14, + 8, + 15, + 8, + 16, + 8, + 17, + 8, + 18, + 8, + 19, + 8, + 20, + 8, + 21, + 8, + 22, + 8, + 23, + 8, + 24, + 8, + 25, + 8, + 26, + 9, + 0, + 9, + 1, + 9, + 2, + 9, + 3, + 9, + 4, + 9, + 5, + 9, + 6, + 9, + 7, + 9, + 8, + 9, + 9, + 9, + 10, + 9, + 11, + 9, + 12, + 9, + 13, + 9, + 14, + 9, + 15, + 9, + 16, + 9, + 17, + 9, + 18, + 9, + 19, + 9, + 20, + 9, + 21, + 9, + 22, + 9, + 23, + 9, + 24, + 9, + 25, + 9, + 26, + 10, + 0, + 10, + 1, + 10, + 2, + 10, + 3, + 10, + 4, + 10, + 5, + 10, + 6, + 10, + 7, + 10, + 8, + 10, + 9, + 10, + 10, + 10, + 11, + 10, + 12, + 10, + 13, + 10, + 14, + 10, + 15, + 10, + 16, + 10, + 17, + 10, + 18, + 10, + 19, + 10, + 20, + 10, + 21, + 10, + 22, + 10, + 23, + 10, + 24, + 10, + 25, + 10, + 26, + 11, + 0, + 11, + 1, + 11, + 2, + 11, + 3, + 11, + 4, + 11, + 5, + 11, + 6, + 11, + 7, + 11, + 8, + 11, + 9, + 11, + 10, + 11, + 11, + 11, + 12, + 11, + 13, + 11, + 14, + 11, + 15, + 11, + 16, + 11, + 17, + 11, + 18, + 11, + 19, + 11, + 20, + 11, + 21, + 11, + 22, + 11, + 23, + 11, + 24, + 11, + 25, + 11, + 26, + 12, + 0, + 12, + 1, + 12, + 2, + 12, + 3, + 12, + 4, + 12, + 5, + 12, + 6, + 12, + 7, + 12, + 8, + 12, + 9, + 12, + 10, + 12, + 11, + 12, + 12, + 12, + 13, + 12, + 14, + 12, + 15, + 12, + 16, + 12, + 17, + 12, + 18, + 12, + 19, + 12, + 20, + 12, + 21, + 12, + 22, + 12, + 23, + 12, + 24, + 12, + 25, + 12, + 26, + 13, + 0, + 13, + 1, + 13, + 2, + 13, + 3, + 13, + 4, + 13, + 5, + 13, + 6, + 13, + 7, + 13, + 8, + 13, + 9, + 13, + 10, + 13, + 11, + 13, + 12, + 13, + 13, + 13, + 14, + 13, + 15, + 13, + 16, + 13, + 17, + 13, + 18, + 13, + 19, + 13, + 20, + 13, + 21, + 13, + 22, + 13, + 23, + 13, + 24, + 13, + 25, + 13, + 26, + 14, + 0, + 14, + 1, + 14, + 2, + 14, + 3, + 14, + 4, + 14, + 5, + 14, + 6, + 14, + 7, + 14, + 8, + 14, + 9, + 14, + 10, + 14, + 11, + 14, + 12, + 14, + 13, + 14, + 14, + 14, + 15, + 14, + 16, + 14, + 17, + 14, + 18, + 14, + 19, + 14, + 20, + 14, + 21, + 14, + 22, + 14, + 23, + 14, + 24, + 14, + 25, + 14, + 26, + 15, + 0, + 15, + 1, + 15, + 2, + 15, + 3, + 15, + 4, + 15, + 5, + 15, + 6, + 15, + 7, + 15, + 8, + 15, + 9, + 15, + 10, + 15, + 11, + 15, + 12, + 15, + 13, + 15, + 14, + 15, + 15, + 15, + 16, + 15, + 17, + 15, + 18, + 15, + 19, + 15, + 20, + 15, + 21, + 15, + 22, + 15, + 23, + 15, + 24, + 15, + 25, + 15, + 26, + 16, + 0, + 16, + 1, + 16, + 2, + 16, + 3, + 16, + 4, + 16, + 5, + 16, + 6, + 16, + 7, + 16, + 8, + 16, + 9, + 16, + 10, + 16, + 11, + 16, + 12, + 16, + 13, + 16, + 14, + 16, + 15, + 16, + 16, + 16, + 17, + 16, + 18, + 16, + 19, + 16, + 20, + 16, + 21, + 16, + 22, + 16, + 23, + 16, + 24, + 16, + 25, + 16, + 26, + 17, + 0, + 17, + 1, + 17, + 2, + 17, + 3, + 17, + 4, + 17, + 5, + 17, + 6, + 17, + 7, + 17, + 8, + 17, + 9, + 17, + 10, + 17, + 11, + 17, + 12, + 17, + 13, + 17, + 14, + 17, + 15, + 17, + 16, + 17, + 17, + 17, + 18, + 17, + 19, + 17, + 20, + 17, + 21, + 17, + 22, + 17, + 23, + 17, + 24, + 17, + 25, + 17, + 26, + 18, + 0, + 18, + 1, + 18, + 2, + 18, + 3, + 18, + 4, + 18, + 5, + 18, + 6, + 18, + 7, + 18, + 8, + 18, + 9, + 18, + 10, + 18, + 11, + 18, + 12, + 18, + 13, + 18, + 14, + 18, + 15, + 18, + 16, + 18, + 17, + 18, + 18, + 18, + 19, + 18, + 20, + 18, + 21, + 18, + 22, + 18, + 23, + 18, + 24, + 18, + 25, + 18, + 26, + 19, + 0, + 19, + 1, + 19, + 2, + 19, + 3, + 19, + 4, + 19, + 5, + 19, + 6, + 19, + 7, + 19, + 8, + 19, + 9, + 19, + 10, + 19, + 11, + 19, + 12, + 19, + 13, + 19, + 14, + 19, + 15, + 19, + 16, + 19, + 17, + 19, + 18, + 19, + 19, + 19, + 20, + 19, + 21, + 19, + 22, + 19, + 23, + 19, + 24, + 19, + 25, + 19, + 26, + 20, + 0, + 20, + 1, + 20, + 2, + 20, + 3, + 20, + 4, + 20, + 5, + 20, + 6, + 20, + 7, + 20, + 8, + 20, + 9, + 20, + 10, + 20, + 11, + 20, + 12, + 20, + 13, + 20, + 14, + 20, + 15, + 20, + 16, + 20, + 17, + 20, + 18, + 20, + 19, + 20, + 20, + 20, + 21, + 20, + 22, + 20, + 23, + 20, + 24, + 20, + 25, + 20, + 26, + 21, + 0, + 21, + 1, + 21, + 2, + 21, + 3, + 21, + 4, + 21, + 5, + 21, + 6, + 21, + 7, + 21, + 8, + 21, + 9, + 21, + 10, + 21, + 11, + 21, + 12, + 21, + 13, + 21, + 14, + 21, + 15, + 21, + 16, + 21, + 17, + 21, + 18, + 21, + 19, + 21, + 20, + 21, + 21, + 21, + 22, + 21, + 23, + 21, + 24, + 21, + 25, + 21, + 26, + 22, + 0, + 22, + 1, + 22, + 2, + 22, + 3, + 22, + 4, + 22, + 5, + 22, + 6, + 22, + 7, + 22, + 8, + 22, + 9, + 22, + 10, + 22, + 11, + 22, + 12, + 22, + 13, + 22, + 14, + 22, + 15, + 22, + 16, + 22, + 17, + 22, + 18, + 22, + 19, + 22, + 20, + 22, + 21, + 22, + 22, + 22, + 23, + 22, + 24, + 22, + 25, + 22, + 26, + 23, + 0, + 23, + 1, + 23, + 2, + 23, + 3, + 23, + 4, + 23, + 5, + 23, + 6, + 23, + 7, + 23, + 8, + 23, + 9, + 23, + 10, + 23, + 11, + 23, + 12, + 23, + 13, + 23, + 14, + 23, + 15, + 23, + 16, + 23, + 17, + 23, + 18, + 23, + 19, + 23, + 20, + 23, + 21, + 23, + 22, + 23, + 23, + 23, + 24, + 23, + 25, + 23, + 26, + 24, + 0, + 24, + 1, + 24, + 2, + 24, + 3, + 24, + 4, + 24, + 5, + 24, + 6, + 24, + 7, + 24, + 8, + 24, + 9, + 24, + 10, + 24, + 11, + 24, + 12, + 24, + 13, + 24, + 14, + 24, + 15, + 24, + 16, + 24, + 17, + 24, + 18, + 24, + 19, + 24, + 20, + 24, + 21, + 24, + 22, + 24, + 23, + 24, + 24, + 24, + 25, + 24, + 26, + 25, + 0, + 25, + 1, + 25, + 2, + 25, + 3, + 25, + 4, + 25, + 5, + 25, + 6, + 25, + 7, + 25, + 8, + 25, + 9, + 25, + 10, + 25, + 11, + 25, + 12, + 25, + 13, + 25, + 14, + 25, + 15, + 25, + 16, + 25, + 17, + 25, + 18, + 25, + 19, + 25, + 20, + 25, + 21, + 25, + 22, + 25, + 23, + 25, + 24, + 25, + 25, + 25, + 26, + 26, + 0, + 26, + 1, + 26, + 2, + 26, + 3, + 26, + 4, + 26, + 5, + 26, + 6, + 26, + 7, + 26, + 8, + 26, + 9, + 26, + 10, + 26, + 11, + 26, + 12, + 26, + 13, + 26, + 14, + 26, + 15, + 26, + 16, + 26, + 17, + 26, + 18, + 26, + 19, + 26, + 20, + 26, + 21, + 26, + 22, + 26, + 23, + 26, + 24, + 26, + 25, + 26, + 26, +}; + +const int32_t ( *c_apaiDemodTables[ALLOC_TABLE_SIZE] )[2] = { + NULL, + c_aaiHuffDemod1, + c_aaiHuffDemod2, + c_aaiHuffDemod3, + c_aaiHuffDemod4, + c_aaiHuffDemod5, + c_aaiHuffDemod6, + c_aaiHuffDemod7, + c_aaiHuffDemod8, + c_aaiHuffDemod9, + c_aaiHuffDemod10, + c_aaiHuffDemod11, + c_aaiHuffDemod12, + c_aaiHuffDemod13, + c_aaiHuffDemod14, + c_aaiHuffDemod15, + c_aaiHuffDemod16, + c_aaiHuffDemod17, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; +#endif + +const int32_t c_aiLogAddTable[LOG_ADD_TABLE_LENGTH] = { + 0x40, + 0x40, + 0x3F, + 0x3F, + 0x3E, + 0x3E, + 0x3D, + 0x3D, + 0x3C, + 0x3C, + 0x3B, + 0x3B, + 0x3A, + 0x3A, + 0x39, + 0x39, + 0x38, + 0x38, + 0x37, + 0x37, + 0x37, + 0x36, + 0x36, + 0x35, + 0x35, + 0x34, + 0x34, + 0x33, + 0x33, + 0x33, + 0x32, + 0x32, + 0x31, + 0x31, + 0x31, + 0x30, + 0x30, + 0x2F, + 0x2F, + 0x2F, + 0x2E, + 0x2E, + 0x2D, + 0x2D, + 0x2D, + 0x2C, + 0x2C, + 0x2B, + 0x2B, + 0x2B, + 0x2A, + 0x2A, + 0x2A, + 0x29, + 0x29, + 0x29, + 0x28, + 0x28, + 0x27, + 0x27, + 0x27, + 0x26, + 0x26, + 0x26, + 0x25, + 0x25, + 0x25, + 0x24, + 0x24, + 0x24, + 0x23, + 0x23, + 0x23, + 0x23, + 0x22, + 0x22, + 0x22, + 0x21, + 0x21, + 0x21, + 0x20, + 0x20, + 0x20, + 0x20, + 0x1F, + 0x1F, + 0x1F, + 0x1E, + 0x1E, + 0x1E, + 0x1E, + 0x1D, + 0x1D, + 0x1D, + 0x1C, + 0x1C, + 0x1C, + 0x1C, + 0x1B, + 0x1B, + 0x1B, + 0x1B, + 0x1A, + 0x1A, + 0x1A, + 0x1A, + 0x19, + 0x19, + 0x19, + 0x19, + 0x18, + 0x18, + 0x18, + 0x18, + 0x18, + 0x17, + 0x17, + 0x17, + 0x17, + 0x16, + 0x16, + 0x16, + 0x16, + 0x16, + 0x15, + 0x15, + 0x15, + 0x15, + 0x15, + 0x14, + 0x14, + 0x14, + 0x14, + 0x14, + 0x13, + 0x13, + 0x13, + 0x13, + 0x13, + 0x13, + 0x12, + 0x12, + 0x12, + 0x12, + 0x12, + 0x11, + 0x11, + 0x11, + 0x11, + 0x11, + 0x11, + 0x10, + 0x10, + 0x10, + 0x10, + 0x10, + 0x10, + 0x0F, + 0x0F, + 0x0F, + 0x0F, + 0x0F, + 0x0F, + 0x0F, + 0x0E, + 0x0E, + 0x0E, + 0x0E, + 0x0E, + 0x0E, + 0x0E, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0D, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0C, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0B, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x0A, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x09, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x07, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x06, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x03, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x02, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, +}; + +const int32_t c_aiBandwidthAdjust48[MAX_BANDS_48] = { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 64, + 64, + 64, + 64, + 64, + 101, + 101, + 128, + 165, + 165, + 180, + 213, +}; + +const int32_t c_aiAbsoluteThresh48[MAX_BANDS_48] = { + -1787, + -1787, + -1787, + -1787, + -1787, + -1787, + -1787, + -1787, + -1782, + -1761, + -1737, + -1679, + -1638, + -1613, + -1590, + -1568, + -1516, + -1459, + -1395, + -1289, + -671, + -409, + -401, +}; + + +#if PERCEPTUAL_MODEL_SLGAIN_SHIFT == 4 +const int32_t c_aiDefaultTheta48[MAX_BANDS_48] = { + 7, + 7, + 6, + 5, + 5, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, +}; +#elif PERCEPTUAL_MODEL_SLGAIN_SHIFT == 8 +const int32_t c_aiDefaultTheta48[MAX_BANDS_48] = { + 112, + 112, + 96, + 80, + 80, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, + 64, +}; +#endif + +const int32_t c_aaiSpreadFunction48[MAX_BANDS_48 * MAX_BANDS_48] = { + 0, + -1561, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -289, + -4, + -1234, + -2295, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -569, + -229, + -8, + -905, + -1705, + -2324, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -789, + -445, + -173, + -16, + -656, + -1271, + -1765, + -2172, + -2520, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -961, + -616, + -340, + -136, + -28, + -488, + -976, + -1382, + -1729, + -2032, + -2305, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1088, + -743, + -465, + -257, + -148, + -31, + -371, + -769, + -1114, + -1417, + -1689, + -2054, + -2483, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1198, + -852, + -574, + -364, + -209, + -148, + -42, + -300, + -635, + -936, + -1207, + -1572, + -2000, + -2376, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1293, + -948, + -669, + -458, + -301, + -183, + -145, + -56, + -258, + -547, + -816, + -1179, + -1606, + -1982, + -2311, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1375, + -1029, + -750, + -539, + -381, + -260, + -180, + -142, + -68, + -231, + -487, + -846, + -1272, + -1647, + -1976, + -2261, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1444, + -1099, + -820, + -608, + -449, + -328, + -233, + -194, + -138, + -77, + -213, + -555, + -978, + -1352, + -1681, + -1966, + -2268, + -2552, + -2552, + -2552, + -2552, + -2552, + -2552, + -1501, + -1155, + -876, + -665, + -505, + -383, + -287, + -210, + -193, + -130, + -79, + -298, + -711, + -1083, + -1411, + -1696, + -1997, + -2288, + -2550, + -2552, + -2552, + -2552, + -2552, + -1567, + -1221, + -942, + -730, + -570, + -448, + -351, + -272, + -206, + -189, + -151, + -72, + -349, + -713, + -1039, + -1324, + -1625, + -1915, + -2177, + -2448, + -2552, + -2552, + -2552, + -1650, + -1304, + -1025, + -813, + -653, + -530, + -432, + -352, + -285, + -227, + -177, + -163, + -69, + -297, + -613, + -895, + -1195, + -1485, + -1746, + -2017, + -2238, + -2401, + -2545, + -1727, + -1381, + -1102, + -890, + -730, + -607, + -509, + -428, + -360, + -301, + -249, + -180, + -153, + -72, + -257, + -527, + -824, + -1112, + -1373, + -1643, + -1865, + -2028, + -2171, + -1798, + -1452, + -1173, + -960, + -800, + -677, + -579, + -498, + -430, + -370, + -317, + -246, + -192, + -145, + -76, + -224, + -505, + -790, + -1050, + -1320, + -1540, + -1703, + -1847, + -1860, + -1514, + -1234, + -1022, + -862, + -738, + -640, + -559, + -490, + -430, + -377, + -306, + -224, + -197, + -136, + -81, + -242, + -515, + -771, + -1040, + -1260, + -1422, + -1566, + -1923, + -1577, + -1297, + -1085, + -925, + -801, + -703, + -621, + -553, + -492, + -439, + -367, + -284, + -213, + -198, + -144, + -83, + -235, + -479, + -744, + -963, + -1125, + -1268, + -1986, + -1640, + -1360, + -1148, + -988, + -864, + -766, + -684, + -615, + -555, + -501, + -429, + -345, + -273, + -211, + -204, + -146, + -89, + -216, + -465, + -680, + -841, + -984, + -2043, + -1697, + -1417, + -1205, + -1044, + -921, + -822, + -741, + -672, + -611, + -557, + -485, + -401, + -328, + -264, + -211, + -205, + -140, + -93, + -227, + -430, + -588, + -729, + -2104, + -1758, + -1479, + -1266, + -1106, + -982, + -884, + -802, + -733, + -673, + -619, + -546, + -461, + -388, + -324, + -269, + -212, + -211, + -151, + -100, + -195, + -336, + -472, + -2163, + -1817, + -1537, + -1324, + -1164, + -1040, + -942, + -860, + -791, + -731, + -676, + -604, + -519, + -445, + -380, + -325, + -268, + -226, + -219, + -147, + -114, + -167, + -280, + -2203, + -1857, + -1577, + -1365, + -1205, + -1081, + -982, + -901, + -831, + -771, + -717, + -644, + -559, + -485, + -420, + -364, + -306, + -252, + -239, + -206, + -132, + -122, + -163, + -2224, + -1878, + -1598, + -1386, + -1225, + -1102, + -1003, + -921, + -852, + -792, + -737, + -665, + -580, + -505, + -441, + -385, + -326, + -271, + -222, + -224, + -176, + -121, + -114, +}; +#endif diff --git a/lib_rend/ivas_lcld_tables.h b/lib_rend/ivas_lcld_tables.h new file mode 100644 index 0000000000000000000000000000000000000000..b50edae637df4d9a9df0e596057f818a6f5db406 --- /dev/null +++ b/lib_rend/ivas_lcld_tables.h @@ -0,0 +1,567 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ +#ifndef _IVAS_TABLES_H_ +#define _IVAS_TABLES_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif +#include +#include // For NULL +#include "options.h" + +#ifndef M_PI + +#define M_PI 3.14159265358979323846264338327950288f + +#endif + +#define CQMF_BLOCKS_PER_FRAME ( 16 ) +#define CQMF_MAX_BLOCKS_PER_FRAME ( 16 ) +#define CQMF_BANDS ( 60 ) + +#define MAX_BANDS ( 23 ) +#define MAX_BANDS_48 ( 23 ) + + extern const int32_t c_aiBandwidths48[MAX_BANDS_48]; // move this + + +#define ENV_MIN ( -64 ) +#define ENV_MAX ( 64 ) + +#define ENV0_BITS ( 7 ) + +#define ENV_DELTA_MIN ( -32 ) +#define ENV_DELTA_MAX ( 31 ) + +#define ENV_RECONSTRUCT_TABLE_SIZE ( 129 ) + +#define ENV_RECONSTRUCT_TABLE_CENTER ( 64 ) + +#define MIN_ALLOC ( 0 ) +#define MAX_ALLOC ( 31 ) + +#define ALLOC_OFFSET_SCALE ( 8 ) + +#define ALLOC_OFFSET_BITS ( 8 ) + +#define MIN_ALLOC_OFFSET ( -128 ) +#define MAX_ALLOC_OFFSET ( 127 ) +#ifdef ROM_TO_RAM +#define READ_LENGTH ( 4 ) +#endif + +#define ALLOC_TABLE_SIZE ( 32 ) + +#ifndef _PI_ +#define _PI_ ( 3.14159265358979f ) +#endif +#define PRED_MAX_VAL ( 12 ) +#define PRED_MIN_VAL ( -PRED_MAX_VAL ) +#define PRED_QUANT_FACTOR ( (float) PRED_MAX_VAL ) +#define PRED_BAND0_BITS ( 5 ) + +#define PHASE_MAX_VAL ( 12 ) +#define PHASE_MIN_VAL ( -PHASE_MAX_VAL ) +#define PHASE_QUANT_FACTOR ( (float) PHASE_MAX_VAL / _PI_ ) +#define PHASE_DIFF_DIM ( 2 ) +#define PHASE_BAND0_BITS ( 5 ) + +#define SIMPLE_PHASE_MAX_VAL ( 3 ) +#define SIMPLE_PHASE_MIN_VAL ( 0 ) +#define SIMPLE_PHASE_BITS ( 2 ) +#define SIMPLE_PHASE_QUANT_FACTOR ( 2.0f / _PI_ ) + +#define TON_QUOTA_ABS_THRESHOLD ( 8.0f ) +#define TON_QUOTA_INC_THRESHOLD ( 4.0f ) + +#define MAX_BANDS_48 ( 23 ) + + //#define USE_DEMOD_TABLES + +#ifndef HUFF_READ_SIZE +#define HUFF_READ_SIZE ( 4 ) +#endif + +#ifndef HUFF_DEC_TABLE_SIZE +#define HUFF_DEC_TABLE_SIZE ( 16 ) +#endif + + extern const float c_afRotRealImag[PRED_MAX_VAL - PRED_MIN_VAL + 1][2]; + extern const float c_afRotRealImagSimple[SIMPLE_PHASE_MAX_VAL + 1][2]; + extern const int32_t c_aiDefaultTheta48[MAX_BANDS_48]; + + extern const float c_afScaleFactor[ALLOC_TABLE_SIZE]; + + extern const float c_afInvScaleFactor[ALLOC_TABLE_SIZE]; + + extern const float c_afRMSEnvReconstructTable[ENV_RECONSTRUCT_TABLE_SIZE]; + + extern const int32_t c_aiQuantMaxValues[ALLOC_TABLE_SIZE]; + + extern const int32_t c_aiHuffmanDim[ALLOC_TABLE_SIZE]; + + extern const int32_t c_aiHuffmanMod[ALLOC_TABLE_SIZE]; + + extern const int32_t c_aiHuffmanSize[ALLOC_TABLE_SIZE]; + +#ifndef ROM_TO_RAM + extern const uint32_t c_aauiCQMFHuffEnc1[16][2]; + + + extern const uint32_t c_aauiCQMFHuffDec1[3][16]; + + + extern const uint32_t c_aauiCQMFHuffEnc2[16][2]; + + + extern const uint32_t c_aauiCQMFHuffDec2[3][16]; + + extern const uint32_t c_aauiCQMFHuffEnc3[25][2]; + + + extern const uint32_t c_aauiCQMFHuffDec3[10][16]; + + extern const uint32_t c_aauiCQMFHuffEnc4[36][2]; + + + extern const uint32_t c_aauiCQMFHuffDec4[5][16]; + + extern const uint32_t c_aauiCQMFHuffEnc5[36][2]; + + + extern const uint32_t c_aauiCQMFHuffDec5[10][16]; + + extern const uint32_t c_aauiCQMFHuffEnc6[49][2]; + + + extern const uint32_t c_aauiCQMFHuffDec6[7][16]; + + extern const uint32_t c_aauiCQMFHuffEnc7[64][2]; + + + extern const uint32_t c_aauiCQMFHuffDec7[25][16]; + + extern const uint32_t c_aauiCQMFHuffEnc8[81][2]; + + + extern const uint32_t c_aauiCQMFHuffDec8[16][16]; + + extern const uint32_t c_aauiCQMFHuffEnc9[100][2]; + + + extern const uint32_t c_aauiCQMFHuffDec9[22][16]; + + extern const uint32_t c_aauiCQMFHuffEnc10[169][2]; + + + extern const uint32_t c_aauiCQMFHuffDec10[45][16]; + + extern const uint32_t c_aauiCQMFHuffEnc11[196][2]; + + + extern const uint32_t c_aauiCQMFHuffDec11[50][16]; + + extern const uint32_t c_aauiCQMFHuffEnc12[289][2]; + + + extern const uint32_t c_aauiCQMFHuffDec12[76][16]; + + extern const uint32_t c_aauiCQMFHuffEnc13[324][2]; + + + extern const uint32_t c_aauiCQMFHuffDec13[89][16]; + + extern const uint32_t c_aauiCQMFHuffEnc14[400][2]; + + + extern const uint32_t c_aauiCQMFHuffDec14[53][16]; + + extern const uint32_t c_aauiCQMFHuffEnc15[576][2]; + + + extern const uint32_t c_aauiCQMFHuffDec15[73][16]; + + extern const uint32_t c_aauiCQMFHuffEnc16[729][2]; + + + extern const uint32_t c_aauiCQMFHuffDec16[85][16]; + + extern const uint32_t c_aauiCQMFHuffEnc17[729][2]; + + + extern const uint32_t c_aauiCQMFHuffDec17[93][16]; + + extern const uint32_t c_aauiCQMFHuffEnc18[28][2]; + + + extern const uint32_t c_aauiCQMFHuffDec18[6][16]; + + extern const uint32_t c_aauiCQMFHuffEnc19[29][2]; + + + extern const uint32_t c_aauiCQMFHuffDec19[6][16]; + + extern const uint32_t c_aauiCQMFHuffEnc20[32][2]; + + + extern const uint32_t c_aauiCQMFHuffDec20[6][16]; + + extern const uint32_t c_aauiCQMFHuffEnc21[37][2]; + + + extern const uint32_t c_aauiCQMFHuffDec21[7][16]; + + extern const uint32_t c_aauiCQMFHuffEnc22[39][2]; + + + extern const uint32_t c_aauiCQMFHuffDec22[9][16]; + + extern const uint32_t c_aauiCQMFHuffEnc23[46][2]; + + + extern const uint32_t c_aauiCQMFHuffDec23[12][16]; + + extern const uint32_t c_aauiCQMFHuffEnc24[55][2]; + + + extern const uint32_t c_aauiCQMFHuffDec24[17][16]; + + extern const uint32_t c_aauiCQMFHuffEnc25[65][2]; + + + extern const uint32_t c_aauiCQMFHuffDec25[19][16]; + + extern const uint32_t c_aauiCQMFHuffEnc26[77][2]; + + + extern const uint32_t c_aauiCQMFHuffDec26[26][16]; + + extern const uint32_t c_aauiCQMFHuffEnc27[91][2]; + + + extern const uint32_t c_aauiCQMFHuffDec27[28][16]; + + extern const uint32_t c_aauiCQMFHuffEnc28[109][2]; + + + extern const uint32_t c_aauiCQMFHuffDec28[30][16]; + + extern const uint32_t c_aauiCQMFHuffEnc29[129][2]; + + + extern const uint32_t c_aauiCQMFHuffDec29[34][16]; + + extern const uint32_t c_aauiCQMFHuffEnc30[153][2]; + + + extern const uint32_t c_aauiCQMFHuffDec30[39][16]; + + extern const uint32_t c_aauiCQMFHuffEnc31[181][2]; + + + extern const uint32_t c_aauiCQMFHuffDec31[43][16]; + + extern const uint32_t c_aauiCQMFHuffEnc33[16][2]; + + + extern const uint32_t c_aauiCQMFHuffDec33[2][16]; + + extern const uint32_t c_aauiCQMFHuffEnc34[16][2]; + + + extern const uint32_t c_aauiCQMFHuffDec34[2][16]; + + extern const uint32_t c_aauiCQMFHuffEnc35[25][2]; + + + extern const uint32_t c_aauiCQMFHuffDec35[9][16]; + + extern const uint32_t c_aauiCQMFHuffEnc36[36][2]; + + + extern const uint32_t c_aauiCQMFHuffDec36[7][16]; + + extern const uint32_t c_aauiCQMFHuffEnc37[36][2]; + + + extern const uint32_t c_aauiCQMFHuffDec37[4][16]; + + extern const uint32_t c_aauiCQMFHuffEnc38[49][2]; + + + extern const uint32_t c_aauiCQMFHuffDec38[22][16]; + + extern const uint32_t c_aauiCQMFHuffEnc39[64][2]; + + + extern const uint32_t c_aauiCQMFHuffDec39[12][16]; + + extern const uint32_t c_aauiCQMFHuffEnc40[81][2]; + + + extern const uint32_t c_aauiCQMFHuffDec40[36][16]; + + extern const uint32_t c_aauiCQMFHuffEnc41[100][2]; + + + extern const uint32_t c_aauiCQMFHuffDec41[16][16]; + + extern const uint32_t c_aauiCQMFHuffEnc42[169][2]; + + + extern const uint32_t c_aauiCQMFHuffDec42[28][16]; + + extern const uint32_t c_aauiCQMFHuffEnc43[196][2]; + + + extern const uint32_t c_aauiCQMFHuffDec43[32][16]; + + extern const uint32_t c_aauiCQMFHuffEnc44[289][2]; + + + extern const uint32_t c_aauiCQMFHuffDec44[27][16]; + + extern const uint32_t c_aauiCQMFHuffEnc45[324][2]; + + + extern const uint32_t c_aauiCQMFHuffDec45[50][16]; + + extern const uint32_t c_aauiCQMFHuffEnc46[400][2]; + + + extern const uint32_t c_aauiCQMFHuffDec46[61][16]; + + extern const uint32_t c_aauiCQMFHuffEnc47[576][2]; + + + extern const uint32_t c_aauiCQMFHuffDec47[87][16]; + + extern const uint32_t c_aauiCQMFHuffEnc48[729][2]; + + + extern const uint32_t c_aauiCQMFHuffDec48[110][16]; + + extern const uint32_t c_aauiCQMFHuffEnc49[729][2]; + + + extern const uint32_t c_aauiCQMFHuffDec49[113][16]; + + extern const uint32_t c_aauiCQMFHuffEnc50[28][2]; + + + extern const uint32_t c_aauiCQMFHuffDec50[6][16]; + + extern const uint32_t c_aauiCQMFHuffEnc51[29][2]; + + + extern const uint32_t c_aauiCQMFHuffDec51[6][16]; + + extern const uint32_t c_aauiCQMFHuffEnc52[32][2]; + + + extern const uint32_t c_aauiCQMFHuffDec52[7][16]; + + extern const uint32_t c_aauiCQMFHuffEnc53[37][2]; + + + extern const uint32_t c_aauiCQMFHuffDec53[9][16]; + + extern const uint32_t c_aauiCQMFHuffEnc54[39][2]; + + + extern const uint32_t c_aauiCQMFHuffDec54[9][16]; + + extern const uint32_t c_aauiCQMFHuffEnc55[46][2]; + + + extern const uint32_t c_aauiCQMFHuffDec55[10][16]; + + extern const uint32_t c_aauiCQMFHuffEnc56[55][2]; + + + extern const uint32_t c_aauiCQMFHuffDec56[12][16]; + + extern const uint32_t c_aauiCQMFHuffEnc57[65][2]; + + + extern const uint32_t c_aauiCQMFHuffDec57[14][16]; + + extern const uint32_t c_aauiCQMFHuffEnc58[77][2]; + + + extern const uint32_t c_aauiCQMFHuffDec58[17][16]; + + extern const uint32_t c_aauiCQMFHuffEnc59[91][2]; + + + extern const uint32_t c_aauiCQMFHuffDec59[20][16]; + + extern const uint32_t c_aauiCQMFHuffEnc60[109][2]; + + + extern const uint32_t c_aauiCQMFHuffDec60[24][16]; + + extern const uint32_t c_aauiCQMFHuffEnc61[129][2]; + + + extern const uint32_t c_aauiCQMFHuffDec61[33][16]; + + extern const uint32_t c_aauiCQMFHuffEnc62[153][2]; + + + extern const uint32_t c_aauiCQMFHuffDec62[41][16]; + + extern const uint32_t c_aauiCQMFHuffEnc63[181][2]; + + + extern const uint32_t c_aauiCQMFHuffDec63[39][16]; + + + extern const uint32_t ( *c_apauiHuffEncTabels[2 * ALLOC_TABLE_SIZE] )[2]; + + extern const uint32_t ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE]; +#else +extern const uint16_t c_aauiCQMFHuffEnc1[16][2]; +extern const uint16_t c_aauiCQMFHuffEnc2[16][2]; +extern const uint16_t c_aauiCQMFHuffEnc3[25][2]; +extern const uint16_t c_aauiCQMFHuffEnc4[36][2]; +extern const uint16_t c_aauiCQMFHuffEnc5[36][2]; +extern const uint16_t c_aauiCQMFHuffEnc6[49][2]; +extern const uint16_t c_aauiCQMFHuffEnc7[64][2]; +extern const uint16_t c_aauiCQMFHuffEnc8[81][2]; +extern const uint16_t c_aauiCQMFHuffEnc9[100][2]; +extern const uint16_t c_aauiCQMFHuffEnc10[169][2]; +extern const uint16_t c_aauiCQMFHuffEnc11[196][2]; +extern const uint16_t c_aauiCQMFHuffEnc12[289][2]; +extern const uint16_t c_aauiCQMFHuffEnc13[324][2]; +extern const uint16_t c_aauiCQMFHuffEnc14[400][2]; +extern const uint16_t c_aauiCQMFHuffEnc15[576][2]; +extern const uint16_t c_aauiCQMFHuffEnc16[729][2]; +extern const uint16_t c_aauiCQMFHuffEnc17[729][2]; +extern const uint16_t c_aauiCQMFHuffEnc18[28][2]; +extern const uint16_t c_aauiCQMFHuffEnc19[29][2]; +extern const uint16_t c_aauiCQMFHuffEnc20[32][2]; +extern const uint16_t c_aauiCQMFHuffEnc21[37][2]; +extern const uint16_t c_aauiCQMFHuffEnc22[39][2]; +extern const uint16_t c_aauiCQMFHuffEnc23[46][2]; +extern const uint16_t c_aauiCQMFHuffEnc24[55][2]; +extern const uint16_t c_aauiCQMFHuffEnc25[65][2]; +extern const uint16_t c_aauiCQMFHuffEnc26[77][2]; +extern const uint16_t c_aauiCQMFHuffEnc27[91][2]; +extern const uint16_t c_aauiCQMFHuffEnc28[109][2]; +extern const uint16_t c_aauiCQMFHuffEnc29[129][2]; +extern const uint16_t c_aauiCQMFHuffEnc30[153][2]; +extern const uint16_t c_aauiCQMFHuffEnc31[181][2]; +extern const uint16_t c_aauiCQMFHuffEnc33[16][2]; +extern const uint16_t c_aauiCQMFHuffEnc34[16][2]; +extern const uint16_t c_aauiCQMFHuffEnc35[25][2]; +extern const uint16_t c_aauiCQMFHuffEnc36[36][2]; +extern const uint16_t c_aauiCQMFHuffEnc37[36][2]; +extern const uint16_t c_aauiCQMFHuffEnc38[49][2]; +extern const uint16_t c_aauiCQMFHuffEnc39[64][2]; +extern const uint16_t c_aauiCQMFHuffEnc40[81][2]; +extern const uint16_t c_aauiCQMFHuffEnc41[100][2]; +extern const uint16_t c_aauiCQMFHuffEnc42[169][2]; +extern const uint16_t c_aauiCQMFHuffEnc43[196][2]; +extern const uint16_t c_aauiCQMFHuffEnc44[289][2]; +extern const uint16_t c_aauiCQMFHuffEnc45[324][2]; +extern const uint16_t c_aauiCQMFHuffEnc46[400][2]; +extern const uint16_t c_aauiCQMFHuffEnc47[576][2]; +extern const uint16_t c_aauiCQMFHuffEnc48[729][2]; +extern const uint16_t c_aauiCQMFHuffEnc49[729][2]; +extern const uint16_t c_aauiCQMFHuffEnc50[28][2]; +extern const uint16_t c_aauiCQMFHuffEnc51[29][2]; +extern const uint16_t c_aauiCQMFHuffEnc52[32][2]; +extern const uint16_t c_aauiCQMFHuffEnc53[37][2]; +extern const uint16_t c_aauiCQMFHuffEnc54[39][2]; +extern const uint16_t c_aauiCQMFHuffEnc55[46][2]; +extern const uint16_t c_aauiCQMFHuffEnc56[55][2]; +extern const uint16_t c_aauiCQMFHuffEnc57[65][2]; +extern const uint16_t c_aauiCQMFHuffEnc58[77][2]; +extern const uint16_t c_aauiCQMFHuffEnc59[91][2]; +extern const uint16_t c_aauiCQMFHuffEnc60[109][2]; +extern const uint16_t c_aauiCQMFHuffEnc61[129][2]; +extern const uint16_t c_aauiCQMFHuffEnc62[153][2]; +extern const uint16_t c_aauiCQMFHuffEnc63[181][2]; +extern const uint16_t ( *c_apauiHuffEncTabels[2 * ALLOC_TABLE_SIZE] )[2]; +extern const uint32_t num_row_aauiCQMFHuff[2 * ALLOC_TABLE_SIZE]; +#endif + +#ifdef USE_DEMOD_TABLES + extern const int32_t c_aaiHuffDemod1[16][2]; + + extern const int32_t c_aaiHuffDemod2[16][2]; + + extern const int32_t c_aaiHuffDemod3[25][2]; + + extern const int32_t c_aaiHuffDemod4[36][2]; + + extern const int32_t c_aaiHuffDemod5[36][2]; + + extern const int32_t c_aaiHuffDemod6[49][2]; + + extern const int32_t c_aaiHuffDemod7[64][2]; + + extern const int32_t c_aaiHuffDemod8[81][2]; + + extern const int32_t c_aaiHuffDemod9[100][2]; + + extern const int32_t c_aaiHuffDemod10[169][2]; + + extern const int32_t c_aaiHuffDemod11[196][2]; + + extern const int32_t c_aaiHuffDemod12[289][2]; + + extern const int32_t c_aaiHuffDemod13[324][2]; + + extern const int32_t c_aaiHuffDemod14[400][2]; + + extern const int32_t c_aaiHuffDemod15[576][2]; + + extern const int32_t c_aaiHuffDemod16[729][2]; + + extern const int32_t c_aaiHuffDemod17[729][2]; + + extern const int32_t ( *c_apaiDemodTables[ALLOC_TABLE_SIZE] )[2]; +#endif + + extern const uint32_t c_aaiRMSEnvHuffEnc[64][2]; + + extern const uint32_t c_aaiRMSEnvHuffDec[13][HUFF_DEC_TABLE_SIZE]; + +#ifdef __cplusplus +} +#endif + +#endif /* _TABLES_H_ */ diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 2ba225b2f15723187a77c6c8ca5404f7526e366b..ef68bb71129cea6a07d429db1809da9ac1007f29 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -36,6 +36,9 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" +#ifdef SPLIT_REND_LC3PLUS +#include "ivas_prot.h" +#endif #include #include "ivas_rom_com.h" #ifdef DEBUGGING @@ -589,8 +592,22 @@ ivas_error ivas_td_binaural_open_ext( transport_config = getIvasAudioConfigFromRendAudioConfig( inConfig ); ivas_format = ( getAudioConfigType( inConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) ? MC_FORMAT : ISM_FORMAT; + +#ifdef SPLIT_REND_WITH_HEAD_ROT + hTransSetup.ls_azimuth = NULL; + hTransSetup.ls_elevation = NULL; +#endif +#ifdef TD_TDREND_FIX_NULLPTR_ACCESS + if ( inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) + { + hTransSetup.ls_azimuth = customLsInput->ls_azimuth; + hTransSetup.ls_elevation = customLsInput->ls_elevation; + } +#else hTransSetup.ls_azimuth = customLsInput->ls_azimuth; hTransSetup.ls_elevation = customLsInput->ls_elevation; +#endif /* TD_TDREND_FIX_NULLPTR_ACCESS */ + if ( NULL != hRendCfg ) { @@ -688,6 +705,156 @@ ivas_error ivas_td_binaural_renderer_ext( return IVAS_ERR_OK; } +#ifdef SPLIT_REND_LC3PLUS +/*---------------------------------------------------------------------* + * ObjRenderIvasFrame_splitBinaural() + * + * Render to multiple binaural pairs based on relative head positions for split rendering. + *---------------------------------------------------------------------*/ +void ObjRenderIvasFrame_splitBinaural( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float output[][L_FRAME48k], /* i/o: SCE channels / Binaural synthesis */ + const int16_t output_frame /* i : output frame length */ +) +{ + int32_t i; +#ifdef SPLIT_REND_LC3PLUS_MC + float tmpProcessing[MAX_OUTPUT_CHANNELS][L_FRAME48k]; +#else + float tmpProcessing[MAX_NUM_OBJECTS][L_FRAME48k]; +#endif + float tmpBinaural[MAX_HEAD_ROT_POSES * 2][L_FRAME48k]; +#ifdef SPLIT_REND_LC3PLUS_MC + float *p_tmpProcessing[MAX_OUTPUT_CHANNELS]; +#else + float *p_tmpProcessing[MAX_NUM_OBJECTS]; +#endif + + int16_t pos_idx; + IVAS_QUATERNION originalHeadRot[MAX_PARAM_SPATIAL_SUBFRAMES]; + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; + BINAURAL_TD_OBJECT_RENDERER_HANDLE tmpTdRendHandle; + + push_wmops( "ObjRenderIvasFrame_splitBinaural" ); + + pMultiBinPoseData = &st_ivas->splitBinRend.splitrend.multiBinPoseData; + + /* If not yet allocated, open additional instances of TD renderer */ + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + if ( st_ivas->splitBinRend.splitrend.hTdRendHandles[i] != NULL ) + { + continue; + } + + ivas_td_binaural_open_unwrap( &st_ivas->hHrtfTD, + st_ivas->hDecoderConfig->output_Fs, + st_ivas->nchan_transport, + st_ivas->ivas_format, + st_ivas->transport_config, + st_ivas->hRenderConfig->directivity, + st_ivas->hTransSetup, + &st_ivas->splitBinRend.splitrend.hTdRendHandles[i], + &st_ivas->binaural_latency_ns ); + } + + /* Save current head positions */ + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; ++i ) + { + originalHeadRot[i] = st_ivas->hCombinedOrientationData->Quaternions[i]; + } + + /* Copy input audio to a processing buffer. Cannot render in-place because binaurally rendered + * audio would overwrite original material, which is still needed for rendering next head pose. */ +#ifdef SPLIT_REND_LC3PLUS_MC + for ( i = 0; i < st_ivas->nchan_transport; ++i ) +#else + for ( i = 0; i < MAX_NUM_OBJECTS; ++i ) +#endif + { + mvr2r( output[i], tmpProcessing[i], output_frame ); + } + + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + /* Update head positions */ + if ( pos_idx != 0 ) + { + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; ++i ) + { + if ( originalHeadRot[i].w == -3.0f ) + { + st_ivas->hCombinedOrientationData->Quaternions[i].w = -3.0f; + st_ivas->hCombinedOrientationData->Quaternions[i].x = originalHeadRot[i].x + pMultiBinPoseData->relative_head_poses[pos_idx][0]; + st_ivas->hCombinedOrientationData->Quaternions[i].y = originalHeadRot[i].y + pMultiBinPoseData->relative_head_poses[pos_idx][1]; + st_ivas->hCombinedOrientationData->Quaternions[i].z = originalHeadRot[i].z + pMultiBinPoseData->relative_head_poses[pos_idx][2]; + } + else + { + st_ivas->hCombinedOrientationData->Quaternions[i].w = -3.0f; + Quat2EulerDegree( originalHeadRot[i], /* TODO tmu : fix bug with ordering*/ + &st_ivas->hCombinedOrientationData->Quaternions[i].z, + &st_ivas->hCombinedOrientationData->Quaternions[i].y, + &st_ivas->hCombinedOrientationData->Quaternions[i].x ); + st_ivas->hCombinedOrientationData->Quaternions[i].x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; + st_ivas->hCombinedOrientationData->Quaternions[i].y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; + st_ivas->hCombinedOrientationData->Quaternions[i].z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; + } + } + } +#ifdef SPLIT_REND_LC3PLUS_MC + for ( i = 0; i < st_ivas->nchan_transport; ++i ) +#else + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) +#endif + { + p_tmpProcessing[i] = tmpProcessing[i]; + } + /* Render */ + if ( pos_idx == 0 ) + { + ivas_td_binaural_renderer( st_ivas, + p_tmpProcessing, + output_frame ); + } + else + { + /* Tmp swap renderer handles for rendering call */ + tmpTdRendHandle = st_ivas->hBinRendererTd; + st_ivas->hBinRendererTd = st_ivas->splitBinRend.splitrend.hTdRendHandles[pos_idx - 1]; + ivas_td_binaural_renderer( st_ivas, + p_tmpProcessing, + output_frame ); + st_ivas->hBinRendererTd = tmpTdRendHandle; + } + + /* Copy rendered audio to tmp storage buffer. Copying directly to output would + * overwrite original audio, which is still needed for rendering next head pose. */ + mvr2r( tmpProcessing[0], tmpBinaural[2 * pos_idx], output_frame ); + mvr2r( tmpProcessing[1], tmpBinaural[2 * pos_idx + 1], output_frame ); + + /* Overwrite first 2 channels with original input audio again */ + mvr2r( output[0], tmpProcessing[0], output_frame ); + mvr2r( output[1], tmpProcessing[1], output_frame ); + } + + /* Copy from storage buffer to output */ + for ( i = 0; i < pMultiBinPoseData->num_poses * BINAURAL_CHANNELS; ++i ) + { + mvr2r( tmpBinaural[i], output[i], output_frame ); + } + + /* Restore original head rotation */ + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; ++i ) + { + st_ivas->hCombinedOrientationData->Quaternions[i] = originalHeadRot[i]; + } + + pop_wmops(); +} +#endif + + /*---------------------------------------------------------------------* * angles_to_vec() * diff --git a/lib_rend/ivas_objectRenderer_sfx.c b/lib_rend/ivas_objectRenderer_sfx.c index 679887b3ecfdc233aa5c554141b9af9bd475897e..74d387b41d4b7519c61498a0d080610483fcb523 100644 --- a/lib_rend/ivas_objectRenderer_sfx.c +++ b/lib_rend/ivas_objectRenderer_sfx.c @@ -182,6 +182,14 @@ static void sincResample( const float *p_sinc_forward; const float *p_sinc_backward; +#ifdef TD_REND_FIX_DIV_BY_ZERO + /* avoid division by 0 */ + if ( 0 == length_out ) + { + return; + } +#endif /* TD_REND_FIX_DIV_BY_ZERO */ + /* Compute fractional time step */ t_step = (float) ( length_in ) / (float) ( length_out ); diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 4e1479faf89f1a6666fbd1ea1d2d420128c87d47..d6a873d26d4fb80f86f8b93af510d7512202b638 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -91,8 +91,13 @@ int16_t audioCfg2channels( nchan_out = 8; break; case AUDIO_CONFIG_BINAURAL: +#ifdef SPLIT_REND_WITH_HEAD_ROT + case AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB: + case AUDIO_CONFIG_BINAURAL_SPLIT_PCM: +#endif case AUDIO_CONFIG_BINAURAL_ROOM_IR: case AUDIO_CONFIG_BINAURAL_ROOM_REVERB: + nchan_out = 2; break; case AUDIO_CONFIG_ISM1: @@ -218,6 +223,10 @@ void ivas_output_init( hOutSetup->is_planar_setup = 0; break; case AUDIO_CONFIG_BINAURAL: +#ifdef SPLIT_REND_WITH_HEAD_ROT + case AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB: + case AUDIO_CONFIG_BINAURAL_SPLIT_PCM: +#endif case AUDIO_CONFIG_BINAURAL_ROOM_IR: case AUDIO_CONFIG_BINAURAL_ROOM_REVERB: case AUDIO_CONFIG_ISM1: diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 803a612502e88c4edc139db1c8c7dbf2bd704748..123d147ac424bd6857c93d2b225aeae6c0b29d8b 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -229,6 +229,15 @@ void ivas_HRTF_CRend_binary_close( * TD object renderer *----------------------------------------------------------------------------------*/ +#ifdef SPLIT_REND_LC3PLUS +/* TODO(sgi): Rework interface */ +void ObjRenderIvasFrame_splitBinaural( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float output[][L_FRAME48k], /* i/o: SCE channels / Binaural synthesis */ + const int16_t output_frame /* i : output frame length */ +); +#endif + ivas_error ivas_td_binaural_renderer_unwrap( const REVERB_HANDLE hReverb, /* i : Reverberator handle */ const AUDIO_CONFIG transport_config, /* i : Transport configuration */ @@ -496,15 +505,107 @@ ivas_error ivas_rend_openCrend( RENDER_CONFIG_DATA *hRendCfg, HRTFS_CREND_HANDLE hSetOfHRTF, const int32_t output_Fs +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + const int16_t num_poses +#endif ); void ivas_rend_closeCrend( - CREND_WRAPPER_HANDLE *pCrend ); + CREND_WRAPPER_HANDLE *pCrend +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + const int16_t num_poses +#endif +); ivas_error ivas_rend_initCrendWrapper( - CREND_WRAPPER_HANDLE *pCrend + CREND_WRAPPER_HANDLE *pCrend +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + const int16_t num_poses +#endif ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +ivas_error ivas_rend_openMultiBinCrend( + CREND_WRAPPER_HANDLE *pCrend, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int32_t output_Fs ); +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT +void ivas_rend_CldfbMultiBinRendProcess( + const BINAURAL_RENDERER_HANDLE hCldfbRend, + const COMBINED_ORIENTATION_HANDLE *pCombinedOrientationData, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_Out_Real[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ + float Cldfb_Out_Imag[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t low_res_pre_rend_rot ); + +ivas_error ivas_rend_openCldfb( + HANDLE_CLDFB_FILTER_BANK cldfbAna[MAX_INPUT_CHANNELS], + const IVAS_REND_AudioConfig inConfig, + const int32_t output_Fs ); +ivas_error ivas_rend_openCldfbRend( + CLDFB_REND_WRAPPER *pCldfbRend, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, +#ifdef SPLIT_REND_WITH_HEAD_ROT + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, +#endif + const int32_t output_Fs ); + +void ivas_mat_mult_2by2_complex( float in_re1[2][2], + float in_im1[2][2], + float in_re2[2][2], + float in_im2[2][2], + float out_re2[2][2], + float out_im2[2][2] ); +void ivas_split_rend_bitstream_init( ivas_split_rend_bits_t *pBits, const int32_t buf_len_bytes, uint8_t *pbuf ); +void ivas_split_rend_huffman_dec_init_min_max_len( ivas_split_rend_huffman_cfg_t *p_huff_cfg ); +void ivas_split_rend_init_huff_cfg( BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg ); +void set_fix_rotation_mat( float fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); +void set_pose_types( IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); +int16_t wrap_a( int16_t val, int16_t min_val, int16_t max_val ); +void ivas_SplitRenderer_getdiagdiff( + int16_t in_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + int16_t out_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + const int16_t sign, + const int16_t min_val, + const int16_t max_val ); +void ivas_split_rend_bitstream_write_int32( ivas_split_rend_bits_t *pBits, int32_t val, int32_t bits ); +int32_t ivas_split_rend_bitstream_read_int32( ivas_split_rend_bits_t *pBits, int32_t bits ); +IVAS_QUATERNION ivas_split_rend_get_sf_rot_data( + const IVAS_QUATERNION headPositions[RENDERER_HEAD_POSITIONS_PER_FRAME], + int16_t subframe_idx ); + +void ivas_rend_closeCldfbRend( CLDFB_REND_WRAPPER *pCldfbRend ); +int32_t ivas_get_lcld_bitrate( const int32_t SplitRendBitRate ); +int32_t ivas_get_split_rend_md_target_brate( const int32_t SplitRendBitRate, const int16_t pcm_out ); +#ifdef SPLIT_REND_LC3PLUS +int32_t ivas_get_lc3plus_bitrate( const int32_t SplitRendBitRate, IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode ); +int8_t ivas_get_lc3plus_bitrate_id( const int32_t SplitRendBitRate ); +int32_t ivas_get_lc3plus_size_from_id( const int8_t SplitRendBitRateId, IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode ); +ivas_error ivas_split_rend_validate_config( const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig ); +#endif +void ivas_split_rend_get_quant_params( + const int16_t num_md_bands, + int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t *num_quant_strats, + int16_t *num_complex_bands ); +#endif + ivas_error ivas_rend_crendProcess( const CREND_WRAPPER *pCrend, const AUDIO_CONFIG inConfig, @@ -513,8 +614,12 @@ ivas_error ivas_rend_crendProcess( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, IVAS_OUTPUT_SETUP_HANDLE hIntSetup, EFAP_HANDLE hEFAPdata, - float *output[], /* i/o: input/output audio channels */ - const int32_t output_Fs + float *output[], /* i/o: input/output audio channels */ + const int32_t output_Fs +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + const int16_t pos_idx +#endif ); ivas_error ivas_rend_crendProcessSubframe( @@ -532,6 +637,15 @@ ivas_error ivas_rend_crendProcessSubframe( const int32_t output_Fs /* i : output sampling rate */ ); +#ifdef SPLIT_REND_LC3PLUS_MC +/* TODO tmu : interface cleanup */ +ivas_error ivas_rend_crendProcessSplitBin( + Decoder_Struct *st_ivas, + float output[][L_FRAME48k], + const int16_t output_frame +); +#endif + /*----------------------------------------------------------------------------------* * Reverberator *----------------------------------------------------------------------------------*/ @@ -785,6 +899,15 @@ void QuatToRotMat( float Rmat[3][3] /* o : real-space rotation matrix for this rotation */ ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +void Quat2EulerDegree( + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ + float *yaw, /* o : yaw */ + float *pitch, /* o : pitch */ + float *roll /* o : roll */ +); +#endif + void rotateAziEle( float azi_in, /* i : output elevation */ float ele_in, /* i : input elevation */ @@ -945,6 +1068,206 @@ ivas_error ivas_orient_trk_Process( IVAS_QUATERNION *pTrkRot /* o : tracked rotation */ ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + +/*----------------------------------------------------------------------------------* + * Split renderer prototypes + *----------------------------------------------------------------------------------*/ + +void ivas_set_split_rend_setup( + IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, + IVAS_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientation handle */ + IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits ); + +void ivas_init_split_rend_handles( + SPLIT_REND_WRAPPER *hSplitRendWrapper ); +void ivas_init_split_post_rend_handles( + SPLIT_POST_REND_WRAPPER *hSplitRendWrapper ); + +ivas_error ivas_split_renderer_open( SPLIT_REND_WRAPPER *hSplitBinRend, + const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const int32_t output_Fs, + const int16_t is_cldfb_in, + const int16_t is_pcm_out); + +void ivas_split_renderer_close( + SPLIT_REND_WRAPPER *hSplitBinRend); + +ivas_error ivas_splitBinLCLDEncOpen( + BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, + int32_t iSampleRate, + int32_t iChannels, + int32_t iDataRate ); + +void ivas_splitBinLCLDEncClose( + BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc ); + +void ivas_splitBinLCLDEncProcess( + BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc, + float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int32_t available_bits, + ivas_split_rend_bits_t *pBits ); + +ivas_error ivas_splitBinLCLDDecOpen( + BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, + int32_t iSampleRate, + int32_t iChannels ); + +void ivas_splitBinLCLDDecClose( + BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec ); + +void ivas_splitBinLCLDDecProcess( + BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec, + ivas_split_rend_bits_t *pBits, + float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] +#ifdef SPLIT_REND_PLC + , + const int16_t bfi +#endif +); + +ivas_error ivas_splitBinPreRendOpen( + BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + , + const int32_t output_Fs +#endif +); + +ivas_error ivas_splitBinPostRendOpen( + BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int32_t output_Fs +#ifndef SPLIT_REND_LC3PLUS + ,const int16_t is_cldfb_in +#endif +); + + +void ivas_init_multi_bin_pose_data( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); +void ivas_renderSplitGetMultiBinPoseData( + const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const IVAS_SPLIT_REND_ROT_AXIS rot_axis); + +#ifdef SPLIT_REND_LC3PLUS +void ivas_renderSplitUpdateNoCorrectionPoseData( + const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); +#endif + +ivas_error ivas_renderMultiBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, + const IVAS_QUATERNION headPositions[MAX_PARAM_SPATIAL_SUBFRAMES], + const int32_t SplitRendBitRate, +#ifdef SPLIT_REND_LC3PLUS + const IVAS_SPLIT_REND_CODEC splitCodec, +#endif + ivas_split_rend_bits_t *pBits, + float Cldfb_In_BinReal[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_BinImag[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t max_bands, + float out[][L_FRAME48k], + const int16_t low_res_pre_rend_rot, +#ifdef SPLIT_REND_LC3PLUS + int16_t td_input, +#endif + const int16_t pcm_out +); + +void ivas_rend_CldfbSplitPreRendProcess( + const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, + const IVAS_QUATERNION headPositions[MAX_PARAM_SPATIAL_SUBFRAMES], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + float Cldfb_In_BinReal[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_BinImag[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + ivas_split_rend_bits_t *pBits, + const int32_t target_md_bits, + const int16_t low_res_pre_rend_rot); + +void ivas_rend_CldfbSplitPostRendProcess( + BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES], + float Cldfb_RealBuffer_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float output[][L_FRAME48k], + const int16_t is_cldfb_in ); + +void ivas_splitBinPreRendClose( + BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend ); + +void ivas_splitBinPostRendClose( + BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend ); + +void ivas_splitBinPostRendMdDec( + ivas_split_rend_bits_t *pBits, + BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + ,BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend +#endif +); + +#ifdef SPLIT_REND_PLC +ivas_error ivas_splitBinRendPLCOpen( + SPLIT_REND_PLC_HANDLE* phSplitRendPLC +); + +void ivas_splitBinRendPLCClose(SPLIT_REND_PLC_HANDLE* phSplitRendPLC); + +void ivas_splitBinRendPLCsaveState( + SPLIT_REND_PLC_HANDLE hSplitRendPLC, + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t num_chs ); + +void ivas_splitBinRendPLC_xf( + SPLIT_REND_PLC_HANDLE hSplitRendPLC, + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t num_chs ); + +void ivas_splitBinRendPLC( + SPLIT_REND_PLC_HANDLE hSplitRendPLC, + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t num_chs ); +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +void ivas_log_cldfb2wav_data( + float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + HANDLE_CLDFB_FILTER_BANK *cldfbSyn, + const int16_t num_chs, + const int16_t num_freq_bands, + const int32_t output_Fs, + const int16_t start_slot_idx, + const int16_t md_band_idx, + const char *filename ); +#endif + +void ivas_SplitRenderer_GetRotMd( + BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + float Cldfb_RealBuffer_Ref_Binaural[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ + float Cldfb_ImagBuffer_Ref_Binaural[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ + int16_t low_res); + +void ivas_SplitRenderer_PostRenderer( + BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ + float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ + const IVAS_QUATERNION Quaternions_act[MAX_PARAM_SPATIAL_SUBFRAMES]); + +#endif /*----------------------------------------------------------------------------------* * Rendering & merging to MASA format *----------------------------------------------------------------------------------*/ @@ -1053,7 +1376,6 @@ void masaPrerendClose( MASA_PREREND_HANDLE *hMasaPrerendPtr /* i/o: prerenderer handle to be closed */ ); - /* clang-format on */ #endif /* IVAS_PROT_REND_H */ diff --git a/lib_rend/ivas_render_config.c b/lib_rend/ivas_render_config.c index 7dfc4b7c4b0f3d7b48ed15df54d28199ad5f35b4..99923860dd576aebd8e44a29fa994b36796621c9 100644 --- a/lib_rend/ivas_render_config.c +++ b/lib_rend/ivas_render_config.c @@ -107,7 +107,7 @@ ivas_error ivas_render_config_init_from_rom( return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "Unexpected null pointer while attempting to fill renderer configuration from ROM" ); } -#ifdef DEBUGGING +#if ( defined DEBUGGING ) || ( defined SPLIT_REND_WITH_HEAD_ROT ) ( *hRenderConfig )->renderer_type_override = RENDER_TYPE_OVERRIDE_NONE; #endif ( *hRenderConfig )->roomAcoustics.override = FALSE; @@ -125,6 +125,16 @@ ivas_error ivas_render_config_init_from_rom( ( *hRenderConfig )->directivity[0] = 360.0f; /* Front cone */ ( *hRenderConfig )->directivity[1] = 360.0f; /* Back cone */ ( *hRenderConfig )->directivity[2] = 1.0f; /* Back attenuation */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( *hRenderConfig )->split_rend_config.splitRendBitRate = SPLIT_REND_768k; + ( *hRenderConfig )->split_rend_config.dof = 3; + ( *hRenderConfig )->split_rend_config.hq_mode = 0; + ( *hRenderConfig )->split_rend_config.codec_delay_ms = 0; +#endif +#ifdef SPLIT_REND_LC3PLUS + ( *hRenderConfig )->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_LCLD; + ( *hRenderConfig )->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; +#endif return IVAS_ERR_OK; } diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index 6374b6812e98f6d53829eb3a6566dcfaf28c14e9..35dc1c220fb637646fe3f74d467808035fc7bc03 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -1607,9 +1607,8 @@ ivas_error ivas_reverb_process( return IVAS_ERR_OK; } - /*------------------------------------------------------------------------- - * ivas_binaural_reverb_processFrame() + * ivas_binaural_reverb_processSubFrame() * * Compute the reverberation - room effect *------------------------------------------------------------------------*/ @@ -1768,7 +1767,6 @@ void ivas_binaural_reverb_processSubframe( return; } - /*------------------------------------------------------------------------- * ivas_binaural_reverb_open() * diff --git a/lib_rend/ivas_rom_rend.h b/lib_rend/ivas_rom_rend.h index c4e1ca153378923382ba84c162635b4b10d3bd17..ae1bb654e64068c6b8835bd87a669f5f7e149948 100644 --- a/lib_rend/ivas_rom_rend.h +++ b/lib_rend/ivas_rom_rend.h @@ -119,4 +119,8 @@ extern const float ls_conversion_cicpX_stereo[12][2]; /* Mapping table of input config : output config with corresponding matrix */ extern const LS_CONVERSION_MAPPING ls_conversion_mapping[]; +#ifdef SPLIT_REND_WITH_HEAD_ROT +extern const int32_t split_rend_brate_tbl[]; +#endif + #endif /* IVAS_ROM_REND_H */ diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 2cd2744b5ab8e04baa373b461073442f2d21e6b5..01d6b68420f9eec1e20a64ab53275a8d8c5c7235 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -48,7 +48,13 @@ * Local funtion declarations *-----------------------------------------------------------------------*/ -static ivas_error combine_external_and_head_orientations( IVAS_QUATERNION *headRotQuaternions, IVAS_VECTOR3 *listenerPos, int16_t numHeadRotQuaternions, EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData ); +static ivas_error combine_external_and_head_orientations( IVAS_QUATERNION *headRotQuaternions, IVAS_VECTOR3 *listenerPos, +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis*/ +#endif + int16_t numHeadRotQuaternions, + EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData ); static void external_target_interpolation( EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, const int16_t i ); @@ -95,6 +101,9 @@ ivas_error ivas_headTrack_open( set_zero( ( *hHeadTrackData )->Rmat_prev[i], 3 ); ( *hHeadTrackData )->Rmat_prev[i][i] = 1.0f; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( *hHeadTrackData )->sr_pose_pred_axis = DEFAULT_AXIS; +#endif set_zero( ( *hHeadTrackData )->chEneIIR[0], MASA_FREQUENCY_BANDS ); set_zero( ( *hHeadTrackData )->chEneIIR[1], MASA_FREQUENCY_BANDS ); @@ -144,17 +153,52 @@ void QuatToRotMat( float Rmat[3][3] /* o : real-space rotation matrix for this rotation */ ) { - Rmat[0][0] = quat.w * quat.w + quat.x * quat.x - quat.y * quat.y - quat.z * quat.z; - Rmat[0][1] = 2.0f * ( quat.x * quat.y - quat.w * quat.z ); - Rmat[0][2] = 2.0f * ( quat.x * quat.z + quat.w * quat.y ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( quat.w == -3.0 ) + { + float c1, c2, c3, s1, s2, s3; + /* Euler angles in R_X(roll)*R_Y(pitch)*R_Z(yaw) convention + * + * yaw: rotate scene counter-clockwise in the horizontal plane + * pitch: rotate scene in the median plane, increase elevation with positive values + * roll: rotate scene from the right ear to the top + */ + + c1 = cosf( quat.z / _180_OVER_PI ); + c2 = cosf( quat.y / _180_OVER_PI ); + c3 = cosf( quat.x / _180_OVER_PI ); + + s1 = sinf( quat.z / _180_OVER_PI ); + s2 = sinf( -quat.y / _180_OVER_PI ); + s3 = sinf( quat.x / _180_OVER_PI ); + + Rmat[0][0] = c2 * c3; + Rmat[0][1] = -c2 * s3; + Rmat[0][2] = s2; + + Rmat[1][0] = c1 * s3 + c3 * s1 * s2; + Rmat[1][1] = c1 * c3 - s1 * s2 * s3; + Rmat[1][2] = -c2 * s1; + + Rmat[2][0] = s1 * s3 - c1 * c3 * s2; + Rmat[2][1] = c3 * s1 + c1 * s2 * s3; + Rmat[2][2] = c1 * c2; + } + else +#endif + { + Rmat[0][0] = quat.w * quat.w + quat.x * quat.x - quat.y * quat.y - quat.z * quat.z; + Rmat[0][1] = 2.0f * ( quat.x * quat.y - quat.w * quat.z ); + Rmat[0][2] = 2.0f * ( quat.x * quat.z + quat.w * quat.y ); - Rmat[1][0] = 2.0f * ( quat.x * quat.y + quat.w * quat.z ); - Rmat[1][1] = quat.w * quat.w - quat.x * quat.x + quat.y * quat.y - quat.z * quat.z; - Rmat[1][2] = 2.0f * ( quat.y * quat.z - quat.w * quat.x ); + Rmat[1][0] = 2.0f * ( quat.x * quat.y + quat.w * quat.z ); + Rmat[1][1] = quat.w * quat.w - quat.x * quat.x + quat.y * quat.y - quat.z * quat.z; + Rmat[1][2] = 2.0f * ( quat.y * quat.z - quat.w * quat.x ); - Rmat[2][0] = 2.0f * ( quat.x * quat.z - quat.w * quat.y ); - Rmat[2][1] = 2.0f * ( quat.y * quat.z + quat.w * quat.x ); - Rmat[2][2] = quat.w * quat.w - quat.x * quat.x - quat.y * quat.y + quat.z * quat.z; + Rmat[2][0] = 2.0f * ( quat.x * quat.z - quat.w * quat.y ); + Rmat[2][1] = 2.0f * ( quat.y * quat.z + quat.w * quat.x ); + Rmat[2][2] = quat.w * quat.w - quat.x * quat.x - quat.y * quat.y + quat.z * quat.z; + } return; } @@ -165,7 +209,6 @@ void QuatToRotMat( * * Calculate corresponding Quaternion from Euler angles in radians *------------------------------------------------------------------------*/ - void Euler2Quat( const float yaw, /* i : yaw (x) */ const float pitch, /* i : pitch (y) */ @@ -179,6 +222,7 @@ void Euler2Quat( float sp = sinf( pitch * 0.5f ); float cy = cosf( yaw * 0.5f ); float sy = sinf( yaw * 0.5f ); + quat->w = cr * cp * cy + sr * sp * sy; quat->x = sr * cp * cy - cr * sp * sy; quat->y = sr * cp * sy + cr * sp * cy; @@ -187,6 +231,55 @@ void Euler2Quat( return; } + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*------------------------------------------------------------------------- + * Quat2EulerDegree() + * + * Quaternion handling: calculate corresponding Euler angles in degrees + *------------------------------------------------------------------------*/ +void Quat2EulerDegree( + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ + float *yaw, /* o : yaw */ + float *pitch, /* o : pitch */ + float *roll /* o : roll */ +) +{ + if ( quat.w != -3.0 ) + { +#ifdef EUALER2QUAT_FIX + float p; +#endif + *yaw = atan2f( 2 * ( quat.w * quat.x + quat.y * quat.z ), 1 - 2 * ( quat.x * quat.x + quat.y * quat.y ) ); +#ifdef EUALER2QUAT_FIX + p = 2 * ( quat.w * quat.y - quat.z * quat.x ); + p = max( -1.0f, min( 1.0f, p ) ); + *pitch = asinf( p ); +#else + *pitch = asinf( 2 * ( quat.w * quat.y - quat.z * quat.x ) ); +#endif + *roll = atan2f( 2 * ( quat.w * quat.z + quat.x * quat.y ), 1 - 2 * ( quat.y * quat.y + quat.z * quat.z ) ); + *yaw *= _180_OVER_PI; + *pitch *= _180_OVER_PI; + *roll *= _180_OVER_PI; + } + else + { + /* Euler angles in R_X(roll)*R_Y(pitch)*R_Z(yaw) convention + * + * yaw: rotate scene counter-clockwise in the horizontal plane + * pitch: rotate scene in the median plane, increase elevation with positive values + * roll: rotate scene from the right ear to the top + */ + *yaw = quat.z; + *pitch = quat.y; + *roll = quat.x; + } + + return; +} +#endif + /*------------------------------------------------------------------------- * deg2rad() * @@ -580,7 +673,6 @@ void rotateFrame_shd_cldfb( return; } - /*------------------------------------------------------------------------- * rotateFrame_sd_cldfb() * @@ -849,6 +941,9 @@ ivas_error combine_external_and_head_orientations_dec( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; +#endif IVAS_QUATERNION *headRotQuaternions = NULL; IVAS_VECTOR3 *listenerPos = NULL; int16_t numHeadRotQuaternions = 0; @@ -861,9 +956,22 @@ ivas_error combine_external_and_head_orientations_dec( headRotQuaternions = hHeadTrackData->Quaternions; listenerPos = hHeadTrackData->Pos; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + sr_pose_pred_axis = hHeadTrackData->sr_pose_pred_axis; +#endif } +#ifdef SPLIT_REND_WITH_HEAD_ROT + else + { + sr_pose_pred_axis = DEFAULT_AXIS; + } +#endif - return combine_external_and_head_orientations( headRotQuaternions, listenerPos, numHeadRotQuaternions, hExtOrientationData, hCombinedOrientationData ); + return combine_external_and_head_orientations( headRotQuaternions, listenerPos, +#ifdef SPLIT_REND_WITH_HEAD_ROT + sr_pose_pred_axis, +#endif + numHeadRotQuaternions, hExtOrientationData, hCombinedOrientationData ); } @@ -879,11 +987,17 @@ ivas_error combine_external_and_head_orientations_rend( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; +#endif IVAS_QUATERNION *headRotQuaternions = NULL; IVAS_VECTOR3 *listenerPos = NULL; int16_t numHeadRotQuaternions = 0; int16_t i; +#ifdef SPLIT_REND_WITH_HEAD_ROT + sr_pose_pred_axis = DEFAULT_AXIS; +#endif if ( hHeadTrackData != NULL ) { if ( hHeadTrackData->headRotEnabled ) @@ -891,6 +1005,9 @@ ivas_error combine_external_and_head_orientations_rend( headRotQuaternions = hHeadTrackData->headPositions; listenerPos = hHeadTrackData->Pos; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + sr_pose_pred_axis = hHeadTrackData->sr_pose_pred_axis; +#endif } else if ( hExtOrientationData != NULL ) { @@ -904,7 +1021,11 @@ ivas_error combine_external_and_head_orientations_rend( } } - return combine_external_and_head_orientations( headRotQuaternions, listenerPos, numHeadRotQuaternions, hExtOrientationData, hCombinedOrientationData ); + return combine_external_and_head_orientations( headRotQuaternions, listenerPos, +#ifdef SPLIT_REND_WITH_HEAD_ROT + sr_pose_pred_axis, +#endif + numHeadRotQuaternions, hExtOrientationData, hCombinedOrientationData ); } @@ -916,8 +1037,11 @@ ivas_error combine_external_and_head_orientations_rend( *------------------------------------------------------------------------*/ static ivas_error combine_external_and_head_orientations( - IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ - IVAS_VECTOR3 *listenerPos, /* i : listener position */ + IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ + IVAS_VECTOR3 *listenerPos, /* i : listener position */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis*/ +#endif int16_t numHeadRotQuaternions, /* i : number of head rotation quaternions */ EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ @@ -1158,6 +1282,9 @@ static ivas_error combine_external_and_head_orientations( hCombinedOrientationData->enableCombinedOrientation[i] = 0; } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCombinedOrientationData->sr_pose_pred_axis = sr_pose_pred_axis; +#endif return IVAS_ERR_OK; } @@ -1345,7 +1472,7 @@ static float SHrot_w( if ( m == 0 ) { - printf( "ERROR should not be called\n" ); + assert( 0 && "ERROR should not be called\n" ); return 0.0f; } else diff --git a/lib_rend/ivas_splitRend_lcld_dec.c b/lib_rend/ivas_splitRend_lcld_dec.c new file mode 100644 index 0000000000000000000000000000000000000000..641d6421523f865462c3de5a72220e11302c19d5 --- /dev/null +++ b/lib_rend/ivas_splitRend_lcld_dec.c @@ -0,0 +1,227 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby +International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der +angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips +N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge +Corporation, and other contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, +Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung +e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph +and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings +Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their +respective contributions in the software. This notice grants no license of any +kind, including but not limited to patent license, nor is any license granted by +implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration +agreement before making contributions. + + This software is provided "AS IS", without any express or implied warranties. +The software is in the development stage. It is intended exclusively for experts +who have experience with such software and solely for the purpose of inspection. +All implied warranties of non-infringement, merchantability and fitness for a +particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing +this software shall be submitted to and settled by the final, binding +jurisdiction of the courts of Munich, Germany in accordance with the laws of the +Federal Republic of Germany excluding its conflict of law rules and the United +Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "cnst.h" +#include "ivas_cnst.h" +#include "ivas_prot_rend.h" +#include "ivas_prot.h" +#include "ivas_rom_binauralRenderer.h" +#include "ivas_rom_com.h" +#include "ivas_rom_dec.h" +#include "ivas_rom_rend.h" +#include "lib_rend.h" +#include "options.h" +#include "prot.h" +#include +#include +#include +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT +ivas_error +ivas_splitBinLCLDDecOpen( BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, + int32_t iSampleRate, + int32_t iChannels ) +{ + ivas_error error; + BIN_HR_SPLIT_LCLD_DEC_HANDLE splitBinLCLDDec; + error = IVAS_ERR_OK; + if ( ( splitBinLCLDDec = (BIN_HR_SPLIT_LCLD_DEC_HANDLE) malloc( + sizeof( BIN_HR_SPLIT_LCLD_DEC ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, + "Can not allocate memory for LCLD decoder Module \n" ) ); + } + + splitBinLCLDDec->pLcld_dec = NULL; // place holder for CLDFB decoder handle + + splitBinLCLDDec->iChannels = iChannels; + splitBinLCLDDec->psCQMFDecoder = CreateCQMFDecoder( iSampleRate, iChannels ); + + splitBinLCLDDec->pppfDecCQMFReal = + (float ***) malloc( iChannels * sizeof( float ** ) ); + splitBinLCLDDec->pppfDecCQMFImag = + (float ***) malloc( iChannels * sizeof( float ** ) ); + for ( int32_t n = 0; n < splitBinLCLDDec->iChannels; n++ ) + { + splitBinLCLDDec->pppfDecCQMFReal[n] = + (float **) malloc( CLDFB_NO_COL_MAX * sizeof( float * ) ); + splitBinLCLDDec->pppfDecCQMFImag[n] = + (float **) malloc( CLDFB_NO_COL_MAX * sizeof( float * ) ); + } + +#ifdef CLDFB_DEBUG + splitBinLCLDDec->numFrame = 0; + char cldfbFilename[50] = "cldfb_out.bin"; + if ( ( splitBinLCLDDec->cldfbOut = fopen( cldfbFilename, "wb" ) ) == NULL ) + { + fprintf( stderr, "Error: CLDFB bitstream file %s could not be opened\n\n", + cldfbFilename ); + exit( -1 ); + } + int num_bands = CLDFB_NO_CHANNELS_MAX; + fwrite( &iChannels, sizeof( int ), 1, splitBinLCLDDec->cldfbOut ); + fwrite( &num_bands, sizeof( int ), 1, splitBinLCLDDec->cldfbOut ); +#endif +#ifdef SPLIT_REND_PLC + ivas_splitBinRendPLCOpen( &splitBinLCLDDec->hSplitRendPLC ); +#endif + + *hSplitBinLCLDDec = splitBinLCLDDec; + return error; +} + +void ivas_splitBinLCLDDecClose( BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec ) +{ + if ( ( *hSplitBinLCLDDec ) != NULL ) + { + if ( ( *hSplitBinLCLDDec )->psCQMFDecoder != NULL ) + { + DeleteCQMFDecoder( ( *hSplitBinLCLDDec )->psCQMFDecoder ); + } + + for ( int32_t n = 0; n < ( *hSplitBinLCLDDec )->iChannels; n++ ) + { + free( ( *hSplitBinLCLDDec )->pppfDecCQMFReal[n] ); + free( ( *hSplitBinLCLDDec )->pppfDecCQMFImag[n] ); + } + free( ( *hSplitBinLCLDDec )->pppfDecCQMFReal ); + free( ( *hSplitBinLCLDDec )->pppfDecCQMFImag ); + +#ifdef CLDFB_DEBUG + if ( ( *hSplitBinLCLDDec )->cldfbOut != NULL ) + { + fclose( ( *hSplitBinLCLDDec )->cldfbOut ); + } +#endif +#ifdef SPLIT_REND_PLC + ivas_splitBinRendPLCClose( &( *hSplitBinLCLDDec )->hSplitRendPLC ); +#endif + + free( *hSplitBinLCLDDec ); + *hSplitBinLCLDDec = NULL; + } + return; +} + +void ivas_splitBinLCLDDecProcess( + BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec, + ivas_split_rend_bits_t *pBits, + float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] +#ifdef SPLIT_REND_PLC + , + const int16_t bfi +#endif +) +{ + push_wmops( "ivas_splitBinLCLDDecProcess" ); + + assert( hSplitBinLCLDDec != NULL ); + assert( Cldfb_Out_Real != NULL ); + assert( Cldfb_Out_Imag != NULL ); + assert( pBits != NULL ); + +#ifdef CLDFB_DEBUG + printf( "Bytes read = %d\n", iBytesWritten ); +#endif +#ifdef SPLIT_REND_PLC + if ( !bfi ) + { +#endif + // Initialized with zeros....... :( + for ( int32_t n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) + { + for ( int32_t k = 0; k < CLDFB_NO_COL_MAX; k++ ) + { + hSplitBinLCLDDec->pppfDecCQMFReal[n][k] = Cldfb_Out_Real[n][k]; + hSplitBinLCLDDec->pppfDecCQMFImag[n][k] = Cldfb_Out_Imag[n][k]; + set_f( hSplitBinLCLDDec->pppfDecCQMFReal[n][k], 0, CLDFB_NO_CHANNELS_MAX ); + set_f( hSplitBinLCLDDec->pppfDecCQMFImag[n][k], 0, CLDFB_NO_CHANNELS_MAX ); + } + } + + DecodeFrame( hSplitBinLCLDDec->psCQMFDecoder, + pBits, + hSplitBinLCLDDec->pppfDecCQMFReal, + hSplitBinLCLDDec->pppfDecCQMFImag ); + +#ifdef CLDFB_DEBUG + printf( "Frame Decoded = %d\n", ++hSplitBinLCLDDec->numFrame ); + int writeByte = 0; + for ( int k = 0; k < CLDFB_NO_COL_MAX; k++ ) + { + for ( int b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) + { + for ( int n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) + { + writeByte = fwrite( &hSplitBinLCLDDec->pppfDecCQMFReal[n][k][b], + sizeof( float ), 1, hSplitBinLCLDDec->cldfbOut ); + if ( writeByte != 1 ) + exit( -1 ); + writeByte = fwrite( &hSplitBinLCLDDec->pppfDecCQMFImag[n][k][b], + sizeof( float ), 1, hSplitBinLCLDDec->cldfbOut ); + if ( writeByte != 1 ) + exit( -1 ); + } + } + } +#endif +#ifdef SPLIT_REND_PLC + if ( hSplitBinLCLDDec->hSplitRendPLC->prev_bfi != 0 ) + { + /* cross-fade recovered frame into good frame */ + ivas_splitBinRendPLC_xf( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels ); + } + } + else + { + /* do PLC for lost split renderer frame */ + ivas_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels ); + } + /* save PLC state */ + ivas_splitBinRendPLCsaveState( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels ); +#endif + + pop_wmops(); + + return; +} +#endif diff --git a/lib_rend/ivas_splitRend_lcld_enc.c b/lib_rend/ivas_splitRend_lcld_enc.c new file mode 100644 index 0000000000000000000000000000000000000000..1904f895b36321fc33ceebd40cc2a0c5abb366f7 --- /dev/null +++ b/lib_rend/ivas_splitRend_lcld_enc.c @@ -0,0 +1,223 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby +International AB, Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der +angewandten Forschung e.V., Huawei Technologies Co. LTD., Koninklijke Philips +N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge +Corporation, and other contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, +Ericsson AB, Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung +e.V., Huawei Technologies Co. LTD., Koninklijke Philips N.V., Nippon Telegraph +and Telephone Corporation, Nokia Technologies Oy, Orange, Panasonic Holdings +Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their +respective contributions in the software. This notice grants no license of any +kind, including but not limited to patent license, nor is any license granted by +implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration +agreement before making contributions. + + This software is provided "AS IS", without any express or implied warranties. +The software is in the development stage. It is intended exclusively for experts +who have experience with such software and solely for the purpose of inspection. +All implied warranties of non-infringement, merchantability and fitness for a +particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing +this software shall be submitted to and settled by the final, binding +jurisdiction of the courts of Munich, Germany in accordance with the laws of the +Federal Republic of Germany excluding its conflict of law rules and the United +Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "cnst.h" +#include "ivas_cnst.h" +#include "ivas_prot_rend.h" +#include "ivas_prot.h" +#include "ivas_rom_binauralRenderer.h" +#include "ivas_rom_com.h" +#include "ivas_rom_dec.h" +#include "ivas_rom_rend.h" +#include "lib_rend.h" +#include "options.h" +#include "prot.h" +#include +#include +#include +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT +ivas_error +ivas_splitBinLCLDEncOpen( BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, + int32_t iSampleRate, + int32_t iChannels, + int32_t iDataRate ) +{ + ivas_error error; + BIN_HR_SPLIT_LCLD_ENC_HANDLE splitBinLCLDEnc; + error = IVAS_ERR_OK; + if ( ( splitBinLCLDEnc = (BIN_HR_SPLIT_LCLD_ENC_HANDLE) malloc( + sizeof( BIN_HR_SPLIT_LCLD_ENC ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, + "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + splitBinLCLDEnc->pLcld_enc = NULL; // place holder for CLDFB encoder handle + + splitBinLCLDEnc->iChannels = iChannels; + splitBinLCLDEnc->psCQMFEncoder = + CreateCQMFEncoder( iSampleRate, iChannels, iDataRate, 1 ); + + splitBinLCLDEnc->pppfCQMFReal = + (float ***) malloc( iChannels * sizeof( float ** ) ); + splitBinLCLDEnc->pppfCQMFImag = + (float ***) malloc( iChannels * sizeof( float ** ) ); + for ( int32_t n = 0; n < splitBinLCLDEnc->iChannels; n++ ) + { + splitBinLCLDEnc->pppfCQMFReal[n] = + (float **) malloc( CLDFB_NO_COL_MAX * sizeof( float * ) ); + splitBinLCLDEnc->pppfCQMFImag[n] = + (float **) malloc( CLDFB_NO_COL_MAX * sizeof( float * ) ); + } + +#ifdef CLDFB_DEBUG + splitBinLCLDEnc->numFrame = 0; + char cldfbFilename[50] = "cldfb_in_ref.qmf"; + if ( ( splitBinLCLDEnc->cldfbIn = fopen( cldfbFilename, "rb" ) ) == NULL ) + { + fprintf( stderr, "Error: CLDFB bitstream file %s could not be opened\n\n", + cldfbFilename ); + exit( -1 ); + } + int chan, band; + fread( &chan, sizeof( int ), 1, splitBinLCLDEnc->cldfbIn ); + fread( &band, sizeof( int ), 1, splitBinLCLDEnc->cldfbIn ); +#endif + + *hSplitBinLCLDEnc = splitBinLCLDEnc; + return error; +} + +void ivas_splitBinLCLDEncClose( BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc ) +{ + if ( ( *hSplitBinLCLDEnc ) != NULL ) + { + DeleteCQMFEncoder( ( *hSplitBinLCLDEnc )->psCQMFEncoder ); + + for ( int32_t n = 0; n < ( *hSplitBinLCLDEnc )->iChannels; n++ ) + { + free( ( *hSplitBinLCLDEnc )->pppfCQMFReal[n] ); + free( ( *hSplitBinLCLDEnc )->pppfCQMFImag[n] ); + } + free( ( *hSplitBinLCLDEnc )->pppfCQMFReal ); + free( ( *hSplitBinLCLDEnc )->pppfCQMFImag ); + +#ifdef CLDFB_DEBUG + if ( ( *hSplitBinLCLDEnc )->cldfbIn != NULL ) + { + fclose( ( *hSplitBinLCLDEnc )->cldfbIn ); + } +#endif + + free( *hSplitBinLCLDEnc ); + *hSplitBinLCLDEnc = NULL; + } + return; +} + +void ivas_splitBinLCLDEncProcess( + BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc, + float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int32_t available_bits, + ivas_split_rend_bits_t *pBits ) +{ + int32_t iBitsWritten; + + push_wmops( "ivas_splitBinLCLDEncProcess" ); + + assert( hSplitBinLCLDEnc != NULL ); + assert( Cldfb_In_Real != NULL ); + assert( Cldfb_In_Imag != NULL ); + assert( pBits != NULL ); + + // A conversion is needed for the 3d pointer interface here ........ :( + for ( int32_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + { + for ( int32_t k = 0; k < CLDFB_NO_COL_MAX; k++ ) + { + hSplitBinLCLDEnc->pppfCQMFReal[n][k] = Cldfb_In_Real[n][k]; + hSplitBinLCLDEnc->pppfCQMFImag[n][k] = Cldfb_In_Imag[n][k]; + } + } + +#ifdef CLDFB_DEBUG + int readByte = 0; + for ( int k = 0; k < CLDFB_NO_COL_MAX; k++ ) + { + for ( int b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) + { + for ( int n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + { +#if 0 + readByte = fread(&hSplitBinLCLDEnc->pppfCQMFReal[n][k][b], sizeof(float), 1, hSplitBinLCLDEnc->cldfbIn); + if ( readByte != 1 ) + break; + readByte = fread(&hSplitBinLCLDEnc->pppfCQMFImag[n][k][b], sizeof(float), 1, hSplitBinLCLDEnc->cldfbIn); +#else + readByte = fread( &Cldfb_In_Real[n][k][b], sizeof( float ), 1, + hSplitBinLCLDEnc->cldfbIn ); + if ( readByte != 1 ) + break; + readByte = fread( &Cldfb_In_Imag[n][k][b], sizeof( float ), 1, + hSplitBinLCLDEnc->cldfbIn ); +#endif + } + } + } + + if ( readByte == 1 ) + { + printf( "Frame Read = %d\n", ++hSplitBinLCLDEnc->numFrame ); + } + else + { + printf( "Writing zeroes...\n" ); + for ( int k = 0; k < CLDFB_NO_COL_MAX; k++ ) + { + for ( int b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) + { + for ( int n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + { + hSplitBinLCLDEnc->pppfCQMFReal[n][k][b] = 0.f; + hSplitBinLCLDEnc->pppfCQMFImag[n][k][b] = 0.f; + } + } + } + } +#endif + + EncodeFrame( hSplitBinLCLDEnc->psCQMFEncoder, hSplitBinLCLDEnc->pppfCQMFReal, + hSplitBinLCLDEnc->pppfCQMFImag, &iBitsWritten, available_bits, + pBits ); + if ( iBitsWritten > available_bits ) + assert( iBitsWritten <= available_bits ); + +#ifdef CLDFB_DEBUG + printf( "Bits written = %d\n", iBitsWritten ); +#endif + + pop_wmops(); + + return; +} +#endif diff --git a/lib_rend/ivas_splitRendererPLC.c b/lib_rend/ivas_splitRendererPLC.c new file mode 100644 index 0000000000000000000000000000000000000000..eafc5617dd7bf22a3376b997e7bbf89122150aed --- /dev/null +++ b/lib_rend/ivas_splitRendererPLC.c @@ -0,0 +1,492 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" + +#include +#ifdef SPLIT_REND_PLC +#include +#include "ivas_prot.h" +#include "prot.h" +#include "cnst.h" +#include "ivas_cnst.h" +#include "ivas_rom_rend.h" +#include "ivas_rom_com.h" +#include "ivas_rom_dec.h" +#include "ivas_rom_binauralRenderer.h" +#include "lib_rend.h" +#include "ivas_prot_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + +#define DO_PERTURB 1 +#define PH_PERT_ONLY 1 +#define START_VAL_AVG_LEN 2 +#define SR_PLC_FADE_START 10 // start fading at this number of bad frames in row +#define SR_PLC_MUTE 30 // Total mute at this number of bad frames in row +#define SR_PLC_FADE_DEGREE -3 // fading degree per frame in dB +#define SRHO_THRESH 2.f / 3.f * 0.1f +#define STH_THRESH 2.f / 3.f * PI2 / 12 + +static void adaptive_polar_ext_plc( + const float *prev_real, + const float *prev_imag, + float *rec_real, + float *rec_imag +#if CLDFB_PLC_XF > 0 + , + float xf_alp[CLDFB_PLC_XF], + float xf_bet[CLDFB_PLC_XF] +#endif +) +{ + float uth[CLDFB_NO_COL_MAX], uthu[CLDFB_NO_COL_MAX], urh[CLDFB_NO_COL_MAX]; + float ph_adj, ph_diff, ph_adj_t, quot, drho, srho, diff, dth, sth, fac_real, fac_imag; + float Ruu_real[2], Ruu_imag[2]; + float start_real, start_imag, abs_fac, abs_fac_powj, comp_fac, fac_powj_real, fac_powj_imag, temp, abs2inv; + float fac_ph_real, fac_ph_imag, rat_real, rat_imag, abs_temp; + int32_t k, j; + + // reset of accumulators + ph_adj = 0.0f; + drho = 0.0f; + srho = 0.0f; + dth = 0.0f; + sth = 0.0f; + + // calculate per-sample phase and magnitude evolution in preceding frame + for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) + { + urh[k] = sqrtf( prev_imag[k] * prev_imag[k] + prev_real[k] * prev_real[k] ); + if ( urh[k] < EPSILON ) + { + // zero encountered + break; + } + uth[k] = atan2f( prev_imag[k], prev_real[k] ); + + // phase unwrap + if ( k == 0 ) + { + uthu[0] = uth[0]; + } + else + { + // phase unwrap + ph_diff = uth[k] - uth[k - 1]; + uthu[k] = uth[k]; + if ( fabsf( ph_diff ) >= PI2 / 2 ) + { + ph_adj_t = ph_diff / PI2; + if ( fabsf( ph_adj_t - truncf( ph_adj_t ) ) == 0.5f ) + { + ph_adj_t = truncf( ph_adj_t ); + } + ph_adj = -PI2 * roundf( ph_adj_t ) + ph_adj; + } + uthu[k] += ph_adj; + // unwrapped phase in uthu + + // mean and stdev of per-sample magnitude ratios + quot = urh[k] / urh[k - 1]; + drho += quot; + srho += SQR( quot ); + // mean and stdev of per-sample phase differences + diff = uthu[k] - uthu[k - 1]; // the mean value calculation could be optimized + dth += diff; + sth += SQR( diff ); + } + } + if ( k == CLDFB_NO_COL_MAX ) + { + // mean and stdev of per-sample magnitude ratios + drho *= 1.0f / ( CLDFB_NO_COL_MAX - 1 ); + temp = srho - ( CLDFB_NO_COL_MAX - 1 ) * SQR( drho ); + if ( temp > 0 ) + { + srho = sqrtf( temp * ( 1.0f / ( CLDFB_NO_COL_MAX - 2 ) ) ); + } + else + { + srho = 0.0f; + } + // mean and stdev of per-sample phase differences + dth *= 1.0f / ( CLDFB_NO_COL_MAX - 1 ); + temp = sth - ( CLDFB_NO_COL_MAX - 1 ) * SQR( dth ); + if ( temp > 0 ) + { + sth = sqrtf( temp * ( 1.0f / ( CLDFB_NO_COL_MAX - 2 ) ) ); + } + else + { + sth = 0.0f; + } + // do phase extension only if the std deviations are small + if ( ( srho < SRHO_THRESH ) || ( sth < STH_THRESH ) ) + { + // calculate complex evolution factor + fac_ph_real = cosf( dth ); + fac_ph_imag = sinf( dth ); + fac_real = min( 1, drho ) * fac_ph_real; + fac_imag = min( 1, drho ) * fac_ph_imag; +#if START_VAL_AVG_LEN > 1 + // Calculate start value for evolution from last samples of previous frame + fac_powj_real = fac_real; + fac_powj_imag = fac_imag; + start_real = prev_real[CLDFB_NO_COL_MAX - 1]; + start_imag = prev_imag[CLDFB_NO_COL_MAX - 1]; + for ( j = 1; j < START_VAL_AVG_LEN; j++ ) + { + start_real += fac_powj_real * prev_real[CLDFB_NO_COL_MAX - j - 1] - fac_powj_imag * prev_imag[CLDFB_NO_COL_MAX - j - 1]; + start_imag += fac_powj_imag * prev_real[CLDFB_NO_COL_MAX - j - 1] + fac_powj_real * prev_imag[CLDFB_NO_COL_MAX - j - 1]; + temp = fac_powj_real * fac_real - fac_powj_imag * fac_imag; + fac_powj_imag = fac_powj_imag * fac_real + fac_powj_real * fac_imag; + fac_powj_real = temp; + } + start_real *= 1.0f / START_VAL_AVG_LEN; + start_imag *= 1.0f / START_VAL_AVG_LEN; +#else + // take last sample of previous frame as start value + start_real = prev_real[CLDFB_NO_COL_MAX - 1]; + start_imag = prev_imag[CLDFB_NO_COL_MAX - 1]; +#endif +#if DO_PERTURB != 0 + // make evolution less static: apply per samples differences as in preceding frame + rat_real = ( prev_real[1] * prev_real[0] + prev_imag[1] * prev_imag[0] ); + rat_imag = ( -prev_real[1] * prev_imag[0] + prev_imag[1] * prev_real[0] ); +#if PH_PERT_ONLY != 0 + // only phase perturbation + abs_temp = sqrtf( SQR( rat_real ) + SQR( rat_imag ) ); + abs2inv = min( 1, drho ) / max( EPSILON, abs_temp ); + rat_real *= abs2inv; + rat_imag *= abs2inv; +#else + // phase and magnitude perturbation + abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[0] ) + SQR( prev_imag[0] ) ) ); + rat_real *= abs2inv; + rat_imag *= abs2inv; +#endif + // apply complex evolution for first substitution sample + rec_real[0] = rat_real * start_real - rat_imag * start_imag; + rec_imag[0] = rat_imag * start_real + rat_real * start_imag; + for ( j = 2; j < CLDFB_NO_COL_MAX; j++ ) + { + // make evolution less static: apply per samples differences as in preceding frame + rat_real = ( prev_real[j] * prev_real[j - 1] + prev_imag[j] * prev_imag[j - 1] ); + rat_imag = ( -prev_real[j] * prev_imag[j - 1] + prev_imag[j] * prev_real[j - 1] ); +#if PH_PERT_ONLY != 0 + // only phase perturbation + abs_temp = sqrtf( SQR( rat_real ) + SQR( rat_imag ) ); + abs2inv = min( 1, drho ) / max( EPSILON, abs_temp ); +#else + // phase and magnitude perturbation + abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[j - 1] ) + SQR( prev_imag[j - 1] ) ) ); +#endif + rat_real *= abs2inv; + rat_imag *= abs2inv; + // apply complex evolution for further substitution samples + rec_real[j - 1] = rat_real * rec_real[j - 2] - rat_imag * rec_imag[j - 2]; + rec_imag[j - 1] = rat_imag * rec_real[j - 2] + rat_real * rec_imag[j - 2]; + } + // do the same for samples of crossfade region + for ( j = 1; j < CLDFB_PLC_XF + 2; j++ ) + { + rat_real = ( prev_real[j] * prev_real[j - 1] + prev_imag[j] * prev_imag[j - 1] ); + rat_imag = ( -prev_real[j] * prev_imag[j - 1] + prev_imag[j] * prev_real[j - 1] ); +#if PH_PERT_ONLY != 0 + abs_temp = sqrtf( SQR( rat_real ) + SQR( rat_imag ) ); + abs2inv = min( 1, drho ) / max( EPSILON, abs_temp ); +#else + abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[j - 1] ) + SQR( prev_imag[j - 1] ) ) ); +#endif + rat_real *= abs2inv; + rat_imag *= abs2inv; + rec_real[j + CLDFB_NO_COL_MAX - 2] = rat_real * rec_real[j + CLDFB_NO_COL_MAX - 3] - rat_imag * rec_imag[j + CLDFB_NO_COL_MAX - 3]; + rec_imag[j + CLDFB_NO_COL_MAX - 2] = rat_imag * rec_real[j + CLDFB_NO_COL_MAX - 3] + rat_real * rec_imag[j + CLDFB_NO_COL_MAX - 3]; + } +#else + rec_real[0] = fac_real * start_real - fac_imag * start_imag; + rec_imag[0] = fac_imag * start_real + fac_real * start_imag; + for ( j = 1; j < CLDFB_NO_COL_MAX + CLDFB_PLC_XF; j++ ) + { + rec_real[j] = fac_real * rec_real[j - 1] - fac_imag * rec_imag[j - 1]; + rec_imag[j] = fac_imag * rec_real[j - 1] + fac_real * rec_imag[j - 1]; + } +#endif +#if CLDFB_PLC_XF > 0 + // apply crossfade + for ( j = 0; j < CLDFB_PLC_XF; j++ ) + { + rec_real[CLDFB_NO_COL_MAX + j] *= xf_alp[j]; + rec_imag[CLDFB_NO_COL_MAX + j] *= xf_alp[j]; + xf_bet[j] = 1 - xf_alp[j]; + } +#endif + } + else + { + // do complex lpc combined with frame repetition + Ruu_real[0] = SQR( prev_real[0] ) + SQR( prev_imag[0] ); + Ruu_real[1] = 0; + Ruu_imag[1] = 0; + for ( j = 1; j < CLDFB_NO_COL_MAX; j++ ) + { + Ruu_real[0] += SQR( prev_real[j] ) + SQR( prev_imag[j] ); + Ruu_real[1] += prev_real[j] * prev_real[j - 1] + prev_imag[j] * prev_imag[j - 1]; + Ruu_imag[1] += prev_imag[j] * prev_real[j - 1] - prev_real[j] * prev_imag[j - 1]; + } + if ( Ruu_real[0] > EPSILON ) + { + // prediction coefficient + fac_real = Ruu_real[1] / Ruu_real[0]; + fac_imag = Ruu_imag[1] / Ruu_real[0]; + } + else + { + fac_real = 0; + fac_imag = 0; + } + // apply prediction using last sample of preceding frame as start value and combine with previous frame samples + fac_powj_real = fac_real; + fac_powj_imag = fac_imag; + abs_fac = sqrtf( SQR( fac_real ) + SQR( fac_imag ) ); + abs_fac_powj = abs_fac; + for ( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + comp_fac = 1 - abs_fac_powj; + rec_real[j] = prev_real[CLDFB_NO_COL_MAX - 1] * fac_powj_real - prev_imag[CLDFB_NO_COL_MAX - 1] * fac_powj_imag + + prev_real[j] * comp_fac; + rec_imag[j] = prev_real[CLDFB_NO_COL_MAX - 1] * fac_powj_imag + prev_imag[CLDFB_NO_COL_MAX - 1] * fac_powj_real + + prev_imag[j] * comp_fac; + abs_fac_powj = abs_fac_powj * abs_fac; + temp = fac_powj_real * fac_real - fac_powj_imag * fac_imag; + fac_powj_imag = fac_powj_real * fac_imag + fac_powj_imag * fac_real; + fac_powj_real = temp; + } + // prepare XF to next frame using prediction + fac_powj_real = fac_real; + fac_powj_imag = fac_imag; + abs_fac_powj = abs_fac; +#if CLDFB_PLC_XF > 0 + for ( j = 0; j < CLDFB_PLC_XF; j++ ) + { + xf_bet[j] = 1 - abs_fac_powj; + rec_real[j + CLDFB_NO_COL_MAX] = rec_real[CLDFB_NO_COL_MAX - 1] * fac_powj_real - rec_imag[CLDFB_NO_COL_MAX - 1] * fac_powj_imag; + rec_imag[j + CLDFB_NO_COL_MAX] = rec_real[CLDFB_NO_COL_MAX - 1] * fac_powj_imag + rec_imag[CLDFB_NO_COL_MAX - 1] * fac_powj_real; + abs_fac_powj = abs_fac_powj * abs_fac; + temp = fac_powj_real * fac_real - fac_powj_imag * fac_imag; + fac_powj_imag = fac_powj_real * fac_imag + fac_powj_imag * fac_real; + fac_powj_real = temp; + } +#endif + } + } + else + { + for ( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + rec_real[j] = prev_real[j]; + rec_imag[j] = prev_imag[j]; + } +#if CLDFB_PLC_XF > 0 + for ( j = 0; j < CLDFB_PLC_XF; j++ ) + { + xf_bet[j] = 1; + rec_real[j + CLDFB_NO_COL_MAX] = 0; + rec_imag[j + CLDFB_NO_COL_MAX] = 0; + } +#endif + } +} + +ivas_error ivas_splitBinRendPLCOpen( + SPLIT_REND_PLC_HANDLE *phSplitRendPLC ) +{ + ivas_error error; + SPLIT_REND_PLC_HANDLE hSplitRendPLC; + + error = IVAS_ERR_OK; + if ( ( hSplitRendPLC = (SPLIT_REND_PLC_HANDLE) malloc( sizeof( SPLIT_REND_PLC_STRUCT ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split renderer PLC Module \n" ) ); + } + hSplitRendPLC->prev_bfi = 0; + hSplitRendPLC->bf_count = 0; + set_zero( &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[0][0][0], 2 * ( CLDFB_NO_COL_MAX + CLDFB_PLC_XF ) * CLDFB_NO_CHANNELS_MAX ); + set_zero( &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[0][0][0], 2 * ( CLDFB_NO_COL_MAX + CLDFB_PLC_XF ) * CLDFB_NO_CHANNELS_MAX ); + *phSplitRendPLC = hSplitRendPLC; + + return error; +} + +void ivas_splitBinRendPLCClose( SPLIT_REND_PLC_HANDLE *phSplitRendPLC ) +{ + if ( ( *phSplitRendPLC ) != NULL ) + { + free( ( *phSplitRendPLC ) ); + ( *phSplitRendPLC ) = NULL; + } + return; +} + +void ivas_splitBinRendPLCsaveState( + SPLIT_REND_PLC_HANDLE hSplitRendPLC, + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t num_chs ) +{ + int32_t k, n; + /* Save Cldfb frame */ + for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) + { + for ( n = 0; n < num_chs; n++ ) + { + mvr2r( &Cldfb_RealBuffer_Binaural[n][k][0], &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][0], CLDFB_NO_CHANNELS_MAX ); + mvr2r( &Cldfb_ImagBuffer_Binaural[n][k][0], &hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][0], CLDFB_NO_CHANNELS_MAX ); + } + } +} + +/* Cross-fade of preceding bad frame into good frame */ +void ivas_splitBinRendPLC_xf( + SPLIT_REND_PLC_HANDLE hSplitRendPLC, + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t num_chs ) +{ + int32_t n, i, k; + // Indicate that next transition will be from a good frame + hSplitRendPLC->prev_bfi = 0; + // Reset bf conter + hSplitRendPLC->bf_count = 0; + + { + // Do the cross fade + for ( n = 0; n < num_chs; n++ ) + { + for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) + { +#if CLDFB_PLC_XF > 0 + for ( k = 0; k < CLDFB_PLC_XF; k++ ) + { + Cldfb_RealBuffer_Binaural[n][k][i] = hSplitRendPLC->CldfbPLC_state.xf_bet[n][i][k] * Cldfb_RealBuffer_Binaural[n][k][i] + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k + CLDFB_NO_COL_MAX][i]; + Cldfb_ImagBuffer_Binaural[n][k][i] = hSplitRendPLC->CldfbPLC_state.xf_bet[n][i][k] * Cldfb_ImagBuffer_Binaural[n][k][i] + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k + CLDFB_NO_COL_MAX][i]; + } +#endif + } + } + } +} + +/* Conceal bad frame */ +void ivas_splitBinRendPLC( + SPLIT_REND_PLC_HANDLE hSplitRendPLC, + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t num_chs ) +{ + int32_t i, n, k; + float fade_fac; + float prev_real[CLDFB_NO_COL_MAX], prev_imag[CLDFB_NO_COL_MAX], rec_real[CLDFB_NO_COL_MAX + CLDFB_PLC_XF], rec_imag[CLDFB_NO_COL_MAX + CLDFB_PLC_XF]; +#if CLDFB_PLC_XF > 0 + float xf_alp[CLDFB_PLC_XF]; +#endif + + // Indicate that next transition will be from a bad frame + hSplitRendPLC->prev_bfi = 1; + + { +#if CLDFB_PLC_XF > 0 + for ( i = 0; i < CLDFB_PLC_XF; i++ ) + { + xf_alp[i] = 1.0f - ( i + 1.0f ) / ( CLDFB_PLC_XF + 1.0f ); + } +#endif + // for k = 1 : size(x, 1) + // y(k, :) = adaptive_polar_ext_plc_vec(x(k, :), false); + // end + for ( n = 0; n < num_chs; n++ ) + { + for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) + { + for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) + { + prev_real[k] = hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i]; + prev_imag[k] = hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][i]; + } + adaptive_polar_ext_plc( prev_real, prev_imag, rec_real, rec_imag +#if CLDFB_PLC_XF > 0 + , + xf_alp, hSplitRendPLC->CldfbPLC_state.xf_bet[n][i] +#endif + ); + for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) + { + Cldfb_RealBuffer_Binaural[n][k][i] = rec_real[k]; + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i] = rec_real[k]; + Cldfb_ImagBuffer_Binaural[n][k][i] = rec_imag[k]; + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][i] = rec_imag[k]; + } +#if CLDFB_PLC_XF > 0 + for ( k = CLDFB_NO_COL_MAX; k < CLDFB_NO_COL_MAX + CLDFB_PLC_XF; k++ ) + { + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i] = rec_real[k]; + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][i] = rec_imag[k]; + } +#endif + } + } + } + + // Check bf counter + if ( hSplitRendPLC->bf_count++ >= SR_PLC_FADE_START ) + { + if ( hSplitRendPLC->bf_count < SR_PLC_MUTE ) + { + fade_fac = powf( 10, ( hSplitRendPLC->bf_count - SR_PLC_FADE_START ) * SR_PLC_FADE_DEGREE / 20.0f ); + v_multc( &Cldfb_RealBuffer_Binaural[0][0][0], fade_fac, &Cldfb_RealBuffer_Binaural[0][0][0], (int16_t) ( (CLDFB_NO_COL_MAX) *num_chs * CLDFB_NO_CHANNELS_MAX ) ); + v_multc( &Cldfb_ImagBuffer_Binaural[0][0][0], fade_fac, &Cldfb_ImagBuffer_Binaural[0][0][0], (int16_t) ( (CLDFB_NO_COL_MAX) *num_chs * CLDFB_NO_CHANNELS_MAX ) ); + } + else + { + set_zero( &Cldfb_RealBuffer_Binaural[0][0][0], (int16_t) ( (CLDFB_NO_COL_MAX) *num_chs * CLDFB_NO_CHANNELS_MAX ) ); + set_zero( &Cldfb_ImagBuffer_Binaural[0][0][0], (int16_t) ( (CLDFB_NO_COL_MAX) *num_chs * CLDFB_NO_CHANNELS_MAX ) ); + hSplitRendPLC->bf_count = SR_PLC_MUTE; + } + } + return; +} + +#endif diff --git a/lib_rend/ivas_splitRendererPost.c b/lib_rend/ivas_splitRendererPost.c new file mode 100644 index 0000000000000000000000000000000000000000..78ad14669946a7a0d476ba769342acf8897b0614 --- /dev/null +++ b/lib_rend/ivas_splitRendererPost.c @@ -0,0 +1,1869 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#include +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +#include +#endif +#include "ivas_prot.h" +#include "prot.h" +#include "cnst.h" +#include "ivas_cnst.h" +#include "ivas_rom_rend.h" +#include "ivas_rom_com.h" +#include "ivas_rom_dec.h" +#include "ivas_rom_binauralRenderer.h" +#include "lib_rend.h" +#include "ivas_prot_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT +ivas_error ivas_splitBinPostRendOpen( + BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int32_t output_Fs +#ifndef SPLIT_REND_LC3PLUS + , + const int16_t is_cldfb_in +#endif +) +{ + BIN_HR_SPLIT_POST_REND_HANDLE hBinRend; + ivas_error error; + int16_t ch; + + error = IVAS_ERR_OK; + if ( ( hBinRend = (BIN_HR_SPLIT_POST_REND_HANDLE) malloc( sizeof( BIN_HR_SPLIT_POST_REND ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split post renderer Module \n" ) ); + } + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hBinRend->cldfbSyn[ch] = NULL; + hBinRend->cldfbAna[ch] = NULL; + } +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hBinRend->cldfbSynReconsBinDec[i][ch] = NULL; + } + } +#endif + + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( error = openCldfb( &( hBinRend->cldfbSyn[ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } +#ifndef SPLIT_REND_LC3PLUS + if ( is_cldfb_in == 0 ) + { +#endif + if ( ( error = openCldfb( &( hBinRend->cldfbAna[ch] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } +#ifndef SPLIT_REND_LC3PLUS + } +#endif + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( error = openCldfb( &( hBinRend->cldfbSynReconsBinDec[i][ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } +#endif + hBinRend->cf_flag = 0; + set_fix_rotation_mat( hBinRend->fix_pos_rot_mat, pMultiBinPoseData ); + set_pose_types( hBinRend->pose_type, pMultiBinPoseData ); + ivas_split_rend_init_huff_cfg( &hBinRend->huff_cfg ); + *hBinHrSplitPostRend = hBinRend; + + return error; +} + +void ivas_splitBinPostRendClose( BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend ) +{ + int16_t ch; + if ( ( *hBinHrSplitPostRend ) != NULL ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( *hBinHrSplitPostRend )->cldfbSyn[ch] != NULL ) + { + deleteCldfb( &( ( *hBinHrSplitPostRend )->cldfbSyn[ch] ) ); + ( *hBinHrSplitPostRend )->cldfbSyn[ch] = NULL; + } + if ( ( *hBinHrSplitPostRend )->cldfbAna[ch] != NULL ) + { + deleteCldfb( &( ( *hBinHrSplitPostRend )->cldfbAna[ch] ) ); + ( *hBinHrSplitPostRend )->cldfbAna[ch] = NULL; + } + } +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( *hBinHrSplitPostRend )->cldfbSynReconsBinDec[i][ch] != NULL ) + { + deleteCldfb( &( ( *hBinHrSplitPostRend )->cldfbSynReconsBinDec[i][ch] ) ); + ( *hBinHrSplitPostRend )->cldfbSynReconsBinDec[i][ch] = NULL; + } + } + } +#endif + + free( ( *hBinHrSplitPostRend ) ); + ( *hBinHrSplitPostRend ) = NULL; + } + return; +} + +/*-----------------------------------------------------------------------------------------* + * Function ivas_huffman_code_bits_present() + * + * Huffman code bits present + *-----------------------------------------------------------------------------------------*/ + +static int32_t ivas_split_rend_huffman_code_bits_present( + const int32_t *codebook, + const int32_t code, + const int32_t bits, + const int32_t len ) +{ + int32_t index = len + 1; + int32_t i = 0; + int32_t code_t, ind_t, bits_t; + + while ( i < len ) + { + ind_t = codebook[0]; + bits_t = codebook[1]; + code_t = codebook[2]; + if ( ( code == code_t ) && ( bits == bits_t ) ) + { + return ind_t; + } + codebook = codebook + 3; + i++; + } + + return index; +} + +static int16_t ivas_split_rend_huffman_decode_opt( + ivas_split_rend_huffman_cfg_t *huff_cfg, + ivas_split_rend_bits_t *pBits, + const int16_t *idx_trav_list ) +{ + int32_t i, ind, code, num_bits, code_b, num_bits_read; + const int32_t *codebook; + codebook = huff_cfg->codebook; + num_bits_read = 0; + ind = huff_cfg->codebook[0] - 1; + code = 0; + for ( i = 0; i < huff_cfg->sym_len; i++ ) + { + codebook = codebook + idx_trav_list[i] * 3; + num_bits = codebook[1]; + code_b = codebook[2]; + num_bits_read = num_bits - num_bits_read; + code = code << num_bits_read; + if ( num_bits_read > 0 ) + { + code |= ivas_split_rend_bitstream_read_int32( pBits, num_bits_read ); + } + + if ( code == code_b ) + { + ind = codebook[0]; + break; + } + + num_bits_read = num_bits; + codebook = huff_cfg->codebook; + } +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + assert( ind >= huff_cfg->codebook[0] ); +#endif + return (int16_t) ind; +} + +static int16_t ivas_split_rend_huffman_decode( + ivas_split_rend_huffman_cfg_t *huff_cfg, + ivas_split_rend_bits_t *pBits ) +{ + int32_t code, bit, num_bits_read, ind; + + code = ivas_split_rend_bitstream_read_int32( pBits, huff_cfg->min_len ); + num_bits_read = huff_cfg->min_len; + + ind = ivas_split_rend_huffman_code_bits_present( huff_cfg->codebook, code, num_bits_read, huff_cfg->sym_len ); + + while ( ind > huff_cfg->sym_len ) + { + bit = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + num_bits_read += 1; + code = code << 1 | bit; + ind = ivas_split_rend_huffman_code_bits_present( huff_cfg->codebook, code, num_bits_read, huff_cfg->sym_len ); + if ( num_bits_read > huff_cfg->max_len ) + { + assert( 0 ); + } + } + + return (int16_t) ind; +} + +static void ivas_split_rend_unquant_md( + BIN_HR_SPLIT_REND_MD_HANDLE hMd, + IVAS_SPLIT_REND_POSE_TYPE pose_type, + int16_t real_only, + float fix_pos_rot_mat[][BINAURAL_CHANNELS] ) +{ + int16_t ch1, ch2; + int16_t gd_idx_min; + + if ( pose_type == PRED_ONLY ) + { + + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re_idx[ch1][ch2] * IVAS_SPLIT_REND_PRED_Q_STEP; + hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re[ch1][ch2] + fix_pos_rot_mat[ch1][ch2]; + } + } + if ( real_only ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + hMd->pred_mat_im[ch1][ch2] = 0.0f; + } + } + } + else + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + hMd->pred_mat_im[ch1][ch2] = hMd->pred_mat_im_idx[ch1][ch2] * IVAS_SPLIT_REND_PRED_Q_STEP; + } + } + } + } + else if ( pose_type == COM_GAIN_ONLY ) + { + gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_D_1BYQ_STEP * IVAS_SPLIT_REND_D_MIN_VAL ); + hMd->gd_idx += gd_idx_min; + hMd->gd = hMd->gd_idx * IVAS_SPLIT_REND_D_Q_STEP; + } + else if ( pose_type == LR_GAIN_ONLY ) + { + gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * IVAS_SPLIT_REND_PITCH_G_MIN_VAL ); + hMd->gd_idx += gd_idx_min; + hMd->gd = hMd->gd_idx * IVAS_SPLIT_REND_PITCH_G_Q_STEP; + + hMd->gd2_idx += gd_idx_min; + hMd->gd2 = hMd->gd2_idx * IVAS_SPLIT_REND_PITCH_G_Q_STEP; + } + else + { + hMd->gd = 0.0f; + } + + return; +} + +static void ivas_splitBinPostRendMdBase2Dec( + ivas_split_rend_bits_t *pBits, + BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int16_t num_subframes, + const int16_t pred_real_bands_yaw, + const int16_t pred_imag_bands_yaw, + const int16_t d_bands_yaw, + const int16_t bands_pitch, + const int16_t pred_real_bands_roll, + const int16_t pred_imag_bands_roll ) +{ + int16_t sf_idx, pos_idx, b, ch1, ch2; + int16_t min_pred_idx, min_gd_idx, min_p_gd_idx, pred_code_len, gd_code_len, p_gd_code_len; + int16_t code; + BIN_HR_SPLIT_REND_MD_HANDLE hMd; + BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; + + pHuff_cfg = &hBinHrSplitPostRend->huff_cfg; + min_pred_idx = (int16_t) pHuff_cfg->pred.codebook[0]; + min_gd_idx = (int16_t) pHuff_cfg->gd.codebook[0]; + min_p_gd_idx = (int16_t) pHuff_cfg->p_gd.codebook[0]; + pred_code_len = pHuff_cfg->pred_base2_code_len; + gd_code_len = pHuff_cfg->gd_base2_code_len; + p_gd_code_len = pHuff_cfg->p_gd_base2_code_len; + + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_code_len ); + hMd->pred_mat_re_idx[ch1][ch2] = code + min_pred_idx; + } + } + } + for ( b = 0; b < pred_imag_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_code_len ); + hMd->pred_mat_im_idx[ch1][ch2] = code + min_pred_idx; + } + } + } + for ( b = 0; b < d_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, gd_code_len ); + hMd->gd_idx = code + min_gd_idx; + } + } + else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, p_gd_code_len ); + hMd->gd_idx = code + min_p_gd_idx; + code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, p_gd_code_len ); + hMd->gd2_idx = code + min_p_gd_idx; + } + } + else + { + for ( b = 0; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_code_len ); + hMd->pred_mat_re_idx[ch1][ch2] = code + min_pred_idx; + } + } + } + for ( b = 0; b < pred_imag_bands_roll; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_code_len ); + hMd->pred_mat_im_idx[ch1][ch2] = code + min_pred_idx; + } + } + } + } + } + } + + return; +} + +static void ivas_splitBinPostRendMdHuffDec( + ivas_split_rend_bits_t *pBits, + BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int16_t num_subframes, + const int16_t pred_real_bands_yaw, + const int16_t pred_imag_bands_yaw, + const int16_t d_bands_yaw, + const int16_t bands_pitch, + const int16_t pred_real_bands_roll, + const int16_t pred_imag_bands_roll ) +{ + int16_t pos_idx, b, sf_idx; + int16_t ch1, ch2; + int16_t sym_adj_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + int16_t min_pred_idx, max_pred_idx; + BIN_HR_SPLIT_REND_MD_HANDLE hMd; + BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; + + pHuff_cfg = &hBinHrSplitPostRend->huff_cfg; + min_pred_idx = (int16_t) pHuff_cfg->pred.codebook[0]; + max_pred_idx = (int16_t) pHuff_cfg->pred.codebook[( IVAS_SPLIT_REND_PRED_QUANT_PNTS - 1 ) * 3]; + + + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred, pBits, pHuff_cfg->pred_idx_trav ); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits ); + } + } + ivas_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_idx, max_pred_idx ); + } + for ( b = 0; b < pred_imag_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred, pBits, pHuff_cfg->pred_idx_trav ); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits ); + } + } + ivas_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_idx, max_pred_idx ); + } + for ( b = 0; b < d_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + hMd->gd_idx = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->gd, pBits, pHuff_cfg->gd_idx_trav ); + // hMd->gd_idx = ivas_split_rend_huffman_decode( &pHuff_cfg->gd, pBits ); + } + } + else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + hMd->gd_idx = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav ); + // hMd->gd_idx = ivas_split_rend_huffman_decode( &pHuff_cfg->gd, pBits ); + + hMd->gd2_idx = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav ); + } + } + else + { + for ( b = 0; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred, pBits, pHuff_cfg->pred_idx_trav ); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits ); + } + } + ivas_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, 1, min_pred_idx, max_pred_idx ); + } + for ( b = 0; b < pred_imag_bands_roll; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->pred, pBits, pHuff_cfg->pred_idx_trav ); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits ); + } + } + ivas_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_idx, max_pred_idx ); + } + } + } + } + + return; +} + +void ivas_splitBinPostRendMdDec( + ivas_split_rend_bits_t *pBits, + BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + , + BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend +#endif +) +{ + int16_t pos_idx, b, sf_idx, num_subframes, ch1; + int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t num_complex_bands, num_quant_strats; + int32_t quant_strat_bits, is_huff_coding, quant_strat; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + int16_t ch1, ch2; +#endif + BIN_HR_SPLIT_REND_MD_HANDLE hMd; + IVAS_SPLIT_REND_CONFIG_DATA split_rend_config; + IVAS_SPLIT_REND_ROT_AXIS rot_axis; + + hBinHrSplitPostRend->low_Res = 1; + //( int16_t ) ivas_split_rend_bitstream_read_int32( pBits, 1 ); + + split_rend_config.dof = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_DOF_BITS ); + split_rend_config.hq_mode = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HQ_MODE_BITS ); + rot_axis = (IVAS_SPLIT_REND_ROT_AXIS) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_ROT_AXIS_BITS ); + + ivas_renderSplitGetMultiBinPoseData( + &split_rend_config, + pMultiBinPoseData, rot_axis ); + + set_fix_rotation_mat( hBinHrSplitPostRend->fix_pos_rot_mat, pMultiBinPoseData ); + set_pose_types( hBinHrSplitPostRend->pose_type, pMultiBinPoseData ); + + num_subframes = ( hBinHrSplitPostRend->low_Res == 0 ) ? MAX_PARAM_SPATIAL_SUBFRAMES : 1; + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + int16_t angle; + + hBinHrSplitPostRend->QuaternionsPre[sf_idx].w = -3.0f; + + angle = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HEAD_POSE_BITS ); + angle -= 180; + hBinHrSplitPostRend->QuaternionsPre[sf_idx].x = (float) angle; + + angle = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HEAD_POSE_BITS ); + angle -= 180; + hBinHrSplitPostRend->QuaternionsPre[sf_idx].y = (float) angle; + + angle = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HEAD_POSE_BITS ); + angle -= 180; + hBinHrSplitPostRend->QuaternionsPre[sf_idx].z = (float) angle; + } + + ivas_split_rend_get_quant_params( + MAX_SPLIT_REND_MD_BANDS, + pred_real_bands_yaw, + pred_imag_bands_yaw, + d_bands_yaw, + bands_pitch, + pred_real_bands_roll, + pred_imag_bands_roll, + &num_quant_strats, + &num_complex_bands ); + + quant_strat_bits = (int32_t) ceilf( log2f( num_quant_strats ) ); + is_huff_coding = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + quant_strat = ivas_split_rend_bitstream_read_int32( pBits, quant_strat_bits ); + + if ( is_huff_coding == 0 ) + { + ivas_splitBinPostRendMdBase2Dec( + pBits, hBinHrSplitPostRend, + pMultiBinPoseData, + num_subframes, + pred_real_bands_yaw[quant_strat], + pred_imag_bands_yaw[quant_strat], + d_bands_yaw[quant_strat], + bands_pitch[quant_strat], + pred_real_bands_roll[quant_strat], + pred_imag_bands_roll[quant_strat] ); + } + else + { + ivas_splitBinPostRendMdHuffDec( + pBits, hBinHrSplitPostRend, + pMultiBinPoseData, + num_subframes, + pred_real_bands_yaw[quant_strat], + pred_imag_bands_yaw[quant_strat], + d_bands_yaw[quant_strat], + bands_pitch[quant_strat], + pred_real_bands_roll[quant_strat], + pred_imag_bands_roll[quant_strat] ); + } +#ifdef SPLIT_MD_CODING_DEBUG + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + int16_t val, ch2, val_ref; + char filename[200] = "split_md_debug_indices.bin"; + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].gd_idx; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch[quant_strat]; b++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].gd_idx; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].gd2_idx; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + else + { + for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + } + } + } + } +#endif + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_unquant_md( hMd, + PRED_ONLY, + 0, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx] ); + } + for ( ; b < pred_real_bands_yaw[quant_strat]; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_unquant_md( hMd, + PRED_ONLY, + 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx] ); + } + for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + set_zero( hMd->pred_mat_re[ch1], BINAURAL_CHANNELS ); + set_zero( hMd->pred_mat_im[ch1], BINAURAL_CHANNELS ); + hMd->pred_mat_re[ch1][ch1] = 1.0f; + } + } + for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_unquant_md( hMd, + COM_GAIN_ONLY, + 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx] ); + } + for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + hMd->gd = 0.0f; + } + } + else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch[quant_strat]; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_unquant_md( hMd, + LR_GAIN_ONLY, + 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx] ); + } + for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + hMd->gd = 1.0f; + hMd->gd2 = 1.0f; + } + } + else + { + for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_unquant_md( hMd, + PRED_ONLY, + 0, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx] ); + } + for ( ; b < pred_real_bands_roll[quant_strat]; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_unquant_md( hMd, + PRED_ONLY, + 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx] ); + } + for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + set_zero( hMd->pred_mat_re[ch1], BINAURAL_CHANNELS ); + set_zero( hMd->pred_mat_im[ch1], BINAURAL_CHANNELS ); + hMd->pred_mat_re[ch1][ch1] = 1.0f; + } + } + } + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + float val; + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + if ( fabsf( hMd->pred_mat_re_idx[ch1][ch2] - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + if ( fabsf( hMd->pred_mat_im_idx[ch1][ch2] - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; + if ( fabsf( hMd->gd_idx - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch[quant_strat]; b++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; + if ( fabsf( hMd->gd_idx - val ) > 1e-20 ) + { + assert( 0 ); + } + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_idx; + if ( fabsf( hMd->gd2_idx - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + else + { + for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + if ( fabsf( hMd->pred_mat_re_idx[ch1][ch2] - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + if ( fabsf( hMd->pred_mat_im_idx[ch1][ch2] - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + } + } + } + } +#endif + + return; +} + +#define REAL_IMAG_INTERPOLATION +static void wrap_around_angle( float *a ) +{ + if ( ( *a ) > 180.0f ) + { + ( *a ) = ( *a ) - 360; + } + else if ( ( *a ) < -180.0f ) + { + ( *a ) = ( *a ) + 360; + } + return; +} +static void wrap_around_ypr( IVAS_QUATERNION *Quaternions ) +{ + /*only if quat is actually yaw, pitch , roll angles*/ + if ( Quaternions->w == -3.0f ) + { + wrap_around_angle( &Quaternions->x ); + wrap_around_angle( &Quaternions->y ); + wrap_around_angle( &Quaternions->z ); + } + return; +} + +static float get_interp_fact( float p[MAX_HEAD_ROT_POSES], float p_t, int16_t ind[2] ) +{ + float n, d, interp_fact; + if ( ind[0] != ind[1] ) + { + n = p[ind[0]] - p[ind[1]]; + d = p[ind[0]] - p_t; + interp_fact = d / n; +#ifdef SPLIT_SIN_SCALING_AND_EXTRAPOL_LIMIT + if ( interp_fact < 0.0f ) + { + d = max( -1.0f * MAX_EXTRAPOLATION_ANGLE, ( min( MAX_EXTRAPOLATION_ANGLE, d ) ) ); + n = sinf( n * ( EVS_PI / 180.0f ) ); + d = sinf( d * ( EVS_PI / 180.0f ) ); + interp_fact = d / n; + } +#endif + } + else + { + interp_fact = 0.0f; + } + + return interp_fact; +} + +static void get_nearest_pose_ind( float p[MAX_HEAD_ROT_POSES], float p_t, int16_t ind[2], int16_t num_poses ) +{ + float min_diff, diff; + int16_t pos_idx; + + ind[0] = 0; + ind[1] = 0; + min_diff = 360.0f; + /*find the closest pose from assumed poses*/ + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + diff = fabsf( p_t - p[pos_idx] ); + if ( diff < min_diff ) + { + ind[0] = pos_idx; + min_diff = (float) diff; + } + } + + min_diff = 360.0; + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + diff = fabsf( p_t - p[pos_idx] ); + if ( ( diff < min_diff ) && + ( fabs( p[pos_idx] - p[ind[0]] ) > EPSILON ) ) + { + ind[1] = pos_idx; + min_diff = (float) diff; + } + } + + return; +} + +static void get_interpolation_vars( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const IVAS_QUATERNION *Quaternions_ref, + const IVAS_QUATERNION *Quaternions_act, + int16_t interp_yaw_pose_idx[2], + int16_t interp_pitch_pose_idx[2], + int16_t interp_roll_pose_idx[2], + float *interp_yaw_fact, + float *interp_pitch_fact, + float *interp_roll_fact ) +{ + IVAS_QUATERNION quaternions_diff, quaternions_ref_euler, quaternions_act_euler; + float y[MAX_HEAD_ROT_POSES], p[MAX_HEAD_ROT_POSES], r[MAX_HEAD_ROT_POSES]; + int16_t pos_idx, num_poses; + + quaternions_diff.x = 0.0f; + quaternions_diff.y = 0.0f; + quaternions_diff.z = 0.0f; + + num_poses = pMultiBinPoseData->num_poses; + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + quaternions_diff.x = pMultiBinPoseData->relative_head_poses[pos_idx][0]; + quaternions_diff.y = pMultiBinPoseData->relative_head_poses[pos_idx][1]; + quaternions_diff.z = pMultiBinPoseData->relative_head_poses[pos_idx][2]; + y[pos_idx] = quaternions_diff.x; + p[pos_idx] = quaternions_diff.y; + r[pos_idx] = quaternions_diff.z; + } + + /*interpolation if actual pose is not same as one of assumed poses*/ + /*get the deviation*/ + Quat2EulerDegree( *Quaternions_ref, &quaternions_ref_euler.z, &quaternions_ref_euler.y, &quaternions_ref_euler.x ); /*order in Quat2Euler seems to be reversed ?*/ + Quat2EulerDegree( *Quaternions_act, &quaternions_act_euler.z, &quaternions_act_euler.y, &quaternions_act_euler.x ); /*order in Quat2Euler seems to be reversed ?*/ + quaternions_diff.w = -3.0f; /*euler*/ + quaternions_diff.x = quaternions_act_euler.x - quaternions_ref_euler.x; + quaternions_diff.y = quaternions_act_euler.y - quaternions_ref_euler.y; + quaternions_diff.z = quaternions_act_euler.z - quaternions_ref_euler.z; + wrap_around_ypr( &quaternions_diff ); + + interp_yaw_pose_idx[0] = 0; + interp_yaw_pose_idx[1] = 0; + if ( fabs( quaternions_diff.x ) > EPSILON ) + { + get_nearest_pose_ind( y, quaternions_diff.x, interp_yaw_pose_idx, num_poses ); + } + *interp_yaw_fact = get_interp_fact( y, quaternions_diff.x, interp_yaw_pose_idx ); + + interp_pitch_pose_idx[0] = 0; + interp_pitch_pose_idx[1] = 0; + if ( fabs( quaternions_diff.y ) > EPSILON ) + { + get_nearest_pose_ind( p, quaternions_diff.y, interp_pitch_pose_idx, num_poses ); + } + *interp_pitch_fact = get_interp_fact( p, quaternions_diff.y, interp_pitch_pose_idx ); + + interp_roll_pose_idx[0] = 0; + interp_roll_pose_idx[1] = 0; + if ( fabs( quaternions_diff.z ) > EPSILON ) + { + get_nearest_pose_ind( r, quaternions_diff.z, interp_roll_pose_idx, num_poses ); + } + *interp_roll_fact = get_interp_fact( r, quaternions_diff.z, interp_roll_pose_idx ); + + return; +} + +static void interpolate_gain_matrix( + BIN_HR_SPLIT_REND_MD rot_md[][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS], + int16_t sf_idx, + int16_t band_idx, + int16_t ind[2], + float interp_fact, + float gain[BINAURAL_CHANNELS] ) +{ + float gd1, gd2, gd3, gd4, diff; + + gd1 = 1.0f; + gd2 = 1.0f; + gd3 = 1.0f; + gd4 = 1.0f; + if ( ind[0] != 0 ) + { + gd1 = rot_md[ind[0] - 1][sf_idx][band_idx].gd; + gd3 = rot_md[ind[0] - 1][sf_idx][band_idx].gd2; + } + if ( ind[1] != 0 ) + { + gd2 = rot_md[ind[1] - 1][sf_idx][band_idx].gd; + gd4 = rot_md[ind[1] - 1][sf_idx][band_idx].gd2; + } +#if 0 + diff = gd1 / gd2; + pitch_gain_l = gd2 * powf( diff, 1.0f - interp_pitch_fact ); + pitch_gain_l = max( 0.0f, pitch_gain_l ); + + diff = gd3 / gd4; + pitch_gain_r = gd4 * powf( diff, 1.0f - interp_pitch_fact ); + pitch_gain_r = max( 0.0f, pitch_gain_r ); +#else + diff = gd1 - gd2; + gain[0] = gd1 - ( diff * interp_fact ); + gain[0] = max( 0.0f, gain[0] ); + + diff = gd3 - gd4; + gain[1] = gd3 - ( diff * interp_fact ); + gain[1] = max( 0.0f, gain[1] ); +#endif +} + +static void interpolate_pred_matrix( + BIN_HR_SPLIT_REND_MD rot_md[][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS], + int16_t sf_idx, + int16_t band_idx, + int16_t ind[2], + float interp_fact, + float mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + float mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS] ) +{ + int16_t ch_idx1, ch_idx2; + float diff; + BIN_HR_SPLIT_REND_MD *pRot_md; + float mix_mat_re1[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float mix_mat_im1[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float mix_mat_re2[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float mix_mat_im2[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; +#ifdef SPIT_ABS_SCALING_INTERP + float abs1, abs2; + float mix_mat_abs[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; +#endif + + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + set_zero( mix_mat_re1[ch_idx1], BINAURAL_CHANNELS ); + set_zero( mix_mat_im1[ch_idx1], BINAURAL_CHANNELS ); + mix_mat_re1[ch_idx1][ch_idx1] = 1.0f; + + set_zero( mix_mat_re2[ch_idx1], BINAURAL_CHANNELS ); + set_zero( mix_mat_im2[ch_idx1], BINAURAL_CHANNELS ); + mix_mat_re2[ch_idx1][ch_idx1] = 1.0f; + } + + if ( ind[0] != 0 ) + { + pRot_md = &rot_md[ind[0] - 1][sf_idx][band_idx]; + + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + for ( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ ) + { + mix_mat_re1[ch_idx1][ch_idx2] = pRot_md->pred_mat_re[ch_idx1][ch_idx2]; + mix_mat_im1[ch_idx1][ch_idx2] = pRot_md->pred_mat_im[ch_idx1][ch_idx2]; + } + } + } + + if ( ind[1] != 0 ) + { + pRot_md = &rot_md[ind[1] - 1][sf_idx][band_idx]; + + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + for ( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ ) + { + mix_mat_re2[ch_idx1][ch_idx2] = pRot_md->pred_mat_re[ch_idx1][ch_idx2]; + mix_mat_im2[ch_idx1][ch_idx2] = pRot_md->pred_mat_im[ch_idx1][ch_idx2]; + } + } + } + +#ifdef SPIT_ABS_SCALING_INTERP + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + for ( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ ) + { + IVAS_CALCULATE_ABS( mix_mat_re1[ch_idx1][ch_idx2], mix_mat_im1[ch_idx1][ch_idx2], abs1 ); + IVAS_CALCULATE_ABS( mix_mat_re2[ch_idx1][ch_idx2], mix_mat_im2[ch_idx1][ch_idx2], abs2 ); + diff = abs1 - abs2; + mix_mat_abs[ch_idx1][ch_idx2] = abs1 - ( diff * interp_fact ); + mix_mat_abs[ch_idx1][ch_idx2] = fabsf( mix_mat_abs[ch_idx1][ch_idx2] ); + } + } +#endif + + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + for ( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ ) + { + diff = mix_mat_re1[ch_idx1][ch_idx2] - mix_mat_re2[ch_idx1][ch_idx2]; + mat_re[ch_idx1][ch_idx2] = mix_mat_re1[ch_idx1][ch_idx2] - ( diff * interp_fact ); + + diff = mix_mat_im1[ch_idx1][ch_idx2] - mix_mat_im2[ch_idx1][ch_idx2]; + mat_im[ch_idx1][ch_idx2] = mix_mat_im1[ch_idx1][ch_idx2] - ( diff * interp_fact ); + } + } + +#ifdef SPIT_ABS_SCALING_INTERP + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + for ( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ ) + { + IVAS_CALCULATE_ABS( mat_re[ch_idx1][ch_idx2], mat_im[ch_idx1][ch_idx2], abs1 ); + if ( abs1 > 1e-10 ) + { + abs1 = mix_mat_abs[ch_idx1][ch_idx2] / abs1; + mat_re[ch_idx1][ch_idx2] = mat_re[ch_idx1][ch_idx2] * abs1; + mat_im[ch_idx1][ch_idx2] = mat_im[ch_idx1][ch_idx2] * abs1; + } + } + } +#endif + + return; +} + +static void interpolate_rend_md( + BIN_HR_SPLIT_REND_MD rot_md[][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS], + float mix_mat_re[][BINAURAL_CHANNELS], + float mix_mat_im[][BINAURAL_CHANNELS], + float *gd_int, + int16_t sf_idx, + int16_t band_idx, + int16_t interp_yaw_pose_idx[2], + int16_t interp_pitch_pose_idx[2], + int16_t interp_roll_pose_idx[2], + float interp_yaw_fact, + float interp_pitch_fact, + float interp_roll_fact ) +{ + int16_t ch_idx1, idx1, idx2; +#ifndef SPLIT_REND_REAL_ONLY_ROLL + float mix_mat_re1[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float mix_mat_im1[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float mix_mat_re3[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float mix_mat_im3[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + int16_t ch_idx2; +#endif + float gd1, gd2, gd3, gd4, diff, pitch_gain_r, pitch_gain_l; + + gd1 = 0.0f; + gd2 = 0.0f; + + idx1 = interp_yaw_pose_idx[0]; + idx2 = interp_yaw_pose_idx[1]; + if ( ( idx1 != 0 ) || ( idx2 != 0 ) ) + { + interpolate_pred_matrix( rot_md, sf_idx, band_idx, interp_yaw_pose_idx, interp_yaw_fact, mix_mat_re, mix_mat_im ); + + if ( idx1 != 0 ) + { + gd1 = rot_md[idx1 - 1][sf_idx][band_idx].gd; + } + + if ( idx2 != 0 ) + { + gd2 = rot_md[idx2 - 1][sf_idx][band_idx].gd; + } + + diff = gd1 - gd2; + *gd_int = gd1 - ( diff * interp_yaw_fact ); + } + else + { + /*P = P'*/ + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + set_zero( mix_mat_re[ch_idx1], BINAURAL_CHANNELS ); + set_zero( mix_mat_im[ch_idx1], BINAURAL_CHANNELS ); + mix_mat_re[ch_idx1][ch_idx1] = 1.0f; + } + *gd_int = 0.0f; + } + + idx1 = interp_pitch_pose_idx[0]; + idx2 = interp_pitch_pose_idx[1]; + if ( ( idx1 != 0 ) || ( idx2 != 0 ) ) + { + gd1 = 1.0f; + gd2 = 1.0f; + + gd3 = 1.0f; + gd4 = 1.0f; + + if ( idx1 != 0 ) + { + gd1 = rot_md[idx1 - 1][sf_idx][band_idx].gd; + gd3 = rot_md[idx1 - 1][sf_idx][band_idx].gd2; + } + if ( idx2 != 0 ) + { + gd2 = rot_md[idx2 - 1][sf_idx][band_idx].gd; + gd4 = rot_md[idx2 - 1][sf_idx][band_idx].gd2; + } +#if 0 + diff = gd1 / gd2; + pitch_gain_l = gd2 * powf( diff, 1.0f - interp_pitch_fact ); + pitch_gain_l = max( 0.0f, pitch_gain_l ); + + diff = gd3 / gd4; + pitch_gain_r = gd4 * powf( diff, 1.0f - interp_pitch_fact ); + pitch_gain_r = max( 0.0f, pitch_gain_r ); +#else + diff = gd1 - gd2; + pitch_gain_l = gd1 - ( diff * interp_pitch_fact ); + pitch_gain_l = max( 0.0f, pitch_gain_l ); + + diff = gd3 - gd4; + pitch_gain_r = gd3 - ( diff * interp_pitch_fact ); + pitch_gain_r = max( 0.0f, pitch_gain_r ); +#endif + + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + mix_mat_re[ch_idx1][0] *= pitch_gain_l; + mix_mat_re[ch_idx1][1] *= pitch_gain_r; + mix_mat_im[ch_idx1][0] *= pitch_gain_l; + mix_mat_im[ch_idx1][1] *= pitch_gain_r; + } + } + else + { + pitch_gain_l = 1.0f; + pitch_gain_r = 1.0f; + } + + idx1 = interp_roll_pose_idx[0]; + idx2 = interp_roll_pose_idx[1]; +#ifdef SPLIT_REND_REAL_ONLY_ROLL + if ( ( idx1 != 0 ) || ( idx2 != 0 ) ) + { + gd1 = 1.0f; + gd2 = 1.0f; + + gd3 = 1.0f; + gd4 = 1.0f; + + if ( idx1 != 0 ) + { + gd1 = rot_md[idx1 - 1][sf_idx][band_idx].gd; + gd3 = rot_md[idx1 - 1][sf_idx][band_idx].gd2; + } + if ( idx2 != 0 ) + { + gd2 = rot_md[idx2 - 1][sf_idx][band_idx].gd; + gd4 = rot_md[idx2 - 1][sf_idx][band_idx].gd2; + } +#if 0 + diff = gd1 / gd2; + pitch_gain_l = gd2 * powf( diff, 1.0f - interp_roll_fact ); + pitch_gain_l = max( 0.0f, pitch_gain_l ); + + diff = gd3 / gd4; + pitch_gain_r = gd4 * powf( diff, 1.0f - interp_roll_fact ); + pitch_gain_r = max( 0.0f, pitch_gain_r ); +#else + diff = gd1 - gd2; + pitch_gain_l = gd1 - ( diff * interp_roll_fact ); + pitch_gain_l = max( 0.0f, pitch_gain_l ); + + diff = gd3 - gd4; + pitch_gain_r = gd3 - ( diff * interp_roll_fact ); + pitch_gain_r = max( 0.0f, pitch_gain_r ); +#endif + + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + mix_mat_re[ch_idx1][0] *= pitch_gain_l; + mix_mat_re[ch_idx1][1] *= pitch_gain_r; + mix_mat_im[ch_idx1][0] *= pitch_gain_l; + mix_mat_im[ch_idx1][1] *= pitch_gain_r; + } + } +#else + if ( ( idx1 != 0 ) || ( idx2 != 0 ) ) + { + + + interpolate_pred_matrix( rot_md, sf_idx, band_idx, interp_roll_pose_idx, interp_roll_fact, mix_mat_re3, mix_mat_im3 ); + + ivas_mat_mult_2by2_complex( mix_mat_re, mix_mat_im, mix_mat_re3, mix_mat_im3, + mix_mat_re1, mix_mat_im1 ); + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + for ( ch_idx2 = 0; ch_idx2 < BINAURAL_CHANNELS; ch_idx2++ ) + { + mix_mat_re[ch_idx1][ch_idx2] = mix_mat_re1[ch_idx1][ch_idx2]; + mix_mat_im[ch_idx1][ch_idx2] = mix_mat_im1[ch_idx1][ch_idx2]; + } + } + } +#endif + + return; +} + +void ivas_SplitRenderer_PostRenderer( + BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ + float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i/o : Reference/out Binaural signals */ + const IVAS_QUATERNION Quaternions_act[MAX_PARAM_SPATIAL_SUBFRAMES] ) +{ + int16_t pos_idx, b, brange[2], ch_idx1; + int16_t num_md_bands, slot_idx, b2, sf_idx, index_slot, num_subframes, num_slots, sf_idx_md; + float pred_out_re[BINAURAL_CHANNELS], pred_out_im[BINAURAL_CHANNELS], tmp_re, tmp_im, gd_int; +#ifdef SPLIT_REND_PLC +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + BIN_HR_SPLIT_REND_MD rot_md_act[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS]; +#else + BIN_HR_SPLIT_REND_MD rot_md_act[1][MAX_SPLIT_REND_MD_BANDS]; +#endif +#endif +#ifndef SPLIT_REND_ZERO_OUT_YAW_D + float gd_cf, gd_cf_abs; +#endif + int16_t interp_yaw_pose_idx[2], interp_pitch_pose_idx[2], interp_roll_pose_idx[2]; + float interp_yaw_fact, interp_pitch_fact, interp_roll_fact; + float mix_mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float mix_mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + float Cldfb_RealBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; +#endif + float fade; + float *pMix_mat_re_prev[BINAURAL_CHANNELS]; + float *pMix_mat_im_prev[BINAURAL_CHANNELS]; + const int16_t *pBand_grouping = SplitRend_band_grouping; + num_md_bands = MAX_SPLIT_REND_MD_BANDS; + + push_wmops( "ivas_SplitRenderer_PostRenderer" ); + + + num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; + num_slots = MAX_PARAM_SPATIAL_SUBFRAMES; + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + pos_idx = MAX_HEAD_ROT_POSES - 1; +#else + pos_idx = 0; +#endif + + sf_idx_md = ( hBinPostRenderer->low_Res == 0 ) ? sf_idx : 0; + get_interpolation_vars( pMultiBinPoseData, + &hBinPostRenderer->QuaternionsPre[sf_idx_md], + &Quaternions_act[sf_idx], + interp_yaw_pose_idx, + interp_pitch_pose_idx, + interp_roll_pose_idx, + &interp_yaw_fact, + &interp_pitch_fact, + &interp_roll_fact ); + for ( b = 0; b < num_md_bands; b++ ) + { + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + set_zero( mix_mat_re[ch_idx1], BINAURAL_CHANNELS ); + set_zero( mix_mat_im[ch_idx1], BINAURAL_CHANNELS ); + mix_mat_re[ch_idx1][ch_idx1] = 1.0f; + } + gd_int = 0.0f; + interpolate_rend_md( hBinPostRenderer->rot_md, mix_mat_re, mix_mat_im, &gd_int, sf_idx_md, b, interp_yaw_pose_idx, interp_pitch_pose_idx, interp_roll_pose_idx, interp_yaw_fact, interp_pitch_fact, interp_roll_fact ); + + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { +#ifdef SPLIT_REND_PLC + /*update the prediction matrix with interpolated matrix*/ + rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][0] = mix_mat_re[ch_idx1][0]; + rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][1] = mix_mat_re[ch_idx1][1]; + rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][0] = mix_mat_im[ch_idx1][0]; + rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][1] = mix_mat_im[ch_idx1][1]; + rot_md_act[pos_idx][b].gd = gd_int; +#else + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][0] = mix_mat_re[ch_idx1][0]; + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][1] = mix_mat_re[ch_idx1][1]; + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][0] = mix_mat_im[ch_idx1][0]; + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][1] = mix_mat_im[ch_idx1][1]; + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd = gd_int; +#endif + } + } + + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES - 1; pos_idx++ ) + { + for ( b = 0; b < num_md_bands; b++ ) + { + if ( hBinPostRenderer->pose_type[pos_idx] == PITCH_ONLY ) + { + + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + set_zero( hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1], BINAURAL_CHANNELS ); + set_zero( hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1], BINAURAL_CHANNELS ); + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][ch_idx1] = 1.0f; + } + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[0][0] *= hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd; + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[1][1] *= hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd2; + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd = 0.0f; + } + else if ( hBinPostRenderer->pose_type[pos_idx] == ANY_ROLL ) + { + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd = 0.0f; + } + +#ifdef SPLIT_REND_PLC + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + + /*update the prediction matrix with interpolated matrix*/ + rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][0] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][0]; + rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][1] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][1]; + rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][0] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][0]; + rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][1] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][1]; + rot_md_act[pos_idx][b].gd = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd; + } +#endif + } + } + +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) +#else + pos_idx = 0; +#endif + { + for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) + { + index_slot = sf_idx * num_slots + slot_idx; + fade = ( (float) slot_idx + 1.0f ) / MAX_PARAM_SPATIAL_SUBFRAMES; + fade = min( fade, 1.0f ); + for ( b = 0; b < num_md_bands; b++ ) + { + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { +#ifdef SPLIT_REND_PLC + if ( hBinPostRenderer->cf_flag ) + { + pMix_mat_re_prev[ch_idx1] = hBinPostRenderer->mixer_mat_re[pos_idx][b][ch_idx1]; + pMix_mat_im_prev[ch_idx1] = hBinPostRenderer->mixer_mat_im[pos_idx][b][ch_idx1]; + mix_mat_re[ch_idx1][0] = fade * ( rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][0] ) + + ( 1.0f - fade ) * pMix_mat_re_prev[ch_idx1][0]; + mix_mat_re[ch_idx1][1] = fade * ( rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][1] ) + + ( 1.0f - fade ) * pMix_mat_re_prev[ch_idx1][1]; + + mix_mat_im[ch_idx1][0] = fade * ( rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][0] ) + + ( 1.0f - fade ) * pMix_mat_im_prev[ch_idx1][0]; + mix_mat_im[ch_idx1][1] = fade * ( rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][1] ) + + ( 1.0f - fade ) * pMix_mat_im_prev[ch_idx1][1]; + } + else + { + mix_mat_re[ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][0]; + mix_mat_re[ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][1]; + mix_mat_im[ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][0]; + mix_mat_im[ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][1]; + } +#else + if ( hBinPostRenderer->cf_flag ) + { + pMix_mat_re_prev[ch_idx1] = hBinPostRenderer->mixer_mat_re[pos_idx][b][ch_idx1]; + pMix_mat_im_prev[ch_idx1] = hBinPostRenderer->mixer_mat_im[pos_idx][b][ch_idx1]; + mix_mat_re[ch_idx1][0] = fade * ( hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][0] ) + + ( 1.0f - fade ) * pMix_mat_re_prev[ch_idx1][0]; + mix_mat_re[ch_idx1][1] = fade * ( hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][1] ) + + ( 1.0f - fade ) * pMix_mat_re_prev[ch_idx1][1]; + + mix_mat_im[ch_idx1][0] = fade * ( hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][0] ) + + ( 1.0f - fade ) * pMix_mat_im_prev[ch_idx1][0]; + mix_mat_im[ch_idx1][1] = fade * ( hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][1] ) + + ( 1.0f - fade ) * pMix_mat_im_prev[ch_idx1][1]; + } + else + { + mix_mat_re[ch_idx1][0] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][0]; + mix_mat_re[ch_idx1][1] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][1]; + mix_mat_im[ch_idx1][0] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][0]; + mix_mat_im[ch_idx1][1] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][1]; + } +#endif + } + +#ifndef SPLIT_REND_ZERO_OUT_YAW_D +#ifdef SPLIT_REND_PLC + if ( hBinPostRenderer->cf_flag ) + { + gd_cf = fade * rot_md_act[pos_idx][b].gd + + ( 1 - fade ) * hBinPostRenderer->gd_mem[pos_idx][b]; + } + else + { + gd_cf = rot_md_act[pos_idx][b].gd; + } +#else + if ( hBinPostRenderer->cf_flag ) + { + gd_cf = fade * hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd + + ( 1 - fade ) * hBinPostRenderer->gd_mem[pos_idx][b]; + } + else + { + gd_cf = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd; + } +#endif + + gd_cf_abs = (float) fabs( gd_cf ); +#endif + + brange[0] = pBand_grouping[b]; + brange[1] = pBand_grouping[b + 1]; + for ( b2 = brange[0]; b2 < brange[1]; b2++ ) + { + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + // Apply prediction matrix + IVAS_CMULT_FLOAT( Cldfb_RealBuffer_Ref_Binaural[0][index_slot][b2], + Cldfb_ImagBuffer_Ref_Binaural[0][index_slot][b2], + mix_mat_re[0][ch_idx1], + mix_mat_im[0][ch_idx1], + tmp_re, + tmp_im ); + pred_out_re[ch_idx1] = tmp_re; + pred_out_im[ch_idx1] = tmp_im; + + IVAS_CMULT_FLOAT( Cldfb_RealBuffer_Ref_Binaural[1][index_slot][b2], + Cldfb_ImagBuffer_Ref_Binaural[1][index_slot][b2], + mix_mat_re[1][ch_idx1], + mix_mat_im[1][ch_idx1], + tmp_re, + tmp_im ); + pred_out_re[ch_idx1] += tmp_re; + pred_out_im[ch_idx1] += tmp_im; + } + +#ifndef SPLIT_REND_ZERO_OUT_YAW_D + // Apply decorrelation + if ( 1 ) + { + tmp_re = Cldfb_RealBuffer_Ref_Binaural[0][index_slot][b2] + Cldfb_RealBuffer_Ref_Binaural[1][index_slot][b2]; + tmp_im = Cldfb_ImagBuffer_Ref_Binaural[0][index_slot][b2] + Cldfb_ImagBuffer_Ref_Binaural[1][index_slot][b2]; + + pred_out_re[0] += ( gd_cf_abs * tmp_re ); + pred_out_im[0] += ( gd_cf_abs * tmp_im ); + pred_out_re[1] += ( gd_cf * tmp_re ); + pred_out_im[1] += ( gd_cf * tmp_im ); + } +#endif + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + Cldfb_RealBuffer_Recons_Binaural[pos_idx][ch_idx1][index_slot][b2] = pred_out_re[ch_idx1]; + Cldfb_ImagBuffer_Recons_Binaural[pos_idx][ch_idx1][index_slot][b2] = pred_out_im[ch_idx1]; +#else + Cldfb_RealBuffer_Ref_Binaural[ch_idx1][index_slot][b2] = pred_out_re[ch_idx1]; + Cldfb_ImagBuffer_Ref_Binaural[ch_idx1][index_slot][b2] = pred_out_im[ch_idx1]; +#endif + } + } + } + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) +#else + pos_idx = 0; +#endif + { +#ifdef SPLIT_REND_PLC + for ( b = 0; b < num_md_bands; b++ ) + { + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + hBinPostRenderer->mixer_mat_re[pos_idx][b][ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][0]; + hBinPostRenderer->mixer_mat_re[pos_idx][b][ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][1]; + hBinPostRenderer->mixer_mat_im[pos_idx][b][ch_idx1][0] = rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][0]; + hBinPostRenderer->mixer_mat_im[pos_idx][b][ch_idx1][1] = rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][1]; + } + hBinPostRenderer->gd_mem[pos_idx][b] = rot_md_act[pos_idx][b].gd; + } +#else + for ( b = 0; b < num_md_bands; b++ ) + { + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + hBinPostRenderer->mixer_mat_re[pos_idx][b][ch_idx1][0] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][0]; + hBinPostRenderer->mixer_mat_re[pos_idx][b][ch_idx1][1] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][1]; + hBinPostRenderer->mixer_mat_im[pos_idx][b][ch_idx1][0] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][0]; + hBinPostRenderer->mixer_mat_im[pos_idx][b][ch_idx1][1] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][1]; + } + hBinPostRenderer->gd_mem[pos_idx][b] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd; + } +#endif + } + hBinPostRenderer->cf_flag = 1; + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + { + int16_t num_cldfb_bands; + num_cldfb_bands = CLDFB_NO_CHANNELS_MAX; + for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) + { + index_slot = sf_idx * num_slots + slot_idx; + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + mvr2r( Cldfb_RealBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES - 1][ch_idx1][index_slot], Cldfb_RealBuffer_Ref_Binaural[ch_idx1][index_slot], num_cldfb_bands ); + mvr2r( Cldfb_ImagBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES - 1][ch_idx1][index_slot], Cldfb_ImagBuffer_Ref_Binaural[ch_idx1][index_slot], num_cldfb_bands ); + } + } + + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + char fname[200] = "recons_out_pos"; + char tag[2]; + tag[0] = (char) ( '0' + pos_idx ); + tag[1] = '\0'; + strcat( fname, tag ); + strcat( fname, ".wav" ); + ivas_log_cldfb2wav_data( + Cldfb_RealBuffer_Recons_Binaural[pos_idx], + Cldfb_ImagBuffer_Recons_Binaural[pos_idx], + hBinPostRenderer->cldfbSynReconsBinDec[pos_idx], + BINAURAL_CHANNELS, + num_cldfb_bands, + 48000, + num_slots, + sf_idx * num_slots, + fname ); + } + } +#endif + } + + pop_wmops(); + return; +} + +static void ivas_rend_CldfbSplitPostRendProcessTdIn( + BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES], + float output[][L_FRAME48k] ) +{ + int16_t ch_idx, slot_idx, num_cldfb_bands; + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + num_cldfb_bands = hBinHrSplitPostRend->cldfbSyn[0]->no_channels; + + /* Implement CLDFB analysis */ + for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) + { + cldfbAnalysis_ts( &( output[ch_idx][num_cldfb_bands * slot_idx] ), + Cldfb_RealBuffer_Binaural[ch_idx][slot_idx], + Cldfb_ImagBuffer_Binaural[ch_idx][slot_idx], + num_cldfb_bands, + hBinHrSplitPostRend->cldfbAna[ch_idx] ); + } + } + + ivas_SplitRenderer_PostRenderer( + hBinHrSplitPostRend, + pMultiBinPoseData, + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural, + QuaternionsPost ); + + /* Implement CLDFB synthesis */ + for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + float *RealBuffer[CLDFB_NO_COL_MAX]; + float *ImagBuffer[CLDFB_NO_COL_MAX]; + + for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) + { + RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[ch_idx][slot_idx]; + ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[ch_idx][slot_idx]; + } + + cldfbSynthesis( RealBuffer, ImagBuffer, &( output[ch_idx][0] ), num_cldfb_bands * CLDFB_NO_COL_MAX, hBinHrSplitPostRend->cldfbSyn[ch_idx] ); + } + return; +} + +void ivas_rend_CldfbSplitPostRendProcess( + BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES], + float Cldfb_RealBuffer_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float output[][L_FRAME48k], + const int16_t is_cldfb_in ) +{ + int16_t ch_idx, slot_idx, num_cldfb_bands; + + push_wmops( "ivas_rend_CldfbSplitPostRendProcess" ); + + num_cldfb_bands = hBinHrSplitPostRend->cldfbSyn[0]->no_channels; + + if ( is_cldfb_in == 0 ) + { + ivas_rend_CldfbSplitPostRendProcessTdIn( hBinHrSplitPostRend, pMultiBinPoseData, QuaternionsPost, output ); + pop_wmops(); + return; + } + + ivas_SplitRenderer_PostRenderer( + hBinHrSplitPostRend, + pMultiBinPoseData, + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural, + QuaternionsPost ); + + /* Implement CLDFB synthesis */ + for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + float *RealBuffer[CLDFB_NO_COL_MAX]; + float *ImagBuffer[CLDFB_NO_COL_MAX]; + + for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) + { + RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[ch_idx][slot_idx]; + ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[ch_idx][slot_idx]; + } + + cldfbSynthesis( RealBuffer, ImagBuffer, &( output[ch_idx][0] ), num_cldfb_bands * CLDFB_NO_COL_MAX, hBinHrSplitPostRend->cldfbSyn[ch_idx] ); + } + + pop_wmops(); + + return; +} + +void ivas_init_split_post_rend_handles( SPLIT_POST_REND_WRAPPER *hSplitRendWrapper ) +{ + hSplitRendWrapper->hBinHrSplitPostRend = NULL; + hSplitRendWrapper->hSplitBinLCLDDec = NULL; +#ifdef SPLIT_REND_LC3PLUS + hSplitRendWrapper->hLc3plusDec = NULL; +#endif + ivas_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData ); +#ifdef SPLIT_REND_PLC + hSplitRendWrapper->first_good_frame_received = 0; +#endif + return; +} +#endif diff --git a/lib_rend/ivas_splitRendererPre.c b/lib_rend/ivas_splitRendererPre.c new file mode 100644 index 0000000000000000000000000000000000000000..2c213b0d98fc775f67a9f6d9ebe27a16693bb0ac --- /dev/null +++ b/lib_rend/ivas_splitRendererPre.c @@ -0,0 +1,2220 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#include +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +#include +#endif +#include "ivas_prot.h" +#include "prot.h" +#include "cnst.h" +#include "ivas_cnst.h" +#include "ivas_rom_rend.h" +#include "ivas_rom_com.h" +#include "ivas_rom_dec.h" +#include "ivas_rom_binauralRenderer.h" +#include "lib_rend.h" +#include "ivas_prot_rend.h" +#ifdef SPLIT_REND_LC3PLUS +#include "ivas_lc3plus_enc.h" +#endif +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + + +#ifdef SPLIT_REND_WITH_HEAD_ROT +#define MAX_BAND_SMOOTH ( 1 ) +#define SMOOTH_NORM_FACTOR ( 5.0f ) + +static void ivas_calc_mat_det_2by2_complex( float in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + float in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + float *det_re, + float *det_im ) +{ + float re1, im1, re2, im2; + IVAS_CMULT_FLOAT( in_re[0][0], in_im[0][0], in_re[1][1], in_im[1][1], re1, im1 ); + IVAS_CMULT_FLOAT( in_re[0][1], in_im[0][1], in_re[1][0], in_im[1][0], re2, im2 ); + *det_re = re1 - re2; + *det_im = im1 - im2; + return; +} + +static int16_t ivas_is_mat_inv_2by2_complex( float in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + float in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS] ) +{ + int16_t is_det_zero = 1; + float det, det_re, det_im; + ivas_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im ); + det = ( ( det_re * det_re ) + ( det_im * det_im ) ); + if ( det < EPSILON ) + { + is_det_zero = 0; + } + return is_det_zero; +} + +static void ivas_calc_mat_inv_2by2_complex( + float in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + float in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + float out_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + float out_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS] ) +{ + float det_re, det_im; + float re, im, det; + ivas_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im ); + det = ( det_re * det_re ) + ( det_im * det_im ); + // assert to catch cases when input is singular matrix + assert( det > 0 ); + det = 1 / det; + + IVAS_CMULT_FLOAT( det_re, -det_im, in_re[1][1], in_im[1][1], re, im ); + out_re[0][0] = re * det; + out_im[0][0] = im * det; + + IVAS_CMULT_FLOAT( det_re, -det_im, in_re[0][1], in_im[0][1], re, im ); + out_re[0][1] = -re * det; + out_im[0][1] = -im * det; + IVAS_CMULT_FLOAT( det_re, -det_im, in_re[1][0], in_im[1][0], re, im ); + out_re[1][0] = -re * det; + out_im[1][0] = -im * det; + IVAS_CMULT_FLOAT( det_re, -det_im, in_re[0][0], in_im[0][0], re, im ); + out_re[1][1] = re * det; + out_im[1][1] = im * det; + return; +} + +static void ComputePredMat( + float cov_ii_re[][BINAURAL_CHANNELS], + float cov_ii_im[][BINAURAL_CHANNELS], + float cov_io_re[][BINAURAL_CHANNELS], + float cov_io_im[][BINAURAL_CHANNELS], + float pred_mat_re[][BINAURAL_CHANNELS], + float pred_mat_im[][BINAURAL_CHANNELS], + int16_t num_chs, + int16_t real_only ) +{ + float cov_ii_local_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + // float cov_ii_local_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float cov_ii_inv_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float cov_ii_inv_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float trace_cov; + int16_t i, j; + + trace_cov = 0.0f; + for ( i = 0; i < num_chs; i++ ) + { + trace_cov += cov_ii_re[i][i]; + } + trace_cov = max( 0.0f, trace_cov ); + if ( trace_cov < EPSILON ) + { + for ( i = 0; i < num_chs; i++ ) + { + /* protection from cases when variance of ref channels is very small */ + set_zero( pred_mat_re[i], BINAURAL_CHANNELS ); + set_zero( pred_mat_im[i], BINAURAL_CHANNELS ); + } + return; + } + + for ( i = 0; i < num_chs; i++ ) + { + mvr2r( cov_ii_re[i], cov_ii_local_re[i], num_chs ); + // mvr2r( cov_ii_im[i], cov_ii_local_im[i], num_chs ); + } + for ( i = 0; i < num_chs; i++ ) + { + cov_ii_local_re[i][i] = cov_ii_re[i][i] + ( trace_cov * 0.0001f ); + // cov_ii_local_im[i][i] = cov_ii_im[i][i] + ( trace_cov * 0.0005f ); + } + + // float det_re, det_im, det; + // ivas_calc_mat_det_2by2_complex( cov_ii_local_re, cov_ii_im, &det_re, &det_im ); + // det = ( ( det_re * det_re ) + ( det_im * det_im ) ); + // det = sqrtf( det ); + // if ( ivas_is_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im ) ) + // if ( det > 0.0001f ) + if ( ivas_is_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im ) ) + { + ivas_calc_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im, cov_ii_inv_re, cov_ii_inv_im ); + ivas_mat_mult_2by2_complex( cov_ii_inv_re, cov_ii_inv_im, cov_io_re, cov_io_im, + pred_mat_re, pred_mat_im ); + } + else + { + // float max_var; + int16_t max_var_idx; + for ( i = 0; i < num_chs; i++ ) + { + set_zero( pred_mat_re[i], BINAURAL_CHANNELS ); + set_zero( pred_mat_im[i], BINAURAL_CHANNELS ); + } + + max_var_idx = 0; + // max_var = cov_ii_local_re[0][0]; + if ( cov_ii_local_re[1][1] > cov_ii_local_re[0][0] ) + { + max_var_idx = 1; + // max_var = cov_ii_local_re[1][1]; + } + + if ( cov_ii_local_re[max_var_idx][max_var_idx] > EPSILON ) + { + for ( j = 0; j < num_chs; j++ ) + { + pred_mat_re[max_var_idx][j] = cov_io_re[max_var_idx][j] / cov_ii_local_re[max_var_idx][max_var_idx]; + pred_mat_im[max_var_idx][j] = cov_io_im[max_var_idx][j] / cov_ii_local_re[max_var_idx][max_var_idx]; + } + } + } + + if ( real_only ) + { + for ( i = 0; i < num_chs; i++ ) + { + set_zero( pred_mat_im[i], BINAURAL_CHANNELS ); + } + } + + return; +} + +static void ComputePostPredCov( + float cov_ii_re[][BINAURAL_CHANNELS], + float cov_ii_im[][BINAURAL_CHANNELS], + float pred_mat_re[][BINAURAL_CHANNELS], + float pred_mat_im[][BINAURAL_CHANNELS], + float postpred_cov_re[][BINAURAL_CHANNELS], + float postpred_cov_im[][BINAURAL_CHANNELS], + int16_t num_chs ) +{ + int16_t i, j; + float dmx_mat_conj_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float dmx_mat_conj_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float temp_mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float temp_mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + + assert( num_chs == BINAURAL_CHANNELS ); + for ( i = 0; i < num_chs; i++ ) + { + for ( j = 0; j < num_chs; j++ ) + { + dmx_mat_conj_re[i][j] = pred_mat_re[j][i]; + dmx_mat_conj_im[i][j] = -pred_mat_im[j][i]; + + temp_mat_re[i][j] = pred_mat_re[i][j]; + temp_mat_im[i][j] = pred_mat_im[i][j]; + } + set_zero( postpred_cov_re[i], BINAURAL_CHANNELS ); + set_zero( postpred_cov_im[i], BINAURAL_CHANNELS ); + } + + /* 2x2 mult */ + ivas_mat_mult_2by2_complex( dmx_mat_conj_re, dmx_mat_conj_im, cov_ii_re, cov_ii_im, + temp_mat_re, temp_mat_im ); + ivas_mat_mult_2by2_complex( temp_mat_re, temp_mat_im, pred_mat_re, pred_mat_im, + postpred_cov_re, postpred_cov_im ); + + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + for ( j = 0; j < i; j++ ) + { + postpred_cov_re[i][j] = postpred_cov_re[j][i]; + postpred_cov_im[i][j] = -postpred_cov_im[j][i]; + } + postpred_cov_im[i][i] = 0; + } + + return; +} + +static void ComputeBandedCrossCov( + float Cldfb_RealBuffer1[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer1[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_RealBuffer2[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer2[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float out_cov_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + float out_cov_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + const int16_t num_chs, + const int16_t *pBand_grouping, + const int16_t num_slots, + const int16_t start_slot_idx, + const int16_t md_band_idx, + const int16_t real_only ) +{ + int16_t sf, cldfb_band_idx, ch_idx1, ch_idx2; + int16_t brange[2]; + + for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + { + set_f( out_cov_re[ch_idx1], 0.0f, num_chs ); + set_f( out_cov_im[ch_idx1], 0.0f, num_chs ); + } + brange[0] = pBand_grouping[md_band_idx]; + brange[1] = pBand_grouping[md_band_idx + 1]; + for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + { + for ( ch_idx2 = 0; ch_idx2 < num_chs; ch_idx2++ ) + { + if ( real_only == 0 ) + { + for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + { + for ( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ ) + { + out_cov_re[ch_idx1][ch_idx2] += + Cldfb_RealBuffer1[ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer2[ch_idx2][sf][cldfb_band_idx] + + Cldfb_ImagBuffer1[ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer2[ch_idx2][sf][cldfb_band_idx]; + + out_cov_im[ch_idx1][ch_idx2] += + Cldfb_RealBuffer1[ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer2[ch_idx2][sf][cldfb_band_idx] - + Cldfb_ImagBuffer1[ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer2[ch_idx2][sf][cldfb_band_idx]; + } + } + } + else + { + for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + { + for ( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ ) + { + out_cov_re[ch_idx1][ch_idx2] += + Cldfb_RealBuffer1[ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer2[ch_idx2][sf][cldfb_band_idx] + + Cldfb_ImagBuffer1[ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer2[ch_idx2][sf][cldfb_band_idx]; + + out_cov_im[ch_idx1][ch_idx2] = 0.0f; + } + } + } + } + } + + + return; +} + +static void ComputeBandedCov( + float Cldfb_RealBuffer[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_ImagBuffer[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float out_cov_re[][BINAURAL_CHANNELS], + float out_cov_im[][BINAURAL_CHANNELS], + const int16_t num_chs, + const int16_t *pBand_grouping, + const int16_t num_slots, + const int16_t start_slot_idx, + const int16_t md_band_idx, + const int16_t real_only ) +{ + int16_t sf, cldfb_band_idx, ch_idx1, ch_idx2; + int16_t brange[2]; + + for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + { + set_f( out_cov_re[ch_idx1], 0.0f, num_chs ); + set_f( out_cov_im[ch_idx1], 0.0f, num_chs ); + } + brange[0] = pBand_grouping[md_band_idx]; + brange[1] = pBand_grouping[md_band_idx + 1]; + for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + { + for ( ch_idx2 = 0; ch_idx2 <= ch_idx1; ch_idx2++ ) + { + if ( ( ch_idx2 != ch_idx1 ) && ( real_only == 0 ) ) + { + for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + { + for ( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ ) + { + out_cov_re[ch_idx1][ch_idx2] += + Cldfb_RealBuffer[ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer[ch_idx2][sf][cldfb_band_idx] + + Cldfb_ImagBuffer[ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer[ch_idx2][sf][cldfb_band_idx]; + + out_cov_im[ch_idx1][ch_idx2] += + Cldfb_RealBuffer[ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer[ch_idx2][sf][cldfb_band_idx] - + Cldfb_ImagBuffer[ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer[ch_idx2][sf][cldfb_band_idx]; + } + } + } + else + { + for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + { + for ( cldfb_band_idx = brange[0]; cldfb_band_idx < brange[1]; cldfb_band_idx++ ) + { + out_cov_re[ch_idx1][ch_idx2] += + Cldfb_RealBuffer[ch_idx1][sf][cldfb_band_idx] * Cldfb_RealBuffer[ch_idx2][sf][cldfb_band_idx] + + Cldfb_ImagBuffer[ch_idx1][sf][cldfb_band_idx] * Cldfb_ImagBuffer[ch_idx2][sf][cldfb_band_idx]; + + out_cov_im[ch_idx1][ch_idx2] = 0.0f; + } + } + } + } + } + + for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + { + for ( ch_idx2 = ch_idx1 + 1; ch_idx2 < num_chs; ch_idx2++ ) + { + out_cov_re[ch_idx1][ch_idx2] = out_cov_re[ch_idx2][ch_idx1]; + out_cov_im[ch_idx1][ch_idx2] = -out_cov_im[ch_idx2][ch_idx1]; + } + } + + + return; +} + +static float GetNormFact( + float cov_ii_re[][BINAURAL_CHANNELS], + float cov_ii_im[][BINAURAL_CHANNELS], + float cov_io_re[][BINAURAL_CHANNELS], + float cov_io_im[][BINAURAL_CHANNELS], + float cov_oo_re[][BINAURAL_CHANNELS] ) +{ + int16_t i, j; + float norm_fact, abs_val; + + norm_fact = 0.0f; + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + IVAS_CALCULATE_ABS( cov_ii_re[i][j], cov_ii_im[i][j], abs_val ); + norm_fact = max( norm_fact, abs_val ); + + IVAS_CALCULATE_ABS( cov_io_re[i][j], cov_io_im[i][j], abs_val ); + norm_fact = max( norm_fact, abs_val ); + + IVAS_CALCULATE_RABS( cov_oo_re[i][j], abs_val ); + norm_fact = max( norm_fact, abs_val ); + } + } + + norm_fact = ( norm_fact > EPSILON ) ? norm_fact : 1.0f; + + norm_fact = PCM16_TO_FLT_FAC / norm_fact; + + return norm_fact; +} + +static void ivas_split_rend_huffman_encode( + ivas_split_rend_huffman_cfg_t *huff_cfg, + int16_t in, + int32_t *hcode, + int32_t *hlen ) +{ + int32_t min_sym_val; + const int32_t *codebook; + + min_sym_val = huff_cfg->codebook[0]; + + codebook = &huff_cfg->codebook[3 * ( in - min_sym_val )]; + *hlen = codebook[1]; + *hcode = codebook[2]; + + return; +} + +static void ivas_split_rend_quant_md( + BIN_HR_SPLIT_REND_MD_HANDLE hMd, + IVAS_SPLIT_REND_POSE_TYPE pose_type, + int16_t real_only, + float fix_pos_rot_mat[][BINAURAL_CHANNELS] ) +{ + int16_t ch1, ch2; + int16_t gd_idx_min; + float sign, quant_val; + + if ( pose_type == PRED_ONLY ) + { + if ( real_only == 1 ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sign = ( hMd->pred_mat_re[ch1][ch2] >= 0.0f ) ? 1.0f : -1.0f; + IVAS_CALCULATE_ABS( hMd->pred_mat_re[ch1][ch2], hMd->pred_mat_im[ch1][ch2], hMd->pred_mat_re[ch1][ch2] ); + hMd->pred_mat_re[ch1][ch2] *= sign; + hMd->pred_mat_im[ch1][ch2] = 0.0f; + } + } + } + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + quant_val = hMd->pred_mat_re[ch1][ch2] - fix_pos_rot_mat[ch1][ch2]; + quant_val = min( IVAS_SPLIT_REND_PRED_MAX_VAL, max( quant_val, IVAS_SPLIT_REND_PRED_MIN_VAL ) ); + hMd->pred_mat_re_idx[ch1][ch2] = (int16_t) roundf( IVAS_SPLIT_REND_PRED_1BYQ_STEP * quant_val ); + // hMd->pred_mat_re[ch1][ch2] = hMd->pred_mat_re_idx[ch1][ch2] * IVAS_SPLIT_REND_PRED_Q_STEP; + } + } + if ( real_only == 0 ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + quant_val = min( IVAS_SPLIT_REND_PRED_MAX_VAL, max( hMd->pred_mat_im[ch1][ch2], IVAS_SPLIT_REND_PRED_MIN_VAL ) ); + hMd->pred_mat_im_idx[ch1][ch2] = (int16_t) roundf( IVAS_SPLIT_REND_PRED_1BYQ_STEP * quant_val ); + // hMd->pred_mat_im[ch1][ch2] = hMd->pred_mat_im_idx[ch1][ch2] * IVAS_SPLIT_REND_PRED_Q_STEP; + } + } + } + } + else if ( pose_type == COM_GAIN_ONLY ) + { + quant_val = min( IVAS_SPLIT_REND_D_MAX_VAL, max( hMd->gd, IVAS_SPLIT_REND_D_MIN_VAL ) ); + gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_D_1BYQ_STEP * IVAS_SPLIT_REND_D_MIN_VAL ); + hMd->gd_idx = (int16_t) roundf( IVAS_SPLIT_REND_D_1BYQ_STEP * quant_val ); + hMd->gd = hMd->gd_idx * IVAS_SPLIT_REND_D_Q_STEP; + hMd->gd_idx = hMd->gd_idx - gd_idx_min; + } + else if ( pose_type == LR_GAIN_ONLY ) + { + quant_val = min( IVAS_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd, IVAS_SPLIT_REND_PITCH_G_MIN_VAL ) ); + gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * IVAS_SPLIT_REND_PITCH_G_MIN_VAL ); + hMd->gd_idx = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val ); + // hMd->gd = hMd->gd_idx * IVAS_SPLIT_REND_PITCH_G_Q_STEP; + hMd->gd_idx = hMd->gd_idx - gd_idx_min; + + quant_val = min( IVAS_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd2, IVAS_SPLIT_REND_PITCH_G_MIN_VAL ) ); + hMd->gd2_idx = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val ); + // hMd->gd2 = hMd->gd2_idx * IVAS_SPLIT_REND_PITCH_G_Q_STEP; + hMd->gd2_idx = hMd->gd2_idx - gd_idx_min; + } + + return; +} + + +static void ComputeCoeffs( + float cov_ii_re[][BINAURAL_CHANNELS], + float cov_ii_im[][BINAURAL_CHANNELS], + float cov_io_re[][BINAURAL_CHANNELS], + float cov_io_im[][BINAURAL_CHANNELS], + float cov_oo_re[][BINAURAL_CHANNELS], + BIN_HR_SPLIT_REND_MD_HANDLE hMd, + IVAS_SPLIT_REND_POSE_TYPE pose_type, + int16_t real_only ) +{ + float postpred_cov_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float postpred_cov_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float cov_ii_norm_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float cov_ii_norm_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float cov_io_norm_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float cov_io_norm_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float cov_oo_norm_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float sigma_d, rho_hat, rho, gd, gd2, gl2, gr2, cov_norm_fact; + float aa, bb, cc, dd, sign; + int16_t i, j; + + if ( pose_type == PITCH_ONLY ) + { +#if 0 + float gd_tmp; + + gd_tmp = cov_ii_re[0][0] + cov_ii_re[1][1]; + if ( gd_tmp < EPSILON ) + { + hMd->gd = 1.0f; + } + else + { + gd_tmp = ( cov_oo_re[0][0] + cov_oo_re[1][1] ) / gd_tmp; + hMd->gd = sqrtf( gd_tmp ); + } +#else + float gd_tmp[BINAURAL_CHANNELS]; + + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + gd_tmp[i] = cov_ii_re[i][i]; + if ( gd_tmp[i] < EPSILON ) + { + gd_tmp[i] = 1.0f; + } + else + { + gd_tmp[i] = ( cov_oo_re[i][i] ) / gd_tmp[i]; + gd_tmp[i] = sqrtf( gd_tmp[i] ); + } + } + hMd->gd = gd_tmp[0]; + hMd->gd2 = gd_tmp[1]; + +#endif + } + else + { + cov_norm_fact = GetNormFact( + cov_ii_re, + cov_ii_im, + cov_io_re, + cov_io_im, + cov_oo_re ); + + // normalize the covariance + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + cov_ii_norm_re[i][j] = cov_ii_re[i][j] * cov_norm_fact; + cov_ii_norm_im[i][j] = cov_ii_im[i][j] * cov_norm_fact; + cov_io_norm_re[i][j] = cov_io_re[i][j] * cov_norm_fact; + cov_io_norm_im[i][j] = cov_io_im[i][j] * cov_norm_fact; + cov_oo_norm_re[i][j] = cov_oo_re[i][j] * cov_norm_fact; + } + } + + ComputePredMat( cov_ii_norm_re, + cov_ii_norm_im, + cov_io_norm_re, + cov_io_norm_im, + hMd->pred_mat_re, + hMd->pred_mat_im, + BINAURAL_CHANNELS, + real_only ); + + + /*TODO : change this function to real only as thats what is needed*/ + ComputePostPredCov( cov_ii_norm_re, + cov_ii_norm_im, + hMd->pred_mat_re, + hMd->pred_mat_im, + postpred_cov_re, + postpred_cov_im, + BINAURAL_CHANNELS ); + + // normalize everything to +-1 range + gd = 1.0f / ( PCM16_TO_FLT_FAC ); + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + postpred_cov_re[i][j] *= gd; + cov_ii_norm_re[i][j] = cov_ii_norm_re[i][j] * gd; + cov_oo_norm_re[i][j] = cov_oo_norm_re[i][j] * gd; + } + } + +#ifdef SPLIT_REND_ZERO_OUT_YAW_D + if ( 1 ) +#else + if ( pose_type != ANY_YAW ) +#endif + { + gd2 = 0.0f; + sigma_d = 0.0f; + hMd->gd = 0.0f; + } + else + { + + sigma_d = cov_ii_norm_re[0][0] + cov_ii_norm_re[1][1] + cov_ii_norm_re[0][1] + cov_ii_norm_re[1][0] + EPSILON; + + rho_hat = max( EPSILON, sqrtf( postpred_cov_re[0][0] * postpred_cov_re[1][1] ) ); + rho_hat = postpred_cov_re[0][1] / rho_hat; + rho = max( EPSILON, sqrtf( cov_oo_norm_re[0][0] * cov_oo_norm_re[1][1] ) ); + rho = cov_oo_norm_re[0][1] / rho; + rho_hat = min( max( rho_hat, -0.9999f ), 0.9999f ); + rho = min( max( rho, -0.9999f ), 0.9999f ); + + // Compute decorrelator gain : gd2 = 0; + gd = 0; + gd2 = 0; + + aa = ( sigma_d * sigma_d ) * ( ( rho_hat * rho_hat ) - 1 ) + EPSILON; + bb = -( rho_hat * rho_hat ) * sigma_d * ( cov_oo_norm_re[0][0] + cov_oo_norm_re[1][1] ); + cc = ( rho_hat * rho_hat ) * cov_oo_norm_re[0][0] * cov_oo_norm_re[1][1]; + cc -= cov_oo_norm_re[0][1] * cov_oo_norm_re[0][1]; + + sign = +1.0f; + if ( rho < ( rho_hat - 0.0001 ) ) + { + bb -= 2 * sigma_d * cov_oo_norm_re[0][1]; + sign = -1.0f; + } + else if ( rho > ( rho_hat + 0.0001 ) ) + { + bb += 2 * sigma_d * cov_oo_norm_re[0][1]; + } + dd = bb * bb - ( 4 * aa * cc ); + if ( dd >= 0 ) + { + float gd2_1, gd2_2; + gd2_1 = ( -bb + sqrtf( dd ) ) / ( 2 * aa ); + gd2_2 = ( -bb - sqrtf( dd ) ) / ( 2 * aa ); + if ( ( gd2_1 >= 0 ) && ( gd2_2 >= 0 ) ) + { + gd2 = min( gd2_1, gd2_2 ); + } + else + { + gd2 = max( 0, max( gd2_1, gd2_2 ) ); + } + gd = sign * sqrtf( gd2 ); + } + + gd = min( IVAS_SPLIT_REND_D_MAX_VAL, max( gd, IVAS_SPLIT_REND_D_MIN_VAL ) ); + hMd->gd = SPLIT_REND_DECOR_ALPHA * gd + ( 1 - SPLIT_REND_DECOR_ALPHA ) * hMd->gd; + gd2 = min( gd2, cov_oo_norm_re[0][0] / sigma_d ); + gd2 = min( gd2, cov_oo_norm_re[1][1] / sigma_d ); + } + + if ( postpred_cov_re[0][0] > EPSILON ) + { + gl2 = ( cov_oo_norm_re[0][0] - ( gd2 * sigma_d ) ) / max( EPSILON, postpred_cov_re[0][0] ); + gl2 = max( gl2, 1.0f ); + gl2 = sqrtf( gl2 ); + } + else + { + gl2 = 1.0f; + } + if ( postpred_cov_re[1][1] > EPSILON ) + { + gr2 = ( cov_oo_norm_re[1][1] - ( gd2 * sigma_d ) ) / max( EPSILON, postpred_cov_re[1][1] ); + gr2 = max( gr2, 1.0f ); + gr2 = sqrtf( gr2 ); + } + else + { + gr2 = 1.0f; + } + + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + hMd->pred_mat_re[i][0] *= gl2; + hMd->pred_mat_re[i][1] *= gr2; + } + if ( real_only == 0 ) + { + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + hMd->pred_mat_im[i][0] *= gl2; + hMd->pred_mat_im[i][1] *= gr2; + } + } + } + return; +} + +static void get_base2_bits( + const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int16_t num_subframes, + const int16_t num_quant_strats, + const int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + const int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + const int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + const int16_t bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + const int16_t pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + const int16_t pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int32_t base2bits[IVAS_SPLIT_REND_NUM_QUANT_STRATS] ) +{ + int16_t pred_bits, d_gain_bits, pitch_gain_bits, pose_idx, q; + IVAS_SPLIT_REND_POSE_TYPE pose_type; + + pred_bits = (int16_t) ceilf( log2f( IVAS_SPLIT_REND_PRED_QUANT_PNTS ) ); + d_gain_bits = (int16_t) ceilf( log2f( IVAS_SPLIT_REND_D_QUANT_PNTS ) ); + pitch_gain_bits = d_gain_bits; + + for ( q = 0; q < num_quant_strats; q++ ) + { + base2bits[q] = 0; + } + + for ( q = 0; q < num_quant_strats; q++ ) + { + for ( pose_idx = 0; pose_idx < pMultiBinPoseData->num_poses - 1; pose_idx++ ) + { + pose_type = hBinHrSplitPreRend->pose_type[pose_idx]; + if ( pose_type == ANY_YAW ) + { + base2bits[q] += pred_bits * pred_real_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; + base2bits[q] += pred_bits * pred_imag_bands_yaw[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; + base2bits[q] += d_gain_bits * d_bands_yaw[q] * num_subframes; + } + else if ( pose_type == PITCH_ONLY ) + { + base2bits[q] += pitch_gain_bits * bands_pitch[q] * num_subframes; + base2bits[q] += pitch_gain_bits * bands_pitch[q] * num_subframes; + } + else + { + base2bits[q] += pred_bits * pred_real_bands_roll[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; + base2bits[q] += pred_bits * pred_imag_bands_roll[q] * num_subframes * BINAURAL_CHANNELS * BINAURAL_CHANNELS; + } + } + } + + return; +} + +static void ivas_SplitRenderer_code_md_base2( + const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int16_t num_subframes, + const int16_t pred_real_bands_yaw, + const int16_t pred_imag_bands_yaw, + const int16_t d_bands_yaw, + const int16_t bands_pitch, + const int16_t pred_real_bands_roll, + const int16_t pred_imag_bands_roll, + ivas_split_rend_bits_t *pBits ) +{ + int16_t pos_idx, b, ch1, ch2, sf_idx; + int16_t min_pred_idx, min_gd_idx, min_p_gd_idx, pred_code_len, gd_code_len, p_gd_code_len, num_poses; + int32_t code; + BIN_HR_SPLIT_REND_MD_HANDLE hMd; + BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; + pHuff_cfg = &hBinHrSplitPreRend->huff_cfg; + min_pred_idx = (int16_t) pHuff_cfg->pred.codebook[0]; + min_gd_idx = (int16_t) pHuff_cfg->gd.codebook[0]; + min_p_gd_idx = (int16_t) pHuff_cfg->p_gd.codebook[0]; + pred_code_len = pHuff_cfg->pred_base2_code_len; + gd_code_len = pHuff_cfg->gd_base2_code_len; + p_gd_code_len = pHuff_cfg->p_gd_base2_code_len; + + num_poses = pMultiBinPoseData->num_poses; + + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_idx; + ivas_split_rend_bitstream_write_int32( pBits, code, pred_code_len ); + } + } + } + + for ( b = 0; b < pred_imag_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_idx; + ivas_split_rend_bitstream_write_int32( pBits, code, pred_code_len ); + } + } + } + for ( b = 0; b < d_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + code = hMd->gd_idx - min_gd_idx; + ivas_split_rend_bitstream_write_int32( pBits, code, gd_code_len ); + } + } + else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + code = hMd->gd_idx - min_p_gd_idx; + ivas_split_rend_bitstream_write_int32( pBits, code, p_gd_code_len ); + + code = hMd->gd2_idx - min_p_gd_idx; + ivas_split_rend_bitstream_write_int32( pBits, code, p_gd_code_len ); + } + } + else + { + for ( b = 0; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_idx; + ivas_split_rend_bitstream_write_int32( pBits, code, pred_code_len ); + } + } + } + + for ( b = 0; b < pred_imag_bands_roll; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_idx; + ivas_split_rend_bitstream_write_int32( pBits, code, pred_code_len ); + } + } + } + } + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + { + static int num_bits = 0; + static int cntr = 0; + float fnum_bits; + + cntr++; + + num_bits += pBits->bits_written; + // collect bits for every second + if ( cntr == 50 ) + { + cntr = 0; + fnum_bits = (float) num_bits / 1000.0f; + dbgwrite_txt( &fnum_bits, 1, "split_rend_MD_bitrate.txt", "MD bitrate (kbps)" ); + num_bits = 0; + } + } +#endif + return; +} + +static void ivas_SplitRenderer_code_md_huff( + const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int16_t num_subframes, + const int16_t pred_real_bands_yaw, + const int16_t pred_imag_bands_yaw, + const int16_t d_bands_yaw, + const int16_t bands_pitch, + const int16_t pred_real_bands_roll, + const int16_t pred_imag_bands_roll, + ivas_split_rend_bits_t *pBits ) +{ + int16_t pos_idx, b, ch1, ch2, sf_idx, num_poses; + int16_t sym_adj_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + int16_t min_pred_idx, max_pred_idx; + int32_t code, len; + BIN_HR_SPLIT_REND_MD_HANDLE hMd; + BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; + pHuff_cfg = &hBinHrSplitPreRend->huff_cfg; + min_pred_idx = (int16_t) pHuff_cfg->pred.codebook[0]; + max_pred_idx = (int16_t) pHuff_cfg->pred.codebook[( IVAS_SPLIT_REND_PRED_QUANT_PNTS - 1 ) * 3]; + + num_poses = pMultiBinPoseData->num_poses; + + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_idx, max_pred_idx ); + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + ivas_split_rend_huffman_encode( &pHuff_cfg->pred, sym_adj_idx[ch1][ch2], &code, &len ); + ivas_split_rend_bitstream_write_int32( pBits, code, len ); + } + } + } + for ( b = 0; b < pred_imag_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx ); + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + ivas_split_rend_huffman_encode( &pHuff_cfg->pred, sym_adj_idx[ch1][ch2], &code, &len ); + ivas_split_rend_bitstream_write_int32( pBits, code, len ); + } + } + } + for ( b = 0; b < d_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_huffman_encode( &pHuff_cfg->gd, hMd->gd_idx, &code, &len ); + ivas_split_rend_bitstream_write_int32( pBits, code, len ); + } + } + else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd_idx, &code, &len ); + ivas_split_rend_bitstream_write_int32( pBits, code, len ); + + ivas_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd2_idx, &code, &len ); + ivas_split_rend_bitstream_write_int32( pBits, code, len ); + } + } + else + { + for ( b = 0; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_SplitRenderer_getdiagdiff( hMd->pred_mat_re_idx, sym_adj_idx, -1, min_pred_idx, max_pred_idx ); + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + ivas_split_rend_huffman_encode( &pHuff_cfg->pred, sym_adj_idx[ch1][ch2], &code, &len ); + ivas_split_rend_bitstream_write_int32( pBits, code, len ); + } + } + } + for ( b = 0; b < pred_imag_bands_roll; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_SplitRenderer_getdiagdiff( hMd->pred_mat_im_idx, sym_adj_idx, 1, min_pred_idx, max_pred_idx ); + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + ivas_split_rend_huffman_encode( &pHuff_cfg->pred, sym_adj_idx[ch1][ch2], &code, &len ); + ivas_split_rend_bitstream_write_int32( pBits, code, len ); + } + } + } + } + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + { + static int num_bits = 0; + static int cntr = 0; + float fnum_bits; + + cntr++; + num_bits += pBits->bits_written; + // collect bits for every second + if ( cntr == 50 ) + { + cntr = 0; + fnum_bits = (float) num_bits / 1000.0f; + dbgwrite_txt( &fnum_bits, 1, "split_rend_MD_bitrate.txt", "MD bitrate (kbps)" ); + num_bits = 0; + } + } +#endif + return; +} + +static void ivas_SplitRenderer_quant_code( + const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, + const IVAS_QUATERNION headPositions[MAX_PARAM_SPATIAL_SUBFRAMES], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + ivas_split_rend_bits_t *pBits, + const int16_t low_res_pre_rend_rot, + const int32_t target_md_bits ) +{ + int16_t num_complex_bands, q, num_subframes, sf_idx, pos_idx, b, num_quant_strats; + int32_t overhead_bits, quant_strat_bits, huff_bits, start_bit; + int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + int32_t base2bits[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + BIN_HR_SPLIT_REND_MD_HANDLE hMd; + + if ( low_res_pre_rend_rot ) + { + num_subframes = 1; + } + else + { + num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; + } + + overhead_bits = pBits->bits_written; + + // ivas_split_rend_bitstream_write_int32( pBits, low_res_pre_rend_rot, 1 ); + ivas_split_rend_bitstream_write_int32( pBits, pMultiBinPoseData->dof, IVAS_SPLIT_REND_DOF_BITS ); + ivas_split_rend_bitstream_write_int32( pBits, pMultiBinPoseData->hq_mode, IVAS_SPLIT_REND_HQ_MODE_BITS ); + ivas_split_rend_bitstream_write_int32( pBits, (int32_t) pMultiBinPoseData->rot_axis, IVAS_SPLIT_REND_ROT_AXIS_BITS ); + + /* code ref pose*/ + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + int16_t angle; + IVAS_QUATERNION head_pos_euler; + Quat2EulerDegree( headPositions[sf_idx], &head_pos_euler.z, &head_pos_euler.y, &head_pos_euler.x ); + angle = (int16_t) roundf( head_pos_euler.x ); + angle += 180; + ivas_split_rend_bitstream_write_int32( pBits, angle, IVAS_SPLIT_REND_HEAD_POSE_BITS ); + + angle = (int16_t) roundf( head_pos_euler.y ); + angle += 180; + ivas_split_rend_bitstream_write_int32( pBits, angle, IVAS_SPLIT_REND_HEAD_POSE_BITS ); + + angle = (int16_t) roundf( head_pos_euler.z ); + angle += 180; + ivas_split_rend_bitstream_write_int32( pBits, angle, IVAS_SPLIT_REND_HEAD_POSE_BITS ); + } + + ivas_split_rend_get_quant_params( + MAX_SPLIT_REND_MD_BANDS, + pred_real_bands_yaw, + pred_imag_bands_yaw, + d_bands_yaw, + bands_pitch, + pred_real_bands_roll, + pred_imag_bands_roll, + &num_quant_strats, + &num_complex_bands ); + quant_strat_bits = (int32_t) ceilf( log2f( num_quant_strats ) ); + + overhead_bits = pBits->bits_written - overhead_bits + quant_strat_bits + 1; // 1 for base2 vs huff + get_base2_bits( + hBinHrSplitPreRend, + pMultiBinPoseData, + num_subframes, + num_quant_strats, + pred_real_bands_yaw, + pred_imag_bands_yaw, + d_bands_yaw, + bands_pitch, + pred_real_bands_roll, + pred_imag_bands_roll, + base2bits ); + + for ( q = 0; q < num_quant_strats; q++ ) + { + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_imag_bands_yaw[q]; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_quant_md( hMd, + PRED_ONLY, + 0, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx] ); + } + for ( ; b < pred_real_bands_yaw[q]; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_quant_md( hMd, + PRED_ONLY, + 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx] ); + } + for ( b = 0; b < d_bands_yaw[q]; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_quant_md( hMd, + COM_GAIN_ONLY, + 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx] ); + } + } + else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch[q]; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_quant_md( hMd, + LR_GAIN_ONLY, + 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx] ); + } + } + else + { + for ( b = 0; b < pred_imag_bands_roll[q]; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_quant_md( hMd, + PRED_ONLY, + 0, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx] ); + } + for ( ; b < pred_real_bands_roll[q]; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_quant_md( hMd, + PRED_ONLY, + 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx] ); + } + } + } + } + + /*get base2 bits and check if its within target. if yes then code with base2 to save complexity on post renderer*/ + { + start_bit = pBits->bits_written; + ivas_split_rend_bitstream_write_int32( pBits, 1, 1 ); + ivas_split_rend_bitstream_write_int32( pBits, q, quant_strat_bits ); + huff_bits = pBits->bits_written; + ivas_SplitRenderer_code_md_huff( + hBinHrSplitPreRend, + pMultiBinPoseData, + num_subframes, + pred_real_bands_yaw[q], + pred_imag_bands_yaw[q], + d_bands_yaw[q], + bands_pitch[q], + pred_real_bands_roll[q], + pred_imag_bands_roll[q], + pBits ); + huff_bits = pBits->bits_written - huff_bits; + if ( ( target_md_bits >= ( base2bits[q] + overhead_bits ) ) || ( target_md_bits >= ( huff_bits + overhead_bits ) ) || ( q == ( num_quant_strats - 1 ) ) ) + { + if ( huff_bits > base2bits[q] ) + { + pBits->bits_written = start_bit; + ivas_split_rend_bitstream_write_int32( pBits, 0, 1 ); + ivas_split_rend_bitstream_write_int32( pBits, q, quant_strat_bits ); + ivas_SplitRenderer_code_md_base2( + hBinHrSplitPreRend, + pMultiBinPoseData, + num_subframes, + pred_real_bands_yaw[q], + pred_imag_bands_yaw[q], + d_bands_yaw[q], + bands_pitch[q], + pred_real_bands_roll[q], + pred_imag_bands_roll[q], + pBits ); + } + break; + } + pBits->bits_written = start_bit; + } + } + +#ifdef SPLIT_MD_CODING_DEBUG + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + int16_t val, quant_strat, ch1, ch2; + char filename[200] = "split_md_debug_indices.bin"; + quant_strat = q; + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + } + for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + } + for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch[quant_strat]; b++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_idx; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + else + { + for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + } + for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + } + } + } + } +#endif + + return; +} + + +void ivas_SplitRenderer_GetRotMd( + BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + float Cldfb_RealBuffer_Ref_Binaural[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ + float Cldfb_ImagBuffer_Ref_Binaural[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ + int16_t low_res ) +{ + float cov_ii_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float cov_oo_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float cov_io_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float cov_ii_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float cov_oo_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float cov_io_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + int16_t real_only = 0; + + int16_t pos_idx, b, sf_idx, start_slot_idx, num_slots, num_subframes; + int16_t num_md_bands, num_poses; + const int16_t *pBand_grouping = SplitRend_band_grouping; + num_md_bands = MAX_SPLIT_REND_MD_BANDS; + + push_wmops( "ivas_SplitRenderer_GetRotMd" ); + + num_poses = pMultiBinPoseData->num_poses; + + if ( low_res ) + { + num_slots = CLDFB_NO_COL_MAX; + num_subframes = 1; + } + else + { + num_slots = MAX_PARAM_SPATIAL_SUBFRAMES; + num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; + } + /*compute reference signal covariance*/ + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + start_slot_idx = sf_idx * num_slots; + for ( b = 0; b < num_md_bands; b++ ) + { + if ( b < COMPLEX_MD_BAND_THRESH ) + { + real_only = 0; + } + else + { + real_only = 1; + } + ComputeBandedCov( Cldfb_RealBuffer_Ref_Binaural[0], + Cldfb_ImagBuffer_Ref_Binaural[0], + cov_ii_re, cov_ii_im, + BINAURAL_CHANNELS, + pBand_grouping, + num_slots, start_slot_idx, b, real_only ); + + /*compute rotated signal covariance*/ + for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + { + ComputeBandedCrossCov( Cldfb_RealBuffer_Ref_Binaural[0], + Cldfb_ImagBuffer_Ref_Binaural[0], + Cldfb_RealBuffer_Ref_Binaural[pos_idx + 1], + Cldfb_ImagBuffer_Ref_Binaural[pos_idx + 1], + cov_io_re, cov_io_im, + BINAURAL_CHANNELS, + pBand_grouping, + num_slots, start_slot_idx, b, real_only ); + + ComputeBandedCov( Cldfb_RealBuffer_Ref_Binaural[pos_idx + 1], + Cldfb_ImagBuffer_Ref_Binaural[pos_idx + 1], + cov_oo_re, cov_oo_im, + BINAURAL_CHANNELS, + pBand_grouping, + num_slots, start_slot_idx, b, real_only ); + + ComputeCoeffs( cov_ii_re, + cov_ii_im, + cov_io_re, + cov_io_im, + cov_oo_re, + &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b], + hBinHrSplitPreRend->pose_type[pos_idx], + real_only ); + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + { + int16_t num_cldfb_bands; + num_cldfb_bands = CLDFB_NO_CHANNELS_MAX; + for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + { + char fname[200] = "rotated_cldfbref_pos"; + char tag[2]; + tag[0] = (char) ( '0' + pos_idx ); + tag[1] = '\0'; + strcat( fname, tag ); + strcat( fname, ".wav" ); + ivas_log_cldfb2wav_data( + Cldfb_RealBuffer_Ref_Binaural[pos_idx + 1], + Cldfb_ImagBuffer_Ref_Binaural[pos_idx + 1], + hBinHrSplitPreRend->cldfbSynRotBinDec[pos_idx], + BINAURAL_CHANNELS, + num_cldfb_bands, + 48000, + num_slots, + start_slot_idx, + fname ); + } + ivas_log_cldfb2wav_data( + Cldfb_RealBuffer_Ref_Binaural[0], + Cldfb_ImagBuffer_Ref_Binaural[0], + hBinHrSplitPreRend->cldfbSynRotBinDec[MAX_HEAD_ROT_POSES], + BINAURAL_CHANNELS, + num_cldfb_bands, + 48000, + num_slots, + start_slot_idx, + "rotated_cldfbref_RefPos.wav" ); + } +#endif + } + + pop_wmops(); + + return; +} + +void ivas_rend_CldfbSplitPreRendProcess( + const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, + const IVAS_QUATERNION headPositions[MAX_PARAM_SPATIAL_SUBFRAMES], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + float Cldfb_In_BinReal[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_BinImag[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + ivas_split_rend_bits_t *pBits, + const int32_t target_md_bits, + const int16_t low_res_pre_rend_rot ) +{ + push_wmops( "ivas_rend_CldfbSplitPreRendProcess" ); + + ivas_SplitRenderer_GetRotMd( + hBinHrSplitPreRend, + pMultiBinPoseData, + Cldfb_In_BinReal, + Cldfb_In_BinImag, + low_res_pre_rend_rot ); + + ivas_SplitRenderer_quant_code( + hBinHrSplitPreRend, + headPositions, + pMultiBinPoseData, + pBits, + low_res_pre_rend_rot, + target_md_bits ); + + pop_wmops(); + + return; +} + +ivas_error ivas_splitBinPreRendOpen( + BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + , + const int32_t output_Fs +#endif +) +{ + BIN_HR_SPLIT_PRE_REND_HANDLE hBinRend; + ivas_error error; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + int16_t ch; +#endif + int16_t pos_idx, sf_idx, bandIdx; + + error = IVAS_ERR_OK; + if ( ( hBinRend = (BIN_HR_SPLIT_PRE_REND_HANDLE) malloc( sizeof( BIN_HR_SPLIT_PRE_REND ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split pre renderer Module \n" ) ); + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hBinRend->cldfbSynRotBinDec[i][ch] = NULL; + } + } + + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( error = openCldfb( &( hBinRend->cldfbSynRotBinDec[i][ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } +#endif + + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + for ( sf_idx = 0; sf_idx < MAX_SPLIT_MD_SUBFRAMES; sf_idx++ ) + { + for ( bandIdx = 0; bandIdx < MAX_SPLIT_REND_MD_BANDS; bandIdx++ ) + { + hBinRend->rot_md[pos_idx][sf_idx][bandIdx].gd = 0.0f; + } + } + } + set_fix_rotation_mat( hBinRend->fix_pos_rot_mat, pMultiBinPoseData ); + set_pose_types( hBinRend->pose_type, pMultiBinPoseData ); + ivas_split_rend_init_huff_cfg( &hBinRend->huff_cfg ); + *hBinHrSplitPreRend = hBinRend; + return error; +} + +void ivas_splitBinPreRendClose( BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend ) +{ + if ( ( *hBinHrSplitPreRend ) != NULL ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + { + int16_t i, n; + for ( i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ ) + { + for ( n = 0; n < BINAURAL_CHANNELS; n++ ) + { + if ( ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] != NULL ) + { + deleteCldfb( &( ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] ) ); + ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] = NULL; + } + } + } + } +#endif + free( ( *hBinHrSplitPreRend ) ); + ( *hBinHrSplitPreRend ) = NULL; + } + return; +} + +void ivas_init_split_rend_handles( SPLIT_REND_WRAPPER *hSplitRendWrapper ) +{ +#ifdef SPLIT_REND_LC3PLUS + int32_t i; +#endif + + hSplitRendWrapper->hBinHrSplitPreRend = NULL; + hSplitRendWrapper->hCldfbHandles = NULL; + hSplitRendWrapper->hSplitBinLCLDEnc = NULL; +#ifdef SPLIT_REND_LC3PLUS + hSplitRendWrapper->hLc3plusEnc = NULL; + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + hSplitRendWrapper->hTdRendHandles[i] = NULL; + } + for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) + { + hSplitRendWrapper->lc3plusDelayBuffers[i] = NULL; + } + hSplitRendWrapper->lc3plusDelaySamples = 0; +#endif + + ivas_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData ); + return; +} + +#ifdef SPLIT_REND_LC3PLUS +static ivas_error split_renderer_open_lc3plus( SPLIT_REND_WRAPPER *hSplitRendWrapper, + const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const int32_t OutSampleRate ) +{ + ivas_error error; + int32_t i, delayBufferLength; + LC3PLUS_CONFIG config; + + config.lc3plus_frame_duration_us = 5000; + config.ivas_frame_duration_us = 20000; + config.samplerate = OutSampleRate; + + config.channels = BINAURAL_CHANNELS; + + error = IVAS_LC3PLUS_ENC_Open( config, ivas_get_lc3plus_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode ), &hSplitRendWrapper->hLc3plusEnc ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + + /* This returns delay of entire LC3plus chain (enc + dec) */ + error = IVAS_LC3PLUS_ENC_GetDelay( hSplitRendWrapper->hLc3plusEnc, &hSplitRendWrapper->lc3plusDelaySamples ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + + /* Alocate buffers for delay compensation */ + if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ) + { + delayBufferLength = OutSampleRate / (int32_t) FRAMES_PER_SECOND + hSplitRendWrapper->lc3plusDelaySamples; + for ( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i ) + { + hSplitRendWrapper->lc3plusDelayBuffers[i] = malloc( delayBufferLength * sizeof( float ) ); + set_zero( hSplitRendWrapper->lc3plusDelayBuffers[i], (int16_t) delayBufferLength ); + } + } + else + { + /* Delay is always expected to be exactly 2 CLDFB columns */ + assert( hSplitRendWrapper->lc3plusDelaySamples % ( OutSampleRate / FRAMES_PER_SEC / CLDFB_NO_COL_MAX ) == 0 ); + assert( hSplitRendWrapper->lc3plusDelaySamples / ( OutSampleRate / FRAMES_PER_SEC / CLDFB_NO_COL_MAX ) == 2 ); + + delayBufferLength = 2 /* Columns */ * 2 /* real and imag */ * CLDFB_NO_CHANNELS_MAX; + for ( i = 0; i < hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++i ) + { + hSplitRendWrapper->lc3plusDelayBuffers[i] = malloc( delayBufferLength * sizeof( float ) ); + set_zero( hSplitRendWrapper->lc3plusDelayBuffers[i], (int16_t) delayBufferLength ); + } + } + + return IVAS_ERR_OK; +} +#endif + +ivas_error ivas_split_renderer_open( SPLIT_REND_WRAPPER *hSplitRendWrapper, + const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const int32_t OutSampleRate, + const int16_t is_cldfb_in, + const int16_t is_pcm_out ) +{ + ivas_error error, ch, num_ch; +#ifdef SPLIT_REND_LC3PLUS + CLDFB_TYPE cldfbMode; + uint8_t useLc3plus; + uint8_t isCldfbNeeded = 0; + cldfbMode = CLDFB_ANALYSIS; + + if ( ( error = ivas_split_rend_validate_config( pSplitRendConfig ) ) != IVAS_ERR_OK ) + { + return error; + } + + useLc3plus = pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS; /* TODO(sgi): change "useLc3plus" to "splitCodec" */ +#endif + error = IVAS_ERR_OK; + +#ifdef SPLIT_REND_LC3PLUS + if ( + is_cldfb_in == 0 ) + { + isCldfbNeeded = 1; + cldfbMode = CLDFB_ANALYSIS; + } + else if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && is_cldfb_in ) + { + isCldfbNeeded = 1; + cldfbMode = CLDFB_SYNTHESIS; + } +#endif + + hSplitRendWrapper->hCldfbHandles = NULL; + if ( +#ifdef SPLIT_REND_LC3PLUS + isCldfbNeeded ) +#else + is_cldfb_in == 0 ) +#endif + { + if ( ( hSplitRendWrapper->hCldfbHandles = (CLDFB_HANDLES_WRAPPER_HANDLE) malloc( sizeof( CLDFB_HANDLES_WRAPPER ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for CLDFB handles\n" ) ); + } +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + num_ch = ( 1 + MAX_HEAD_ROT_POSES ) * BINAURAL_CHANNELS; +#else + num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; +#endif + for ( ch = 0; ch < num_ch; ch++ ) + { + hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; + } +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + num_ch = ( 1 + hSplitRendWrapper->multiBinPoseData.num_poses ) * BINAURAL_CHANNELS; +#else + num_ch = hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; +#endif + + for ( ch = 0; ch < num_ch; ch++ ) + { + if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), +#ifdef SPLIT_REND_LC3PLUS + cldfbMode, +#else + CLDFB_ANALYSIS, +#endif + OutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + error = ivas_splitBinPreRendOpen( &hSplitRendWrapper->hBinHrSplitPreRend, + &hSplitRendWrapper->multiBinPoseData +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + , + OutSampleRate +#endif + ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + if ( is_pcm_out == 0 ) + { +#ifdef SPLIT_REND_LC3PLUS + if ( !useLc3plus ) + { +#endif + error = ivas_splitBinLCLDEncOpen( &hSplitRendWrapper->hSplitBinLCLDEnc, OutSampleRate, BINAURAL_CHANNELS, ivas_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate ) ); + if ( error != IVAS_ERR_OK ) + { + return error; + } +#ifdef SPLIT_REND_LC3PLUS + } + else + { + error = split_renderer_open_lc3plus( hSplitRendWrapper, pSplitRendConfig, OutSampleRate ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + } +#endif + } + return error; +} + +void ivas_split_renderer_close( SPLIT_REND_WRAPPER *hSplitBinRend ) +{ + int32_t i; + + if ( hSplitBinRend->hBinHrSplitPreRend != NULL ) + { + ivas_splitBinPreRendClose( &hSplitBinRend->hBinHrSplitPreRend ); + } + if ( hSplitBinRend->hSplitBinLCLDEnc != NULL ) + { + ivas_splitBinLCLDEncClose( &hSplitBinRend->hSplitBinLCLDEnc ); + } + + if ( hSplitBinRend->hCldfbHandles != NULL ) + { + int16_t num_ch, ch; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + num_ch = ( 1 + MAX_HEAD_ROT_POSES ) * BINAURAL_CHANNELS; +#else + num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; +#endif + for ( ch = 0; ch < num_ch; ch++ ) + { + if ( hSplitBinRend->hCldfbHandles->cldfbAna[ch] != NULL ) + { + deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbAna[ch] ); + hSplitBinRend->hCldfbHandles->cldfbAna[ch] = NULL; + } + } + free( hSplitBinRend->hCldfbHandles ); + hSplitBinRend->hCldfbHandles = NULL; + } + +#ifdef SPLIT_REND_LC3PLUS + if ( hSplitBinRend->hLc3plusEnc != NULL ) + { + IVAS_LC3PLUS_ENC_Close( &hSplitBinRend->hLc3plusEnc ); + } + + for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) + { + if ( hSplitBinRend->lc3plusDelayBuffers[i] != NULL ) + { + free( hSplitBinRend->lc3plusDelayBuffers[i] ); + hSplitBinRend->lc3plusDelayBuffers[i] = NULL; + } + } + + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + if ( hSplitBinRend->hTdRendHandles[i] != NULL ) + { + hSplitBinRend->hTdRendHandles[i]->HrFiltSet_p = NULL; + ivas_td_binaural_close( &hSplitBinRend->hTdRendHandles[i] ); + } + } +#endif + + return; +} + +#ifdef SPLIT_REND_LC3PLUS +static ivas_error splitRendLc3plusEncodeAndWrite( + SPLIT_REND_WRAPPER *hSplitBin, + ivas_split_rend_bits_t *pBits, + const int32_t SplitRendBitRate, + float in[][L_FRAME48k] ) +{ + ivas_error error; + int16_t i; + + int32_t lc3plusBitstreamSize; + float *channel_ptrs[MAX_HEAD_ROT_POSES * 2]; + assert( hSplitBin->hLc3plusEnc != NULL ); + + /* Find next byte boundary and zero-pad to it */ + while ( pBits->bits_written % 8 != 0 ) + { + ivas_split_rend_bitstream_write_int32( pBits, (int32_t) 0, 1 ); + } + + for ( i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i ) + { + channel_ptrs[i] = in[i]; + } + if ( ( error = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( hSplitBin->hLc3plusEnc, &lc3plusBitstreamSize ) ) != IVAS_ERR_OK ) + { + return error; + } + /* Write bitstream size info */ + ivas_split_rend_bitstream_write_int32( pBits, ivas_get_lc3plus_bitrate_id( SplitRendBitRate ), 8 ); + + /* Write bitstream */ + if ( ( error = IVAS_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8] ) ) != IVAS_ERR_OK ) + { + return error; + } + pBits->bits_written += 8 * lc3plusBitstreamSize; + pBits->codec = IVAS_SPLIT_REND_CODEC_LC3PLUS; + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + return IVAS_ERR_OK; +} +#endif + +static ivas_error ivas_renderMultiTDBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, + const IVAS_QUATERNION headPositions[MAX_PARAM_SPATIAL_SUBFRAMES], + const int32_t SplitRendBitRate, + ivas_split_rend_bits_t *pBits, + const int16_t max_bands, + float in[][L_FRAME48k], + const int16_t low_res_pre_rend_rot, + const int16_t pcm_out ) +{ + ivas_error error; + int32_t bit_len, available_bits, target_md_bits, actual_md_bits; + int16_t num_cldfb_bands, ch, slot_idx, pos_idx, num_poses; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + float Cldfb_In_BinReal[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_In_BinImag[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; +#else + float Cldfb_In_BinReal[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_In_BinImag[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; +#endif +#ifdef SPLIT_REND_LC3PLUS + uint8_t useLc3plus; + float *in_delayed[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; + int32_t i; +#endif + + push_wmops( "ivas_renderMultiTDBinToSplitBinaural" ); + + error = IVAS_ERR_OK; +#ifndef SPLIT_REND_LC3PLUS + assert( hSplitBin->hCldfbHandles != NULL ); + num_cldfb_bands = hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels; +#endif + num_poses = hSplitBin->multiBinPoseData.num_poses; + +#ifdef SPLIT_REND_LC3PLUS + useLc3plus = hSplitBin->hLc3plusEnc != NULL; + + if ( useLc3plus ) + { + int32_t frame_size = hSplitBin->hLc3plusEnc->config.samplerate / (int32_t) FRAMES_PER_SECOND; + + for ( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + /* Artificially delay input to head pose correction analysis by LC3plus coding delay, so that audio and metadata are in sync after decoding */ + mvr2r( hSplitBin->lc3plusDelayBuffers[i] + frame_size, hSplitBin->lc3plusDelayBuffers[i], (int16_t) hSplitBin->lc3plusDelaySamples ); + in_delayed[i] = hSplitBin->lc3plusDelayBuffers[i]; + mvr2r( in[i], hSplitBin->lc3plusDelayBuffers[i] + hSplitBin->lc3plusDelaySamples, (int16_t) frame_size ); + } + } + else + { + for ( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + in_delayed[i] = in[i]; + } + } +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + float *pPcm[BINAURAL_CHANNELS]; + + char fname[200] = "rotated_ref_pos"; + char tag[2]; + tag[0] = (char) ( '0' + pos_idx ); + tag[1] = '\0'; + strcat( fname, tag ); + strcat( fname, ".wav" ); + for ( int i = 0; i < BINAURAL_CHANNELS; i++ ) + { + pPcm[i] = in[pos_idx * BINAURAL_CHANNELS + i]; + } + dbgwrite_wav( pPcm, 960, + fname, 48000, BINAURAL_CHANNELS ); + } +#endif + +#ifdef SPLIT_REND_LC3PLUS + actual_md_bits = pBits->bits_written; + if ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + num_cldfb_bands = hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels; + +#endif + /* CLDFB Analysis*/ +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( pos_idx = 0; pos_idx < num_poses + 1; pos_idx++ ) +#else + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) +#endif + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) + { +#ifdef SPLIT_REND_LC3PLUS + cldfbAnalysis_ts( &( in_delayed[pos_idx * BINAURAL_CHANNELS + ch][num_cldfb_bands * slot_idx] ), +#else + cldfbAnalysis_ts( &( in[pos_idx * BINAURAL_CHANNELS + ch][num_cldfb_bands * slot_idx] ), +#endif + Cldfb_In_BinReal[pos_idx][ch][slot_idx], + Cldfb_In_BinImag[pos_idx][ch][slot_idx], + max_bands, + hSplitBin->hCldfbHandles->cldfbAna[pos_idx * BINAURAL_CHANNELS + ch] ); + } + } + } + + target_md_bits = ivas_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out ) * L_FRAME48k / 48000; + actual_md_bits = pBits->bits_written; + ivas_rend_CldfbSplitPreRendProcess( + hSplitBin->hBinHrSplitPreRend, + headPositions, + &hSplitBin->multiBinPoseData, + Cldfb_In_BinReal, + Cldfb_In_BinImag, + pBits, + target_md_bits, + low_res_pre_rend_rot ); + } + + if ( pcm_out == 0 ) + { +#ifdef SPLIT_REND_LC3PLUS + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + pBits->codec = useLc3plus ? IVAS_SPLIT_REND_CODEC_LC3PLUS : IVAS_SPLIT_REND_CODEC_LCLD; /* TODO(sgi): useLc3plus could be changed to splitCodec */ +#endif + +#ifdef SPLIT_REND_LC3PLUS + if ( !useLc3plus ) + { +#endif + // available_bits = ivas_get_lcld_bitrate( SplitRendBitRate ) * L_FRAME48k / 48000; + available_bits = SplitRendBitRate * L_FRAME48k / 48000; + actual_md_bits = pBits->bits_written - actual_md_bits; + available_bits -= actual_md_bits; + ivas_splitBinLCLDEncProcess( + hSplitBin->hSplitBinLCLDEnc, + Cldfb_In_BinReal[0], + Cldfb_In_BinImag[0], + available_bits, + pBits ); +#ifdef SPLIT_REND_LC3PLUS + } + else + { + if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, in ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + } +#ifdef SPLIT_REND_LC3PLUS + else + { + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + pBits->codec = IVAS_SPLIT_REND_CODEC_NONE; + } +#endif + + /*zero pad*/ + bit_len = SplitRendBitRate / FRAMES_PER_SEC; + while ( pBits->bits_written < bit_len ) + { + ivas_split_rend_bitstream_write_int32( pBits, (int32_t) 0, 1 ); + } + + pop_wmops(); + + return error; +} + +#ifdef SPLIT_REND_LC3PLUS +static void lc3plusTimeAlignCldfbPoseCorr( + SPLIT_REND_WRAPPER *hSplitBin, + float Cldfb_In_BinReal[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_BinImag[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ) +{ + float Cldfb_In_BinReal_tmp[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][2][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_In_BinImag_tmp[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][2][CLDFB_NO_CHANNELS_MAX]; + int16_t pose, ch, slot_idx; + float *bufRead, *bufWrite; + + for ( pose = 0; pose < hSplitBin->multiBinPoseData.num_poses; ++pose ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ++ch ) + { + bufRead = hSplitBin->lc3plusDelayBuffers[pose * BINAURAL_CHANNELS + ch]; + bufWrite = bufRead; + + /* Save last 2 columns for next frame */ + for ( slot_idx = 0; slot_idx < 2; ++slot_idx ) + { + mvr2r( Cldfb_In_BinReal[pose][ch][CLDFB_NO_COL_MAX - 2 + slot_idx], Cldfb_In_BinReal_tmp[pose][ch][slot_idx], CLDFB_NO_CHANNELS_MAX ); + mvr2r( Cldfb_In_BinImag[pose][ch][CLDFB_NO_COL_MAX - 2 + slot_idx], Cldfb_In_BinImag_tmp[pose][ch][slot_idx], CLDFB_NO_CHANNELS_MAX ); + } + + /* Delay existing columns by 2 slots */ + for ( slot_idx = CLDFB_NO_COL_MAX - 2 - 1; slot_idx >= 0; --slot_idx ) + { + mvr2r( Cldfb_In_BinReal[pose][ch][slot_idx], Cldfb_In_BinReal[pose][ch][slot_idx + 2], CLDFB_NO_CHANNELS_MAX ); + mvr2r( Cldfb_In_BinImag[pose][ch][slot_idx], Cldfb_In_BinImag[pose][ch][slot_idx + 2], CLDFB_NO_CHANNELS_MAX ); + } + + /* Fill 2 first columns from buffer */ + for ( slot_idx = 0; slot_idx < 2; ++slot_idx ) + { + mvr2r( bufRead, Cldfb_In_BinReal[pose][ch][slot_idx], CLDFB_NO_CHANNELS_MAX ); + bufRead += CLDFB_NO_CHANNELS_MAX; + mvr2r( bufRead, Cldfb_In_BinImag[pose][ch][slot_idx], CLDFB_NO_CHANNELS_MAX ); + bufRead += CLDFB_NO_CHANNELS_MAX; + } + + /* Copy last 2 columns to buffer */ + for ( slot_idx = 0; slot_idx < 2; ++slot_idx ) + { + mvr2r( Cldfb_In_BinReal_tmp[pose][ch][slot_idx], bufWrite, CLDFB_NO_CHANNELS_MAX ); + bufWrite += CLDFB_NO_CHANNELS_MAX; + mvr2r( Cldfb_In_BinImag_tmp[pose][ch][slot_idx], bufWrite, CLDFB_NO_CHANNELS_MAX ); + bufWrite += CLDFB_NO_CHANNELS_MAX; + } + } + } +} +#endif + +ivas_error ivas_renderMultiBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, + const IVAS_QUATERNION headPositions[MAX_PARAM_SPATIAL_SUBFRAMES], + const int32_t SplitRendBitRate, +#ifdef SPLIT_REND_LC3PLUS + const IVAS_SPLIT_REND_CODEC splitCodec, +#endif + ivas_split_rend_bits_t *pBits, + float Cldfb_In_BinReal[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_BinImag[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t max_bands, + float out[][L_FRAME48k], + const int16_t low_res_pre_rend_rot, +#ifdef SPLIT_REND_LC3PLUS + int16_t td_input, +#endif + const int16_t pcm_out ) +{ + ivas_error error; + int32_t bit_len, target_md_bits, actual_md_bits, available_bits; + error = IVAS_ERR_OK; + + push_wmops( "ivas_renderMultiBinToSplitBinaural" ); + + set_fix_rotation_mat( hSplitBin->hBinHrSplitPreRend->fix_pos_rot_mat, &hSplitBin->multiBinPoseData ); + set_pose_types( hSplitBin->hBinHrSplitPreRend->pose_type, &hSplitBin->multiBinPoseData ); + + if ( +#ifdef SPLIT_REND_LC3PLUS + td_input +#else + hSplitBin->hCldfbHandles != NULL +#endif + ) + { + /*TD input*/ + /*if CLDFB handles have been allocated then assume valid multi binaural input in out[][] buffer and perform CLDFB analysis*/ + error = ivas_renderMultiTDBinToSplitBinaural( hSplitBin, headPositions, SplitRendBitRate, pBits, max_bands, out, + low_res_pre_rend_rot, pcm_out ); + pop_wmops(); + return error; + } + +#ifdef SPLIT_REND_LC3PLUS + if ( splitCodec == IVAS_SPLIT_REND_CODEC_LC3PLUS && hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + /* Time-align pose correction to delay of LC3plus */ + lc3plusTimeAlignCldfbPoseCorr( hSplitBin, Cldfb_In_BinReal, Cldfb_In_BinImag ); + } + + actual_md_bits = pBits->bits_written; + if ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { +#endif + target_md_bits = ivas_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out ) * L_FRAME48k / 48000; + actual_md_bits = pBits->bits_written; + ivas_rend_CldfbSplitPreRendProcess( + hSplitBin->hBinHrSplitPreRend, + headPositions, + &hSplitBin->multiBinPoseData, + Cldfb_In_BinReal, + Cldfb_In_BinImag, + pBits, + target_md_bits, + low_res_pre_rend_rot ); +#ifdef SPLIT_REND_LC3PLUS + } +#endif + + if ( pcm_out == 0 ) + { +#ifdef SPLIT_REND_LC3PLUS + pBits->codec = splitCodec; + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + + if ( splitCodec == IVAS_SPLIT_REND_CODEC_LCLD ) + { +#endif + // available_bits = ivas_get_lcld_bitrate( SplitRendBitRate ) * L_FRAME48k / 48000; + available_bits = SplitRendBitRate * L_FRAME48k / 48000; + actual_md_bits = pBits->bits_written - actual_md_bits; + available_bits -= actual_md_bits; + ivas_splitBinLCLDEncProcess( + hSplitBin->hSplitBinLCLDEnc, + Cldfb_In_BinReal[0], + Cldfb_In_BinImag[0], + available_bits, + pBits ); + +#ifdef SPLIT_REND_LC3PLUS + } + else + { + int16_t ch, slot_idx; + /* CLDFB synthesis of main pose */ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + float *Cldfb_In_BinReal_p[CLDFB_NO_COL_MAX]; + float *Cldfb_In_BinImag_p[CLDFB_NO_COL_MAX]; + + for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) + { + Cldfb_In_BinReal_p[slot_idx] = Cldfb_In_BinReal[0][ch][slot_idx]; + Cldfb_In_BinImag_p[slot_idx] = Cldfb_In_BinImag[0][ch][slot_idx]; + } + cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, out[ch], -1, hSplitBin->hCldfbHandles->cldfbAna[ch] ); + } + + if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, out ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + } +#ifdef SPLIT_REND_LC3PLUS + else + { + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + pBits->codec = IVAS_SPLIT_REND_CODEC_NONE; + } +#endif + + /*zero pad*/ + /*TODO: do this inside the LCLD ENC codec */ + bit_len = SplitRendBitRate / FRAMES_PER_SEC; + + while ( pBits->bits_written < bit_len ) + { + ivas_split_rend_bitstream_write_int32( pBits, (int32_t) 0, 1 ); + } + + pop_wmops(); + + return error; +} +#endif diff --git a/lib_rend/ivas_splitRenderer_utils.c b/lib_rend/ivas_splitRenderer_utils.c new file mode 100644 index 0000000000000000000000000000000000000000..50d70ceb31ab953981a3eee178783ec02f60395b --- /dev/null +++ b/lib_rend/ivas_splitRenderer_utils.c @@ -0,0 +1,803 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include "options.h" +#include +#include "ivas_prot.h" +#include "prot.h" +#include "cnst.h" +#include "ivas_cnst.h" +#include "ivas_rom_rend.h" +#include "ivas_rom_com.h" +#include "ivas_rom_dec.h" +#include "ivas_rom_binauralRenderer.h" +#include "lib_rend.h" +#include "ivas_prot_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT + +void ivas_mat_mult_2by2_complex( float in_re1[2][2], + float in_im1[2][2], + float in_re2[2][2], + float in_im2[2][2], + float out_re2[2][2], + float out_im2[2][2] ) +{ + int16_t i, j; + float tmp_re, tmp_im; + + for ( i = 0; i < 2; i++ ) + { + for ( j = 0; j < 2; j++ ) + { + + IVAS_CMULT_FLOAT( in_re1[i][0], in_im1[i][0], + in_re2[0][j], in_im2[0][j], tmp_re, tmp_im ); + out_re2[i][j] = tmp_re; + out_im2[i][j] = tmp_im; + IVAS_CMULT_FLOAT( in_re1[i][1], in_im1[i][1], + in_re2[1][j], in_im2[1][j], tmp_re, tmp_im ); + out_re2[i][j] += tmp_re; + out_im2[i][j] += tmp_im; + } + } + return; +} +void ivas_split_rend_bitstream_init( ivas_split_rend_bits_t *pBits, const int32_t buf_len_bytes, uint8_t *pbuf ) +{ + pBits->bits_buf = pbuf; + pBits->buf_len = buf_len_bytes; + pBits->bits_read = 0; + pBits->bits_written = 0; + return; +} + +void ivas_split_rend_huffman_dec_init_min_max_len( + ivas_split_rend_huffman_cfg_t *p_huff_cfg ) +{ + int16_t i, code_len; + const int32_t *codebook; + + codebook = p_huff_cfg->codebook; + + p_huff_cfg->min_len = p_huff_cfg->sym_len; + p_huff_cfg->max_len = 0; + + for ( i = 0; i < p_huff_cfg->sym_len; i++ ) + { + code_len = (int16_t) codebook[1]; + if ( p_huff_cfg->min_len > code_len ) + { + p_huff_cfg->min_len = code_len; + } + if ( p_huff_cfg->max_len < code_len ) + { + p_huff_cfg->max_len = code_len; + } + codebook = codebook + 3; + } + + return; +} + +static int16_t is_idx_present( int16_t *idx_list, const int16_t idx, const int16_t len ) +{ + int16_t i; + for ( i = 0; i < len; i++ ) + { + if ( idx_list[i] == idx ) + { + return 1; + } + } + return 0; +} +static void ivas_split_huff_get_idx_trav_list( int16_t *idx_list, ivas_split_rend_huffman_cfg_t *p_huff_cfg ) +{ + int16_t i, j, min_idx; + int32_t min_bits; + const int32_t *codebook; + + for ( i = 0; i < p_huff_cfg->sym_len; i++ ) + { + idx_list[i] = -1; + } + + for ( i = 0; i < p_huff_cfg->sym_len; i++ ) + { + codebook = p_huff_cfg->codebook; + min_bits = p_huff_cfg->max_len; + min_idx = -1; + for ( j = 0; j < p_huff_cfg->sym_len; j++ ) + { + if ( ( min_bits >= codebook[1] ) && ( is_idx_present( idx_list, j, i + 1 ) == 0 ) ) + { + min_bits = codebook[1]; + min_idx = j; + } + codebook += 3; + } + idx_list[i] = min_idx; + } + + return; +} + +void ivas_split_rend_init_huff_cfg( BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg ) +{ + pHuff_cfg->pred.codebook = &ivas_split_rend_huff_pred_consts[0][0]; + pHuff_cfg->pred.sym_len = IVAS_SPLIT_REND_PRED_QUANT_PNTS; + ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred ); + ivas_split_huff_get_idx_trav_list( pHuff_cfg->pred_idx_trav, &pHuff_cfg->pred ); + pHuff_cfg->pred_base2_code_len = (int16_t) ceilf( log2f( pHuff_cfg->pred.sym_len ) ); + + pHuff_cfg->gd.codebook = &ivas_split_rend_huff_d_consts[0][0]; + pHuff_cfg->gd.sym_len = IVAS_SPLIT_REND_D_QUANT_PNTS; + ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->gd ); + ivas_split_huff_get_idx_trav_list( pHuff_cfg->gd_idx_trav, &pHuff_cfg->gd ); + pHuff_cfg->gd_base2_code_len = (int16_t) ceilf( log2f( pHuff_cfg->gd.sym_len ) ); + + pHuff_cfg->p_gd.codebook = &ivas_split_rend_huff_p_d_consts[0][0]; + pHuff_cfg->p_gd.sym_len = IVAS_SPLIT_REND_D_QUANT_PNTS; + ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd ); + ivas_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_idx_trav, &pHuff_cfg->p_gd ); + pHuff_cfg->p_gd_base2_code_len = (int16_t) ceilf( log2f( pHuff_cfg->p_gd.sym_len ) ); + + pHuff_cfg->p_gd_diff.codebook = &ivas_split_rend_huff_p_d_diff_consts[0][0]; + pHuff_cfg->p_gd_diff.sym_len = IVAS_SPLIT_REND_D_QUANT_PNTS; + ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd_diff ); + ivas_split_huff_get_idx_trav_list( pHuff_cfg->p_gd_diff_idx_trav, &pHuff_cfg->p_gd_diff ); + pHuff_cfg->p_gd_diff_base2_code_len = (int16_t) ceilf( log2f( pHuff_cfg->p_gd_diff.sym_len ) ); + + return; +} + +void set_fix_rotation_mat( float fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS], MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + float yaw_a, cos_yaw, sin_yaw; + int16_t pos_idx; + yaw_a = 0.0f; + + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + yaw_a = pMultiBinPoseData->relative_head_poses[pos_idx + 1][0]; + cos_yaw = cosf( EVS_PI * yaw_a / 180.0f ); + sin_yaw = sinf( EVS_PI * yaw_a / 180.0f ); + sin_yaw = 0.0f; + fix_pos_rot_mat[pos_idx][0][0] = cos_yaw; + fix_pos_rot_mat[pos_idx][1][1] = cos_yaw; + fix_pos_rot_mat[pos_idx][0][1] = sin_yaw; + fix_pos_rot_mat[pos_idx][1][0] = -1.0f * sin_yaw; + } + return; +} + +void set_pose_types( IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + int16_t pos_idx; + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( fabs( pMultiBinPoseData->relative_head_poses[pos_idx + 1][0] ) > EPSILON ) + { + pose_type[pos_idx] = ANY_YAW; + } + else if ( fabs( pMultiBinPoseData->relative_head_poses[pos_idx + 1][2] ) > EPSILON ) + { +#ifdef SPLIT_REND_REAL_ONLY_ROLL + pose_type[pos_idx] = PITCH_ONLY; +#else + pose_type[pos_idx] = ANY_ROLL; +#endif + } + else + { + pose_type[pos_idx] = PITCH_ONLY; + } + } + return; +} + +int16_t wrap_a( int16_t val, int16_t min_val, int16_t max_val ) +{ + if ( val < min_val ) + { + val = max_val - min_val + val + 1; + } + if ( val > max_val ) + { + val = min_val + val - max_val - 1; + } + return val; +} + +void ivas_SplitRenderer_getdiagdiff( + int16_t in_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + int16_t out_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + const int16_t sign, + const int16_t min_val, + const int16_t max_val ) +{ + out_idx[0][0] = in_idx[0][0]; + out_idx[0][1] = in_idx[0][1]; + out_idx[1][1] = in_idx[1][1] + sign * out_idx[0][0]; + out_idx[1][1] = wrap_a( out_idx[1][1], min_val, max_val ); + out_idx[1][0] = in_idx[1][0] + sign * out_idx[0][1]; + out_idx[1][0] = wrap_a( out_idx[1][0], min_val, max_val ); + + return; +} + +int32_t ivas_split_rend_bitstream_read_int32( ivas_split_rend_bits_t *pBits, int32_t bits ) +{ + int32_t val, k, bit_val; + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + assert( ( pBits->bits_written - pBits->bits_read ) >= bits ); + assert( bits <= 32 ); +#endif + + /* write bit by bit */ + val = 0; + for ( k = bits - 1; k >= 0; k-- ) + { +#if 0 + if ( pBits->bits_buf[pBits->bits_read >> 3] & ( 1 << ( pBits->bits_read & 7 ) ) ) + { + val |= 1 << k; + } +#else + bit_val = ( pBits->bits_buf[pBits->bits_read >> 3] & ( 1 << ( pBits->bits_read & 7 ) ) ) != 0; + val |= bit_val << k; +#endif + pBits->bits_read++; + } + return val; +} +void ivas_split_rend_bitstream_write_int32( ivas_split_rend_bits_t *pBits, int32_t val, int32_t bits ) +{ + int32_t mask, k; + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + /*protection check*/ + if ( ( pBits->buf_len << 3 ) < ( pBits->bits_written + bits ) ) + { + assert( 0 ); + } +#endif + + mask = 1 << ( bits - 1 ); + /* write bit by bit */ + for ( k = 0; k < bits; k++ ) + { + if ( val & mask ) + { + pBits->bits_buf[pBits->bits_written >> 3] |= ( 1 << ( pBits->bits_written & 7 ) ); + } + else + { + pBits->bits_buf[pBits->bits_written >> 3] &= ~( 1 << ( pBits->bits_written & 7 ) ); + } + pBits->bits_written++; + mask >>= 1; + } + return; +} + +IVAS_QUATERNION ivas_split_rend_get_sf_rot_data( + const IVAS_QUATERNION headPositions[RENDERER_HEAD_POSITIONS_PER_FRAME], + int16_t subframe_idx ) +{ + int16_t idx; + + idx = ( subframe_idx * RENDERER_HEAD_POSITIONS_PER_FRAME ) / MAX_PARAM_SPATIAL_SUBFRAMES; + return headPositions[idx]; +} + + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +void ivas_log_cldfb2wav_data( + float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + HANDLE_CLDFB_FILTER_BANK *cldfbSyn, + const int16_t num_chs, + const int16_t num_freq_bands, + const int32_t output_Fs, + const int16_t num_slots, + const int16_t start_slot_idx, + const char *filename ) +{ + float *RealBuffer[CLDFB_NO_COL_MAX]; + float *ImagBuffer[CLDFB_NO_COL_MAX]; + float pcm_out[BINAURAL_CHANNELS][L_FRAME48k]; + float *pPcm[BINAURAL_CHANNELS]; + float Cldfb_local_Real[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_local_Imag[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + int16_t sf, ch; + + assert( num_chs <= BINAURAL_CHANNELS ); + for ( ch = 0; ch < num_chs; ch++ ) + { + for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + { + mvr2r( Cldfb_In_Real[ch][sf], Cldfb_local_Real[ch][sf], num_freq_bands ); + mvr2r( Cldfb_In_Imag[ch][sf], Cldfb_local_Imag[ch][sf], num_freq_bands ); + RealBuffer[sf - start_slot_idx] = Cldfb_local_Real[ch][sf]; + ImagBuffer[sf - start_slot_idx] = Cldfb_local_Imag[ch][sf]; + } + cldfbSynthesis( RealBuffer, + ImagBuffer, + &( pcm_out[ch][0] ), + num_freq_bands * num_slots, + cldfbSyn[ch] ); + pPcm[ch] = pcm_out[ch]; + } + dbgwrite_wav( pPcm, num_freq_bands * num_slots, + filename, output_Fs, num_chs ); +} +#endif + +int32_t ivas_get_split_rend_md_target_brate( const int32_t SplitRendBitRate, const int16_t pcm_out ) +{ + int32_t md_bitrate; + if ( pcm_out == 1 ) + { + md_bitrate = SplitRendBitRate; + } + else + { + switch ( SplitRendBitRate ) + { + case SPLIT_REND_768k: + { + md_bitrate = 256000; + break; + } + case SPLIT_REND_512k: + { + md_bitrate = 128000; + break; + } + case SPLIT_REND_384k: + { + md_bitrate = 128000; + break; + } +#ifdef SPLIT_REND_LC3PLUS_HBR_DBG + case -1: + { + md_bitrate = 256000; + break; + } +#endif + default: + { + return -1; + } + } + } + return md_bitrate; +} + +int32_t ivas_get_lcld_bitrate( const int32_t SplitRendBitRate ) +{ + switch ( SplitRendBitRate ) + { + case SPLIT_REND_768k: + { + return IVAS_384k; + } + case SPLIT_REND_512k: + { + return IVAS_384k; + } + case SPLIT_REND_384k: + { + return IVAS_256k; + } + default: + { + break; + } + } + return -1; +} + +#ifdef SPLIT_REND_LC3PLUS +int32_t ivas_get_lc3plus_bitrate( const int32_t SplitRendBitRate, IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode ) +{ +#ifdef SPLIT_REND_LC3PLUS_HBR_DBG + if ( SplitRendBitRate == -1 ) + { + return -1; + } +#endif + + if ( poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + int32_t inBandMdBps = 8 * FRAMES_PER_SECOND; + return ivas_get_lcld_bitrate( SplitRendBitRate ) - inBandMdBps; + } + if ( poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) + { + return SplitRendBitRate; + } + + /* Should not be reached */ + assert( 0 ); + return -1; +} + +int8_t ivas_get_lc3plus_bitrate_id( const int32_t SplitRendBitRate ) +{ +#ifdef SPLIT_REND_LC3PLUS_HBR_DBG + if ( SplitRendBitRate == -1 ) + { + return 3; + } +#endif + switch ( SplitRendBitRate ) + { + case SPLIT_REND_768k: + { + return 3; + } + case SPLIT_REND_512k: + { + return 2; + } + case SPLIT_REND_384k: + { + return 1; + } + case SPLIT_REND_320k: + { + return 0; + } + default: + { + break; + } + } + return -1; +} +int32_t ivas_get_lc3plus_size_from_id( const int8_t SplitRendBitRateId, IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode ) +{ + int32_t bitrate; + +#ifdef SPLIT_REND_LC3PLUS_HBR_DBG + if ( SplitRendBitRateId == 3 ) + { + return -1; + } +#endif + + switch ( SplitRendBitRateId ) + { + case 3: + { + bitrate = SPLIT_REND_768k; + break; + } + case 2: + { + bitrate = SPLIT_REND_512k; + break; + } + case 1: + { + bitrate = SPLIT_REND_384k; + break; + } + case 0: + { + bitrate = SPLIT_REND_320k; + break; + } + default: + { + return -1; + } + } + + bitrate = ivas_get_lc3plus_bitrate( bitrate, poseCorrectionMode ); + + /* Return size in bytes */ + return bitrate / FRAMES_PER_SECOND / 8; +} + +ivas_error ivas_split_rend_validate_config( const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig ) +{ + /* Valid DOF range is 0-3 */ + if ( pSplitRendConfig->dof < 0 || pSplitRendConfig->dof > 3 ) + { + return IVAS_ERR_INVALID_SPLIT_REND_CONFIG; + } + + if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LCLD ) + { + /* LCLD only supports CLDFB head pose correction */ + if ( pSplitRendConfig->poseCorrectionMode != IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + return IVAS_ERR_INVALID_SPLIT_REND_CONFIG; + } + + /* LCLD doesn't support 0-DOF */ + if ( pSplitRendConfig->dof == 0 ) + { + return IVAS_ERR_INVALID_SPLIT_REND_CONFIG; + } + } + + /* Only CLDFB pose correction supports HQ mode */ + if ( pSplitRendConfig->poseCorrectionMode != IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB && pSplitRendConfig->hq_mode != 0 ) + { + return IVAS_ERR_INVALID_SPLIT_REND_CONFIG; + } + + /* Validate bitrate */ + switch ( pSplitRendConfig->splitRendBitRate ) + { + case SPLIT_REND_256k: + case SPLIT_REND_384k: + case SPLIT_REND_512k: + case SPLIT_REND_768k: + /* Always valid */ + break; + case SPLIT_REND_320k: + /* Only valid with 0 DOF */ + if ( pSplitRendConfig->dof != 0 ) + { + return IVAS_ERR_INVALID_SPLIT_REND_CONFIG; + } + break; + default: + return IVAS_ERR_LC3PLUS_INVALID_BITRATE; + } + + return IVAS_ERR_OK; +} +#endif + +void ivas_split_rend_get_quant_params( + const int16_t num_md_bands, + int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t *num_quant_strats, + int16_t *num_complex_bands ) +{ + int16_t q; + + *num_quant_strats = IVAS_SPLIT_REND_NUM_QUANT_STRATS; + *num_complex_bands = COMPLEX_MD_BAND_THRESH_LOW; + assert( *num_complex_bands <= num_md_bands ); + + + for ( q = 0; q < *num_quant_strats; q++ ) + { + pred_real_bands_yaw[q] = num_md_bands; + pred_real_bands_roll[q] = num_md_bands; + } + pred_imag_bands_yaw[0] = num_md_bands; + pred_imag_bands_roll[0] = num_md_bands; + for ( q = 1; q < *num_quant_strats; q++ ) + { + pred_imag_bands_yaw[q] = ( q == 1 ) ? num_md_bands : *num_complex_bands; + pred_imag_bands_roll[q] = *num_complex_bands; + } + +#ifdef SPLIT_REND_ZERO_OUT_YAW_D + d_bands_yaw[0] = 0; +#else + d_bands_yaw[0] = num_md_bands; +#endif + bands_pitch[0] = num_md_bands; + for ( q = 1; q < *num_quant_strats; q++ ) + { + d_bands_yaw[q] = 0; + bands_pitch[q] = num_md_bands; + } + + return; +} + +void ivas_renderSplitGetMultiBinPoseData( + const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const IVAS_SPLIT_REND_ROT_AXIS rot_axis ) +{ + int16_t pos_idx, num_yaw_poses, num_pitch_poses, num_roll_poses; + const float *relative_yaw_angles; + const float *relative_pitch_angles; + const float *relative_roll_angles; + + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + pMultiBinPoseData->relative_head_poses[pos_idx][0] = 0.0f; + pMultiBinPoseData->relative_head_poses[pos_idx][1] = 0.0f; + pMultiBinPoseData->relative_head_poses[pos_idx][2] = 0.0f; + } + + num_yaw_poses = 0; + num_pitch_poses = 0; + num_roll_poses = 0; + + if ( pSplit_rend_config->dof == 1 ) + { + relative_yaw_angles = split_rend_relative_yaw_pos_angles_hq; + relative_pitch_angles = split_rend_relative_pitch_pos_angles_hq; + relative_roll_angles = split_rend_relative_roll_pos_angles_hq; + switch ( rot_axis ) + { + case DEFAULT_AXIS: + case YAW: + { + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + break; + } + case PITCH: + { + num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; + break; + } + case ROLL: + { + num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; + break; + } + default: + { + assert( 0 && "unsupported rotation axis value" ); + } + } + } + else if ( pSplit_rend_config->dof == 2 ) + { + relative_yaw_angles = split_rend_relative_yaw_pos_angles_hq; + relative_pitch_angles = split_rend_relative_pitch_pos_angles_hq; + relative_roll_angles = split_rend_relative_roll_pos_angles_hq; + switch ( rot_axis ) + { + case DEFAULT_AXIS: + case YAW: + case PITCH: + case YAW_PITCH: + { + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; + break; + } + case ROLL: + case YAW_ROLL: + { + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; + break; + } + case PITCH_ROLL: + { + num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; + num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; + break; + } + default: + { + assert( 0 && "unsupported rotation axis value" ); + } + } + } + else + { + if ( pSplit_rend_config->hq_mode == 1 ) + { + relative_yaw_angles = split_rend_relative_yaw_pos_angles_hq; + relative_pitch_angles = split_rend_relative_pitch_pos_angles_hq; + relative_roll_angles = split_rend_relative_roll_pos_angles_hq; + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; + num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; + } + else + { + relative_yaw_angles = split_rend_relative_yaw_pos_angles; + relative_pitch_angles = split_rend_relative_pitch_pos_angles; + relative_roll_angles = split_rend_relative_roll_pos_angles; + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + num_pitch_poses = 1; + num_roll_poses = 1; + } + } + pMultiBinPoseData->num_poses = num_yaw_poses + num_pitch_poses + num_roll_poses + 1; + assert( pMultiBinPoseData->num_poses <= MAX_HEAD_ROT_POSES ); + + + for ( pos_idx = 0; pos_idx < num_yaw_poses; pos_idx++ ) + { + pMultiBinPoseData->relative_head_poses[pos_idx + 1][0] = relative_yaw_angles[pos_idx]; + } + for ( pos_idx = 0; pos_idx < num_pitch_poses; pos_idx++ ) + { + pMultiBinPoseData->relative_head_poses[pos_idx + num_yaw_poses + 1][1] = relative_pitch_angles[pos_idx]; + } + for ( pos_idx = 0; pos_idx < num_roll_poses; pos_idx++ ) + { + pMultiBinPoseData->relative_head_poses[pos_idx + num_yaw_poses + num_pitch_poses + 1][2] = relative_roll_angles[pos_idx]; + } + pMultiBinPoseData->dof = pSplit_rend_config->dof; + pMultiBinPoseData->hq_mode = pSplit_rend_config->hq_mode; + pMultiBinPoseData->rot_axis = rot_axis; +#ifdef SPLIT_REND_LC3PLUS + pMultiBinPoseData->poseCorrectionMode = pSplit_rend_config->poseCorrectionMode; +#endif + + return; +} + +#ifdef SPLIT_REND_LC3PLUS +void ivas_renderSplitUpdateNoCorrectionPoseData( + const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + pMultiBinPoseData->num_poses = 1; + assert( pSplit_rend_config->dof == 0 ); + pMultiBinPoseData->dof = pSplit_rend_config->dof; + assert( pSplit_rend_config->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ); + pMultiBinPoseData->poseCorrectionMode = pSplit_rend_config->poseCorrectionMode; +} +#endif + +void ivas_init_multi_bin_pose_data( MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + int16_t pos_idx; + + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + pMultiBinPoseData->relative_head_poses[pos_idx][0] = 0.0f; + pMultiBinPoseData->relative_head_poses[pos_idx][1] = 0.0f; + pMultiBinPoseData->relative_head_poses[pos_idx][2] = 0.0f; + } + pMultiBinPoseData->num_poses = 1; + pMultiBinPoseData->dof = 3; + pMultiBinPoseData->hq_mode = 0; + pMultiBinPoseData->rot_axis = DEFAULT_AXIS; + + return; +} +#endif diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index c763630325297df7dc08b38100fa4b99d5c32c79..674ba95d6ca3d13d285bb1b6f7b7685003938d7c 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -39,7 +39,15 @@ #include "ivas_stat_com.h" // note: needed for DIRAC_DEC_BIN_HANDLE until #156 is solved #include "stat_com.h" /* Note: Currently needed for CLDFB. */ #include "common_api_types.h" - +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "stat_com.h" +#include "ivas_CQMFEncoder.h" +#include "ivas_CQMFDecoder.h" +#endif +#ifdef SPLIT_REND_LC3PLUS +#include "ivas_lc3plus_enc.h" +#include "ivas_lc3plus_dec.h" +#endif /*----------------------------------------------------------------------------------* * Output configuration for renderer (e.g. DirAC, MASA, Binaural Renderer...) @@ -152,14 +160,200 @@ typedef struct ivas_binaural_rendering_conv_module_struct float ***filterTapsRightReal; float ***filterTapsRightImag; +#ifdef SPLIT_REND_WITH_HEAD_ROT + float ****filterStatesLeftReal; + float ****filterStatesLeftImag; +#else float ***filterStatesLeftReal; float ***filterStatesLeftImag; +#endif int16_t numTapsArray[BINAURAL_CONVBANDS]; int16_t numTaps; } BINRENDERER_CONV_MODULE, *BINRENDERER_CONV_MODULE_HANDLE; +#ifdef SPLIT_REND_WITH_HEAD_ROT +/* binaural split rendering head rotation data structure */ +typedef struct ivas_binaural_head_rot_split_rendering_md_struct +{ + float pred_mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float pred_mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float gd; + float gd2; + int16_t pred_mat_re_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + int16_t pred_mat_im_idx[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + int16_t gd_idx; + int16_t gd2_idx; +} BIN_HR_SPLIT_REND_MD, *BIN_HR_SPLIT_REND_MD_HANDLE; + +typedef struct ivas_split_rend_huffman_cfg_t +{ + const int32_t *codebook; + int16_t min_len; + int16_t max_len; + int16_t sym_len; +} ivas_split_rend_huffman_cfg_t; + +typedef struct ivas_binaural_head_rot_split_rendering_huff_struct +{ + ivas_split_rend_huffman_cfg_t pred; + int16_t pred_idx_trav[IVAS_SPLIT_REND_PRED_QUANT_PNTS]; + int16_t pred_base2_code_len; + ivas_split_rend_huffman_cfg_t gd; + int16_t gd_base2_code_len; + int16_t gd_idx_trav[IVAS_SPLIT_REND_D_QUANT_PNTS]; + ivas_split_rend_huffman_cfg_t p_gd; + int16_t p_gd_base2_code_len; + int16_t p_gd_idx_trav[IVAS_SPLIT_REND_D_QUANT_PNTS]; + ivas_split_rend_huffman_cfg_t p_gd_diff; + int16_t p_gd_diff_base2_code_len; + int16_t p_gd_diff_idx_trav[IVAS_SPLIT_REND_D_QUANT_PNTS]; +} BIN_HR_SPLIT_REND_HUFF, *BIN_HR_SPLIT_REND_HUFF_HANDLE; + +typedef struct ivas_binaural_head_rot_split_pre_rendering_struct +{ + BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES - 1][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; + float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; + BIN_HR_SPLIT_REND_HUFF huff_cfg; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbSynRotBinDec[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS]; +#endif +} BIN_HR_SPLIT_PRE_REND, *BIN_HR_SPLIT_PRE_REND_HANDLE; + +typedef struct ivas_binaural_head_rot_split_post_rendering_struct +{ + BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; + IVAS_QUATERNION QuaternionsPre[MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t low_Res; + + float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; + BIN_HR_SPLIT_REND_HUFF huff_cfg; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + float mixer_mat_re[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float mixer_mat_im[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float gd_mem[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS]; +#else + float mixer_mat_re[1][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float mixer_mat_im[1][MAX_SPLIT_REND_MD_BANDS][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float gd_mem[1][MAX_SPLIT_REND_MD_BANDS]; +#endif + int16_t cf_flag; + HANDLE_CLDFB_FILTER_BANK cldfbAna[BINAURAL_CHANNELS]; + HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS]; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbSynReconsBinDec[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS]; +#endif +} BIN_HR_SPLIT_POST_REND, *BIN_HR_SPLIT_POST_REND_HANDLE; + +typedef struct ivas_binaural_head_rot_split_rendering_lcld_enc_struct +{ + void *pLcld_enc; + int32_t iChannels; + CQMFEncoder *psCQMFEncoder; + float ***pppfCQMFReal; + float ***pppfCQMFImag; +#ifdef CLDFB_DEBUG + FILE *cldfbIn; + int numFrame; +#endif +} BIN_HR_SPLIT_LCLD_ENC, *BIN_HR_SPLIT_LCLD_ENC_HANDLE; + +#ifdef SPLIT_REND_PLC +typedef struct +{ + float Cldfb_Prev_BinReal[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_Prev_BinImag[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX + CLDFB_PLC_XF][CLDFB_NO_CHANNELS_MAX]; +#if CLDFB_PLC_XF > 0 + float xf_bet[2][CLDFB_NO_CHANNELS_MAX][CLDFB_PLC_XF]; +#endif +} CLDFB_PLC, *CLDFB_PLC_HANDLE; + +typedef struct +{ + CLDFB_PLC CldfbPLC_state; + int16_t prev_bfi; + int16_t bf_count; +} SPLIT_REND_PLC_STRUCT, *SPLIT_REND_PLC_HANDLE; +#endif + +typedef struct ivas_binaural_head_rot_split_rendering_lcld_dec_struct +{ + void *pLcld_dec; + int32_t iChannels; + CQMFDecoder *psCQMFDecoder; + float ***pppfDecCQMFReal; + float ***pppfDecCQMFImag; +#ifdef CLDFB_DEBUG + FILE *cldfbOut; + int numFrame; +#endif +#ifdef SPLIT_REND_PLC + SPLIT_REND_PLC_HANDLE hSplitRendPLC; +#endif +} BIN_HR_SPLIT_LCLD_DEC, *BIN_HR_SPLIT_LCLD_DEC_HANDLE; + +typedef struct +{ +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbAna[( 1 + MAX_HEAD_ROT_POSES ) * BINAURAL_CHANNELS]; +#else + /* TODO(sgi): rename to "cldfb" during harmonization - these handles are sometimes also used for synthesis */ + HANDLE_CLDFB_FILTER_BANK cldfbAna[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; +#endif +} CLDFB_HANDLES_WRAPPER, *CLDFB_HANDLES_WRAPPER_HANDLE; + +#ifdef SPLIT_REND_WITH_HEAD_ROT +typedef struct +{ + int16_t num_poses; + float relative_head_poses[MAX_HEAD_ROT_POSES][3]; + int16_t dof; + int16_t hq_mode; + IVAS_SPLIT_REND_ROT_AXIS rot_axis; +#ifdef SPLIT_REND_LC3PLUS + IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; +#endif +} MULTI_BIN_REND_POSE_DATA; +#endif + +#ifdef SPLIT_REND_LC3PLUS +/* Forward declaration of TD_OBJECT_RENDERER_HANDLE. + This avoids shifting the entire definition of TD Renderer structs above + this line, which could cause merge conflicts. + Can be cleaned up later. */ +typedef struct ivas_binaural_td_rendering_struct *TD_OBJECT_RENDERER_HANDLE; +#endif + +typedef struct +{ + MULTI_BIN_REND_POSE_DATA multiBinPoseData; + BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend; + BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc; + CLDFB_HANDLES_WRAPPER_HANDLE hCldfbHandles; +#ifdef SPLIT_REND_LC3PLUS + IVAS_LC3PLUS_ENC_HANDLE hLc3plusEnc; + TD_OBJECT_RENDERER_HANDLE hTdRendHandles[MAX_HEAD_ROT_POSES - 1]; + float *lc3plusDelayBuffers[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* Used to time-align head pose correction metadata with LC3plus-coded reference audio */ + int32_t lc3plusDelaySamples; +#endif +} SPLIT_REND_WRAPPER; + +typedef struct +{ + MULTI_BIN_REND_POSE_DATA multiBinPoseData; + BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend; + BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec; +#ifdef SPLIT_REND_PLC + int16_t first_good_frame_received; +#endif +#ifdef SPLIT_REND_LC3PLUS + IVAS_LC3PLUS_DEC_HANDLE hLc3plusDec; +#endif +} SPLIT_POST_REND_WRAPPER; +#endif /*----------------------------------------------------------------------------------* * EFAP structures @@ -251,6 +445,9 @@ typedef struct IVAS_QUATERNION headPositions[RENDERER_HEAD_POSITIONS_PER_FRAME]; IVAS_VECTOR3 Pos[RENDERER_HEAD_POSITIONS_PER_FRAME]; float crossfade[L_FRAME48k / RENDERER_HEAD_POSITIONS_PER_FRAME]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; +#endif ivas_orient_trk_state_t *hOrientationTracker; } IVAS_REND_HeadRotData; @@ -273,6 +470,9 @@ typedef struct ivas_binaural_head_track_struct int16_t shd_rot_max_order; ivas_orient_trk_state_t *OrientationTracker; +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; +#endif } HEAD_TRACK_DATA, *HEAD_TRACK_DATA_HANDLE; /*----------------------------------------------------------------------------------* @@ -314,6 +514,9 @@ typedef struct ivas_combined_orientation_struct float procChEneIIR[2][MASA_FREQUENCY_BANDS]; int16_t shd_rot_max_order; IVAS_VECTOR3 listenerPos[MAX_PARAM_SPATIAL_SUBFRAMES]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; +#endif } COMBINED_ORIENTATION_DATA, *COMBINED_ORIENTATION_HANDLE; @@ -337,11 +540,14 @@ typedef struct ivas_roomAcoustics_t typedef struct ivas_render_config_t { -#ifdef DEBUGGING +#if ( defined DEBUGGING ) || ( defined SPLIT_REND_WITH_HEAD_ROT ) ivas_renderTypeOverride renderer_type_override; #endif ivas_roomAcoustics_t roomAcoustics; float directivity[3]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_CONFIG_DATA split_rend_config; +#endif } RENDER_CONFIG_DATA, *RENDER_CONFIG_HANDLE; @@ -724,11 +930,43 @@ typedef struct ivas_crend_state_t typedef struct ivas_binaural_crend_wrapper_struct { int32_t binaural_latency_ns; +#ifdef SPLIT_REND_WITH_HEAD_ROT + CREND_HANDLE hCrend[MAX_HEAD_ROT_POSES]; +#else CREND_HANDLE hCrend; +#endif HRTFS_HANDLE hHrtfCrend; } CREND_WRAPPER, *CREND_WRAPPER_HANDLE; +#ifdef SPLIT_REND_WITH_HEAD_ROT +/* Fastconv binaural data structure */ +typedef struct ivas_binaural_rendering_struct +{ + /* Common variables for all modules */ + IVAS_OUTPUT_SETUP_HANDLE hInputSetup; /* pointer to input spatial format for binaural renderer*/ + EFAP_HANDLE hEFAPdata; /* EFAP structure*/ + float *hoa_dec_mtx; /* pointer to HOA decoder mtx */ + int8_t rotInCldfb; /* Flag to enable rotation within bin Renderer in CLDFB*/ + int16_t max_band; /* band upto which rendering is performed */ + int16_t conv_band; /* band upto which convolution in cldfb domain is performed */ + int16_t timeSlots; /* number of time slots of binaural renderer */ + int16_t nInChannels; /* number input channels */ + int8_t render_lfe; /* Flag to render LFE in binaural rendering*/ + IVAS_FORMAT ivas_format; /* format; corresponds to st_ivas->ivas_format, unless the signal gets transormed to a different domain for rendering */ + + /* Convolution module structure */ + BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule; + + /* Variables related to reverberator module */ + float earlyPartEneCorrection[CLDFB_NO_CHANNELS_MAX]; + REVERB_STRUCT_HANDLE hReverb; + +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t numPoses; +#endif +} BINAURAL_RENDERER, *BINAURAL_RENDERER_HANDLE; +#endif /*------------------------------------------------------------------------------------------* * HRTF structures - htrfs from binary files @@ -869,6 +1107,20 @@ typedef struct ivas_LS_setup_custom } LSSETUP_CUSTOM_STRUCT, *LSSETUP_CUSTOM_HANDLE; + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------------------* + * CLDFB renderer wrapper + *----------------------------------------------------------------------------------*/ + +typedef struct +{ + int32_t binaural_latency_ns; + BINAURAL_RENDERER_HANDLE hCldfbRend; + HRTFS_FASTCONV_HANDLE hHrtfFastConv; +} CLDFB_REND_WRAPPER; +#endif + /* Channel types in a channel-based config */ typedef enum { diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 4e75d5fea8d18b56814306cae5f13a2392158b12..6bd6ff62b2d65f5b20b89c1b0a0aa20733e83723 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -50,10 +50,22 @@ /* Maximum buffer length (per channel) in samples. * Keep this separate from L_FRAME48k in case we want to support different size later */ -#define MAX_BUFFER_LENGTH_PER_CHANNEL ( L_FRAME48k ) +#define MAX_BUFFER_LENGTH_PER_CHANNEL ( L_FRAME48k ) +#define MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL ( MAX_BUFFER_LENGTH_PER_CHANNEL * 2 ) /* Maximum buffer length (total) in samples. */ +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef REND_STATIC_MEM_OPT +#define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) +#define MAX_CLDFB_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) +#define MAX_BIN_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS ) +#else +#define MAX_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) +#endif + +#else #define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) +#endif /* Frame size required when rendering to binaural */ #define BINAURAL_RENDERING_FRAME_SIZE_MS 20 @@ -90,6 +102,16 @@ typedef struct const LSSETUP_CUSTOM_STRUCT *pCustomLsOut; const EFAP_WRAPPER *pEfapOutWrapper; const IVAS_REND_HeadRotData *pHeadRotData; +#ifdef SPLIT_REND_WITH_HEAD_ROT + const RENDER_CONFIG_HANDLE *hhRendererConfig; +#endif +#ifdef SPLIT_REND_PLC + const int16_t *pSplitRendBFI; +#endif +#ifdef SPLIT_REND_LC3PLUS + const SPLIT_REND_WRAPPER *pSplitRendWrapper; +#endif + /* TODO @Philips : would this be a better place to store the render config data? * bearing in mind we could have multiple inputs to the renderer, we might neeed to accomodate * multiple rendering configurations unless one global one can be used. If this is not relevant, @@ -104,7 +126,9 @@ typedef struct IVAS_REND_AudioConfig inConfig; IVAS_REND_InputId id; IVAS_REND_AudioBuffer inputBuffer; +#ifndef REND_STATIC_MEM_OPT float bufferData[MAX_BUFFER_LENGTH]; +#endif float gain; /* Linear, not in dB */ rendering_context ctx; int32_t numNewSamplesPerChannel; /* Used to keep track how much new audio was fed before rendering current frame */ @@ -119,6 +143,12 @@ typedef struct CREND_WRAPPER_HANDLE crendWrapper; REVERB_HANDLE hReverb; rotation_matrix rot_mat_prev; +#ifdef SPLIT_REND_LC3PLUS + TDREND_WRAPPER splitTdRendWrappers[MAX_HEAD_ROT_POSES - 1]; /* Additional TD Rend instances used for split rendering */ +#endif +#ifdef REND_STATIC_MEM_OPT + float *bufferData; +#endif int16_t nonDiegeticPan; float nonDiegeticPanGain; OMASA_ANA_HANDLE hOMasa; @@ -147,11 +177,17 @@ typedef struct EFAP_WRAPPER efapInWrapper; TDREND_WRAPPER tdRendWrapper; CREND_WRAPPER_HANDLE crendWrapper; +#ifdef SPLIT_REND_LC3PLUS_MC + TDREND_WRAPPER splitTdRendWrappers[MAX_HEAD_ROT_POSES - 1]; /* Additional TD Rend instances used for split rendering */ +#endif REVERB_HANDLE hReverb; rotation_gains rot_gains_prev; int16_t nonDiegeticPan; float nonDiegeticPanGain; lfe_routing lfeRouting; +#ifdef REND_STATIC_MEM_OPT + float *bufferData; +#endif MCMASA_ANA_HANDLE hMcMasa; } input_mc; @@ -159,11 +195,35 @@ typedef struct { input_base base; pan_matrix hoaDecMtx; +#ifdef SPLIT_REND_WITH_HEAD_ROT + CLDFB_REND_WRAPPER cldfbRendWrapper; + SPLIT_REND_WRAPPER splitRendWrapper; +#endif CREND_WRAPPER_HANDLE crendWrapper; +#ifdef SPLIT_REND_WITH_HEAD_ROT + rotation_gains rot_gains_prev[MAX_HEAD_ROT_POSES]; +#else rotation_gains rot_gains_prev; + +#endif + +#ifdef REND_STATIC_MEM_OPT + float *bufferData; +#endif DIRAC_ANA_HANDLE hDirAC; } input_sba; +#ifdef SPLIT_REND_WITH_HEAD_ROT +typedef struct +{ + input_base base; + SPLIT_POST_REND_WRAPPER splitPostRendWrapper; +#ifdef REND_STATIC_MEM_OPT + float *bufferData; +#endif +} input_split_post_rend; +#endif + /* Due to API of some rendering methods, the renderer has to use the decoder struct. Only struct members relevant for rendering will be initialized, therefore typedef as "dummy" decoder struct */ typedef Decoder_Struct DecoderDummy; @@ -174,6 +234,9 @@ typedef struct DecoderDummy *decDummy; MASA_METADATA_FRAME masaMetadata; bool metadataHasBeenFed; +#ifdef REND_STATIC_MEM_OPT + float *bufferData; +#endif MASA_PREREND_HANDLE hMasaPrerend; } input_masa; @@ -190,14 +253,25 @@ struct IVAS_REND input_mc inputsMc[RENDERER_MAX_MC_INPUTS]; input_sba inputsSba[RENDERER_MAX_SBA_INPUTS]; input_masa inputsMasa[RENDERER_MAX_MASA_INPUTS]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + input_split_post_rend inputsSplitPost[RENDERER_MAX_BIN_INPUTS]; +#endif /* TODO @Philips - inputConfig should not be stored here, but read from e.g. input_mc->input_base.inConfig, please remove this */ IVAS_REND_AudioConfig inputConfig; IVAS_REND_AudioConfig outputConfig; EFAP_WRAPPER efapOutWrapper; IVAS_LSSETUP_CUSTOM_STRUCT customLsOut; +#ifdef SPLIT_REND_LC3PLUS + SPLIT_REND_WRAPPER splitRendWrapper; + IVAS_REND_AudioBuffer splitRendEncBuffer; +#endif IVAS_REND_HeadRotData headRotData; +#ifdef SPLIT_REND_PLC + int16_t splitRendBFI; +#endif + EXTERNAL_ORIENTATION_HANDLE hExternalOrientationData; COMBINED_ORIENTATION_HANDLE hCombinedOrientationData; @@ -211,6 +285,30 @@ struct IVAS_REND * Local functions *-------------------------------------------------------------------*/ +#ifdef REND_STATIC_MEM_OPT +static ivas_error allocateInputBaseBufferData( float **data, const int16_t data_size ) +{ + *data = (float *) malloc( data_size * sizeof( float ) ); + if ( *data == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for input base buffer data" ); + } + + return IVAS_ERR_OK; +} + +static void freeInputBaseBufferData( float **data ) +{ + if ( *data != NULL ) + { + free( *data ); + *data = NULL; + } + + return; +} +#endif + static IVAS_QUATERNION quaternionInit( void ) { @@ -228,6 +326,106 @@ static float *getSmplPtr( return buffer.data + chnlIdx * buffer.config.numSamplesPerChannel + smplIdx; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +static void convertBitsBufferToInternalBitsBuff( + const IVAS_REND_BitstreamBuffer outBits, + ivas_split_rend_bits_t *hBits ) +{ + hBits->bits_buf = outBits.bits; + hBits->bits_read = outBits.config.bitsRead; + hBits->bits_written = outBits.config.bitsWritten; + hBits->buf_len = outBits.config.bufLenInBytes; +#ifdef SPLIT_REND_LC3PLUS + hBits->codec = outBits.config.codec; + hBits->pose_correction = outBits.config.poseCorrection; +#endif + + return; +} + +static void convertInternalBitsBuffToBitsBuffer( + IVAS_REND_BitstreamBuffer *hOutBits, + const ivas_split_rend_bits_t bits ) +{ + hOutBits->bits = bits.bits_buf; + hOutBits->config.bitsRead = bits.bits_read; + hOutBits->config.bitsWritten = bits.bits_written; + hOutBits->config.bufLenInBytes = bits.buf_len; +#ifdef SPLIT_REND_LC3PLUS + hOutBits->config.codec = bits.codec; + hOutBits->config.poseCorrection = bits.pose_correction; +#endif + + return; +} +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT +static void copyBufferToCLDFBarray( + const IVAS_REND_AudioBuffer buffer, + float re[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float im[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ) +{ + uint32_t smplIdx, slotIdx; + uint32_t numCldfbSamples, num_bands; + uint32_t chnlIdx; + const float *readPtr; + + assert( ( buffer.config.is_cldfb == 1 ) && "for time domain input call copyBufferTo2dArray()" ); + readPtr = buffer.data; + numCldfbSamples = ( (uint32_t) buffer.config.numSamplesPerChannel ) >> 1; + num_bands = numCldfbSamples / CLDFB_NO_COL_MAX; + for ( chnlIdx = 0; chnlIdx < (uint32_t) buffer.config.numChannels; ++chnlIdx ) + { + for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX; ++slotIdx ) + { + for ( smplIdx = 0; smplIdx < num_bands; ++smplIdx ) + { + re[chnlIdx][slotIdx][smplIdx] = *readPtr++; + } + for ( smplIdx = 0; smplIdx < num_bands; ++smplIdx ) + { + im[chnlIdx][slotIdx][smplIdx] = *readPtr++; + } + } + } + + return; +} + +static void accumulateCLDFBArrayToBuffer( + float re[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float im[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + IVAS_REND_AudioBuffer *buffer ) +{ + uint32_t smplIdx, slotIdx; + uint32_t numCldfbSamples, num_bands; + uint32_t chnlIdx; + float *writePtr; + + assert( ( buffer->config.is_cldfb == 1 ) && "for time domain input call copyBufferTo2dArray()" ); + writePtr = buffer->data; + numCldfbSamples = ( (uint32_t) buffer->config.numSamplesPerChannel ) >> 1; + num_bands = numCldfbSamples / CLDFB_NO_COL_MAX; + for ( chnlIdx = 0; chnlIdx < (uint32_t) buffer->config.numChannels; ++chnlIdx ) + { + for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX; ++slotIdx ) + { + for ( smplIdx = 0; smplIdx < num_bands; ++smplIdx ) + { + *writePtr++ += re[chnlIdx][slotIdx][smplIdx]; + } + for ( smplIdx = 0; smplIdx < num_bands; ++smplIdx ) + { + *writePtr++ += im[chnlIdx][slotIdx][smplIdx]; + } + } + } + + return; +} +#endif + static void copyBufferTo2dArray( const IVAS_REND_AudioBuffer buffer, float array[MAX_OUTPUT_CHANNELS][L_FRAME48k] ) @@ -236,6 +434,9 @@ static void copyBufferTo2dArray( uint32_t chnlIdx; const float *readPtr; +#ifdef SPLIT_REND_WITH_HEAD_ROT + assert( ( buffer.config.is_cldfb == 0 ) && "for CLDFB input call copyBufferToCLDFBarray()" ); +#endif readPtr = buffer.data; for ( chnlIdx = 0; chnlIdx < (uint32_t) buffer.config.numChannels; ++chnlIdx ) @@ -251,7 +452,7 @@ static void copyBufferTo2dArray( static void accumulate2dArrayToBuffer( float array[MAX_OUTPUT_CHANNELS][L_FRAME48k], - IVAS_REND_AudioBuffer *buffer ) + const IVAS_REND_AudioBuffer *buffer ) { int16_t smplIdx, chnlIdx; float *writePtr; @@ -357,6 +558,12 @@ AUDIO_CONFIG getIvasAudioConfigFromRendAudioConfig( return AUDIO_CONFIG_OBA; case IVAS_REND_AUDIO_CONFIG_BINAURAL: return AUDIO_CONFIG_BINAURAL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB: + return AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB; + case IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + return AUDIO_CONFIG_BINAURAL_SPLIT_PCM; +#endif case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_IR: return AUDIO_CONFIG_BINAURAL_ROOM_IR; case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: @@ -389,6 +596,12 @@ IVAS_REND_AudioConfig getRendAudioConfigFromIvasAudioConfig( return IVAS_REND_AUDIO_CONFIG_STEREO; case AUDIO_CONFIG_BINAURAL: return IVAS_REND_AUDIO_CONFIG_BINAURAL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + case AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB: + return IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB; + case AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + return IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM; +#endif case AUDIO_CONFIG_BINAURAL_ROOM_IR: return IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_IR; case AUDIO_CONFIG_BINAURAL_ROOM_REVERB: @@ -438,6 +651,10 @@ static ivas_error validateOutputAudioConfig( case IVAS_REND_AUDIO_CONFIG_HOA2: case IVAS_REND_AUDIO_CONFIG_HOA3: case IVAS_REND_AUDIO_CONFIG_BINAURAL: +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB: + case IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: +#endif case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: return IVAS_ERR_OK; @@ -512,6 +729,10 @@ ivas_error getAudioConfigNumChannels( break; case IVAS_REND_AUDIO_CONFIG_STEREO: case IVAS_REND_AUDIO_CONFIG_BINAURAL: +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB: + case IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: +#endif case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: case IVAS_REND_AUDIO_CONFIG_MASA2: @@ -943,6 +1164,9 @@ static ivas_error initHeadRotation( { hIvasRend->headRotData.headPositions[i] = quaternionInit(); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + hIvasRend->headRotData.sr_pose_pred_axis = DEFAULT_AXIS; +#endif if ( ( hIvasRend->headRotData.hOrientationTracker = (ivas_orient_trk_state_t *) malloc( sizeof( ivas_orient_trk_state_t ) ) ) == NULL ) { @@ -1003,7 +1227,13 @@ static void initRendInputBase( input_base *inputBase, const IVAS_REND_AudioConfig inConfig, const IVAS_REND_InputId id, - const rendering_context rendCtx ) + const rendering_context rendCtx +#ifdef REND_STATIC_MEM_OPT + , + float *dataBuf, + const int16_t dataBufSize +#endif +) { inputBase->inConfig = inConfig; inputBase->id = id; @@ -1013,10 +1243,17 @@ static void initRendInputBase( inputBase->inputBuffer.config.numSamplesPerChannel = 0; inputBase->inputBuffer.config.numChannels = 0; +#ifndef REND_STATIC_MEM_OPT inputBase->inputBuffer.data = inputBase->bufferData; set_zero( inputBase->bufferData, MAX_BUFFER_LENGTH ); - +#else + inputBase->inputBuffer.data = dataBuf; + if ( inputBase->inputBuffer.data != NULL ) + { + set_zero( inputBase->inputBuffer.data, dataBufSize ); + } +#endif return; } @@ -1048,6 +1285,15 @@ static rendering_context getRendCtx( ctx.pCustomLsOut = &hIvasRend->customLsOut; ctx.pEfapOutWrapper = &hIvasRend->efapOutWrapper; ctx.pHeadRotData = &hIvasRend->headRotData; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ctx.hhRendererConfig = &hIvasRend->hRendererConfig; +#endif +#ifdef SPLIT_REND_PLC + ctx.pSplitRendBFI = &hIvasRend->splitRendBFI; +#endif +#ifdef SPLIT_REND_LC3PLUS + ctx.pSplitRendWrapper = &hIvasRend->splitRendWrapper; +#endif ctx.pCombinedOrientationData = &hIvasRend->hCombinedOrientationData; return ctx; @@ -1070,7 +1316,15 @@ static CREND_WRAPPER defaultCrendWrapper( { CREND_WRAPPER w; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t i; + for ( i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + w.hCrend[i] = NULL; + } +#else w.hCrend = NULL; +#endif w.hHrtfCrend = NULL; w.binaural_latency_ns = 0; @@ -1103,7 +1357,12 @@ static ivas_error initIsmMasaRendering( ivas_td_binaural_close( &inputIsm->tdRendWrapper.hBinRendererTd ); inputIsm->tdRendWrapper.hHrtfTD = NULL; } - ivas_rend_closeCrend( &inputIsm->crendWrapper ); + ivas_rend_closeCrend( &inputIsm->crendWrapper +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 1 +#endif + ); ivas_reverb_close( &inputIsm->hReverb ); if ( ( error = ivas_omasa_ana_open( &inputIsm->hOMasa, inSampleRate, inputIsm->total_num_objects ) ) != IVAS_ERR_OK ) @@ -1124,6 +1383,9 @@ static ivas_error setRendInputActiveIsm( rendering_context rendCtx; IVAS_REND_AudioConfig outConfig; input_ism *inputIsm; +#ifdef SPLIT_REND_LC3PLUS + int16_t i; +#endif inputIsm = (input_ism *) input; rendCtx = inputIsm->base.ctx; @@ -1134,7 +1396,18 @@ static ivas_error setRendInputActiveIsm( return IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED; } - initRendInputBase( &inputIsm->base, inConfig, id, rendCtx ); +#ifdef REND_STATIC_MEM_OPT + if ( ( error = allocateInputBaseBufferData( &inputIsm->bufferData, MAX_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + initRendInputBase( &inputIsm->base, inConfig, id, rendCtx +#ifdef REND_STATIC_MEM_OPT + , + inputIsm->bufferData, MAX_BUFFER_LENGTH +#endif + ); inputIsm->currentPos = defaultObjectPosition(); inputIsm->previousPos = defaultObjectPosition(); @@ -1142,16 +1415,39 @@ static ivas_error setRendInputActiveIsm( inputIsm->hReverb = NULL; inputIsm->tdRendWrapper = defaultTdRendWrapper(); initRotMatrix( inputIsm->rot_mat_prev ); +#ifdef SPLIT_REND_LC3PLUS + for ( i = 0; i < (int16_t) ( sizeof( inputIsm->splitTdRendWrappers ) / sizeof( *inputIsm->splitTdRendWrappers ) ); ++i ) + { + inputIsm->splitTdRendWrappers[i] = defaultTdRendWrapper(); + } +#endif inputIsm->hOMasa = NULL; error = IVAS_ERR_OK; - if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_IR ) + + if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL +#ifdef SPLIT_REND_LC3PLUS + || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif + ) { +#ifndef FIX_SPLIT_REND_MERGE if ( ( error = ivas_rend_openCrend( &inputIsm->crendWrapper, AUDIO_CONFIG_7_1_4, getIvasAudioConfigFromRendAudioConfig( outConfig ), hRendCfg, - NULL, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) + NULL, *rendCtx.pOutSampleRate +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 1 +#endif + ) ) != IVAS_ERR_OK ) { return error; } +#else + if ( ( error = ivas_td_binaural_open_ext( &inputIsm->tdRendWrapper, inConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif } else if ( outConfig == IVAS_REND_AUDIO_CONFIG_MASA1 || outConfig == IVAS_REND_AUDIO_CONFIG_MASA2 ) { @@ -1162,17 +1458,45 @@ static ivas_error setRendInputActiveIsm( } else { +#ifndef FIX_SPLIT_REND_MERGE + if ( ( error = ivas_td_binaural_open_ext( &inputIsm->tdRendWrapper, inConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) + { + if ( ( error = ivas_reverb_open( &( inputIsm->hReverb ), getIvasAudioConfigFromRendAudioConfig( outConfig ), NULL, hRendCfg, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#else if ( ( error = ivas_td_binaural_open_ext( &inputIsm->tdRendWrapper, inConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) { return error; } if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { + if ( ( error = ivas_reverb_open( &( inputIsm->hReverb ), getIvasAudioConfigFromRendAudioConfig( outConfig ), NULL, hRendCfg, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) { return error; } } + else if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_IR ) + { + if ( ( error = ivas_rend_openCrend( &inputIsm->crendWrapper, AUDIO_CONFIG_7_1_4, getIvasAudioConfigFromRendAudioConfig( outConfig ), hRendCfg, + NULL, *rendCtx.pOutSampleRate +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 1 +#endif + ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif } @@ -1183,14 +1507,30 @@ static void clearInputIsm( input_ism *inputIsm ) { rendering_context rendCtx; +#ifdef SPLIT_REND_LC3PLUS + int16_t i; +#endif rendCtx = inputIsm->base.ctx; - initRendInputBase( &inputIsm->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx ); +#ifdef REND_STATIC_MEM_OPT + freeInputBaseBufferData( &inputIsm->base.inputBuffer.data ); +#endif + initRendInputBase( &inputIsm->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx +#ifdef REND_STATIC_MEM_OPT + , + NULL, 0 +#endif + ); /* Free input's internal handles */ - ivas_rend_closeCrend( &inputIsm->crendWrapper ); + ivas_rend_closeCrend( &inputIsm->crendWrapper +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 1 +#endif + ); ivas_reverb_close( &inputIsm->hReverb ); @@ -1199,6 +1539,13 @@ static void clearInputIsm( ivas_td_binaural_close( &inputIsm->tdRendWrapper.hBinRendererTd ); inputIsm->tdRendWrapper.hHrtfTD = NULL; } +#ifdef SPLIT_REND_LC3PLUS + for ( i = 0; i < (int16_t) ( sizeof( inputIsm->splitTdRendWrappers ) / sizeof( *inputIsm->splitTdRendWrappers ) ); ++i ) + { + ivas_td_binaural_close( &inputIsm->splitTdRendWrappers[i].hBinRendererTd ); + inputIsm->splitTdRendWrappers[i].hHrtfTD = NULL; + } +#endif ivas_omasa_ana_close( &( inputIsm->hOMasa ) ); @@ -1791,6 +2138,10 @@ static ivas_error updateMcPanGains( switch ( outConfig ) { case IVAS_REND_AUDIO_CONFIG_BINAURAL: +#ifdef SPLIT_REND_LC3PLUS_MC + case IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB: + case IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: +#endif break; /* Do nothing */ case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: @@ -1837,6 +2188,9 @@ static ivas_error initMcBinauralRendering( RENDER_CONFIG_DATA *hRendCfg ) { ivas_error error; +#ifdef SPLIT_REND_LC3PLUS_MC + int16_t i; +#endif int32_t outSampleRate; /* check if re-initialization */ @@ -1846,7 +2200,23 @@ static ivas_error initMcBinauralRendering( inputMc->tdRendWrapper.hHrtfTD = NULL; } - ivas_rend_closeCrend( &inputMc->crendWrapper ); +#ifdef SPLIT_REND_LC3PLUS_MC + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + if ( inputMc->splitTdRendWrappers[i].hBinRendererTd != NULL ) + { + ivas_td_binaural_close( &inputMc->splitTdRendWrappers[i].hBinRendererTd ); + inputMc->splitTdRendWrappers[i].hHrtfTD = NULL; + } + } +#endif + + ivas_rend_closeCrend( &inputMc->crendWrapper +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 1 +#endif + ); ivas_reverb_close( &inputMc->hReverb ); @@ -1885,6 +2255,27 @@ static ivas_error initMcBinauralRendering( return error; } +#ifdef SPLIT_REND_LC3PLUS_MC + if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + /* Open TD renderer wrappers */ + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + if ( ( error = ivas_td_binaural_open_ext( &inputMc->splitTdRendWrappers[i], + inConfig, + hRendCfg, + &inputMc->customLsInput, + outSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Assert same delay as main TD renderer */ + assert( inputMc->splitTdRendWrappers[i].binaural_latency_ns == inputMc->tdRendWrapper.binaural_latency_ns ); + } + } + +#endif if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { if ( ( error = ivas_reverb_open( &( inputMc->hReverb ), getIvasAudioConfigFromRendAudioConfig( outConfig ), NULL, hRendCfg, outSampleRate ) ) != IVAS_ERR_OK ) @@ -1896,7 +2287,16 @@ static ivas_error initMcBinauralRendering( { if ( ( error = ivas_rend_openCrend( &inputMc->crendWrapper, ( inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) ? AUDIO_CONFIG_7_1_4 : getIvasAudioConfigFromRendAudioConfig( inConfig ), getIvasAudioConfigFromRendAudioConfig( outConfig ), hRendCfg, - NULL, outSampleRate ) ) != IVAS_ERR_OK ) + NULL, outSampleRate +#ifdef SPLIT_REND_WITH_HEAD_ROT + , +#ifdef SPLIT_REND_LC3PLUS_MC + ( ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) || ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) ) ? inputMc->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses : 1 +#else + 1 +#endif +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -1926,7 +2326,12 @@ static ivas_error initMcMasaRendering( ivas_td_binaural_close( &inputMc->tdRendWrapper.hBinRendererTd ); inputMc->tdRendWrapper.hHrtfTD = NULL; } - ivas_rend_closeCrend( &inputMc->crendWrapper ); + ivas_rend_closeCrend( &inputMc->crendWrapper +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 1 +#endif + ); ivas_reverb_close( &inputMc->hReverb ); if ( inputMc->efapInWrapper.hEfap != NULL ) { @@ -2005,6 +2410,9 @@ static ivas_error setRendInputActiveMc( const IVAS_REND_InputId id, RENDER_CONFIG_DATA *hRendCfg ) { +#ifdef SPLIT_REND_LC3PLUS_MC + int16_t i; +#endif ivas_error error; rendering_context rendCtx; IVAS_REND_AudioConfig outConfig; @@ -2019,7 +2427,18 @@ static ivas_error setRendInputActiveMc( return IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED; } - initRendInputBase( &inputMc->base, inConfig, id, rendCtx ); +#ifdef REND_STATIC_MEM_OPT + if ( ( error = allocateInputBaseBufferData( &inputMc->bufferData, MAX_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + initRendInputBase( &inputMc->base, inConfig, id, rendCtx +#ifdef REND_STATIC_MEM_OPT + , + inputMc->bufferData, MAX_BUFFER_LENGTH +#endif + ); setZeroPanMatrix( inputMc->panGains ); inputMc->customLsInput = defaultCustomLs(); inputMc->tdRendWrapper = defaultTdRendWrapper(); @@ -2028,8 +2447,19 @@ static ivas_error setRendInputActiveMc( inputMc->hMcMasa = NULL; initRotGains( inputMc->rot_gains_prev ); inputMc->lfeRouting = defaultLfeRouting( inConfig, inputMc->customLsInput, outConfig, *inputMc->base.ctx.pCustomLsOut ); +#ifdef SPLIT_REND_LC3PLUS_MC + for ( i = 0; i < (int16_t) ( sizeof( inputMc->splitTdRendWrappers ) / sizeof( *inputMc->splitTdRendWrappers ) ); ++i ) + { + inputMc->splitTdRendWrappers[i] = defaultTdRendWrapper(); + } +#endif + +#ifdef SPLIT_REND_LC3PLUS_MC + if ( getAudioConfigType( outConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) +#else if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_IR || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) +#endif { if ( ( error = initMcBinauralRendering( inputMc, inConfig, outConfig, hRendCfg ) ) != IVAS_ERR_OK ) { @@ -2056,11 +2486,22 @@ static ivas_error setRendInputActiveMc( static void clearInputMc( input_mc *inputMc ) { +#ifdef SPLIT_REND_LC3PLUS_MC + int16_t i; +#endif rendering_context rendCtx; rendCtx = inputMc->base.ctx; - initRendInputBase( &inputMc->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx ); +#ifdef REND_STATIC_MEM_OPT + freeInputBaseBufferData( &inputMc->bufferData ); +#endif + initRendInputBase( &inputMc->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx +#ifdef REND_STATIC_MEM_OPT + , + NULL, 0 +#endif + ); /* Free input's internal handles */ if ( inputMc->efapInWrapper.hEfap != NULL ) @@ -2068,7 +2509,12 @@ static void clearInputMc( efap_free_data( &inputMc->efapInWrapper.hEfap ); } - ivas_rend_closeCrend( &inputMc->crendWrapper ); + ivas_rend_closeCrend( &inputMc->crendWrapper +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 1 +#endif + ); ivas_reverb_close( &inputMc->hReverb ); @@ -2078,6 +2524,17 @@ static void clearInputMc( inputMc->tdRendWrapper.hHrtfTD = NULL; } +#ifdef SPLIT_REND_LC3PLUS_MC + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + if ( inputMc->splitTdRendWrappers[i].hBinRendererTd != NULL ) + { + ivas_td_binaural_close( &inputMc->splitTdRendWrappers[i].hBinRendererTd ); + inputMc->splitTdRendWrappers[i].hHrtfTD = NULL; + } + } +#endif + ivas_mcmasa_ana_close( &( inputMc->hMcMasa ) ); return; @@ -2171,7 +2628,52 @@ static ivas_error initSbaPanGainsForSbaOut( return error; } -static ivas_error updateSbaPanGains( +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error +updateSplitPostRendPanGains( + input_split_post_rend *inputSplitPostRend, + const IVAS_REND_AudioConfig outConfig, + RENDER_CONFIG_DATA *hRendCfg ) +{ + ivas_error error; + rendering_context rendCtx; + int16_t numOutChannels; + getAudioConfigNumChannels( outConfig, &numOutChannels ); + + rendCtx = inputSplitPostRend->base.ctx; + ivas_renderSplitGetMultiBinPoseData( + &hRendCfg->split_rend_config, + &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, + rendCtx.pHeadRotData->sr_pose_pred_axis ); + + error = ivas_splitBinPostRendOpen( &inputSplitPostRend->splitPostRendWrapper.hBinHrSplitPostRend, + &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, + *rendCtx.pOutSampleRate +#ifndef SPLIT_REND_LC3PLUS + , + ( inputSplitPostRend->base.inConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) ? 1 : 0 +#endif + ); + if ( error != IVAS_ERR_OK ) + { + return error; + } +#ifndef SPLIT_REND_LC3PLUS + if ( inputSplitPostRend->base.inConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) + { + error = ivas_splitBinLCLDDecOpen( &inputSplitPostRend->splitPostRendWrapper.hSplitBinLCLDDec, *rendCtx.pOutSampleRate, numOutChannels ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + } +#endif + + return IVAS_ERR_OK; +} +#endif +static ivas_error +updateSbaPanGains( input_sba *inputSba, const IVAS_REND_AudioConfig outConfig, RENDER_CONFIG_DATA *hRendCfg ) @@ -2197,13 +2699,82 @@ static ivas_error updateSbaPanGains( case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: switch ( outConfig ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB: + case IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + { + int16_t is_cldfb_in; + + is_cldfb_in = 1; + ivas_renderSplitGetMultiBinPoseData( + &rendCtx.hhRendererConfig[0]->split_rend_config, + &inputSba->splitRendWrapper.multiBinPoseData, + rendCtx.pHeadRotData->sr_pose_pred_axis ); + +#if defined DEBUGGING && defined SPLIT_REND_WITH_HEAD_ROT /* TODO: redundant nested switch SPLIT_REND_WITH_HEAD_ROT */ + if ( hRendCfg->renderer_type_override == RENDER_TYPE_OVERRIDE_FASTCONV ) + + { + assert( inConfig == IVAS_REND_AUDIO_CONFIG_HOA3 && ( *rendCtx.pOutSampleRate == 48000 ) && "split binaural fast conv mode is currently supported with HOA3 input and 48k sampling rate only" ); + error = ivas_rend_openCldfbRend( &inputSba->cldfbRendWrapper, inConfig, outConfig, + &inputSba->splitRendWrapper.multiBinPoseData, + *rendCtx.pOutSampleRate ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + is_cldfb_in = 1; + } + + else +#endif + { + assert( ( *rendCtx.pOutSampleRate == 48000 ) && "split binaural crend mode is currently supported with 48k sampling rate only" ); + error = ivas_rend_openMultiBinCrend( &inputSba->crendWrapper, inConfig, outConfig, + &inputSba->splitRendWrapper.multiBinPoseData, + *rendCtx.pOutSampleRate ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + is_cldfb_in = 0; + } + + error = ivas_split_renderer_open( &inputSba->splitRendWrapper, + &inputSba->base.ctx.hhRendererConfig[0]->split_rend_config, + *rendCtx.pOutSampleRate, + is_cldfb_in, ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ); + break; + } +#endif case IVAS_REND_AUDIO_CONFIG_BINAURAL: - error = ivas_rend_openCrend( &inputSba->crendWrapper, - getIvasAudioConfigFromRendAudioConfig( inConfig ), - getIvasAudioConfigFromRendAudioConfig( outConfig ), - hRendCfg, - NULL, - *rendCtx.pOutSampleRate ); +#if defined DEBUGGING && defined SPLIT_REND_WITH_HEAD_ROT + if ( hRendCfg->renderer_type_override == RENDER_TYPE_OVERRIDE_FASTCONV ) + + { + error = ivas_rend_openCldfbRend( &inputSba->cldfbRendWrapper, inConfig, outConfig, + &inputSba->splitRendWrapper.multiBinPoseData, + *rendCtx.pOutSampleRate ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + } + else +#endif + { + error = ivas_rend_openCrend( &inputSba->crendWrapper, + getIvasAudioConfigFromRendAudioConfig( inConfig ), + getIvasAudioConfigFromRendAudioConfig( outConfig ), + hRendCfg, + NULL, + *rendCtx.pOutSampleRate +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 1 +#endif + ); + } break; case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: @@ -2217,7 +2788,12 @@ static ivas_error updateSbaPanGains( getIvasAudioConfigFromRendAudioConfig( outConfig ), hRendCfg, NULL, - *rendCtx.pOutSampleRate ); + *rendCtx.pOutSampleRate +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 1 +#endif + ); break; default: return IVAS_ERR_INVALID_OUTPUT_FORMAT; @@ -2238,19 +2814,60 @@ static ivas_error updateSbaPanGains( return IVAS_ERR_OK; } -static ivas_error initSbaMasaRendering( +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error setRendInputActiveSplitPostRend( + void *input, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_InputId id, + RENDER_CONFIG_DATA *hRendCfg ) +{ + ivas_error error; + rendering_context rendCtx; + IVAS_REND_AudioConfig outConfig; + input_split_post_rend *inputSplitPostRend; + + inputSplitPostRend = (input_split_post_rend *) input; + rendCtx = inputSplitPostRend->base.ctx; + outConfig = *rendCtx.pOutConfig; + +#ifdef REND_STATIC_MEM_OPT + if ( ( error = allocateInputBaseBufferData( &inputSplitPostRend->bufferData, MAX_BIN_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + initRendInputBase( &inputSplitPostRend->base, inConfig, id, rendCtx +#ifdef REND_STATIC_MEM_OPT + , + inputSplitPostRend->bufferData, MAX_BIN_BUFFER_LENGTH +#endif + ); + + if ( ( error = updateSplitPostRendPanGains( inputSplitPostRend, outConfig, hRendCfg ) ) != IVAS_ERR_OK ) + { + return error; + } + return IVAS_ERR_OK; +} +#endif + +static ivas_error initSbaMasaRendering( input_sba *inputSba, int32_t inSampleRate ) { ivas_error error; - ivas_rend_closeCrend( &inputSba->crendWrapper ); + ivas_rend_closeCrend( &inputSba->crendWrapper +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 1 +#endif + ); if ( ( error = ivas_dirac_ana_open( &inputSba->hDirAC, inSampleRate ) ) != IVAS_ERR_OK ) { return error; } - return IVAS_ERR_OK; } @@ -2264,6 +2881,9 @@ static ivas_error setRendInputActiveSba( rendering_context rendCtx; IVAS_REND_AudioConfig outConfig; input_sba *inputSba; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; +#endif inputSba = (input_sba *) input; rendCtx = inputSba->base.ctx; @@ -2274,11 +2894,30 @@ static ivas_error setRendInputActiveSba( return IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED; } - initRendInputBase( &inputSba->base, inConfig, id, rendCtx ); +#ifdef REND_STATIC_MEM_OPT + if ( ( error = allocateInputBaseBufferData( &inputSba->bufferData, MAX_CLDFB_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + initRendInputBase( &inputSba->base, inConfig, id, rendCtx +#ifdef REND_STATIC_MEM_OPT + , + inputSba->bufferData, MAX_CLDFB_BUFFER_LENGTH +#endif + ); setZeroPanMatrix( inputSba->hoaDecMtx ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + inputSba->crendWrapper = NULL; + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + initRotGains( inputSba->rot_gains_prev[pos_idx] ); + } +#else inputSba->crendWrapper = NULL; inputSba->hDirAC = NULL; initRotGains( inputSba->rot_gains_prev ); +#endif if ( outConfig == IVAS_REND_AUDIO_CONFIG_MASA1 || outConfig == IVAS_REND_AUDIO_CONFIG_MASA2 ) { @@ -2296,6 +2935,42 @@ static ivas_error setRendInputActiveSba( return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +static void clearInputSplitRend( + input_split_post_rend *inputSplitRend ) +{ + rendering_context rendCtx; + + rendCtx = inputSplitRend->base.ctx; + +#ifdef REND_STATIC_MEM_OPT + freeInputBaseBufferData( &inputSplitRend->bufferData ); +#endif + initRendInputBase( &inputSplitRend->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx +#ifdef REND_STATIC_MEM_OPT + , + NULL, 0 +#endif + ); + if ( inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend != NULL ) + { + ivas_splitBinPostRendClose( &inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend ); + } + if ( inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec != NULL ) + { + ivas_splitBinLCLDDecClose( &inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec ); + } +#ifdef SPLIT_REND_LC3PLUS + if ( inputSplitRend->splitPostRendWrapper.hLc3plusDec != NULL ) + { + IVAS_LC3PLUS_DEC_Close( &inputSplitRend->splitPostRendWrapper.hLc3plusDec ); + } +#endif + + return; +} + +#endif static void clearInputSba( input_sba *inputSba ) { @@ -2303,10 +2978,27 @@ static void clearInputSba( rendCtx = inputSba->base.ctx; - initRendInputBase( &inputSba->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx ); +#ifdef REND_STATIC_MEM_OPT + freeInputBaseBufferData( &inputSba->bufferData ); +#endif + initRendInputBase( &inputSba->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx +#ifdef REND_STATIC_MEM_OPT + , + NULL, 0 +#endif + ); /* Free input's internal handles */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &inputSba->crendWrapper, inputSba->splitRendWrapper.multiBinPoseData.num_poses ); + if ( inputSba->cldfbRendWrapper.hCldfbRend != NULL ) + { + ivas_rend_closeCldfbRend( &inputSba->cldfbRendWrapper ); + } + ivas_split_renderer_close( &inputSba->splitRendWrapper ); +#else ivas_rend_closeCrend( &inputSba->crendWrapper ); +#endif ivas_dirac_ana_close( &( inputSba->hDirAC ) ); @@ -2489,7 +3181,11 @@ static ivas_error initMasaDummyDecForBinauralOut( decDummy->mc_mode = MC_MODE_NONE; /* Todo Nokia: This should be also refactored in such way that it is not checked if not in MC mode */ ivas_output_init( &( decDummy->hOutSetup ), output_config ); - if ( output_config == AUDIO_CONFIG_BINAURAL ) + if ( output_config == AUDIO_CONFIG_BINAURAL +#ifdef SPLIT_REND_WITH_HEAD_ROT + || output_config == AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB || output_config == AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif + ) { decDummy->renderer_type = RENDERER_BINAURAL_PARAMETRIC; } @@ -2586,6 +3282,11 @@ static DecoderDummy *initDecoderDummy( decDummy->hDecoderConfig->voip_active = 0; decDummy->hBinRenderer = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + decDummy->splitBinRend.hSplitRendBits = NULL; + decDummy->splitBinRend.hMultiBinCldfbData = NULL; + ivas_init_split_rend_handles( &decDummy->splitBinRend.splitrend ); +#endif decDummy->hEFAPdata = NULL; decDummy->hCrendWrapper = NULL; decDummy->hHrtfTD = NULL; @@ -2688,7 +3389,18 @@ static ivas_error setRendInputActiveMasa( return IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED; } - initRendInputBase( &inputMasa->base, inConfig, id, rendCtx ); +#ifdef REND_STATIC_MEM_OPT + if ( ( error = allocateInputBaseBufferData( &inputMasa->bufferData, MAX_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + initRendInputBase( &inputMasa->base, inConfig, id, rendCtx +#ifdef REND_STATIC_MEM_OPT + , + inputMasa->bufferData, MAX_BUFFER_LENGTH +#endif + ); if ( ( error = getAudioConfigNumChannels( inConfig, &numInChannels ) ) != IVAS_ERR_OK ) { @@ -2804,13 +3516,82 @@ static void clearInputMasa( rendCtx = inputMasa->base.ctx; +#ifdef REND_STATIC_MEM_OPT + freeInputBaseBufferData( &inputMasa->bufferData ); +#endif + masaPrerendClose( &inputMasa->hMasaPrerend ); - initRendInputBase( &inputMasa->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx ); + initRendInputBase( &inputMasa->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx +#ifdef REND_STATIC_MEM_OPT + , + NULL, 0 +#endif + ); freeDecoderDummy( &inputMasa->decDummy ); return; } +#ifdef SPLIT_REND_LC3PLUS +static ivas_error initSplitRend( SPLIT_REND_WRAPPER *pSplitRendWrapper, IVAS_REND_AudioBuffer *pSplitRendEncBuffer, const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, IVAS_REND_HeadRotData headRotData, const int32_t outputSampleRate, const IVAS_REND_AudioConfig outConfig ) +{ + ivas_error error; + IVAS_REND_AudioBufferConfig bufConfig; + + ivas_init_split_rend_handles( pSplitRendWrapper ); + if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + + if ( pSplit_rend_config->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + ivas_renderSplitGetMultiBinPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData, headRotData.sr_pose_pred_axis ); + } + else if ( pSplit_rend_config->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) + { + ivas_renderSplitUpdateNoCorrectionPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData ); + } + + error = ivas_split_renderer_open( pSplitRendWrapper, + pSplit_rend_config, + outputSampleRate, + + 0, +#ifdef SPLIT_REND_CLDFB_ISM + ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 +#else + 0 +#endif + ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + + bufConfig.numSamplesPerChannel = MAX_BUFFER_LENGTH_PER_CHANNEL; + bufConfig.numChannels = BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES; + bufConfig.is_cldfb = 0; + pSplitRendEncBuffer->config = bufConfig; + pSplitRendEncBuffer->data = malloc( bufConfig.numChannels * bufConfig.numSamplesPerChannel * sizeof( float ) ); + if ( pSplitRendEncBuffer->data == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + } + else + { + IVAS_REND_AudioBufferConfig bufConfig2; + + bufConfig2.numSamplesPerChannel = 0; + bufConfig2.numChannels = 0; + bufConfig2.is_cldfb = 0; + pSplitRendEncBuffer->config = bufConfig2; + pSplitRendEncBuffer->data = NULL; + } + + return IVAS_ERR_OK; +} +#endif + ivas_error IVAS_REND_Open( IVAS_REND_HANDLE *phIvasRend, const int32_t outputSampleRate, @@ -2819,6 +3600,9 @@ ivas_error IVAS_REND_Open( const float nonDiegeticPanGain ) { int16_t i; +#ifdef SPLIT_REND_LC3PLUS + int16_t j; +#endif IVAS_REND_HANDLE hIvasRend; ivas_error error; int16_t numOutChannels; @@ -2894,10 +3678,25 @@ ivas_error IVAS_REND_Open( /* Initialize inputs */ for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) { - initRendInputBase( &hIvasRend->inputsIsm[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ) ); + initRendInputBase( &hIvasRend->inputsIsm[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ) +#ifdef REND_STATIC_MEM_OPT + , + NULL, 0 +#endif + ); hIvasRend->inputsIsm[i].crendWrapper = NULL; hIvasRend->inputsIsm[i].hReverb = NULL; hIvasRend->inputsIsm[i].tdRendWrapper.hBinRendererTd = NULL; +#ifdef SPLIT_REND_LC3PLUS + for ( j = 0; j < (int16_t) ( sizeof( hIvasRend->inputsIsm[i].splitTdRendWrappers ) / sizeof( *hIvasRend->inputsIsm[i].splitTdRendWrappers ) ); ++j ) + { + hIvasRend->inputsIsm[i].splitTdRendWrappers[j].hBinRendererTd = NULL; + hIvasRend->inputsIsm[i].splitTdRendWrappers[j].hHrtfTD = NULL; + } +#endif +#ifdef REND_STATIC_MEM_OPT + hIvasRend->inputsIsm[i].bufferData = NULL; +#endif hIvasRend->inputsIsm[i].nonDiegeticPan = nonDiegeticPan; hIvasRend->inputsIsm[i].nonDiegeticPanGain = nonDiegeticPanGain; hIvasRend->inputsIsm[i].hOMasa = NULL; @@ -2905,11 +3704,19 @@ ivas_error IVAS_REND_Open( for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { - initRendInputBase( &hIvasRend->inputsMc[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ) ); + initRendInputBase( &hIvasRend->inputsMc[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ) +#ifdef REND_STATIC_MEM_OPT + , + NULL, 0 +#endif + ); hIvasRend->inputsMc[i].efapInWrapper.hEfap = NULL; hIvasRend->inputsMc[i].crendWrapper = NULL; hIvasRend->inputsMc[i].hReverb = NULL; hIvasRend->inputsMc[i].tdRendWrapper.hBinRendererTd = NULL; +#ifdef REND_STATIC_MEM_OPT + hIvasRend->inputsMc[i].bufferData = NULL; +#endif hIvasRend->inputsMc[i].nonDiegeticPan = nonDiegeticPan; hIvasRend->inputsMc[i].nonDiegeticPanGain = nonDiegeticPanGain; hIvasRend->inputsMc[i].hMcMasa = NULL; @@ -2917,18 +3724,61 @@ ivas_error IVAS_REND_Open( for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) { - initRendInputBase( &hIvasRend->inputsSba[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ) ); + initRendInputBase( &hIvasRend->inputsSba[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ) +#ifdef REND_STATIC_MEM_OPT + , + NULL, 0 +#endif + ); hIvasRend->inputsSba[i].crendWrapper = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hIvasRend->inputsSba[i].cldfbRendWrapper.hCldfbRend = NULL; + hIvasRend->inputsSba[i].cldfbRendWrapper.hHrtfFastConv = NULL; + ivas_init_split_rend_handles( &hIvasRend->inputsSba[i].splitRendWrapper ); +#endif +#ifdef REND_STATIC_MEM_OPT + hIvasRend->inputsSba[i].bufferData = NULL; +#endif hIvasRend->inputsSba[i].hDirAC = NULL; } for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { - initRendInputBase( &hIvasRend->inputsMasa[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ) ); + initRendInputBase( &hIvasRend->inputsMasa[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ) +#ifdef REND_STATIC_MEM_OPT + , + NULL, 0 +#endif + ); hIvasRend->inputsMasa[i].decDummy = NULL; hIvasRend->inputsMasa[i].metadataHasBeenFed = false; +#ifdef REND_STATIC_MEM_OPT + hIvasRend->inputsMasa[i].bufferData = NULL; +#endif hIvasRend->inputsMasa[i].hMasaPrerend = NULL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + { + initRendInputBase( &hIvasRend->inputsSplitPost[i].base, + IVAS_REND_AUDIO_CONFIG_UNKNOWN, + 0, + getRendCtx( hIvasRend ) +#ifdef REND_STATIC_MEM_OPT + , + NULL, 0 +#endif + ); + ivas_init_split_post_rend_handles( &hIvasRend->inputsSplitPost[i].splitPostRendWrapper ); +#ifdef SPLIT_REND_PLC + hIvasRend->splitRendBFI = 0; +#endif +#ifdef REND_STATIC_MEM_OPT + hIvasRend->inputsSplitPost[i].bufferData = NULL; + +#endif + } +#endif return IVAS_ERR_OK; } @@ -3161,6 +4011,15 @@ static ivas_error getInputById( } pInputBase = &hIvasRend->inputsMasa[inputIndex].base; break; +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: + if ( inputIndex > RENDERER_MAX_BIN_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base; + break; +#endif default: return IVAS_ERR_INVALID_INPUT_ID; } @@ -3226,6 +4085,15 @@ static ivas_error getConstInputById( } pInputBase = &hIvasRend->inputsMasa[inputIndex].base; break; +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: + if ( inputIndex > RENDERER_MAX_BIN_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base; + break; +#endif default: return IVAS_ERR_INVALID_INPUT_ID; } @@ -3283,6 +4151,18 @@ static ivas_error findFreeInputSlot( return IVAS_ERR_OK; } +#ifdef SPLIT_REND_LC3PLUS +static void closeSplitRend( SPLIT_REND_WRAPPER *pSplitRendWrapper, IVAS_REND_AudioBuffer *pSplitRendEncBuffer ) +{ + ivas_split_renderer_close( pSplitRendWrapper ); + if ( pSplitRendEncBuffer->data != NULL ) + { + free( pSplitRendEncBuffer->data ); + } + pSplitRendEncBuffer->config.numChannels = 0; + pSplitRendEncBuffer->config.numSamplesPerChannel = 0; +} +#endif /*-------------------------------------------------------------------* * IVAS_REND_AddInput() @@ -3316,6 +4196,21 @@ ivas_error IVAS_REND_AddInput( inputsArray = hIvasRend->inputsIsm; inputStructSize = sizeof( *hIvasRend->inputsIsm ); activateInput = setRendInputActiveIsm; +#ifdef SPLIT_REND_LC3PLUS + if ( hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) + { + /* Hack to override default split rendering codec from Dolby CLDFB to LC3plus. + This will not be necessary once the split rendering codec becomes selectable by the lib user. */ + closeSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); +#ifndef SPLIT_REND_CLDFB_ISM + hIvasRend->hRendererConfig->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_LC3PLUS; +#endif + if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif break; case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: maxNumInputsOfType = RENDERER_MAX_MC_INPUTS; @@ -3335,6 +4230,14 @@ ivas_error IVAS_REND_AddInput( inputStructSize = sizeof( *hIvasRend->inputsMasa ); activateInput = setRendInputActiveMasa; break; +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: + maxNumInputsOfType = RENDERER_MAX_BIN_INPUTS; + inputsArray = hIvasRend->inputsSplitPost; + inputStructSize = sizeof( *hIvasRend->inputsSplitPost ); + activateInput = setRendInputActiveSplitPostRend; + break; +#endif default: return IVAS_ERR_INVALID_INPUT_FORMAT; } @@ -3406,7 +4309,11 @@ ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( return error; } +#ifdef SPLIT_REND_LC3PLUS_MC + if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) +#else if ( hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL || hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_IR || hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) +#endif { if ( ( error = initMcBinauralRendering( inputMc, inputMc->base.inConfig, hIvasRend->outputConfig, hIvasRend->hRendererConfig ) ) != IVAS_ERR_OK ) { @@ -3594,6 +4501,11 @@ ivas_error IVAS_REND_RemoveInput( case IVAS_REND_AUDIO_CONFIG_TYPE_MASA: clearInputMasa( (input_masa *) inputBase ); break; +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: + clearInputSplitRend( (input_split_post_rend *) inputBase ); + break; +#endif default: return IVAS_ERR_INVALID_INPUT_FORMAT; } @@ -3716,10 +4628,61 @@ ivas_error IVAS_REND_GetDelay( { if ( hIvasRend->inputsSba[i].base.inConfig != IVAS_REND_AUDIO_CONFIG_UNKNOWN ) { - latency_ns = ( hIvasRend->inputsSba[i].crendWrapper != NULL ) ? hIvasRend->inputsSba[i].crendWrapper->binaural_latency_ns : 0; +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( hIvasRend->inputsSba[i].splitRendWrapper.hBinHrSplitPreRend != NULL ) + { +#if ( defined DEBUGGING ) || ( defined SPLIT_REND_WITH_HEAD_ROT ) + if ( hIvasRend->hRendererConfig->renderer_type_override == RENDER_TYPE_OVERRIDE_FASTCONV ) + { + latency_ns = hIvasRend->inputsSba[i].cldfbRendWrapper.binaural_latency_ns; + } + else +#endif + { + latency_ns = ( hIvasRend->inputsSba[i].crendWrapper != NULL ) ? hIvasRend->inputsSba[i].crendWrapper->binaural_latency_ns : 0; + } + max_latency_ns = max( max_latency_ns, latency_ns ); + } + else if ( hIvasRend->inputsSba[i].cldfbRendWrapper.hCldfbRend != NULL ) + { + latency_ns = hIvasRend->inputsSba[i].cldfbRendWrapper.binaural_latency_ns; + latency_ns += IVAS_FB_DEC_DELAY_NS; + max_latency_ns = max( max_latency_ns, latency_ns ); + } + else +#endif + { + latency_ns = ( hIvasRend->inputsSba[i].crendWrapper != NULL ) ? hIvasRend->inputsSba[i].crendWrapper->binaural_latency_ns : 0; + max_latency_ns = max( max_latency_ns, latency_ns ); + } + } + } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; i++ ) + { + if ( hIvasRend->inputsSplitPost[i].base.inConfig != IVAS_REND_AUDIO_CONFIG_UNKNOWN ) + { +#ifdef SPLIT_REND_LC3PLUS + latency_ns = 0; + if ( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hLc3plusDec != NULL ) + { + int32_t lc3plusDelaySamples; + IVAS_LC3PLUS_DEC_GetDelay( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.hLc3plusDec, &lc3plusDelaySamples ); + latency_ns = (int32_t) roundf( lc3plusDelaySamples * 1000000000.f / *timeScale ); + } +#endif +#ifdef SPLIT_REND_LC3PLUS + if ( hIvasRend->inputsSplitPost[i].splitPostRendWrapper.multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { +#endif + latency_ns += IVAS_FB_DEC_DELAY_NS; +#ifdef SPLIT_REND_LC3PLUS + } +#endif max_latency_ns = max( max_latency_ns, latency_ns ); } } +#endif for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; i++ ) { @@ -3729,7 +4692,6 @@ ivas_error IVAS_REND_GetDelay( max_latency_ns = max( max_latency_ns, latency_ns ); } } - *nSamples = (int16_t) roundf( (float) max_latency_ns * *timeScale / 1000000000.f ); return IVAS_ERR_OK; @@ -3751,14 +4713,22 @@ ivas_error IVAS_REND_FeedInputAudio( ivas_error error; input_base *inputBase; int16_t numInputChannels; - +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t cldfb2tdSampleFact; +#endif /* Validate function arguments */ if ( hIvasRend == NULL || inputAudio.data == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + cldfb2tdSampleFact = ( inputAudio.config.is_cldfb ) ? 2 : 1; + if ( inputAudio.config.numSamplesPerChannel <= 0 || ( MAX_BUFFER_LENGTH_PER_CHANNEL < inputAudio.config.numSamplesPerChannel && inputAudio.config.is_cldfb == 0 ) || + ( ( MAX_BUFFER_LENGTH_PER_CHANNEL * cldfb2tdSampleFact ) < inputAudio.config.numSamplesPerChannel && inputAudio.config.is_cldfb == 1 ) ) +#else if ( inputAudio.config.numSamplesPerChannel <= 0 || MAX_BUFFER_LENGTH_PER_CHANNEL < inputAudio.config.numSamplesPerChannel ) +#endif { return IVAS_ERR_INVALID_BUFFER_SIZE; } @@ -3767,9 +4737,13 @@ ivas_error IVAS_REND_FeedInputAudio( { return IVAS_ERR_WRONG_NUM_CHANNELS; } - +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && + ( inputAudio.config.numSamplesPerChannel * 1000 / cldfb2tdSampleFact ) != BINAURAL_RENDERING_FRAME_SIZE_MS * hIvasRend->sampleRateOut ) +#else if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && inputAudio.config.numSamplesPerChannel * 1000 != BINAURAL_RENDERING_FRAME_SIZE_MS * hIvasRend->sampleRateOut ) +#endif { /* Binaural rendering requires specific frame size */ return IVAS_ERR_INVALID_BUFFER_SIZE; @@ -3953,9 +4927,37 @@ ivas_error IVAS_REND_InitConfig( hIvasRend->hRendererConfig = NULL; } +#ifdef SPLIT_REND_LC3PLUS + /* ToDo: The entire contents of this function should be part of IVAS_REND_Open - otherwise renderer handle is partly uninitialized after opening */ + /* Initialize split rendering */ + if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + return IVAS_ERR_OK; } +#ifndef SPLIT_REND_LC3PLUS /* Functionality moved to ivas_split_rend_validate_config() */ +#ifdef SPLIT_REND_WITH_HEAD_ROT +static int16_t is_SplitRend_BitRate( const int32_t splitRendBitRate ) +{ + int16_t j; + + j = 0; + while ( j < SIZE_SPLIT_REND_BRATE_TBL && splitRendBitRate != split_rend_brate_tbl[j] ) + { + j++; + } + if ( j >= SIZE_SPLIT_REND_BRATE_TBL ) + { + return 0; + } + return 1; +} +#endif +#endif /*-------------------------------------------------------------------* * IVAS_REND_GetRenderConfig() @@ -3976,7 +4978,7 @@ int16_t IVAS_REND_GetRenderConfig( } hRCin = hIvasRend->hRendererConfig; -#ifdef DEBUGGING +#if ( defined DEBUGGING ) || ( defined SPLIT_REND_WITH_HEAD_ROT ) switch ( hRCin->renderer_type_override ) { case RENDER_TYPE_OVERRIDE_CREND: @@ -4000,6 +5002,17 @@ int16_t IVAS_REND_GetRenderConfig( mvr2r( hRCin->roomAcoustics.pAcoustic_rt60, hRCout->room_acoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); mvr2r( hRCin->roomAcoustics.pAcoustic_dsr, hRCout->room_acoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + hRCout->split_rend_config.splitRendBitRate = SPLIT_REND_768k; + hRCout->split_rend_config.dof = 3; + hRCout->split_rend_config.hq_mode = 0; + hRCout->split_rend_config.codec_delay_ms = 0; +#endif +#ifdef SPLIT_REND_LC3PLUS + hRCout->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_LCLD; + hRCout->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; +#endif + return IVAS_ERR_OK; } @@ -4016,6 +5029,9 @@ int16_t IVAS_REND_FeedRenderConfig( ) { RENDER_CONFIG_HANDLE hRenderConfig; +#ifdef SPLIT_REND_LC3PLUS + ivas_error error; +#endif if ( hIvasRend == NULL || hIvasRend->hRendererConfig == NULL ) { @@ -4023,7 +5039,8 @@ int16_t IVAS_REND_FeedRenderConfig( } hRenderConfig = hIvasRend->hRendererConfig; -#ifdef DEBUGGING +#if ( defined DEBUGGING ) || ( defined SPLIT_REND_WITH_HEAD_ROT ) + hRenderConfig->renderer_type_override = RENDER_TYPE_OVERRIDE_NONE; if ( renderConfig.renderer_type_override == IVAS_RENDER_TYPE_OVERRIDE_FASTCONV ) { @@ -4043,6 +5060,31 @@ int16_t IVAS_REND_FeedRenderConfig( mvr2r( renderConfig.room_acoustics.pAcoustic_dsr, hRenderConfig->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); mvr2r( renderConfig.directivity, hRenderConfig->directivity, 3 ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + hRenderConfig->split_rend_config = renderConfig.split_rend_config; +#endif +#ifdef SPLIT_REND_LC3PLUS + /* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */ + if ( hRenderConfig->split_rend_config.dof == 0 ) + { + hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + } + + hRenderConfig->split_rend_config.codec = renderConfig.split_rend_config.codec; + + if ( ( error = ivas_split_rend_validate_config( &hRenderConfig->split_rend_config ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Must re-initialize split rendering config which depends on renderer config */ + closeSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); + if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + return IVAS_ERR_OK; } @@ -4057,6 +5099,10 @@ ivas_error IVAS_REND_SetHeadRotation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME], /* i : head orientations for next rendering call */ const IVAS_VECTOR3 Pos[RENDERER_HEAD_POSITIONS_PER_FRAME] /* i : listener positions for next rendering call */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + IVAS_SPLIT_REND_ROT_AXIS rot_axis +#endif ) { int16_t i; @@ -4076,7 +5122,26 @@ ivas_error IVAS_REND_SetHeadRotation( if ( headRot == NULL ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) || + ( hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + hIvasRend->headRotData.headRotEnabled = 1; + for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) + { + hIvasRend->headRotData.headPositions[i].w = -3.0f; + hIvasRend->headRotData.headPositions[i].x = 0.0f; + hIvasRend->headRotData.headPositions[i].y = 0.0f; + hIvasRend->headRotData.headPositions[i].z = 0.0f; + } + } + else + { + hIvasRend->headRotData.headRotEnabled = 0; + } +#else hIvasRend->headRotData.headRotEnabled = 0; +#endif } else { @@ -4086,7 +5151,23 @@ ivas_error IVAS_REND_SetHeadRotation( /* check for Euler angle signaling */ if ( headRot[i].w == -3.0f ) { - Euler2Quat( deg2rad( headRot[i].x ), deg2rad( headRot[i].y ), deg2rad( headRot[i].z ), &rotQuat ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) || + ( hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) || + ( hIvasRend->inputsSplitPost[0].base.inConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) || + ( hIvasRend->inputsSplitPost[0].base.inConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { +#ifndef EUALER2QUAT_FIX + rotQuat = headRot[i]; /* TODO: temp change until Euler2Quat() is fixed*/ +#else + Euler2Quat( deg2rad( headRot[i].x ), deg2rad( headRot[i].y ), deg2rad( headRot[i].z ), &rotQuat ); +#endif + } + else +#endif + { + Euler2Quat( deg2rad( headRot[i].x ), deg2rad( headRot[i].y ), deg2rad( headRot[i].z ), &rotQuat ); + } } else { @@ -4098,9 +5179,22 @@ ivas_error IVAS_REND_SetHeadRotation( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + hIvasRend->headRotData.sr_pose_pred_axis = rot_axis; +#endif + return IVAS_ERR_OK; } +#ifdef SPLIT_REND_PLC +ivas_error IVAS_REND_SetSplitRendBFI( + IVAS_REND_HANDLE hIvasRend, + const int16_t bfi ) +{ + hIvasRend->splitRendBFI = bfi; + return IVAS_ERR_OK; +} +#endif /*-------------------------------------------------------------------* * IVAS_REND_SetOrientationTrackingMode() @@ -4556,11 +5650,19 @@ static ivas_error rotateFrameSba( int16_t m1, m2; int16_t shd_rot_max_order; int16_t subframe_idx, subframe_len; +#ifdef SBA_CREND_ROT_OPT + float *writePtr; +#else float *readPtr, *writePtr; +#endif rotation_matrix Rmat; float tmpRot[2 * HEADROT_ORDER + 1]; rotation_gains gains; ivas_error error; +#ifdef SBA_CREND_ROT_OPT + int16_t idx; + float val, cf, oneminuscf; +#endif push_wmops( "rotateFrameSba" ); @@ -4601,6 +5703,11 @@ static ivas_error rotateFrameSba( for ( i = 0; i < subframe_len; i++ ) { +#ifdef SBA_CREND_ROT_OPT + idx = subframe_idx * subframe_len + i; + cf = headRotData->crossfade[i]; + oneminuscf = 1 - cf; +#endif /* As the rotation matrix becomes block diagonal in a SH basis, we can*/ /* apply each angular-momentum block individually to save complexity. */ @@ -4616,10 +5723,16 @@ static ivas_error rotateFrameSba( for ( m = m1; m < m2; m++ ) { +#ifdef SBA_CREND_ROT_OPT + val = inAudio.data[m * inAudio.config.numSamplesPerChannel + idx]; + /* crossfade with previous rotation gains */ + tmpRot[n - m1] += ( cf * gains[n][m] * val + oneminuscf * gains_prev[n][m] * val ); +#else readPtr = getSmplPtr( inAudio, m, subframe_idx * subframe_len + i ); /* crossfade with previous rotation gains */ tmpRot[n - m1] += headRotData->crossfade[i] * gains[n][m] * ( *readPtr ) + ( 1 - headRotData->crossfade[i] ) * gains_prev[n][m] * ( *readPtr ); +#endif } } /* write back the result */ @@ -4817,13 +5930,16 @@ static ivas_error renderIsmToBinauralRoom( copyBufferTo2dArray( tmpMcBuffer, tmpRendBuffer ); if ( ( error = ivas_rend_crendProcess( ismInput->crendWrapper, AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_BINAURAL_ROOM_IR, - NULL, NULL, NULL, NULL, p_tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + NULL, NULL, NULL, NULL, p_tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 0 +#endif + ) ) != IVAS_ERR_OK ) { return error; } - accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); - free( tmpMcBuffer.data ); pop_wmops(); @@ -4987,9 +6103,148 @@ static ivas_error renderIsmToSba( return error; } -static ivas_error renderIsmToMasa( +#ifdef SPLIT_REND_LC3PLUS +static ivas_error renderIsmToSplitBinaural( input_ism *ismInput, - IVAS_REND_AudioBuffer outAudio ) + const IVAS_REND_AudioBuffer outAudio ) +{ + int32_t i; + ivas_error error; + float tmpProcessing[MAX_NUM_OBJECTS][L_FRAME48k]; + int16_t pos_idx; + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; + const SPLIT_REND_WRAPPER *pSplitRendWrapper; + IVAS_QUATERNION originalHeadRot[MAX_PARAM_SPATIAL_SUBFRAMES]; + float tmpBinaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k]; + int16_t output_frame = ismInput->base.inputBuffer.config.numSamplesPerChannel; + COMBINED_ORIENTATION_HANDLE pCombinedOrientationData; + + push_wmops( "renderIsmToSplitBinaural" ); + + pSplitRendWrapper = ismInput->base.ctx.pSplitRendWrapper; + pMultiBinPoseData = &pSplitRendWrapper->multiBinPoseData; + + /* If not yet allocated, open additional instances of TD renderer */ + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + if ( ismInput->splitTdRendWrappers[i].hBinRendererTd != NULL ) + { + continue; + } + + /* ToDo: Could re-use already existing HRTF (ismInput->tdRendWrapper.hHrtfTD), but this complicates internal memory handling in TD renderer */ + ismInput->splitTdRendWrappers[i].hHrtfTD = NULL; + + /* Open TD renderer wrapper */ + if ( ( error = ivas_td_binaural_open_ext( &ismInput->splitTdRendWrappers[i], ismInput->base.inConfig, *ismInput->base.ctx.hhRendererConfig, NULL, *ismInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Assert same delay as main TD renderer */ + assert( ismInput->splitTdRendWrappers[i].binaural_latency_ns == ismInput->tdRendWrapper.binaural_latency_ns ); + } + + pCombinedOrientationData = *ismInput->base.ctx.pCombinedOrientationData; + + for ( i = 1; i < MAX_PARAM_SPATIAL_SUBFRAMES; ++i ) + { + pCombinedOrientationData->Quaternions[i] = pCombinedOrientationData->Quaternions[0]; + } + + /* Save current head positions */ + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; ++i ) + { + originalHeadRot[i] = pCombinedOrientationData->Quaternions[i]; + } + + /* Copy input audio to a processing buffer. */ + copyBufferTo2dArray( ismInput->base.inputBuffer, tmpProcessing ); + + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + /* Update head positions */ + if ( pos_idx != 0 ) + { + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; ++i ) + { + if ( originalHeadRot[i].w == -3.0f ) + { + pCombinedOrientationData->Quaternions[i].w = -3.0f; + pCombinedOrientationData->Quaternions[i].x = originalHeadRot[i].x + pMultiBinPoseData->relative_head_poses[pos_idx][0]; + pCombinedOrientationData->Quaternions[i].y = originalHeadRot[i].y + pMultiBinPoseData->relative_head_poses[pos_idx][1]; + pCombinedOrientationData->Quaternions[i].z = originalHeadRot[i].z + pMultiBinPoseData->relative_head_poses[pos_idx][2]; + } + else + { + pCombinedOrientationData->Quaternions[i].w = -3.0f; + Quat2EulerDegree( originalHeadRot[i], + &pCombinedOrientationData->Quaternions[i].z, + &pCombinedOrientationData->Quaternions[i].y, + &pCombinedOrientationData->Quaternions[i].x ); + pCombinedOrientationData->Quaternions[i].x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; + pCombinedOrientationData->Quaternions[i].y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; + pCombinedOrientationData->Quaternions[i].z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; + } + } + } + + /* Render */ + if ( pos_idx == 0 ) + { + error = ivas_td_binaural_renderer_ext( &ismInput->tdRendWrapper, + ismInput->base.inConfig, + NULL, + ismInput->base.ctx.pCombinedOrientationData, + &ismInput->currentPos, + NULL, + output_frame, + tmpProcessing ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + } + else + { + error = ivas_td_binaural_renderer_ext( &ismInput->splitTdRendWrappers[pos_idx - 1], + ismInput->base.inConfig, + NULL, + ismInput->base.ctx.pCombinedOrientationData, + &ismInput->currentPos, + NULL, + output_frame, + tmpProcessing ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + } + + /* Copy rendered audio to tmp storage buffer. Copying directly to output would + * overwrite original audio, which is still needed for rendering next head pose. */ + mvr2r( tmpProcessing[0], tmpBinaural[2 * pos_idx], output_frame ); + mvr2r( tmpProcessing[1], tmpBinaural[2 * pos_idx + 1], output_frame ); + + /* Overwrite processing buffer with original input audio again */ + copyBufferTo2dArray( ismInput->base.inputBuffer, tmpProcessing ); + } + /* Restore original head rotation */ + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; ++i ) + { + pCombinedOrientationData->Quaternions[i] = originalHeadRot[i]; + } + + accumulate2dArrayToBuffer( tmpBinaural, &outAudio ); + pop_wmops(); + + return IVAS_ERR_OK; +} +#endif +/* Encoding to split rendering bitstream done at a higher level */ +static ivas_error renderIsmToMasa( + input_ism *ismInput, + IVAS_REND_AudioBuffer outAudio ) { float tmpRendBuffer[MAX_NUM_OBJECTS][L_FRAME48k]; @@ -5041,9 +6296,18 @@ static ivas_error renderInputIsm( case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_IR: error = renderIsmToBinauralRoom( ismInput, outAudio ); break; + +#ifdef SPLIT_REND_LC3PLUS + case IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB: + case IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + error = renderIsmToSplitBinaural( ismInput, outAudio ); + break; +#endif + case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: error = renderIsmToBinauralReverb( ismInput, outAudio ); break; + default: return IVAS_ERR_INVALID_OUTPUT_FORMAT; } @@ -5090,14 +6354,24 @@ static ivas_error renderActiveInputsIsm( static ivas_error renderLfeToBinaural( const input_mc *mcInput, +#ifdef SPLIT_REND_LC3PLUS_MC + const IVAS_REND_AudioConfig outConfig, +#endif IVAS_REND_AudioBuffer outAudio ) { int16_t i; int16_t lfe_idx; +#ifdef SPLIT_REND_LC3PLUS_MC + int16_t pose_idx, num_poses; +#endif float gain; float *readPtr, *writePtr; +#ifdef SPLIT_REND_LC3PLUS_MC + assert( ( getAudioConfigType( outConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) && "Must be binaural output" ); +#else assert( ( outAudio.config.numChannels == 2 ) && "Must be binaural output" ); +#endif push_wmops( "renderLfeToBinaural" ); @@ -5117,6 +6391,34 @@ static ivas_error renderLfeToBinaural( return IVAS_ERR_OK; } +#ifdef SPLIT_REND_LC3PLUS_MC + /* Copy LFE to left and right binaural channels */ + if ( mcInput->base.ctx.pSplitRendWrapper != NULL ) + { + num_poses = mcInput->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses; + } + else + { + num_poses = 1; + } + + for ( pose_idx = 0; pose_idx < num_poses; ++pose_idx ) + { + readPtr = getSmplPtr( mcInput->base.inputBuffer, lfe_idx, 0 ); + writePtr = getSmplPtr( outAudio, pose_idx * BINAURAL_CHANNELS, 0 ); + for ( i = 0; i < mcInput->base.inputBuffer.config.numSamplesPerChannel; i++ ) + { + *writePtr++ += gain * ( *readPtr++ ); + } + + readPtr = getSmplPtr( mcInput->base.inputBuffer, lfe_idx, 0 ); + writePtr = getSmplPtr( outAudio, pose_idx * BINAURAL_CHANNELS + 1, 0 ); + for ( i = 0; i < mcInput->base.inputBuffer.config.numSamplesPerChannel; i++ ) + { + *writePtr++ += gain * ( *readPtr++ ); + } + } +#else /* Copy LFE to left and right ears */ readPtr = getSmplPtr( mcInput->base.inputBuffer, lfe_idx, 0 ); writePtr = getSmplPtr( outAudio, 0, 0 ); @@ -5131,6 +6433,7 @@ static ivas_error renderLfeToBinaural( { *writePtr++ += gain * ( *readPtr++ ); } +#endif pop_wmops(); @@ -5215,7 +6518,13 @@ static ivas_error renderMcToBinaural( /* call CREND */ if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, getIvasAudioConfigFromRendAudioConfig( mcInput->base.inConfig ), getIvasAudioConfigFromRendAudioConfig( outConfig ), - NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 0 +#endif + ) ) != IVAS_ERR_OK ) + { return error; } @@ -5223,7 +6532,11 @@ static ivas_error renderMcToBinaural( accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); +#ifdef SPLIT_REND_LC3PLUS_MC + if ( ( error = renderLfeToBinaural( mcInput, outConfig, outAudio ) ) != IVAS_ERR_OK ) +#else if ( ( error = renderLfeToBinaural( mcInput, outAudio ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -5308,7 +6621,12 @@ static ivas_error renderMcToBinauralRoom( /* call CREND */ if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, getIvasAudioConfigFromRendAudioConfig( mcInput->base.inConfig ), getIvasAudioConfigFromRendAudioConfig( outConfig ), - NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 0 +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -5316,7 +6634,11 @@ static ivas_error renderMcToBinauralRoom( accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); +#ifdef SPLIT_REND_LC3PLUS_MC + if ( ( error = renderLfeToBinaural( mcInput, outConfig, outAudio ) ) != IVAS_ERR_OK ) +#else if ( ( error = renderLfeToBinaural( mcInput, outAudio ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -5402,14 +6724,23 @@ static ivas_error renderMcCustomLsToBinauralRoom( /* call CREND */ if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, AUDIO_CONFIG_7_1_4, getIvasAudioConfigFromRendAudioConfig( outConfig ), NULL, NULL, NULL, NULL, - p_tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + p_tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 0 +#endif + ) ) != IVAS_ERR_OK ) { return error; } accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); +#ifdef SPLIT_REND_LC3PLUS_MC + if ( ( error = renderLfeToBinaural( mcInput, outConfig, outAudio ) ) != IVAS_ERR_OK ) +#else if ( ( error = renderLfeToBinaural( mcInput, outAudio ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -5484,6 +6815,178 @@ static ivas_error renderMcToMasa( return IVAS_ERR_OK; } +#ifdef SPLIT_REND_LC3PLUS_MC +static ivas_error renderMcToSplitBinaural( + input_mc *mcInput, + const IVAS_REND_AudioConfig outConfig, + IVAS_REND_AudioBuffer outAudio ) +{ + int16_t i, j, sf, pos_idx; + int16_t output_frame; + ivas_error error; + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; + const SPLIT_REND_WRAPPER *pSplitRendWrapper; + float tmpRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float *p_tmpRendBuffer[MAX_OUTPUT_CHANNELS]; + float tmpSplitBinauralBuffer[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k]; + IVAS_REND_AudioConfig inConfig; + IVAS_REND_AudioBuffer tmpRotBuffer; + COMBINED_ORIENTATION_DATA combinedOrientationDataLocal; + COMBINED_ORIENTATION_HANDLE pCombinedOrientationDataLocal; + + push_wmops( "renderMcToSplitBinaural" ); + + inConfig = mcInput->base.inConfig; + output_frame = mcInput->base.inputBuffer.config.numSamplesPerChannel; + + pSplitRendWrapper = mcInput->base.ctx.pSplitRendWrapper; + pMultiBinPoseData = &pSplitRendWrapper->multiBinPoseData; + + for ( i = 0; i < MAX_OUTPUT_CHANNELS; ++i ) + { + p_tmpRendBuffer[i] = tmpRendBuffer[i]; + } + + /* save current head positions */ + pCombinedOrientationDataLocal = *mcInput->base.ctx.pCombinedOrientationData; + combinedOrientationDataLocal = *pCombinedOrientationDataLocal; + for ( sf = 1; sf < RENDERER_HEAD_POSITIONS_PER_FRAME; ++sf ) + { + combinedOrientationDataLocal.Quaternions[sf] = combinedOrientationDataLocal.Quaternions[0]; + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + combinedOrientationDataLocal.Rmat[sf][i][j] = combinedOrientationDataLocal.Rmat[0][i][j]; + } + } + } + + + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + /* Update head positions */ + IVAS_QUATERNION Quaternions_orig[RENDERER_HEAD_POSITIONS_PER_FRAME], Quaternions_abs; + for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) + { + Quaternions_orig[i] = combinedOrientationDataLocal.Quaternions[i]; + Quaternions_abs.w = -3.0f; + Quat2EulerDegree( combinedOrientationDataLocal.Quaternions[i], &Quaternions_abs.z, &Quaternions_abs.y, &Quaternions_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ + + Quaternions_abs.x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; + Quaternions_abs.y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; + Quaternions_abs.z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; + combinedOrientationDataLocal.Quaternions[i] = Quaternions_abs; + QuatToRotMat( combinedOrientationDataLocal.Quaternions[i], combinedOrientationDataLocal.Rmat[i] ); + } + + if ( inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM || inConfig == IVAS_REND_AUDIO_CONFIG_5_1 || inConfig == IVAS_REND_AUDIO_CONFIG_7_1 ) + { + /* tdrend processing overview: + * 1. copy from inputBuffer to tmpRendBuffer + * 2. td_binaural_renderer_ext: inplace processing in tmpRendBuffer + * 3. copy from tmpRendBuffer to tmpSplitBinBuffer + * 4. LFE mixing + * 5. tmpSplitBinBuffer accumulated to outBuffer */ + + /* copy input to tdrend input/output buffer */ + copyBufferTo2dArray( mcInput->base.inputBuffer, tmpRendBuffer ); + + /* Render */ + if ( ( error = ivas_td_binaural_renderer_ext( &mcInput->splitTdRendWrappers[pos_idx - 1], + mcInput->base.inConfig, + &mcInput->customLsInput, + &pCombinedOrientationDataLocal, + NULL, + mcInput->hReverb, + mcInput->base.inputBuffer.config.numSamplesPerChannel, + tmpRendBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Copy rendered audio to tmp storage buffer. Copying directly to output would + * overwrite original audio, which is still needed for rendering next head pose. */ + mvr2r( tmpRendBuffer[0], tmpSplitBinauralBuffer[2 * pos_idx], output_frame ); + mvr2r( tmpRendBuffer[1], tmpSplitBinauralBuffer[2 * pos_idx + 1], output_frame ); + } + else + { + /* crend processing overview: + * 1. rotateFrameMc: inputBuffer to tmpRotBuffer + * 2. crend_process: tmpRotBuffer to tmpRendBuffer + * 3. copy from tmpRendBuffer to tmpSplitBinBuffer + * 4. LFE mixing + * 5. tmpSplitBinBuffer accumulated to outBuffer */ + + /* temporary buffer for rotation in source format */ + tmpRotBuffer = mcInput->base.inputBuffer; + tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); + + /* copy input for in-place rotation */ + mvr2r( mcInput->base.inputBuffer.data, tmpRotBuffer.data, + tmpRotBuffer.config.numChannels * tmpRotBuffer.config.numSamplesPerChannel ); + + /* perform rotation in source format to tmpRotBuffer */ + pCombinedOrientationDataLocal = &combinedOrientationDataLocal; + if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, + mcInput->base.inConfig, + mcInput->customLsInput, + mcInput->base.ctx.pHeadRotData, + &pCombinedOrientationDataLocal, + mcInput->rot_gains_prev, + mcInput->efapInWrapper.hEfap, + tmpRotBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + + copyBufferTo2dArray( tmpRotBuffer, tmpRendBuffer ); + + /* call CREND (rotation already performed) */ + if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, + getIvasAudioConfigFromRendAudioConfig( mcInput->base.inConfig ), + getIvasAudioConfigFromRendAudioConfig( outConfig ), + NULL, + NULL, + NULL, + NULL, + p_tmpRendBuffer, + *mcInput->base.ctx.pOutSampleRate, + pos_idx ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Copy rendererd audio to tmp storage buffer, Copying directly to output would + * overwrite original audio, which is still needed for rendering next head pose. */ + mvr2r( tmpRendBuffer[0], tmpSplitBinauralBuffer[2 * pos_idx], output_frame ); + mvr2r( tmpRendBuffer[1], tmpSplitBinauralBuffer[2 * pos_idx + 1], output_frame ); + + free( tmpRotBuffer.data ); + } + + /* restore original headrotation data */ + for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) + { + combinedOrientationDataLocal.Quaternions[i] = Quaternions_orig[i]; + } + } + + /* TODO tmu : needs delay compensation */ + if ( ( error = renderLfeToBinaural( mcInput, outConfig, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } + + accumulate2dArrayToBuffer( tmpSplitBinauralBuffer, &outAudio ); + + pop_wmops(); + + return IVAS_ERR_OK; +} + +#endif static ivas_error renderInputMc( input_mc *mcInput, IVAS_REND_AudioConfig outConfig, @@ -5534,6 +7037,12 @@ static ivas_error renderInputMc( error = renderMcToBinauralRoom( mcInput, outConfig, outAudio ); } break; +#ifdef SPLIT_REND_LC3PLUS_MC + case IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB: + case IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + error = renderMcToSplitBinaural( mcInput, outConfig, outAudio ); + break; +#endif default: return IVAS_ERR_INVALID_OUTPUT_FORMAT; } @@ -5615,44 +7124,526 @@ static void renderSbaToSba( return; } -static ivas_error renderSbaToBinaural( +#ifdef SPLIT_REND_LC3PLUS +static ivas_error splitBinLc3plusDecode( + SPLIT_POST_REND_WRAPPER *hSplitBin, + ivas_split_rend_bits_t *bits, + float outputBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k], + IVAS_SPLIT_REND_POSE_CORRECTION_MODE pose_correction ) +{ + ivas_error error; + float *channel_ptrs[MAX_HEAD_ROT_POSES * 2]; + int32_t lc3plusBitrateId, lc3plusBitstreamSize; + + push_wmops( "splitBinLc3plusDecode" ); + + assert( hSplitBin->hLc3plusDec != NULL ); + + /* Find next byte boundary */ + while ( bits->bits_read % 8 != 0 ) + { + ++bits->bits_read; + } + /* Read LC3plus bitstream size info */ + lc3plusBitrateId = ivas_split_rend_bitstream_read_int32( bits, 8 ); + lc3plusBitstreamSize = ivas_get_lc3plus_size_from_id( (int8_t) lc3plusBitrateId, pose_correction ); +#ifdef SPLIT_REND_LC3PLUS_HBR_DBG + if ( lc3plusBitstreamSize == -1 ) + { + lc3plusBitstreamSize = hSplitBin->hLc3plusDec->num_decs * SPLIT_REND_LC3PLUS_HBR / FRAMES_PER_SECOND / 8; + } +#endif + + for ( int16_t i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i ) + { + channel_ptrs[i] = outputBuffer[i]; + } + if ( ( error = IVAS_LC3PLUS_DEC_Decode( hSplitBin->hLc3plusDec, + &bits->bits_buf[bits->bits_read / 8], + lc3plusBitstreamSize, + channel_ptrs ) ) != IVAS_ERR_OK ) + { + return error; + } + + pop_wmops(); + + return IVAS_ERR_OK; +} +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error renderSplitBinauralWithPostRot( + input_split_post_rend *splitBinInput, + IVAS_REND_AudioBuffer outAudio, + IVAS_REND_BitstreamBuffer *hBits +#ifdef SPLIT_REND_PLC + , + const int16_t SplitRendBFI +#endif /* SPLIT_REND_PLC */ +) +{ + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + ivas_error error; + IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t sf_idx; + ivas_split_rend_bits_t bits; + float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + COMBINED_ORIENTATION_HANDLE pCombinedOrientationData; + SPLIT_POST_REND_WRAPPER *hSplitBin; +#ifdef SPLIT_REND_LC3PLUS + int8_t isPostRendInputCldfb; + + isPostRendInputCldfb = 0; +#endif /* SPLIT_REND_LC3PLUS */ + + push_wmops( "renderSplitBinauralWithPostRot" ); + + error = IVAS_ERR_OK; + + pCombinedOrientationData = *splitBinInput->base.ctx.pCombinedOrientationData; + hSplitBin = &splitBinInput->splitPostRendWrapper; + convertBitsBufferToInternalBitsBuff( *hBits, &bits ); + +#ifdef SPLIT_REND_LC3PLUS + if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD && splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec == NULL ) + { + error = ivas_splitBinLCLDDecOpen( &splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec, *splitBinInput->base.ctx.pOutSampleRate, BINAURAL_CHANNELS ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + } + else if ( bits.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && splitBinInput->splitPostRendWrapper.hLc3plusDec == NULL ) + { + LC3PLUS_CONFIG config; + config.lc3plus_frame_duration_us = 5000; + config.ivas_frame_duration_us = 20000; + config.channels = BINAURAL_CHANNELS; + config.samplerate = *splitBinInput->base.ctx.pOutSampleRate; + + IVAS_LC3PLUS_DEC_Open( config, +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + 0 /* caching disabled */, +#endif + &splitBinInput->splitPostRendWrapper.hLc3plusDec ); + } +#endif /* SPLIT_REND_LC3PLUS */ + + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + QuaternionsPost[sf_idx] = ivas_split_rend_get_sf_rot_data( pCombinedOrientationData->Quaternions, sf_idx ); + } + +#ifdef SPLIT_REND_PLC + if ( !SplitRendBFI ) + { + hSplitBin->first_good_frame_received = 1; + } +#endif /* SPLIT_REND_PLC */ + +#ifdef SPLIT_REND_PLC + if ( hSplitBin->first_good_frame_received == 1 ) + { +#endif /* SPLIT_REND_PLC */ + if ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { +#ifdef SPLIT_REND_PLC + if ( !SplitRendBFI ) /* ToDo: this is always true */ +#endif /* SPLIT_REND_PLC */ + { + ivas_splitBinPostRendMdDec( + &bits, + hSplitBin->hBinHrSplitPostRend, + &hSplitBin->multiBinPoseData +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + , + hSplitBin->hBinHrSplitPreRend +#endif /* SPLIT_REND_WITH_HEAD_ROT_DEBUG */ + ); + } + } + /*copy pose correction after MD is parsed*/ +#ifdef SPLIT_REND_LC3PLUS + hSplitBin->multiBinPoseData.poseCorrectionMode = bits.pose_correction; +#endif + + if ( splitBinInput->base.inConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) + { +#ifdef SPLIT_REND_LC3PLUS + if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD ) + { +#endif /* SPLIT_REND_LC3PLUS */ + ivas_splitBinLCLDDecProcess( + hSplitBin->hSplitBinLCLDDec, + &bits, + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural +#ifdef SPLIT_REND_PLC + , + SplitRendBFI +#endif /* SPLIT_REND_PLC */ + ); +#ifdef SPLIT_REND_LC3PLUS + isPostRendInputCldfb = 1; + } + else + { + error = splitBinLc3plusDecode( hSplitBin, &bits, tmpCrendBuffer, bits.pose_correction ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + } +#endif + } + else + { + copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer ); + } + +#ifdef SPLIT_REND_LC3PLUS + if ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { +#endif /* SPLIT_REND_LC3PLUS */ + ivas_rend_CldfbSplitPostRendProcess( + hSplitBin->hBinHrSplitPostRend, + &hSplitBin->multiBinPoseData, + QuaternionsPost, + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural, + tmpCrendBuffer, +#ifdef SPLIT_REND_LC3PLUS + isPostRendInputCldfb ); + } +#else /* SPLIT_REND_LC3PLUS */ + ( splitBinInput->base.inConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) ? 1 : 0 ); +#endif /* SPLIT_REND_LC3PLUS */ + +#ifdef SPLIT_REND_PLC + } + else + { + if ( splitBinInput->base.inConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) + { + int16_t ch_idx; + for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + set_zero( tmpCrendBuffer[ch_idx], outAudio.config.numSamplesPerChannel ); + } + } + else + { + copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer ); + } + } +#endif /* SPLIT_REND_PLC */ + + convertInternalBitsBuffToBitsBuffer( hBits, bits ); + accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); + + pop_wmops(); + + return error; +} + +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error renderSbaToMultiBinaural( input_sba *sbaInput, const IVAS_REND_AudioConfig outConfig, - IVAS_REND_AudioBuffer outAudio ) + float out[][L_FRAME48k] ) { float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - ivas_error error; - IVAS_REND_AudioBuffer tmpRotBuffer; +#ifdef FIX_SPLIT_REND_MERGE float *p_tmpCrendBuffer[MAX_OUTPUT_CHANNELS]; - int16_t i; - const COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData; - int8_t combinedOrientationEnabled; - int16_t subframe_idx; - push_wmops( "renderSbaToBinaural" ); +#endif + int16_t sf, i, j, pos_idx; + COMBINED_ORIENTATION_DATA combinedOrientationDataLocal; + COMBINED_ORIENTATION_HANDLE pCombinedOrientationDataLocal; + + ivas_error error; + IVAS_REND_AudioBuffer tmpRotBuffer; + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; +#ifdef FIX_SPLIT_REND_MERGE for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) { p_tmpCrendBuffer[i] = tmpCrendBuffer[i]; } - - hCombinedOrientationData = sbaInput->base.ctx.pCombinedOrientationData; - combinedOrientationEnabled = 0; - if ( hCombinedOrientationData != NULL ) +#endif + push_wmops( "renderSbaToMultiBinaural" ); + pCombinedOrientationDataLocal = *sbaInput->base.ctx.pCombinedOrientationData; + combinedOrientationDataLocal = *pCombinedOrientationDataLocal; + for ( sf = 1; sf < RENDERER_HEAD_POSITIONS_PER_FRAME; sf++ ) { - for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) + combinedOrientationDataLocal.Quaternions[sf] = combinedOrientationDataLocal.Quaternions[0]; + for ( i = 0; i < 3; i++ ) { - if ( ( *hCombinedOrientationData )->enableCombinedOrientation[subframe_idx] != 0 ) + for ( j = 0; j < 3; j++ ) { - combinedOrientationEnabled = 1; - break; + combinedOrientationDataLocal.Rmat[sf][i][j] = combinedOrientationDataLocal.Rmat[0][i][j]; } } } - /* apply rotation */ - if ( combinedOrientationEnabled ) + tmpRotBuffer = sbaInput->base.inputBuffer; + tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); + + pMultiBinPoseData = &sbaInput->splitRendWrapper.multiBinPoseData; + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + IVAS_QUATERNION Quaternions_orig[RENDERER_HEAD_POSITIONS_PER_FRAME], Quaternions_abs; + for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) + { + Quaternions_orig[i] = combinedOrientationDataLocal.Quaternions[i]; + Quaternions_abs.w = -3.0f; + Quat2EulerDegree( combinedOrientationDataLocal.Quaternions[i], &Quaternions_abs.z, &Quaternions_abs.y, &Quaternions_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ + + Quaternions_abs.x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; + Quaternions_abs.y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; + Quaternions_abs.z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; + combinedOrientationDataLocal.Quaternions[i] = Quaternions_abs; + QuatToRotMat( combinedOrientationDataLocal.Quaternions[i], combinedOrientationDataLocal.Rmat[i] ); + } + + + /* copy input for in-place rotation */ + mvr2r( sbaInput->base.inputBuffer.data, tmpRotBuffer.data, + tmpRotBuffer.config.numChannels * tmpRotBuffer.config.numSamplesPerChannel ); + + pCombinedOrientationDataLocal = &combinedOrientationDataLocal; + rotateFrameSba( sbaInput->base.inputBuffer, + sbaInput->base.inConfig, + sbaInput->base.ctx.pHeadRotData, + &pCombinedOrientationDataLocal, + sbaInput->rot_gains_prev[pos_idx], + tmpRotBuffer ); + + copyBufferTo2dArray( tmpRotBuffer, tmpCrendBuffer ); + + assert( sbaInput->crendWrapper->hCrend[0]->hReverb == NULL ); + /* call CREND */ + if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, getIvasAudioConfigFromRendAudioConfig( sbaInput->base.inConfig ), getIvasAudioConfigFromRendAudioConfig( outConfig ), + NULL, NULL, NULL, NULL, +#ifdef FIX_SPLIT_REND_MERGE + p_tmpCrendBuffer, +#else + tmpCrendBuffer +#endif + *sbaInput->base.ctx.pOutSampleRate, + pos_idx ) ) != IVAS_ERR_OK ) + { + return error; + } + + for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) + { + combinedOrientationDataLocal.Quaternions[i] = Quaternions_orig[i]; + } + + /* move to output */ + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + mvr2r( tmpCrendBuffer[i], out[pos_idx * BINAURAL_CHANNELS + i], tmpRotBuffer.config.numSamplesPerChannel ); + } + } + + free( tmpRotBuffer.data ); + + pop_wmops(); + + return IVAS_ERR_OK; +} +#endif + +#ifdef SPLIT_REND_STACK_OPT +static ivas_error renderSbaToMultiBinauralCldfb( input_sba *sbaInput, + float Cldfb_Out_Real[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_Out_Imag[][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t low_res_pre_rend_rot ) +{ + float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + + copyBufferToCLDFBarray( sbaInput->base.inputBuffer, Cldfb_RealBuffer, Cldfb_ImagBuffer ); + + ivas_rend_CldfbMultiBinRendProcess( + sbaInput->cldfbRendWrapper.hCldfbRend, + sbaInput->base.ctx.pCombinedOrientationData, + &sbaInput->splitRendWrapper.multiBinPoseData, + Cldfb_RealBuffer, + Cldfb_ImagBuffer, + Cldfb_Out_Real, + Cldfb_Out_Imag, + low_res_pre_rend_rot ); + return IVAS_ERR_OK; +} +#endif + +static ivas_error renderSbaToSplitBinaural( + input_sba *sbaInput, +#ifdef SPLIT_REND_WITH_HEAD_ROT + const IVAS_REND_AudioConfig outConfig, +#endif + IVAS_REND_AudioBuffer outAudio, + IVAS_REND_BitstreamBuffer *hBits ) +{ + float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + ivas_error error; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; +#else + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; +#endif + ivas_split_rend_bits_t bits; + int16_t low_res_pre_rend_rot, max_band; +#ifdef SPLIT_REND_LC3PLUS + int16_t td_input; +#endif + + low_res_pre_rend_rot = 1; //( *sbaInput->base.ctx.pSplitRendBitRate == SPLIT_REND_768k ) ? 0 : 1; + + push_wmops( "renderSbaToSplitBinaural" ); + error = IVAS_ERR_OK; + + ivas_renderSplitGetMultiBinPoseData( + &sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config, + &sbaInput->splitRendWrapper.multiBinPoseData, + sbaInput->base.ctx.pHeadRotData->sr_pose_pred_axis ); + +#if ( defined DEBUGGING ) || ( defined SPLIT_REND_WITH_HEAD_ROT ) + if ( sbaInput->base.ctx.hhRendererConfig[0]->renderer_type_override == RENDER_TYPE_OVERRIDE_FASTCONV ) + { + +#ifdef SPLIT_REND_STACK_OPT + renderSbaToMultiBinauralCldfb( sbaInput, + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural, + low_res_pre_rend_rot ); +#else + float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + + copyBufferToCLDFBarray( sbaInput->base.inputBuffer, Cldfb_RealBuffer, Cldfb_ImagBuffer ); + + ivas_rend_CldfbMultiBinRendProcess( + sbaInput->cldfbRendWrapper.hCldfbRend, + sbaInput->base.ctx.pHeadRotData, + &sbaInput->splitRendWrapper.multiBinPoseData, + Cldfb_RealBuffer, + Cldfb_ImagBuffer, + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural, + low_res_pre_rend_rot ); +#endif + max_band = sbaInput->cldfbRendWrapper.hCldfbRend->max_band; +#ifdef SPLIT_REND_LC3PLUS + td_input = 0; +#endif + } + else +#endif { + renderSbaToMultiBinaural( + sbaInput, + outConfig, + tmpCrendBuffer ); + max_band = (int16_t) ( ( BINAURAL_MAXBANDS * ( *sbaInput->base.ctx.pOutSampleRate ) ) / 48000 ); + if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); + } +#ifdef SPLIT_REND_LC3PLUS + td_input = 1; +#endif + } + + /*SPLIT pre rendering MD and CLDFB coding*/ + convertBitsBufferToInternalBitsBuff( *hBits, &bits ); + + ivas_renderMultiBinToSplitBinaural( &sbaInput->splitRendWrapper, + sbaInput->base.ctx.pHeadRotData->headPositions, + sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.splitRendBitRate, +#ifdef SPLIT_REND_LC3PLUS + sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.codec, +#endif + &bits, + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural, + max_band, + tmpCrendBuffer, + low_res_pre_rend_rot, +#ifdef SPLIT_REND_LC3PLUS + td_input, +#endif + ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ); + + convertInternalBitsBuffToBitsBuffer( hBits, bits ); + + pop_wmops(); + + return error; +} +#endif + +static ivas_error +renderSbaToBinaural( + input_sba *sbaInput, + const IVAS_REND_AudioConfig outConfig, + IVAS_REND_AudioBuffer outAudio ) +{ + ivas_error error; + IVAS_REND_AudioBuffer tmpRotBuffer; + + push_wmops( "renderSbaToBinaural" ); + +#if defined DEBUGGING && defined SPLIT_REND_WITH_HEAD_ROT + if ( sbaInput->base.ctx.hhRendererConfig[0]->renderer_type_override == RENDER_TYPE_OVERRIDE_FASTCONV ) + { + float Cldfb_RealBuffer_Binaural[1][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[1][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; +#ifdef SPLIT_REND_STACK_OPT + renderSbaToMultiBinauralCldfb( sbaInput, + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural, + 0 ); +#else + float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + + copyBufferToCLDFBarray( sbaInput->base.inputBuffer, Cldfb_RealBuffer, Cldfb_ImagBuffer ); + + ivas_rend_CldfbMultiBinRendProcess( + sbaInput->cldfbRendWrapper.hCldfbRend, + sbaInput->base.ctx.pHeadRotData, + &sbaInput->splitRendWrapper.multiBinPoseData, + Cldfb_RealBuffer, + Cldfb_ImagBuffer, + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural, + 0 ); +#endif + accumulateCLDFBArrayToBuffer( Cldfb_RealBuffer_Binaural[0], Cldfb_ImagBuffer_Binaural[0], &outAudio ); + } + else +#endif + + { + float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; +#ifdef FIX_SPLIT_REND_MERGE + float *p_tmpCrendBuffer[MAX_OUTPUT_CHANNELS]; + for ( int16_t i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + p_tmpCrendBuffer[i] = tmpCrendBuffer[i]; + } +#endif tmpRotBuffer = sbaInput->base.inputBuffer; tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); @@ -5661,27 +7652,40 @@ static ivas_error renderSbaToBinaural( if ( ( error = rotateFrameSba( sbaInput->base.inputBuffer, sbaInput->base.inConfig, sbaInput->base.ctx.pHeadRotData, sbaInput->base.ctx.pCombinedOrientationData, - sbaInput->rot_gains_prev, tmpRotBuffer ) ) != IVAS_ERR_OK ) + + +#ifdef SPLIT_REND_WITH_HEAD_ROT + sbaInput->rot_gains_prev[0], +#else + sbaInput->rot_gains_prev, +#endif + tmpRotBuffer ) ) != IVAS_ERR_OK ) + { return error; } copyBufferTo2dArray( tmpRotBuffer, tmpCrendBuffer ); free( tmpRotBuffer.data ); + /* call CREND */ + if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, getIvasAudioConfigFromRendAudioConfig( sbaInput->base.inConfig ), getIvasAudioConfigFromRendAudioConfig( outConfig ), + NULL, NULL, NULL, NULL, +#ifdef FIX_SPLIT_REND_MERGE + p_tmpCrendBuffer, +#else + tmpCrendBuffer, +#endif + *sbaInput->base.ctx.pOutSampleRate +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 0 +#endif + ) ) != IVAS_ERR_OK ) + { + return error; + } + accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); } - else - { - copyBufferTo2dArray( sbaInput->base.inputBuffer, tmpCrendBuffer ); - } - - /* call CREND */ - if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, getIvasAudioConfigFromRendAudioConfig( sbaInput->base.inConfig ), getIvasAudioConfigFromRendAudioConfig( outConfig ), - NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) - { - return error; - } - - accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); pop_wmops(); @@ -5739,7 +7743,12 @@ static ivas_error renderSbaToBinauralRoom( if ( ( error = rotateFrameSba( sbaInput->base.inputBuffer, sbaInput->base.inConfig, sbaInput->base.ctx.pHeadRotData, sbaInput->base.ctx.pCombinedOrientationData, - sbaInput->rot_gains_prev, tmpRotBuffer ) ) != IVAS_ERR_OK ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + sbaInput->rot_gains_prev[0], +#else + sbaInput->rot_gains_prev, +#endif + tmpRotBuffer ) ) != IVAS_ERR_OK ) { return error; } @@ -5767,7 +7776,12 @@ static ivas_error renderSbaToBinauralRoom( /* call CREND */ if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, AUDIO_CONFIG_7_1_4, getIvasAudioConfigFromRendAudioConfig( outConfig ), - NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + 0 +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -5784,6 +7798,53 @@ static ivas_error renderSbaToBinauralRoom( return IVAS_ERR_OK; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error renderInputSplitBin( + input_split_post_rend *splitBinInput, + const IVAS_REND_AudioConfig outConfig, + IVAS_REND_AudioBuffer outAudio, + IVAS_REND_BitstreamBuffer *hBits +#ifdef SPLIT_REND_PLC + , + const int16_t SplitRendBFI +#endif +) +{ + ivas_error error; + IVAS_REND_AudioBuffer inAudio; + + inAudio = splitBinInput->base.inputBuffer; + if ( splitBinInput->base.numNewSamplesPerChannel != outAudio.config.numSamplesPerChannel ) + { + /* Mismatch between the number of input samples vs number of requested output samples - currently not allowed */ + return IVAS_ERR_INVALID_BUFFER_SIZE; + } + + splitBinInput->base.numNewSamplesPerChannel = 0; + + /* Apply input gain to new audio */ + v_multc( inAudio.data, + splitBinInput->base.gain, + inAudio.data, + inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); + switch ( outConfig ) + { + case IVAS_REND_AUDIO_CONFIG_BINAURAL: + error = renderSplitBinauralWithPostRot( splitBinInput, outAudio, + hBits +#ifdef SPLIT_REND_PLC + , + SplitRendBFI +#endif + ); + break; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + + return error; +} +#endif static ivas_error renderSbaToMasa( input_sba *sbaInput, @@ -5802,10 +7863,16 @@ static ivas_error renderSbaToMasa( return IVAS_ERR_OK; } + static ivas_error renderInputSba( input_sba *sbaInput, const IVAS_REND_AudioConfig outConfig, - IVAS_REND_AudioBuffer outAudio ) + IVAS_REND_AudioBuffer outAudio +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + IVAS_REND_BitstreamBuffer *hBits +#endif +) { ivas_error error; IVAS_REND_AudioBuffer inAudio; @@ -5814,7 +7881,12 @@ static ivas_error renderInputSba( inAudio = sbaInput->base.inputBuffer; +#ifdef SPLIT_REND_LC3PLUS + if ( ( sbaInput->base.numNewSamplesPerChannel != outAudio.config.numSamplesPerChannel ) && + ( outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) ) +#else if ( sbaInput->base.numNewSamplesPerChannel != outAudio.config.numSamplesPerChannel ) +#endif { /* Mismatch between the number of input samples vs number of requested output samples - currently not allowed */ return IVAS_ERR_INVALID_BUFFER_SIZE; @@ -5838,6 +7910,17 @@ static ivas_error renderInputSba( case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: switch ( outConfig ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB: + case IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + error = renderSbaToSplitBinaural( sbaInput, +#ifdef SPLIT_REND_WITH_HEAD_ROT + outConfig, +#endif + outAudio, + hBits ); + break; +#endif case IVAS_REND_AUDIO_CONFIG_BINAURAL: error = renderSbaToBinaural( sbaInput, outConfig, outAudio ); break; @@ -5859,9 +7942,46 @@ static ivas_error renderInputSba( return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error renderActiveInputsSplitBin( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_AudioBuffer outAudio, + IVAS_REND_BitstreamBuffer *hBits ) +{ + int16_t i; + input_split_post_rend *pCurrentInput; + ivas_error error; + + for ( i = 0, pCurrentInput = hIvasRend->inputsSplitPost; i < RENDERER_MAX_BIN_INPUTS; ++i, ++pCurrentInput ) + { + if ( pCurrentInput->base.inConfig == IVAS_REND_AUDIO_CONFIG_UNKNOWN ) + { + /* Skip inactive inputs */ + continue; + } + + if ( ( error = renderInputSplitBin( pCurrentInput, hIvasRend->outputConfig, outAudio, hBits +#ifdef SPLIT_REND_PLC + , + hIvasRend->splitRendBFI +#endif + ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + return IVAS_ERR_OK; +} +#endif static ivas_error renderActiveInputsSba( IVAS_REND_HANDLE hIvasRend, - IVAS_REND_AudioBuffer outAudio ) + IVAS_REND_AudioBuffer outAudio +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + IVAS_REND_BitstreamBuffer *hBits +#endif +) { int16_t i; input_sba *pCurrentInput; @@ -5875,7 +7995,12 @@ static ivas_error renderActiveInputsSba( continue; } - if ( ( error = renderInputSba( pCurrentInput, hIvasRend->outputConfig, outAudio ) ) != IVAS_ERR_OK ) + if ( ( error = renderInputSba( pCurrentInput, hIvasRend->outputConfig, outAudio +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + hBits +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -6149,7 +8274,7 @@ static ivas_error renderInputMasa( case IVAS_REND_AUDIO_CONFIG_BINAURAL: renderMasaToBinaural( masaInput, outAudio ); break; - /* ToDo */ + /* ToDo */ //#ifdef FIX_196_REFACTOR_RENDERER_OUTPUT_CONFIG // case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_IR: // case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: @@ -6361,18 +8486,33 @@ ivas_error IVAS_REND_SetTotalNumberOfObjects( ivas_error IVAS_REND_GetSamples( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + IVAS_REND_BitstreamBuffer *hBits /*i/o: buffer for input/output bitstream. Needed in split rendering mode*/ +#endif ) { ivas_error error; int16_t numOutChannels; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t cldfb2tdSampleFact; + IVAS_REND_AudioBuffer outAudioOrig; +#endif /* Validate function arguments */ if ( hIvasRend == NULL || outAudio.data == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - +#ifdef SPLIT_REND_WITH_HEAD_ROT + cldfb2tdSampleFact = ( outAudio.config.is_cldfb ) ? 2 : 1; +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( outAudio.config.numSamplesPerChannel <= 0 || ( MAX_BUFFER_LENGTH_PER_CHANNEL < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 0 ) || + ( ( MAX_BUFFER_LENGTH_PER_CHANNEL * cldfb2tdSampleFact ) < outAudio.config.numSamplesPerChannel && outAudio.config.is_cldfb == 1 ) ) +#else if ( outAudio.config.numSamplesPerChannel <= 0 || MAX_BUFFER_LENGTH_PER_CHANNEL < outAudio.config.numSamplesPerChannel ) +#endif { return IVAS_ERR_INVALID_BUFFER_SIZE; } @@ -6381,9 +8521,13 @@ ivas_error IVAS_REND_GetSamples( { return IVAS_ERR_WRONG_NUM_CHANNELS; } - +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && + ( outAudio.config.numSamplesPerChannel * 1000 / cldfb2tdSampleFact ) != BINAURAL_RENDERING_FRAME_SIZE_MS * hIvasRend->sampleRateOut ) +#else if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && outAudio.config.numSamplesPerChannel * 1000 != BINAURAL_RENDERING_FRAME_SIZE_MS * hIvasRend->sampleRateOut ) +#endif { /* Binaural rendering requires specific frame size */ return IVAS_ERR_INVALID_BUFFER_SIZE; @@ -6430,6 +8574,20 @@ ivas_error IVAS_REND_GetSamples( return IVAS_ERR_WRONG_NUM_CHANNELS; } +#ifdef SPLIT_REND_LC3PLUS + /* Clear original output buffer */ + set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel ); + + outAudioOrig = outAudio; + /* Use internal buffer if outputting split rendering bitstream */ + if ( ( hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB ) || + ( ( hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && + ( hIvasRend->inputsIsm[0].base.inConfig != IVAS_REND_AUDIO_CONFIG_UNKNOWN ) ) ) + { + outAudio = hIvasRend->splitRendEncBuffer; + } +#endif + /* Clear output buffer */ set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel ); @@ -6443,7 +8601,12 @@ ivas_error IVAS_REND_GetSamples( return error; } - if ( ( error = renderActiveInputsSba( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + if ( ( error = renderActiveInputsSba( hIvasRend, outAudio +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + hBits +#endif + ) ) != IVAS_ERR_OK ) { return error; } @@ -6452,11 +8615,81 @@ ivas_error IVAS_REND_GetSamples( { return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = renderActiveInputsSplitBin( hIvasRend, outAudio, hBits ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( outAudio.config.is_cldfb == 0 ) + { +#ifdef DEBUGGING + hIvasRend->numClipping += +#endif + limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); + } +#else #ifdef DEBUGGING hIvasRend->numClipping += #endif limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); +#endif + +#ifdef SPLIT_REND_LC3PLUS + if ( ( hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB +#ifdef SPLIT_REND_CLDFB_ISM + || hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif + ) + /* The condition below is a temp fix for differences in procesing paths between split rendering of SBA and ISM. Should be unified */ +#ifdef SPLIT_REND_LC3PLUS_MC + && ( ( hIvasRend->inputsIsm[0].base.inConfig != IVAS_REND_AUDIO_CONFIG_UNKNOWN ) || + ( hIvasRend->inputsMc[0].base.inConfig != IVAS_REND_AUDIO_CONFIG_UNKNOWN ) ) ) +#else + && hIvasRend->inputsIsm[0].base.inConfig != IVAS_REND_AUDIO_CONFIG_UNKNOWN ) +#endif + { + /* TODO: doesn't work for multiple SBA inputs, needs to be updated like the ISM path for TD */ + ivas_split_rend_bits_t bits; + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float tmpBinaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k]; + + copyBufferTo2dArray( outAudio, tmpBinaural ); + + /* Encode split rendering bitstream */ + convertBitsBufferToInternalBitsBuff( *hBits, &bits ); + error = ivas_renderMultiBinToSplitBinaural( &hIvasRend->splitRendWrapper, + hIvasRend->headRotData.headPositions, + hIvasRend->hRendererConfig->split_rend_config.splitRendBitRate, + hIvasRend->hRendererConfig->split_rend_config.codec, + &bits, + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural, + ( const int16_t )( ( BINAURAL_MAXBANDS * hIvasRend->sampleRateOut ) / 48000 ), + tmpBinaural, + 1, + 1, +#ifdef SPLIT_REND_CLDFB_ISM + ( hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 +#else + 0 +#endif + ); + if ( error != IVAS_ERR_OK ) + { + return error; + } + convertInternalBitsBuffToBitsBuffer( hBits, bits ); + outAudio = outAudioOrig; + accumulate2dArrayToBuffer( tmpBinaural, &outAudio ); + } +#endif + return IVAS_ERR_OK; } @@ -6504,12 +8737,22 @@ void IVAS_REND_Close( { clearInputMasa( &hIvasRend->inputsMasa[i] ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + { + clearInputSplitRend( &hIvasRend->inputsSplitPost[i] ); + } +#endif /* clear Config. Renderer */ ivas_render_config_close( &( hIvasRend->hRendererConfig ) ); ivas_limiter_close( &hIvasRend->hLimiter ); +#ifdef SPLIT_REND_LC3PLUS + closeSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); +#endif + closeHeadRotation( hIvasRend ); ivas_external_orientation_close( &hIvasRend->hExternalOrientationData ); diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 88e96d29163fa21347d37c2fea20aeacf20f985c..3bae23f1fb34d0057bd2a186f1092bff3d23020f 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -41,6 +41,9 @@ #define RENDERER_MAX_MC_INPUTS 1 #define RENDERER_MAX_SBA_INPUTS 1 #define RENDERER_MAX_MASA_INPUTS 1 +#ifdef SPLIT_REND_WITH_HEAD_ROT +#define RENDERER_MAX_BIN_INPUTS 1 +#endif typedef float IVAS_REND_LfePanMtx[IVAS_MAX_INPUT_LFE_CHANNELS][IVAS_MAX_OUTPUT_CHANNELS]; @@ -49,6 +52,9 @@ typedef struct { int16_t numSamplesPerChannel; int16_t numChannels; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t is_cldfb; +#endif } IVAS_REND_AudioBufferConfig; typedef struct @@ -57,6 +63,22 @@ typedef struct float *data; } IVAS_REND_AudioBuffer; +typedef struct +{ + int32_t bufLenInBytes; + int32_t bitsWritten; + int32_t bitsRead; +#ifdef SPLIT_REND_LC3PLUS + IVAS_SPLIT_REND_CODEC codec; + IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; +#endif +} IVAS_REND_BitstreamBufferConfig; +typedef struct +{ + IVAS_REND_BitstreamBufferConfig config; + uint8_t *bits; +} IVAS_REND_BitstreamBuffer; + typedef struct { IVAS_REND_AudioBufferConfig config; @@ -113,6 +135,11 @@ typedef enum IVAS_REND_AUDIO_CONFIG_OBJECT = IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED << 8 | 0, IVAS_REND_AUDIO_CONFIG_BINAURAL = IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL << 8 | 0, + +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_PCM = IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL << 8 | 3, + IVAS_REND_AUDIO_CONFIG_BINAURAL_SPLIT_CLDFB = IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL << 8 | 4, +#endif IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_IR = IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL << 8 | 1, IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM_REVERB = IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL << 8 | 2, @@ -248,7 +275,11 @@ int16_t IVAS_REND_FeedRenderConfig( ivas_error IVAS_REND_SetHeadRotation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME], /* i : head orientations for next rendering call */ - const IVAS_VECTOR3 Pos[RENDERER_HEAD_POSITIONS_PER_FRAME] /* i : listener positions for next rendering call */ + const IVAS_VECTOR3 Pos[RENDERER_HEAD_POSITIONS_PER_FRAME] /* i : listener positions for next rendering call */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + IVAS_SPLIT_REND_ROT_AXIS rot_axis +#endif ); ivas_error IVAS_REND_SetOrientationTrackingMode( @@ -277,6 +308,12 @@ ivas_error IVAS_REND_SetReferenceVector( const IVAS_VECTOR3 refPos /* i : Reference position */ ); +#ifdef SPLIT_REND_PLC +ivas_error IVAS_REND_SetSplitRendBFI( + IVAS_REND_HANDLE hIvasRend, + const int16_t bfi); +#endif + ivas_error IVAS_REND_SetExternalOrientation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ IVAS_QUATERNION *orientation, /* i : external orientation data */ @@ -321,6 +358,10 @@ ivas_error IVAS_REND_GetNumAllObjects( ivas_error IVAS_REND_GetSamples( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + IVAS_REND_BitstreamBuffer *hBits /*i/o: buffer for input/output bitstream. Needed in split rendering mode*/ +#endif ); /* Functions to be called after rendering */ @@ -340,5 +381,4 @@ int32_t IVAS_REND_GetCntFramesLimited( #endif /* clang-format on */ - #endif diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index e2181ca6e161dfa01782eb1b87605056565db857..e6850743b5d4d9699087e8040f4220ccb879dfc0 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -1030,7 +1030,7 @@ static ivas_error create_fastconv_HRTF_from_rawdata( // if ( hHRTF == NULL ) // { - // if ( ( ( *hHRTF ) = (HRTFS_FASTCONV_HANDLE) count_malloc( sizeof( HRTFS_FASTCONV ) ) ) == NULL ) + // if ( ( ( *hHRTF ) = (HRTFS_FASTCONV_HANDLE) malloc( sizeof( HRTFS_FASTCONV ) ) ) == NULL ) // { // return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "Can not allocate memory for Fastconv HRTF binary\n" ); // } diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index a3b04563e4e62141f8ed937b110ecad6b27c3522..cf89b3b7dad6649bace2bf4df2b170651158f8c9 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -175,7 +175,7 @@ static void strip_spaces_upper( while ( pStr[read_idx] ) { - if ( !isspace( pStr[read_idx] ) && !iscntrl( pStr[read_idx] ) ) + if ( !isspace( (int32_t) pStr[read_idx] ) && !iscntrl( (int32_t) pStr[read_idx] ) ) { pStr[write_idx++] = pStr[read_idx]; } @@ -290,7 +290,7 @@ static ivas_error RenderConfigReader_checkValues( return IVAS_ERR_WRONG_PARAMS; } -#ifdef DEBUGGING +#if ( defined DEBUGGING ) || ( defined SPLIT_REND_WITH_HEAD_ROT ) /* Specific limits for Jot reverb */ if ( hRenderConfig->renderer_type_override == IVAS_RENDER_TYPE_OVERRIDE_CREND ) { @@ -485,7 +485,66 @@ ivas_error RenderConfigReader_read( fprintf( stderr, "Reverb config: number of bands changed but configuration vectors missing\n" ); } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + else if ( strcmp( chapter, "SPLITREND" ) == 0 && strlen( pParams ) != 0 ) + { + params_idx = 0; + pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); + while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) + { + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); + fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); + if ( strcmp( item, "CODECDELAY" ) == 0 ) + { + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.codec_delay_ms ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "HQMODE" ) == 0 ) + { + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.hq_mode ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "BITRATE" ) == 0 ) + { + if ( !sscanf( pValue, "%d", &hRenderConfig->split_rend_config.splitRendBitRate ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "DOF" ) == 0 ) + { + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.dof ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } +#ifdef SPLIT_REND_LC3PLUS + else if ( strcmp( item, "CODEC" ) == 0 ) + { + int16_t tmp; + if ( !sscanf( pValue, "%hd", &tmp ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + hRenderConfig->split_rend_config.codec = tmp == 0 ? IVAS_SPLIT_REND_CODEC_LCLD : IVAS_SPLIT_REND_CODEC_LC3PLUS; + } +#endif + #ifdef DEBUGGING + else + { + fprintf( stderr, "Unsupported configuration property %s\n", item ); + } +#endif + } + free( pValue ); + } +#endif +#if ( defined DEBUGGING ) || ( defined SPLIT_REND_WITH_HEAD_ROT ) else if ( strcmp( chapter, "GENERAL" ) == 0 && strlen( pParams ) != 0 ) { params_idx = 0; diff --git a/lib_util/split_rend_bfi_file_reader.c b/lib_util/split_rend_bfi_file_reader.c new file mode 100644 index 0000000000000000000000000000000000000000..2c1fe4e3b86b2b8b7bb4777cb6bb7b552bfd73b3 --- /dev/null +++ b/lib_util/split_rend_bfi_file_reader.c @@ -0,0 +1,161 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "split_rend_bfi_file_reader.h" +#include +#include +#include +#include +#include "prot.h" + +struct SplitRendBFIFileReader +{ + FILE *bfiFile; + int32_t frameCounter; + char *file_path; + bool fileRewind; + bool txtfile; +}; + + +/*-----------------------------------------------------------------------* + * SplitRendBFIFileReader_open() + * + * Allocate and initialize Split Renderer Frameloss file reader + *-----------------------------------------------------------------------*/ + +ivas_error SplitRendBFIFileReader_open( + char *bfiFilePath, /* i : frame loss file name */ + SplitRendBFIFileReader **SplitRendBFIReader /* o : SplitRendBFIFileReader handle */ +) +{ + SplitRendBFIFileReader *self; + FILE *bfiFile; + bool txtfile; + + /* Open bfi file */ + if ( strlen( bfiFilePath ) < 1 ) + { + return IVAS_ERR_FAILED_FILE_OPEN; + } + + bfiFile = fopen( bfiFilePath, "r" ); + + if ( !bfiFile ) + { + return IVAS_ERR_FAILED_FILE_OPEN; + } + + txtfile = ( strcmp( bfiFilePath + strlen( bfiFilePath ) - 4, ".txt" ) ? false : true ); + + self = calloc( sizeof( SplitRendBFIFileReader ), 1 ); + self->bfiFile = bfiFile; + self->frameCounter = 0; + self->file_path = calloc( sizeof( char ), strlen( bfiFilePath ) + 1 ); + strcpy( self->file_path, bfiFilePath ); + self->fileRewind = false; + self->txtfile = txtfile; + + *SplitRendBFIReader = self; + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------* + * SplitRendBFIFileReading() + * + * Read values from the bfi file + *-----------------------------------------------------------------------*/ + +ivas_error SplitRendBFIFileReading( + SplitRendBFIFileReader *SplitRendBFIReader, /* i/o: SplitRendBFIFileReader handle */ + int16_t *bfi ) +{ + if ( SplitRendBFIReader->txtfile ? 1 != fscanf( SplitRendBFIReader->bfiFile, "%hd", bfi ) : 1 != fread( bfi, sizeof( *bfi ), 1, SplitRendBFIReader->bfiFile ) ) + { + if ( feof( SplitRendBFIReader->bfiFile ) ) + { + rewind( SplitRendBFIReader->bfiFile ); + SplitRendBFIReader->fileRewind = true; + return SplitRendBFIFileReading( SplitRendBFIReader, bfi ); + } + return IVAS_ERR_FAILED_FILE_PARSE; + } + + ( SplitRendBFIReader->frameCounter )++; + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------* + * SplitRendBFIationFileReader_close() + * + * Deallocates memory for the Head-Tracking reader + *-----------------------------------------------------------------------*/ + +void SplitRendBFIFileReader_close( + SplitRendBFIFileReader **SplitRendBFIReader /* i/o: SplitRendBFIFileReader handle */ +) +{ + if ( SplitRendBFIReader == NULL || *SplitRendBFIReader == NULL ) + { + return; + } + + fclose( ( *SplitRendBFIReader )->bfiFile ); + free( ( *SplitRendBFIReader )->file_path ); + free( *SplitRendBFIReader ); + *SplitRendBFIReader = NULL; + + return; +} + + +/*-----------------------------------------------------------------------* + * SplitRendBFIFileReader_getFilePath() + * + * + *-----------------------------------------------------------------------*/ + +const char *SplitRendBFIFileReader_getFilePath( + SplitRendBFIFileReader *SplitRendBFIReader /* i/o: SplitRendBFIFileReader handle */ +) +{ + if ( SplitRendBFIReader == NULL ) + { + return NULL; + } + + return SplitRendBFIReader->file_path; +} diff --git a/lib_util/split_rend_bfi_file_reader.h b/lib_util/split_rend_bfi_file_reader.h new file mode 100644 index 0000000000000000000000000000000000000000..97df1c7fbb0124bddbc66b0887ac24854ed6265c --- /dev/null +++ b/lib_util/split_rend_bfi_file_reader.h @@ -0,0 +1,60 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef IVAS_SR_BFI_FILE_READER_H +#define IVAS_SR_BFI_FILE_READER_H + +#include "common_api_types.h" +#include "ivas_error.h" + + +typedef struct SplitRendBFIFileReader SplitRendBFIFileReader; + +ivas_error SplitRendBFIFileReader_open( + char *trajFilePath, /* i : head rotation trajectory file name */ + SplitRendBFIFileReader **SplitRendBFIReader /* o : SplitRendBFIFileReader handle */ +); + +ivas_error SplitRendBFIFileReading( + SplitRendBFIFileReader *SplitRendBFIReader, /* i/o: SplitRendBFIFileReader handle */ + int16_t *bfi ); + +void SplitRendBFIFileReader_close( + SplitRendBFIFileReader **SplitRendBFIReader /* i/o: SplitRendBFIFileReader handle */ +); + +const char *SplitRendBFIFileReader_getFilePath( + SplitRendBFIFileReader *SplitRendBFIReader /* i/o: SplitRendBFIFileReader handle */ +); + + +#endif /* IVAS_SR_BFI_FILE_READER_H */ diff --git a/lib_util/split_render_file_read_write.c b/lib_util/split_render_file_read_write.c new file mode 100644 index 0000000000000000000000000000000000000000..2e9547ce081b56af505429ef12b9358d0a345270 --- /dev/null +++ b/lib_util/split_render_file_read_write.c @@ -0,0 +1,298 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include "split_render_file_read_write.h" +#include +#include +#include +#include +#include +#include "cmdl_tools.h" +#include "prot.h" +#include "ivas_cnst.h" + +/*------------------------------------------------------------------------------------------* + * PreProc Macros + *------------------------------------------------------------------------------------------*/ +#define SPLIT_RENDERER_FRAME_HEADER_LEN ( 12 ) + +/*------------------------------------------------------------------------------------------* + * Type definitions + *------------------------------------------------------------------------------------------*/ + +#ifdef SPLIT_REND_WITH_HEAD_ROT +struct SplitFileReadWrite +{ + FILE *file; + uint32_t delay_ns; +}; + + +/*-----------------------------------------------------------------------------------------* + * Function split_rend_reader_open() + * open in read mode + *-----------------------------------------------------------------------------------------*/ +ivas_error split_rend_reader_open( SplitFileReadWrite **hhSplitRendFileReadWrite, char *filename ) +{ + SplitFileReadWrite *hSplitRendFileReadWrite; + size_t header_len, h; + char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "MAIN_SPLITH"; + char header_read[SPLIT_RENDERER_FRAME_HEADER_LEN]; + + hSplitRendFileReadWrite = (SplitFileReadWrite *) malloc( sizeof( SplitFileReadWrite ) ); + hSplitRendFileReadWrite->file = fopen( filename, "rb" ); + if ( hSplitRendFileReadWrite->file == NULL ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", filename ); + exit( -1 ); + } + + header_len = strlen( header ); + + /*read frame header*/ + for ( h = 0; h < header_len; h++ ) + { + if ( fread( &header_read[h], sizeof( char ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + } + if ( strncmp( header_read, header, header_len ) ) + { + fprintf( stderr, "Error split rend bitstream main header mismatch\n" ); + return IVAS_ERR_FAILED_FILE_READ; + } + + fread( &hSplitRendFileReadWrite->delay_ns, sizeof( uint32_t ), 1, hSplitRendFileReadWrite->file ); + + *hhSplitRendFileReadWrite = hSplitRendFileReadWrite; + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------------------------* + * Function split_rend_writer_open() + * open in write mode + *-----------------------------------------------------------------------------------------*/ +ivas_error split_rend_writer_open( SplitFileReadWrite **hhSplitRendFileReadWrite, char *filename, int16_t delayNumSamples, int32_t delayTimeScale ) +{ + SplitFileReadWrite *hSplitRendFileReadWrite; + size_t header_len, h; + char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "MAIN_SPLITH"; + + hSplitRendFileReadWrite = (SplitFileReadWrite *) malloc( sizeof( SplitFileReadWrite ) ); + hSplitRendFileReadWrite->file = fopen( filename, "wb" ); + if ( hSplitRendFileReadWrite->file == NULL ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", filename ); + exit( -1 ); + } + + header_len = strlen( header ); + + /*read frame header*/ + for ( h = 0; h < header_len; h++ ) + { + if ( fwrite( &header[h], sizeof( char ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_END_OF_FILE; + } + } + hSplitRendFileReadWrite->delay_ns = (int32_t) ( (float) delayNumSamples * 1000000000.0f / (float) delayTimeScale ); + fwrite( &hSplitRendFileReadWrite->delay_ns, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ); + + *hhSplitRendFileReadWrite = hSplitRendFileReadWrite; + return IVAS_ERR_OK; +} + +ivas_error split_rend_reader_writer_close( SplitFileReadWrite **hhSplitRendFileReadWrite ) +{ + if ( ( *hhSplitRendFileReadWrite ) != NULL ) + { + if ( ( *hhSplitRendFileReadWrite )->file != NULL ) + { + fclose( ( *hhSplitRendFileReadWrite )->file ); + ( *hhSplitRendFileReadWrite )->file = NULL; + } + free( *hhSplitRendFileReadWrite ); + *hhSplitRendFileReadWrite = NULL; + } + return IVAS_ERR_OK; +} + +ivas_error split_rend_write_bitstream_to_file( SplitFileReadWrite *hSplitRendFileReadWrite, uint8_t *bits, int32_t *bits_read, int32_t *bits_written +#ifdef SPLIT_REND_LC3PLUS + , + IVAS_SPLIT_REND_CODEC codec, + IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection +#endif +) +{ + char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "SPLIT_FRAME"; + size_t header_len, i, num_bytes; + + if ( hSplitRendFileReadWrite == NULL ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + if ( hSplitRendFileReadWrite->file == NULL ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + header_len = strlen( header ); + + /*write frame header*/ + for ( i = 0; i < header_len; i++ ) + { + if ( fwrite( &header[i], sizeof( char ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + } + +#ifdef SPLIT_REND_LC3PLUS + /* Write codec signalling */ + if ( fwrite( &codec, sizeof( codec ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + /* Write pose correction signalling */ + if ( fwrite( &poseCorrection, sizeof( poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } +#endif + + /*write num bytes*/ + if ( fwrite( bits_written, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + num_bytes = ( *bits_written + 7 ) >> 3; + if ( fwrite( bits, sizeof( uint8_t ), num_bytes, hSplitRendFileReadWrite->file ) != num_bytes ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + *bits_read = 0; + *bits_written = 0; + + return IVAS_ERR_OK; +} + +ivas_error split_rend_read_bits_from_file( SplitFileReadWrite *hSplitRendFileReadWrite, uint8_t *bits, int32_t *bits_read, int32_t *bits_written +#ifdef SPLIT_REND_LC3PLUS + , + IVAS_SPLIT_REND_CODEC *codec, + IVAS_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection +#endif +) +{ + char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "SPLIT_FRAME"; + char header_read[SPLIT_RENDERER_FRAME_HEADER_LEN]; + int32_t header_len, i, num_bytes, bit_len = 0; + + if ( hSplitRendFileReadWrite == NULL ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + if ( hSplitRendFileReadWrite->file == NULL ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + header_len = strlen( header ); + + /*write frame header*/ + for ( i = 0; i < header_len; i++ ) + { + if ( fread( &header_read[i], sizeof( char ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_END_OF_FILE; + } + } + if ( strncmp( header_read, header, header_len ) ) + { + fprintf( stderr, "Error bitstream frame header mismatch\n" ); + return IVAS_ERR_FAILED_FILE_READ; + } + +#ifdef SPLIT_REND_LC3PLUS + /* read codec signalling */ + if ( fread( codec, sizeof( *codec ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + /* read pose correction signalling */ + if ( fread( poseCorrection, sizeof( *poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } +#endif + + /*write num bytes*/ + if ( fread( &bit_len, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + num_bytes = ( bit_len + 7 ) >> 3; + + if ( fread( bits, sizeof( uint8_t ), num_bytes, hSplitRendFileReadWrite->file ) != (uint32_t) num_bytes ) + { + return IVAS_ERR_FAILED_FILE_READ; + } +#ifdef SPLIT_REND_CLDFB_HUFF_SAN_FIX + for ( i = 0; i < SPLIT_REND_ADDITIONAL_BYTES_TO_READ; i++ ) + { + bits[num_bytes + i] = 0; + } +#endif + + *bits_read = 0; + *bits_written = bit_len; + + return IVAS_ERR_OK; +} + +ivas_error split_rend_read_pre_rend_delay_ns( SplitFileReadWrite *hSplitRendFileReadWrite, uint32_t *delay_ns ) +{ + if ( hSplitRendFileReadWrite == NULL ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + *delay_ns = hSplitRendFileReadWrite->delay_ns; + return IVAS_ERR_OK; +} +#endif diff --git a/lib_util/split_render_file_read_write.h b/lib_util/split_render_file_read_write.h new file mode 100644 index 0000000000000000000000000000000000000000..2ec0cdcb54df75a20d0cb956569339cbb7183126 --- /dev/null +++ b/lib_util/split_render_file_read_write.h @@ -0,0 +1,73 @@ +/****************************************************************************************************** + + (C) 2022 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, + Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., + Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, + Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other + contributors to this repository retain full ownership rights in their respective contributions in + the software. This notice grants no license of any kind, including but not limited to patent + license, nor is any license granted by implication, estoppel or otherwise. + + Contributors are required to enter into the IVAS codec Public Collaboration agreement before making + contributions. + + This software is provided "AS IS", without any express or implied warranties. The software is in the + development stage. It is intended exclusively for experts who have experience with such software and + solely for the purpose of inspection. All implied warranties of non-infringement, merchantability + and fitness for a particular purpose are hereby disclaimed and excluded. + + Any dispute, controversy or claim arising under or in relation to providing this software shall be + submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in + accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and + the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#ifndef SPLIT_RENDER_FILE_READ_WRITE_H +#define SPLIT_RENDER_FILE_READ_WRITE_H + +#include "common_api_types.h" +#include "ivas_error.h" + + +typedef struct SplitFileReadWrite SplitFileReadWrite; + +/* Allocates and initializes a a split renderer reader instance */ +ivas_error split_rend_reader_open( SplitFileReadWrite **hhSplitRendFileReadWrite, char *filename ); + + +/* Allocates and initializes a a split renderer writer instance */ +ivas_error split_rend_writer_open( SplitFileReadWrite **hhSplitRendFileReadWrite, char *filename, int16_t delayNumSamples, int32_t delayTimeScale ); + +/* Closes the split renderer reader/writer and deallocates memory */ +ivas_error split_rend_reader_writer_close( SplitFileReadWrite **hhSplitRendFileReadWrite ); + +/*write split rend coded bitstream to file*/ +ivas_error split_rend_write_bitstream_to_file( SplitFileReadWrite *hSplitRendFileReadWrite, uint8_t *bits, int32_t *bits_read, int32_t *bits_written +#ifdef SPLIT_REND_LC3PLUS + , + IVAS_SPLIT_REND_CODEC codec, + IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection +#endif +); + +/*read split rend coded bits from file*/ +ivas_error split_rend_read_bits_from_file( SplitFileReadWrite *hSplitRendFileReadWrite, uint8_t *bits, int32_t *bits_read, int32_t *bits_written +#ifdef SPLIT_REND_LC3PLUS + , + IVAS_SPLIT_REND_CODEC *codec, + IVAS_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection +#endif +); + +/*read split pre rend delay*/ +ivas_error split_rend_read_pre_rend_delay_ns( SplitFileReadWrite *hSplitRendFileReadWrite, uint32_t *delay_ns ); + +#endif diff --git a/scripts/cppp/.gitignore b/scripts/cppp/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d9e7f83c69df888bde70e174e43f27bbe74d7f63 --- /dev/null +++ b/scripts/cppp/.gitignore @@ -0,0 +1,2 @@ +*.pm +*.pl \ No newline at end of file diff --git a/scripts/lc3plus_lib_setup/get_lc3plus.sh b/scripts/lc3plus_lib_setup/get_lc3plus.sh new file mode 100755 index 0000000000000000000000000000000000000000..52152999cf7612eb60ea66898c23c6bd81682cd5 --- /dev/null +++ b/scripts/lc3plus_lib_setup/get_lc3plus.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +# This script shall only be used by automated continuous integration systems + +scriptdir=$(dirname "$0") +pushd "$scriptdir" || exit 1 + +# Download and unzip LC3plus code +rm -rf ETSI_Release +curl -o ./lc3plus_sources.zip https://www.etsi.org/deliver/etsi_ts/103600_103699/103634/01.04.01_60/ts_103634v010401p0.zip +unzip lc3plus_sources.zip -d . + +# Modify LC3plus code to be compatible with IVAS tools (e.g. WMC tool) +git apply --ignore-whitespace lc3plus.patch +rm ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft.c +rm ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/codec_exe.c +rm ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/makefile +rm ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tinywavein_c.h +rm ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tinywaveout_c.h +rm -r ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/msvc +find ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point -type f -exec chmod -x {} \; + +# Move to output dir +rm -rf ../../lc3plus +mkdir ../../lc3plus +mv ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/* ../../lc3plus + +# Clean up +rm -rf lc3plus_sources.zip ETSI_Release + +popd || exit diff --git a/scripts/lc3plus_lib_setup/lc3plus.patch b/scripts/lc3plus_lib_setup/lc3plus.patch new file mode 100644 index 0000000000000000000000000000000000000000..14b81a39727b034b4d1de3b01a90879baeb34947 --- /dev/null +++ b/scripts/lc3plus_lib_setup/lc3plus.patch @@ -0,0 +1,1474 @@ +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/adjust_global_gain.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/adjust_global_gain.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/adjust_global_gain.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/adjust_global_gain.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + void processAdjustGlobalGain_fl(LC3_INT* gg_idx, LC3_INT gg_idx_min, LC3_INT gg_idx_off, LC3_FLOAT* gain, LC3_INT target, LC3_INT nBits, LC3_INT* gainChange, LC3_INT fs_idx +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/al_fec_fl.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/al_fec_fl.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/al_fec_fl.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/al_fec_fl.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "stdint.h" + #include + #include +@@ -1010,8 +1011,8 @@ + LC3_UINT8 blacklist[FEC_N_MODES]; + LC3_INT32 rop; + +- rop = 0; + void (*syndr_calc[3])(LC3_UINT8 *, LC3_UINT8 *, LC3_INT32); ++ rop = 0; + + /* initialization */ + blacklist[0] = 0; +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/apply_global_gain.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/apply_global_gain.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/apply_global_gain.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/apply_global_gain.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + void processApplyGlobalGain_fl(LC3_FLOAT x[], LC3_INT xLen, LC3_INT global_gain_idx, LC3_INT global_gain_off) +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ari_codec.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ari_codec.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ari_codec.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ari_codec.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + static void ac_shift_fl(Encoder_State_fl* st); +@@ -620,7 +621,7 @@ + + if (st.pc_c_bp_side != 0) + { +- nbits_side = total_bits - 8 * (st.pc_b_left) + 8 * (st.pc_bytes - bp_side) - (8 - LC3_LOG2(mask_side)); ++ nbits_side = total_bits - 8 * (st.pc_b_left) + 8 * (st.pc_bytes - bp_side) - (8 - LC3_LOGTWO(mask_side)); + } + } + +@@ -891,7 +892,7 @@ + { + LC3_INT bits = 0, mask = 0, val = 0, over1 = 0, high = 0, over2 = 0, c = 0, b = 0; + +- bits = 24 - floor(LC3_LOG2(st->range)); ++ bits = 24 - floor(LC3_LOGTWO(st->range)); + mask = ((LC3_INT)pow(2, 24) - 1) >> bits; + val = st->low + mask; + over1 = val >> 24; +@@ -1078,8 +1079,8 @@ + } + + /* Residual bits */ +- nbits_side = total_bits - (8 * (*(st.bp_side) + 1) + 8 - LC3_LOG2(*(st.mask_side))); +- nbits_ari = (st.bp + 1) * 8 + 25 - floor(LC3_LOG2(st.range)); ++ nbits_side = total_bits - (8 * (*(st.bp_side) + 1) + 8 - LC3_LOGTWO(*(st.mask_side))); ++ nbits_ari = (st.bp + 1) * 8 + 25 - floor(LC3_LOGTWO(st.range)); + + if (st.cache >= 0) { + nbits_ari = nbits_ari + 8; +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/attack_detector.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/attack_detector.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/attack_detector.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/attack_detector.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + void attack_detector_fl(LC3_FLOAT* in, LC3_INT frame_size, LC3_INT fs, LC3_INT* lastAttackPosition, LC3_FLOAT* accNrg, LC3_INT* attackFlag, +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/constants.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/constants.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/constants.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/constants.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + /* DCT */ +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/cutoff_bandwidth.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/cutoff_bandwidth.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/cutoff_bandwidth.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/cutoff_bandwidth.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + void process_cutoff_bandwidth(LC3_FLOAT *d_fl, LC3_INT len, LC3_INT bw_bin) +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dct4.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dct4.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dct4.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dct4.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + void dct2_init(Dct2* dct, int length) +@@ -27,11 +28,11 @@ + + void dct2_apply(Dct2* dct, const LC3_FLOAT* input, LC3_FLOAT* output) + { +- assert(input != output); + Complex tmp1[MAX_LEN]; + Complex tmp2[MAX_LEN]; + int i = 0; + const int len = dct->length; ++ assert(input != output); + + for (i = 0; i < len / 2; i++) { + tmp1[i] = cmplx(input[i * 2], 0); +@@ -49,8 +50,8 @@ + + void dct4_init(Dct4* dct, int length) + { +- assert(length <= MAX_LEN); + int i = 0; ++ assert(length <= MAX_LEN); + dct->length = length; + dct->twid1 = calloc(sizeof(*dct->twid1), length / 2); + dct->twid2 = calloc(sizeof(*dct->twid2), length / 2); +@@ -73,12 +74,12 @@ + + void dct4_apply(Dct4* dct, const LC3_FLOAT* input, LC3_FLOAT* output) + { +- assert(input != output); + Complex tmp2[MAX_LEN / 2]; + int i = 0; + Complex* tmp1 = (Complex*)output; + const int len = dct->length; + const LC3_FLOAT norm = (LC3_FLOAT)1.0 / LC3_SQRT((LC3_FLOAT)(len >> 1)); ++ assert(input != output); + + for (i = 0; i < len / 2; i++) { + tmp1[i] = cmul(cmplx(input[i * 2], input[len - i * 2 - 1]), dct->twid1[i]); +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dec_entropy.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dec_entropy.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dec_entropy.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dec_entropy.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + static void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit); +@@ -53,7 +54,7 @@ + LC3_INT nbbytes = nbbits >> 3; + LC3_INT lastnz; + LC3_INT bw_cutoff_idx; +- LC3_INT nbits = ceil(LC3_LOG2(L_spec / 2)); ++ LC3_INT nbits = ceil(LC3_LOGTWO(L_spec / 2)); + + if (nbits > nbbits) + { +@@ -173,7 +174,7 @@ + } + + /* Last non-zero tuple */ +- read_uint_fl(ceil(LC3_LOG2(N / 2)), ptr, &mask_side_local, &bp_side_local, lastnz); ++ read_uint_fl(ceil(LC3_LOGTWO(N / 2)), ptr, &mask_side_local, &bp_side_local, lastnz); + *lastnz = (*lastnz + 1) * 2; + + if (*lastnz > N) { +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dec_lc3_fl.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dec_lc3_fl.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dec_lc3_fl.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/dec_lc3_fl.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + +@@ -53,8 +54,8 @@ + + if (decoder->rframe == 1 && zero_frame == 0 && bfi != 1) + { +- bfi = 2; + LC3_INT32 max_bw_stopband = BW_cutoff_bin_all[bw_cutoff_idx]; ++ bfi = 2; + switch (decoder->frame_dms) + { + # ifdef ENABLE_025_DMS_MODE +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/defines.h mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/defines.h +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/defines.h 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/defines.h 2023-06-29 12:58:27 +@@ -24,13 +24,13 @@ + typedef uint32_t LC3_UINT32; + + /* Release defines */ +-#define ENABLE_2_5MS_MODE ++// #define ENABLE_2_5MS_MODE + #define ENABLE_5MS_MODE + #define ENABLE_10_MS_MODE + #define ENABLE_ADVANCED_PLC_FL + #define ENABLE_ADVANCED_PLC_FL_DEFAULT + #define ENABLE_BW_CONTROLLER +-#define ENABLE_HR_MODE_FL ++//#define ENABLE_HR_MODE_FL + #define ENABLE_PADDING + #define ENABLE_RFRAME_FL + #define ENABLE_PLC +@@ -49,8 +49,8 @@ + /* Precision Defines */ + #define LC3_FABS(x) (fabsf(x)) + #define LC3_POW(x, y) (powf(x, y)) +-#define LC3_LOG10(x) (log10f(x)) +-#define LC3_LOG2(x) (log2f(x)) ++#define LC3_LOGTEN(x) (log10f(x)) ++#define LC3_LOGTWO(x) (log2f(x)) + # define LC3_COS(x) (cos(x)) + # define LC3_SIN(x) (sin(x)) + #define LC3_SQRT(x) (sqrtf(x)) +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/detect_cutoff_warped.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/detect_cutoff_warped.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/detect_cutoff_warped.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/detect_cutoff_warped.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + void processDetectCutoffWarped_fl(LC3_FLOAT* d2, LC3_INT fs_idx, LC3_INT frame_dms, LC3_INT* bw_idx) +@@ -68,7 +69,7 @@ + dist = bw_dist[counter]; + + for (i = stop; i >= stop - dist; i--) { +- e_diff = 10.0 * LC3_LOG10(d2[i - dist + 1] + FLT_EPSILON) - 10.0 * LC3_LOG10(d2[i + 1] + FLT_EPSILON); ++ e_diff = 10.0 * LC3_LOGTEN(d2[i - dist + 1] + FLT_EPSILON) - 10.0 * LC3_LOGTEN(d2[i + 1] + FLT_EPSILON); + + if (e_diff > thr) { + brickwall = 1; +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/enc_entropy.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/enc_entropy.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/enc_entropy.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/enc_entropy.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + void processEncoderEntropy_fl(LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT numbytes, LC3_INT bw_cutoff_bits, +@@ -33,11 +34,11 @@ + + /* Last non zero touple */ + if (bfi_ext == 1) { +- write_uint_backward_fl(ptr, bp_side, mask_side, lastnzTrigger[fs_idx], ceil(LC3_LOG2(N >> 1))); ++ write_uint_backward_fl(ptr, bp_side, mask_side, lastnzTrigger[fs_idx], ceil(LC3_LOGTWO(N >> 1))); + } + else + { +- write_uint_backward_fl(ptr, bp_side, mask_side, lastnz / 2 - 1, ceil(LC3_LOG2(N / 2))); ++ write_uint_backward_fl(ptr, bp_side, mask_side, lastnz / 2 - 1, ceil(LC3_LOGTWO(N / 2))); + } + + /* LSB mode bit */ +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/enc_lc3_fl.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/enc_lc3_fl.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/enc_lc3_fl.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/enc_lc3_fl.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s_in, uint8_t* bytes, int bps +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/estimate_global_gain.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/estimate_global_gain.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/estimate_global_gain.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/estimate_global_gain.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + +@@ -60,8 +61,8 @@ + } else { + g_min = x_max / (32767 - 0.375); + } +- /* Prevent positive rounding errors from LC3_LOG10 function */ +- ind_min = 28.0 * LC3_LOG10(g_min); ++ /* Prevent positive rounding errors from LC3_LOGTEN function */ ++ ind_min = 28.0 * LC3_LOGTEN(g_min); + + ind_min = ceil(ind_min + LC3_FABS(ind_min) * LC3_EPS); + +@@ -76,7 +77,7 @@ + tmp += x[i + 1] * x[i + 1]; + tmp += x[i + 2] * x[i + 2]; + tmp += x[i + 3] * x[i + 3]; +- en[j] = (28.0 / 20.0) * (7 + 10.0 * LC3_LOG10(tmp + reg_val)); ++ en[j] = (28.0 / 20.0) * (7 + 10.0 * LC3_LOGTEN(tmp + reg_val)); + j++; + } + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/cfft.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/cfft.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/cfft.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/cfft.c 2023-06-29 12:58:27 +@@ -8,7 +8,7 @@ + ******************************************************************************/ + + +- ++#include "options.h" + #include "cfft.h" + #include "iisfft.h" /* for M_PIl */ + #include /* for abs() */ +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iis_fft.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iis_fft.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iis_fft.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iis_fft.c 2023-06-29 12:58:27 +@@ -8,14 +8,15 @@ + ******************************************************************************/ + + ++#include "options.h" + #include + #include +-#include "iis_fft.h" + #include + #include + #include +-#include "../structs.h" ++#include + ++#include "iis_fft.h" + /**************************************************************************************************/ + + /* AFFT uses two fft implementations +@@ -24,9 +25,6 @@ + fast lengths, check the fft_n function. + */ + +-#include +-#include "cfft.h" +-#include "iisfft.h" + + #define FFT_COMPLEX 1 + #define FFT_REAL 2 +@@ -122,12 +120,13 @@ + + IIS_FFT_ERROR LC3_IIS_FFT_Apply_CFFT(HANDLE_IIS_FFT handle, const Complex* input, Complex* output) + { ++ LC3_FLOAT* dummy; + if (!handle) + return IIS_FFT_INTERNAL_ERROR; + + /* check for inplace operation */ + memmove(output, input, sizeof(*input) * handle->len); +- LC3_FLOAT* dummy = (LC3_FLOAT*)output; ++ dummy = (LC3_FLOAT*)output; + if (handle->cfft.len > 0) { + LC3_cfft_apply(&handle->cfft, dummy, dummy + 1, 2); + } else { +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iis_fft.h mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iis_fft.h +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iis_fft.h 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iis_fft.h 2023-06-29 12:58:27 +@@ -12,6 +12,7 @@ + #define IIS_FFT_H + + #include "../structs.h" ++#include "../defines.h" + #include "cfft.h" + + #ifdef __cplusplus +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iisfft.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iisfft.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iisfft.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iisfft.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + + #include + #include /* for mmove */ +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iisfft.h mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iisfft.h +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iisfft.h 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/fft/iisfft.h 2023-06-29 12:58:27 +@@ -11,6 +11,7 @@ + #ifndef IISFFT_H + #define IISFFT_H + ++#include "../defines.h" + + #ifndef M_PIl + #define M_PIl 3.1415926535897932384626433832795029L /* pi */ +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/imdct.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/imdct.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/imdct.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/imdct.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + /* Function expects already flipped window */ +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/lc3.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/lc3.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/lc3.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/lc3.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "lc3.h" + #include "defines.h" + #include "functions.h" +@@ -48,8 +49,9 @@ + case 44100: return 1; + case 48000: return 1; + case 96000: return 1; +- default: return 0; ++ default: break; + } ++ return 0; + } + + static int lc3plus_plc_mode_supported(LC3PLUS_PlcMode plc_mode) +@@ -58,8 +60,9 @@ + { + case LC3PLUS_PLC_ADVANCED: /* fallthru */ + return 1; +- default: return 0; ++ default: break; + } ++ return 0; + } + + static int lc3plus_frame_size_supported(float frame_ms) +@@ -69,8 +72,9 @@ + case 25: /* fallthru */ + case 50: /* fallthru */ + case 100: return 1; +- default: return 0; ++ default: break; + } ++ return 0; + } + + static int null_in_list(void **list, int n) +@@ -97,13 +101,14 @@ + /* encoder functions *********************************************************/ + LC3PLUS_Error lc3plus_enc_init(LC3PLUS_Enc *encoder, int samplerate, int channels, int hrmode, int32_t lfe_channel_array[]) + { ++ int ch = 0; ++ + RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); + RETURN_IF((uintptr_t)encoder % 4 != 0, LC3PLUS_ALIGN_ERROR); + RETURN_IF(!lc3plus_samplerate_supported(samplerate), LC3PLUS_SAMPLERATE_ERROR); + RETURN_IF(!lc3plus_channels_supported(channels), LC3PLUS_CHANNELS_ERROR); + RETURN_IF(samplerate==96000 && hrmode == 0, LC3PLUS_HRMODE_ERROR); + +- int ch = 0; + for (ch = 0; ch < channels; ch++) + { + RETURN_IF(!lc3_enc_supported_lfe() && lfe_channel_array[ch], LC3PLUS_LFE_MODE_NOT_SUPPORTED); +@@ -142,6 +147,7 @@ + int lc3plus_enc_get_real_bitrate(const LC3PLUS_Enc *encoder) + { + int ch = 0, totalBytes = 0; ++ int bitrate; + RETURN_IF(encoder == NULL, 0); + RETURN_IF(!encoder->lc3_br_set, LC3PLUS_BITRATE_UNSET_ERROR); + +@@ -150,7 +156,7 @@ + totalBytes += encoder->channel_setup[ch]->targetBytes; + } + +- int bitrate = (totalBytes * 80000.0 + encoder->frame_dms - 1) / encoder->frame_dms; ++ bitrate = (totalBytes * 80000.0 + encoder->frame_dms - 1) / encoder->frame_dms; + + if (encoder->fs_in == 44100) + { +@@ -191,11 +197,13 @@ + + LC3PLUS_Error lc3plus_enc_set_bandwidth(LC3PLUS_Enc *encoder, int bandwidth) + { ++ LC3_INT effective_fs; ++ + RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); + #ifdef ENABLE_HR_MODE_FL_FLAG + RETURN_IF(encoder->hrmode == 1, LC3PLUS_HRMODE_BW_ERROR); + #endif +- LC3_INT effective_fs = encoder->fs_in; ++ effective_fs = encoder->fs_in; + if (encoder->bandwidth != bandwidth) { + if (encoder->fs_in > 40000) { + effective_fs = 40000; +@@ -338,9 +346,9 @@ + + LC3PLUS_Error lc3plus_free_encoder_structs(LC3PLUS_Enc* encoder) + { ++ int ch = 0; + RETURN_IF(!encoder, LC3PLUS_NULL_ERROR); + +- int ch = 0; + for (ch = 0; ch < encoder->channels; ch++) { + mdct_free(&encoder->channel_setup[ch]->mdctStruct); + dct2_free(&encoder->channel_setup[ch]->dct2StructSNS); +@@ -351,9 +359,9 @@ + + LC3PLUS_Error lc3plus_free_decoder_structs(LC3PLUS_Dec* decoder) + { ++ int ch = 0; + RETURN_IF(!decoder, LC3PLUS_NULL_ERROR); + +- int ch = 0; + for (ch = 0; ch < decoder->channels; ch++) { + dct4_free(&decoder->channel_setup[ch]->dct4structImdct); + real_fft_free(&decoder->channel_setup[ch]->PlcAdvSetup->PlcPhEcuSetup.PhEcu_Fft); +@@ -378,11 +386,14 @@ + + LC3PLUS_Error lc3plus_enc_set_ep_mode(LC3PLUS_Enc *encoder, LC3PLUS_EpMode epmode) + { ++ LC3PLUS_EpMode oldEpmode; ++ LC3PLUS_Error error; ++ + RETURN_IF(encoder == NULL, LC3PLUS_NULL_ERROR); + RETURN_IF((unsigned)epmode > LC3PLUS_EP_HIGH, LC3PLUS_EPMODE_ERROR); +- LC3PLUS_EpMode oldEpmode = encoder->epmode; ++ oldEpmode = encoder->epmode; + encoder->epmode = epmode; +- LC3PLUS_Error error = encoder->lc3_br_set ? update_enc_bitrate(encoder, encoder->bitrate) : LC3PLUS_OK; ++ error = encoder->lc3_br_set ? update_enc_bitrate(encoder, encoder->bitrate) : LC3PLUS_OK; + if (error != LC3PLUS_OK) + { + encoder->epmode = oldEpmode; // preserve old epmode in case of failure +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/lc3plus_fft.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/lc3plus_fft.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/lc3plus_fft.c 1970-01-01 01:00:00 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/lc3plus_fft.c 2023-06-29 12:58:27 +@@ -0,0 +1,99 @@ ++/****************************************************************************** ++* ETSI TS 103 634 V1.4.1 * ++* Low Complexity Communication Codec Plus (LC3plus) * ++* * ++* Copyright licence is solely granted through ETSI Intellectual Property * ++* Rights Policy, 3rd April 2019. No patent licence is granted by implication, * ++* estoppel or otherwise. * ++******************************************************************************/ ++ ++ ++#include "options.h" ++#include "functions.h" ++#include "fft/iis_fft.c" ++#include "fft/iisfft.c" ++#include "fft/cfft.c" ++ ++void fft_init(Fft* fft, int length) ++{ ++ HANDLE_IIS_FFT handle = NULL; ++ IIS_FFT_ERROR error = 0; ++ assert(length % 2 == 0); ++ ++ fft->length = length; ++ ++ error = LC3_IIS_CFFT_Create(&handle, length, IIS_FFT_FWD); ++ ++ assert(error == IIS_FFT_NO_ERROR); ++ fft->handle = handle; ++} ++ ++void fft_free(Fft* fft) ++{ ++ IIS_FFT_ERROR error = 0; ++ ++ if (fft) { ++ error = LC3_IIS_CFFT_Destroy((HANDLE_IIS_FFT *) &fft->handle); ++ ++ assert(error == IIS_FFT_NO_ERROR); ++ memset(fft, 0, sizeof(*fft)); ++ } ++} ++ ++void real_fft_free(Fft* fft) ++{ ++ IIS_FFT_ERROR error = 0; ++ ++ if (fft) { ++ error = LC3_IIS_RFFT_Destroy((HANDLE_IIS_FFT *) &fft->handle); ++ ++ assert(error == IIS_FFT_NO_ERROR); ++ memset(fft, 0, sizeof(*fft)); ++ } ++} ++ ++void real_fft_init(Fft* fft, LC3_INT32 length, HANDLE_IIS_FFT *handle) ++{ ++ IIS_FFT_ERROR error = IIS_FFT_NO_ERROR; ++ assert(length % 4 == 0); /* due to current limitation of core complex FFTs*/ ++ ++ fft->length = length; ++ ++ error = LC3_IIS_RFFT_Create(handle, length, IIS_FFT_FWD); ++ assert(error == IIS_FFT_NO_ERROR); ++ fft->handle = *handle; ++} ++ ++ ++void real_ifft_init(Fft* fft, LC3_INT32 length, HANDLE_IIS_FFT *handle) ++{ ++ IIS_FFT_ERROR error = IIS_FFT_NO_ERROR; ++ assert(length % 4 == 0); /* due to current limitation of core complex FFTs*/ ++ ++ fft->length = length; ++ ++ error = LC3_IIS_RFFT_Create(handle, length, IIS_FFT_BWD); ++ ++ assert(error == IIS_FFT_NO_ERROR); ++ fft->handle = *handle; ++} ++ ++void fft_apply(Fft* fft, const Complex* input, Complex* output) ++{ ++ IIS_FFT_ERROR error = 0; ++ error = LC3_IIS_FFT_Apply_CFFT(fft->handle, input, output); ++ ++ assert(error == IIS_FFT_NO_ERROR); ++} ++ ++ ++void real_fft_apply(Fft* fft, const LC3_FLOAT* input, LC3_FLOAT* output) ++{ ++ IIS_FFT_ERROR error = IIS_FFT_NO_ERROR; ++ ++ UNUSED(error); ++ ++ error = LC3_IIS_FFT_Apply_RFFT(fft->handle, input, output); ++ ++ assert(error == IIS_FFT_NO_ERROR); ++} +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ltpf_coder.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ltpf_coder.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ltpf_coder.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ltpf_coder.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + static LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len); +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ltpf_decoder.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ltpf_decoder.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ltpf_decoder.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/ltpf_decoder.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT fs, LC3_FLOAT* mem_old_x, LC3_FLOAT* mem_old_y, +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/mdct.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/mdct.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/mdct.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/mdct.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + static const LC3_FLOAT* mdct_window(LC3_INT length, LC3_INT frame_dms, LC3_INT hrmode) +@@ -104,6 +105,7 @@ + { + LC3_FLOAT tmp[MAX_LEN * 2] = {0}; + LC3_INT i = 0; ++ LC3_INT hlen; + + move_float(tmp, mdct->mem, mdct->mem_length); + move_float(tmp + mdct->mem_length, input, mdct->length); +@@ -112,7 +114,7 @@ + + mult_vec(tmp, mdct->window, mdct->length * 2); + +- LC3_INT hlen = mdct->length / 2; ++ hlen = mdct->length / 2; + for (i = 0; i < hlen; i++) { + output[i] = -tmp[hlen * 3 - i - 1] - tmp[hlen * 3 + i]; + output[hlen + i] = tmp[i] - tmp[hlen * 2 - i - 1]; +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/mdct_shaping.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/mdct_shaping.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/mdct_shaping.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/mdct_shaping.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + void processMdctShaping_fl(LC3_FLOAT x[], LC3_FLOAT scf[], const LC3_INT bands_offset[], LC3_INT fdns_npts) +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/msvc/.gitignore mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/msvc/.gitignore +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/msvc/.gitignore 1970-01-01 01:00:00 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/msvc/.gitignore 2023-06-29 12:58:27 +@@ -0,0 +1 @@ ++Win32/ +\ No newline at end of file +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/near_nyquist_detector.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/near_nyquist_detector.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/near_nyquist_detector.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/near_nyquist_detector.c 2023-06-29 12:58:35 +@@ -8,15 +8,16 @@ + ******************************************************************************/ + + #include "functions.h" ++#include "options.h" + + + void processNearNyquistdetector_fl(LC3_INT16* near_nyquist_flag, const LC3_INT fs_idx, const LC3_INT near_nyquist_index, + const LC3_INT bands_number, const LC3_FLOAT* ener) + { + *near_nyquist_flag = 0; +- ++ + if (fs_idx < 4) +- { ++ { + LC3_INT i = 0; + LC3_FLOAT ener_low = FLT_EPSILON, ener_high = 0; + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/noise_factor.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/noise_factor.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/noise_factor.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/noise_factor.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + void processNoiseFactor_fl(LC3_INT* fac_ns_idx, LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gg, LC3_INT BW_cutoff_idx, LC3_INT frame_dms, +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/noise_filling.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/noise_filling.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/noise_filling.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/noise_filling.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, LC3_INT bw_stopband, LC3_INT frame_dms, LC3_FLOAT fac_ns_pc, LC3_INT spec_inv_idx) +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/olpa.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/olpa.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/olpa.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/olpa.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + static void filter_olpa(LC3_FLOAT* in, LC3_FLOAT* out, const LC3_FLOAT* buf, LC3_FLOAT len_buf, LC3_INT len_input); +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_apply.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_apply.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_apply.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_apply.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_classify.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_classify.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_classify.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_classify.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_main.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_main.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_main.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_main.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_update.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_update.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_update.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/pc_update.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/per_band_energy.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/per_band_energy.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/per_band_energy.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/per_band_energy.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + void processPerBandEnergy_fl(LC3_INT bands_number, const LC3_INT* acc_coeff_per_band, LC3_INT16 hrmode, LC3_INT16 frame_dms, LC3_FLOAT* d2, LC3_FLOAT* d) +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_classify.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_classify.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_classify.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_classify.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_compute_stab_fac.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_compute_stab_fac.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_compute_stab_fac.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_compute_stab_fac.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_damping_scrambling.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_damping_scrambling.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_damping_scrambling.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_damping_scrambling.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_main.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_main.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_main.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_main.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* decoder, DecSetup* h_DecSetup, LC3_INT bfi, +@@ -56,6 +57,8 @@ + { + case 2: + { ++ LC3_FLOAT pitch_fl_c; ++ + assert(decoder->fs_idx == floor(decoder->fs / 10000)); + // phaseECU supports only 10ms framing + assert(PlcSetup->nbLostCmpt != 0 || decoder->frame_dms == 100); +@@ -69,7 +72,7 @@ + } + + /* call phaseEcu */ +- LC3_FLOAT pitch_fl_c = (LC3_FLOAT)ltpf_pitch_int + (LC3_FLOAT)ltpf_pitch_fr / 4.0; /* use non-rounded pitch indeces */ ++ pitch_fl_c = (LC3_FLOAT)ltpf_pitch_int + (LC3_FLOAT)ltpf_pitch_fr / 4.0; /* use non-rounded pitch indeces */ + + + if (prev_bfi_plc2 == 0) +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_noise_substitution.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_noise_substitution.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_noise_substitution.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_noise_substitution.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_noise_substitution0.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_noise_substitution0.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_noise_substitution0.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_noise_substitution0.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_f0_refine_first.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_f0_refine_first.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_f0_refine_first.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_f0_refine_first.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "defines.h" + #include "functions.h" + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_fec_hq.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_fec_hq.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_fec_hq.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_fec_hq.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "defines.h" + #include "functions.h" + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_hq_ecu.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_hq_ecu.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_hq_ecu.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_hq_ecu.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "defines.h" + #include "functions.h" + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_lf_peak_analysis.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_lf_peak_analysis.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_lf_peak_analysis.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_lf_peak_analysis.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "defines.h" + #include "functions.h" + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_rec_frame.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_rec_frame.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_rec_frame.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_rec_frame.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "defines.h" + #include "functions.h" + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_setf0hz.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_setf0hz.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_setf0hz.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_setf0hz.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "defines.h" + #include "functions.h" + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_spec_ana.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_spec_ana.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_spec_ana.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_spec_ana.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "defines.h" + #include "functions.h" + +@@ -135,13 +136,13 @@ + + if (max_xfp_abs >= 0.5) + { +- PLC2_Q_flt = (LC3_FLOAT)LC3_FLOOR(LC3_LOG2(32768 / 2 / 2 / max_xfp_abs)); ++ PLC2_Q_flt = (LC3_FLOAT)LC3_FLOOR(LC3_LOGTWO(32768 / 2 / 2 / max_xfp_abs)); + Q_scale_flt = LC3_POW(2.0, PLC2_Q_flt) / fx_fft_scale / fft_fs_scale; /* basop way using xfp scale */ + + /* C-Float additional safety limit/verification of the integer xfp based scaling using the available C-float Xabs max value inp_high as well */ + { + LC3_FLOAT tmp_scale; +- tmp_scale = LC3_POW(2.0, LC3_FLOOR(LC3_LOG2(32768 / 2 / 2 / inp_high))); ++ tmp_scale = LC3_POW(2.0, LC3_FLOOR(LC3_LOGTWO(32768 / 2 / 2 / inp_high))); + if (Q_scale_flt > tmp_scale) { + Q_scale_flt = tmp_scale; + } +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_subst_spec.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_subst_spec.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_subst_spec.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_subst_spec.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "defines.h" + #include "functions.h" + #include "constants.h" +@@ -30,6 +31,7 @@ + LC3_INT32 segmentLen, e; + LC3_FLOAT Xph; + LC3_FLOAT seed_local; ++ LC3_INT32 binCounter, subInd; + + UNUSED(corr_phase_dbg); + UNUSED(X_i_new_re_dbg); +@@ -49,8 +51,8 @@ + + + // EVOLVE PHASE ----------------- +- LC3_INT32 binCounter = 1; +- LC3_INT32 subInd = 0; ++ binCounter = 1; ++ subInd = 0; + + one_peak_flag_mask = -1; + if (n_plocs < 3 && n_plocs > 0) { +@@ -219,9 +221,10 @@ + } + + static LC3_INT32 own_rand(LC3_INT32 seed) { +- assert(seed <= 32767 && seed >= -32768); +- LC3_INT32 retSeed = (13849 + (seed + 32768) * 31821) & 65535; +- retSeed -= 32768; ++ LC3_INT32 retSeed; ++ assert(seed <= 32767 && seed >= -32768); ++ retSeed = (13849 + (seed + 32768) * 31821) & 65535; ++ retSeed -= 32768; + assert(retSeed <= 32767 && retSeed >= -32768); + return retSeed; + } +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_per_band_gain.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_per_band_gain.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_per_band_gain.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_per_band_gain.c 2023-06-29 12:58:35 +@@ -6,13 +6,14 @@ + * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * + * estoppel or otherwise. * + ******************************************************************************/ +- + ++ ++#include "options.h" + #include "defines.h" + #include "functions.h" + + +-void plc_phEcu_tba_per_band_gain(LC3_INT32 n_grp, LC3_FLOAT *gr_pow_left, LC3_FLOAT *gr_pow_right, LC3_FLOAT *trans, LC3_FLOAT *grp_pow_change) ++void plc_phEcu_tba_per_band_gain(LC3_INT32 n_grp, LC3_FLOAT *gr_pow_left, LC3_FLOAT *gr_pow_right, LC3_FLOAT *trans, LC3_FLOAT *grp_pow_change) + { + LC3_INT32 i; + +@@ -34,10 +35,10 @@ + trans[i] = 1.0; /* 0/0 no transient , no power change */ + } + } +- grp_pow_change[i] = (LC3_FLOAT) 10.0 * LC3_LOG10(trans[i]); ++ grp_pow_change[i] = (LC3_FLOAT) 10.0 * LC3_LOGTEN(trans[i]); + + } + +- return; ++ return; + } + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_spect_Xavg.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_spect_Xavg.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_spect_Xavg.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_spect_Xavg.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "defines.h" + #include "functions.h" + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_trans_dect_gains.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_trans_dect_gains.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_trans_dect_gains.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_tba_trans_dect_gains.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "defines.h" + #include "functions.h" + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_trans_burst_ana_sub.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_trans_burst_ana_sub.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_trans_burst_ana_sub.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_phecu_trans_burst_ana_sub.c 2023-06-29 12:58:35 +@@ -6,16 +6,17 @@ + * Rights Policy, 3rd April 2019. No patent licence is granted by implication, * + * estoppel or otherwise. * + ******************************************************************************/ +- + ++ ++#include "options.h" + #include "defines.h" + #include "functions.h" + + +-void plc_phEcu_trans_burst_ana_sub(LC3_INT32 fs_idx, LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *oold_spect_shape, +- LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_spect_shape, ++void plc_phEcu_trans_burst_ana_sub(LC3_INT32 fs_idx, LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FLOAT *oold_spect_shape, ++ LC3_FLOAT *oold_EwPtr, LC3_FLOAT *old_spect_shape, + LC3_FLOAT *old_EwPtr, LC3_FLOAT *stPhECU_beta_mute, +- LC3_FLOAT *stPhECU_mag_chg_1st, LC3_FLOAT *stPhECU_Xavg, LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg) ++ LC3_FLOAT *stPhECU_mag_chg_1st, LC3_FLOAT *stPhECU_Xavg, LC3_FLOAT *alpha, LC3_FLOAT *beta, LC3_FLOAT *mag_chg, LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg) + { + LC3_FLOAT gr_pow_left[MAX_LGW]; + LC3_FLOAT gr_pow_right[MAX_LGW]; +@@ -27,7 +28,7 @@ + + LC3_INT32 attDegreeFrames; + LC3_FLOAT thresh_dbg; +- ++ + UNUSED(tr_dec_dbg); + UNUSED(gpc_dbg); + +@@ -39,7 +40,7 @@ + + } + +- ++ + plc_phEcu_tba_trans_dect_gains(burst_len, n_grp, grp_pow_change, stPhECU_beta_mute, stPhECU_mag_chg_1st, alpha, beta, mag_chg, ph_dith, tr_dec, att_val, &attDegreeFrames, &thresh_dbg); + + return; +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_tdc.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_tdc.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_tdc.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_tdc.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + /***************************************************************************\ + * contents/description: Main function for Time domain concealment + \***************************************************************************/ +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_tdc_tdac.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_tdc_tdac.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_tdc_tdac.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_tdc_tdac.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_update.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_update.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_update.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/plc_update.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + #include "functions.h" ++#include "options.h" + + + void processPlcUpdate_fl(PlcAdvSetup *PlcAdvSetup, LC3_INT32 frame_length, LC3_FLOAT *syntM, LC3_FLOAT *scf_q, +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/quantize_spec.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/quantize_spec.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/quantize_spec.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/quantize_spec.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + static LC3_INT sign(LC3_FLOAT x); +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/reorder_bitstream.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/reorder_bitstream.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/reorder_bitstream.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/reorder_bitstream.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/resamp12k8.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/resamp12k8.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/resamp12k8.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/resamp12k8.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3_INT mem_in_len, LC3_FLOAT mem_50[], LC3_FLOAT mem_out[], +@@ -17,6 +18,8 @@ + + LC3_INT len_12k8 = 0, N12k8 = 0, i = 0, k = 0; + LC3_FLOAT mac = 0, buf_out[120 + MAX_LEN] = {0}, bufdown[128] = {0}, buf[120 + MAX_LEN] = {0}; ++ LC3_INT32 index_int, index_frac, resamp_upfac, resamp_delay, resamp_off_int, resamp_off_frac; ++ LC3_FLOAT u_11, u_21, u_1, u_2; + + const LC3_FLOAT *filter; + const LC3_FLOAT *filt_input, *filt_coeff; +@@ -49,12 +52,12 @@ + + /* Upsampling & Low-pass Filtering & Downsampling */ + +- LC3_INT32 index_int = 1; +- LC3_INT32 index_frac = 0; +- LC3_INT32 resamp_upfac = resamp_params[fs_idx][0]; +- LC3_INT32 resamp_delay = resamp_params[fs_idx][1]; +- LC3_INT32 resamp_off_int = resamp_params[fs_idx][2]; +- LC3_INT32 resamp_off_frac = resamp_params[fs_idx][3]; ++ index_int = 1; ++ index_frac = 0; ++ resamp_upfac = resamp_params[fs_idx][0]; ++ resamp_delay = resamp_params[fs_idx][1]; ++ resamp_off_int = resamp_params[fs_idx][2]; ++ resamp_off_frac = resamp_params[fs_idx][3]; + + k = 0; + for (i = 0; i < N12k8; i++) { +@@ -78,9 +81,8 @@ + + + /* 50Hz High-Pass */ +- LC3_FLOAT u_11 = mem_50[0]; +- LC3_FLOAT u_21 = mem_50[1]; +- LC3_FLOAT u_1, u_2; ++ u_11 = mem_50[0]; ++ u_21 = mem_50[1]; + + for (i = 0; i < len_12k8; i++) { + LC3_FLOAT y1 = (highpass50_filt_b[0] * bufdown[i] + u_11); +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/residual_coding.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/residual_coding.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/residual_coding.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/residual_coding.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + void processResidualCoding_fl(LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gain, LC3_INT L_spec, LC3_INT targetBits, LC3_INT nBits, uint8_t* resBits, LC3_INT* numResBits +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/residual_decoding.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/residual_decoding.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/residual_decoding.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/residual_decoding.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + void processResidualDecoding_fl(LC3_INT* bitsRead, LC3_FLOAT x[], LC3_INT L_spec, uint8_t prm[], LC3_INT resQBits +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_com_lc3.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_com_lc3.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_com_lc3.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_com_lc3.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + #include "functions.h" ++#include "options.h" + + LC3_FLOAT array_max_abs(LC3_FLOAT *in, LC3_INT32 len) + { +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_dec_lc3.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_dec_lc3.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_dec_lc3.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_dec_lc3.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "setup_dec_lc3.h" + #include "functions.h" + #include +@@ -32,6 +33,7 @@ + LC3_FLOAT *sine_table1_phecu, *sine_table2_phecu; + HANDLE_IIS_FFT handle_fft_phaseecu; + HANDLE_IIS_FFT handle_ifft_phaseecu; ++ LC3_FLOAT *q_old_res; + + for (ch = 0; ch < channels; ch++) { + DecSetup* setup = balloc(decoder, &size, sizeof(DecSetup)); +@@ -56,7 +58,7 @@ + sine_table1_phecu = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((CODEC_FS(samplerate) * 16) / 1000) / 2 + 1)); + sine_table2_phecu = balloc(decoder, &size, sizeof(LC3_FLOAT) * (((CODEC_FS(samplerate) * 16) / 1000) / 2 + 1)); + +- LC3_FLOAT *q_old_res = balloc(decoder, &size, sizeof(LC3_FLOAT) * frame_len); ++ q_old_res = balloc(decoder, &size, sizeof(LC3_FLOAT) * frame_len); + + if (decoder) { + decoder->channel_setup[ch] = setup; +@@ -346,6 +348,7 @@ + LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes) + { + int totalBits = 0, bitsTmp = 0, channel_bytes = 0, maxBytes = 0, minBytes = 0; ++ DecSetup* setup; + + if (decoder->hrmode) + { +@@ -375,7 +378,7 @@ + + channel_bytes = nBytes; + +- DecSetup* setup = decoder->channel_setup[ch]; ++ setup = decoder->channel_setup[ch]; + + if (channel_bytes < minBytes || channel_bytes > maxBytes) + { +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_enc_lc3.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_enc_lc3.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_enc_lc3.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/setup_enc_lc3.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "setup_enc_lc3.h" + #include "functions.h" + #include +@@ -33,6 +34,7 @@ + , int32_t lfe_channel_array[] + ) + { ++ int ch = 0; + memset(encoder, 0, lc3plus_enc_get_size(samplerate, channels)); + alloc_encoder(encoder, channels); + +@@ -56,7 +58,6 @@ + encoder->r12k8_mem_in_len = 2 * 8 * encoder->fs / 12800; + encoder->r12k8_mem_out_len = 24; + +- int ch = 0; + for (ch = 0; ch < encoder->channels; ch++) + { + encoder->channel_setup[ch]->lfe = lfe_channel_array[ch] != 0; +@@ -220,6 +221,7 @@ + + if (encoder->hrmode) + { ++#ifdef ENABLE_HR_MODE_FL + switch (encoder->frame_dms) + { + case 25: +@@ -243,6 +245,7 @@ + default: + return LC3PLUS_HRMODE_ERROR; + } ++#endif + } + else + { +@@ -368,7 +371,7 @@ + setup->total_bits = setup->targetBytes << 3; + setup->targetBitsInit = setup->total_bits - encoder->envelope_bits - encoder->global_gain_bits - + encoder->noise_fac_bits - encoder->BW_cutoff_bits - +- ceil(LC3_LOG2(encoder->frame_length / 2)) - 2 - 1; ++ ceil(LC3_LOGTWO(encoder->frame_length / 2)) - 2 - 1; + + if (setup->total_bits > 1280) { + setup->targetBitsInit = setup->targetBitsInit - 1; +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_compute_scf.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_compute_scf.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_compute_scf.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_compute_scf.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor) +@@ -109,7 +110,7 @@ + + /* Log-domain */ + for (i = 0; i < 64; i++) { +- xl[i] = LC3_LOG2(x[i]) / 2.0; ++ xl[i] = LC3_LOGTWO(x[i]) / 2.0; + } + + /* Downsampling */ +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_interpolate_scf.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_interpolate_scf.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_interpolate_scf.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_interpolate_scf.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + void processSnsInterpolateScf_fl(LC3_FLOAT* gains, LC3_INT encoder_side, LC3_INT bands_number, LC3_FLOAT* gains_int) +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_quantize_scf.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_quantize_scf.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_quantize_scf.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/sns_quantize_scf.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + static void pvq_dec(LC3_INT k, LC3_INT m, LC3_INT LS_ind, LC3_INT MPVQ_ind, LC3_INT* pulses); +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tinywavein_c.h mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tinywavein_c.h +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tinywavein_c.h 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tinywavein_c.h 2023-06-29 12:58:27 +@@ -17,6 +17,7 @@ + #include + #include + ++ + #if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) || defined(__arm__) || \ + defined(__aarch64__) + #define __TWI_LE /* _T_iny _W_ave _I_n _L_ittle _E_ndian */ +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tns_coder.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tns_coder.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tns_coder.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tns_coder.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + static void xcorr(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT lag, LC3_INT inLen); +diff -Naur ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tns_decoder.c mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tns_decoder.c +--- ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tns_decoder.c 2023-02-28 20:25:37 ++++ mod/ETSI_Release/LC3plus_ETSI_src_va15eb59632b_20230228/src/floating_point/tns_decoder.c 2023-06-29 12:58:27 +@@ -8,6 +8,7 @@ + ******************************************************************************/ + + ++#include "options.h" + #include "functions.h" + + void processTnsDecoder_fl(LC3_FLOAT* x, LC3_INT* rc_idx, LC3_INT* order, LC3_INT numfilters, LC3_INT bw_fcbin, LC3_INT N, LC3_INT fs) diff --git a/scripts/prepare_instrumentation.sh b/scripts/prepare_instrumentation.sh index 70d69874968d26e078a7ce5b65b1e2c5ec5b5bee..01dffb2978832afea0680606de7ae5a2dda41de6 100755 --- a/scripts/prepare_instrumentation.sh +++ b/scripts/prepare_instrumentation.sh @@ -63,8 +63,10 @@ mkdir $targetdir # copy files from source-dir cp -R ../lib_* $targetdir +cp -R ../lc3plus $targetdir cp -R ../apps $targetdir cp -R ../Makefile $targetdir +cp -R ../CMakeLists.txt $targetdir cp -R ../Workspace_msvc $targetdir # back up #ifdef-list @@ -104,7 +106,7 @@ find $targetdir -name "*.[ch]" -exec sed -i.bak -e "s/\(0x[0-9a-fA-F]*\)UL/\(\(u # run wmc_tool "tools/$system/wmc_tool" -m "$targetdir/apps/encoder.c" "$targetdir/lib_enc/*.c" "$targetdir/lib_com/*.c" >> /dev/null "tools/$system/wmc_tool" -m "$targetdir/apps/decoder.c" "$targetdir/lib_dec/*.c" >> /dev/null -"tools/$system/wmc_tool" -m "$targetdir/apps/renderer.c" "$targetdir/lib_rend/*.c" >> /dev/null +"tools/$system/wmc_tool" -m "$targetdir/apps/renderer.c" "$targetdir/lib_rend/*.c" "$targetdir/lc3plus/*.c" "$targetdir/lc3plus/fft/*.c" >> /dev/null # automatically enable #define WMOPS in options.h sed -i.bak -e "s/\/\*[[:space:]]*\(#define[[:space:]]*WMOPS\)[[:space:]]*\*\//\1/g" $targetdir/lib_com/options.h diff --git a/scripts/split_rendering/lc3plus/.gitignore b/scripts/split_rendering/lc3plus/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..9cd2def1f8d1ce4f0300a90324e6479906a6f5cb --- /dev/null +++ b/scripts/split_rendering/lc3plus/.gitignore @@ -0,0 +1 @@ +ivas_lc3plus_unit_test \ No newline at end of file diff --git a/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c b/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c new file mode 100644 index 0000000000000000000000000000000000000000..c27809c2e7c1912141ea4102096b34c699a94974 --- /dev/null +++ b/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c @@ -0,0 +1,632 @@ +/****************************************************************************************************** + +(C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +contributors to this repository. All Rights Reserved. + +This software is protected by copyright law and by international treaties. +The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, +Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +contributors to this repository retain full ownership rights in their respective contributions in +the software. This notice grants no license of any kind, including but not limited to patent +license, nor is any license granted by implication, estoppel or otherwise. + +Contributors are required to enter into the IVAS codec Public Collaboration agreement before making +contributions. + +This software is provided "AS IS", without any express or implied warranties. The software is in the +development stage. It is intended exclusively for experts who have experience with such software and +solely for the purpose of inspection. All implied warranties of non-infringement, merchantability +and fitness for a particular purpose are hereby disclaimed and excluded. + +Any dispute, controversy or claim arising under or in relation to providing this software shall be +submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in +accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and +the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include +#include "ivas_lc3plus_enc.h" +#include "ivas_lc3plus_common.h" +#include "ivas_lc3plus_dec.h" +#include "ivas_error_utils.h" + +#define MAX_SAMPLES_PER_CHANNEL 960 + +static int encodeAndDecodeOneStereoFrame( LC3PLUS_CONFIG config ) +{ + ivas_error err; + uint32_t bps = 128000; + int32_t encDelay = -1; + int32_t decDelay = -1; + + IVAS_LC3PLUS_ENC_HANDLE encHandle; + err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + err = IVAS_LC3PLUS_ENC_GetDelay( encHandle, &encDelay ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + if ( encDelay == -1 || encDelay == 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "encDelay is zero or uninitialized\n" ); + } + + /* encode one frame */ + int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.ivas_frame_duration_us ); + float *pcm_in[2]; + float pcm_in_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_in_ch1, 0, numSamplesPerChannels * sizeof( float ) ); + float pcm_in_ch2[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_in_ch2, 0, numSamplesPerChannels * sizeof( float ) ); + pcm_in[0] = pcm_in_ch1; + pcm_in[1] = pcm_in_ch2; + + int32_t bitstreamSizePerIvasFrame = 0; + err = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); + if ( IVAS_ERR_OK != err ) + return err; + + uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); + memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); + + err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out ); + if ( IVAS_ERR_OK != err ) + return err; + IVAS_LC3PLUS_ENC_Close( &encHandle ); + + /* decode one frame */ + IVAS_LC3PLUS_DEC_HANDLE decHandle; + err = IVAS_LC3PLUS_DEC_Open( config, +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + 1 /*caching enabled*/, +#endif + &decHandle ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + err = IVAS_LC3PLUS_DEC_GetDelay( decHandle, &decDelay ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + if ( decDelay == -1 || decDelay == 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "decDelay is zero or uninitialized\n" ); + } + + uint8_t *bitstream_in = bitstream_out; + + float *pcm_out[2]; + float pcm_out_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_out_ch1, 0, numSamplesPerChannels * sizeof( float ) ); + float pcm_out_ch2[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_out_ch2, 0, numSamplesPerChannels * sizeof( float ) ); + pcm_out[0] = pcm_out_ch1; + pcm_out[1] = pcm_out_ch2; + + err = IVAS_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + err = IVAS_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + IVAS_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); + + return 0; +} + + +static int openCloseEncoder( void ) +{ + ivas_error err; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + uint32_t bps = 128000; + + IVAS_LC3PLUS_ENC_HANDLE encHandle; + err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + IVAS_LC3PLUS_ENC_Close( &encHandle ); + return 0; +} + +static int tryOpenEncoderWithInvalidBitrate( void ) +{ + ivas_error err; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + /* lc3plus max bitrate is 320000 per channel */ + uint32_t invalid_high_bps = 700000; + uint32_t invalid_low_bps = 8; + + IVAS_LC3PLUS_ENC_HANDLE encHandle; + err = IVAS_LC3PLUS_ENC_Open( config, invalid_high_bps, &encHandle ); + /* setting an invalid bitrate should trigger an error - which is what we expect */ + if ( IVAS_ERR_LC3PLUS_INVALID_BITRATE != err ) + { + return 1; + } + err = IVAS_LC3PLUS_ENC_Open( config, invalid_low_bps, &encHandle ); + /* setting an invalid bitrate should trigger an error - which is what we expect */ + if ( IVAS_ERR_LC3PLUS_INVALID_BITRATE != err ) + { + return 1; + } + return 0; +} + +static int tryOpenEncoderWithInvalidFrameDuration( void ) +{ + ivas_error err; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + config.lc3plus_frame_duration_us = 1234; /*unsupported frame duration*/ + uint32_t bps = 320000; + + IVAS_LC3PLUS_ENC_HANDLE encHandle; + err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); + /* setting an invalid fame duration should trigger an error - which is what we expect */ + if ( IVAS_ERR_OK == err ) + { + return 1; + } + return 0; +} + +static int tryOpenEncoderWithInvalidSampleRate( void ) +{ + ivas_error err; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + config.samplerate = 1234; /*unsupported sample rate */ + uint32_t bps = 320000; + + IVAS_LC3PLUS_ENC_HANDLE encHandle; + err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); + /* setting an invalid sample rate should trigger an error - which is what we expect */ + if ( IVAS_ERR_OK == err ) + { + return 1; + } + return 0; +} + +static int tryCallEncoderApiWithInvalidParams( void ) +{ + IVAS_LC3PLUS_ENC_HANDLE invalidEncHandle = NULL; + int32_t *invalidBsSize = NULL; + int32_t bsSize; + int32_t *invalidDelayInSamples = NULL; + int32_t delayInSamples; + float **invalidPcm_in = NULL; + void *invalidBitstream_out = NULL; + + const int16_t numSamplesPerChannels = MAX_SAMPLES_PER_CHANNEL; + float *pcm_in[1]; + float pcm_in_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_in_ch1, 0, numSamplesPerChannels * sizeof( float ) ); + pcm_in[0] = pcm_in_ch1; + uint8_t bitstream_out[1200]; + + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_GetDelay( invalidEncHandle, invalidDelayInSamples ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_GetDelay( invalidEncHandle, &delayInSamples ) ) + { + return 1; + } + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( invalidEncHandle, invalidBsSize ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( invalidEncHandle, &bsSize ) ) + { + return 1; + } + IVAS_LC3PLUS_ENC_Close( &invalidEncHandle ); + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, invalidBitstream_out ) ) + { + return 1; + } + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, invalidBitstream_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, invalidPcm_in, bitstream_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_ENC_Encode( invalidEncHandle, pcm_in, bitstream_out ) ) + { + return 1; + } + return 0; +} + + +static int tryCallDecoderApiWithInvalidParams( void ) +{ + IVAS_LC3PLUS_DEC_HANDLE invalidDecHandle = NULL; + + int32_t *invalidDelayInSamples = NULL; + int32_t delayInSamples; + float **invalidPcm_out = NULL; + void *invalidBitstream_in = NULL; + int32_t invalidBitstream_in_size = 0; + int32_t bitstream_in_size = 100; + + const int16_t numSamplesPerChannels = MAX_SAMPLES_PER_CHANNEL; + float *pcm_out[1]; + float pcm_out_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_out_ch1, 0, numSamplesPerChannels * sizeof( float ) ); + pcm_out[0] = pcm_out_ch1; + uint8_t bitstream_in[1200]; + + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_GetDelay( invalidDecHandle, invalidDelayInSamples ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_GetDelay( invalidDecHandle, &delayInSamples ) ) + { + return 1; + } + IVAS_LC3PLUS_DEC_Close( &invalidDecHandle ); + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, invalidBitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, invalidBitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, bitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, invalidBitstream_in, bitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, invalidBitstream_in_size, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, invalidBitstream_in_size, pcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Decode( invalidDecHandle, bitstream_in, bitstream_in_size, pcm_out ) ) + { + return 1; + } + + if ( IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Conceal( invalidDecHandle, invalidPcm_out ) || IVAS_ERR_UNEXPECTED_NULL_POINTER != IVAS_LC3PLUS_DEC_Conceal( invalidDecHandle, pcm_out ) ) + { + return 1; + } + return 0; +} + +static int openCloseDecoderWithCaching( void ) +{ + ivas_error err; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + + IVAS_LC3PLUS_DEC_HANDLE decHandle; + err = IVAS_LC3PLUS_DEC_Open( config, +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + 1 /*caching enabled*/, +#endif + &decHandle ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + IVAS_LC3PLUS_DEC_Close( &decHandle ); + return 0; +} + +static int openCloseDecoderWithoutCaching( void ) +{ + ivas_error err; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + + IVAS_LC3PLUS_DEC_HANDLE decHandle; + err = IVAS_LC3PLUS_DEC_Open( config, +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + 1 /*caching enabled*/, +#endif + &decHandle ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + IVAS_LC3PLUS_DEC_Close( &decHandle ); + return 0; +} + + + + +static int tryOpenDecoderWithInvalidFrameDuration( void ) +{ + ivas_error err; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + config.lc3plus_frame_duration_us = 1234; /*unsupported frame duration*/ + + IVAS_LC3PLUS_DEC_HANDLE decHandle; + err = IVAS_LC3PLUS_DEC_Open( config, +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + 1 /*caching enabled*/, +#endif + &decHandle ); + /* setting an invalid fame duration should trigger an error - which is what we expect */ + if ( IVAS_ERR_OK == err ) + { + return 1; + } + return 0; +} + +static int tryOpenDecoderWithInvalidSampleRate( void ) +{ + ivas_error err; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + config.samplerate = 1234; /*unsupported sample rate*/ + + IVAS_LC3PLUS_DEC_HANDLE decHandle; + err = IVAS_LC3PLUS_DEC_Open( config, +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + 1 /*caching enabled*/, +#endif + &decHandle ); + /* setting an invalid sample rate should trigger an error - which is what we expect */ + if ( IVAS_ERR_OK == err ) + { + return 1; + } + return 0; +} + +static int encodeOneFrame( void ) +{ + ivas_error err; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + uint32_t bps = 128000; + + IVAS_LC3PLUS_ENC_HANDLE encHandle; + err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); + if ( IVAS_ERR_OK != err ) + return err; + + int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.ivas_frame_duration_us ); + + float *pcm[1]; + float pcm_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_ch1, 0, numSamplesPerChannels * sizeof( float ) ); + pcm[0] = pcm_ch1; + + int32_t bitstreamSizePerIvasFrame = 0; + err = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); + if ( IVAS_ERR_OK != err ) + return err; + uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); + memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); + + err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm, bitstream_out ); + if ( IVAS_ERR_OK != err ) + return err; + + IVAS_LC3PLUS_ENC_Close( &encHandle ); + free( bitstream_out ); + return 0; +} + + +static int encodeAndDecodeOneMonoFrame( void ) +{ + ivas_error err; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20000, .channels = 1, .samplerate = 48000 }; + uint32_t bps = 128000; + + IVAS_LC3PLUS_ENC_HANDLE encHandle; + err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* encode one frame */ + int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.ivas_frame_duration_us ); + float *pcm_in[1]; + float pcm_in_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_in_ch1, 0, numSamplesPerChannels * sizeof( float ) ); + pcm_in[0] = pcm_in_ch1; + + int32_t bitstreamSizePerIvasFrame = 0; + err = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); + if ( IVAS_ERR_OK != err ) + return err; + + uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); + memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); + + err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out ); + if ( IVAS_ERR_OK != err ) + return err; + IVAS_LC3PLUS_ENC_Close( &encHandle ); + + /* decode one frame */ + IVAS_LC3PLUS_DEC_HANDLE decHandle; + err = IVAS_LC3PLUS_DEC_Open( config, +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + 1 /*caching enabled*/, +#endif + &decHandle ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + uint8_t *bitstream_in = bitstream_out; + + float *pcm_out[1]; + float pcm_out_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_out_ch1, 0, numSamplesPerChannels * sizeof( float ) ); + pcm_out[0] = pcm_out_ch1; + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + err = IVAS_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + IVAS_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); + + return 0; +} + +static int encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_48kHz( void ) +{ + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000 }; + return encodeAndDecodeOneStereoFrame( config ); +} + +static int encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_32kHz( void ) +{ + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 32000 }; + return encodeAndDecodeOneStereoFrame( config ); +} + +static int encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_16kHz( void ) +{ + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 16000 }; + return encodeAndDecodeOneStereoFrame( config ); +} + +static int encodeAndDecodeOneStereoFrameIvas5msLc3plus5ms_48kHz( void ) +{ + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5 * 1000, .channels = 2, .samplerate = 48000 }; + return encodeAndDecodeOneStereoFrame( config ); +} + +static int encodeAndDecodeOneMonoFrameIvas20msLc3plus10ms_48kHz( void ) +{ + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 10 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 1, .samplerate = 48000 }; + return encodeAndDecodeOneStereoFrame( config ); +} + +static int encodeAndDecodeOneMonoFrameIvas5msLc3plus5ms_48kHz( void ) +{ + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 5 * 1000, .channels = 1, .samplerate = 48000 }; + return encodeAndDecodeOneStereoFrame( config ); +} + +static int encodeAndDecodeOneStereoFrameIvas20msLc3plus2_5ms_48kHz( void ) +{ + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 2.5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 2, .samplerate = 48000 }; + return encodeAndDecodeOneStereoFrame( config ); +} + +#include "ivas_lc3plus_unit_test_selective_decoding.c" + + +int main( + int argc, + char *argv[] ) +{ + int ret = 0; + ret = openCloseEncoder(); + if ( ret != 0 ) + return ret; + ret = tryOpenEncoderWithInvalidBitrate(); + if ( ret != 0 ) + return ret; + ret = tryOpenEncoderWithInvalidFrameDuration(); + if ( ret != 0 ) + return ret; + ret = tryOpenEncoderWithInvalidSampleRate(); + if ( ret != 0 ) + return ret; + ret = tryCallEncoderApiWithInvalidParams(); + if ( ret != 0 ) + return ret; + ret = openCloseDecoderWithCaching(); + if ( ret != 0 ) + return ret; + ret = openCloseDecoderWithoutCaching(); + if ( ret != 0 ) + return ret; + ret = tryOpenDecoderWithInvalidFrameDuration(); + if ( ret != 0 ) + return ret; + ret = tryOpenDecoderWithInvalidSampleRate(); + if ( ret != 0 ) + return ret; + ret = tryCallDecoderApiWithInvalidParams(); + if ( ret != 0 ) + return ret; + ret = encodeOneFrame(); + if ( ret != 0 ) + return ret; + ret = encodeAndDecodeOneMonoFrame(); + if ( ret != 0 ) + return ret; + ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_48kHz(); + if ( ret != 0 ) + return ret; + ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_32kHz(); + if ( ret != 0 ) + return ret; + ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus10ms_16kHz(); + if ( ret != 0 ) + return ret; + ret = encodeAndDecodeOneStereoFrameIvas5msLc3plus5ms_48kHz(); + if ( ret != 0 ) + return ret; + ret = encodeAndDecodeOneMonoFrameIvas20msLc3plus10ms_48kHz(); + if ( ret != 0 ) + return ret; + ret = encodeAndDecodeOneMonoFrameIvas5msLc3plus5ms_48kHz(); + if ( ret != 0 ) + return ret; + ret = encodeAndDecodeOneStereoFrameIvas20msLc3plus2_5ms_48kHz(); + if ( ret != 0 ) + return ret; + ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_decode_all_subframes(); + if ( ret != 0 ) + return ret; + ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_dont_decode_last_2_subframes(); + if ( ret != 0 ) + return ret; + ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_dont_decode_last_3_subframes(); + if ( ret != 0 ) + return ret; + ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_skip_first_subframe(); + if ( ret != 0 ) + return ret; + ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_decode_cache(); + if ( ret != 0 ) + return ret; + ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_switches_skip_first(); + if ( ret != 0 ) + return ret; + ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_switches_dec_first(); + if ( ret != 0 ) + return ret; + ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_bundle_switches_dec_first(); + if ( ret != 0 ) + return ret; + ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_bundle_switches_skip_first(); + if ( ret != 0 ) + return ret; + ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_get_active_dont_cache(); + if ( ret != 0 ) + return ret; +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + ret = selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_switches_dec_first_no_caching(); + if ( ret != 0 ) + return ret; +#endif +#if 0 + ret = selectiveDecIvas5msLc3plus5ms_48kHz_scenario_decode_all_subframes(); + if(ret != 0) + return ret; + ret = selectiveDecIvas5msLc3plus5ms_48kHz_scenario_dont_decode_last_subframes(); + if(ret != 0) + return ret; +#endif + return ret; +} diff --git a/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_selective_decoding.c b/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_selective_decoding.c new file mode 100644 index 0000000000000000000000000000000000000000..d90e98ed5bf5b601dc216964746b77806fb82166 --- /dev/null +++ b/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test_selective_decoding.c @@ -0,0 +1,1954 @@ +/****************************************************************************************************** + +(C) 2022-2023 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB, +Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +contributors to this repository. All Rights Reserved. + +This software is protected by copyright law and by international treaties. +The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB, +Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD., +Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange, +Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other +contributors to this repository retain full ownership rights in their respective contributions in +the software. This notice grants no license of any kind, including but not limited to patent +license, nor is any license granted by implication, estoppel or otherwise. + +Contributors are required to enter into the IVAS codec Public Collaboration agreement before making +contributions. + +This software is provided "AS IS", without any express or implied warranties. The software is in the +development stage. It is intended exclusively for experts who have experience with such software and +solely for the purpose of inspection. All implied warranties of non-infringement, merchantability +and fitness for a particular purpose are hereby disclaimed and excluded. + +Any dispute, controversy or claim arising under or in relation to providing this software shall be +submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in +accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and +the United Nations Convention on Contracts on the International Sales of Goods. + +*******************************************************************************************************/ + +#include +#include +#include "ivas_lc3plus_enc.h" +#include "ivas_lc3plus_common.h" +#include "ivas_lc3plus_dec.h" +#include "ivas_error_utils.h" + +#define MAX_SAMPLES_PER_CHANNEL 960 + +/* included by ivas_lc3plus_unit_test.c */ + +typedef int ( *ScenarioFnPtr )( const LC3PLUS_CONFIG config, + IVAS_LC3PLUS_DEC_HANDLE dec, + uint8_t *bitstream_in, + int32_t bitstream_in_size, + float **pcm_out ); + +static int encodeAndDecodeOne6chFrameFixture( LC3PLUS_CONFIG config, const int16_t enableCaching, const int32_t bps, ScenarioFnPtr scenarioFn ) +{ + ivas_error err; + int32_t encDelay = -1; + int32_t decDelay = -1; + + IVAS_LC3PLUS_ENC_HANDLE encHandle; + err = IVAS_LC3PLUS_ENC_Open( config, bps, &encHandle ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + err = IVAS_LC3PLUS_ENC_GetDelay( encHandle, &encDelay ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + if ( encDelay == -1 || encDelay == 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "encDelay is zero or uninitialized\n" ); + } + + /* encode one frame */ + int16_t numSamplesPerChannels = config.samplerate / ( 1000000 / config.ivas_frame_duration_us ); + float *pcm_in[6]; + float pcm_in_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_in_ch1, 0, numSamplesPerChannels * sizeof( float ) ); + float pcm_in_ch2[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_in_ch2, 0, numSamplesPerChannels * sizeof( float ) ); + float pcm_in_ch3[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_in_ch3, 0, numSamplesPerChannels * sizeof( float ) ); + float pcm_in_ch4[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_in_ch4, 0, numSamplesPerChannels * sizeof( float ) ); + float pcm_in_ch5[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_in_ch5, 0, numSamplesPerChannels * sizeof( float ) ); + float pcm_in_ch6[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_in_ch6, 0, numSamplesPerChannels * sizeof( float ) ); + pcm_in[0] = pcm_in_ch1; + pcm_in[1] = pcm_in_ch2; + pcm_in[2] = pcm_in_ch3; + pcm_in[3] = pcm_in_ch4; + pcm_in[4] = pcm_in_ch5; + pcm_in[5] = pcm_in_ch6; + + int32_t bitstreamSizePerIvasFrame = 0; + err = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( encHandle, &bitstreamSizePerIvasFrame ); + if ( IVAS_ERR_OK != err ) + return err; + + uint8_t *bitstream_out = malloc( bitstreamSizePerIvasFrame ); + memset( bitstream_out, 0, bitstreamSizePerIvasFrame ); + + err = IVAS_LC3PLUS_ENC_Encode( encHandle, pcm_in, bitstream_out ); + if ( IVAS_ERR_OK != err ) + return err; + IVAS_LC3PLUS_ENC_Close( &encHandle ); + + /* decode one frame */ + IVAS_LC3PLUS_DEC_HANDLE decHandle; + err = IVAS_LC3PLUS_DEC_Open( config, +#ifdef LC3PLUS_DEC_ALLOW_DISABLE_CACHING + enableCaching, +#endif + &decHandle ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + err = IVAS_LC3PLUS_DEC_GetDelay( decHandle, &decDelay ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + if ( decDelay == -1 || decDelay == 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "decDelay is zero or uninitialized\n" ); + } + + uint8_t *bitstream_in = bitstream_out; + + float *pcm_out[6]; + float pcm_out_ch1[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_out_ch1, 0, numSamplesPerChannels * sizeof( float ) ); + float pcm_out_ch2[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_out_ch2, 0, numSamplesPerChannels * sizeof( float ) ); + float pcm_out_ch3[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_out_ch3, 0, numSamplesPerChannels * sizeof( float ) ); + float pcm_out_ch4[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_out_ch4, 0, numSamplesPerChannels * sizeof( float ) ); + float pcm_out_ch5[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_out_ch5, 0, numSamplesPerChannels * sizeof( float ) ); + float pcm_out_ch6[MAX_SAMPLES_PER_CHANNEL * sizeof( float )]; + memset( pcm_out_ch6, 0, numSamplesPerChannels * sizeof( float ) ); + pcm_out[0] = pcm_out_ch1; + pcm_out[1] = pcm_out_ch2; + pcm_out[2] = pcm_out_ch3; + pcm_out[3] = pcm_out_ch4; + pcm_out[4] = pcm_out_ch5; + pcm_out[5] = pcm_out_ch6; + + err = IVAS_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + if ( NULL != scenarioFn ) + { + err = ( *scenarioFn )( config, decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + } + + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstreamSizePerIvasFrame, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + err = IVAS_LC3PLUS_DEC_Conceal( decHandle, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + IVAS_LC3PLUS_DEC_Close( &decHandle ); + free( bitstream_out ); + + return 0; +} + +/* + * in: [dec, dec, dec, dec] + * expected out: [dec_and_use, dec_and_use, dec_and_use, dec_and_use] + */ +static int scenario_decode_all_subframes( const LC3PLUS_CONFIG config, + IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ + uint8_t *bitstream_in, /* i: pointer to input bitstream */ + int32_t bitstream_in_size, /* i: size of bitstream_in */ + float **pcm_out /* o: decoded samples */ ) +{ + ivas_error err; + const int16_t decode = 1; + // const int16_t skipDecoding = 0; + uint32_t iDec = 0; + int iLc3plusFrame = 0; + int lc3framesPerIvasFrame; + int16_t **selective_decoding_matrix; + err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* Set selective decoding scenario */ + for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) + { + for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) + { + selective_decoding_matrix[iSubframeIdx][decIdx] = decode; + } + } + + /* Apply selective decoding scenario */ + err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder actions */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + assert( decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame == 0 ); + if(NULL != decHandle->bitstream_caches) + { + assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + } + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct post decoding state */ + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + } + + IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); + return IVAS_ERR_OK; +} + + +/* + * in: [dec, dec, skip, skip] + * expected out: [dec_and_use, dec_and_use, skip, cache] + */ +static int scenario_dont_decode_last_2_subframes( + const LC3PLUS_CONFIG config, + IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ + uint8_t *bitstream_in, /* i: pointer to input bitstream */ + int32_t bitstream_in_size, /* i: size of bitstream_in */ + float **pcm_out /* o: decoded samples */ ) +{ + ivas_error err; + const int16_t decode = 1; + const int16_t skipDecoding = 0; + uint32_t iDec = 0; + int iLc3plusFrame = 0; + int lc3framesPerIvasFrame; + int16_t **selective_decoding_matrix; + err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* Set selective decoding scenario */ + for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) + { + for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) + { + assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); + if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ + { + /* skip the last two subframes */ + selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; + } + else + { + /* decode the previous ones */ + selective_decoding_matrix[iSubframeIdx][decIdx] = decode; + } + } + } + + /* Apply selective decoding scenario */ + err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder actions */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + if(NULL != decHandle->bitstream_caches) + { + assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + } + if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) + { + /* last subframe is expected to be cached */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); + } + else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) + { + /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); + } + else + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + } + + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder caching */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + + IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); + return IVAS_ERR_OK; +} + +/* + * in: [dec, skip, skip, skip] + * expected out: [dec_and_use, skip, skip, cache] + */ +static int scenario_dont_decode_last_3_subframes( + const LC3PLUS_CONFIG config, + IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ + uint8_t *bitstream_in, /* i: pointer to input bitstream */ + int32_t bitstream_in_size, /* i: size of bitstream_in */ + float **pcm_out /* o: decoded samples */ ) +{ + ivas_error err; + const int16_t decode = 1; + const int16_t skipDecoding = 0; + uint32_t iDec = 0; + int iLc3plusFrame = 0; + int lc3framesPerIvasFrame; + int16_t **selective_decoding_matrix; + err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* Set selective decoding scenario */ + for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) + { + for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) + { + assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); + if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 3 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ + { + /* skip the last three subframes */ + selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; + } + else + { + /* decode the previous ones */ + selective_decoding_matrix[iSubframeIdx][decIdx] = decode; + } + } + } + + /* Apply selective decoding scenario */ + err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder actions */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) + { + /* last subframe is expected to be cached */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); + } + else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) + { + /* subframes before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); + } + else if ( iLc3plusFrame == lc3framesPerIvasFrame - 3 ) + { + /* subframes before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); + } + else + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + } + + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder caching */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + + IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); + return IVAS_ERR_OK; +} + + +/* + * in: [skip, dec, dec, dec] + * expected out: [dec_and_drop, dec_and_use, dec_and_use, dec_and_use] + */ +static int scenario_skip_first_subframe( + const LC3PLUS_CONFIG config, + IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ + uint8_t *bitstream_in, /* i: pointer to input bitstream */ + int32_t bitstream_in_size, /* i: size of bitstream_in */ + float **pcm_out /* o: decoded samples */ ) +{ + ivas_error err; + const int16_t decode = 1; + const int16_t skipDecoding = 0; + uint32_t iDec = 0; + int iLc3plusFrame = 0; + int lc3framesPerIvasFrame; + int16_t **selective_decoding_matrix; + err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* Set selective decoding scenario */ + for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) + { + for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) + { + if ( iSubframeIdx == 0 ) + { + /* skip the first subframe */ + selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; + } + else + { + /* decode the following subframes */ + selective_decoding_matrix[iSubframeIdx][decIdx] = decode; + } + } + } + + /* Apply selective decoding scenario */ + err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder actions */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + + if ( iLc3plusFrame == 0 ) + { + /* first subframe is expected to be decoded and dropped */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_DROP ); + } + else + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + } + + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder caching */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + + IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); + return IVAS_ERR_OK; +} + +/* + * Step1: + * in: [dec, dec, skip, skip] + * expected out: [dec_and_use, dec_and_use, skip, cache] + * + * Step2: + * in: [dec, dec, dec, dec] + * expected out: [dec_cache & dec_and_use, dec_and_use, dec_and_use, dec_and_use] + */ +static int scenario_decode_cache( + const LC3PLUS_CONFIG config, + IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ + uint8_t *bitstream_in, /* i: pointer to input bitstream */ + int32_t bitstream_in_size, /* i: size of bitstream_in */ + float **pcm_out /* o: decoded samples */ ) +{ + ivas_error err; + const int16_t decode = 1; + const int16_t skipDecoding = 0; + uint32_t iDec = 0; + int iLc3plusFrame = 0; + int lc3framesPerIvasFrame; + int16_t **selective_decoding_matrix; + err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* Set selective decoding scenario */ + for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) + { + for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) + { + assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); + if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ + { + /* skip the last two subframes */ + selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; + } + else + { + /* decode the previous ones */ + selective_decoding_matrix[iSubframeIdx][decIdx] = decode; + } + } + } + + /* Apply selective decoding scenario */ + err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder actions */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + + if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) + { + /* last subframe is expected to be cached */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); + } + else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) + { + /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); + } + else + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + } + + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder caching */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + + /* Step 2, ensure that the cache is used */ + for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) + { + for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) + { + /* decode all */ + selective_decoding_matrix[iSubframeIdx][decIdx] = decode; + } + } + /* Apply selective decoding scenario */ + err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + /* verify correct decoder actions */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 1 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + /* verify correct post-decoding state */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + + IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); + return IVAS_ERR_OK; +} + +/* + * Step1: + * in: [skip, skip, dec, dec] + * expected out: [skip, dec_and_drop, dec_and_use, dec_and_use] + * + * Step2: + * in: [dec, dec, dec, dec] + * expected out: [no_cache & dec_and_use, dec_and_use, dec_and_use, dec_and_use] + */ +static int scenario_get_active_dont_cache( + const LC3PLUS_CONFIG config, + IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ + uint8_t *bitstream_in, /* i: pointer to input bitstream */ + int32_t bitstream_in_size, /* i: size of bitstream_in */ + float **pcm_out /* o: decoded samples */ ) +{ + ivas_error err; + const int16_t decode = 1; + const int16_t skipDecoding = 0; + uint32_t iDec = 0; + int iLc3plusFrame = 0; + int lc3framesPerIvasFrame; + int16_t **selective_decoding_matrix; + err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* Set selective decoding scenario */ + for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) + { + for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) + { + assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); + if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ + { + /* skip the last two subframes */ + selective_decoding_matrix[iSubframeIdx][decIdx] = decode; + } + else + { + /* decode the previous ones */ + selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; + } + } + } + + /* Apply selective decoding scenario */ + err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder actions + * * expected out: [skip, dec_and_drop, dec_and_use, dec_and_use] */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) + { + /* last subframe is expected to be cached */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) + { + /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + else if ( iLc3plusFrame == lc3framesPerIvasFrame - 3 ) + { + /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_DROP ); + } + else + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); + } + } + } + + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder caching */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + + /* Step 2, ensure that there is no cache */ + for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) + { + for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) + { + /* decode all [dec, dec, dec, dec]*/ + selective_decoding_matrix[iSubframeIdx][decIdx] = decode; + } + } + /* Apply selective decoding scenario */ + err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + /* verify correct decoder actions + * expected out: [no_cache & dec_and_use, dec_and_use, dec_and_use, dec_and_use]*/ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + /* verify correct post-decoding state */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + + IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); + return IVAS_ERR_OK; +} + + +/* + * Step1: + * in: [dec, dec, skip, skip] + * expected out: [dec_and_use, dec_and_use, skip, cache] + * + * Step2: + * in: [skip, dec, skip, dec] + * expected out: [drop_cache & dec_and_drop, dec_and_use, dec_and_drop, dec_and_use] + * */ +static int scenario_per_subframe_switches_skip_first( + const LC3PLUS_CONFIG config, + IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ + uint8_t *bitstream_in, /* i: pointer to input bitstream */ + int32_t bitstream_in_size, /* i: size of bitstream_in */ + float **pcm_out /* o: decoded samples */ ) +{ + ivas_error err; + const int16_t decode = 1; + const int16_t skipDecoding = 0; + uint32_t iDec = 0; + int iLc3plusFrame = 0; + int lc3framesPerIvasFrame; + int16_t **selective_decoding_matrix; + err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* Set selective decoding scenario */ + for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) + { + for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) + { + assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); + if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ + { + /* skip the last two subframes */ + selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; + } + else + { + /* decode the previous ones */ + selective_decoding_matrix[iSubframeIdx][decIdx] = decode; + } + } + } + + /* Apply selective decoding scenario */ + err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder actions */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) + { + /* last subframe is expected to be cached */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); + } + else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) + { + /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); + } + else + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + } + + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder caching */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + + /* Step 2 + * in: [skip, dec, skip, dec] + * */ + for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) + { + for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) + { + if(iSubframeIdx == 0 || iSubframeIdx == 2) + { + selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; + } + else if(iSubframeIdx == 1 || iSubframeIdx == 3) + { + selective_decoding_matrix[iSubframeIdx][decIdx] = decode; + } + else + { + //unsupported iSubframeIdx count; + return 1; + } + + } + } + /* Apply selective decoding scenario */ + err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder actions + * expected out: [drop_cache & dec_and_drop, dec_and_use, dec_and_drop, dec_and_use] + * */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + if ( iLc3plusFrame == 1 || iLc3plusFrame == 3) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + else if ( iLc3plusFrame == 0 || iLc3plusFrame == 2) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_DROP ); + } + else + { + assert(0); + } + } + } + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + /* verify correct post-decoding state */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + + IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); + return IVAS_ERR_OK; +} + +/* + * Step1: + * in: [dec, dec, skip, skip] + * expected out: [dec_and_use, dec_and_use, skip, cache] + * + * Step2: + * in: [dec, skip, dec, skip] + * expected out: [dec_cache & dec_and_use, dec_and_drop, dec_and_use, cache] + * */ +static int scenario_per_subframe_switches_dec_first( + const LC3PLUS_CONFIG config, + IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ + uint8_t *bitstream_in, /* i: pointer to input bitstream */ + int32_t bitstream_in_size, /* i: size of bitstream_in */ + float **pcm_out /* o: decoded samples */ ) +{ + ivas_error err; + const int16_t decode = 1; + const int16_t skipDecoding = 0; + uint32_t iDec = 0; + int iLc3plusFrame = 0; + int lc3framesPerIvasFrame; + int16_t **selective_decoding_matrix; + err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* Set selective decoding scenario */ + for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) + { + for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) + { + assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); + if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ + { + /* skip the last two subframes */ + selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; + } + else + { + /* decode the previous ones */ + selective_decoding_matrix[iSubframeIdx][decIdx] = decode; + } + } + } + + /* Apply selective decoding scenario */ + err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder actions */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) + { + /* last subframe is expected to be cached */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); + } + else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) + { + /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); + } + else + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + } + + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder caching */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + + /* Step 2 + * in: [dec, skip, dec, skip] + * */ + for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) + { + for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) + { + if(iSubframeIdx == 0 || iSubframeIdx == 2) + { + selective_decoding_matrix[iSubframeIdx][decIdx] = decode; + } + else if(iSubframeIdx == 1 || iSubframeIdx == 3) + { + selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; + } + else + { + // unsupported iSubframeIdx count + return 1; + } + + } + } + /* Apply selective decoding scenario */ + err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder actions + * expected out: [dec_cache & dec_and_use, dec_and_drop, dec_and_use, cache] + * */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 1 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + if ( iLc3plusFrame == 0 ) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + else if ( iLc3plusFrame == 1 ) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_DROP ); + } + else if ( iLc3plusFrame == 2 ) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + else if ( iLc3plusFrame == 3) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); + } + else + { + assert(0); + } + } + } + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + /* verify correct post-decoding state */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + + IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); + return IVAS_ERR_OK; +} + +/* + * Step1: + * in: [dec, dec, skip, skip] + * expected out: [dec_and_use, dec_and_use, skip, skip] + * + * Step2: + * in: [dec, skip, dec, skip] + * expected out: [drop_cache & dec_and_use, skip, dec_and_use, skip] + * */ +static int scenario_per_subframe_switches_dec_first_no_caching( + const LC3PLUS_CONFIG config, + IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ + uint8_t *bitstream_in, /* i: pointer to input bitstream */ + int32_t bitstream_in_size, /* i: size of bitstream_in */ + float **pcm_out /* o: decoded samples */ ) +{ + ivas_error err; + const int16_t decode = 1; + const int16_t skipDecoding = 0; + uint32_t iDec = 0; + int iLc3plusFrame = 0; + int lc3framesPerIvasFrame; + int16_t **selective_decoding_matrix; + err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* Set selective decoding scenario */ + for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) + { + for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) + { + assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); + if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ + { + /* skip the last two subframes */ + selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; + } + else + { + /* decode the previous ones */ + selective_decoding_matrix[iSubframeIdx][decIdx] = decode; + } + } + } + + /* Apply selective decoding scenario */ + err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder actions */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( NULL == decHandle->bitstream_caches ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) + { + /* last subframe is expected to be cached */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); + } + else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) + { + /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); + } + else + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + } + + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder caching */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( NULL == decHandle->bitstream_caches ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + + /* Step 2 + * in: [dec, skip, dec, skip] + * */ + for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) + { + for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) + { + if(iSubframeIdx == 0 || iSubframeIdx == 2) + { + selective_decoding_matrix[iSubframeIdx][decIdx] = decode; + } + else if(iSubframeIdx == 1 || iSubframeIdx == 3) + { + selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; + } + else + { + // unsupported iSubframeIdx count + return 1; + } + + } + } + /* Apply selective decoding scenario */ + err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder actions + * expected out: [drop_cache & dec_and_use, skip, dec_and_use, skip] + * */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( NULL == decHandle->bitstream_caches ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + if ( iLc3plusFrame == 0 ) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + else if ( iLc3plusFrame == 1 ) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); + } + else if ( iLc3plusFrame == 2 ) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + else if ( iLc3plusFrame == 3) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); + } + else + { + assert(0); + } + } + } + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + /* verify correct post-decoding state */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( NULL == decHandle->bitstream_caches ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + + IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); + return IVAS_ERR_OK; +} + + +/* + * Step1: + * in: [dec, dec, skip, skip] + * expected out: [dec_and_use, dec_and_use, skip, cache] + * + * Step2: + * in: [dec, skip, skip, dec] + * expected out: [dec_cache & dec_and_use, skip, dec_and_drop, dec_and_use] + * */ +static int scenario_per_subframe_bundle_switches_dec_first( + const LC3PLUS_CONFIG config, + IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ + uint8_t *bitstream_in, /* i: pointer to input bitstream */ + int32_t bitstream_in_size, /* i: size of bitstream_in */ + float **pcm_out /* o: decoded samples */ ) +{ + ivas_error err; + const int16_t decode = 1; + const int16_t skipDecoding = 0; + uint32_t iDec = 0; + int iLc3plusFrame = 0; + int lc3framesPerIvasFrame; + int16_t **selective_decoding_matrix; + err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* Set selective decoding scenario */ + for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) + { + for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) + { + assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); + if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ + { + /* skip the last two subframes */ + selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; + } + else + { + /* decode the previous ones */ + selective_decoding_matrix[iSubframeIdx][decIdx] = decode; + } + } + } + + /* Apply selective decoding scenario */ + err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder actions */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) + { + /* last subframe is expected to be cached */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); + } + else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) + { + /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); + } + else + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + } + + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder caching */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + + /* Step 2 + * in: [dec, skip, skip, dec] + * */ + for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) + { + for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) + { + if(iSubframeIdx == 0 || iSubframeIdx == 3) + { + selective_decoding_matrix[iSubframeIdx][decIdx] = decode; + } + else if(iSubframeIdx == 1 || iSubframeIdx == 2) + { + selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; + } + else + { + // unsupported iSubframeIdx count + return 1; + } + + } + } + /* Apply selective decoding scenario */ + err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder actions + * expected out: [dec_cache & dec_and_use, skip, dec_and_drop, dec_and_use] + * */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 1 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + if ( iLc3plusFrame == 0 ) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + else if ( iLc3plusFrame == 1 ) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); + } + else if ( iLc3plusFrame == 2 ) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_DROP ); + } + else if ( iLc3plusFrame == 3) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + else + { + assert(0); + } + } + } + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + /* verify correct post-decoding state */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + + IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); + return IVAS_ERR_OK; +} + +/* + * Step1: + * in: [dec, dec, skip, skip] + * expected out: [dec_and_use, dec_and_use, skip, cache] + * + * Step2: + * in: [skip, dec, dec, skip] + * expected out: [drop_cache & dec_and_drop, dec_and_use, dec_and_use, cache] + * */ +static int scenario_per_subframe_bundle_switches_skip_first( + const LC3PLUS_CONFIG config, + IVAS_LC3PLUS_DEC_HANDLE decHandle, /* i: decoder handle */ + uint8_t *bitstream_in, /* i: pointer to input bitstream */ + int32_t bitstream_in_size, /* i: size of bitstream_in */ + float **pcm_out /* o: decoded samples */ ) +{ + ivas_error err; + const int16_t decode = 1; + const int16_t skipDecoding = 0; + uint32_t iDec = 0; + int iLc3plusFrame = 0; + int lc3framesPerIvasFrame; + int16_t **selective_decoding_matrix; + err = IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( &selective_decoding_matrix, config.channels ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* Set selective decoding scenario */ + for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) + { + for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) + { + assert( MAX_PARAM_SPATIAL_SUBFRAMES == 4 ); + if ( iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 1 || iSubframeIdx == MAX_PARAM_SPATIAL_SUBFRAMES - 2 ) /*only valid for MAX_PARAM_SPATIAL_SUBFRAMES == 4 */ + { + /* skip the last two subframes */ + selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; + } + else + { + /* decode the previous ones */ + selective_decoding_matrix[iSubframeIdx][decIdx] = decode; + } + } + } + + /* Apply selective decoding scenario */ + err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder actions */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 0 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 == decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + if ( iLc3plusFrame == lc3framesPerIvasFrame - 1 ) + { + /* last subframe is expected to be cached */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); + } + else if ( iLc3plusFrame == lc3framesPerIvasFrame - 2 ) + { + /* subframe before the last one is expected to be skipped, since only the last one is required to flush the decoder after a pause */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_SKIP ); + } + else + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + } + + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder caching */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + + /* Step 2 + * in: [skip, dec, dec, skip] + * */ + for ( int16_t iSubframeIdx = 0; iSubframeIdx < MAX_PARAM_SPATIAL_SUBFRAMES; iSubframeIdx++ ) + { + for ( int16_t decIdx = 0; decIdx < config.channels; decIdx++ ) + { + if(iSubframeIdx == 1 || iSubframeIdx == 2) + { + selective_decoding_matrix[iSubframeIdx][decIdx] = decode; + } + else if(iSubframeIdx == 0 || iSubframeIdx == 3) + { + selective_decoding_matrix[iSubframeIdx][decIdx] = skipDecoding; + } + else + { + // unsupported iSubframeIdx count + return 1; + } + + } + } + /* Apply selective decoding scenario */ + err = IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( decHandle, selective_decoding_matrix ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + + /* verify correct decoder actions + * expected out: [drop_cache & dec_and_drop, dec_and_use, dec_and_use, cache] + * */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + if ( iLc3plusFrame == 0 ) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_DROP ); + } + else if ( iLc3plusFrame == 1 ) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + else if ( iLc3plusFrame == 2 ) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + else if ( iLc3plusFrame == 3) + { + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_CACHE ); + } + else + { + assert(0); + } + } + } + err = IVAS_LC3PLUS_DEC_Decode( decHandle, bitstream_in, bitstream_in_size, pcm_out ); + if ( IVAS_ERR_OK != err ) + { + return err; + } + /* verify correct post-decoding state */ + lc3framesPerIvasFrame = decHandle->config.ivas_frame_duration_us / decHandle->config.lc3plus_frame_duration_us; + for ( iDec = 0; iDec < decHandle->num_decs; iDec++ ) + { + assert( 1 == decHandle->selective_decoding_states[iDec]->has_skipped_a_frame ); + assert( 0 == decHandle->selective_decoding_states[iDec]->shall_decode_cached_frame ); + assert( 0 != decHandle->bitstream_caches[iDec]->bitstream_cache_size ); + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + /* default action after decoding should be DEC_ACTION_DECODE_AND_USE again */ + assert( decHandle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] == DEC_ACTION_DECODE_AND_USE ); + } + } + + IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( selective_decoding_matrix ); + return IVAS_ERR_OK; +} + + +static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_decode_all_subframes( void ) +{ + int err; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; + const int16_t enableCaching = 1; + err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_decode_all_subframes ); + if ( 0 != err ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + return err; +} + +static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_dont_decode_last_2_subframes( void ) +{ + int err = 0; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; + const int16_t enableCaching = 1; + err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_dont_decode_last_2_subframes ); + if ( 0 != err ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + return err; +} + +static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_dont_decode_last_3_subframes( void ) +{ + int err = 0; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; + const int16_t enableCaching = 1; + err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_dont_decode_last_3_subframes ); + if ( 0 != err ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + return err; +} + +static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_skip_first_subframe( void ) +{ + int err = 0; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; + const int16_t enableCaching = 1; + err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_skip_first_subframe ); + if ( 0 != err ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + return err; +} + +static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_decode_cache( void ) +{ + int err = 0; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; + const int16_t enableCaching = 1; + err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_decode_cache ); + if ( 0 != err ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + return err; +} + +static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_switches_skip_first( void ) +{ + int err = 0; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; + const int16_t enableCaching = 1; + err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_per_subframe_switches_skip_first ); + if ( 0 != err ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + return err; +} + +static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_switches_dec_first( void ) +{ + int err = 0; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; + const int16_t enableCaching = 1; + err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_per_subframe_switches_dec_first ); + if ( 0 != err ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + return err; +} + +static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_bundle_switches_dec_first( void ) +{ + int err = 0; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; + const int16_t enableCaching = 1; + err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_per_subframe_bundle_switches_dec_first ); + if ( 0 != err ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + return err; +} + +static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_bundle_switches_skip_first( void ) +{ + int err = 0; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; + const int16_t enableCaching = 1; + err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_per_subframe_bundle_switches_skip_first ); + if ( 0 != err ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + return err; +} + +static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_per_subframe_switches_dec_first_no_caching( void ) +{ + int err = 0; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; + const int16_t enableCaching = 0; + err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_per_subframe_switches_dec_first_no_caching ); + if ( 0 != err ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + return err; +} + + +static int selectiveDecIvas20msLc3plus5ms_48kHz_scenario_get_active_dont_cache( void ) +{ + int err = 0; + LC3PLUS_CONFIG config = { .lc3plus_frame_duration_us = 5 * 1000, .ivas_frame_duration_us = 20 * 1000, .channels = 6, .samplerate = 48000 }; + const int16_t enableCaching = 1; + err = encodeAndDecodeOne6chFrameFixture( config, enableCaching, 768000, &scenario_get_active_dont_cache ); + if ( 0 != err ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "test failed\n" ); + } + return err; +} + + + + + + diff --git a/scripts/split_rendering/lc3plus/split_rend_lc3plus_cmdlines.py b/scripts/split_rendering/lc3plus/split_rend_lc3plus_cmdlines.py new file mode 100755 index 0000000000000000000000000000000000000000..f72fce6a871cd2d7b50c8552bed5b2fedc79e2aa --- /dev/null +++ b/scripts/split_rendering/lc3plus/split_rend_lc3plus_cmdlines.py @@ -0,0 +1,173 @@ +""" +Generate command lines for split rendering with LC3plus +""" + +import itertools +import os + +# Paths +ENC_PATH = "./IVAS_cod" +DEC_PATH = "./IVAS_dec" +REND_PATH = "./IVAS_rend" +TEMP_DIR = "tmp" + +# Config values to iterate over +ISM_CONFIGS_NUM_OBJECTS = [1, 2, 3, 4] +IVAS_BITRATES = [128000] +PRE_HEAD_ROT_FILES = ["Workspace_msvc/trajectories/pre-renderer_pose_files/pre_yaw-20static.csv"] +POST_HEAD_ROT_FILES = ["Workspace_msvc/trajectories/post-renderer_pose_files/post_0static.csv"] +RENDER_CONFIG_FILES = [ + ####################################################### + # Alternative 2 - LC3plus with CLDFB pose correction + "Workspace_msvc/renderer_configs/split_renderer_config_768_1dof.txt", + "Workspace_msvc/renderer_configs/split_renderer_config_512_2dof.txt", + None, # Alternative 2 is the default when no rendering config file is given on command line + ####################################################### + # Alternative 3 - LC3plus with multi-stream (TD) pose correction + "Workspace_msvc/renderer_configs/split_renderer_config_768_1dof_tdposecorr.txt", + "Workspace_msvc/renderer_configs/split_renderer_config_1536_2dof_tdposecorr.txt", +] + + +def audio_for_ism(num_objects): + return f"scripts/testv/stv{num_objects}ISM48s.wav" + + +def metadata_for_ism(num_objects): + return f"scripts/testv/stvISM{num_objects}.csv" + + +def basename(file_path): + basename_w_ext = os.path.basename(file_path) + return os.path.splitext(basename_w_ext)[0] + + +# Full chain: IVAS_cod -> IVAS_dec -> IVAS_rend(post) +def full_chain(num_objects, ivas_bitrate, pre_head_rot_file, render_config_file, post_head_rot_file): + bs_name = f"{TEMP_DIR}/ism{num_objects}_b{ivas_bitrate}_full_chain.g192" + cod = [ + ENC_PATH, + "-ism", + str(num_objects), + *[metadata_for_ism(i + 1) for i in range(num_objects)], + str(ivas_bitrate), + "48", + audio_for_ism(num_objects), + bs_name, + ] + + render_config_infix = f"##{basename(render_config_file)}" if render_config_file else "" + split_bs_name = bs_name.replace(".g192", f"##{basename(pre_head_rot_file)}{render_config_infix}##split.bs") + render_config_args = ["-render_config", render_config_file] if render_config_file else [] + dec = [ + DEC_PATH, + "-T", + pre_head_rot_file, + *render_config_args, + "SPLIT_BINAURAL", + "48", + bs_name, + split_bs_name, + ] + + binaural_output_name = split_bs_name.replace(".bs", f"##{basename(post_head_rot_file)}##binaural.wav") + rend = [ + REND_PATH, + "-i", + split_bs_name, + "-if", + "BINAURAL_SPLIT_CLDFB", + "-of", + "BINAURAL", + "-fs", + "48", + "-tf", + post_head_rot_file, + "-o", + binaural_output_name, + ] + + return [cod, dec, rend] + + +# Renderer chain: IVAS_rend(pre) -> IVAS_rend(post) +def rend_chain(num_objects, pre_head_rot_file, render_config_file, post_head_rot_file): + render_config_infix = f"##{basename(render_config_file)}" if render_config_file else "" + split_bs_name = ( + f"{TEMP_DIR}/ism{num_objects}_rend_chain##{basename(pre_head_rot_file)}{render_config_infix}##split.bs" + ) + render_config_args = ["-render_config", render_config_file] if render_config_file else [] + pre = [ + REND_PATH, + "-i", + audio_for_ism(num_objects), + "-if", + f"ISM{num_objects}", + "-im", + *[metadata_for_ism(i + 1) for i in range(num_objects)], + "-of", + "BINAURAL_SPLIT_CLDFB", + "-fs", + "48", + *render_config_args, + "-tf", + pre_head_rot_file, + "-o", + split_bs_name, + ] + + binaural_output_name = split_bs_name.replace(".bs", f"##{basename(post_head_rot_file)}##binaural.wav") + post = [ + REND_PATH, + "-i", + split_bs_name, + "-if", + "BINAURAL_SPLIT_CLDFB", + "-of", + "BINAURAL", + "-fs", + "48", + "-tf", + post_head_rot_file, + "-o", + binaural_output_name, + ] + + return [pre, post] + + +def print_command_list(list_of_lists): + for lst in list_of_lists: + print(" ".join(lst)) + print("") # newline + + +def main(): + print("\n##########################################") + print("# Full chain: enc -> dec -> rend(post)") + print("##########################################\n") + for args_full_chain in itertools.product( + # Ordering here must match argument order in function call below! + ISM_CONFIGS_NUM_OBJECTS, + IVAS_BITRATES, + PRE_HEAD_ROT_FILES, + RENDER_CONFIG_FILES, + POST_HEAD_ROT_FILES, + ): + print_command_list(full_chain(*args_full_chain)) + + print("\n##########################################") + print("# Renderer chain: rend(pre) -> rend(post)") + print("##########################################\n") + for args_rend_chain in itertools.product( + # Ordering here must match argument order in function call below! + ISM_CONFIGS_NUM_OBJECTS, + PRE_HEAD_ROT_FILES, + RENDER_CONFIG_FILES, + POST_HEAD_ROT_FILES, + ): + print_command_list(rend_chain(*args_rend_chain)) + + +if __name__ == "__main__": + main()