aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarish Mahendrakar <harish.mahendrakar@ittiam.com>2020-10-04 19:14:15 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-10-04 19:14:15 +0000
commitad4bd1a10fbdf609c337becbfd7585453f428b11 (patch)
tree086b8caee09ec165e8b7a1700e63427b54d79e39
parent6f3060bc0fd66912b6f467b1bbaa51d11422e5dc (diff)
parent7015979258a4b4eefb522ad072b03ee9b5ab3602 (diff)
downloadlibopus-ad4bd1a10fbdf609c337becbfd7585453f428b11.tar.gz
Merge branch 'upstream-master' am: e2bcf2c247 am: 7a87b356ef am: 0dc8a539d8 am: 57e7bcb6ae am: 7015979258
Original change: https://android-review.googlesource.com/c/platform/external/libopus/+/1443636 Change-Id: I4b55fd4b9c5338df3701793595e93da428810902
-rw-r--r--.gitignore5
-rw-r--r--.gitlab-ci.yml42
-rw-r--r--CMakeLists.txt574
-rw-r--r--METADATA12
-rw-r--r--Makefile.am16
-rw-r--r--Makefile.mips2
-rw-r--r--README4
-rw-r--r--README.draft4
-rw-r--r--README.version10
-rw-r--r--celt/arch.h5
-rw-r--r--celt/arm/armcpu.c2
-rw-r--r--celt/bands.c4
-rw-r--r--celt/celt_decoder.c8
-rw-r--r--celt/celt_encoder.c2
-rw-r--r--celt/ecintrin.h4
-rw-r--r--celt/float_cast.h58
-rw-r--r--celt/mips/celt_mipsr1.h1
-rw-r--r--celt/mips/vq_mipsr1.h8
-rw-r--r--celt/os_support.h1
-rw-r--r--celt/rate.h2
-rw-r--r--celt/vq.c4
-rw-r--r--celt/vq.h4
-rw-r--r--celt_sources.mk3
-rw-r--r--cmake/CFeatureCheck.cmake39
-rw-r--r--cmake/OpusBuildtype.cmake27
-rw-r--r--cmake/OpusConfig.cmake104
-rw-r--r--cmake/OpusConfig.cmake.in20
-rw-r--r--cmake/OpusFunctions.cmake215
-rw-r--r--cmake/OpusPackageVersion.cmake70
-rw-r--r--cmake/OpusSources.cmake46
-rw-r--r--cmake/config.h.cmake.in1
-rw-r--r--cmake/vla.c7
-rw-r--r--configure.ac17
-rw-r--r--doc/Doxyfile.in14
-rwxr-xr-xdoc/build_draft.sh11
-rw-r--r--doc/footer.html8
-rw-r--r--doc/header.html17
-rw-r--r--doc/release.txt4
-rw-r--r--doc/trivial_example.c19
-rw-r--r--include/opus_custom.h4
-rw-r--r--include/opus_defines.h11
-rw-r--r--opus_sources.mk3
-rw-r--r--releases.sha214
-rw-r--r--silk/CNG.c4
-rw-r--r--silk/MacroCount.h2
-rw-r--r--silk/NSQ_del_dec.c12
-rw-r--r--silk/PLC.c6
-rw-r--r--silk/debug.c3
-rw-r--r--silk/debug.h25
-rw-r--r--silk/decode_frame.c1
-rw-r--r--silk/define.h1
-rw-r--r--silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h7
-rw-r--r--silk/fixed/warped_autocorrelation_FIX.c2
-rw-r--r--silk/float/warped_autocorrelation_FLP.c4
-rw-r--r--silk/typedef.h3
-rw-r--r--silk_sources.mk6
-rw-r--r--src/analysis.c62
-rw-r--r--src/analysis.h1
-rw-r--r--src/mapping_matrix.h2
-rw-r--r--src/mlp.c75
-rw-r--r--src/opus_encoder.c124
-rw-r--r--src/opus_multistream_decoder.c9
-rw-r--r--src/opus_multistream_encoder.c2
-rw-r--r--src/opus_private.h1
-rw-r--r--tests/opus_decode_fuzzer.c33
-rw-r--r--tests/test_opus_common.h3
-rw-r--r--tests/test_opus_encode.c34
-rw-r--r--tests/test_opus_projection.c2
-rwxr-xr-xtraining/rnn_dump.py66
-rwxr-xr-xtraining/rnn_train.py177
-rwxr-xr-xtraining/txt2hdf5.py12
71 files changed, 1851 insertions, 254 deletions
diff --git a/.gitignore b/.gitignore
index eccd0a2a..837619f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,6 +38,7 @@ opus_demo
repacketizer_demo
stamp-h1
test-driver
+trivial_example
*.sw*
*.o
*.lo
@@ -83,3 +84,7 @@ silk/tests/test_unit_LPC_inv_pred_gain
src/Debug
src/Release
src/x64
+/*[Bb]uild*/
+.vs/
+.vscode/
+CMakeSettings.json
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 00000000..88a1342c
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,42 @@
+default:
+ tags:
+ - docker
+ # Image from https://hub.docker.com/_/gcc/ based on Debian
+ image: gcc:9
+
+whitespace:
+ stage: test
+ only:
+ - merge_requests
+ script:
+ - git diff-tree --check origin/master HEAD
+
+autoconf:
+ stage: build
+ before_script:
+ - apt-get update &&
+ apt-get install -y zip doxygen
+ script:
+ - ./autogen.sh
+ - ./configure
+ - make
+ - make distcheck
+ cache:
+ paths:
+ - "src/*.o"
+ - "src/.libs/*.o"
+ - "silk/*.o"
+ - "silk/.libs/*.o"
+ - "celt/*.o"
+ - "celt/.libs/*.o"
+
+cmake:
+ stage: build
+ before_script:
+ - apt-get update &&
+ apt-get install -y cmake ninja-build
+ script:
+ - mkdir build
+ - cmake -S . -B build -G "Ninja" -DCMAKE_BUILD_TYPE=Release -DOPUS_BUILD_TESTING=ON -DOPUS_BUILD_PROGRAMS=ON
+ - cmake --build build
+ - cd build && ctest --output-on-failure
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 00000000..244ad139
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,574 @@
+cmake_minimum_required(VERSION 3.1)
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+
+include(OpusPackageVersion)
+get_package_version(PACKAGE_VERSION PROJECT_VERSION)
+
+project(Opus LANGUAGES C VERSION ${PROJECT_VERSION})
+
+include(OpusFunctions)
+include(OpusBuildtype)
+include(OpusConfig)
+include(OpusSources)
+include(GNUInstallDirs)
+include(CMakeDependentOption)
+include(FeatureSummary)
+
+set(OPUS_BUILD_SHARED_LIBRARY_HELP_STR "build shared library.")
+option(OPUS_BUILD_SHARED_LIBRARY ${OPUS_BUILD_SHARED_LIBRARY_HELP_STR} OFF)
+if(OPUS_BUILD_SHARED_LIBRARY OR BUILD_SHARED_LIBS OR OPUS_BUILD_FRAMEWORK)
+ # Global flag to cause add_library() to create shared libraries if on.
+ set(BUILD_SHARED_LIBS ON)
+ set(OPUS_BUILD_SHARED_LIBRARY ON)
+endif()
+add_feature_info(OPUS_BUILD_SHARED_LIBRARY OPUS_BUILD_SHARED_LIBRARY ${OPUS_BUILD_SHARED_LIBRARY_HELP_STR})
+
+set(OPUS_BUILD_TESTING_HELP_STR "build tests.")
+option(OPUS_BUILD_TESTING ${OPUS_BUILD_TESTING_HELP_STR} OFF)
+if(OPUS_BUILD_TESTING OR BUILD_TESTING)
+ set(OPUS_BUILD_TESTING ON)
+ set(BUILD_TESTING ON)
+endif()
+add_feature_info(OPUS_BUILD_TESTING OPUS_BUILD_TESTING ${OPUS_BUILD_TESTING_HELP_STR})
+
+set(OPUS_CUSTOM_MODES_HELP_STR "enable non-Opus modes, e.g. 44.1 kHz & 2^n frames.")
+option(OPUS_CUSTOM_MODES ${OPUS_CUSTOM_MODES_HELP_STR} OFF)
+add_feature_info(OPUS_CUSTOM_MODES OPUS_CUSTOM_MODES ${OPUS_CUSTOM_MODES_HELP_STR})
+
+set(OPUS_BUILD_PROGRAMS_HELP_STR "build programs.")
+option(OPUS_BUILD_PROGRAMS ${OPUS_BUILD_PROGRAMS_HELP_STR} OFF)
+add_feature_info(OPUS_BUILD_PROGRAMS OPUS_BUILD_PROGRAMS ${OPUS_BUILD_PROGRAMS_HELP_STR})
+
+set(OPUS_DISABLE_INTRINSICS_HELP_STR "disable all intrinsics optimizations.")
+option(OPUS_DISABLE_INTRINSICS ${OPUS_DISABLE_INTRINSICS_HELP_STR} OFF)
+add_feature_info(OPUS_DISABLE_INTRINSICS OPUS_DISABLE_INTRINSICS ${OPUS_DISABLE_INTRINSICS_HELP_STR})
+
+set(OPUS_FIXED_POINT_HELP_STR "compile as fixed-point (for machines without a fast enough FPU).")
+option(OPUS_FIXED_POINT ${OPUS_FIXED_POINT_HELP_STR} OFF)
+add_feature_info(OPUS_FIXED_POINT OPUS_FIXED_POINT ${OPUS_FIXED_POINT_HELP_STR})
+
+set(OPUS_ENABLE_FLOAT_API_HELP_STR "compile with the floating point API (for machines with float library).")
+option(OPUS_ENABLE_FLOAT_API ${OPUS_ENABLE_FLOAT_API_HELP_STR} ON)
+add_feature_info(OPUS_ENABLE_FLOAT_API OPUS_ENABLE_FLOAT_API ${OPUS_ENABLE_FLOAT_API_HELP_STR})
+
+set(OPUS_FLOAT_APPROX_HELP_STR "enable floating point approximations (Ensure your platform supports IEEE 754 before enabling).")
+option(OPUS_FLOAT_APPROX ${OPUS_FLOAT_APPROX_HELP_STR} OFF)
+add_feature_info(OPUS_FLOAT_APPROX OPUS_FLOAT_APPROX ${OPUS_FLOAT_APPROX_HELP_STR})
+
+set(OPUS_INSTALL_PKG_CONFIG_MODULE_HELP_STR "install pkg-config module.")
+option(OPUS_INSTALL_PKG_CONFIG_MODULE ${OPUS_INSTALL_PKG_CONFIG_MODULE_HELP_STR} ON)
+add_feature_info(OPUS_INSTALL_PKG_CONFIG_MODULE OPUS_INSTALL_PKG_CONFIG_MODULE ${OPUS_INSTALL_PKG_CONFIG_MODULE_HELP_STR})
+
+set(OPUS_INSTALL_CMAKE_CONFIG_MODULE_HELP_STR "install CMake package config module.")
+option(OPUS_INSTALL_CMAKE_CONFIG_MODULE ${OPUS_INSTALL_CMAKE_CONFIG_MODULE_HELP_STR} ON)
+add_feature_info(OPUS_INSTALL_CMAKE_CONFIG_MODULE OPUS_INSTALL_CMAKE_CONFIG_MODULE ${OPUS_INSTALL_CMAKE_CONFIG_MODULE_HELP_STR})
+
+if(APPLE)
+ set(OPUS_BUILD_FRAMEWORK_HELP_STR "build Framework bundle for Apple systems.")
+ option(OPUS_BUILD_FRAMEWORK ${OPUS_BUILD_FRAMEWORK_HELP_STR} OFF)
+ add_feature_info(OPUS_BUILD_FRAMEWORK OPUS_BUILD_FRAMEWORK ${OPUS_BUILD_FRAMEWORK_HELP_STR})
+endif()
+
+set(OPUS_VAR_ARRAYS_HELP_STR "use variable length arrays for stack arrays.")
+cmake_dependent_option(OPUS_VAR_ARRAYS
+ ${OPUS_VAR_ARRAYS_HELP_STR}
+ ON
+ "VLA_SUPPORTED; NOT OPUS_USE_ALLOCA; NOT OPUS_NONTHREADSAFE_PSEUDOSTACK"
+ OFF)
+add_feature_info(OPUS_VAR_ARRAYS OPUS_VAR_ARRAYS ${OPUS_VAR_ARRAYS_HELP_STR})
+
+set(OPUS_USE_ALLOCA_HELP_STR "use alloca for stack arrays (on non-C99 compilers).")
+cmake_dependent_option(OPUS_USE_ALLOCA
+ ${OPUS_USE_ALLOCA_HELP_STR}
+ ON
+ "USE_ALLOCA_SUPPORTED; NOT OPUS_VAR_ARRAYS; NOT OPUS_NONTHREADSAFE_PSEUDOSTACK"
+ OFF)
+add_feature_info(OPUS_USE_ALLOCA OPUS_USE_ALLOCA ${OPUS_USE_ALLOCA_HELP_STR})
+
+set(OPUS_NONTHREADSAFE_PSEUDOSTACK_HELP_STR "use a non threadsafe pseudostack when neither variable length arrays or alloca is supported.")
+cmake_dependent_option(OPUS_NONTHREADSAFE_PSEUDOSTACK
+ ${OPUS_NONTHREADSAFE_PSEUDOSTACK_HELP_STR}
+ ON
+ "NOT OPUS_VAR_ARRAYS; NOT OPUS_USE_ALLOCA"
+ OFF)
+add_feature_info(OPUS_NONTHREADSAFE_PSEUDOSTACK OPUS_NONTHREADSAFE_PSEUDOSTACK ${OPUS_NONTHREADSAFE_PSEUDOSTACK_HELP_STR})
+
+set(OPUS_FAST_MATH_HELP_STR "enable fast math (unsupported and discouraged use, as code is not well tested with this build option).")
+cmake_dependent_option(OPUS_FAST_MATH
+ ${OPUS_FAST_MATH_HELP_STR}
+ ON
+ "OPUS_FLOAT_APPROX; OPUS_FAST_MATH; FAST_MATH_SUPPORTED"
+ OFF)
+add_feature_info(OPUS_FAST_MATH OPUS_FAST_MATH ${OPUS_FAST_MATH_HELP_STR})
+
+set(OPUS_STACK_PROTECTOR_HELP_STR "use stack protection.")
+cmake_dependent_option(OPUS_STACK_PROTECTOR
+ ${OPUS_STACK_PROTECTOR_HELP_STR}
+ ON
+ "STACK_PROTECTOR_SUPPORTED"
+ OFF)
+add_feature_info(OPUS_STACK_PROTECTOR OPUS_STACK_PROTECTOR ${OPUS_STACK_PROTECTOR_HELP_STR})
+
+if(NOT MSVC)
+ set(OPUS_FORTIFY_SOURCE_HELP_STR "add protection against buffer overflows.")
+ cmake_dependent_option(OPUS_FORTIFY_SOURCE
+ ${OPUS_FORTIFY_SOURCE_HELP_STR}
+ ON
+ "FORTIFY_SOURCE_SUPPORTED"
+ OFF)
+ add_feature_info(OPUS_FORTIFY_SOURCE OPUS_FORTIFY_SOURCE ${OPUS_FORTIFY_SOURCE_HELP_STR})
+endif()
+
+if(MINGW AND (OPUS_FORTIFY_SOURCE OR OPUS_STACK_PROTECTOR))
+ # ssp lib is needed for security features for MINGW
+ list(APPEND OPUS_REQUIRED_LIBRARIES ssp)
+endif()
+
+if(OPUS_CPU_X86 OR OPUS_CPU_X64)
+ set(OPUS_X86_MAY_HAVE_SSE_HELP_STR "does runtime check for SSE1 support.")
+ cmake_dependent_option(OPUS_X86_MAY_HAVE_SSE
+ ${OPUS_X86_MAY_HAVE_SSE_HELP_STR}
+ ON
+ "SSE1_SUPPORTED; NOT OPUS_DISABLE_INTRINSICS"
+ OFF)
+ add_feature_info(OPUS_X86_MAY_HAVE_SSE OPUS_X86_MAY_HAVE_SSE ${OPUS_X86_MAY_HAVE_SSE_HELP_STR})
+
+ set(OPUS_X86_MAY_HAVE_SSE2_HELP_STR "does runtime check for SSE2 support.")
+ cmake_dependent_option(OPUS_X86_MAY_HAVE_SSE2
+ ${OPUS_X86_MAY_HAVE_SSE2_HELP_STR}
+ ON
+ "SSE2_SUPPORTED; NOT OPUS_DISABLE_INTRINSICS"
+ OFF)
+ add_feature_info(OPUS_X86_MAY_HAVE_SSE2 OPUS_X86_MAY_HAVE_SSE2 ${OPUS_X86_MAY_HAVE_SSE2_HELP_STR})
+
+ set(OPUS_X86_MAY_HAVE_SSE4_1_HELP_STR "does runtime check for SSE4.1 support.")
+ cmake_dependent_option(OPUS_X86_MAY_HAVE_SSE4_1
+ ${OPUS_X86_MAY_HAVE_SSE4_1_HELP_STR}
+ ON
+ "SSE4_1_SUPPORTED; NOT OPUS_DISABLE_INTRINSICS"
+ OFF)
+ add_feature_info(OPUS_X86_MAY_HAVE_SSE4_1 OPUS_X86_MAY_HAVE_SSE4_1 ${OPUS_X86_MAY_HAVE_SSE4_1_HELP_STR})
+
+ set(OPUS_X86_MAY_HAVE_AVX_HELP_STR "does runtime check for AVX support.")
+ cmake_dependent_option(OPUS_X86_MAY_HAVE_AVX
+ ${OPUS_X86_MAY_HAVE_AVX_HELP_STR}
+ ON
+ "AVX_SUPPORTED; NOT OPUS_DISABLE_INTRINSICS"
+ OFF)
+ add_feature_info(OPUS_X86_MAY_HAVE_AVX OPUS_X86_MAY_HAVE_AVX ${OPUS_X86_MAY_HAVE_AVX_HELP_STR})
+
+ # PRESUME depends on MAY HAVE, but PRESUME will override runtime detection
+ set(OPUS_X86_PRESUME_SSE_HELP_STR "assume target CPU has SSE1 support (override runtime check).")
+ set(OPUS_X86_PRESUME_SSE2_HELP_STR "assume target CPU has SSE2 support (override runtime check).")
+ if(OPUS_CPU_X64) # Assume x86_64 has up to SSE2 support
+ cmake_dependent_option(OPUS_X86_PRESUME_SSE
+ ${OPUS_X86_PRESUME_SSE_HELP_STR}
+ ON
+ "OPUS_X86_MAY_HAVE_SSE; NOT OPUS_DISABLE_INTRINSICS"
+ OFF)
+
+ cmake_dependent_option(OPUS_X86_PRESUME_SSE2
+ ${OPUS_X86_PRESUME_SSE2_HELP_STR}
+ ON
+ "OPUS_X86_MAY_HAVE_SSE2; NOT OPUS_DISABLE_INTRINSICS"
+ OFF)
+ else()
+ cmake_dependent_option(OPUS_X86_PRESUME_SSE
+ ${OPUS_X86_PRESUME_SSE_HELP_STR}
+ OFF
+ "OPUS_X86_MAY_HAVE_SSE; NOT OPUS_DISABLE_INTRINSICS"
+ OFF)
+
+ cmake_dependent_option(OPUS_X86_PRESUME_SSE2
+ ${OPUS_X86_PRESUME_SSE2_HELP_STR}
+ OFF
+ "OPUS_X86_MAY_HAVE_SSE2; NOT OPUS_DISABLE_INTRINSICS"
+ OFF)
+ endif()
+ add_feature_info(OPUS_X86_PRESUME_SSE OPUS_X86_PRESUME_SSE ${OPUS_X86_PRESUME_SSE_HELP_STR})
+ add_feature_info(OPUS_X86_PRESUME_SSE2 OPUS_X86_PRESUME_SSE2 ${OPUS_X86_PRESUME_SSE2_HELP_STR})
+
+ set(OPUS_X86_PRESUME_SSE4_1_HELP_STR "assume target CPU has SSE4.1 support (override runtime check).")
+ cmake_dependent_option(OPUS_X86_PRESUME_SSE4_1
+ ${OPUS_X86_PRESUME_SSE4_1_HELP_STR}
+ OFF
+ "OPUS_X86_MAY_HAVE_SSE4_1; NOT OPUS_DISABLE_INTRINSICS"
+ OFF)
+ add_feature_info(OPUS_X86_PRESUME_SSE4_1 OPUS_X86_PRESUME_SSE4_1 ${OPUS_X86_PRESUME_SSE4_1_HELP_STR})
+
+ set(OPUS_X86_PRESUME_AVX_HELP_STR "assume target CPU has AVX support (override runtime check).")
+ cmake_dependent_option(OPUS_X86_PRESUME_AVX
+ ${OPUS_X86_PRESUME_AVX_HELP_STR}
+ OFF
+ "OPUS_X86_MAY_HAVE_AVX; NOT OPUS_DISABLE_INTRINSICS"
+ OFF)
+ add_feature_info(OPUS_X86_PRESUME_AVX OPUS_X86_PRESUME_AVX ${OPUS_X86_PRESUME_AVX_HELP_STR})
+endif()
+
+feature_summary(WHAT ALL)
+
+set_package_properties(Git
+ PROPERTIES
+ TYPE
+ REQUIRED
+ DESCRIPTION
+ "fast, scalable, distributed revision control system"
+ URL
+ "https://git-scm.com/"
+ PURPOSE
+ "required to set up package version")
+
+set(Opus_PUBLIC_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/opus.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/opus_defines.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/opus_multistream.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/opus_projection.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/include/opus_types.h)
+
+if(OPUS_CUSTOM_MODES)
+ list(APPEND Opus_PUBLIC_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/include/opus_custom.h)
+endif()
+
+add_library(opus ${opus_headers} ${opus_sources} ${opus_sources_float} ${Opus_PUBLIC_HEADER})
+add_library(Opus::opus ALIAS opus)
+
+get_library_version(OPUS_LIBRARY_VERSION OPUS_LIBRARY_VERSION_MAJOR)
+message(STATUS "Opus library version: ${OPUS_LIBRARY_VERSION}")
+
+set_target_properties(opus
+ PROPERTIES SOVERSION
+ ${OPUS_LIBRARY_VERSION_MAJOR}
+ VERSION
+ ${OPUS_LIBRARY_VERSION}
+ PUBLIC_HEADER
+ "${Opus_PUBLIC_HEADER}")
+
+target_include_directories(
+ opus
+ PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/opus>
+ PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+ ${CMAKE_CURRENT_SOURCE_DIR}
+ celt
+ silk)
+
+target_link_libraries(opus PRIVATE ${OPUS_REQUIRED_LIBRARIES})
+target_compile_definitions(opus PRIVATE OPUS_BUILD ENABLE_HARDENING)
+
+if(OPUS_FORTIFY_SOURCE AND NOT MSVC)
+ target_compile_definitions(opus PRIVATE
+ $<$<NOT:$<CONFIG:debug>>:_FORTIFY_SOURCE=2>)
+endif()
+
+if(OPUS_FLOAT_APPROX)
+ target_compile_definitions(opus PRIVATE FLOAT_APPROX)
+endif()
+
+if(OPUS_VAR_ARRAYS)
+ target_compile_definitions(opus PRIVATE VAR_ARRAYS)
+elseif(OPUS_USE_ALLOCA)
+ target_compile_definitions(opus PRIVATE USE_ALLOCA)
+elseif(OPUS_NONTHREADSAFE_PSEUDOSTACK)
+ target_compile_definitions(opus PRIVATE NONTHREADSAFE_PSEUDOSTACK)
+else()
+ message(ERROR "Need to set a define for stack allocation")
+endif()
+
+if(OPUS_CUSTOM_MODES)
+ target_compile_definitions(opus PRIVATE CUSTOM_MODES)
+endif()
+
+if(OPUS_FAST_MATH)
+ if(MSVC)
+ target_compile_options(opus PRIVATE /fp:fast)
+ else()
+ target_compile_options(opus PRIVATE -ffast-math)
+ endif()
+endif()
+
+if(OPUS_STACK_PROTECTOR)
+ if(MSVC)
+ target_compile_options(opus PRIVATE /GS)
+ else()
+ target_compile_options(opus PRIVATE -fstack-protector-strong)
+ endif()
+elseif(STACK_PROTECTOR_DISABLED_SUPPORTED)
+ target_compile_options(opus PRIVATE /GS-)
+endif()
+
+if(BUILD_SHARED_LIBS)
+ if(WIN32)
+ target_compile_definitions(opus PRIVATE DLL_EXPORT)
+ elseif(HIDDEN_VISIBILITY_SUPPORTED)
+ set_target_properties(opus PROPERTIES C_VISIBILITY_PRESET hidden)
+ endif()
+endif()
+
+add_sources_group(opus silk ${silk_headers} ${silk_sources})
+add_sources_group(opus celt ${celt_headers} ${celt_sources})
+
+if(OPUS_FIXED_POINT)
+ add_sources_group(opus silk ${silk_sources_fixed})
+ target_include_directories(opus PRIVATE silk/fixed)
+ target_compile_definitions(opus PRIVATE FIXED_POINT=1)
+else()
+ add_sources_group(opus silk ${silk_sources_float})
+ target_include_directories(opus PRIVATE silk/float)
+endif()
+
+if(NOT OPUS_ENABLE_FLOAT_API)
+ target_compile_definitions(opus PRIVATE DISABLE_FLOAT_API)
+endif()
+
+if(NOT OPUS_DISABLE_INTRINSICS)
+ if((OPUS_X86_MAY_HAVE_SSE AND NOT OPUS_X86_PRESUME_SSE) OR
+ (OPUS_X86_MAY_HAVE_SSE2 AND NOT OPUS_X86_PRESUME_SSE2) OR
+ (OPUS_X86_MAY_HAVE_SSE4_1 AND NOT OPUS_X86_PRESUME_SSE4_1) OR
+ (OPUS_X86_MAY_HAVE_AVX AND NOT OPUS_X86_PRESUME_AVX))
+ target_compile_definitions(opus PRIVATE OPUS_HAVE_RTCD)
+ endif()
+
+ if(SSE1_SUPPORTED)
+ if(OPUS_X86_MAY_HAVE_SSE)
+ add_sources_group(opus celt ${celt_sources_sse})
+ target_compile_definitions(opus PRIVATE OPUS_X86_MAY_HAVE_SSE)
+ if(NOT MSVC)
+ set_source_files_properties(${celt_sources_sse} PROPERTIES COMPILE_FLAGS -msse)
+ endif()
+ endif()
+ if(OPUS_X86_PRESUME_SSE)
+ target_compile_definitions(opus PRIVATE OPUS_X86_PRESUME_SSE)
+ if(NOT MSVC)
+ target_compile_options(opus PRIVATE -msse)
+ endif()
+ endif()
+ endif()
+
+ if(SSE2_SUPPORTED)
+ if(OPUS_X86_MAY_HAVE_SSE2)
+ add_sources_group(opus celt ${celt_sources_sse2})
+ target_compile_definitions(opus PRIVATE OPUS_X86_MAY_HAVE_SSE2)
+ if(NOT MSVC)
+ set_source_files_properties(${celt_sources_sse2} PROPERTIES COMPILE_FLAGS -msse2)
+ endif()
+ endif()
+ if(OPUS_X86_PRESUME_SSE2)
+ target_compile_definitions(opus PRIVATE OPUS_X86_PRESUME_SSE2)
+ if(NOT MSVC)
+ target_compile_options(opus PRIVATE -msse2)
+ endif()
+ endif()
+ endif()
+
+ if(SSE4_1_SUPPORTED)
+ if(OPUS_X86_MAY_HAVE_SSE4_1)
+ add_sources_group(opus celt ${celt_sources_sse4_1})
+ add_sources_group(opus silk ${silk_sources_sse4_1})
+ target_compile_definitions(opus PRIVATE OPUS_X86_MAY_HAVE_SSE4_1)
+ if(NOT MSVC)
+ set_source_files_properties(${celt_sources_sse4_1} ${silk_sources_sse4_1} PROPERTIES COMPILE_FLAGS -msse4.1)
+ endif()
+
+ if(OPUS_FIXED_POINT)
+ add_sources_group(opus silk ${silk_sources_fixed_sse4_1})
+ if(NOT MSVC)
+ set_source_files_properties(${silk_sources_fixed_sse4_1} PROPERTIES COMPILE_FLAGS -msse4.1)
+ endif()
+ endif()
+ endif()
+ if(OPUS_X86_PRESUME_SSE4_1)
+ target_compile_definitions(opus PRIVATE OPUS_X86_PRESUME_SSE4_1)
+ if(NOT MSVC)
+ target_compile_options(opus PRIVATE -msse4.1)
+ endif()
+ endif()
+ endif()
+
+ if(AVX_SUPPORTED)
+ # mostly placeholder in case of avx intrinsics is added
+ if(OPUS_X86_MAY_HAVE_AVX)
+ target_compile_definitions(opus PRIVATE OPUS_X86_MAY_HAVE_AVX)
+ endif()
+ if(OPUS_X86_PRESUME_AVX)
+ target_compile_definitions(opus PRIVATE OPUS_X86_PRESUME_AVX)
+ if(NOT MSVC)
+ target_compile_options(opus PRIVATE -mavx)
+ endif()
+ endif()
+ endif()
+
+ if(MSVC)
+ if(AVX_SUPPORTED AND OPUS_X86_PRESUME_AVX) # on 64 bit and 32 bits
+ add_definitions(/arch:AVX)
+ elseif(OPUS_CPU_X86) # if AVX not supported then set SSE flag
+ if((SSE4_1_SUPPORTED AND OPUS_X86_PRESUME_SSE4_1)
+ OR (SSE2_SUPPORTED AND OPUS_X86_PRESUME_SSE2))
+ target_compile_definitions(opus PRIVATE /arch:SSE2)
+ elseif(SSE1_SUPPORTED AND OPUS_X86_PRESUME_SSE)
+ target_compile_definitions(opus PRIVATE /arch:SSE)
+ endif()
+ endif()
+ endif()
+
+ if(CMAKE_SYSTEM_PROCESSOR MATCHES "(arm|aarch64)")
+ add_sources_group(opus celt ${celt_sources_arm})
+ endif()
+
+ if(COMPILER_SUPPORT_NEON)
+ if(OPUS_MAY_HAVE_NEON)
+ if(RUNTIME_CPU_CAPABILITY_DETECTION)
+ message(STATUS "OPUS_MAY_HAVE_NEON enabling runtime detection")
+ target_compile_definitions(opus PRIVATE OPUS_HAVE_RTCD)
+ else()
+ message(ERROR "Runtime cpu capability detection needed for MAY_HAVE_NEON")
+ endif()
+ # Do runtime check for NEON
+ target_compile_definitions(opus
+ PRIVATE
+ OPUS_ARM_MAY_HAVE_NEON
+ OPUS_ARM_MAY_HAVE_NEON_INTR)
+ endif()
+
+ add_sources_group(opus celt ${celt_sources_arm_neon_intr})
+ add_sources_group(opus silk ${silk_sources_arm_neon_intr})
+
+ # silk arm neon depends on main_Fix.h
+ target_include_directories(opus PRIVATE silk/fixed)
+
+ if(OPUS_FIXED_POINT)
+ add_sources_group(opus silk ${silk_sources_fixed_arm_neon_intr})
+ endif()
+
+ if(OPUS_PRESUME_NEON)
+ target_compile_definitions(opus
+ PRIVATE
+ OPUS_ARM_PRESUME_NEON
+ OPUS_ARM_PRESUME_NEON_INTR)
+ endif()
+ endif()
+endif()
+
+target_compile_definitions(opus
+ PRIVATE
+ $<$<BOOL:${HAVE_LRINT}>:HAVE_LRINT>
+ $<$<BOOL:${HAVE_LRINTF}>:HAVE_LRINTF>)
+
+if(OPUS_BUILD_FRAMEWORK)
+ set_target_properties(opus PROPERTIES
+ FRAMEWORK TRUE
+ FRAMEWORK_VERSION ${PROJECT_VERSION}
+ MACOSX_FRAMEWORK_IDENTIFIER org.xiph.opus
+ MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${PROJECT_VERSION}
+ MACOSX_FRAMEWORK_BUNDLE_VERSION ${PROJECT_VERSION}
+ XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
+ OUTPUT_NAME Opus)
+endif()
+
+install(TARGETS opus
+ EXPORT OpusTargets
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ FRAMEWORK DESTINATION ${CMAKE_INSTALL_PREFIX}
+ PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/opus)
+
+if(OPUS_INSTALL_PKG_CONFIG_MODULE)
+ set(prefix ${CMAKE_INSTALL_PREFIX})
+ set(exec_prefix ${CMAKE_INSTALL_PREFIX})
+ set(libdir ${CMAKE_INSTALL_FULL_LIBDIR})
+ set(includedir ${CMAKE_INSTALL_FULL_INCLUDEDIR})
+ set(VERSION ${PACKAGE_VERSION})
+ if(HAVE_LIBM)
+ set(LIBM "-lm")
+ endif()
+ configure_file(opus.pc.in opus.pc)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/opus.pc
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
+endif()
+
+if(OPUS_INSTALL_CMAKE_CONFIG_MODULE)
+ set(CPACK_GENERATOR TGZ)
+ include(CPack)
+ set(CMAKE_INSTALL_PACKAGEDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
+ install(EXPORT OpusTargets
+ NAMESPACE Opus::
+ DESTINATION ${CMAKE_INSTALL_PACKAGEDIR})
+
+ include(CMakePackageConfigHelpers)
+
+ set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR})
+ configure_package_config_file(${PROJECT_SOURCE_DIR}/cmake/OpusConfig.cmake.in
+ OpusConfig.cmake
+ INSTALL_DESTINATION
+ ${CMAKE_INSTALL_PACKAGEDIR}
+ PATH_VARS
+ INCLUDE_INSTALL_DIR
+ INSTALL_PREFIX
+ ${CMAKE_INSTALL_PREFIX})
+ write_basic_package_version_file(OpusConfigVersion.cmake
+ VERSION ${PROJECT_VERSION}
+ COMPATIBILITY SameMajorVersion)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/OpusConfig.cmake
+ ${CMAKE_CURRENT_BINARY_DIR}/OpusConfigVersion.cmake
+ DESTINATION ${CMAKE_INSTALL_PACKAGEDIR})
+endif()
+
+if(OPUS_BUILD_PROGRAMS)
+ # demo
+ if(OPUS_CUSTOM_MODES)
+ add_executable(opus_custom_demo ${opus_custom_demo_sources})
+ target_include_directories(opus_custom_demo
+ PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+ target_link_libraries(opus_custom_demo PRIVATE opus)
+ endif()
+
+ add_executable(opus_demo ${opus_demo_sources})
+ target_include_directories(opus_demo PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+ target_include_directories(opus_demo PRIVATE silk) # debug.h
+ target_include_directories(opus_demo PRIVATE celt) # arch.h
+ target_link_libraries(opus_demo PRIVATE opus ${OPUS_REQUIRED_LIBRARIES})
+
+ # compare
+ add_executable(opus_compare ${opus_compare_sources})
+ target_include_directories(opus_compare PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+ target_link_libraries(opus_compare PRIVATE opus ${OPUS_REQUIRED_LIBRARIES})
+endif()
+
+if(BUILD_TESTING)
+ enable_testing()
+
+ # tests
+ add_executable(test_opus_decode ${test_opus_decode_sources})
+ target_include_directories(test_opus_decode
+ PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+ target_link_libraries(test_opus_decode PRIVATE opus)
+ if(OPUS_FIXED_POINT)
+ target_compile_definitions(test_opus_decode PRIVATE DISABLE_FLOAT_API)
+ endif()
+ add_test(test_opus_decode test_opus_decode)
+
+ add_executable(test_opus_padding ${test_opus_padding_sources})
+ target_include_directories(test_opus_padding
+ PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+ target_link_libraries(test_opus_padding PRIVATE opus)
+ add_test(test_opus_padding test_opus_padding)
+
+ if(NOT BUILD_SHARED_LIBS)
+ # disable tests that depends on private API when building shared lib
+ add_executable(test_opus_api ${test_opus_api_sources})
+ target_include_directories(test_opus_api
+ PRIVATE ${CMAKE_CURRENT_BINARY_DIR} celt)
+ target_link_libraries(test_opus_api PRIVATE opus)
+ if(OPUS_FIXED_POINT)
+ target_compile_definitions(test_opus_api PRIVATE DISABLE_FLOAT_API)
+ endif()
+ add_test(test_opus_api test_opus_api)
+
+ add_executable(test_opus_encode ${test_opus_encode_sources})
+ target_include_directories(test_opus_encode
+ PRIVATE ${CMAKE_CURRENT_BINARY_DIR} celt)
+ target_link_libraries(test_opus_encode PRIVATE opus)
+ add_test(test_opus_encode test_opus_encode)
+ endif()
+endif()
diff --git a/METADATA b/METADATA
index d97975ca..c5500a3f 100644
--- a/METADATA
+++ b/METADATA
@@ -1,3 +1,15 @@
+name: "libopus"
+description: "Android fork of the opus library."
third_party {
+ url {
+ type: GIT
+ value: "https://gitlab.xiph.org/xiph/opus.git"
+ }
+ version: "b83dd52868326a401c8578041e3dbea439d53f11"
license_type: NOTICE
+ last_upgrade_date {
+ year: 2020
+ month: 9
+ day: 30
+ }
}
diff --git a/Makefile.am b/Makefile.am
index 9c09decd..e5213739 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -103,7 +103,8 @@ noinst_PROGRAMS = celt/tests/test_unit_cwrs32 \
tests/test_opus_decode \
tests/test_opus_encode \
tests/test_opus_padding \
- tests/test_opus_projection
+ tests/test_opus_projection \
+ trivial_example
TESTS = celt/tests/test_unit_cwrs32 \
celt/tests/test_unit_dft \
@@ -131,6 +132,9 @@ repacketizer_demo_LDADD = libopus.la $(NE10_LIBS) $(LIBM)
opus_compare_SOURCES = src/opus_compare.c
opus_compare_LDADD = $(LIBM)
+trivial_example_SOURCES = doc/trivial_example.c
+trivial_example_LDADD = libopus.la $(LIBM)
+
tests_test_opus_api_SOURCES = tests/test_opus_api.c tests/test_opus_common.h
tests_test_opus_api_LDADD = libopus.la $(NE10_LIBS) $(LIBM)
@@ -210,6 +214,16 @@ EXTRA_DIST = opus.pc.in \
opus.m4 \
Makefile.mips \
Makefile.unix \
+ CMakeLists.txt \
+ cmake/CFeatureCheck.cmake \
+ cmake/OpusBuildtype.cmake \
+ cmake/OpusConfig.cmake \
+ cmake/OpusConfig.cmake.in \
+ cmake/OpusFunctions.cmake \
+ cmake/OpusPackageVersion.cmake \
+ cmake/OpusSources.cmake \
+ cmake/config.h.cmake.in \
+ cmake/vla.c \
tests/run_vectors.sh \
celt/arm/arm2gnu.pl \
celt/arm/celt_pitch_xcorr_arm.s \
diff --git a/Makefile.mips b/Makefile.mips
index d25af8cb..e9bfc22e 100644
--- a/Makefile.mips
+++ b/Makefile.mips
@@ -12,7 +12,7 @@ CFLAGS := -DUSE_ALLOCA $(CFLAGS)
# These options affect performance
# HAVE_LRINTF: Use C99 intrinsics to speed up float-to-int conversion
-#CFLAGS := -DHAVE_LRINTF $(CFLAGS)
+CFLAGS := -DHAVE_LRINTF $(CFLAGS)
###################### END OF OPTIONS ######################
diff --git a/README b/README
index 27fddf96..4b13076f 100644
--- a/README
+++ b/README
@@ -35,7 +35,7 @@ An opus-tools package is available which provides encoding and decoding of
Ogg encapsulated Opus files and includes a number of useful features.
Opus-tools can be found at:
- https://git.xiph.org/?p=opus-tools.git
+ https://gitlab.xiph.org/xiph/opus-tools.git
or on the main Opus website:
https://opus-codec.org/
@@ -68,7 +68,7 @@ On Apple macOS, install Xcode and brew.sh, then in the Terminal enter:
1) Clone the repository:
- % git clone https://git.xiph.org/opus.git
+ % git clone https://gitlab.xiph.org/xiph/opus.git
% cd opus
2) Compiling the source
diff --git a/README.draft b/README.draft
index 8d8e24df..9c31bd02 100644
--- a/README.draft
+++ b/README.draft
@@ -7,7 +7,7 @@ If this does not work, or if you want to change the default configuration
in the Makefile.
An up-to-date implementation conforming to this standard is available in a
-Git repository at https://git.xiph.org/opus.git or on a website at:
+Git repository at https://gitlab.xiph.org/xiph/opus.git or on a website at:
https://opus-codec.org/
However, although that implementation is expected to remain conformant
with the standard, it is the code in this RFC that shall remain normative.
@@ -17,7 +17,7 @@ steps:
1) Clone the repository (latest implementation of this standard at the time
of publication)
-% git clone https://git.xiph.org/opus.git
+% git clone https://gitlab.xiph.org/xiph/opus.git
% cd opus
2) Compile
diff --git a/README.version b/README.version
index 77ed7aa4..515fea88 100644
--- a/README.version
+++ b/README.version
@@ -1,3 +1,7 @@
-URL: https://git.xiph.org/?p=opus.git;a=snapshot;h=83d5155f151ca47c9d6274ded1a7481f746b9a43;sf=tgz
-Version: 1.3
-BugComponent: 25690
+This commit is upto-date with following the commit in upstream-master
+Branch: upstream-master
+commit: b83dd52868326a401c8578041e3dbea439d53f11
+
+upstream-master is in sync with upstream project at
+URL: https://gitlab.xiph.org/xiph/opus.git
+
diff --git a/celt/arch.h b/celt/arch.h
index c627a744..3845c3a0 100644
--- a/celt/arch.h
+++ b/celt/arch.h
@@ -73,6 +73,9 @@ __attribute__((noreturn))
void celt_fatal(const char *str, const char *file, int line)
{
fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
+#if defined(_MSC_VER)
+ _set_abort_behavior( 0, _WRITE_ABORT_MSG);
+#endif
abort();
}
#endif
@@ -160,7 +163,7 @@ static OPUS_INLINE opus_int16 SAT16(opus_int32 x) {
#ifdef OPUS_ARM_PRESUME_AARCH64_NEON_INTR
#include "arm/fixed_arm64.h"
-#elif OPUS_ARM_INLINE_EDSP
+#elif defined (OPUS_ARM_INLINE_EDSP)
#include "arm/fixed_armv5e.h"
#elif defined (OPUS_ARM_INLINE_ASM)
#include "arm/fixed_armv4.h"
diff --git a/celt/arm/armcpu.c b/celt/arm/armcpu.c
index 694a63b7..cce3ae3a 100644
--- a/celt/arm/armcpu.c
+++ b/celt/arm/armcpu.c
@@ -93,6 +93,8 @@ static OPUS_INLINE opus_uint32 opus_cpu_capabilities(void){
#elif defined(__linux__)
/* Linux based */
+#include <stdio.h>
+
opus_uint32 opus_cpu_capabilities(void)
{
opus_uint32 flags = 0;
diff --git a/celt/bands.c b/celt/bands.c
index f7bb66a9..2702963c 100644
--- a/celt/bands.c
+++ b/celt/bands.c
@@ -371,14 +371,14 @@ void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_mas
static void compute_channel_weights(celt_ener Ex, celt_ener Ey, opus_val16 w[2])
{
celt_ener minE;
-#if FIXED_POINT
+#ifdef FIXED_POINT
int shift;
#endif
minE = MIN32(Ex, Ey);
/* Adjustment to make the weights a bit more conservative. */
Ex = ADD32(Ex, minE/3);
Ey = ADD32(Ey, minE/3);
-#if FIXED_POINT
+#ifdef FIXED_POINT
shift = celt_ilog2(EPSILON+MAX32(Ex, Ey))-14;
#endif
w[0] = VSHR32(Ex, shift);
diff --git a/celt/celt_decoder.c b/celt/celt_decoder.c
index e6efce93..74ca3b74 100644
--- a/celt/celt_decoder.c
+++ b/celt/celt_decoder.c
@@ -117,13 +117,19 @@ void validate_celt_decoder(CELTDecoder *st)
#ifndef CUSTOM_MODES
celt_assert(st->mode == opus_custom_mode_create(48000, 960, NULL));
celt_assert(st->overlap == 120);
+ celt_assert(st->end <= 21);
+#else
+/* From Section 4.3 in the spec: "The normal CELT layer uses 21 of those bands,
+ though Opus Custom (see Section 6.2) may use a different number of bands"
+
+ Check if it's within the maximum number of Bark frequency bands instead */
+ celt_assert(st->end <= 25);
#endif
celt_assert(st->channels == 1 || st->channels == 2);
celt_assert(st->stream_channels == 1 || st->stream_channels == 2);
celt_assert(st->downsample > 0);
celt_assert(st->start == 0 || st->start == 17);
celt_assert(st->start < st->end);
- celt_assert(st->end <= 21);
#ifdef OPUS_ARCHMASK
celt_assert(st->arch >= 0);
celt_assert(st->arch <= OPUS_ARCHMASK);
diff --git a/celt/celt_encoder.c b/celt/celt_encoder.c
index 44cb0850..d6f8afc2 100644
--- a/celt/celt_encoder.c
+++ b/celt/celt_encoder.c
@@ -1571,7 +1571,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
(tmp+4*mode->Fs)/(8*mode->Fs)-!!st->signalling));
effectiveBytes = nbCompressedBytes - nbFilledBytes;
}
- equiv_rate = ((opus_int32)nbCompressedBytes*8*50 >> (3-LM)) - (40*C+20)*((400>>LM) - 50);
+ equiv_rate = ((opus_int32)nbCompressedBytes*8*50 << (3-LM)) - (40*C+20)*((400>>LM) - 50);
if (st->bitrate != OPUS_BITRATE_MAX)
equiv_rate = IMIN(equiv_rate, st->bitrate - (40*C+20)*((400>>LM) - 50));
diff --git a/celt/ecintrin.h b/celt/ecintrin.h
index 2263cff6..66a4c36e 100644
--- a/celt/ecintrin.h
+++ b/celt/ecintrin.h
@@ -49,7 +49,11 @@
This macro should only be used for implementing ec_ilog(), if it is defined.
All other code should use EC_ILOG() instead.*/
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
+#if defined(_MSC_VER) && (_MSC_VER >= 1910)
+# include <intrin0.h> /* Improve compiler throughput. */
+#else
# include <intrin.h>
+#endif
/*In _DEBUG mode this is not an intrinsic by default.*/
# pragma intrinsic(_BitScanReverse)
diff --git a/celt/float_cast.h b/celt/float_cast.h
index f218e864..9d34976e 100644
--- a/celt/float_cast.h
+++ b/celt/float_cast.h
@@ -67,6 +67,38 @@
#include <xmmintrin.h>
static OPUS_INLINE opus_int32 float2int(float x) {return _mm_cvt_ss2si(_mm_set_ss(x));}
+#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1))
+
+ #include <xmmintrin.h>
+ static OPUS_INLINE opus_int32 float2int(float value)
+ {
+ /* _mm_load_ss will generate same code as _mm_set_ss
+ ** in _MSC_VER >= 1914 /02 so keep __mm_load__ss
+ ** for backward compatibility.
+ */
+ return _mm_cvtss_si32(_mm_load_ss(&value));
+ }
+
+#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && defined (_M_IX86)
+
+ #include <math.h>
+
+ /* Win32 doesn't seem to have these functions.
+ ** Therefore implement OPUS_INLINE versions of these functions here.
+ */
+
+ static OPUS_INLINE opus_int32
+ float2int (float flt)
+ { int intgr;
+
+ _asm
+ { fld flt
+ fistp intgr
+ } ;
+
+ return intgr ;
+ }
+
#elif defined(HAVE_LRINTF)
/* These defines enable functionality introduced with the 1999 ISO C
@@ -96,32 +128,6 @@ static OPUS_INLINE opus_int32 float2int(float x) {return _mm_cvt_ss2si(_mm_set_s
#include <math.h>
#define float2int(x) lrint(x)
-#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1))
- #include <xmmintrin.h>
-
- __inline long int float2int(float value)
- {
- return _mm_cvtss_si32(_mm_load_ss(&value));
- }
-#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && defined (_M_IX86)
- #include <math.h>
-
- /* Win32 doesn't seem to have these functions.
- ** Therefore implement OPUS_INLINE versions of these functions here.
- */
-
- __inline long int
- float2int (float flt)
- { int intgr;
-
- _asm
- { fld flt
- fistp intgr
- } ;
-
- return intgr ;
- }
-
#else
#if (defined(__GNUC__) && defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L)
diff --git a/celt/mips/celt_mipsr1.h b/celt/mips/celt_mipsr1.h
index e85661a6..c332fe04 100644
--- a/celt/mips/celt_mipsr1.h
+++ b/celt/mips/celt_mipsr1.h
@@ -53,6 +53,7 @@
#include "celt_lpc.h"
#include "vq.h"
+#define OVERRIDE_COMB_FILTER_CONST
#define OVERRIDE_comb_filter
void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
diff --git a/celt/mips/vq_mipsr1.h b/celt/mips/vq_mipsr1.h
index fd18eab7..f26a33e7 100644
--- a/celt/mips/vq_mipsr1.h
+++ b/celt/mips/vq_mipsr1.h
@@ -36,8 +36,6 @@
#include "mathops.h"
#include "arch.h"
-static void renormalise_vector_mips(celt_norm *X, int N, opus_val16 gain, int arch);
-
#define OVERRIDE_vq_exp_rotation1
static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_val16 s)
{
@@ -66,11 +64,7 @@ static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_
}
#define OVERRIDE_renormalise_vector
-
-#define renormalise_vector(X, N, gain, arch) \
- (renormalise_vector_mips(X, N, gain, arch))
-
-void renormalise_vector_mips(celt_norm *X, int N, opus_val16 gain, int arch)
+void renormalise_vector(celt_norm *X, int N, opus_val16 gain, int arch)
{
int i;
#ifdef FIXED_POINT
diff --git a/celt/os_support.h b/celt/os_support.h
index a2171971..009bf861 100644
--- a/celt/os_support.h
+++ b/celt/os_support.h
@@ -39,7 +39,6 @@
#include "opus_defines.h"
#include <string.h>
-#include <stdio.h>
#include <stdlib.h>
/** Opus wrapper for malloc(). To do your own dynamic allocation, all you need to do is replace this function and opus_free */
diff --git a/celt/rate.h b/celt/rate.h
index 852b9d6f..fad5e412 100644
--- a/celt/rate.h
+++ b/celt/rate.h
@@ -95,7 +95,7 @@ static OPUS_INLINE int pulses2bits(const CELTMode *m, int band, int LM, int puls
@param pulses Number of pulses per band (returned)
@return Total number of bits allocated
*/
-int clt_compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stero,
+int clt_compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stereo,
opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev, int signalBandwidth);
#endif
diff --git a/celt/vq.c b/celt/vq.c
index a6b5552d..8011e225 100644
--- a/celt/vq.c
+++ b/celt/vq.c
@@ -39,6 +39,10 @@
#include "rate.h"
#include "pitch.h"
+#if defined(MIPSr1_ASM)
+#include "mips/vq_mipsr1.h"
+#endif
+
#ifndef OVERRIDE_vq_exp_rotation1
static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_val16 s)
{
diff --git a/celt/vq.h b/celt/vq.h
index 0dfe6af0..45ec5591 100644
--- a/celt/vq.h
+++ b/celt/vq.h
@@ -41,10 +41,6 @@
#include "x86/vq_sse.h"
#endif
-#if defined(MIPSr1_ASM)
-#include "mips/vq_mipsr1.h"
-#endif
-
void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread);
opus_val16 op_pvq_search_c(celt_norm *X, int *iy, int K, int N, int arch);
diff --git a/celt_sources.mk b/celt_sources.mk
index b619dae3..c9dab06e 100644
--- a/celt_sources.mk
+++ b/celt_sources.mk
@@ -1,4 +1,5 @@
-CELT_SOURCES = celt/bands.c \
+CELT_SOURCES = \
+celt/bands.c \
celt/celt.c \
celt/celt_encoder.c \
celt/celt_decoder.c \
diff --git a/cmake/CFeatureCheck.cmake b/cmake/CFeatureCheck.cmake
new file mode 100644
index 00000000..08828f58
--- /dev/null
+++ b/cmake/CFeatureCheck.cmake
@@ -0,0 +1,39 @@
+# - Compile and run code to check for C features
+#
+# This functions compiles a source file under the `cmake` folder
+# and adds the corresponding `HAVE_[FILENAME]` flag to the CMake
+# environment
+#
+# c_feature_check(<FLAG> [<VARIANT>])
+#
+# - Example
+#
+# include(CFeatureCheck)
+# c_feature_check(VLA)
+
+if(__c_feature_check)
+ return()
+endif()
+set(__c_feature_check INCLUDED)
+
+function(c_feature_check FILE)
+ string(TOLOWER ${FILE} FILE)
+ string(TOUPPER ${FILE} VAR)
+ string(TOUPPER "${VAR}_SUPPORTED" FEATURE)
+ if (DEFINED ${VAR}_SUPPORTED)
+ set(${VAR}_SUPPORTED 1 PARENT_SCOPE)
+ return()
+ endif()
+
+ if (NOT DEFINED COMPILE_${FEATURE})
+ message(STATUS "Performing Test ${FEATURE}")
+ try_compile(COMPILE_${FEATURE} ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/cmake/${FILE}.c)
+ endif()
+
+ if(COMPILE_${FEATURE})
+ message(STATUS "Performing Test ${FEATURE} -- success")
+ set(${VAR}_SUPPORTED 1 PARENT_SCOPE)
+ else()
+ message(STATUS "Performing Test ${FEATURE} -- failed to compile")
+ endif()
+endfunction()
diff --git a/cmake/OpusBuildtype.cmake b/cmake/OpusBuildtype.cmake
new file mode 100644
index 00000000..557cc89b
--- /dev/null
+++ b/cmake/OpusBuildtype.cmake
@@ -0,0 +1,27 @@
+# Set a default build type if none was specified
+if(__opus_buildtype)
+ return()
+endif()
+set(__opus_buildtype INCLUDED)
+
+if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+ if(CMAKE_C_FLAGS)
+ message(STATUS "CMAKE_C_FLAGS: " ${CMAKE_C_FLAGS})
+ else()
+ set(default_build_type "Release")
+ message(
+ STATUS
+ "Setting build type to '${default_build_type}' as none was specified and no CFLAGS was exported."
+ )
+ set(CMAKE_BUILD_TYPE "${default_build_type}"
+ CACHE STRING "Choose the type of build."
+ FORCE)
+ # Set the possible values of build type for cmake-gui
+ set_property(CACHE CMAKE_BUILD_TYPE
+ PROPERTY STRINGS
+ "Debug"
+ "Release"
+ "MinSizeRel"
+ "RelWithDebInfo")
+ endif()
+endif()
diff --git a/cmake/OpusConfig.cmake b/cmake/OpusConfig.cmake
new file mode 100644
index 00000000..8d19a535
--- /dev/null
+++ b/cmake/OpusConfig.cmake
@@ -0,0 +1,104 @@
+if(__opus_config)
+ return()
+endif()
+set(__opus_config INCLUDED)
+
+include(OpusFunctions)
+
+configure_file(cmake/config.h.cmake.in config.h @ONLY)
+add_definitions(-DHAVE_CONFIG_H)
+
+set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+set_property(GLOBAL PROPERTY C_STANDARD 99)
+
+if(MSVC)
+ add_definitions(-D_CRT_SECURE_NO_WARNINGS)
+endif()
+
+include(CheckLibraryExists)
+check_library_exists(m floor "" HAVE_LIBM)
+if(HAVE_LIBM)
+ list(APPEND OPUS_REQUIRED_LIBRARIES m)
+endif()
+
+include(CFeatureCheck)
+c_feature_check(VLA)
+
+include(CheckIncludeFile)
+check_include_file(alloca.h HAVE_ALLOCA_H)
+
+include(CheckSymbolExists)
+if(HAVE_ALLOCA_H)
+ add_definitions(-DHAVE_ALLOCA_H)
+ check_symbol_exists(alloca "alloca.h" USE_ALLOCA_SUPPORTED)
+else()
+ check_symbol_exists(alloca "stdlib.h;malloc.h" USE_ALLOCA_SUPPORTED)
+endif()
+
+include(CheckFunctionExists)
+check_function_exists(lrintf HAVE_LRINTF)
+check_function_exists(lrint HAVE_LRINT)
+
+if(CMAKE_SYSTEM_PROCESSOR MATCHES "(i[0-9]86|x86|X86|amd64|AMD64|x86_64)")
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(OPUS_CPU_X64 1)
+ else()
+ set(OPUS_CPU_X86 1)
+ endif()
+elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(arm|aarch64)")
+ set(OPUS_CPU_ARM 1)
+endif()
+
+if(NOT OPUS_DISABLE_INTRINSICS)
+ opus_supports_cpu_detection(RUNTIME_CPU_CAPABILITY_DETECTION)
+endif()
+
+if(OPUS_CPU_X86 OR OPUS_CPU_X64 AND NOT OPUS_DISABLE_INTRINSICS)
+ opus_detect_sse(COMPILER_SUPPORT_SIMD)
+elseif(OPUS_CPU_ARM AND NOT OPUS_DISABLE_INTRINSICS)
+ opus_detect_neon(COMPILER_SUPPORT_NEON)
+ if(COMPILER_SUPPORT_NEON)
+ option(OPUS_USE_NEON "Option to enable NEON" ON)
+ option(OPUS_MAY_HAVE_NEON "Does runtime check for neon support" ON)
+ option(OPUS_PRESUME_NEON "Assume target CPU has NEON support" OFF)
+ if(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
+ set(OPUS_PRESUME_NEON ON)
+ elseif(CMAKE_SYSTEM_NAME MATCHES "iOS")
+ set(OPUS_PRESUME_NEON ON)
+ endif()
+ endif()
+endif()
+
+if(MSVC)
+ check_flag(FAST_MATH /fp:fast)
+ check_flag(STACK_PROTECTOR /GS)
+ check_flag(STACK_PROTECTOR_DISABLED /GS-)
+else()
+ check_flag(FAST_MATH -ffast-math)
+ check_flag(STACK_PROTECTOR -fstack-protector-strong)
+ check_flag(HIDDEN_VISIBILITY -fvisibility=hidden)
+ set(FORTIFY_SOURCE_SUPPORTED 1)
+endif()
+
+if(MINGW)
+ # For MINGW we need to link ssp lib for security features such as
+ # stack protector and fortify_sources
+ check_library_exists(ssp __stack_chk_fail "" HAVE_LIBSSP)
+ if(NOT HAVE_LIBSSP)
+ message(WARNING "Could not find libssp in MinGW, disabling STACK_PROTECTOR and FORTIFY_SOURCE")
+ set(STACK_PROTECTOR_SUPPORTED 0)
+ set(FORTIFY_SOURCE_SUPPORTED 0)
+ endif()
+endif()
+
+if(NOT MSVC)
+ set(WARNING_LIST -Wall -W -Wstrict-prototypes -Wextra -Wcast-align -Wnested-externs -Wshadow)
+ include(CheckCCompilerFlag)
+ foreach(WARNING_FLAG ${WARNING_LIST})
+ string(REPLACE - "" WARNING_VAR ${WARNING_FLAG})
+ check_c_compiler_flag(${WARNING_FLAG} ${WARNING_VAR}_SUPPORTED)
+ if(${WARNING_VAR}_SUPPORTED)
+ add_compile_options(${WARNING_FLAG})
+ endif()
+ endforeach()
+endif()
diff --git a/cmake/OpusConfig.cmake.in b/cmake/OpusConfig.cmake.in
new file mode 100644
index 00000000..0b21231d
--- /dev/null
+++ b/cmake/OpusConfig.cmake.in
@@ -0,0 +1,20 @@
+set(OPUS_VERSION @PROJECT_VERSION@)
+set(OPUS_VERSION_STRING @PROJECT_VERSION@)
+set(OPUS_VERSION_MAJOR @PROJECT_VERSION_MAJOR@)
+set(OPUS_VERSION_MINOR @PROJECT_VERSION_MINOR@)
+set(OPUS_VERSION_PATCH @PROJECT_VERSION_PATCH@)
+
+@PACKAGE_INIT@
+
+set_and_check(OPUS_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
+set(OPUS_INCLUDE_DIR ${OPUS_INCLUDE_DIR};${OPUS_INCLUDE_DIR}/opus)
+set(OPUS_INCLUDE_DIRS "@PACKAGE_INCLUDE_INSTALL_DIR@;@PACKAGE_INCLUDE_INSTALL_DIR@/opus")
+
+include(${CMAKE_CURRENT_LIST_DIR}/OpusTargets.cmake)
+
+set(OPUS_LIBRARY Opus::opus)
+set(OPUS_LIBRARIES Opus::opus)
+
+check_required_components(Opus)
+
+set(OPUS_FOUND 1)
diff --git a/cmake/OpusFunctions.cmake b/cmake/OpusFunctions.cmake
new file mode 100644
index 00000000..fcf3351f
--- /dev/null
+++ b/cmake/OpusFunctions.cmake
@@ -0,0 +1,215 @@
+if(__opus_functions)
+ return()
+endif()
+set(__opus_functions INCLUDED)
+
+function(get_library_version OPUS_LIBRARY_VERSION OPUS_LIBRARY_VERSION_MAJOR)
+ file(STRINGS configure.ac opus_lt_current_string
+ LIMIT_COUNT 1
+ REGEX "OPUS_LT_CURRENT=")
+ string(REGEX MATCH
+ "OPUS_LT_CURRENT=([0-9]*)"
+ _
+ ${opus_lt_current_string})
+ set(OPUS_LT_CURRENT ${CMAKE_MATCH_1})
+
+ file(STRINGS configure.ac opus_lt_revision_string
+ LIMIT_COUNT 1
+ REGEX "OPUS_LT_REVISION=")
+ string(REGEX MATCH
+ "OPUS_LT_REVISION=([0-9]*)"
+ _
+ ${opus_lt_revision_string})
+ set(OPUS_LT_REVISION ${CMAKE_MATCH_1})
+
+ file(STRINGS configure.ac opus_lt_age_string
+ LIMIT_COUNT 1
+ REGEX "OPUS_LT_AGE=")
+ string(REGEX MATCH
+ "OPUS_LT_AGE=([0-9]*)"
+ _
+ ${opus_lt_age_string})
+ set(OPUS_LT_AGE ${CMAKE_MATCH_1})
+
+ math(EXPR OPUS_LIBRARY_VERSION_MAJOR "${OPUS_LT_CURRENT} - ${OPUS_LT_AGE}")
+ set(OPUS_LIBRARY_VERSION_MINOR ${OPUS_LT_AGE})
+ set(OPUS_LIBRARY_VERSION_PATCH ${OPUS_LT_REVISION})
+ set(
+ OPUS_LIBRARY_VERSION
+ "${OPUS_LIBRARY_VERSION_MAJOR}.${OPUS_LIBRARY_VERSION_MINOR}.${OPUS_LIBRARY_VERSION_PATCH}"
+ PARENT_SCOPE)
+ set(OPUS_LIBRARY_VERSION_MAJOR ${OPUS_LIBRARY_VERSION_MAJOR} PARENT_SCOPE)
+endfunction()
+
+function(check_flag NAME FLAG)
+ include(CheckCCompilerFlag)
+ check_c_compiler_flag(${FLAG} ${NAME}_SUPPORTED)
+endfunction()
+
+include(CheckIncludeFile)
+# function to check if compiler supports SSE, SSE2, SSE4.1 and AVX if target
+# systems may not have SSE support then use OPUS_MAY_HAVE_SSE option if target
+# system is guaranteed to have SSE support then OPUS_PRESUME_SSE can be used to
+# skip SSE runtime check
+function(opus_detect_sse COMPILER_SUPPORT_SIMD)
+ message(STATUS "Check SIMD support by compiler")
+ check_include_file(xmmintrin.h HAVE_XMMINTRIN_H) # SSE1
+ if(HAVE_XMMINTRIN_H)
+ if(MSVC)
+ # different arch options for 32 and 64 bit target for MSVC
+ if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ check_flag(SSE1 /arch:SSE)
+ else()
+ set(SSE1_SUPPORTED
+ 1
+ PARENT_SCOPE)
+ endif()
+ else()
+ check_flag(SSE1 -msse)
+ endif()
+ else()
+ set(SSE1_SUPPORTED
+ 0
+ PARENT_SCOPE)
+ endif()
+
+ check_include_file(emmintrin.h HAVE_EMMINTRIN_H) # SSE2
+ if(HAVE_EMMINTRIN_H)
+ if(MSVC)
+ if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ check_flag(SSE2 /arch:SSE2)
+ else()
+ set(SSE2_SUPPORTED
+ 1
+ PARENT_SCOPE)
+ endif()
+ else()
+ check_flag(SSE2 -msse2)
+ endif()
+ else()
+ set(SSE2_SUPPORTED
+ 0
+ PARENT_SCOPE)
+ endif()
+
+ check_include_file(smmintrin.h HAVE_SMMINTRIN_H) # SSE4.1
+ if(HAVE_SMMINTRIN_H)
+ if(MSVC)
+ if(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ check_flag(SSE4_1 /arch:SSE2) # SSE2 and above
+ else()
+ set(SSE4_1_SUPPORTED
+ 1
+ PARENT_SCOPE)
+ endif()
+ else()
+ check_flag(SSE4_1 -msse4.1)
+ endif()
+ else()
+ set(SSE4_1_SUPPORTED
+ 0
+ PARENT_SCOPE)
+ endif()
+
+ check_include_file(immintrin.h HAVE_IMMINTRIN_H) # AVX
+ if(HAVE_IMMINTRIN_H)
+ if(MSVC)
+ check_flag(AVX /arch:AVX)
+ else()
+ check_flag(AVX -mavx)
+ endif()
+ else()
+ set(AVX_SUPPORTED
+ 0
+ PARENT_SCOPE)
+ endif()
+
+ if(SSE1_SUPPORTED OR SSE2_SUPPORTED OR SSE4_1_SUPPORTED OR AVX_SUPPORTED)
+ set(COMPILER_SUPPORT_SIMD 1 PARENT_SCOPE)
+ else()
+ message(STATUS "No SIMD support in compiler")
+ endif()
+endfunction()
+
+function(opus_detect_neon COMPILER_SUPPORT_NEON)
+ if(CMAKE_SYSTEM_PROCESSOR MATCHES "(arm|aarch64)")
+ message(STATUS "Check NEON support by compiler")
+ check_include_file(arm_neon.h HAVE_ARM_NEON_H)
+ if(HAVE_ARM_NEON_H)
+ set(COMPILER_SUPPORT_NEON ${HAVE_ARM_NEON_H} PARENT_SCOPE)
+ endif()
+ endif()
+endfunction()
+
+function(opus_supports_cpu_detection RUNTIME_CPU_CAPABILITY_DETECTION)
+ if(MSVC)
+ check_include_file(intrin.h HAVE_INTRIN_H)
+ else()
+ check_include_file(cpuid.h HAVE_CPUID_H)
+ endif()
+ if(HAVE_INTRIN_H OR HAVE_CPUID_H)
+ set(RUNTIME_CPU_CAPABILITY_DETECTION 1 PARENT_SCOPE)
+ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(arm|aarch64)")
+ # ARM cpu detection is implemented for Windows and anything
+ # using a Linux kernel (such as Android).
+ if (CMAKE_SYSTEM_NAME MATCHES "(Windows|Linux|Android)")
+ set(RUNTIME_CPU_CAPABILITY_DETECTION 1 PARENT_SCOPE)
+ endif ()
+ else()
+ set(RUNTIME_CPU_CAPABILITY_DETECTION 0 PARENT_SCOPE)
+ endif()
+endfunction()
+
+function(add_sources_group target group)
+ target_sources(${target} PRIVATE ${ARGN})
+ source_group(${group} FILES ${ARGN})
+endfunction()
+
+function(get_opus_sources SOURCE_GROUP MAKE_FILE SOURCES)
+ # read file, each item in list is one group
+ file(STRINGS ${MAKE_FILE} opus_sources)
+
+ # add wildcard for regex match
+ string(CONCAT SOURCE_GROUP ${SOURCE_GROUP} ".*$")
+
+ # find group
+ foreach(val IN LISTS opus_sources)
+ if(val MATCHES ${SOURCE_GROUP})
+ list(LENGTH val list_length)
+ if(${list_length} EQUAL 1)
+ # for tests split by '=' and clean up the rest into a list
+ string(FIND ${val} "=" index)
+ math(EXPR index "${index} + 1")
+ string(SUBSTRING ${val}
+ ${index}
+ -1
+ sources)
+ string(REPLACE " "
+ ";"
+ sources
+ ${sources})
+ else()
+ # discard the group
+ list(REMOVE_AT val 0)
+ set(sources ${val})
+ endif()
+ break()
+ endif()
+ endforeach()
+
+ list(LENGTH sources list_length)
+ if(${list_length} LESS 1)
+ message(
+ FATAL_ERROR
+ "No files parsed succesfully from ${SOURCE_GROUP} in ${MAKE_FILE}")
+ endif()
+
+ # remove trailing whitespaces
+ set(list_var "")
+ foreach(source ${sources})
+ string(STRIP "${source}" source)
+ list(APPEND list_var "${source}")
+ endforeach()
+
+ set(${SOURCES} ${list_var} PARENT_SCOPE)
+endfunction()
diff --git a/cmake/OpusPackageVersion.cmake b/cmake/OpusPackageVersion.cmake
new file mode 100644
index 00000000..447ce3b1
--- /dev/null
+++ b/cmake/OpusPackageVersion.cmake
@@ -0,0 +1,70 @@
+if(__opus_version)
+ return()
+endif()
+set(__opus_version INCLUDED)
+
+function(get_package_version PACKAGE_VERSION PROJECT_VERSION)
+
+ find_package(Git)
+ if(GIT_FOUND AND EXISTS "${CMAKE_CURRENT_LIST_DIR}/.git")
+ execute_process(COMMAND ${GIT_EXECUTABLE}
+ --git-dir=${CMAKE_CURRENT_LIST_DIR}/.git describe
+ --tags --match "v*" OUTPUT_VARIABLE OPUS_PACKAGE_VERSION)
+ if(OPUS_PACKAGE_VERSION)
+ string(STRIP ${OPUS_PACKAGE_VERSION}, OPUS_PACKAGE_VERSION)
+ string(REPLACE \n
+ ""
+ OPUS_PACKAGE_VERSION
+ ${OPUS_PACKAGE_VERSION})
+ string(REPLACE ,
+ ""
+ OPUS_PACKAGE_VERSION
+ ${OPUS_PACKAGE_VERSION})
+
+ string(SUBSTRING ${OPUS_PACKAGE_VERSION}
+ 1
+ -1
+ OPUS_PACKAGE_VERSION)
+ message(STATUS "Opus package version from git repo: ${OPUS_PACKAGE_VERSION}")
+ endif()
+
+ elseif(EXISTS "${CMAKE_CURRENT_LIST_DIR}/package_version"
+ AND NOT OPUS_PACKAGE_VERSION)
+ # Not a git repo, lets' try to parse it from package_version file if exists
+ file(STRINGS package_version OPUS_PACKAGE_VERSION
+ LIMIT_COUNT 1
+ REGEX "PACKAGE_VERSION=")
+ string(REPLACE "PACKAGE_VERSION="
+ ""
+ OPUS_PACKAGE_VERSION
+ ${OPUS_PACKAGE_VERSION})
+ string(REPLACE "\""
+ ""
+ OPUS_PACKAGE_VERSION
+ ${OPUS_PACKAGE_VERSION})
+ # In case we have a unknown dist here we just replace it with 0
+ string(REPLACE "unknown"
+ "0"
+ OPUS_PACKAGE_VERSION
+ ${OPUS_PACKAGE_VERSION})
+ message(STATUS "Opus package version from package_version file: ${OPUS_PACKAGE_VERSION}")
+ endif()
+
+ if(OPUS_PACKAGE_VERSION)
+ string(REGEX
+ REPLACE "^([0-9]+.[0-9]+\\.?([0-9]+)?).*"
+ "\\1"
+ OPUS_PROJECT_VERSION
+ ${OPUS_PACKAGE_VERSION})
+ else()
+ # fail to parse version from git and package version
+ message(WARNING "Could not get package version.")
+ set(OPUS_PACKAGE_VERSION 0)
+ set(OPUS_PROJECT_VERSION 0)
+ endif()
+
+ message(STATUS "Opus project version: ${OPUS_PROJECT_VERSION}")
+
+ set(PACKAGE_VERSION ${OPUS_PACKAGE_VERSION} PARENT_SCOPE)
+ set(PROJECT_VERSION ${OPUS_PROJECT_VERSION} PARENT_SCOPE)
+endfunction()
diff --git a/cmake/OpusSources.cmake b/cmake/OpusSources.cmake
new file mode 100644
index 00000000..01e75d1a
--- /dev/null
+++ b/cmake/OpusSources.cmake
@@ -0,0 +1,46 @@
+if(__opus_sources)
+ return()
+endif()
+set(__opus_sources INCLUDED)
+
+include(OpusFunctions)
+
+get_opus_sources(SILK_HEAD silk_headers.mk silk_headers)
+get_opus_sources(SILK_SOURCES silk_sources.mk silk_sources)
+get_opus_sources(SILK_SOURCES_FLOAT silk_sources.mk silk_sources_float)
+get_opus_sources(SILK_SOURCES_FIXED silk_sources.mk silk_sources_fixed)
+get_opus_sources(SILK_SOURCES_SSE4_1 silk_sources.mk silk_sources_sse4_1)
+get_opus_sources(SILK_SOURCES_FIXED_SSE4_1 silk_sources.mk
+ silk_sources_fixed_sse4_1)
+get_opus_sources(SILK_SOURCES_ARM_NEON_INTR silk_sources.mk
+ silk_sources_arm_neon_intr)
+get_opus_sources(SILK_SOURCES_FIXED_ARM_NEON_INTR silk_sources.mk
+ silk_sources_fixed_arm_neon_intr)
+
+get_opus_sources(OPUS_HEAD opus_headers.mk opus_headers)
+get_opus_sources(OPUS_SOURCES opus_sources.mk opus_sources)
+get_opus_sources(OPUS_SOURCES_FLOAT opus_sources.mk opus_sources_float)
+
+get_opus_sources(CELT_HEAD celt_headers.mk celt_headers)
+get_opus_sources(CELT_SOURCES celt_sources.mk celt_sources)
+get_opus_sources(CELT_SOURCES_SSE celt_sources.mk celt_sources_sse)
+get_opus_sources(CELT_SOURCES_SSE2 celt_sources.mk celt_sources_sse2)
+get_opus_sources(CELT_SOURCES_SSE4_1 celt_sources.mk celt_sources_sse4_1)
+get_opus_sources(CELT_SOURCES_ARM celt_sources.mk celt_sources_arm)
+get_opus_sources(CELT_SOURCES_ARM_ASM celt_sources.mk celt_sources_arm_asm)
+get_opus_sources(CELT_AM_SOURCES_ARM_ASM celt_sources.mk
+ celt_am_sources_arm_asm)
+get_opus_sources(CELT_SOURCES_ARM_NEON_INTR celt_sources.mk
+ celt_sources_arm_neon_intr)
+get_opus_sources(CELT_SOURCES_ARM_NE10 celt_sources.mk celt_sources_arm_ne10)
+
+get_opus_sources(opus_demo_SOURCES Makefile.am opus_demo_sources)
+get_opus_sources(opus_custom_demo_SOURCES Makefile.am opus_custom_demo_sources)
+get_opus_sources(opus_compare_SOURCES Makefile.am opus_compare_sources)
+get_opus_sources(tests_test_opus_api_SOURCES Makefile.am test_opus_api_sources)
+get_opus_sources(tests_test_opus_encode_SOURCES Makefile.am
+ test_opus_encode_sources)
+get_opus_sources(tests_test_opus_decode_SOURCES Makefile.am
+ test_opus_decode_sources)
+get_opus_sources(tests_test_opus_padding_SOURCES Makefile.am
+ test_opus_padding_sources)
diff --git a/cmake/config.h.cmake.in b/cmake/config.h.cmake.in
new file mode 100644
index 00000000..5550842c
--- /dev/null
+++ b/cmake/config.h.cmake.in
@@ -0,0 +1 @@
+#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@" \ No newline at end of file
diff --git a/cmake/vla.c b/cmake/vla.c
new file mode 100644
index 00000000..05b21197
--- /dev/null
+++ b/cmake/vla.c
@@ -0,0 +1,7 @@
+int main() {
+ static int x;
+ char a[++x];
+ a[sizeof a - 1] = 0;
+ int N;
+ return a[0];
+} \ No newline at end of file
diff --git a/configure.ac b/configure.ac
index e2921fa2..f12f0aa9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,9 +22,9 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
# For libtool.
dnl Please update these for releases.
-OPUS_LT_CURRENT=7
+OPUS_LT_CURRENT=8
OPUS_LT_REVISION=0
-OPUS_LT_AGE=7
+OPUS_LT_AGE=8
AC_SUBST(OPUS_LT_CURRENT)
AC_SUBST(OPUS_LT_REVISION)
@@ -691,6 +691,18 @@ AS_IF([test x"$enable_intrinsics" = x"yes"],[
unsigned int CPUInfo2;
unsigned int CPUInfo3;
unsigned int InfoType;
+ #if defined(__i386__) && defined(__PIC__)
+ __asm__ __volatile__ (
+ "xchg %%ebx, %1\n"
+ "cpuid\n"
+ "xchg %%ebx, %1\n":
+ "=a" (CPUInfo0),
+ "=r" (CPUInfo1),
+ "=c" (CPUInfo2),
+ "=d" (CPUInfo3) :
+ "a" (InfoType), "c" (0)
+ );
+ #else
__asm__ __volatile__ (
"cpuid":
"=a" (CPUInfo0),
@@ -699,6 +711,7 @@ AS_IF([test x"$enable_intrinsics" = x"yes"],[
"=d" (CPUInfo3) :
"a" (InfoType), "c" (0)
);
+ #endif
]])],
[get_cpuid_by_asm="yes"
AC_MSG_RESULT([Inline Assembly])
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
index 36eee0b5..6d25f1fb 100644
--- a/doc/Doxyfile.in
+++ b/doc/Doxyfile.in
@@ -1,4 +1,4 @@
-# Doxyfile 1.8.10
+# Doxyfile 1.8.18
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
@@ -101,7 +101,7 @@ EXTRACT_PRIVATE = NO
# names in lower-case letters. If set to YES, upper-case letters are also
# allowed. This is useful if you have classes or files whose names only differ
# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
+# (including Cygwin) ands Mac users are advised to set this option to NO.
# The default value is: system dependent.
CASE_SENSE_NAMES = YES
@@ -248,8 +248,8 @@ HTML_TIMESTAMP = YES
# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
# Content Delivery Network so you can quickly see the result without installing
# MathJax. However, it is strongly recommended to install a local copy of
-# MathJax from http://www.mathjax.org before deployment.
-# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# MathJax from https://www.mathjax.org before deployment.
+# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_RELPATH = https://www.mathjax.org/mathjax
@@ -326,10 +326,12 @@ PREDEFINED = OPUS_EXPORT= \
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz (see:
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
-# Bell Labs.
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
# Debian defaults to YES here, while Fedora and Homebrew default to NO.
# So we set this based on whether the graphviz package is available at
# configure time.
#
-HAVE_DOT = @HAVE_DOT@
+HAVE_DOT = @HAVE_DOT@
diff --git a/doc/build_draft.sh b/doc/build_draft.sh
index d15b22a7..14ae51dd 100755
--- a/doc/build_draft.sh
+++ b/doc/build_draft.sh
@@ -48,7 +48,16 @@ mkdir "${destdir}/src"
mkdir "${destdir}/silk"
mkdir "${destdir}/silk/float"
mkdir "${destdir}/silk/fixed"
+mkdir "${destdir}/silk/fixed/x86"
+mkdir "${destdir}/silk/fixed/arm"
+mkdir "${destdir}/silk/fixed/mips"
+mkdir "${destdir}/silk/x86"
+mkdir "${destdir}/silk/arm"
+mkdir "${destdir}/silk/mips"
mkdir "${destdir}/celt"
+mkdir "${destdir}/celt/x86"
+mkdir "${destdir}/celt/arm"
+mkdir "${destdir}/celt/mips"
mkdir "${destdir}/include"
for f in `cat "${toplevel}"/opus_sources.mk "${toplevel}"/celt_sources.mk \
"${toplevel}"/silk_sources.mk "${toplevel}"/opus_headers.mk \
@@ -82,7 +91,7 @@ cat opus_source.tar.gz| base64 | tr -d '\n' | fold -w 64 | \
#echo '</artwork>' >> opus_compare_escaped.c
#echo '</figure>' >> opus_compare_escaped.c
-if [[ ! -d ../opus_testvectors ]] ; then
+if [ ! -d ../opus_testvectors ] ; then
echo "Downloading test vectors..."
wget 'http://opus-codec.org/testvectors/opus_testvectors.tar.gz'
tar -C .. -xvzf opus_testvectors.tar.gz
diff --git a/doc/footer.html b/doc/footer.html
index ad4a9259..346c40ab 100644
--- a/doc/footer.html
+++ b/doc/footer.html
@@ -1,6 +1,10 @@
+<!-- HTML footer for doxygen 1.8.18-->
+<!-- start footer part -->
<!--BEGIN GENERATE_TREEVIEW-->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+ <ul>
<li class="footer">Generated by
- <a href="https://www.stack.nl/~dimitri/doxygen/">
+ <a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> $doxygenversion </li>
</ul>
</div>
@@ -16,7 +20,7 @@ For more information visit the <a href="https://opus-codec.org">Opus Website</a>
<td>
<address class="footer"><small>
Generated by
- <a href="https://www.stack.nl/~dimitri/doxygen/">doxygen</a>
+ <a href="http://www.doxygen.org/index.html">doxygen</a>
$doxygenversion
</small></address>
</td>
diff --git a/doc/header.html b/doc/header.html
index b2c906be..babdcf6d 100644
--- a/doc/header.html
+++ b/doc/header.html
@@ -1,18 +1,24 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!-- HTML header for doxygen 1.8.18-->
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
+<meta name="generator" content="Doxygen $doxygenversion"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
-<link href="$relpath$tabs.css" rel="stylesheet" type="text/css"/>
-<link href="$relpath$customdoxygen.css" rel="stylesheet" type="text/css" />
+<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="$relpath^jquery.js"></script>
+<script type="text/javascript" src="$relpath^dynsections.js"></script>
$treeview
$search
$mathjax
+<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
+$extrastylesheet
</head>
<body>
-<div id="top"><!-- do not remove this div! -->
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<!--BEGIN TITLEAREA-->
<div id="titlearea">
@@ -20,7 +26,7 @@ $mathjax
<tbody>
<tr style="height: 64px;">
<!--BEGIN PROJECT_LOGO-->
- <td id="projectlogo"><img alt="Logo" src="$relpath$$projectlogo"/></td>
+ <td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
<!--END PROJECT_LOGO-->
<!--BEGIN PROJECT_NAME-->
<td style="padding-left: 0.5em;">
@@ -52,3 +58,4 @@ $mathjax
</table>
</div>
<!--END TITLEAREA-->
+<!-- end header part -->
diff --git a/doc/release.txt b/doc/release.txt
index 6d3ffa23..411ab7f4 100644
--- a/doc/release.txt
+++ b/doc/release.txt
@@ -15,7 +15,7 @@
- svn commit
- Copy to archive.mozilla.org/pub/opus/
- Update checksum files there as well.
-- Add release notes to https://git.xiph.org/opus-website.git
+- Add release notes to https://gitlab.xiph.org/xiph/opus-website.git
- Update links and checksums on the downloads page.
- Add a copy of the documentation to <https://www.opus-codec.org/docs/>
and update the links.
@@ -25,7 +25,7 @@ Releases are commited to https://svn.xiph.org/releases/opus/
which propagates to downloads.xiph.org, and copied manually
to https://archive.mozilla.org/pub/opus/
-Website updates are committed to https://git.xiph.org/opus-website.git
+Website updates are committed to https://gitlab.xiph.org/xiph/opus-website.git
which propagates to https://opus-codec.org/
== Binary release ==
diff --git a/doc/trivial_example.c b/doc/trivial_example.c
index 047ca0a2..9cf435b4 100644
--- a/doc/trivial_example.c
+++ b/doc/trivial_example.c
@@ -85,7 +85,7 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}
inFile = argv[1];
- fin = fopen(inFile, "r");
+ fin = fopen(inFile, "rb");
if (fin==NULL)
{
fprintf(stderr, "failed to open input file: %s\n", strerror(errno));
@@ -101,7 +101,7 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}
outFile = argv[2];
- fout = fopen(outFile, "w");
+ fout = fopen(outFile, "wb");
if (fout==NULL)
{
fprintf(stderr, "failed to open output file: %s\n", strerror(errno));
@@ -113,14 +113,25 @@ int main(int argc, char **argv)
int i;
unsigned char pcm_bytes[MAX_FRAME_SIZE*CHANNELS*2];
int frame_size;
+ size_t samples;
/* Read a 16 bits/sample audio frame. */
- fread(pcm_bytes, sizeof(short)*CHANNELS, FRAME_SIZE, fin);
- if (feof(fin))
+ samples = fread(pcm_bytes, sizeof(short)*CHANNELS, FRAME_SIZE, fin);
+
+ /* For simplicity, only read whole frames. In a real application,
+ * we'd pad the final partial frame with zeroes, record the exact
+ * duration, and trim the decoded audio to match.
+ */
+ if (samples != FRAME_SIZE)
+ {
break;
+ }
+
/* Convert from little-endian ordering. */
for (i=0;i<CHANNELS*FRAME_SIZE;i++)
+ {
in[i]=pcm_bytes[2*i+1]<<8|pcm_bytes[2*i];
+ }
/* Encode the frame. */
nbBytes = opus_encode(encoder, in, FRAME_SIZE, cbits, MAX_PACKET_SIZE);
diff --git a/include/opus_custom.h b/include/opus_custom.h
index 41f36bf2..2227be01 100644
--- a/include/opus_custom.h
+++ b/include/opus_custom.h
@@ -178,7 +178,7 @@ OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomEncoder *opus_custom_encode
) OPUS_ARG_NONNULL(1);
-/** Destroys a an encoder state.
+/** Destroys an encoder state.
* @param[in] st <tt>OpusCustomEncoder*</tt>: State to be freed.
*/
OPUS_CUSTOM_EXPORT void opus_custom_encoder_destroy(OpusCustomEncoder *st);
@@ -286,7 +286,7 @@ OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomDecoder *opus_custom_decode
int *error
) OPUS_ARG_NONNULL(1);
-/** Destroys a an decoder state.
+/** Destroys a decoder state.
* @param[in] st <tt>OpusCustomDecoder*</tt>: State to be freed.
*/
OPUS_CUSTOM_EXPORT void opus_custom_decoder_destroy(OpusCustomDecoder *st);
diff --git a/include/opus_defines.h b/include/opus_defines.h
index fbf5d0eb..d141418b 100644
--- a/include/opus_defines.h
+++ b/include/opus_defines.h
@@ -168,6 +168,7 @@ extern "C" {
/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */
#define OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST 4046
#define OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST 4047
+#define OPUS_GET_IN_DTX_REQUEST 4049
/** Defines for the presence of extended APIs. */
#define OPUS_HAVE_OPUS_PROJECTION_H
@@ -715,6 +716,16 @@ extern "C" {
* </dl>
* @hideinitializer */
#define OPUS_GET_PHASE_INVERSION_DISABLED(x) OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, __opus_check_int_ptr(x)
+/** Gets the DTX state of the encoder.
+ * Returns whether the last encoded frame was either a comfort noise update
+ * during DTX or not encoded because of DTX.
+ * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
+ * <dl>
+ * <dt>0</dt><dd>The encoder is not in DTX.</dd>
+ * <dt>1</dt><dd>The encoder is in DTX.</dd>
+ * </dl>
+ * @hideinitializer */
+#define OPUS_GET_IN_DTX(x) OPUS_GET_IN_DTX_REQUEST, __opus_check_int_ptr(x)
/**@}*/
diff --git a/opus_sources.mk b/opus_sources.mk
index b0763f99..44153b57 100644
--- a/opus_sources.mk
+++ b/opus_sources.mk
@@ -1,4 +1,5 @@
-OPUS_SOURCES = src/opus.c \
+OPUS_SOURCES = \
+src/opus.c \
src/opus_decoder.c \
src/opus_encoder.c \
src/opus_multistream.c \
diff --git a/releases.sha2 b/releases.sha2
index 76170ac9..334976b1 100644
--- a/releases.sha2
+++ b/releases.sha2
@@ -38,8 +38,12 @@ c0e90507259cf21ce7b2c82fb9ac55367d8543dae91cc3d4d2c59afd37f44023 opus-1.2-alpha
cfafd339ccd9c5ef8d6ab15d7e1a412c054bf4cb4ecbbbcc78c12ef2def70732 opus-1.2.1.tar.gz
7f56e058c9549d03ae35511ad9e16ef6d1eb257836830d54abff0f495f17e187 opus-1.3-beta.tar.gz
96fa28598e8ccd558b297277ad59a045c551ba0e06d65a9675938e084f837669 opus-1.3-rc.tar.gz
+f6bab321fb81db984766f1e4d340a9e71a5ca2c5d4d53f4ee072e84afda271ca opus-1.3-rc2.tar.gz
+4f3d69aefdf2dbaf9825408e452a8a414ffc60494c70633560700398820dc550 opus-1.3.tar.gz
+65b58e1e25b2a114157014736a3d9dfeaad8d41be1c8179866f144a2fb44ff9d opus-1.3.1.tar.gz
94ac78ca4f74c4e43bc9fe4ec1ad0aa36f38ab90f45b0727c40dd1e96096e767 opus_testvectors-draft11.tar.gz
94ac78ca4f74c4e43bc9fe4ec1ad0aa36f38ab90f45b0727c40dd1e96096e767 opus_testvectors.tar.gz
+6b26a22f9ba87b2b836906a9bb7afec5f8e54d49553b1200382520ee6fedfa55 opus_testvectors-rfc8251.tar.gz
5d2b99757bcb628bab2611f3ed27af6f35276ce3abc96c0ed4399d6c6463dda5 opus-tools-0.1.2.tar.gz
008317297d6ce84f84992abf8cc948a048a4fa135e1d1caf429fafde8965a792 opus-tools-0.1.3.tar.gz
de80485c5afa1fd83c0e16a0dd4860470c872997a7dd0a58e99b2ee8a93e5168 opus-tools-0.1.4.tar.gz
@@ -49,7 +53,11 @@ e0f08d301555dffc417604269b5a85d2bd197f259c7d6c957f370ffd33d6d9cd opus-tools-0.1
e4e188579ea1c4e4d5066460d4a7214a7eafe3539e9a4466fdc98af41ba4a2f6 opus-tools-0.1.8.tar.gz
b1873dd78c7fbc98cf65d6e10cfddb5c2c03b3af93f922139a2104baedb4643a opus-tools-0.1.9.tar.gz
a2357532d19471b70666e0e0ec17d514246d8b3cb2eb168f68bb0f6fd372b28c opus-tools-0.1.10.tar.gz
+b4e56cb00d3e509acfba9a9b627ffd8273b876b4e2408642259f6da28fa0ff86 opus-tools-0.2.tar.gz
bd6d14e8897a2f80065ef34a516c70e74f8e00060abdbc238e79e5f99bca3e96 libopusenc-0.1.tar.gz
+02e6e0b14cbbe0569d948a46420f9c9a81d93bba32dc576a4007cbf96da68ef3 libopusenc-0.1.1.tar.gz
+c79e95eeee43a0b965e9b2c59a243763a8f8b0a7e71441df2aa9084f6171c73a libopusenc-0.2.tar.gz
+8298db61a8d3d63e41c1a80705baa8ce9ff3f50452ea7ec1c19a564fe106cbb9 libopusenc-0.2.1.tar.gz
8071b968475c1a17f54b6840d6de9d9ee20f930e827b0401abe3c4cf4f3bf30a opusfile-0.1.tar.gz
b4a678b3b6c4adfb6aff1f67ef658becfe146ea7c7ff228e99543762171557f9 opusfile-0.2.tar.gz
4248927f2c4e316ea5b84fb02bd100bfec8fa4624a6910d77f0af7f0c6cb8baa opusfile-0.3.tar.gz
@@ -63,3 +71,9 @@ b940d62beb15b5974764574b9f265481fe5b6ee16902fb705727546caf956261 opusfile-0.5.z
346967d7989bb83b05949483b76bd0f69a12c59bd8b4457e864902b52bb0ac34 opusfile-0.7.zip
2c231ed3cfaa1b3173f52d740e5bbd77d51b9dfecb87014b404917fba4b855a4 opusfile-0.8.tar.gz
89dff4342c3b789574cbea5c57f11b96d4ebe4d28ab90248c1783ea569b1e9e3 opusfile-0.8.zip
+f75fb500e40b122775ac1a71ad80c4477698842a8fe9da4a1b4a1a9f16e4e979 opusfile-0.9.tar.gz
+e9591da4d4c9e857436c2d46a28a9e470fa5355ea5a76d4d582f137d18755d36 opusfile-0.9.zip
+48e03526ba87ef9cf5f1c47b5ebe3aa195bd89b912a57060c36184a6cd19412f opusfile-0.10.tar.gz
+9d9e95d01817ecf48bf6daaea8f071f9b45bd1751ca1fc8ce50e5075eb2bc3c8 opusfile-0.10.zip
+74ce9b6cf4da103133e7b5c95df810ceb7195471e1162ed57af415fabf5603bf opusfile-0.11.tar.gz
+23c5168026c4f1fc34843650135b409d0fc8cf452508163b4ece8077256ac6ff opusfile-0.11.zip
diff --git a/silk/CNG.c b/silk/CNG.c
index ef8e38df..2a910099 100644
--- a/silk/CNG.c
+++ b/silk/CNG.c
@@ -118,6 +118,10 @@ void silk_CNG(
/* Smooth gains */
for( i = 0; i < psDec->nb_subfr; i++ ) {
psCNG->CNG_smth_Gain_Q16 += silk_SMULWB( psDecCtrl->Gains_Q16[ i ] - psCNG->CNG_smth_Gain_Q16, CNG_GAIN_SMTH_Q16 );
+ /* If the smoothed gain is 3 dB greater than this subframe's gain, use this subframe's gain to adapt faster. */
+ if( silk_SMULWW( psCNG->CNG_smth_Gain_Q16, CNG_GAIN_SMTH_THRESHOLD_Q16 ) > psDecCtrl->Gains_Q16[ i ] ) {
+ psCNG->CNG_smth_Gain_Q16 = psDecCtrl->Gains_Q16[ i ];
+ }
}
}
diff --git a/silk/MacroCount.h b/silk/MacroCount.h
index 78100ffe..dab2f57a 100644
--- a/silk/MacroCount.h
+++ b/silk/MacroCount.h
@@ -27,9 +27,9 @@ POSSIBILITY OF SUCH DAMAGE.
#ifndef SIGPROCFIX_API_MACROCOUNT_H
#define SIGPROCFIX_API_MACROCOUNT_H
-#include <stdio.h>
#ifdef silk_MACRO_COUNT
+#include <stdio.h>
#define varDefine opus_int64 ops_count = 0;
extern opus_int64 ops_count;
diff --git a/silk/NSQ_del_dec.c b/silk/NSQ_del_dec.c
index 3fd9fa0d..00e749c3 100644
--- a/silk/NSQ_del_dec.c
+++ b/silk/NSQ_del_dec.c
@@ -394,8 +394,8 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
/* Long-term shaping */
if( lag > 0 ) {
/* Symmetric, packed FIR coefficients */
- n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
- n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
+ n_LTP_Q14 = silk_SMULWB( silk_ADD_SAT32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
+ n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */
shp_lag_ptr++;
} else {
@@ -451,9 +451,9 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
/* Input minus prediction plus noise feedback */
/* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */
- tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */
+ tmp1 = silk_ADD_SAT32( n_AR_Q14, n_LF_Q14 ); /* Q14 */
tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */
- tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */
+ tmp1 = silk_SUB_SAT32( tmp2, tmp1 ); /* Q13 */
tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */
r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */
@@ -535,7 +535,7 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
/* Update states */
psSS[ 0 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 );
sLF_AR_shp_Q14 = silk_SUB32( psSS[ 0 ].Diff_Q14, n_AR_Q14 );
- psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
+ psSS[ 0 ].sLTP_shp_Q14 = silk_SUB_SAT32( sLF_AR_shp_Q14, n_LF_Q14 );
psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14;
psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14;
psSS[ 0 ].xq_Q14 = xq_Q14;
@@ -555,7 +555,7 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
/* Update states */
psSS[ 1 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 );
sLF_AR_shp_Q14 = silk_SUB32( psSS[ 1 ].Diff_Q14, n_AR_Q14 );
- psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
+ psSS[ 1 ].sLTP_shp_Q14 = silk_SUB_SAT32( sLF_AR_shp_Q14, n_LF_Q14 );
psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14;
psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14;
psSS[ 1 ].xq_Q14 = xq_Q14;
diff --git a/silk/PLC.c b/silk/PLC.c
index f8939165..4667440d 100644
--- a/silk/PLC.c
+++ b/silk/PLC.c
@@ -328,10 +328,8 @@ static OPUS_INLINE void silk_PLC_conceal(
for( j = 0; j < LTP_ORDER; j++ ) {
B_Q14[ j ] = silk_RSHIFT( silk_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 );
}
- if ( psDec->indices.signalType != TYPE_NO_VOICE_ACTIVITY ) {
- /* Gradually reduce excitation gain */
- rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 );
- }
+ /* Gradually reduce excitation gain */
+ rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 );
/* Slowly increase pitch lag */
psPLC->pitchL_Q8 = silk_SMLAWB( psPLC->pitchL_Q8, psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 );
diff --git a/silk/debug.c b/silk/debug.c
index 9253faf7..71e69cc6 100644
--- a/silk/debug.c
+++ b/silk/debug.c
@@ -30,7 +30,10 @@ POSSIBILITY OF SUCH DAMAGE.
#endif
#include "debug.h"
+
+#if SILK_DEBUG || SILK_TIC_TOC
#include "SigProc_FIX.h"
+#endif
#if SILK_TIC_TOC
diff --git a/silk/debug.h b/silk/debug.h
index 6f68c1ca..36163e47 100644
--- a/silk/debug.h
+++ b/silk/debug.h
@@ -28,28 +28,29 @@ POSSIBILITY OF SUCH DAMAGE.
#ifndef SILK_DEBUG_H
#define SILK_DEBUG_H
-#include "typedef.h"
-#include <stdio.h> /* file writing */
-#include <string.h> /* strcpy, strcmp */
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-unsigned long GetHighResolutionTime(void); /* O time in usec*/
-
/* Set to 1 to enable DEBUG_STORE_DATA() macros for dumping
* intermediate signals from the codec.
*/
#define SILK_DEBUG 0
/* Flag for using timers */
-#define SILK_TIC_TOC 0
+#define SILK_TIC_TOC 0
+#if SILK_DEBUG || SILK_TIC_TOC
+#include "typedef.h"
+#include <string.h> /* strcpy, strcmp */
+#include <stdio.h> /* file writing */
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
#if SILK_TIC_TOC
+unsigned long GetHighResolutionTime(void); /* O time in usec*/
+
#if (defined(_WIN32) || defined(_WINCE))
#include <windows.h> /* timer */
#else /* Linux or Mac*/
diff --git a/silk/decode_frame.c b/silk/decode_frame.c
index e73825b2..4f36f854 100644
--- a/silk/decode_frame.c
+++ b/silk/decode_frame.c
@@ -97,7 +97,6 @@ opus_int silk_decode_frame(
psDec->first_frame_after_reset = 0;
} else {
/* Handle packet loss by extrapolation */
- psDec->indices.signalType = psDec->prevSignalType;
silk_PLC( psDec, psDecCtrl, pOut, 1, arch );
}
diff --git a/silk/define.h b/silk/define.h
index 247cb0bf..491c86f3 100644
--- a/silk/define.h
+++ b/silk/define.h
@@ -225,6 +225,7 @@ extern "C"
/* Defines for CN generation */
#define CNG_BUF_MASK_MAX 255 /* 2^floor(log2(MAX_FRAME_LENGTH))-1 */
#define CNG_GAIN_SMTH_Q16 4634 /* 0.25^(1/4) */
+#define CNG_GAIN_SMTH_THRESHOLD_Q16 46396 /* -3 dB */
#define CNG_NLSF_SMTH_Q16 16348 /* 0.25 */
#ifdef __cplusplus
diff --git a/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h b/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h
index fcbd96c8..66eb2ed2 100644
--- a/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h
+++ b/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h
@@ -41,15 +41,14 @@ POSSIBILITY OF SUCH DAMAGE.
#define QS 14
/* Autocorrelations for a warped frequency axis */
-#define OVERRIDE_silk_warped_autocorrelation_FIX
-void silk_warped_autocorrelation_FIX(
+#define OVERRIDE_silk_warped_autocorrelation_FIX_c
+void silk_warped_autocorrelation_FIX_c(
opus_int32 *corr, /* O Result [order + 1] */
opus_int *scale, /* O Scaling of the correlation vector */
const opus_int16 *input, /* I Input data to correlate */
const opus_int warping_Q16, /* I Warping coefficient */
const opus_int length, /* I Length of input */
- const opus_int order, /* I Correlation order (even) */
- int arch /* I Run-time architecture */
+ const opus_int order /* I Correlation order (even) */
)
{
opus_int n, i, lsh;
diff --git a/silk/fixed/warped_autocorrelation_FIX.c b/silk/fixed/warped_autocorrelation_FIX.c
index 52002a11..5c79553b 100644
--- a/silk/fixed/warped_autocorrelation_FIX.c
+++ b/silk/fixed/warped_autocorrelation_FIX.c
@@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.
/* Autocorrelations for a warped frequency axis */
+#ifndef OVERRIDE_silk_warped_autocorrelation_FIX_c
void silk_warped_autocorrelation_FIX_c(
opus_int32 *corr, /* O Result [order + 1] */
opus_int *scale, /* O Scaling of the correlation vector */
@@ -88,3 +89,4 @@ void silk_warped_autocorrelation_FIX_c(
}
silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/
}
+#endif /* OVERRIDE_silk_warped_autocorrelation_FIX_c */
diff --git a/silk/float/warped_autocorrelation_FLP.c b/silk/float/warped_autocorrelation_FLP.c
index 96662767..09186e73 100644
--- a/silk/float/warped_autocorrelation_FLP.c
+++ b/silk/float/warped_autocorrelation_FLP.c
@@ -42,8 +42,8 @@ void silk_warped_autocorrelation_FLP(
{
opus_int n, i;
double tmp1, tmp2;
- double state[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
- double C[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+ double state[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
+ double C[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
/* Order must be even */
celt_assert( ( order & 1 ) == 0 );
diff --git a/silk/typedef.h b/silk/typedef.h
index 97b7e709..793d2c0c 100644
--- a/silk/typedef.h
+++ b/silk/typedef.h
@@ -67,6 +67,9 @@ __attribute__((noreturn))
static OPUS_INLINE void _silk_fatal(const char *str, const char *file, int line)
{
fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
+#if defined(_MSC_VER)
+ _set_abort_behavior( 0, _WRITE_ABORT_MSG);
+#endif
abort();
}
# define silk_assert(COND) {if (!(COND)) {silk_fatal("assertion failed: " #COND);}}
diff --git a/silk_sources.mk b/silk_sources.mk
index 67c8a4fd..d2666e66 100644
--- a/silk_sources.mk
+++ b/silk_sources.mk
@@ -77,7 +77,8 @@ silk/stereo_find_predictor.c \
silk/stereo_quant_pred.c \
silk/LPC_fit.c
-SILK_SOURCES_SSE4_1 = silk/x86/NSQ_sse4_1.c \
+SILK_SOURCES_SSE4_1 = \
+silk/x86/NSQ_sse4_1.c \
silk/x86/NSQ_del_dec_sse4_1.c \
silk/x86/x86_silk_map.c \
silk/x86/VAD_sse4_1.c \
@@ -115,7 +116,8 @@ silk/fixed/vector_ops_FIX.c \
silk/fixed/schur64_FIX.c \
silk/fixed/schur_FIX.c
-SILK_SOURCES_FIXED_SSE4_1 = silk/fixed/x86/vector_ops_FIX_sse4_1.c \
+SILK_SOURCES_FIXED_SSE4_1 = \
+silk/fixed/x86/vector_ops_FIX_sse4_1.c \
silk/fixed/x86/burg_modified_FIX_sse4_1.c
SILK_SOURCES_FIXED_ARM_NEON_INTR = \
diff --git a/src/analysis.c b/src/analysis.c
index b192ae4e..058328f0 100644
--- a/src/analysis.c
+++ b/src/analysis.c
@@ -31,7 +31,9 @@
#define ANALYSIS_C
+#ifdef MLP_TRAINING
#include <stdio.h>
+#endif
#include "mathops.h"
#include "kiss_fft.h"
@@ -249,6 +251,15 @@ void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int
if (curr_lookahead<0)
curr_lookahead += DETECT_SIZE;
+ tonal->read_subframe += len/(tonal->Fs/400);
+ while (tonal->read_subframe>=8)
+ {
+ tonal->read_subframe -= 8;
+ tonal->read_pos++;
+ }
+ if (tonal->read_pos>=DETECT_SIZE)
+ tonal->read_pos-=DETECT_SIZE;
+
/* On long frames, look at the second analysis window rather than the first. */
if (len > tonal->Fs/50 && pos != tonal->write_pos)
{
@@ -262,6 +273,8 @@ void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int
pos = DETECT_SIZE-1;
pos0 = pos;
OPUS_COPY(info_out, &tonal->info[pos], 1);
+ if (!info_out->valid)
+ return;
tonality_max = tonality_avg = info_out->tonality;
tonality_count = 1;
/* Look at the neighbouring frames and pick largest bandwidth found (to be safe). */
@@ -393,14 +406,6 @@ void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int
info_out->music_prob_max = prob_max;
/* printf("%f %f %f %f %f\n", prob_min, prob_max, prob_avg/prob_count, vad_prob, info_out->music_prob); */
- tonal->read_subframe += len/(tonal->Fs/400);
- while (tonal->read_subframe>=8)
- {
- tonal->read_subframe -= 8;
- tonal->read_pos++;
- }
- if (tonal->read_pos>=DETECT_SIZE)
- tonal->read_pos-=DETECT_SIZE;
}
static const float std_feature_bias[9] = {
@@ -420,6 +425,24 @@ static const float std_feature_bias[9] = {
#define SCALE_ENER(e) (e)
#endif
+#ifdef FIXED_POINT
+static int is_digital_silence32(const opus_val32* pcm, int frame_size, int channels, int lsb_depth)
+{
+ int silence = 0;
+ opus_val32 sample_max = 0;
+#ifdef MLP_TRAINING
+ return 0;
+#endif
+ sample_max = celt_maxabs32(pcm, frame_size*channels);
+
+ silence = (sample_max == 0);
+ (void)lsb_depth;
+ return silence;
+}
+#else
+#define is_digital_silence32(pcm, frame_size, channels, lsb_depth) is_digital_silence(pcm, frame_size, channels, lsb_depth)
+#endif
+
static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt_mode, const void *x, int len, int offset, int c1, int c2, int C, int lsb_depth, downmix_func downmix)
{
int i, b;
@@ -464,8 +487,14 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
float layer_out[MAX_NEURONS];
float below_max_pitch;
float above_max_pitch;
+ int is_silence;
SAVE_STACK;
+ if (!tonal->initialized)
+ {
+ tonal->mem_fill = 240;
+ tonal->initialized = 1;
+ }
alpha = 1.f/IMIN(10, 1+tonal->count);
alphaE = 1.f/IMIN(25, 1+tonal->count);
/* Noise floor related decay for bandwidth detection: -2.2 dB/second */
@@ -483,8 +512,6 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
}
kfft = celt_mode->mdct.kfft[0];
- if (tonal->count==0)
- tonal->mem_fill = 240;
tonal->hp_ener_accum += (float)downmix_and_resample(downmix, x,
&tonal->inmem[tonal->mem_fill], tonal->downmix_state,
IMIN(len, ANALYSIS_BUF_SIZE-tonal->mem_fill), offset, c1, c2, C, tonal->Fs);
@@ -500,6 +527,8 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
if (tonal->write_pos>=DETECT_SIZE)
tonal->write_pos-=DETECT_SIZE;
+ is_silence = is_digital_silence32(tonal->inmem, ANALYSIS_BUF_SIZE, 1, lsb_depth);
+
ALLOC(in, 480, kiss_fft_cpx);
ALLOC(out, 480, kiss_fft_cpx);
ALLOC(tonality, 240, float);
@@ -518,6 +547,16 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
&tonal->inmem[240], tonal->downmix_state, remaining,
offset+ANALYSIS_BUF_SIZE-tonal->mem_fill, c1, c2, C, tonal->Fs);
tonal->mem_fill = 240 + remaining;
+ if (is_silence)
+ {
+ /* On silence, copy the previous analysis. */
+ int prev_pos = tonal->write_pos-2;
+ if (prev_pos < 0)
+ prev_pos += DETECT_SIZE;
+ OPUS_COPY(info, &tonal->info[prev_pos], 1);
+ RESTORE_STACK;
+ return;
+ }
opus_fft(kfft, in, out, tonal->arch);
#ifndef FIXED_POINT
/* If there's any NaN on the input, the entire output will be NaN, so we only need to check one value. */
@@ -654,7 +693,7 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
tonal->lowE[b] = logE[b];
tonal->highE[b] = MIN32(tonal->lowE[b]+15, tonal->highE[b]);
}
- relativeE += (logE[b]-tonal->lowE[b])/(1e-15f + (tonal->highE[b]-tonal->lowE[b]));
+ relativeE += (logE[b]-tonal->lowE[b])/(1e-5f + (tonal->highE[b]-tonal->lowE[b]));
L1=L2=0;
for (i=0;i<NB_FRAMES;i++)
@@ -938,7 +977,6 @@ void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, co
analysis->analysis_offset -= frame_size;
}
- analysis_info->valid = 0;
tonality_get_info(analysis, analysis_info, frame_size);
}
diff --git a/src/analysis.h b/src/analysis.h
index 289c845e..0b66555f 100644
--- a/src/analysis.h
+++ b/src/analysis.h
@@ -74,6 +74,7 @@ typedef struct {
int read_pos;
int read_subframe;
float hp_ener_accum;
+ int initialized;
float rnn_state[MAX_NEURONS];
opus_val32 downmix_state[3];
AnalysisInfo info[DETECT_SIZE];
diff --git a/src/mapping_matrix.h b/src/mapping_matrix.h
index 9c20483e..98bc82df 100644
--- a/src/mapping_matrix.h
+++ b/src/mapping_matrix.h
@@ -53,7 +53,7 @@ opus_int32 mapping_matrix_get_size(int rows, int cols);
opus_int16 *mapping_matrix_get_data(const MappingMatrix *matrix);
void mapping_matrix_init(
- MappingMatrix * const st,
+ MappingMatrix * const matrix,
int rows,
int cols,
int gain,
diff --git a/src/mlp.c b/src/mlp.c
index f43a704e..964c6a98 100644
--- a/src/mlp.c
+++ b/src/mlp.c
@@ -69,22 +69,29 @@ static OPUS_INLINE float sigmoid_approx(float x)
return .5f + .5f*tansig_approx(.5f*x);
}
-void compute_dense(const DenseLayer *layer, float *output, const float *input)
+static void gemm_accum(float *out, const opus_int8 *weights, int rows, int cols, int col_stride, const float *x)
{
int i, j;
+ for (i=0;i<rows;i++)
+ {
+ for (j=0;j<cols;j++)
+ out[i] += weights[j*col_stride + i]*x[j];
+ }
+}
+
+void compute_dense(const DenseLayer *layer, float *output, const float *input)
+{
+ int i;
int N, M;
int stride;
M = layer->nb_inputs;
N = layer->nb_neurons;
stride = N;
for (i=0;i<N;i++)
- {
- /* Compute update gate. */
- float sum = layer->bias[i];
- for (j=0;j<M;j++)
- sum += layer->input_weights[j*stride + i]*input[j];
- output[i] = WEIGHTS_SCALE*sum;
- }
+ output[i] = layer->bias[i];
+ gemm_accum(output, layer->input_weights, N, M, stride, input);
+ for (i=0;i<N;i++)
+ output[i] *= WEIGHTS_SCALE;
if (layer->sigmoid) {
for (i=0;i<N;i++)
output[i] = sigmoid_approx(output[i]);
@@ -96,45 +103,41 @@ void compute_dense(const DenseLayer *layer, float *output, const float *input)
void compute_gru(const GRULayer *gru, float *state, const float *input)
{
- int i, j;
+ int i;
int N, M;
int stride;
+ float tmp[MAX_NEURONS];
float z[MAX_NEURONS];
float r[MAX_NEURONS];
float h[MAX_NEURONS];
M = gru->nb_inputs;
N = gru->nb_neurons;
stride = 3*N;
+ /* Compute update gate. */
for (i=0;i<N;i++)
- {
- /* Compute update gate. */
- float sum = gru->bias[i];
- for (j=0;j<M;j++)
- sum += gru->input_weights[j*stride + i]*input[j];
- for (j=0;j<N;j++)
- sum += gru->recurrent_weights[j*stride + i]*state[j];
- z[i] = sigmoid_approx(WEIGHTS_SCALE*sum);
- }
+ z[i] = gru->bias[i];
+ gemm_accum(z, gru->input_weights, N, M, stride, input);
+ gemm_accum(z, gru->recurrent_weights, N, N, stride, state);
for (i=0;i<N;i++)
- {
- /* Compute reset gate. */
- float sum = gru->bias[N + i];
- for (j=0;j<M;j++)
- sum += gru->input_weights[N + j*stride + i]*input[j];
- for (j=0;j<N;j++)
- sum += gru->recurrent_weights[N + j*stride + i]*state[j];
- r[i] = sigmoid_approx(WEIGHTS_SCALE*sum);
- }
+ z[i] = sigmoid_approx(WEIGHTS_SCALE*z[i]);
+
+ /* Compute reset gate. */
for (i=0;i<N;i++)
- {
- /* Compute output. */
- float sum = gru->bias[2*N + i];
- for (j=0;j<M;j++)
- sum += gru->input_weights[2*N + j*stride + i]*input[j];
- for (j=0;j<N;j++)
- sum += gru->recurrent_weights[2*N + j*stride + i]*state[j]*r[j];
- h[i] = z[i]*state[i] + (1-z[i])*tansig_approx(WEIGHTS_SCALE*sum);
- }
+ r[i] = gru->bias[N + i];
+ gemm_accum(r, &gru->input_weights[N], N, M, stride, input);
+ gemm_accum(r, &gru->recurrent_weights[N], N, N, stride, state);
+ for (i=0;i<N;i++)
+ r[i] = sigmoid_approx(WEIGHTS_SCALE*r[i]);
+
+ /* Compute output. */
+ for (i=0;i<N;i++)
+ h[i] = gru->bias[2*N + i];
+ for (i=0;i<N;i++)
+ tmp[i] = state[i] * r[i];
+ gemm_accum(h, &gru->input_weights[2*N], N, M, stride, input);
+ gemm_accum(h, &gru->recurrent_weights[2*N], N, N, stride, tmp);
+ for (i=0;i<N;i++)
+ h[i] = z[i]*state[i] + (1-z[i])*tansig_approx(WEIGHTS_SCALE*h[i]);
for (i=0;i<N;i++)
state[i] = h[i];
}
diff --git a/src/opus_encoder.c b/src/opus_encoder.c
index 1c5a8b33..7b5f0abf 100644
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -837,7 +837,7 @@ static opus_int32 compute_equiv_rate(opus_int32 bitrate, int channels,
#ifndef DISABLE_FLOAT_API
-static int is_digital_silence(const opus_val16* pcm, int frame_size, int channels, int lsb_depth)
+int is_digital_silence(const opus_val16* pcm, int frame_size, int channels, int lsb_depth)
{
int silence = 0;
opus_val32 sample_max = 0;
@@ -892,34 +892,15 @@ static opus_val32 compute_frame_energy(const opus_val16 *pcm, int frame_size, in
#endif
/* Decides if DTX should be turned on (=1) or off (=0) */
-static int decide_dtx_mode(float activity_probability, /* probability that current frame contains speech/music */
- int *nb_no_activity_frames, /* number of consecutive frames with no activity */
- opus_val32 peak_signal_energy, /* peak energy of desired signal detected so far */
- const opus_val16 *pcm, /* input pcm signal */
- int frame_size, /* frame size */
- int channels,
- int is_silence, /* only digital silence detected in this frame */
- int arch
- )
-{
- opus_val32 noise_energy;
-
- if (!is_silence)
- {
- if (activity_probability < DTX_ACTIVITY_THRESHOLD) /* is noise */
- {
- noise_energy = compute_frame_energy(pcm, frame_size, channels, arch);
+static int decide_dtx_mode(opus_int activity, /* indicates if this frame contains speech/music */
+ int *nb_no_activity_frames /* number of consecutive frames with no activity */
+ )
- /* but is sufficiently quiet */
- is_silence = peak_signal_energy >= (PSEUDO_SNR_THRESHOLD * noise_energy);
- }
- }
-
- if (is_silence)
+{
+ if (!activity)
{
/* The number of consecutive DTX frames should be within the allowed bounds */
(*nb_no_activity_frames)++;
-
if (*nb_no_activity_frames > NB_SPEECH_FRAMES_BEFORE_DTX)
{
if (*nb_no_activity_frames <= (NB_SPEECH_FRAMES_BEFORE_DTX + MAX_CONSECUTIVE_DTX))
@@ -1102,6 +1083,8 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
int analysis_read_subframe_bak=-1;
int is_silence = 0;
#endif
+ opus_int activity = VAD_NO_DECISION;
+
VARDECL(opus_val16, tmp_prefill);
ALLOC_STACK;
@@ -1140,21 +1123,19 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
if (st->silk_mode.complexity >= 7 && st->Fs>=16000)
#endif
{
- if (is_digital_silence(pcm, frame_size, st->channels, lsb_depth))
- {
- is_silence = 1;
- } else {
- analysis_read_pos_bak = st->analysis.read_pos;
- analysis_read_subframe_bak = st->analysis.read_subframe;
- run_analysis(&st->analysis, celt_mode, analysis_pcm, analysis_size, frame_size,
- c1, c2, analysis_channels, st->Fs,
- lsb_depth, downmix, &analysis_info);
- }
+ is_silence = is_digital_silence(pcm, frame_size, st->channels, lsb_depth);
+ analysis_read_pos_bak = st->analysis.read_pos;
+ analysis_read_subframe_bak = st->analysis.read_subframe;
+ run_analysis(&st->analysis, celt_mode, analysis_pcm, analysis_size, frame_size,
+ c1, c2, analysis_channels, st->Fs,
+ lsb_depth, downmix, &analysis_info);
/* Track the peak signal energy */
if (!is_silence && analysis_info.activity_probability > DTX_ACTIVITY_THRESHOLD)
st->peak_signal_energy = MAX32(MULT16_32_Q15(QCONST16(0.999f, 15), st->peak_signal_energy),
compute_frame_energy(pcm, frame_size, st->channels, st->arch));
+ } else if (st->analysis.initialized) {
+ tonality_analysis_reset(&st->analysis);
}
#else
(void)analysis_pcm;
@@ -1171,6 +1152,20 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
if (!is_silence)
st->voice_ratio = -1;
+ if (is_silence)
+ {
+ activity = !is_silence;
+ } else if (analysis_info.valid)
+ {
+ activity = analysis_info.activity_probability >= DTX_ACTIVITY_THRESHOLD;
+ if (!activity)
+ {
+ /* Mark as active if this noise frame is sufficiently loud */
+ opus_val32 noise_energy = compute_frame_energy(pcm, frame_size, st->channels, st->arch);
+ activity = st->peak_signal_energy < (PSEUDO_SNR_THRESHOLD * noise_energy);
+ }
+ }
+
st->detected_bandwidth = 0;
if (analysis_info.valid)
{
@@ -1338,6 +1333,14 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
equiv_rate = compute_equiv_rate(st->bitrate_bps, st->stream_channels, st->Fs/frame_size,
st->use_vbr, 0, st->silk_mode.complexity, st->silk_mode.packetLossPercentage);
+ /* Allow SILK DTX if DTX is enabled but the generalized DTX cannot be used,
+ e.g. because of the complexity setting or sample rate. */
+#ifndef DISABLE_FLOAT_API
+ st->silk_mode.useDTX = st->use_dtx && !(analysis_info.valid || is_silence);
+#else
+ st->silk_mode.useDTX = st->use_dtx;
+#endif
+
/* Mode selection depending on application and signal type */
if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
{
@@ -1386,13 +1389,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
if (st->silk_mode.useInBandFEC && st->silk_mode.packetLossPercentage > (128-voice_est)>>4)
st->mode = MODE_SILK_ONLY;
/* When encoding voice and DTX is enabled but the generalized DTX cannot be used,
- because of complexity and sampling frequency settings, switch to SILK DTX and
- set the encoder to SILK mode */
-#ifndef DISABLE_FLOAT_API
- st->silk_mode.useDTX = st->use_dtx && !(analysis_info.valid || is_silence);
-#else
- st->silk_mode.useDTX = st->use_dtx;
-#endif
+ use SILK in order to make use of its DTX. */
if (st->silk_mode.useDTX && voice_est > 100)
st->mode = MODE_SILK_ONLY;
#endif
@@ -1668,7 +1665,6 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
if (st->mode != MODE_CELT_ONLY)
{
opus_int32 total_bitRate, celt_rate;
- opus_int activity;
#ifdef FIXED_POINT
const opus_int16 *pcm_silk;
#else
@@ -1676,14 +1672,6 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
ALLOC(pcm_silk, st->channels*frame_size, opus_int16);
#endif
- activity = VAD_NO_DECISION;
-#ifndef DISABLE_FLOAT_API
- if( analysis_info.valid ) {
- /* Inform SILK about the Opus VAD decision */
- activity = ( analysis_info.activity_probability >= DTX_ACTIVITY_THRESHOLD );
- }
-#endif
-
/* Distribute bits between SILK and CELT */
total_bitRate = 8 * bytes_target * frame_rate;
if( st->mode == MODE_HYBRID ) {
@@ -2144,14 +2132,15 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
#ifndef DISABLE_FLOAT_API
if (st->use_dtx && (analysis_info.valid || is_silence))
{
- if (decide_dtx_mode(analysis_info.activity_probability, &st->nb_no_activity_frames,
- st->peak_signal_energy, pcm, frame_size, st->channels, is_silence, st->arch))
+ if (decide_dtx_mode(activity, &st->nb_no_activity_frames))
{
st->rangeFinal = 0;
data[0] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels);
RESTORE_STACK;
return 1;
}
+ } else {
+ st->nb_no_activity_frames = 0;
}
#endif
@@ -2629,7 +2618,6 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
goto bad_arg;
}
st->variable_duration = value;
- celt_encoder_ctl(celt_enc, OPUS_SET_EXPERT_FRAME_DURATION(value));
}
break;
case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
@@ -2726,7 +2714,33 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
ret = celt_encoder_ctl(celt_enc, OPUS_SET_ENERGY_MASK(value));
}
break;
-
+ case OPUS_GET_IN_DTX_REQUEST:
+ {
+ opus_int32 *value = va_arg(ap, opus_int32*);
+ if (!value)
+ {
+ goto bad_arg;
+ }
+ if (st->silk_mode.useDTX && (st->prev_mode == MODE_SILK_ONLY || st->prev_mode == MODE_HYBRID)) {
+ /* DTX determined by Silk. */
+ silk_encoder *silk_enc = (silk_encoder*)(void *)((char*)st+st->silk_enc_offset);
+ *value = silk_enc->state_Fxx[0].sCmn.noSpeechCounter >= NB_SPEECH_FRAMES_BEFORE_DTX;
+ /* Stereo: check second channel unless only the middle channel was encoded. */
+ if(*value == 1 && st->silk_mode.nChannelsInternal == 2 && silk_enc->prev_decode_only_middle == 0) {
+ *value = silk_enc->state_Fxx[1].sCmn.noSpeechCounter >= NB_SPEECH_FRAMES_BEFORE_DTX;
+ }
+ }
+#ifndef DISABLE_FLOAT_API
+ else if (st->use_dtx) {
+ /* DTX determined by Opus. */
+ *value = st->nb_no_activity_frames >= NB_SPEECH_FRAMES_BEFORE_DTX;
+ }
+#endif
+ else {
+ *value = 0;
+ }
+ }
+ break;
case CELT_GET_MODE_REQUEST:
{
const CELTMode ** value = va_arg(ap, const CELTMode**);
diff --git a/src/opus_multistream_decoder.c b/src/opus_multistream_decoder.c
index 562103cd..a2837c35 100644
--- a/src/opus_multistream_decoder.c
+++ b/src/opus_multistream_decoder.c
@@ -251,8 +251,11 @@ int opus_multistream_decode_native(
}
packet_offset = 0;
ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset, soft_clip);
- data += packet_offset;
- len -= packet_offset;
+ if (!do_plc)
+ {
+ data += packet_offset;
+ len -= packet_offset;
+ }
if (ret <= 0)
{
RESTORE_STACK;
@@ -487,7 +490,7 @@ int opus_multistream_decoder_ctl_va_list(OpusMSDecoder *st, int request,
OpusDecoder **value;
stream_id = va_arg(ap, opus_int32);
if (stream_id<0 || stream_id >= st->layout.nb_streams)
- ret = OPUS_BAD_ARG;
+ goto bad_arg;
value = va_arg(ap, OpusDecoder**);
if (!value)
{
diff --git a/src/opus_multistream_encoder.c b/src/opus_multistream_encoder.c
index 9cb9bf34..93204a14 100644
--- a/src/opus_multistream_encoder.c
+++ b/src/opus_multistream_encoder.c
@@ -1249,7 +1249,7 @@ int opus_multistream_encoder_ctl_va_list(OpusMSEncoder *st, int request,
OpusEncoder **value;
stream_id = va_arg(ap, opus_int32);
if (stream_id<0 || stream_id >= st->layout.nb_streams)
- ret = OPUS_BAD_ARG;
+ goto bad_arg;
value = va_arg(ap, OpusEncoder**);
if (!value)
{
diff --git a/src/opus_private.h b/src/opus_private.h
index 09783cee..5e2463f5 100644
--- a/src/opus_private.h
+++ b/src/opus_private.h
@@ -135,6 +135,7 @@ typedef void (*opus_copy_channel_out_func)(
typedef void (*downmix_func)(const void *, opus_val32 *, int, int, int, int, int);
void downmix_float(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C);
void downmix_int(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C);
+int is_digital_silence(const opus_val16* pcm, int frame_size, int channels, int lsb_depth);
int encode_size(int size, unsigned char *data);
diff --git a/tests/opus_decode_fuzzer.c b/tests/opus_decode_fuzzer.c
index 90026221..20fa1e5a 100644
--- a/tests/opus_decode_fuzzer.c
+++ b/tests/opus_decode_fuzzer.c
@@ -62,9 +62,10 @@ static void ParseToc(const uint8_t *toc, TocInfo *const info) {
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
OpusDecoder *dec;
opus_int16 *pcm;
- uint8_t *packet;
+ uint8_t *temp_data;
TocInfo toc;
- int i, err;
+ int i = 0;
+ int err = OPUS_OK;
/* Not enough data to setup the decoder (+1 for the ToC) */
if (size < SETUP_BYTE_COUNT + 1) {
@@ -75,26 +76,20 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
ParseToc(&data[SETUP_BYTE_COUNT], &toc);
dec = opus_decoder_create(toc.fs, toc.channels, &err);
- if (err != OPUS_OK | dec == NULL) {
+ if (err != OPUS_OK || dec == NULL) {
return 0;
}
pcm = (opus_int16*) malloc(sizeof(*pcm) * MAX_FRAME_SAMP * toc.channels);
- packet = (uint8_t*) calloc(MAX_PACKET, sizeof(*packet));
- i = 0;
- while (1) {
+ while (i + SETUP_BYTE_COUNT < size) {
int len, fec;
- if (i + SETUP_BYTE_COUNT >= size) {
- break;
- }
-
len = (opus_uint32) data[i ] << 24 |
(opus_uint32) data[i + 1] << 16 |
(opus_uint32) data[i + 2] << 8 |
(opus_uint32) data[i + 3];
- if (len > MAX_PACKET || len < 0) {
+ if (len > MAX_PACKET || len < 0 || i + SETUP_BYTE_COUNT + len > size) {
break;
}
@@ -102,17 +97,18 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
* Instead, byte 4 is repurposed to determine if FEC is used. */
fec = data[i + 4] & 1;
- /* Lost packet */
if (len == 0) {
+ /* Lost packet */
int frame_size;
opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&frame_size));
- (void) opus_decode(dec, NULL, size, pcm, frame_size, fec);
+ (void) opus_decode(dec, NULL, len, pcm, frame_size, fec);
} else {
- if (i + SETUP_BYTE_COUNT + len > size) {
- break;
- }
- memcpy(pcm, &data[i + SETUP_BYTE_COUNT], len);
- (void) opus_decode(dec, data, size, pcm, MAX_FRAME_SAMP, fec);
+ temp_data = (uint8_t*) malloc(len);
+ memcpy(temp_data, &data[i + SETUP_BYTE_COUNT], len);
+
+ (void) opus_decode(dec, temp_data, len, pcm, MAX_FRAME_SAMP, fec);
+
+ free(temp_data);
}
i += SETUP_BYTE_COUNT + len;
@@ -120,7 +116,6 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
opus_decoder_destroy(dec);
free(pcm);
- free(packet);
return 0;
}
diff --git a/tests/test_opus_common.h b/tests/test_opus_common.h
index 235cf1c1..d96c7d84 100644
--- a/tests/test_opus_common.h
+++ b/tests/test_opus_common.h
@@ -75,6 +75,9 @@ static OPUS_INLINE void _test_failed(const char *file, int line)
fprintf(stderr,"Please report this failure and include\n");
fprintf(stderr,"'make check SEED=%u fails %s at line %d for %s'\n",iseed,file,line,opus_get_version_string());
fprintf(stderr,"and any relevant details about your system.\n\n");
+#if defined(_MSC_VER)
+ _set_abort_behavior( 0, _WRITE_ABORT_MSG);
+#endif
abort();
}
#define test_failed() _test_failed(__FILE__, __LINE__);
diff --git a/tests/test_opus_encode.c b/tests/test_opus_encode.c
index dae49c3d..00795a1e 100644
--- a/tests/test_opus_encode.c
+++ b/tests/test_opus_encode.c
@@ -140,7 +140,7 @@ int get_frame_size_enum(int frame_size, int sampling_rate)
return frame_size_enum;
}
-void test_encode(OpusEncoder *enc, int channels, int frame_size, OpusDecoder *dec, const char* debug_info)
+int test_encode(OpusEncoder *enc, int channels, int frame_size, OpusDecoder *dec)
{
int samp_count = 0;
opus_int16 *inbuf;
@@ -148,6 +148,7 @@ void test_encode(OpusEncoder *enc, int channels, int frame_size, OpusDecoder *de
int len;
opus_int16 *outbuf;
int out_samples;
+ int ret = 0;
/* Generate input data */
inbuf = (opus_int16*)malloc(sizeof(*inbuf)*SSAMPLES);
@@ -160,16 +161,16 @@ void test_encode(OpusEncoder *enc, int channels, int frame_size, OpusDecoder *de
do {
len = opus_encode(enc, &inbuf[samp_count*channels], frame_size, packet, MAX_PACKET);
if(len<0 || len>MAX_PACKET) {
- fprintf(stderr,"%s\n",debug_info);
fprintf(stderr,"opus_encode() returned %d\n",len);
- test_failed();
+ ret = -1;
+ break;
}
out_samples = opus_decode(dec, packet, len, outbuf, MAX_FRAME_SAMP, 0);
if(out_samples!=frame_size) {
- fprintf(stderr,"%s\n",debug_info);
fprintf(stderr,"opus_decode() returned %d\n",out_samples);
- test_failed();
+ ret = -1;
+ break;
}
samp_count += frame_size;
@@ -178,6 +179,7 @@ void test_encode(OpusEncoder *enc, int channels, int frame_size, OpusDecoder *de
/* Clean up */
free(inbuf);
free(outbuf);
+ return ret;
}
void fuzz_encoder_settings(const int num_encoders, const int num_setting_changes)
@@ -205,7 +207,6 @@ void fuzz_encoder_settings(const int num_encoders, const int num_setting_changes
int prediction_disabled[3] = {0, 0, 1};
int use_dtx[2] = {0, 1};
int frame_sizes_ms_x2[9] = {5, 10, 20, 40, 80, 120, 160, 200, 240}; /* x2 to avoid 2.5 ms */
- char debug_info[512];
for (i=0; i<num_encoders; i++) {
int sampling_rate = RAND_SAMPLE(sampling_rates);
@@ -236,15 +237,6 @@ void fuzz_encoder_settings(const int num_encoders, const int num_setting_changes
int frame_size_enum = get_frame_size_enum(frame_size, sampling_rate);
force_channel = IMIN(force_channel, num_channels);
- sprintf(debug_info,
- "fuzz_encoder_settings: %d kHz, %d ch, application: %d, "
- "%d bps, force ch: %d, vbr: %d, vbr constraint: %d, complexity: %d, "
- "max bw: %d, signal: %d, inband fec: %d, pkt loss: %d%%, lsb depth: %d, "
- "pred disabled: %d, dtx: %d, (%d/2) ms\n",
- sampling_rate/1000, num_channels, application, bitrate,
- force_channel, vbr, vbr_constraint, complexity, max_bw, sig, inband_fec,
- pkt_loss, lsb_depth, pred_disabled, dtx, frame_size_ms_x2);
-
if(opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate)) != OPUS_OK) test_failed();
if(opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(force_channel)) != OPUS_OK) test_failed();
if(opus_encoder_ctl(enc, OPUS_SET_VBR(vbr)) != OPUS_OK) test_failed();
@@ -259,7 +251,17 @@ void fuzz_encoder_settings(const int num_encoders, const int num_setting_changes
if(opus_encoder_ctl(enc, OPUS_SET_DTX(dtx)) != OPUS_OK) test_failed();
if(opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(frame_size_enum)) != OPUS_OK) test_failed();
- test_encode(enc, num_channels, frame_size, dec, debug_info);
+ if(test_encode(enc, num_channels, frame_size, dec)) {
+ fprintf(stderr,
+ "fuzz_encoder_settings: %d kHz, %d ch, application: %d, "
+ "%d bps, force ch: %d, vbr: %d, vbr constraint: %d, complexity: %d, "
+ "max bw: %d, signal: %d, inband fec: %d, pkt loss: %d%%, lsb depth: %d, "
+ "pred disabled: %d, dtx: %d, (%d/2) ms\n",
+ sampling_rate/1000, num_channels, application, bitrate,
+ force_channel, vbr, vbr_constraint, complexity, max_bw, sig, inband_fec,
+ pkt_loss, lsb_depth, pred_disabled, dtx, frame_size_ms_x2);
+ test_failed();
+ }
}
opus_encoder_destroy(enc);
diff --git a/tests/test_opus_projection.c b/tests/test_opus_projection.c
index 4d622e86..5f0d672c 100644
--- a/tests/test_opus_projection.c
+++ b/tests/test_opus_projection.c
@@ -360,6 +360,8 @@ void test_encode_decode(opus_int32 bitrate, opus_int32 channels,
goto bad_cleanup;
}
+ opus_projection_decoder_destroy(st_dec);
+ opus_projection_encoder_destroy(st_enc);
free(buffer_in);
free(buffer_out);
return;
diff --git a/training/rnn_dump.py b/training/rnn_dump.py
new file mode 100755
index 00000000..c312088e
--- /dev/null
+++ b/training/rnn_dump.py
@@ -0,0 +1,66 @@
+#!/usr/bin/python
+
+from __future__ import print_function
+
+from keras.models import Sequential
+from keras.models import Model
+from keras.layers import Input
+from keras.layers import Dense
+from keras.layers import LSTM
+from keras.layers import GRU
+from keras.models import load_model
+from keras import backend as K
+import sys
+
+import numpy as np
+
+def printVector(f, vector, name):
+ v = np.reshape(vector, (-1));
+ #print('static const float ', name, '[', len(v), '] = \n', file=f)
+ f.write('static const opus_int8 {}[{}] = {{\n '.format(name, len(v)))
+ for i in range(0, len(v)):
+ f.write('{}'.format(max(-128,min(127,int(round(128*v[i]))))))
+ if (i!=len(v)-1):
+ f.write(',')
+ else:
+ break;
+ if (i%8==7):
+ f.write("\n ")
+ else:
+ f.write(" ")
+ #print(v, file=f)
+ f.write('\n};\n\n')
+ return;
+
+def binary_crossentrop2(y_true, y_pred):
+ return K.mean(2*K.abs(y_true-0.5) * K.binary_crossentropy(y_pred, y_true), axis=-1)
+
+
+#model = load_model(sys.argv[1], custom_objects={'binary_crossentrop2': binary_crossentrop2})
+main_input = Input(shape=(None, 25), name='main_input')
+x = Dense(32, activation='tanh')(main_input)
+x = GRU(24, activation='tanh', recurrent_activation='sigmoid', return_sequences=True)(x)
+x = Dense(2, activation='sigmoid')(x)
+model = Model(inputs=main_input, outputs=x)
+model.load_weights(sys.argv[1])
+
+weights = model.get_weights()
+
+f = open(sys.argv[2], 'w')
+
+f.write('/*This file is automatically generated from a Keras model*/\n\n')
+f.write('#ifdef HAVE_CONFIG_H\n#include "config.h"\n#endif\n\n#include "mlp.h"\n\n')
+
+printVector(f, weights[0], 'layer0_weights')
+printVector(f, weights[1], 'layer0_bias')
+printVector(f, weights[2], 'layer1_weights')
+printVector(f, weights[3], 'layer1_recur_weights')
+printVector(f, weights[4], 'layer1_bias')
+printVector(f, weights[5], 'layer2_weights')
+printVector(f, weights[6], 'layer2_bias')
+
+f.write('const DenseLayer layer0 = {\n layer0_bias,\n layer0_weights,\n 25, 32, 0\n};\n\n')
+f.write('const GRULayer layer1 = {\n layer1_bias,\n layer1_weights,\n layer1_recur_weights,\n 32, 24\n};\n\n')
+f.write('const DenseLayer layer2 = {\n layer2_bias,\n layer2_weights,\n 24, 2, 1\n};\n\n')
+
+f.close()
diff --git a/training/rnn_train.py b/training/rnn_train.py
new file mode 100755
index 00000000..29bcb034
--- /dev/null
+++ b/training/rnn_train.py
@@ -0,0 +1,177 @@
+#!/usr/bin/python3
+
+from __future__ import print_function
+
+from keras.models import Sequential
+from keras.models import Model
+from keras.layers import Input
+from keras.layers import Dense
+from keras.layers import LSTM
+from keras.layers import GRU
+from keras.layers import CuDNNGRU
+from keras.layers import SimpleRNN
+from keras.layers import Dropout
+from keras import losses
+import h5py
+from keras.optimizers import Adam
+
+from keras.constraints import Constraint
+from keras import backend as K
+import numpy as np
+
+import tensorflow as tf
+from keras.backend.tensorflow_backend import set_session
+config = tf.ConfigProto()
+config.gpu_options.per_process_gpu_memory_fraction = 0.44
+set_session(tf.Session(config=config))
+
+def binary_crossentrop2(y_true, y_pred):
+ return K.mean(2*K.abs(y_true-0.5) * K.binary_crossentropy(y_true, y_pred), axis=-1)
+
+def binary_accuracy2(y_true, y_pred):
+ return K.mean(K.cast(K.equal(y_true, K.round(y_pred)), 'float32') + K.cast(K.equal(y_true, 0.5), 'float32'), axis=-1)
+
+def quant_model(model):
+ weights = model.get_weights()
+ for k in range(len(weights)):
+ weights[k] = np.maximum(-128, np.minimum(127, np.round(128*weights[k])*0.0078125))
+ model.set_weights(weights)
+
+class WeightClip(Constraint):
+ '''Clips the weights incident to each hidden unit to be inside a range
+ '''
+ def __init__(self, c=2):
+ self.c = c
+
+ def __call__(self, p):
+ return K.clip(p, -self.c, self.c)
+
+ def get_config(self):
+ return {'name': self.__class__.__name__,
+ 'c': self.c}
+
+reg = 0.000001
+constraint = WeightClip(.998)
+
+print('Build model...')
+
+main_input = Input(shape=(None, 25), name='main_input')
+x = Dense(32, activation='tanh', kernel_constraint=constraint, bias_constraint=constraint)(main_input)
+#x = CuDNNGRU(24, return_sequences=True, kernel_constraint=constraint, recurrent_constraint=constraint, bias_constraint=constraint)(x)
+x = GRU(24, recurrent_activation='sigmoid', activation='tanh', return_sequences=True, kernel_constraint=constraint, recurrent_constraint=constraint, bias_constraint=constraint)(x)
+x = Dense(2, activation='sigmoid', kernel_constraint=constraint, bias_constraint=constraint)(x)
+model = Model(inputs=main_input, outputs=x)
+
+batch_size = 2048
+
+print('Loading data...')
+with h5py.File('features10b.h5', 'r') as hf:
+ all_data = hf['data'][:]
+print('done.')
+
+window_size = 1500
+
+nb_sequences = len(all_data)//window_size
+print(nb_sequences, ' sequences')
+x_train = all_data[:nb_sequences*window_size, :-2]
+x_train = np.reshape(x_train, (nb_sequences, window_size, 25))
+
+y_train = np.copy(all_data[:nb_sequences*window_size, -2:])
+y_train = np.reshape(y_train, (nb_sequences, window_size, 2))
+
+print("Marking ignores")
+for s in y_train:
+ for e in s:
+ if (e[1] >= 1):
+ break
+ e[0] = 0.5
+
+all_data = 0;
+x_train = x_train.astype('float32')
+y_train = y_train.astype('float32')
+
+print(len(x_train), 'train sequences. x shape =', x_train.shape, 'y shape = ', y_train.shape)
+
+model.load_weights('newweights10a1b_ep206.hdf5')
+
+#weights = model.get_weights()
+#for k in range(len(weights)):
+# weights[k] = np.round(128*weights[k])*0.0078125
+#model.set_weights(weights)
+
+# try using different optimizers and different optimizer configs
+model.compile(loss=binary_crossentrop2,
+ optimizer=Adam(0.0001),
+ metrics=[binary_accuracy2])
+
+print('Train...')
+quant_model(model)
+model.fit(x_train, y_train,
+ batch_size=batch_size,
+ epochs=10, validation_data=(x_train, y_train))
+model.save("newweights10a1c_ep10.hdf5")
+
+quant_model(model)
+model.fit(x_train, y_train,
+ batch_size=batch_size,
+ epochs=50, initial_epoch=10)
+model.save("newweights10a1c_ep50.hdf5")
+
+model.compile(loss=binary_crossentrop2,
+ optimizer=Adam(0.0001),
+ metrics=[binary_accuracy2])
+
+quant_model(model)
+model.fit(x_train, y_train,
+ batch_size=batch_size,
+ epochs=100, initial_epoch=50)
+model.save("newweights10a1c_ep100.hdf5")
+
+quant_model(model)
+model.fit(x_train, y_train,
+ batch_size=batch_size,
+ epochs=150, initial_epoch=100)
+model.save("newweights10a1c_ep150.hdf5")
+
+quant_model(model)
+model.fit(x_train, y_train,
+ batch_size=batch_size,
+ epochs=200, initial_epoch=150)
+model.save("newweights10a1c_ep200.hdf5")
+
+quant_model(model)
+model.fit(x_train, y_train,
+ batch_size=batch_size,
+ epochs=201, initial_epoch=200)
+model.save("newweights10a1c_ep201.hdf5")
+
+quant_model(model)
+model.fit(x_train, y_train,
+ batch_size=batch_size,
+ epochs=202, initial_epoch=201, validation_data=(x_train, y_train))
+model.save("newweights10a1c_ep202.hdf5")
+
+quant_model(model)
+model.fit(x_train, y_train,
+ batch_size=batch_size,
+ epochs=203, initial_epoch=202, validation_data=(x_train, y_train))
+model.save("newweights10a1c_ep203.hdf5")
+
+quant_model(model)
+model.fit(x_train, y_train,
+ batch_size=batch_size,
+ epochs=204, initial_epoch=203, validation_data=(x_train, y_train))
+model.save("newweights10a1c_ep204.hdf5")
+
+quant_model(model)
+model.fit(x_train, y_train,
+ batch_size=batch_size,
+ epochs=205, initial_epoch=204, validation_data=(x_train, y_train))
+model.save("newweights10a1c_ep205.hdf5")
+
+quant_model(model)
+model.fit(x_train, y_train,
+ batch_size=batch_size,
+ epochs=206, initial_epoch=205, validation_data=(x_train, y_train))
+model.save("newweights10a1c_ep206.hdf5")
+
diff --git a/training/txt2hdf5.py b/training/txt2hdf5.py
new file mode 100755
index 00000000..9c602877
--- /dev/null
+++ b/training/txt2hdf5.py
@@ -0,0 +1,12 @@
+#!/usr/bin/python
+
+from __future__ import print_function
+
+import numpy as np
+import h5py
+import sys
+
+data = np.loadtxt(sys.argv[1], dtype='float32')
+h5f = h5py.File(sys.argv[2], 'w');
+h5f.create_dataset('data', data=data)
+h5f.close()