Update libsoxr to 0.1.1
This commit is contained in:
parent
0413de548b
commit
f510d21218
|
@ -117,12 +117,10 @@ libsoxr
|
|||
The SoX Resampler library performs one-dimensional sample-rate conversion,
|
||||
by Rob Sykes.
|
||||
http://sourceforge.net/p/soxr/wiki/Home/
|
||||
Version in Audacity SVN: 0.0.5
|
||||
Version in Audacity SVN: 0.1.1
|
||||
Patches:
|
||||
* "libsoxr/configure" file: modified cmake params
|
||||
* modified .vcproj file in win\Projects\libsoxr
|
||||
|
||||
Upstream Version: 0.0.5 (although no file downloads are available yet)
|
||||
Upstream Version: 0.1.1
|
||||
|
||||
libvamp
|
||||
-------
|
||||
|
|
|
@ -1,280 +1,297 @@
|
|||
# SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
# Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
cmake_minimum_required (VERSION 2.8 FATAL_ERROR)
|
||||
|
||||
project (soxr C)
|
||||
set (DESCRIPTION_SUMMARY "One-dimensional sample-rate conversion library")
|
||||
|
||||
|
||||
|
||||
# Release versioning:
|
||||
|
||||
set (PROJECT_VERSION_MAJOR 0)
|
||||
set (PROJECT_VERSION_MINOR 0)
|
||||
set (PROJECT_VERSION_PATCH 5)
|
||||
|
||||
# For shared-object; if, since the last public release:
|
||||
# * library code changed at all: ++revision
|
||||
# * interfaces changed at all: ++current, revision = 0
|
||||
# * interfaces added: ++age
|
||||
# * interfaces removed: age = 0
|
||||
|
||||
set (SO_VERSION_CURRENT 0)
|
||||
set (SO_VERSION_REVISION 0)
|
||||
set (SO_VERSION_AGE 0)
|
||||
|
||||
|
||||
|
||||
# Main options:
|
||||
|
||||
include (CMakeDependentOption)
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set (CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
||||
endif ()
|
||||
|
||||
option (BUILD_TESTS "Build sanity-tests." OFF)
|
||||
option (BUILD_SHARED_LIBS "Build shared libraries." ON)
|
||||
option (BUILD_EXAMPLES "Build examples." OFF)
|
||||
option (WITH_OPENMP "Include OpenMP threading." ON)
|
||||
option (WITH_LSR_BINDINGS "Include a `libsamplerate'-like interface." ON)
|
||||
cmake_dependent_option (WITH_SINGLE_PRECISION "Build with single precision (for up to 20-bit accuracy)." ON
|
||||
"WITH_DOUBLE_PRECISION" ON)
|
||||
cmake_dependent_option (WITH_DOUBLE_PRECISION "Build with double precision (for up to 32-bit accuracy)." ON
|
||||
"WITH_SINGLE_PRECISION" ON)
|
||||
cmake_dependent_option (WITH_SIMD "Use SIMD (for faster single precision)." ON
|
||||
"WITH_SINGLE_PRECISION" OFF)
|
||||
cmake_dependent_option (WITH_AVFFT "Use libavcodec (LGPL) for SIMD DFT." OFF
|
||||
"WITH_SIMD;NOT WITH_PFFFT" OFF)
|
||||
cmake_dependent_option (WITH_PFFFT "Use PFFFT (BSD-like licence) for SIMD DFT." ON
|
||||
"WITH_SIMD;NOT WITH_AVFFT" OFF)
|
||||
if (UNIX)
|
||||
cmake_dependent_option (BUILD_LSR_TESTS "Build LSR tests." OFF
|
||||
"WITH_LSR_BINDINGS" OFF)
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
# Introspection:
|
||||
|
||||
list (APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
|
||||
|
||||
include (CheckFunctionExists)
|
||||
include (CheckIncludeFiles)
|
||||
include (CheckLibraryExists)
|
||||
include (TestBigEndian)
|
||||
|
||||
check_library_exists (m pow "" NEED_LIBM)
|
||||
if (NEED_LIBM)
|
||||
set (CMAKE_REQUIRED_LIBRARIES "m;${CMAKE_REQUIRED_LIBRARIES}")
|
||||
link_libraries (m)
|
||||
endif ()
|
||||
|
||||
if (WITH_OPENMP)
|
||||
find_package (OpenMP)
|
||||
endif ()
|
||||
if (OPENMP_FOUND)
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
|
||||
endif ()
|
||||
|
||||
if (WITH_SIMD)
|
||||
find_package (SIMD)
|
||||
if (SIMD_FOUND)
|
||||
set (HAVE_SIMD 1)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (WITH_SINGLE_PRECISION)
|
||||
set (HAVE_SINGLE_PRECISION 1)
|
||||
endif ()
|
||||
|
||||
if (WITH_DOUBLE_PRECISION)
|
||||
set (HAVE_DOUBLE_PRECISION 1)
|
||||
endif ()
|
||||
|
||||
if (WITH_AVFFT)
|
||||
find_package (LibAVCodec)
|
||||
if (AVCODEC_FOUND)
|
||||
include_directories (${AVCODEC_INCLUDE_DIRS})
|
||||
link_libraries (${AVCODEC_LIBRARIES})
|
||||
set (HAVE_AVFFT 1)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (EXISTS ${PROJECT_SOURCE_DIR}/src/vr32.c)
|
||||
set (HAVE_VR 1)
|
||||
endif ()
|
||||
|
||||
check_function_exists (lrint HAVE_LRINT)
|
||||
check_include_files (fenv.h HAVE_FENV_H)
|
||||
test_big_endian (WORDS_BIGENDIAN)
|
||||
|
||||
macro (make_exist)
|
||||
foreach (x ${ARGN})
|
||||
if (NOT ${x})
|
||||
set (${x} 0)
|
||||
endif ()
|
||||
endforeach ()
|
||||
endmacro ()
|
||||
|
||||
make_exist (HAVE_LRINT HAVE_FENV_H WORDS_BIGENDIAN HAVE_SIMD HAVE_VR)
|
||||
make_exist (HAVE_SINGLE_PRECISION HAVE_DOUBLE_PRECISION HAVE_AVFFT)
|
||||
|
||||
|
||||
|
||||
# Compiler configuration:
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||
set (PROJECT_CXX_FLAGS "-Wconversion -Wall -W -pedantic -Wundef -Wcast-align -Wpointer-arith -Wno-long-long")
|
||||
set (PROJECT_C_FLAGS "${PROJECT_CXX_FLAGS} -Wnested-externs -Wmissing-prototypes -Wstrict-prototypes")
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set (CMAKE_SHARED_LINKER_FLAGS "-s") # strip
|
||||
endif ()
|
||||
#option (VISIBILITY_HIDDEN "Build with -fvisibility=hidden." ON)
|
||||
if (VISIBILITY_HIDDEN)
|
||||
add_definitions (-fvisibility=hidden)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (MSVC)
|
||||
add_definitions (-D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS)
|
||||
option (ENABLE_STATIC_RUNTIME "Visual Studio, link with runtime statically." OFF)
|
||||
if (ENABLE_STATIC_RUNTIME)
|
||||
foreach (flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
string (REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
|
||||
endforeach ()
|
||||
endif ()
|
||||
# By default, do not warn when built on machines using only VS Express:
|
||||
if (NOT DEFINED CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
|
||||
set (CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
# Build configuration:
|
||||
|
||||
if (${BUILD_SHARED_LIBS} AND ${CMAKE_SYSTEM_NAME} STREQUAL Windows) # Allow exes to find dlls:
|
||||
set (BIN ${PROJECT_BINARY_DIR}/bin/)
|
||||
set (EXAMPLES_BIN ${BIN})
|
||||
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${BIN})
|
||||
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BIN})
|
||||
else ()
|
||||
set (BIN ./)
|
||||
set (EXAMPLES_BIN ../examples/)
|
||||
endif ()
|
||||
|
||||
set (LIB_TYPE STATIC)
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set (LIB_TYPE SHARED)
|
||||
if (MSVC)
|
||||
add_definitions (-DSOXR_DLL)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
# Installation configuration:
|
||||
|
||||
set (LIB_SUFFIX "" CACHE STRING "Define suffix of libraries directory name (32 or 64).")
|
||||
set (BIN_INSTALL_DIR "bin" CACHE PATH "The subdirectory to the binaries." FORCE)
|
||||
set (LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "The subdirectory to the libraries." FORCE)
|
||||
set (INCLUDE_INSTALL_DIR "include" CACHE PATH "The subdirectory to the headers." FORCE)
|
||||
|
||||
if (APPLE)
|
||||
option (BUILD_FRAMEWORK "Build an OS X framework." OFF)
|
||||
set (FRAMEWORK_INSTALL_DIR "/Library/Frameworks" CACHE STRING "Directory to install frameworks to.")
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
# Top-level:
|
||||
|
||||
set (PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH})
|
||||
math (EXPR SO_VERSION_MAJOR "${SO_VERSION_CURRENT} - ${SO_VERSION_AGE}")
|
||||
math (EXPR SO_VERSION_MINOR "${SO_VERSION_AGE}")
|
||||
math (EXPR SO_VERSION_PATCH "${SO_VERSION_REVISION}")
|
||||
set (SO_VERSION ${SO_VERSION_MAJOR}.${SO_VERSION_MINOR}.${SO_VERSION_PATCH})
|
||||
|
||||
configure_file (
|
||||
${PROJECT_SOURCE_DIR}/${PROJECT_NAME}-config.h.in
|
||||
${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.h)
|
||||
include_directories (${PROJECT_BINARY_DIR})
|
||||
|
||||
if (BUILD_TESTS OR BUILD_LSR_TESTS)
|
||||
enable_testing ()
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
# Subdirectories:
|
||||
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src)
|
||||
|
||||
add_subdirectory (src)
|
||||
if (BUILD_TESTS)
|
||||
add_subdirectory (tests)
|
||||
endif ()
|
||||
if (BUILD_LSR_TESTS)
|
||||
add_subdirectory (lsr-tests)
|
||||
endif ()
|
||||
if (BUILD_EXAMPLES OR BUILD_TESTS)
|
||||
add_subdirectory (examples)
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
# Rough-and-ready distclean for anyone still doing in-tree builds:
|
||||
|
||||
if (UNIX)
|
||||
add_custom_target (distclean
|
||||
COMMAND make clean && rm -rf
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
cmake_install.cmake
|
||||
CPackConfig.cmake
|
||||
CPackSourceConfig.cmake
|
||||
deinstall.cmake
|
||||
Makefile
|
||||
soxr-config.h
|
||||
src/CMakeFiles
|
||||
src/cmake_install.cmake
|
||||
src/libsoxr-dev.src
|
||||
src/libsoxr-lsr.pc
|
||||
src/libsoxr.pc
|
||||
src/libsoxr.src
|
||||
src/Makefile)
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
# Deinstallation:
|
||||
|
||||
configure_file (
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/deinstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/deinstall.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target (deinstall
|
||||
COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/deinstall.cmake")
|
||||
|
||||
|
||||
|
||||
# Packaging:
|
||||
|
||||
if (UNIX)
|
||||
set (CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
|
||||
set (CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
|
||||
set (CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
|
||||
|
||||
set (CPACK_SOURCE_GENERATOR "TBZ2")
|
||||
set (CPACK_SOURCE_IGNORE_FILES "/Debug/;/Release/;/cpack/;\\\\.swp$;\\\\.gitignore")
|
||||
|
||||
include (CPack)
|
||||
|
||||
if (IS_DIRECTORY ${PROJECT_SOURCE_DIR}/cpack)
|
||||
add_subdirectory (cpack)
|
||||
endif ()
|
||||
endif ()
|
||||
# SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
# Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
cmake_minimum_required (VERSION 2.8 FATAL_ERROR)
|
||||
|
||||
project (soxr C)
|
||||
set (DESCRIPTION_SUMMARY "High quality, one-dimensional sample-rate conversion library")
|
||||
|
||||
|
||||
|
||||
# Release versioning:
|
||||
|
||||
set (PROJECT_VERSION_MAJOR 0)
|
||||
set (PROJECT_VERSION_MINOR 1)
|
||||
set (PROJECT_VERSION_PATCH 1)
|
||||
|
||||
# For shared-object; if, since the last public release:
|
||||
# * library code changed at all: ++revision
|
||||
# * interfaces changed at all: ++current, revision = 0
|
||||
# * interfaces added: ++age
|
||||
# * interfaces removed: age = 0
|
||||
|
||||
set (SO_VERSION_CURRENT 1)
|
||||
set (SO_VERSION_REVISION 0)
|
||||
set (SO_VERSION_AGE 1)
|
||||
|
||||
|
||||
|
||||
# Main options:
|
||||
|
||||
include (CMakeDependentOption)
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set (CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
||||
endif ()
|
||||
|
||||
option (BUILD_TESTS "Build sanity-tests." ON)
|
||||
option (BUILD_SHARED_LIBS "Build shared libraries." ON)
|
||||
option (BUILD_EXAMPLES "Build examples." OFF)
|
||||
option (WITH_OPENMP "Include OpenMP threading." ON)
|
||||
option (WITH_LSR_BINDINGS "Include a `libsamplerate'-like interface." ON)
|
||||
cmake_dependent_option (WITH_SINGLE_PRECISION "Build with single precision (for up to 20-bit accuracy)." ON
|
||||
"WITH_DOUBLE_PRECISION" ON)
|
||||
cmake_dependent_option (WITH_DOUBLE_PRECISION "Build with double precision (for up to 32-bit accuracy)." ON
|
||||
"WITH_SINGLE_PRECISION" ON)
|
||||
cmake_dependent_option (WITH_SIMD "Use SIMD (for faster single precision)." ON
|
||||
"WITH_SINGLE_PRECISION" OFF)
|
||||
cmake_dependent_option (WITH_AVFFT "Use libavcodec (LGPL) for SIMD DFT." OFF
|
||||
"WITH_SIMD;NOT WITH_PFFFT" OFF)
|
||||
cmake_dependent_option (WITH_PFFFT "Use PFFFT (BSD-like licence) for SIMD DFT." ON
|
||||
"WITH_SIMD;NOT WITH_AVFFT" OFF)
|
||||
if (UNIX)
|
||||
if (EXISTS ${PROJECT_SOURCE_DIR}/lsr-tests)
|
||||
cmake_dependent_option (BUILD_LSR_TESTS "Build LSR tests." OFF
|
||||
"WITH_LSR_BINDINGS" OFF)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
# Introspection:
|
||||
|
||||
list (APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
|
||||
|
||||
include (CheckFunctionExists)
|
||||
include (CheckIncludeFiles)
|
||||
include (CheckLibraryExists)
|
||||
include (TestBigEndian)
|
||||
|
||||
check_library_exists (m pow "" NEED_LIBM)
|
||||
if (NEED_LIBM)
|
||||
set (CMAKE_REQUIRED_LIBRARIES "m;${CMAKE_REQUIRED_LIBRARIES}")
|
||||
link_libraries (m)
|
||||
endif ()
|
||||
|
||||
if (WITH_OPENMP)
|
||||
find_package (OpenMP)
|
||||
endif ()
|
||||
if (OPENMP_FOUND)
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
|
||||
endif ()
|
||||
|
||||
if (WITH_SIMD)
|
||||
find_package (SIMD)
|
||||
if (SIMD_FOUND)
|
||||
set (HAVE_SIMD 1)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (WITH_SINGLE_PRECISION)
|
||||
set (HAVE_SINGLE_PRECISION 1)
|
||||
endif ()
|
||||
|
||||
if (WITH_DOUBLE_PRECISION)
|
||||
set (HAVE_DOUBLE_PRECISION 1)
|
||||
endif ()
|
||||
|
||||
if (WITH_AVFFT)
|
||||
find_package (LibAVCodec)
|
||||
if (AVCODEC_FOUND)
|
||||
include_directories (${AVCODEC_INCLUDE_DIRS})
|
||||
link_libraries (${AVCODEC_LIBRARIES})
|
||||
set (HAVE_AVFFT 1)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
check_function_exists (lrint HAVE_LRINT)
|
||||
check_include_files (fenv.h HAVE_FENV_H)
|
||||
test_big_endian (WORDS_BIGENDIAN)
|
||||
|
||||
macro (make_exist)
|
||||
foreach (x ${ARGN})
|
||||
if (NOT ${x})
|
||||
set (${x} 0)
|
||||
endif ()
|
||||
endforeach ()
|
||||
endmacro ()
|
||||
|
||||
make_exist (HAVE_LRINT HAVE_FENV_H WORDS_BIGENDIAN HAVE_SIMD)
|
||||
make_exist (HAVE_SINGLE_PRECISION HAVE_DOUBLE_PRECISION HAVE_AVFFT)
|
||||
|
||||
|
||||
|
||||
# Compiler configuration:
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||
set (PROJECT_CXX_FLAGS "-Wconversion -Wall -W -pedantic -Wundef -Wcast-align -Wpointer-arith -Wno-long-long")
|
||||
set (PROJECT_C_FLAGS "${PROJECT_CXX_FLAGS} -Wnested-externs -Wmissing-prototypes -Wstrict-prototypes")
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -s") # strip
|
||||
endif ()
|
||||
cmake_dependent_option (VISIBILITY_HIDDEN "Build with -fvisibility=hidden." ON
|
||||
"BUILD_SHARED_LIBS" OFF)
|
||||
if (VISIBILITY_HIDDEN)
|
||||
add_definitions (-fvisibility=hidden -DSOXR_VISIBILITY)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (MSVC)
|
||||
add_definitions (-D_USE_MATH_DEFINES -D_CRT_SECURE_NO_WARNINGS)
|
||||
option (ENABLE_STATIC_RUNTIME "Visual Studio, link with runtime statically." OFF)
|
||||
if (ENABLE_STATIC_RUNTIME)
|
||||
foreach (flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
string (REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
|
||||
endforeach ()
|
||||
endif ()
|
||||
# By default, do not warn when built on machines using only VS Express:
|
||||
if (NOT DEFINED CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS)
|
||||
set (CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_NO_WARNINGS ON)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
# Build configuration:
|
||||
|
||||
if (${BUILD_SHARED_LIBS} AND ${CMAKE_SYSTEM_NAME} STREQUAL Windows) # Allow exes to find dlls:
|
||||
set (BIN ${PROJECT_BINARY_DIR}/bin/)
|
||||
set (EXAMPLES_BIN ${BIN})
|
||||
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${BIN})
|
||||
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${BIN})
|
||||
else ()
|
||||
set (BIN ./)
|
||||
set (EXAMPLES_BIN ../examples/)
|
||||
endif ()
|
||||
|
||||
set (LIB_TYPE STATIC)
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set (LIB_TYPE SHARED)
|
||||
if (MSVC)
|
||||
add_definitions (-DSOXR_DLL)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
# Installation configuration:
|
||||
|
||||
if (NOT DEFINED BIN_INSTALL_DIR)
|
||||
set (BIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin")
|
||||
endif ()
|
||||
if (NOT DEFINED LIB_INSTALL_DIR)
|
||||
set (LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}")
|
||||
endif ()
|
||||
if (NOT DEFINED INCLUDE_INSTALL_DIR)
|
||||
set (INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include")
|
||||
endif ()
|
||||
if (NOT DEFINED DOC_INSTALL_DIR)
|
||||
if (UNIX)
|
||||
set (DOC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/doc/lib${PROJECT_NAME}")
|
||||
else ()
|
||||
set (DOC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/doc")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (APPLE)
|
||||
option (BUILD_FRAMEWORK "Build an OS X framework." OFF)
|
||||
set (FRAMEWORK_INSTALL_DIR "/Library/Frameworks" CACHE STRING "Directory to install frameworks to.")
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
# Top-level:
|
||||
|
||||
set (PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH})
|
||||
math (EXPR SO_VERSION_MAJOR "${SO_VERSION_CURRENT} - ${SO_VERSION_AGE}")
|
||||
math (EXPR SO_VERSION_MINOR "${SO_VERSION_AGE}")
|
||||
math (EXPR SO_VERSION_PATCH "${SO_VERSION_REVISION}")
|
||||
set (SO_VERSION ${SO_VERSION_MAJOR}.${SO_VERSION_MINOR}.${SO_VERSION_PATCH})
|
||||
|
||||
configure_file (
|
||||
${PROJECT_SOURCE_DIR}/${PROJECT_NAME}-config.h.in
|
||||
${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.h)
|
||||
include_directories (${PROJECT_BINARY_DIR})
|
||||
|
||||
if (BUILD_TESTS OR BUILD_LSR_TESTS)
|
||||
enable_testing ()
|
||||
endif ()
|
||||
|
||||
install (FILES
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/README
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/LICENCE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/NEWS
|
||||
DESTINATION ${DOC_INSTALL_DIR})
|
||||
|
||||
|
||||
|
||||
# Subdirectories:
|
||||
|
||||
include_directories (${PROJECT_SOURCE_DIR}/src)
|
||||
|
||||
add_subdirectory (src)
|
||||
if (BUILD_TESTS)
|
||||
add_subdirectory (tests)
|
||||
endif ()
|
||||
if (BUILD_LSR_TESTS)
|
||||
add_subdirectory (lsr-tests)
|
||||
endif ()
|
||||
if (BUILD_EXAMPLES OR BUILD_TESTS)
|
||||
add_subdirectory (examples)
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
# Rough-and-ready distclean for anyone still doing in-tree builds:
|
||||
|
||||
if (UNIX)
|
||||
add_custom_target (distclean
|
||||
COMMAND make clean && rm -rf
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
cmake_install.cmake
|
||||
CPackConfig.cmake
|
||||
CPackSourceConfig.cmake
|
||||
deinstall.cmake
|
||||
Makefile
|
||||
soxr-config.h
|
||||
src/CMakeFiles
|
||||
src/cmake_install.cmake
|
||||
src/libsoxr-dev.src
|
||||
src/libsoxr-lsr.pc
|
||||
src/libsoxr.pc
|
||||
src/libsoxr.src
|
||||
src/Makefile)
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
# Deinstallation:
|
||||
|
||||
configure_file (
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/deinstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/deinstall.cmake"
|
||||
IMMEDIATE @ONLY)
|
||||
|
||||
add_custom_target (deinstall
|
||||
COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/deinstall.cmake")
|
||||
|
||||
|
||||
|
||||
# Packaging:
|
||||
|
||||
if (UNIX)
|
||||
set (CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
|
||||
set (CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
|
||||
set (CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
|
||||
|
||||
set (CPACK_SOURCE_GENERATOR "TGZ")
|
||||
set (CPACK_SOURCE_IGNORE_FILES "dist;/lsr-tests/;/Debug/;/Release/;/cpack/;\\\\.swp$;\\\\.gitignore;/\\\\.git/")
|
||||
|
||||
include (CPack)
|
||||
|
||||
if (IS_DIRECTORY ${PROJECT_SOURCE_DIR}/cpack)
|
||||
add_subdirectory (cpack)
|
||||
endif ()
|
||||
endif ()
|
||||
|
|
|
@ -1,208 +0,0 @@
|
|||
# Doxyfile 1.3.4
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
PROJECT_NAME = lib${PROJECT_NAME}
|
||||
PROJECT_NUMBER = ${PROJECT_VERSION}
|
||||
OUTPUT_DIRECTORY = doc
|
||||
OUTPUT_LANGUAGE = English
|
||||
USE_WINDOWS_ENCODING = NO
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = NO
|
||||
STRIP_FROM_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
DETAILS_AT_TOP = NO
|
||||
INHERIT_DOCS = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
TAB_SIZE = 2
|
||||
ALIASES =
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
SUBGROUPING = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
EXTRACT_ALL = YES
|
||||
EXTRACT_PRIVATE = NO
|
||||
EXTRACT_STATIC = NO
|
||||
EXTRACT_LOCAL_CLASSES = NO
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = YES
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
GENERATE_TODOLIST = NO
|
||||
GENERATE_TESTLIST = NO
|
||||
GENERATE_BUGLIST = NO
|
||||
GENERATE_DEPRECATEDLIST= NO
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = NO
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = NO
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = @CMAKE_SOURCE_DIR@/src
|
||||
FILE_PATTERNS = @PROJECT_NAME@.h
|
||||
RECURSIVE = YES
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = NO
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
VERBATIM_HEADERS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = YES
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER = @CMAKE_SOURCE_DIR@/doc/header.html
|
||||
HTML_FOOTER = @CMAKE_SOURCE_DIR@/doc/footer.html
|
||||
HTML_STYLESHEET = @CMAKE_SOURCE_DIR@/doc/stylesheet.css
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
GENERATE_HTMLHELP = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = YES
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
GENERATE_TREEVIEW = NO
|
||||
TREEVIEW_WIDTH = 250
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = letter
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = YES
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
XML_OUTPUT = xml
|
||||
XML_SCHEMA =
|
||||
XML_DTD =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the Perl module output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED = DO_NOT_DOCUMENT \
|
||||
DOXYGEN \
|
||||
WITH_MP4 \
|
||||
WITH_ASF
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = YES
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = YES
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
UML_LOOK = NO
|
||||
TEMPLATE_RELATIONS = YES
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
CALL_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MAX_DOT_GRAPH_WIDTH = 1024
|
||||
MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
MAX_DOT_GRAPH_DEPTH = 0
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
SEARCHENGINE = NO
|
|
@ -1,4 +1,15 @@
|
|||
SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
|
||||
INSTALLATION GUIDE CONTENTS
|
||||
|
||||
* Standard build
|
||||
* Build customisation
|
||||
* Cross-compiling with mingw (linux host)
|
||||
* Integration with other build systems
|
||||
|
||||
|
||||
|
||||
STANDARD BUILD
|
||||
|
||||
1. Prerequisites:
|
||||
|
||||
|
@ -42,10 +53,13 @@ SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
|||
|
||||
5. Installation test
|
||||
|
||||
To test the installation, build and run the first example programme (see
|
||||
examples/README).
|
||||
To test the installation, build and run some of the example programmes
|
||||
(see examples/README).
|
||||
|
||||
|
||||
|
||||
BUILD CUSTOMISATION
|
||||
|
||||
If it is necessary to customise the build, then steps 2 and 3 above may be
|
||||
substituted as follows. Change directory to the one containing this file,
|
||||
then enter commands along the lines of:
|
||||
|
@ -64,3 +78,46 @@ To list help on the available options, enter:
|
|||
Options, if given, should be preceded with '-D', e.g.
|
||||
|
||||
cmake -DWITH_SIMD:BOOL=OFF ..
|
||||
|
||||
|
||||
|
||||
CROSS-COMPILING WITH MINGW (LINUX HOST)
|
||||
|
||||
For example:
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-x86_64-mingw-w64-mingw32.cmake \
|
||||
-DCMAKE_INSTALL_PREFIX=install \
|
||||
-DHAVE_WORDS_BIGENDIAN_EXITCODE=1 \
|
||||
-DBUILD_TESTS=0 \
|
||||
-DBUILD_EXAMPLES=1 \
|
||||
..
|
||||
make
|
||||
|
||||
where ~/Toolchain-x86_64-mingw-w64-mingw32.cmake might contain:
|
||||
|
||||
SET(CMAKE_SYSTEM_NAME Windows)
|
||||
SET(CMAKE_C_COMPILER /usr/bin/x86_64-w64-mingw32-gcc)
|
||||
SET(CMAKE_CXX_COMPILER /usr/bin/x86_64-w64-mingw32-g++)
|
||||
SET(CMAKE_RC_COMPILER /usr/bin/x86_64-w64-mingw32-windres)
|
||||
SET(CMAKE_Fortran_COMPILER /usr/bin/x86_64-w64-mingw32-gfortran)
|
||||
SET(CMAKE_AR:FILEPATH /usr/bin/x86_64-w64-mingw32-ar)
|
||||
SET(CMAKE_RANLIB:FILEPATH /usr/bin/x86_64-w64-mingw32-ranlib)
|
||||
SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
SET(QT_BINARY_DIR /usr/x86_64-w64-mingw32/bin /usr/bin)
|
||||
SET(Boost_COMPILER -gcc47)
|
||||
|
||||
|
||||
|
||||
INTEGRATION WITH OTHER BUILD SYSTEMS
|
||||
|
||||
Autotools-based systems might find it useful to create a file called
|
||||
`configure' in the directory containing this file, consisting of the line:
|
||||
cmake -DBUILD_SHARED_LIBS=OFF .
|
||||
(or with other build options as required).
|
||||
|
||||
For MS visual studio, see msvc/README
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
|
||||
This library is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
Version 0.1.1 (2013-03-03)
|
||||
* Minor fixes/improvements to build/tests.
|
||||
* Fix crash (e.g. with k3b) when null error pointer passed to src_create (lsr
|
||||
bindings only).
|
||||
* Fix broken resampling in many cases with SIMD and anti_aliasing_pc < 100.
|
||||
* For clarity, renamed and slightly changed usage of three parameters in
|
||||
soxr_quality_spec_t (ABI compatible, API incompatible). An application not
|
||||
setting these parameters directly need make no change; otherwise, changes
|
||||
should be made per the following example (as shown, compatibility with both
|
||||
old/new APIs is maintained). See also the comments on these parameters in
|
||||
soxr.h. N.B. ABI compatibility with the 0.1.0 API may be removed in a
|
||||
future release.
|
||||
#if !defined SOXR_VERSION /* Deprecated, 0.1.0 API */
|
||||
q_spec.phase = minimum_phase? 0 : 50;
|
||||
q_spec.bw_pc = cutoff * 100;
|
||||
q_spec.anti_aliasing_pc = anti_aliasing * 100;
|
||||
#else /* 0.1.1 API */ Explanation:
|
||||
q_spec.phase_response = minimum_phase? 0 : 50; Renamed.
|
||||
q_spec.passband_end = cutoff; Renamed, no longer %.
|
||||
q_spec.stopband_begin = 2 - anti_aliasing; Renamed, no longer %, no
|
||||
#endif longer mirrored in Fs.
|
||||
|
||||
Version 0.1.0 (2013-01-19)
|
||||
* First public release.
|
|
@ -1,50 +1,53 @@
|
|||
SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
|
||||
The SoX Resampler library `libsoxr' performs one-dimensional sample-rate
|
||||
conversion -- it may be used, for example, to resample PCM-encoded audio.
|
||||
For higher-dimensional resampling, such as for visual-image processing, you
|
||||
should look elsewhere.
|
||||
|
||||
It aims to give fast¹ and very high quality² results for any constant
|
||||
(rational or irrational) resampling ratio. Phase-response, preserved
|
||||
bandwidth, aliasing, and rejection level parameters are all configurable;
|
||||
alternatively, simple `preset' configurations may be selected. An
|
||||
experimental, variable-rate resampling mode of operation is also included.
|
||||
|
||||
The resampler is currently available either as part of `libsox' (the audio
|
||||
file-format and effect library), or stand-alone as `libsoxr' (this package).
|
||||
The interfaces to libsox and libsoxr are slightly different, with that of
|
||||
libsoxr designed specifically for resampling. An application requiring
|
||||
support for other effects, or for reading-from or writing-to audio files or
|
||||
devices, should use libsox (or other libraries such as libsndfile or
|
||||
libavformat).
|
||||
|
||||
Libsoxr provides a simple API that allows interfacing using the most
|
||||
commonly-used sample formats and buffering schemes: sample-formats may be
|
||||
either floating-point or integer, and multiple channels either interleaved
|
||||
or split in separate buffers. The API is documented in the header file
|
||||
`soxr.h', together with sample code found in the 'examples' directory.
|
||||
|
||||
For compatibility with the popular `libsamplerate' library, the header file
|
||||
`soxr-lsr.h' is provided and may be used as an alternative API.³ Note
|
||||
however, that libsoxr does not provide a full emulation of libsamplerate
|
||||
and that using this approach, only a sub-set of libsoxr's features are
|
||||
available.
|
||||
|
||||
The design was inspired by Laurent De Soras' paper `The Quest For The
|
||||
Perfect Resampler', http://ldesoras.free.fr/doc/articles/resampler-en.pdf;
|
||||
in essence, it combines Julius O. Smith's `Bandlimited Interpolation'
|
||||
technique (https://ccrma.stanford.edu/~jos/resample/resample.pdf) with FFT-
|
||||
based over-sampling.
|
||||
|
||||
Note that for real-time resampling, libsoxr may have a higher latency
|
||||
than non-FFT based resamplers. For example, when using the `High Quality'
|
||||
configuration to resample between 44100Hz and 48000Hz, the latency is
|
||||
around 1000 output samples, i.e. roughly 20ms.
|
||||
|
||||
For build and installation instructions, see the file `INSTALL'; for
|
||||
copyright and licensing information, see the file `LICENCE'.
|
||||
________
|
||||
¹ For example, multi-channel resampling can utilise multiple CPU-cores.
|
||||
² Bit-perfect within practical occupied-bandwidth limits.
|
||||
³ For details of that API, see http://www.mega-nerd.com/SRC/api.html.
|
||||
SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
|
||||
The SoX Resampler library `libsoxr' performs one-dimensional sample-rate
|
||||
conversion -- it may be used, for example, to resample PCM-encoded audio.
|
||||
For higher-dimensional resampling, such as for visual-image processing, you
|
||||
should look elsewhere.
|
||||
|
||||
It aims to give fast¹ and very high quality² results for any constant
|
||||
(rational or irrational) resampling ratio. Phase-response, preserved
|
||||
bandwidth, aliasing, and rejection level parameters are all configurable;
|
||||
alternatively, simple `preset' configurations may be selected. An
|
||||
experimental, variable-rate resampling mode of operation is also included.
|
||||
|
||||
The resampler is currently available either as part of `libsox' (the audio
|
||||
file-format and effect library), or stand-alone as `libsoxr' (this package).
|
||||
The interfaces to libsox and libsoxr are slightly different, with that of
|
||||
libsoxr designed specifically for resampling. An application requiring
|
||||
support for other effects, or for reading-from or writing-to audio files or
|
||||
devices, should use libsox (or other libraries such as libsndfile or
|
||||
libavformat).
|
||||
|
||||
Libsoxr provides a simple API that allows interfacing using the most
|
||||
commonly-used sample formats and buffering schemes: sample-formats may be
|
||||
either floating-point or integer, and multiple channels either interleaved
|
||||
or split in separate buffers. The API is documented in the header file
|
||||
`soxr.h', together with sample code found in the 'examples' directory.
|
||||
|
||||
For compatibility with the popular `libsamplerate' library, the header file
|
||||
`soxr-lsr.h' is provided and may be used as an alternative API.³ Note
|
||||
however, that libsoxr does not provide a full emulation of libsamplerate
|
||||
and that using this approach, only a sub-set of libsoxr's features are
|
||||
available.
|
||||
|
||||
The design was inspired by Laurent De Soras' paper `The Quest For The
|
||||
Perfect Resampler', http://ldesoras.free.fr/doc/articles/resampler-en.pdf;
|
||||
in essence, it combines Julius O. Smith's `Bandlimited Interpolation'
|
||||
technique (https://ccrma.stanford.edu/~jos/resample/resample.pdf) with FFT-
|
||||
based over-sampling.
|
||||
|
||||
Note that for real-time resampling, libsoxr may have a higher latency
|
||||
than non-FFT based resamplers. For example, when using the `High Quality'
|
||||
configuration to resample between 44100Hz and 48000Hz, the latency is
|
||||
around 1000 output samples, i.e. roughly 20ms (though passband and FFT-
|
||||
size configuration parameters may be used to reduce this figure).
|
||||
|
||||
For build and installation instructions, see the file `INSTALL'; for
|
||||
copyright and licensing information, see the file `LICENCE'.
|
||||
|
||||
For support and new versions, see http://soxr.sourceforge.net
|
||||
________
|
||||
¹ For example, multi-channel resampling can utilise multiple CPU-cores.
|
||||
² Bit-perfect within practical occupied-bandwidth limits.
|
||||
³ For details of that API, see http://www.mega-nerd.com/SRC/api.html.
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
# SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
# Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
# - Find AVCODEC
|
||||
# Find the native installation of this package: includes and libraries.
|
||||
#
|
||||
# AVCODEC_INCLUDES - where to find headers for this package.
|
||||
# AVCODEC_LIBRARIES - List of libraries when using this package.
|
||||
# AVCODEC_FOUND - True if this package can be found.
|
||||
|
||||
if (AVCODEC_INCLUDES)
|
||||
set (AVCODEC_FIND_QUIETLY TRUE)
|
||||
endif (AVCODEC_INCLUDES)
|
||||
|
||||
find_path (AVCODEC_INCLUDES libavcodec/avcodec.h)
|
||||
|
||||
find_library (AVCODEC_LIBRARIES NAMES avcodec)
|
||||
|
||||
include (FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args (
|
||||
AVCODEC DEFAULT_MSG AVCODEC_LIBRARIES AVCODEC_INCLUDES)
|
||||
|
||||
mark_as_advanced (AVCODEC_LIBRARIES AVCODEC_INCLUDES)
|
||||
# SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
# Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
# - Find AVCODEC
|
||||
# Find the native installation of this package: includes and libraries.
|
||||
#
|
||||
# AVCODEC_INCLUDES - where to find headers for this package.
|
||||
# AVCODEC_LIBRARIES - List of libraries when using this package.
|
||||
# AVCODEC_FOUND - True if this package can be found.
|
||||
|
||||
if (AVCODEC_INCLUDES)
|
||||
set (AVCODEC_FIND_QUIETLY TRUE)
|
||||
endif (AVCODEC_INCLUDES)
|
||||
|
||||
find_path (AVCODEC_INCLUDES libavcodec/avcodec.h)
|
||||
|
||||
find_library (AVCODEC_LIBRARIES NAMES avcodec)
|
||||
|
||||
include (FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args (
|
||||
AVCODEC DEFAULT_MSG AVCODEC_LIBRARIES AVCODEC_INCLUDES)
|
||||
|
||||
mark_as_advanced (AVCODEC_LIBRARIES AVCODEC_INCLUDES)
|
||||
|
|
|
@ -1,91 +1,108 @@
|
|||
# - Finds OpenMP support
|
||||
# This module can be used to detect OpenMP support in a compiler.
|
||||
# If the compiler supports OpenMP, the flags required to compile with
|
||||
# openmp support are set.
|
||||
#
|
||||
# The following variables are set:
|
||||
# OpenMP_C_FLAGS - flags to add to the C compiler for OpenMP support
|
||||
# OPENMP_FOUND - true if openmp is detected
|
||||
#
|
||||
# Supported compilers can be found at http://openmp.org/wp/openmp-compilers/
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2009 Kitware, Inc.
|
||||
# Copyright 2008-2009 André Rigland Brodtkorb <Andre.Brodtkorb@ifi.uio.no>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#
|
||||
# Modified for libsoxr not to rely on presence of C++ compiler.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
include (CheckCSourceCompiles)
|
||||
include (FindPackageHandleStandardArgs)
|
||||
|
||||
set (OpenMP_C_FLAG_CANDIDATES
|
||||
#Gnu
|
||||
"-fopenmp"
|
||||
#Microsoft Visual Studio
|
||||
"/openmp"
|
||||
#Intel windows
|
||||
"-Qopenmp"
|
||||
#Intel
|
||||
"-openmp"
|
||||
#Empty, if compiler automatically accepts openmp
|
||||
" "
|
||||
#Sun
|
||||
"-xopenmp"
|
||||
#HP
|
||||
"+Oopenmp"
|
||||
#IBM XL C/c++
|
||||
"-qsmp"
|
||||
#Portland Group
|
||||
"-mp"
|
||||
)
|
||||
|
||||
# sample openmp source code to test
|
||||
set (OpenMP_C_TEST_SOURCE
|
||||
"
|
||||
#include <omp.h>
|
||||
int main() {
|
||||
#ifdef _OPENMP
|
||||
return 0;
|
||||
#else
|
||||
breaks_on_purpose
|
||||
#endif
|
||||
}
|
||||
")
|
||||
# if these are set then do not try to find them again,
|
||||
# by avoiding any try_compiles for the flags
|
||||
if (DEFINED OpenMP_C_FLAGS)
|
||||
set (OpenMP_C_FLAG_CANDIDATES)
|
||||
endif (DEFINED OpenMP_C_FLAGS)
|
||||
|
||||
# check c compiler
|
||||
foreach (FLAG ${OpenMP_C_FLAG_CANDIDATES})
|
||||
set (SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
|
||||
set (CMAKE_REQUIRED_FLAGS "${FLAG}")
|
||||
unset (OpenMP_FLAG_DETECTED CACHE)
|
||||
message (STATUS "Try OpenMP C flag = [${FLAG}]")
|
||||
check_c_source_compiles ("${OpenMP_C_TEST_SOURCE}" OpenMP_FLAG_DETECTED)
|
||||
set (CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}")
|
||||
if (OpenMP_FLAG_DETECTED)
|
||||
set (OpenMP_C_FLAGS_INTERNAL "${FLAG}")
|
||||
break ()
|
||||
endif (OpenMP_FLAG_DETECTED)
|
||||
endforeach (FLAG ${OpenMP_C_FLAG_CANDIDATES})
|
||||
|
||||
set (OpenMP_C_FLAGS "${OpenMP_C_FLAGS_INTERNAL}"
|
||||
CACHE STRING "C compiler flags for OpenMP parallization")
|
||||
|
||||
# handle the standard arguments for find_package
|
||||
find_package_handle_standard_args (OpenMP DEFAULT_MSG
|
||||
OpenMP_C_FLAGS OpenMP_C_FLAGS)
|
||||
|
||||
mark_as_advanced (OpenMP_C_FLAGS)
|
||||
# - Finds OpenMP support
|
||||
# This module can be used to detect OpenMP support in a compiler.
|
||||
# If the compiler supports OpenMP, the flags required to compile with
|
||||
# openmp support are set.
|
||||
#
|
||||
# The following variables are set:
|
||||
# OpenMP_C_FLAGS - flags to add to the C compiler for OpenMP support
|
||||
# OPENMP_FOUND - true if openmp is detected
|
||||
#
|
||||
# Supported compilers can be found at http://openmp.org/wp/openmp-compilers/
|
||||
#
|
||||
# Modified for libsoxr not to rely on presence of C++ compiler.
|
||||
#
|
||||
#=============================================================================
|
||||
# Copyright 2009 Kitware, Inc.
|
||||
# Copyright 2008-2009 André Rigland Brodtkorb <Andre.Brodtkorb@ifi.uio.no>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * The names of Kitware, Inc., the Insight Consortium, or the names of
|
||||
# any consortium members, or of any contributors, may not be used to
|
||||
# endorse or promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
include (CheckCSourceCompiles)
|
||||
include (FindPackageHandleStandardArgs)
|
||||
|
||||
set (OpenMP_C_FLAG_CANDIDATES
|
||||
#Gnu
|
||||
"-fopenmp"
|
||||
#Microsoft Visual Studio
|
||||
"/openmp"
|
||||
#Intel windows
|
||||
"-Qopenmp"
|
||||
#Intel
|
||||
"-openmp"
|
||||
#Empty, if compiler automatically accepts openmp
|
||||
" "
|
||||
#Sun
|
||||
"-xopenmp"
|
||||
#HP
|
||||
"+Oopenmp"
|
||||
#IBM XL C/c++
|
||||
"-qsmp"
|
||||
#Portland Group
|
||||
"-mp"
|
||||
)
|
||||
|
||||
# sample openmp source code to test
|
||||
set (OpenMP_C_TEST_SOURCE
|
||||
"
|
||||
#include <omp.h>
|
||||
int main() {
|
||||
#ifdef _OPENMP
|
||||
return 0;
|
||||
#else
|
||||
breaks_on_purpose
|
||||
#endif
|
||||
}
|
||||
")
|
||||
# if these are set then do not try to find them again,
|
||||
# by avoiding any try_compiles for the flags
|
||||
if (DEFINED OpenMP_C_FLAGS)
|
||||
set (OpenMP_C_FLAG_CANDIDATES)
|
||||
endif (DEFINED OpenMP_C_FLAGS)
|
||||
|
||||
# check c compiler
|
||||
foreach (FLAG ${OpenMP_C_FLAG_CANDIDATES})
|
||||
set (SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
|
||||
set (CMAKE_REQUIRED_FLAGS "${FLAG}")
|
||||
unset (OpenMP_FLAG_DETECTED CACHE)
|
||||
message (STATUS "Try OpenMP C flag = [${FLAG}]")
|
||||
check_c_source_compiles ("${OpenMP_C_TEST_SOURCE}" OpenMP_FLAG_DETECTED)
|
||||
set (CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}")
|
||||
if (OpenMP_FLAG_DETECTED)
|
||||
set (OpenMP_C_FLAGS_INTERNAL "${FLAG}")
|
||||
break ()
|
||||
endif (OpenMP_FLAG_DETECTED)
|
||||
endforeach (FLAG ${OpenMP_C_FLAG_CANDIDATES})
|
||||
|
||||
set (OpenMP_C_FLAGS "${OpenMP_C_FLAGS_INTERNAL}"
|
||||
CACHE STRING "C compiler flags for OpenMP parallization")
|
||||
|
||||
# handle the standard arguments for find_package
|
||||
find_package_handle_standard_args (OpenMP DEFAULT_MSG
|
||||
OpenMP_C_FLAGS OpenMP_C_FLAGS)
|
||||
|
||||
mark_as_advanced (OpenMP_C_FLAGS)
|
||||
|
|
|
@ -1,53 +1,88 @@
|
|||
# - Finds SIMD support
|
||||
#
|
||||
# The following variables are set:
|
||||
# SIMD_C_FLAGS - flags to add to the C compiler for this package.
|
||||
# SIMD_FOUND - true if support for this package is found.
|
||||
|
||||
include (CheckCSourceCompiles)
|
||||
include (FindPackageHandleStandardArgs)
|
||||
|
||||
set (SIMD_C_FLAG_CANDIDATES
|
||||
#Microsoft Visual Studio
|
||||
"/arch:SSE /fp:fast -D__SSE__"
|
||||
#Gnu
|
||||
"-msse -mfpmath=sse"
|
||||
)
|
||||
|
||||
set (SIMD_C_TEST_SOURCE
|
||||
"
|
||||
#include <xmmintrin.h>
|
||||
int main()
|
||||
{
|
||||
__m128 a, b;
|
||||
float vals[4] = {0};
|
||||
a = _mm_loadu_ps (vals);
|
||||
b = a;
|
||||
b = _mm_add_ps (a,b);
|
||||
_mm_storeu_ps (vals,b);
|
||||
return 0;
|
||||
}
|
||||
")
|
||||
|
||||
if (DEFINED SIMD_C_FLAGS)
|
||||
set (SIMD_C_FLAG_CANDIDATES)
|
||||
endif ()
|
||||
|
||||
foreach (FLAG ${SIMD_C_FLAG_CANDIDATES})
|
||||
set (SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
|
||||
set (CMAKE_REQUIRED_FLAGS "${FLAG}")
|
||||
unset (SIMD_FLAG_DETECTED CACHE)
|
||||
message (STATUS "Try SIMD C flag = [${FLAG}]")
|
||||
check_c_source_compiles ("${SIMD_C_TEST_SOURCE}" SIMD_FLAG_DETECTED)
|
||||
set (CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}")
|
||||
if (SIMD_FLAG_DETECTED)
|
||||
set (SIMD_C_FLAGS_INTERNAL "${FLAG}")
|
||||
break ()
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
set (SIMD_C_FLAGS "${SIMD_C_FLAGS_INTERNAL}"
|
||||
CACHE STRING "C compiler flags for SIMD vectorization")
|
||||
|
||||
find_package_handle_standard_args (SIMD DEFAULT_MSG SIMD_C_FLAGS SIMD_C_FLAGS)
|
||||
mark_as_advanced (SIMD_C_FLAGS)
|
||||
# - Finds SIMD support
|
||||
#
|
||||
# The following variables are set:
|
||||
# SIMD_C_FLAGS - flags to add to the C compiler for this package.
|
||||
# SIMD_FOUND - true if support for this package is found.
|
||||
#
|
||||
#=============================================================================
|
||||
# Based on FindOpenMP.cmake, which is:
|
||||
#
|
||||
# Copyright 2009 Kitware, Inc.
|
||||
# Copyright 2008-2009 André Rigland Brodtkorb <Andre.Brodtkorb@ifi.uio.no>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# * The names of Kitware, Inc., the Insight Consortium, or the names of
|
||||
# any consortium members, or of any contributors, may not be used to
|
||||
# endorse or promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
include (CheckCSourceCompiles)
|
||||
include (FindPackageHandleStandardArgs)
|
||||
|
||||
set (SIMD_C_FLAG_CANDIDATES
|
||||
# Microsoft Visual Studio x64
|
||||
" "
|
||||
# Microsoft Visual Studio x86
|
||||
"/arch:SSE /fp:fast -D__SSE__"
|
||||
# Gnu
|
||||
"-msse -mfpmath=sse"
|
||||
)
|
||||
|
||||
set (SIMD_C_TEST_SOURCE
|
||||
"
|
||||
#include <xmmintrin.h>
|
||||
int main()
|
||||
{
|
||||
__m128 a, b;
|
||||
float vals[4] = {0};
|
||||
a = _mm_loadu_ps (vals);
|
||||
b = a;
|
||||
b = _mm_add_ps (a,b);
|
||||
_mm_storeu_ps (vals,b);
|
||||
return 0;
|
||||
}
|
||||
")
|
||||
|
||||
if (DEFINED SIMD_C_FLAGS)
|
||||
set (SIMD_C_FLAG_CANDIDATES)
|
||||
endif ()
|
||||
|
||||
foreach (FLAG ${SIMD_C_FLAG_CANDIDATES})
|
||||
set (SAFE_CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS}")
|
||||
set (CMAKE_REQUIRED_FLAGS "${FLAG}")
|
||||
unset (SIMD_FLAG_DETECTED CACHE)
|
||||
message (STATUS "Try SIMD C flag = [${FLAG}]")
|
||||
check_c_source_compiles ("${SIMD_C_TEST_SOURCE}" SIMD_FLAG_DETECTED)
|
||||
set (CMAKE_REQUIRED_FLAGS "${SAFE_CMAKE_REQUIRED_FLAGS}")
|
||||
if (SIMD_FLAG_DETECTED)
|
||||
set (SIMD_C_FLAGS_INTERNAL "${FLAG}")
|
||||
break ()
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
set (SIMD_C_FLAGS "${SIMD_C_FLAGS_INTERNAL}"
|
||||
CACHE STRING "C compiler flags for SIMD vectorization")
|
||||
|
||||
find_package_handle_standard_args (SIMD DEFAULT_MSG SIMD_C_FLAGS SIMD_C_FLAGS)
|
||||
mark_as_advanced (SIMD_C_FLAGS)
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
# SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
# Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
# - Macro to determine endian type
|
||||
# test_big_endian (VARIABLE)
|
||||
# VARIABLE - variable to store the result to
|
||||
|
||||
macro (test_big_endian VARIABLE)
|
||||
if ("HAVE_${VARIABLE}" MATCHES "^HAVE_${VARIABLE}$")
|
||||
include (CheckCSourceRuns)
|
||||
check_c_source_runs ("int main() {union {long i; char c[sizeof(long)];}
|
||||
const u = {1}; return !!u.c[0];}" HAVE_${VARIABLE})
|
||||
set (${VARIABLE} "${HAVE_${VARIABLE}}" CACHE INTERNAL "1 if system is big endian" FORCE)
|
||||
endif ()
|
||||
endmacro ()
|
||||
# SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
# Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
# - Macro to determine endian type
|
||||
# test_big_endian (VARIABLE)
|
||||
# VARIABLE - variable to store the result to
|
||||
|
||||
macro (test_big_endian VARIABLE)
|
||||
if ("HAVE_${VARIABLE}" MATCHES "^HAVE_${VARIABLE}$")
|
||||
include (CheckCSourceRuns)
|
||||
check_c_source_runs ("int main() {union {long i; char c[sizeof(long)];}
|
||||
const u = {1}; return !!u.c[0];}" HAVE_${VARIABLE})
|
||||
set (${VARIABLE} "${HAVE_${VARIABLE}}" CACHE INTERNAL "1 if system is big endian" FORCE)
|
||||
endif ()
|
||||
endmacro ()
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
# Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
# Wrapper to allow easier integration with projects using autotools.
|
||||
|
||||
# Such projects will probably be using static libs so should pass
|
||||
# -DBUILD_SHARED_LIBS=OFF amongst any other options needed.
|
||||
|
||||
# Autotools options should not be passed to this script.
|
||||
|
||||
cmake -DBUILD_SHARED_LIBS=OFF -DWITH_OPENMP=OFF .
|
|
@ -1,4 +1,4 @@
|
|||
# SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
# SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
# Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
|
@ -12,7 +12,7 @@ foreach (file ${files})
|
|||
message (STATUS "Deinstalling \"${dest}\"")
|
||||
if (EXISTS "${dest}" OR IS_SYMLINK "${dest}")
|
||||
execute_process (
|
||||
COMMAND @CMAKE_COMMAND@ -E remove "${dest}"
|
||||
COMMAND "@CMAKE_COMMAND@" -E remove "${dest}"
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RESULT_VARIABLE rm_retval
|
||||
)
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
Not convinced that this is going anywhere useful.
|
||||
|
||||
Run "make docs" in the parent directory to generate the API documentation.
|
|
@ -1,4 +0,0 @@
|
|||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,31 +0,0 @@
|
|||
<head>
|
||||
<title>$title ($projectname)</title>
|
||||
<link href="stylesheet.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<table border="0" width="100%">
|
||||
<tr>
|
||||
<td width="1">
|
||||
<img src="../logo.png">
|
||||
</td>
|
||||
<td>
|
||||
<div id="intro">
|
||||
<table border="0" height="119" cellpadding="0" cellspacing="0" width="100%">
|
||||
<tr><td valign="top"><h1>The SoX Resampler $projectnumber ($title)</h1></td></tr>
|
||||
<tr>
|
||||
<td valign="bottom">
|
||||
<div id="links">
|
||||
<a href="index.html">Home</a>
|
||||
<a href="files.html">Headers</a>
|
||||
<a href="functions.html">Class Members</a>
|
||||
<a href="globals.html">File Members</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="text">
|
Binary file not shown.
Before Width: | Height: | Size: 3.9 KiB |
|
@ -1,395 +0,0 @@
|
|||
body {
|
||||
font-family: sans-serif;
|
||||
background: white;
|
||||
color: black;
|
||||
margin: 0px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
a:link {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #cccccc;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:active {
|
||||
color: #cccccc;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
img {
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
/* container */
|
||||
|
||||
#container {
|
||||
position: absolute;
|
||||
border-width: thin;
|
||||
border-style: solid;
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
/* intro */
|
||||
|
||||
#intro {
|
||||
padding: 5px;
|
||||
margin: 0px;
|
||||
background: #cccccc;
|
||||
border-width: medium;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
#intro h1 {
|
||||
margin: 5px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
/* links */
|
||||
|
||||
#links {
|
||||
font-size: x-small;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
#links a {
|
||||
border-width: thin;
|
||||
border-style: dotted;
|
||||
border-color: white;
|
||||
/* margin: 0px 10px 0px 0px; */
|
||||
margin: 1px;
|
||||
padding: 3px;
|
||||
line-height: 230%
|
||||
}
|
||||
|
||||
#links a:hover {
|
||||
color: black;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#links h3 {
|
||||
outline-width: thin;
|
||||
border-style: solid;
|
||||
padding: 2px;
|
||||
margin: 3px 0px 3px 0px;
|
||||
}
|
||||
|
||||
/* menu */
|
||||
|
||||
#menu h3 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* text */
|
||||
|
||||
#text {
|
||||
margin: 0px;
|
||||
padding: 5px 5px 0px 5px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#text h3 {
|
||||
border-width: thin;
|
||||
border-style: solid;
|
||||
padding: 2px;
|
||||
margin: 3px 0px 3px 0px;
|
||||
}
|
||||
|
||||
#text li {
|
||||
margin: 0px 0px 10px 0px;
|
||||
}
|
||||
|
||||
#text ul {
|
||||
margin: 5px;
|
||||
padding: 0px 0px 0px 20px;
|
||||
}
|
||||
|
||||
#leftcolumn {
|
||||
float: left;
|
||||
width: 300px;
|
||||
margin: 0px 10px 0px 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
#rightcolumn {
|
||||
float: right;
|
||||
width: 210px;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
/* vspacer */
|
||||
|
||||
.vspacer {
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.silver {
|
||||
border-width: thin;
|
||||
border-color: black;
|
||||
border-style: solid;
|
||||
background: #cccccc;
|
||||
}
|
||||
|
||||
a.code {
|
||||
text-decoration: none;
|
||||
font-weight: normal;
|
||||
color: #4444ee
|
||||
}
|
||||
|
||||
a.codeRef {
|
||||
font-weight: normal;
|
||||
color: #4444ee
|
||||
}
|
||||
|
||||
div.fragment {
|
||||
width: 98%;
|
||||
border: 1px solid #CCCCCC;
|
||||
background-color: #f5f5f5;
|
||||
padding-left: 4px;
|
||||
margin: 4px;
|
||||
}
|
||||
|
||||
div.ah {
|
||||
background-color: black;
|
||||
font-weight: bold; color: #ffffff;
|
||||
margin-bottom: 3px;
|
||||
margin-top: 3px
|
||||
}
|
||||
|
||||
#text td {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
div.memdoc {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 20px;
|
||||
padding: 10px 10px 10px 40px;
|
||||
}
|
||||
|
||||
div.memproto {
|
||||
border: thin solid black;
|
||||
background-color: #f2f2ff;
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
td.paramtype {
|
||||
color: #602020;
|
||||
}
|
||||
|
||||
table.memname {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.groupHeader {
|
||||
margin-left: 16px;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 6px;
|
||||
font-weight: bold
|
||||
}
|
||||
|
||||
div.groupText {
|
||||
margin-left: 16px;
|
||||
font-style: italic;
|
||||
font-size: smaller
|
||||
}
|
||||
|
||||
body {
|
||||
background: white;
|
||||
color: black;
|
||||
margin-right: 20px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
td.indexkey {
|
||||
background-color: #eeeeff;
|
||||
font-weight: bold;
|
||||
padding-right : 10px;
|
||||
padding-top : 2px;
|
||||
padding-left : 10px;
|
||||
padding-bottom : 2px;
|
||||
margin-left : 0px;
|
||||
margin-right : 0px;
|
||||
margin-top : 2px;
|
||||
margin-bottom : 2px
|
||||
}
|
||||
|
||||
td.indexvalue {
|
||||
background-color: #eeeeff;
|
||||
font-style: italic;
|
||||
padding-right : 10px;
|
||||
padding-top : 2px;
|
||||
padding-left : 10px;
|
||||
padding-bottom : 2px;
|
||||
margin-left : 0px;
|
||||
margin-right : 0px;
|
||||
margin-top : 2px;
|
||||
margin-bottom : 2px
|
||||
}
|
||||
|
||||
tr.memlist {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
p.formulaDsp {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
img.formulaDsp {
|
||||
|
||||
}
|
||||
|
||||
img.formulaInl {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
span.keyword {
|
||||
color: #008000
|
||||
}
|
||||
|
||||
span.keywordtype {
|
||||
color: #604020
|
||||
}
|
||||
|
||||
span.keywordflow {
|
||||
color: #e08000
|
||||
}
|
||||
|
||||
span.comment {
|
||||
color: #800000
|
||||
}
|
||||
|
||||
span.preprocessor {
|
||||
color: #806020
|
||||
}
|
||||
|
||||
span.stringliteral {
|
||||
color: #002080
|
||||
}
|
||||
|
||||
span.charliteral {
|
||||
color: #008080
|
||||
}
|
||||
|
||||
.mdTable {
|
||||
border: 1px solid #868686;
|
||||
background-color: #f2f2ff;
|
||||
}
|
||||
|
||||
.mdRow {
|
||||
padding: 8px 20px;
|
||||
}
|
||||
|
||||
.mdescLeft {
|
||||
font-size: smaller;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
background-color: #FAFAFA;
|
||||
padding-left: 8px;
|
||||
border-top: 1px none #E0E0E0;
|
||||
border-right: 1px none #E0E0E0;
|
||||
border-bottom: 1px none #E0E0E0;
|
||||
border-left: 1px none #E0E0E0;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.mdescRight {
|
||||
font-size: smaller;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-style: italic;
|
||||
background-color: #FAFAFA;
|
||||
padding-left: 4px;
|
||||
border-top: 1px none #E0E0E0;
|
||||
border-right: 1px none #E0E0E0;
|
||||
border-bottom: 1px none #E0E0E0;
|
||||
border-left: 1px none #E0E0E0;
|
||||
margin: 0px;
|
||||
padding-bottom: 0px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.memItemLeft {
|
||||
padding: 1px 0px 0px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-style: solid;
|
||||
border-top-color: #E0E0E0;
|
||||
border-right-color: #E0E0E0;
|
||||
border-bottom-color: #E0E0E0;
|
||||
border-left-color: #E0E0E0;
|
||||
border-right-style: none;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
background-color: #FAFAFA;
|
||||
font-family: Geneva, Arial, Helvetica, sans-serif;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.memItemRight {
|
||||
padding: 1px 0px 0px 8px;
|
||||
margin: 4px;
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-style: solid;
|
||||
border-top-color: #E0E0E0;
|
||||
border-right-color: #E0E0E0;
|
||||
border-bottom-color: #E0E0E0;
|
||||
border-left-color: #E0E0E0;
|
||||
border-right-style: none;
|
||||
border-bottom-style: none;
|
||||
border-left-style: none;
|
||||
background-color: #FAFAFA;
|
||||
font-family: Geneva, Arial, Helvetica, sans-serif;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.search {
|
||||
color: #0000ee;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
form.search {
|
||||
margin-bottom: 0px;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
input.search {
|
||||
font-size: 75%;
|
||||
color: #000080;
|
||||
font-weight: normal;
|
||||
background-color: #eeeeff;
|
||||
}
|
||||
|
||||
td.tiny {
|
||||
font-size: 75%;
|
||||
}
|
|
@ -1,48 +1,50 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Example 1: `One-shot' resample a single block of data in memory.
|
||||
*
|
||||
* N.B. See example 2 for how to resample a stream (of blocks).
|
||||
*
|
||||
* Optional arguments are: INPUT-RATE OUTPUT-RATE
|
||||
*
|
||||
* With the default arguments, the output should produce lines similar to the
|
||||
* following:
|
||||
*
|
||||
* 0.00 0.71 1.00 0.71 -0.00 -0.71 -1.00 -0.71
|
||||
*
|
||||
* Gibbs effect may be seen at the ends of the resampled signal; this is because
|
||||
* unlike a `real-world' signal, the synthetic input signal is not band-limited.
|
||||
*/
|
||||
|
||||
#include <soxr.h>
|
||||
#include "examples-common.h"
|
||||
|
||||
const float in[] = { /* Input: 12 cycles of a sine wave with freq. = irate/4 */
|
||||
0,1,0,-1, 0,1,0,-1, 0,1,0,-1, 0,1,0,-1, 0,1,0,-1, 0,1,0,-1,
|
||||
0,1,0,-1, 0,1,0,-1, 0,1,0,-1, 0,1,0,-1, 0,1,0,-1, 0,1,0,-1};
|
||||
|
||||
int main(int argc, char const * arg[])
|
||||
{
|
||||
double irate = argc > 1? atof(arg[1]) : 1; /* Default to upsampling */
|
||||
double orate = argc > 2? atof(arg[2]) : 2; /* by a factor of 2. */
|
||||
|
||||
size_t olen = (size_t)(AL(in) * orate / irate + .5); /* Assay output len. */
|
||||
float * out = malloc(sizeof(*out) * olen); /* Allocate output buffer. */
|
||||
size_t odone;
|
||||
|
||||
soxr_error_t error = soxr_oneshot(irate, orate, 1, /* Rates and # of chans. */
|
||||
in, AL(in), NULL, /* Input. */
|
||||
out, olen, &odone, /* Output. */
|
||||
NULL, NULL, NULL); /* Default configuration.*/
|
||||
|
||||
unsigned i = 0; /* Print out the resampled data... */
|
||||
while (i++ < odone)
|
||||
printf("%5.2f%c", out[i-1], " \n"[!(i&7) || i == odone]);
|
||||
puts(soxr_strerror(error)); /* ...and the reported result. */
|
||||
|
||||
free(out); /* Tidy up. */
|
||||
return !!error;
|
||||
(void)argc, (void)arg; /* Not used in this example. */
|
||||
}
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Example 1: `One-shot' resample a single block of data in memory.
|
||||
*
|
||||
* N.B. See example 2 for how to resample a stream (of blocks).
|
||||
*
|
||||
* Optional arguments are: INPUT-RATE OUTPUT-RATE
|
||||
*
|
||||
* With the default arguments, the output should produce lines similar to the
|
||||
* following:
|
||||
*
|
||||
* 0.00 0.71 1.00 0.71 -0.00 -0.71 -1.00 -0.71
|
||||
*
|
||||
* Gibbs effect may be seen at the ends of the resampled signal; this is because
|
||||
* unlike a `real-world' signal, the synthetic input signal is not band-limited.
|
||||
*/
|
||||
|
||||
#include <soxr.h>
|
||||
#include "examples-common.h"
|
||||
|
||||
const float in[] = { /* Input: 12 cycles of a sine wave with freq. = irate/4 */
|
||||
0,1,0,-1, 0,1,0,-1, 0,1,0,-1, 0,1,0,-1, 0,1,0,-1, 0,1,0,-1,
|
||||
0,1,0,-1, 0,1,0,-1, 0,1,0,-1, 0,1,0,-1, 0,1,0,-1, 0,1,0,-1};
|
||||
|
||||
int main(int argc, char const * arg[])
|
||||
{
|
||||
double irate = argc > 1? atof(arg[1]) : 1; /* Default to upsampling */
|
||||
double orate = argc > 2? atof(arg[2]) : 2; /* by a factor of 2. */
|
||||
|
||||
size_t olen = (size_t)(AL(in) * orate / irate + .5); /* Assay output len. */
|
||||
float * out = malloc(sizeof(*out) * olen); /* Allocate output buffer. */
|
||||
size_t odone;
|
||||
|
||||
soxr_error_t error = soxr_oneshot(irate, orate, 1, /* Rates and # of chans. */
|
||||
in, AL(in), NULL, /* Input. */
|
||||
out, olen, &odone, /* Output. */
|
||||
NULL, NULL, NULL); /* Default configuration.*/
|
||||
|
||||
unsigned i = 0; /* Print out the resampled data, */
|
||||
while (i++ < odone)
|
||||
printf("%5.2f%c", out[i-1], " \n"[!(i&7) || i == odone]);
|
||||
printf("%-26s %s\n", arg[0], soxr_strerror(error)); /* and reported result. */
|
||||
|
||||
if (argc > 3) /* Library version check: */
|
||||
printf("runtime=%s API="SOXR_THIS_VERSION_STR"\n", soxr_version());
|
||||
|
||||
free(out); /* Tidy up. */
|
||||
return !!error;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Example 1a: Variant of example 1 using libsamplerate-like bindings. */
|
||||
|
||||
#include <soxr-lsr.h>
|
||||
#include "examples-common.h"
|
||||
|
||||
float in[] = { /* Input: 12 cycles of a sine wave with freq. = irate/4 */
|
||||
0,1,0,-1, 0,1,0,-1, 0,1,0,-1, 0,1,0,-1, 0,1,0,-1, 0,1,0,-1,
|
||||
0,1,0,-1, 0,1,0,-1, 0,1,0,-1, 0,1,0,-1, 0,1,0,-1, 0,1,0,-1};
|
||||
|
||||
int main(int argc, char const * arg[])
|
||||
{
|
||||
double irate = argc > 1? atof(arg[1]) : 1; /* Default to upsampling */
|
||||
double orate = argc > 2? atof(arg[2]) : 2; /* by a factor of 2. */
|
||||
|
||||
size_t olen = (size_t)(AL(in) * orate / irate + .5); /* Assay output len. */
|
||||
float * out = (float *)malloc(sizeof(*out) * olen); /* Allocate output buf. */
|
||||
|
||||
int error, i = 0;
|
||||
SRC_DATA data;
|
||||
|
||||
data.data_in = in;
|
||||
data.data_out = out;
|
||||
data.input_frames = AL(in);
|
||||
data.output_frames = (int)olen;
|
||||
data.src_ratio = orate / irate;
|
||||
error = src_simple(&data, SRC_SINC_FASTEST, 1);
|
||||
|
||||
while (i++ < data.output_frames_gen) /* Print out the resampled data, */
|
||||
printf("%5.2f%c", out[i-1], " \n"[!(i&7) || i == data.output_frames_gen]);
|
||||
printf("%-26s %s\n", arg[0], src_strerror(error)); /* and reported result. */
|
||||
|
||||
if (argc > 3) /* Library version check: */
|
||||
printf("runtime=%s\n", src_get_version());
|
||||
|
||||
free(out); /* Tidy up. */
|
||||
return !!error;
|
||||
}
|
|
@ -1,78 +1,78 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Example 2: resample a raw, single-channel, floating-point data stream from
|
||||
* stdin to stdout.
|
||||
*
|
||||
* The application uses the single function `soxr_process' for both input and
|
||||
* output to/from the resampler; compared to the `input function' approach
|
||||
* (illustrated in example 3) this requires that the application implements
|
||||
* more logic, but one less function.
|
||||
*
|
||||
* Arguments are: INPUT-RATE OUTPUT-RATE
|
||||
*/
|
||||
|
||||
#include <soxr.h>
|
||||
#include "examples-common.h"
|
||||
|
||||
int main(int argc, char const * arg[])
|
||||
{
|
||||
double const irate = argc > 1? atof(arg[1]) : 96000.;
|
||||
double const orate = argc > 2? atof(arg[2]) : 44100.;
|
||||
|
||||
/* Allocate resampling input and output buffers in proportion to the input
|
||||
* and output rates: */
|
||||
#define buf_total_len 15000 /* In samples. */
|
||||
size_t const olen = (size_t)(orate * buf_total_len / (irate + orate) + .5);
|
||||
size_t const ilen = buf_total_len - olen;
|
||||
size_t const osize = sizeof(float), isize = osize;
|
||||
void * obuf = malloc(osize * olen);
|
||||
void * ibuf = malloc(isize * ilen);
|
||||
|
||||
size_t odone, written, need_input = 1;
|
||||
soxr_error_t error;
|
||||
|
||||
/* Create a stream resampler: */
|
||||
soxr_t soxr = soxr_create(
|
||||
irate, orate, 1, /* Input rate, output rate, # of channels. */
|
||||
&error, /* To report any error during creation. */
|
||||
NULL, NULL, NULL); /* Use configuration defaults.*/
|
||||
|
||||
if (!error) { /* If all is well, run the resampler: */
|
||||
USE_STD_STDIO;
|
||||
/* Resample in blocks: */
|
||||
do {
|
||||
size_t ilen1 = 0;
|
||||
|
||||
if (need_input) {
|
||||
|
||||
/* Read one block into the buffer, ready to be resampled: */
|
||||
ilen1 = fread(ibuf, isize, ilen, stdin);
|
||||
|
||||
if (!ilen1) { /* If the is no (more) input data available, */
|
||||
free(ibuf); /* set ibuf to NULL, to indicate end-of-input */
|
||||
ibuf = NULL; /* to the resampler. */
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy data from the input buffer into the resampler, and resample
|
||||
* to produce as much output as is possible to the given output buffer: */
|
||||
error = soxr_process(soxr, ibuf, ilen1, NULL, obuf, olen, &odone);
|
||||
|
||||
written = fwrite(obuf, osize, odone, stdout); /* Consume output.*/
|
||||
|
||||
/* If the actual amount of data output is less than that requested, and
|
||||
* we have not already reached the end of the input data, then supply some
|
||||
* more input next time round the loop: */
|
||||
need_input = odone < olen && ibuf;
|
||||
|
||||
} while (!error && (need_input || written));
|
||||
}
|
||||
/* Tidy up: */
|
||||
soxr_delete(soxr);
|
||||
free(obuf), free(ibuf);
|
||||
/* Diagnostics: */
|
||||
fprintf(stderr, "%-26s %s; I/O: %s\n", arg[0],
|
||||
soxr_strerror(error), errno? strerror(errno) : "no error");
|
||||
return error || errno;
|
||||
}
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Example 2: resample a raw, single-channel, floating-point data stream from
|
||||
* stdin to stdout.
|
||||
*
|
||||
* The application uses the single function `soxr_process' for both input and
|
||||
* output to/from the resampler; compared to the `input function' approach
|
||||
* (illustrated in example 3) this requires that the application implements
|
||||
* more logic, but one less function.
|
||||
*
|
||||
* Arguments are: INPUT-RATE OUTPUT-RATE
|
||||
*/
|
||||
|
||||
#include <soxr.h>
|
||||
#include "examples-common.h"
|
||||
|
||||
int main(int argc, char const * arg[])
|
||||
{
|
||||
double const irate = argc > 1? atof(arg[1]) : 96000.;
|
||||
double const orate = argc > 2? atof(arg[2]) : 44100.;
|
||||
|
||||
/* Allocate resampling input and output buffers in proportion to the input
|
||||
* and output rates: */
|
||||
#define buf_total_len 15000 /* In samples. */
|
||||
size_t const olen = (size_t)(orate * buf_total_len / (irate + orate) + .5);
|
||||
size_t const ilen = buf_total_len - olen;
|
||||
size_t const osize = sizeof(float), isize = osize;
|
||||
void * obuf = malloc(osize * olen);
|
||||
void * ibuf = malloc(isize * ilen);
|
||||
|
||||
size_t odone, written, need_input = 1;
|
||||
soxr_error_t error;
|
||||
|
||||
/* Create a stream resampler: */
|
||||
soxr_t soxr = soxr_create(
|
||||
irate, orate, 1, /* Input rate, output rate, # of channels. */
|
||||
&error, /* To report any error during creation. */
|
||||
NULL, NULL, NULL); /* Use configuration defaults.*/
|
||||
|
||||
if (!error) { /* If all is well, run the resampler: */
|
||||
USE_STD_STDIO;
|
||||
/* Resample in blocks: */
|
||||
do {
|
||||
size_t ilen1 = 0;
|
||||
|
||||
if (need_input) {
|
||||
|
||||
/* Read one block into the buffer, ready to be resampled: */
|
||||
ilen1 = fread(ibuf, isize, ilen, stdin);
|
||||
|
||||
if (!ilen1) { /* If the is no (more) input data available, */
|
||||
free(ibuf); /* set ibuf to NULL, to indicate end-of-input */
|
||||
ibuf = NULL; /* to the resampler. */
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy data from the input buffer into the resampler, and resample
|
||||
* to produce as much output as is possible to the given output buffer: */
|
||||
error = soxr_process(soxr, ibuf, ilen1, NULL, obuf, olen, &odone);
|
||||
|
||||
written = fwrite(obuf, osize, odone, stdout); /* Consume output.*/
|
||||
|
||||
/* If the actual amount of data output is less than that requested, and
|
||||
* we have not already reached the end of the input data, then supply some
|
||||
* more input next time round the loop: */
|
||||
need_input = odone < olen && ibuf;
|
||||
|
||||
} while (!error && (need_input || written));
|
||||
}
|
||||
/* Tidy up: */
|
||||
soxr_delete(soxr);
|
||||
free(obuf), free(ibuf);
|
||||
/* Diagnostics: */
|
||||
fprintf(stderr, "%-26s %s; I/O: %s\n", arg[0],
|
||||
soxr_strerror(error), errno? strerror(errno) : "no error");
|
||||
return error || errno;
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Example 2a: resample a raw, single-channel, floating-point data stream from
|
||||
* stdin to stdout. The application uses the single function `soxr_process'
|
||||
* for both input and output to/from the resampler.
|
||||
*
|
||||
* Arguments are: INPUT-RATE OUTPUT-RATE
|
||||
*/
|
||||
|
||||
#include <soxr.h>
|
||||
#include "examples-common.h"
|
||||
|
||||
int main(int argc, char const * arg[])
|
||||
{
|
||||
double irate = argc > 1? atof(arg[1]) : 44100.;
|
||||
double orate = argc > 2? atof(arg[2]) : 96000.;
|
||||
|
||||
soxr_error_t error;
|
||||
|
||||
soxr_t resampler = soxr_create(
|
||||
irate, orate, 1, /* Input rate, output rate, # of channels. */
|
||||
&error, /* To report any error during creation. */
|
||||
NULL, NULL, NULL); /* Use configuration defaults.*/
|
||||
|
||||
if (!error) {
|
||||
#define buf_total_len 12000 /* In samples. */
|
||||
|
||||
/* Allocate resampling input and output buffers in proportion to the input
|
||||
* and output rates: */
|
||||
size_t ibuflen = (size_t)(irate * buf_total_len / (irate + orate) + .5);
|
||||
size_t obuflen = buf_total_len - ibuflen;
|
||||
char * ibuf = malloc(sizeof(float) * ibuflen), * iptr = 0;
|
||||
void * obuf = malloc(sizeof(float) * obuflen);
|
||||
|
||||
size_t iavailable = 0;
|
||||
size_t idone, odone, written;
|
||||
|
||||
USE_STD_STDIO;
|
||||
do { /* Resample in blocks: */
|
||||
if (!iavailable && ibuf) { /* If ibuf is empty, try to fill it: */
|
||||
iavailable = fread(ibuf, sizeof(float), ibuflen, stdin);
|
||||
if (!iavailable) /* If none available, don't retry. Pass NULL */
|
||||
free(ibuf), ibuf = 0;/* ibuf to resampler to indicate end-of-input. */
|
||||
iptr = ibuf; /* Reset input to the start of the buffer. */
|
||||
}
|
||||
|
||||
error = soxr_process(resampler,
|
||||
iptr, iavailable, &idone, obuf, obuflen, &odone);
|
||||
|
||||
iptr += idone * sizeof(float); /* Update input buffer according to how */
|
||||
iavailable -= idone; /* much the resampler has consumed. */
|
||||
|
||||
written = fwrite(obuf, sizeof(float), odone, stdout); /* Consume output.*/
|
||||
} while (!error && (ibuf || written));
|
||||
/* Tidy up: */
|
||||
free(obuf), free(ibuf);
|
||||
soxr_delete(resampler);
|
||||
}
|
||||
/* Diagnostics: */
|
||||
fprintf(stderr, "%-26s %s; I/O: %s\n", arg[0],
|
||||
soxr_strerror(error), errno? strerror(errno) : "no error");
|
||||
return error || errno;
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Example 2b: resample a raw, single-channel, floating-point data stream from
|
||||
* stdin to stdout. The application provides an input function, called on
|
||||
* demand by libsoxr, in response to calls to soxr_output().
|
||||
*
|
||||
* Arguments are: INPUT-RATE OUTPUT-RATE
|
||||
*/
|
||||
|
||||
#include <soxr.h>
|
||||
#include "examples-common.h"
|
||||
|
||||
#define iolen 10000
|
||||
|
||||
static size_t input_fn(
|
||||
void * p, /* Generic pointer to any state variables neded here. */
|
||||
soxr_cbuf_t * buf, /* To tell the resampler where the data is. */
|
||||
size_t requested_len) /* In samples per channel. */
|
||||
{
|
||||
static float * ibuf; /* Static context; this could be changed using `p'. */
|
||||
size_t actual;
|
||||
size_t len = min(requested_len, iolen);
|
||||
|
||||
/* Allocate the input buffer memory; check for errors: */
|
||||
*buf = ibuf = (float *)realloc(ibuf, sizeof(float) * len);
|
||||
if (!ibuf)
|
||||
return 0; /* Indicate failure (*buf is also 0). */
|
||||
|
||||
/* Read samples from the input stream; check for errors: */
|
||||
actual = fread(ibuf, sizeof(float), len, stdin);
|
||||
if (!actual) {
|
||||
if (ferror(stdin))
|
||||
*buf = 0; /* Indicate failure (actual is also 0). */
|
||||
free(ibuf), ibuf = 0;
|
||||
}
|
||||
|
||||
return actual;
|
||||
(void)p; /* Not used in this example. */
|
||||
}
|
||||
|
||||
int main(int argc, char const * arg[])
|
||||
{
|
||||
double irate = argc > 1? atof(arg[1]) : 44100.;
|
||||
double orate = argc > 2? atof(arg[2]) : 96000.;
|
||||
|
||||
soxr_error_t error;
|
||||
soxr_t resampler = soxr_create(irate, orate, 1, &error, 0, 0, 0);
|
||||
if (!error) /* Register input_fn with the resampler: */
|
||||
error = soxr_set_input_fn(resampler, input_fn, 0);
|
||||
|
||||
if (!error) { /* If all is good, run the resampler: */
|
||||
float resampled[iolen];
|
||||
size_t actual;
|
||||
/* Resample in blocks: */
|
||||
USE_STD_STDIO;
|
||||
do actual = soxr_output(resampler, resampled, iolen);
|
||||
while (fwrite(resampled, sizeof(float), actual, stdout));
|
||||
|
||||
error = soxr_error(resampler); /* Note: before deleting the resampler! */
|
||||
soxr_delete(resampler);
|
||||
}
|
||||
/* Diagnostics: */
|
||||
fprintf(stderr, "%-26s %s; I/O: %s\n", arg[0],
|
||||
soxr_strerror(error), errno? strerror(errno) : "no error");
|
||||
return error || errno;
|
||||
}
|
|
@ -1,97 +1,110 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Example 3: extends example 2 with multiple channels, multiple datatypes,
|
||||
* and other options.
|
||||
*
|
||||
* The application provides an input function, called on demand by libsoxr, in
|
||||
* response to calls to soxr_output(); compared to the `process' approach
|
||||
* (illustrated in example 2) this requires that the application implements
|
||||
* less logic, but one more function.
|
||||
*
|
||||
* The eight arguments (which are optional, from last to first) are:
|
||||
* INPUT-RATE As example 2
|
||||
* OUTPUT-RATE Ditto
|
||||
* NUM-CHANNELS Number of interleaved channels
|
||||
* IN-DATATYPE# 0:float32 1:float64 2:int32 3:int16
|
||||
* OUT-DATATYPE# Ditto
|
||||
* Q-RECIPE Quality recipe (in hex) See soxr.h
|
||||
* Q-FLAGS Quality flags (in hex) See soxr.h
|
||||
* USE-THREADS 1 to use multi-threading (where available)
|
||||
*/
|
||||
|
||||
#include <soxr.h>
|
||||
#include "examples-common.h"
|
||||
|
||||
typedef struct {void * ibuf; size_t isize;} input_context_t;
|
||||
|
||||
static size_t input_fn(input_context_t * p, soxr_cbuf_t * buf, size_t len)
|
||||
{
|
||||
/* Read one block into the buffer, ready to be input to the resampler: */
|
||||
len = fread(p->ibuf, p->isize, len, stdin); /* Actual len read may be less. */
|
||||
|
||||
/* Inform the resampler of the data's whereabouts (which could be anywhere, in
|
||||
* a freshly malloc'd buffer, for example): */
|
||||
*buf = (!len && ferror(stdin))? NULL : p->ibuf; /* NULL if error occurred. */
|
||||
|
||||
return len; /* # of samples per channel to input. */
|
||||
}
|
||||
|
||||
int main(int n, char const * arg[])
|
||||
{
|
||||
char const * const arg0 = n? --n, *arg++ : "";
|
||||
double const irate = n? --n, atof(*arg++) : 96000.;
|
||||
double const orate = n? --n, atof(*arg++) : 44100.;
|
||||
unsigned const chans = n? --n, (unsigned)atoi(*arg++) : 1;
|
||||
soxr_datatype_t const itype = n? --n, (soxr_datatype_t)atoi(*arg++) : 0;
|
||||
soxr_datatype_t const otype = n? --n, (soxr_datatype_t)atoi(*arg++) : 0;
|
||||
unsigned long const q_recipe= n? --n, strtoul(*arg++, 0, 16) : SOXR_HQ;
|
||||
unsigned long const q_flags = n? --n, strtoul(*arg++, 0, 16) : 0;
|
||||
int const use_threads = n? --n, atoi(*arg++) : 1;
|
||||
|
||||
soxr_quality_spec_t const q_spec = soxr_quality_spec(q_recipe, q_flags);
|
||||
soxr_io_spec_t const io_spec = soxr_io_spec(itype, otype);
|
||||
soxr_runtime_spec_t const runtime_spec = soxr_runtime_spec(!use_threads);
|
||||
|
||||
/* Allocate resampling input and output buffers in proportion to the input
|
||||
* and output rates: */
|
||||
#define buf_total_len 15000 /* In samples per channel. */
|
||||
size_t const osize = soxr_datatype_size(otype) * chans;
|
||||
size_t const isize = soxr_datatype_size(itype) * chans;
|
||||
size_t const olen = (size_t)(orate * buf_total_len / (irate + orate) + .5);
|
||||
size_t const ilen = buf_total_len - olen;
|
||||
void * const obuf = malloc(osize * olen);
|
||||
void * const ibuf = malloc(isize * ilen);
|
||||
|
||||
input_context_t icontext;
|
||||
size_t odone, clips = 0;
|
||||
soxr_error_t error;
|
||||
|
||||
/* Create a stream resampler: */
|
||||
soxr_t soxr = soxr_create(
|
||||
irate, orate, chans, /* Input rate, output rate, # of channels. */
|
||||
&error, /* To report any error during creation. */
|
||||
&io_spec, &q_spec, &runtime_spec);
|
||||
|
||||
if (!error) { /* Register input_fn with the resampler: */
|
||||
icontext.ibuf = ibuf, icontext.isize = isize;
|
||||
error = soxr_set_input_fn(soxr, (soxr_input_fn_t)input_fn, &icontext, ilen);
|
||||
}
|
||||
|
||||
if (!error) { /* If all is well, run the resampler: */
|
||||
USE_STD_STDIO;
|
||||
/* Resample in blocks: */
|
||||
do odone = soxr_output(soxr, obuf, olen);
|
||||
while (fwrite(obuf, osize, odone, stdout)); /* Consume output. */
|
||||
|
||||
error = soxr_error(soxr); /* Check if any soxr error occurred. */
|
||||
clips = *soxr_num_clips(soxr); /* Can occur only with integer output. */
|
||||
}
|
||||
/* Tidy up: */
|
||||
soxr_delete(soxr);
|
||||
free(obuf), free(ibuf);
|
||||
/* Diagnostics: */
|
||||
fprintf(stderr, "%-26s %s; %lu clips; I/O: %s\n", arg0, soxr_strerror(error),
|
||||
(long unsigned)clips, errno? strerror(errno) : "no error");
|
||||
return error || errno;
|
||||
}
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Example 3: extends example 2 with multiple channels, multiple datatypes,
|
||||
* and other options.
|
||||
*
|
||||
* The application provides an input function, called on demand by libsoxr, in
|
||||
* response to calls to soxr_output(); compared to the `process' approach
|
||||
* (illustrated in example 2) this requires that the application implements
|
||||
* less logic, but one more function.
|
||||
*
|
||||
* The 11 arguments (which are optional, from last to first) are:
|
||||
* INPUT-RATE As example 2
|
||||
* OUTPUT-RATE Ditto
|
||||
* NUM-CHANNELS Number of interleaved channels
|
||||
* IN-DATATYPE# 0:float32 1:float64 2:int32 3:int16
|
||||
* OUT-DATATYPE# Ditto
|
||||
* Q-RECIPE Quality recipe (in hex) See soxr.h
|
||||
* Q-FLAGS Quality flags (in hex) See soxr.h
|
||||
* PASSBAND-END %
|
||||
* STOPBAND-BEGIN %
|
||||
* PHASE-RESPONSE [0,100]
|
||||
* USE-THREADS 1 to use multi-threading (where available)
|
||||
*/
|
||||
|
||||
#include <soxr.h>
|
||||
#include "examples-common.h"
|
||||
|
||||
typedef struct {void * ibuf; size_t isize;} input_context_t;
|
||||
|
||||
static size_t input_fn(input_context_t * p, soxr_cbuf_t * buf, size_t len)
|
||||
{
|
||||
/* Read one block into the buffer, ready to be input to the resampler: */
|
||||
len = fread(p->ibuf, p->isize, len, stdin); /* Actual len read may be less. */
|
||||
|
||||
/* Inform the resampler of the data's whereabouts (which could be anywhere, in
|
||||
* a freshly malloc'd buffer, for example): */
|
||||
*buf = (!len && ferror(stdin))? NULL : p->ibuf; /* NULL if error occurred. */
|
||||
|
||||
return len; /* # of samples per channel to input. */
|
||||
}
|
||||
|
||||
int main(int n, char const * arg[])
|
||||
{
|
||||
char const * const arg0 = n? --n, *arg++ : "";
|
||||
double const irate = n? --n, atof(*arg++) : 96000.;
|
||||
double const orate = n? --n, atof(*arg++) : 44100.;
|
||||
unsigned const chans = n? --n, (unsigned)atoi(*arg++) : 1;
|
||||
soxr_datatype_t const itype = n? --n, (soxr_datatype_t)atoi(*arg++) : 0;
|
||||
soxr_datatype_t const otype = n? --n, (soxr_datatype_t)atoi(*arg++) : 0;
|
||||
unsigned long const q_recipe= n? --n, strtoul(*arg++, 0, 16) : SOXR_HQ;
|
||||
unsigned long const q_flags = n? --n, strtoul(*arg++, 0, 16) : 0;
|
||||
double const passband_end = n? --n, atof(*arg++) : 0;
|
||||
double const stopband_begin = n? --n, atof(*arg++) : 0;
|
||||
double const phase_response = n? --n, atof(*arg++) : -1;
|
||||
int const use_threads = n? --n, atoi(*arg++) : 1;
|
||||
|
||||
soxr_quality_spec_t q_spec = soxr_quality_spec(q_recipe, q_flags);
|
||||
soxr_io_spec_t const io_spec = soxr_io_spec(itype, otype);
|
||||
soxr_runtime_spec_t const runtime_spec = soxr_runtime_spec(!use_threads);
|
||||
|
||||
/* Allocate resampling input and output buffers in proportion to the input
|
||||
* and output rates: */
|
||||
#define buf_total_len 15000 /* In samples per channel. */
|
||||
size_t const osize = soxr_datatype_size(otype) * chans;
|
||||
size_t const isize = soxr_datatype_size(itype) * chans;
|
||||
size_t const olen0= (size_t)(orate * buf_total_len / (irate + orate) + .5);
|
||||
size_t const olen = min(max(olen0, 1), buf_total_len - 1);
|
||||
size_t const ilen = buf_total_len - olen;
|
||||
void * const obuf = malloc(osize * olen);
|
||||
void * const ibuf = malloc(isize * ilen);
|
||||
|
||||
input_context_t icontext;
|
||||
size_t odone, clips = 0;
|
||||
soxr_error_t error;
|
||||
soxr_t soxr;
|
||||
|
||||
/* Overrides (if given): */
|
||||
if (passband_end > 0) q_spec.passband_end = passband_end / 100;
|
||||
if (stopband_begin > 0) q_spec.stopband_begin = stopband_begin / 100;
|
||||
if (phase_response >=0) q_spec.phase_response = phase_response;
|
||||
|
||||
/* Create a stream resampler: */
|
||||
soxr = soxr_create(
|
||||
irate, orate, chans, /* Input rate, output rate, # of channels. */
|
||||
&error, /* To report any error during creation. */
|
||||
&io_spec, &q_spec, &runtime_spec);
|
||||
|
||||
if (!error) { /* Register input_fn with the resampler: */
|
||||
icontext.ibuf = ibuf, icontext.isize = isize;
|
||||
error = soxr_set_input_fn(soxr, (soxr_input_fn_t)input_fn, &icontext, ilen);
|
||||
}
|
||||
|
||||
if (!error) { /* If all is well, run the resampler: */
|
||||
USE_STD_STDIO;
|
||||
/* Resample in blocks: */
|
||||
do odone = soxr_output(soxr, obuf, olen);
|
||||
while (fwrite(obuf, osize, odone, stdout)); /* Consume output. */
|
||||
|
||||
error = soxr_error(soxr); /* Check if any soxr error occurred. */
|
||||
clips = *soxr_num_clips(soxr); /* Can occur only with integer output. */
|
||||
}
|
||||
/* Tidy up: */
|
||||
soxr_delete(soxr);
|
||||
free(obuf), free(ibuf);
|
||||
/* Diagnostics: */
|
||||
fprintf(stderr, "%-26s %s; %lu clips; I/O: %s\n", arg0, soxr_strerror(error),
|
||||
(long unsigned)clips, errno? strerror(errno) : "no error");
|
||||
return error || errno;
|
||||
}
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Example 3a: extends example 2a with multiple channels, multiple datatypes,
|
||||
* and other options.
|
||||
*
|
||||
* The eight arguments are:
|
||||
* INPUT-RATE As example 2a
|
||||
* OUTPUT-RATE Ditto
|
||||
* NUM-CHANNELS Number of interleaved channels
|
||||
* IN-DATATYPE# 0:float32 1:float64 2:int32 3:int16
|
||||
* OUT-DATATYPE# Ditto
|
||||
* Q-RECIPE Quality recipe (in hex) See soxr.h
|
||||
* Q-FLAGS Quality flags (in hex) See soxr.h
|
||||
* USE-THREADS 1 to use multi-threading
|
||||
*/
|
||||
|
||||
#include <soxr.h>
|
||||
#include "examples-common.h"
|
||||
|
||||
int main(int n, char const * arg[])
|
||||
{
|
||||
char const * arg0 = n? --n, *arg++ : "";
|
||||
double irate = n? --n, atof(*arg++) : 96000.;
|
||||
double orate = n? --n, atof(*arg++) : 44100.;
|
||||
unsigned chans = n? --n, (unsigned)atoi(*arg++) : 1;
|
||||
soxr_datatype_t itype = n? --n, (soxr_datatype_t)atoi(*arg++) :SOXR_FLOAT32_I;
|
||||
soxr_datatype_t otype = n? --n, (soxr_datatype_t)atoi(*arg++) :SOXR_FLOAT32_I;
|
||||
unsigned long q_recipe= n? --n, strtoul(*arg++, 0, 16) : SOXR_HQ;
|
||||
unsigned long q_flags = n? --n, strtoul(*arg++, 0, 16) : 0;
|
||||
int use_threads = n? --n, atoi(*arg++) : 1;
|
||||
|
||||
size_t isize = soxr_datatype_size(itype) * chans;
|
||||
size_t osize = soxr_datatype_size(otype) * chans;
|
||||
size_t clips = 0;
|
||||
soxr_error_t error;
|
||||
|
||||
soxr_quality_spec_t q_spec = soxr_quality_spec(q_recipe, q_flags);
|
||||
soxr_io_spec_t io_spec = soxr_io_spec(itype, otype);
|
||||
soxr_runtime_spec_t runtime_spec = soxr_runtime_spec(!use_threads);
|
||||
|
||||
soxr_t resampler = soxr_create(
|
||||
irate, orate, chans, &error, &io_spec, &q_spec, &runtime_spec);
|
||||
|
||||
if (!error) {
|
||||
#define buf_total_len 15000 /* In samples. */
|
||||
|
||||
/* Allocate resampling input and output buffers in proportion to the input
|
||||
* and output rates: */
|
||||
size_t ibuflen = (size_t)(irate * buf_total_len / (irate + orate) + .5);
|
||||
size_t obuflen = buf_total_len - ibuflen;
|
||||
char * ibuf = malloc(isize * ibuflen), * iptr = 0;
|
||||
void * obuf = malloc(osize * obuflen);
|
||||
|
||||
size_t iavailable = 0;
|
||||
size_t idone, odone, written;
|
||||
|
||||
USE_STD_STDIO;
|
||||
do { /* Resample in blocks: */
|
||||
if (!iavailable && ibuf) { /* If ibuf is empty, try to fill it: */
|
||||
iavailable = fread(ibuf, isize, ibuflen, stdin);
|
||||
if (!iavailable) /* If none available, don't retry. Pass NULL */
|
||||
free(ibuf), ibuf = 0;/* ibuf to resampler to indicate end-of-input. */
|
||||
iptr = ibuf; /* Reset input to the start of the buffer. */
|
||||
}
|
||||
|
||||
error = soxr_process(resampler,
|
||||
iptr, iavailable, &idone, obuf, obuflen, &odone);
|
||||
|
||||
iptr += idone * isize; /* Update input buffer according to how */
|
||||
iavailable -= idone; /* much the resampler has consumed. */
|
||||
|
||||
written = fwrite(obuf, osize, odone, stdout); /* Consume output. */
|
||||
} while (!error && (ibuf || written));
|
||||
|
||||
free(obuf), free(ibuf);
|
||||
clips = *soxr_num_clips(resampler); /* Can occur only with integer output.*/
|
||||
soxr_delete(resampler);
|
||||
}
|
||||
fprintf(stderr, "%-26s %s; %lu clips; I/O: %s\n", arg0, soxr_strerror(error),
|
||||
(long unsigned)clips, errno? strerror(errno) : "no error");
|
||||
return error || errno;
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Example 3b: extends example 2b with multiple channels, multiple datatypes,
|
||||
* and other options.
|
||||
*
|
||||
* The eight arguments are:
|
||||
* INPUT-RATE As example 2b
|
||||
* OUTPUT-RATE Ditto
|
||||
* NUM-CHANNELS Number of interleaved channels
|
||||
* IN-DATATYPE# 0:float32 1:float64 2:int32 3:int16
|
||||
* OUT-DATATYPE# Ditto
|
||||
* Q-RECIPE Quality recipe (in hex) See soxr.h
|
||||
* Q-FLAGS Quality flags (in hex) See soxr.h
|
||||
* USE-THREADS 1 to use multi-threading
|
||||
*/
|
||||
|
||||
#include <soxr.h>
|
||||
#include "examples-common.h"
|
||||
|
||||
#define iolen 8000
|
||||
|
||||
|
||||
|
||||
static size_t input_fn(void * p, soxr_cbuf_t * buf, size_t len)
|
||||
{
|
||||
static float * ibuf;
|
||||
size_t isize = *(size_t *)p;
|
||||
len = min(len, iolen);
|
||||
*buf = ibuf = realloc(ibuf, isize * len);
|
||||
if (!ibuf)
|
||||
return 0;
|
||||
len = fread(ibuf, isize, len, stdin);
|
||||
if (!len) {
|
||||
if (ferror(stdin))
|
||||
*buf = 0;
|
||||
free(ibuf), ibuf = 0;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int n, char const * arg[])
|
||||
{
|
||||
char const * arg0 = n? --n, *arg++ : "";
|
||||
double irate = n? --n, atof(*arg++) : 96000.;
|
||||
double orate = n? --n, atof(*arg++) : 44100.;
|
||||
unsigned chans = n? --n, (unsigned)atoi(*arg++) : 1;
|
||||
soxr_datatype_t itype = n? --n, (soxr_datatype_t)atoi(*arg++) :SOXR_FLOAT32_I;
|
||||
soxr_datatype_t otype = n? --n, (soxr_datatype_t)atoi(*arg++) :SOXR_FLOAT32_I;
|
||||
unsigned long q_recipe= n? --n, strtoul(*arg++, 0, 16) : SOXR_HQ;
|
||||
unsigned long q_flags = n? --n, strtoul(*arg++, 0, 16) : 0;
|
||||
int use_threads = n? --n, atoi(*arg++) : 1;
|
||||
|
||||
size_t isize = soxr_datatype_size(itype) * chans;
|
||||
size_t osize = soxr_datatype_size(otype) * chans;
|
||||
size_t clips = 0;
|
||||
soxr_error_t error;
|
||||
|
||||
soxr_quality_spec_t q_spec = soxr_quality_spec(q_recipe, q_flags);
|
||||
soxr_io_spec_t io_spec = soxr_io_spec(itype, otype);
|
||||
soxr_runtime_spec_t runtime_spec = soxr_runtime_spec(!use_threads);
|
||||
|
||||
soxr_t resampler = soxr_create(
|
||||
irate, orate, chans, &error, &io_spec, &q_spec, &runtime_spec);
|
||||
if (!error) error = soxr_set_input_fn(resampler, input_fn, &isize);
|
||||
|
||||
USE_STD_STDIO;
|
||||
if (!error) {
|
||||
void * resampled = malloc(osize * iolen);
|
||||
size_t actual;
|
||||
|
||||
do actual = soxr_output(resampler, resampled, iolen);
|
||||
while (fwrite(resampled, osize, actual, stdout));
|
||||
|
||||
free(resampled);
|
||||
error = soxr_error(resampler);
|
||||
clips = *soxr_num_clips(resampler); /* Can occur only with integer output.*/
|
||||
soxr_delete(resampler);
|
||||
}
|
||||
fprintf(stderr, "%-26s %s; %lu clips; I/O: %s\n", arg0, soxr_strerror(error),
|
||||
(long unsigned)clips, errno? strerror(errno) : "no error");
|
||||
return error || errno;
|
||||
}
|
|
@ -1,147 +1,147 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Example 4: variant of examples 2 & 3, demonstrating I/O with split channels.
|
||||
*
|
||||
* Note that, for convenience of the demonstration, split-channel data is
|
||||
* made available by deinterleaving data sourced from and sent to
|
||||
* interleaved file-streams; this adds a lot of code to the example that,
|
||||
* for purposes of understanding how to use split-channels, may safely be
|
||||
* ignored. In a real application, the channel-data might never be
|
||||
* interleaved; for example, the split-channel data output from the
|
||||
* resampler might be sent directly to digital-to-analogue converters.
|
||||
*
|
||||
* Note also (not shown in the examples) that split/interleaved channels may
|
||||
* be used for input and output independently.
|
||||
*/
|
||||
|
||||
#include <soxr.h>
|
||||
#include "examples-common.h"
|
||||
|
||||
|
||||
|
||||
#define DEINTERLEAVE(T) do { \
|
||||
unsigned i; \
|
||||
size_t j; \
|
||||
T * const * dest = (T * const *)dest0; \
|
||||
T const * src = src0; \
|
||||
if (ch == 1) memcpy(dest[0], src, n * sizeof(dest[0][0])); \
|
||||
else for (j = 0; j < n; ++j) for (i = 0; i < ch; ++i) dest[i][j] = *src++; \
|
||||
return; \
|
||||
} while (0)
|
||||
|
||||
static void deinterleave(soxr_datatype_t data_type,
|
||||
void * const * dest0,
|
||||
void const * src0,
|
||||
size_t n, unsigned ch)
|
||||
{
|
||||
switch (data_type & 3) {
|
||||
case SOXR_FLOAT32: DEINTERLEAVE(float);
|
||||
case SOXR_FLOAT64: DEINTERLEAVE(double);
|
||||
case SOXR_INT32 : DEINTERLEAVE(int32_t);
|
||||
case SOXR_INT16 : DEINTERLEAVE(int16_t);
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
#define INTERLEAVE(T) do { \
|
||||
unsigned i; \
|
||||
size_t j; \
|
||||
T * dest = dest0; \
|
||||
T const * const * src = (T const * const *)src0; \
|
||||
if (ch == 1) memcpy(dest, src[0], n * sizeof(dest[0])); \
|
||||
else for (j = 0; j < n; ++j) for (i = 0; i < ch; ++i) *dest++ = src[i][j]; \
|
||||
return; \
|
||||
} while (0)
|
||||
|
||||
static void interleave(soxr_datatype_t data_type, void * dest0,
|
||||
void * const * src0, size_t n, unsigned ch)
|
||||
{
|
||||
switch (data_type & 3) {
|
||||
case SOXR_FLOAT32: INTERLEAVE(float);
|
||||
case SOXR_FLOAT64: INTERLEAVE(double);
|
||||
case SOXR_INT32 : INTERLEAVE(int32_t);
|
||||
case SOXR_INT16 : INTERLEAVE(int16_t);
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int n, char const * arg[])
|
||||
{
|
||||
char const * const arg0 = n? --n, *arg++ : "";
|
||||
double const irate = n? --n, atof(*arg++) : 96000.;
|
||||
double const orate = n? --n, atof(*arg++) : 44100.;
|
||||
unsigned const chans = n? --n, (unsigned)atoi(*arg++) : 1;
|
||||
soxr_datatype_t const itype = n? --n, (soxr_datatype_t)atoi(*arg++) : 0;
|
||||
soxr_datatype_t const otype = n? --n, (soxr_datatype_t)atoi(*arg++) : 0;
|
||||
unsigned long const q_recipe= n? --n, strtoul(*arg++, 0, 16) : SOXR_HQ;
|
||||
unsigned long const q_flags = n? --n, strtoul(*arg++, 0, 16) : 0;
|
||||
int const use_threads = n? --n, atoi(*arg++) : 1;
|
||||
|
||||
soxr_quality_spec_t const q_spec = soxr_quality_spec(q_recipe, q_flags);
|
||||
soxr_io_spec_t const io_spec=soxr_io_spec(itype|SOXR_SPLIT, otype|SOXR_SPLIT);
|
||||
soxr_runtime_spec_t const runtime_spec = soxr_runtime_spec(!use_threads);
|
||||
|
||||
/* Allocate resampling input and output buffers in proportion to the input
|
||||
* and output rates: */
|
||||
#define buf_total_len 15000 /* In samples per channel. */
|
||||
size_t const osize = soxr_datatype_size(otype) * chans;
|
||||
size_t const isize = soxr_datatype_size(itype) * chans;
|
||||
size_t const olen = (size_t)(orate * buf_total_len / (irate + orate) + .5);
|
||||
size_t const ilen = buf_total_len - olen;
|
||||
|
||||
/* For split channels: */
|
||||
void * * const obuf_ptrs = malloc(sizeof(void *) * chans);
|
||||
void * * ibuf_ptrs = malloc(sizeof(void *) * chans);
|
||||
char * const obufs = malloc(osize * olen), * optr = obufs;
|
||||
char * const ibufs = malloc(isize * ilen), * iptr = ibufs;
|
||||
|
||||
/* For interleaved channels: */
|
||||
char * const obuf = malloc(osize * olen);
|
||||
char * const ibuf = malloc(isize * ilen);
|
||||
|
||||
size_t odone, written, need_input = 1, clips = 0;
|
||||
soxr_error_t error;
|
||||
|
||||
soxr_t soxr = soxr_create(
|
||||
irate, orate, chans, &error, &io_spec, &q_spec, &runtime_spec);
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < chans; ++i) {
|
||||
ibuf_ptrs[i] = iptr;
|
||||
obuf_ptrs[i] = optr;
|
||||
iptr += ilen * soxr_datatype_size(itype);
|
||||
optr += olen * soxr_datatype_size(otype);
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
USE_STD_STDIO;
|
||||
|
||||
do {
|
||||
size_t ilen1 = 0;
|
||||
|
||||
if (need_input) {
|
||||
if (!(ilen1 = fread(ibuf, isize, ilen, stdin)))
|
||||
free(ibuf_ptrs), ibuf_ptrs = 0; /* If none available, don't retry. */
|
||||
else deinterleave(itype, ibuf_ptrs, ibuf, ilen1, chans);
|
||||
}
|
||||
|
||||
error = soxr_process(soxr, ibuf_ptrs, ilen1, NULL, obuf_ptrs, olen, &odone);
|
||||
interleave(otype, obuf, obuf_ptrs, odone, chans); /* Consume output... */
|
||||
written = fwrite(obuf, osize, odone, stdout);
|
||||
|
||||
need_input = odone < olen && ibuf_ptrs;
|
||||
|
||||
} while (!error && (need_input || written));
|
||||
|
||||
clips = *soxr_num_clips(soxr); /* Can occur only with integer output. */
|
||||
}
|
||||
/* Tidy up: */
|
||||
soxr_delete(soxr);
|
||||
free(obuf), free(ibuf), free(obufs), free(ibufs);
|
||||
free(obuf_ptrs), free(ibuf_ptrs);
|
||||
/* Diagnostics: */
|
||||
fprintf(stderr, "%-26s %s; %lu clips; I/O: %s\n", arg0, soxr_strerror(error),
|
||||
(long unsigned)clips, errno? strerror(errno) : "no error");
|
||||
return error || errno;
|
||||
}
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Example 4: variant of examples 2 & 3, demonstrating I/O with split channels.
|
||||
*
|
||||
* Note that, for convenience of the demonstration, split-channel data is
|
||||
* made available by deinterleaving data sourced from and sent to
|
||||
* interleaved file-streams; this adds a lot of code to the example that,
|
||||
* for purposes of understanding how to use split-channels, may safely be
|
||||
* ignored. In a real application, the channel-data might never be
|
||||
* interleaved; for example, the split-channel data output from the
|
||||
* resampler might be sent directly to digital-to-analogue converters.
|
||||
*
|
||||
* Note also (not shown in the examples) that split/interleaved channels may
|
||||
* be used for input and output independently.
|
||||
*/
|
||||
|
||||
#include <soxr.h>
|
||||
#include "examples-common.h"
|
||||
|
||||
|
||||
|
||||
#define DEINTERLEAVE(T) do { \
|
||||
unsigned i; \
|
||||
size_t j; \
|
||||
T * const * dest = (T * const *)dest0; \
|
||||
T const * src = src0; \
|
||||
if (ch == 1) memcpy(dest[0], src, n * sizeof(dest[0][0])); \
|
||||
else for (j = 0; j < n; ++j) for (i = 0; i < ch; ++i) dest[i][j] = *src++; \
|
||||
return; \
|
||||
} while (0)
|
||||
|
||||
static void deinterleave(soxr_datatype_t data_type,
|
||||
void * const * dest0,
|
||||
void const * src0,
|
||||
size_t n, unsigned ch)
|
||||
{
|
||||
switch (data_type & 3) {
|
||||
case SOXR_FLOAT32: DEINTERLEAVE(float);
|
||||
case SOXR_FLOAT64: DEINTERLEAVE(double);
|
||||
case SOXR_INT32 : DEINTERLEAVE(int32_t);
|
||||
case SOXR_INT16 : DEINTERLEAVE(int16_t);
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
#define INTERLEAVE(T) do { \
|
||||
unsigned i; \
|
||||
size_t j; \
|
||||
T * dest = dest0; \
|
||||
T const * const * src = (T const * const *)src0; \
|
||||
if (ch == 1) memcpy(dest, src[0], n * sizeof(dest[0])); \
|
||||
else for (j = 0; j < n; ++j) for (i = 0; i < ch; ++i) *dest++ = src[i][j]; \
|
||||
return; \
|
||||
} while (0)
|
||||
|
||||
static void interleave(soxr_datatype_t data_type, void * dest0,
|
||||
void * const * src0, size_t n, unsigned ch)
|
||||
{
|
||||
switch (data_type & 3) {
|
||||
case SOXR_FLOAT32: INTERLEAVE(float);
|
||||
case SOXR_FLOAT64: INTERLEAVE(double);
|
||||
case SOXR_INT32 : INTERLEAVE(int32_t);
|
||||
case SOXR_INT16 : INTERLEAVE(int16_t);
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int n, char const * arg[])
|
||||
{
|
||||
char const * const arg0 = n? --n, *arg++ : "";
|
||||
double const irate = n? --n, atof(*arg++) : 96000.;
|
||||
double const orate = n? --n, atof(*arg++) : 44100.;
|
||||
unsigned const chans = n? --n, (unsigned)atoi(*arg++) : 1;
|
||||
soxr_datatype_t const itype = n? --n, (soxr_datatype_t)atoi(*arg++) : 0;
|
||||
soxr_datatype_t const otype = n? --n, (soxr_datatype_t)atoi(*arg++) : 0;
|
||||
unsigned long const q_recipe= n? --n, strtoul(*arg++, 0, 16) : SOXR_HQ;
|
||||
unsigned long const q_flags = n? --n, strtoul(*arg++, 0, 16) : 0;
|
||||
int const use_threads = n? --n, atoi(*arg++) : 1;
|
||||
|
||||
soxr_quality_spec_t const q_spec = soxr_quality_spec(q_recipe, q_flags);
|
||||
soxr_io_spec_t const io_spec=soxr_io_spec(itype|SOXR_SPLIT, otype|SOXR_SPLIT);
|
||||
soxr_runtime_spec_t const runtime_spec = soxr_runtime_spec(!use_threads);
|
||||
|
||||
/* Allocate resampling input and output buffers in proportion to the input
|
||||
* and output rates: */
|
||||
#define buf_total_len 15000 /* In samples per channel. */
|
||||
size_t const osize = soxr_datatype_size(otype) * chans;
|
||||
size_t const isize = soxr_datatype_size(itype) * chans;
|
||||
size_t const olen = (size_t)(orate * buf_total_len / (irate + orate) + .5);
|
||||
size_t const ilen = buf_total_len - olen;
|
||||
|
||||
/* For split channels: */
|
||||
void * * const obuf_ptrs = malloc(sizeof(void *) * chans);
|
||||
void * * ibuf_ptrs = malloc(sizeof(void *) * chans);
|
||||
char * const obufs = malloc(osize * olen), * optr = obufs;
|
||||
char * const ibufs = malloc(isize * ilen), * iptr = ibufs;
|
||||
|
||||
/* For interleaved channels: */
|
||||
char * const obuf = malloc(osize * olen);
|
||||
char * const ibuf = malloc(isize * ilen);
|
||||
|
||||
size_t odone, written, need_input = 1, clips = 0;
|
||||
soxr_error_t error;
|
||||
|
||||
soxr_t soxr = soxr_create(
|
||||
irate, orate, chans, &error, &io_spec, &q_spec, &runtime_spec);
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < chans; ++i) {
|
||||
ibuf_ptrs[i] = iptr;
|
||||
obuf_ptrs[i] = optr;
|
||||
iptr += ilen * soxr_datatype_size(itype);
|
||||
optr += olen * soxr_datatype_size(otype);
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
USE_STD_STDIO;
|
||||
|
||||
do {
|
||||
size_t ilen1 = 0;
|
||||
|
||||
if (need_input) {
|
||||
if (!(ilen1 = fread(ibuf, isize, ilen, stdin)))
|
||||
free(ibuf_ptrs), ibuf_ptrs = 0; /* If none available, don't retry. */
|
||||
else deinterleave(itype, ibuf_ptrs, ibuf, ilen1, chans);
|
||||
}
|
||||
|
||||
error = soxr_process(soxr, ibuf_ptrs, ilen1, NULL, obuf_ptrs, olen, &odone);
|
||||
interleave(otype, obuf, obuf_ptrs, odone, chans); /* Consume output... */
|
||||
written = fwrite(obuf, osize, odone, stdout);
|
||||
|
||||
need_input = odone < olen && ibuf_ptrs;
|
||||
|
||||
} while (!error && (need_input || written));
|
||||
|
||||
clips = *soxr_num_clips(soxr); /* Can occur only with integer output. */
|
||||
}
|
||||
/* Tidy up: */
|
||||
soxr_delete(soxr);
|
||||
free(obuf), free(ibuf), free(obufs), free(ibufs);
|
||||
free(obuf_ptrs), free(ibuf_ptrs);
|
||||
/* Diagnostics: */
|
||||
fprintf(stderr, "%-26s %s; %lu clips; I/O: %s\n", arg0, soxr_strerror(error),
|
||||
(long unsigned)clips, errno? strerror(errno) : "no error");
|
||||
return error || errno;
|
||||
}
|
||||
|
|
|
@ -1,94 +1,94 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Example 5: Variable-rate resampling (N.B. experimental). A test signal
|
||||
* (held in a buffer) is resampled over a wide range of octaves. Resampled
|
||||
* data is sent to stdout as raw, float32 samples. Choices of 2 test-signals
|
||||
* and of 2 ways of varying the sample-rate are combined in a command-line
|
||||
* option:
|
||||
*
|
||||
* Usage: ./5-variable-rate [0|1|2|3]
|
||||
*/
|
||||
|
||||
#include <soxr.h>
|
||||
#include "examples-common.h"
|
||||
|
||||
#define OCTAVES 5 /* Resampling range. ± */
|
||||
#define OLEN 16 /* Output length in seconds. */
|
||||
#define FS 44100 /* Output sampling rate in Hz. */
|
||||
|
||||
/* For output pos in [0,1], returns an ioratio in the 2^±OCTAVES range: */
|
||||
static double ioratio(double pos, int fm)
|
||||
{
|
||||
if (fm) /* fm: non-0 for a fast-changing ioratio, 0 for a slow sweep. */
|
||||
pos = .5 - cos(pos * 2 * M_PI) * .4 + sin(pos * OLEN * 20 * M_PI) * .05;
|
||||
return pow(2, 2 * OCTAVES * pos - OCTAVES);
|
||||
}
|
||||
|
||||
int main(int argc, char *arg[])
|
||||
{
|
||||
int opt = argc <= 1? 2 : (atoi(arg[1]) & 3), saw = opt & 1, fm = opt & 2;
|
||||
float ibuf[10 << OCTAVES], obuf[AL(ibuf)];
|
||||
int i, wl = 2 << OCTAVES;
|
||||
size_t ilen = AL(ibuf), need_input = 1;
|
||||
size_t odone, total_odone, total_olen = OLEN * FS;
|
||||
size_t olen1 = fm? 10 : AL(obuf); /* Small block-len if fast-changing ratio */
|
||||
soxr_error_t error;
|
||||
|
||||
/* When creating a var-rate resampler, q_spec must be set as follows: */
|
||||
soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_HQ, SOXR_VR);
|
||||
|
||||
/* The ratio of the given input rate and output rates must equate to the
|
||||
* maximum I/O ratio that will be used: */
|
||||
soxr_t soxr = soxr_create(1 << OCTAVES, 1, 1, &error, NULL, &q_spec, NULL);
|
||||
|
||||
if (!error) {
|
||||
USE_STD_STDIO;
|
||||
|
||||
/* Generate input signal, sine or saw, with wave-length = wl: */
|
||||
for (i = 0; i < (int)ilen; ++i)
|
||||
ibuf[i] = (float)(saw? (i%wl)/(wl-1.)-.5 : .9 * sin(2 * M_PI * i / wl));
|
||||
|
||||
/* Set the initial resampling ratio (N.B. 3rd parameter = 0): */
|
||||
soxr_set_io_ratio(soxr, ioratio(0, fm), 0);
|
||||
|
||||
/* Resample in blocks of size olen1: */
|
||||
for (total_odone = 0; !error && total_odone < total_olen;) {
|
||||
|
||||
/* The last block might be shorter: */
|
||||
size_t block_len = min(olen1, total_olen - total_odone);
|
||||
|
||||
/* Determine the position in [0,1] of the end of the current block: */
|
||||
double pos = (double)(total_odone + block_len) / (double)total_olen;
|
||||
|
||||
/* Calculate an ioratio for this position and instruct the resampler to
|
||||
* move smoothly to the new value, over the course of outputting the next
|
||||
* 'block_len' samples (or give 0 for an instant change instead): */
|
||||
soxr_set_io_ratio(soxr, ioratio(pos, fm), block_len);
|
||||
|
||||
/* Output the block of samples, supplying input samples as needed: */
|
||||
do {
|
||||
size_t len = need_input? ilen : 0;
|
||||
error = soxr_process(soxr, ibuf, len, NULL, obuf, block_len, &odone);
|
||||
fwrite(obuf, sizeof(float), odone, stdout);
|
||||
|
||||
/* Update counters for the current block and for the total length: */
|
||||
block_len -= odone;
|
||||
total_odone += odone;
|
||||
|
||||
/* If soxr_process did not provide the complete block, we must call it
|
||||
* again, supplying more input samples: */
|
||||
need_input = block_len != 0;
|
||||
|
||||
} while (need_input && !error);
|
||||
|
||||
/* Now that the block for the current ioratio is complete, go back
|
||||
* round the main `for' loop in order to process the next block. */
|
||||
}
|
||||
soxr_delete(soxr);
|
||||
}
|
||||
/* Diagnostics: */
|
||||
fprintf(stderr, "%-26s %s; I/O: %s\n", arg[0],
|
||||
soxr_strerror(error), errno? strerror(errno) : "no error");
|
||||
return error || errno;
|
||||
}
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Example 5: Variable-rate resampling (N.B. experimental). A test signal
|
||||
* (held in a buffer) is resampled over a wide range of octaves. Resampled
|
||||
* data is sent to stdout as raw, float32 samples. Choices of 2 test-signals
|
||||
* and of 2 ways of varying the sample-rate are combined in a command-line
|
||||
* option:
|
||||
*
|
||||
* Usage: ./5-variable-rate [0|1|2|3]
|
||||
*/
|
||||
|
||||
#include <soxr.h>
|
||||
#include "examples-common.h"
|
||||
|
||||
#define OCTAVES 5 /* Resampling range. ± */
|
||||
#define OLEN 16 /* Output length in seconds. */
|
||||
#define FS 44100 /* Output sampling rate in Hz. */
|
||||
|
||||
/* For output pos in [0,1], returns an ioratio in the 2^±OCTAVES range: */
|
||||
static double ioratio(double pos, int fm)
|
||||
{
|
||||
if (fm) /* fm: non-0 for a fast-changing ioratio, 0 for a slow sweep. */
|
||||
pos = .5 - cos(pos * 2 * M_PI) * .4 + sin(pos * OLEN * 20 * M_PI) * .05;
|
||||
return pow(2, 2 * OCTAVES * pos - OCTAVES);
|
||||
}
|
||||
|
||||
int main(int argc, char *arg[])
|
||||
{
|
||||
int opt = argc <= 1? 2 : (atoi(arg[1]) & 3), saw = opt & 1, fm = opt & 2;
|
||||
float ibuf[10 << OCTAVES], obuf[AL(ibuf)];
|
||||
int i, wl = 2 << OCTAVES;
|
||||
size_t ilen = AL(ibuf), need_input = 1;
|
||||
size_t odone, total_odone, total_olen = OLEN * FS;
|
||||
size_t olen1 = fm? 10 : AL(obuf); /* Small block-len if fast-changing ratio */
|
||||
soxr_error_t error;
|
||||
|
||||
/* When creating a var-rate resampler, q_spec must be set as follows: */
|
||||
soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_HQ, SOXR_VR);
|
||||
|
||||
/* The ratio of the given input rate and output rates must equate to the
|
||||
* maximum I/O ratio that will be used: */
|
||||
soxr_t soxr = soxr_create(1 << OCTAVES, 1, 1, &error, NULL, &q_spec, NULL);
|
||||
|
||||
if (!error) {
|
||||
USE_STD_STDIO;
|
||||
|
||||
/* Generate input signal, sine or saw, with wave-length = wl: */
|
||||
for (i = 0; i < (int)ilen; ++i)
|
||||
ibuf[i] = (float)(saw? (i%wl)/(wl-1.)-.5 : .9 * sin(2 * M_PI * i / wl));
|
||||
|
||||
/* Set the initial resampling ratio (N.B. 3rd parameter = 0): */
|
||||
soxr_set_io_ratio(soxr, ioratio(0, fm), 0);
|
||||
|
||||
/* Resample in blocks of size olen1: */
|
||||
for (total_odone = 0; !error && total_odone < total_olen;) {
|
||||
|
||||
/* The last block might be shorter: */
|
||||
size_t block_len = min(olen1, total_olen - total_odone);
|
||||
|
||||
/* Determine the position in [0,1] of the end of the current block: */
|
||||
double pos = (double)(total_odone + block_len) / (double)total_olen;
|
||||
|
||||
/* Calculate an ioratio for this position and instruct the resampler to
|
||||
* move smoothly to the new value, over the course of outputting the next
|
||||
* 'block_len' samples (or give 0 for an instant change instead): */
|
||||
soxr_set_io_ratio(soxr, ioratio(pos, fm), block_len);
|
||||
|
||||
/* Output the block of samples, supplying input samples as needed: */
|
||||
do {
|
||||
size_t len = need_input? ilen : 0;
|
||||
error = soxr_process(soxr, ibuf, len, NULL, obuf, block_len, &odone);
|
||||
fwrite(obuf, sizeof(float), odone, stdout);
|
||||
|
||||
/* Update counters for the current block and for the total length: */
|
||||
block_len -= odone;
|
||||
total_odone += odone;
|
||||
|
||||
/* If soxr_process did not provide the complete block, we must call it
|
||||
* again, supplying more input samples: */
|
||||
need_input = block_len != 0;
|
||||
|
||||
} while (need_input && !error);
|
||||
|
||||
/* Now that the block for the current ioratio is complete, go back
|
||||
* round the main `for' loop in order to process the next block. */
|
||||
}
|
||||
soxr_delete(soxr);
|
||||
}
|
||||
/* Diagnostics: */
|
||||
fprintf(stderr, "%-26s %s; I/O: %s\n", arg[0],
|
||||
soxr_strerror(error), errno? strerror(errno) : "no error");
|
||||
return error || errno;
|
||||
}
|
||||
|
|
|
@ -1,21 +1,37 @@
|
|||
# SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
# Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
if (${BUILD_EXAMPLES})
|
||||
project (soxr)
|
||||
file (GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.[cC])
|
||||
if (NOT BUILD_SHARED_LIBS AND OPENMP_FOUND)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_C_FLAGS}")
|
||||
endif ()
|
||||
else ()
|
||||
file (GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/3*.c)
|
||||
endif ()
|
||||
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PROJECT_C_FLAGS}")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PROJECT_CXX_FLAGS}")
|
||||
link_libraries (${PROJECT_NAME})
|
||||
|
||||
foreach (fe ${SOURCES})
|
||||
get_filename_component (f ${fe} NAME_WE)
|
||||
add_executable (${f} ${fe})
|
||||
endforeach ()
|
||||
# SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
# Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
if (${BUILD_EXAMPLES})
|
||||
project (soxr) # Adds c++ compiler
|
||||
file (GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/[1-9]-*.[cC])
|
||||
elseif (${BUILD_TESTS})
|
||||
file (GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/3*.c)
|
||||
endif ()
|
||||
|
||||
if (${BUILD_EXAMPLES} OR ${BUILD_TESTS})
|
||||
if (${WITH_LSR_BINDINGS})
|
||||
set (LSR_SOURCES 1a-lsr.c)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (NOT BUILD_SHARED_LIBS AND OPENMP_FOUND)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_C_FLAGS}")
|
||||
endif ()
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PROJECT_C_FLAGS}")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PROJECT_CXX_FLAGS}")
|
||||
link_libraries (${PROJECT_NAME})
|
||||
|
||||
foreach (fe ${SOURCES} ${LSR_SOURCES})
|
||||
get_filename_component (f ${fe} NAME_WE)
|
||||
add_executable (${f} ${fe})
|
||||
if (${f} STREQUAL "1a-lsr")
|
||||
target_link_libraries (${f} soxr-lsr)
|
||||
endif ()
|
||||
endforeach ()
|
||||
|
||||
if (${BUILD_TESTS} AND ${WITH_LSR_BINDINGS})
|
||||
add_test (lsr-bindings ${BIN}1a-lsr)
|
||||
endif ()
|
||||
|
||||
file (GLOB INSTALL_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.[cCh])
|
||||
install (FILES ${INSTALL_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/README DESTINATION ${DOC_INSTALL_DIR}/examples)
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
|
||||
These simple examples show the different ways that an application may
|
||||
interface with libsoxr. Note that real-world applications may also have to
|
||||
deal with file-formats, codecs, (more sophisticated) dithering, etc., which
|
||||
are not covered here.
|
||||
|
||||
With libsoxr installed, the examples may be built using commands similar to
|
||||
the following. On unix-like systems:
|
||||
|
||||
cc 1-single-block.c -lsoxr
|
||||
|
||||
or, on MS-Windows:
|
||||
|
||||
cl 1-single-block.c -I"C:/Program Files/soxr/include" "C:/Program Files/soxr/lib/soxr.lib"
|
||||
|
||||
IDEs may hide such commands behind configuration screens and build menus --
|
||||
where applicable, consult your IDE's user-manual.
|
||||
SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
|
||||
These simple examples show the different ways that an application may
|
||||
interface with soxr. Note that real-world applications may also have to
|
||||
deal with file-formats, codecs, (more sophisticated) dithering, etc., which
|
||||
are not covered here.
|
||||
|
||||
With the library installed, the examples may be built using commands similar
|
||||
to the following. On unix-like systems:
|
||||
|
||||
cc 1-single-block.c -lsoxr
|
||||
cc 1a-lsr.c -lsoxr-lsr
|
||||
|
||||
or, with MSVC on MS-Windows:
|
||||
|
||||
cl 1-single-block.c -I"C:/Program Files/soxr/include" "C:/Program Files/soxr/lib/soxr.lib"
|
||||
cl 1a-lsr.c -I"C:/Program Files/soxr/include" "C:/Program Files/soxr/lib/soxr-lsr.lib"
|
||||
|
||||
IDEs may hide such commands behind configuration screens and build menus --
|
||||
where applicable, consult your IDE's user-manual.
|
||||
|
|
|
@ -1,45 +1,45 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Common includes etc. for the examples. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Work-around for broken file-I/O on MS-Windows: */
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#define USE_STD_STDIO _setmode(_fileno(stdout), _O_BINARY), \
|
||||
_setmode(_fileno(stdin ), _O_BINARY);
|
||||
/* Sometimes missing, so ensure that it is defined: */
|
||||
#undef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#else
|
||||
#define USE_STD_STDIO
|
||||
#endif
|
||||
|
||||
#undef int16_t
|
||||
#define int16_t short
|
||||
|
||||
#undef int32_t
|
||||
#if LONG_MAX > 2147483647L
|
||||
#define int32_t int
|
||||
#elif LONG_MAX < 2147483647L
|
||||
#error this programme requires that 'long int' has at least 32-bits
|
||||
#else
|
||||
#define int32_t long
|
||||
#endif
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
#define min(x,y) ((x)<(y)?(x):(y))
|
||||
#define max(x,y) ((x)>(y)?(x):(y))
|
||||
|
||||
#define AL(a) (sizeof(a)/sizeof((a)[0])) /* Array Length */
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Common includes etc. for the examples. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Work-around for broken file-I/O on MS-Windows: */
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#define USE_STD_STDIO _setmode(_fileno(stdout), _O_BINARY), \
|
||||
_setmode(_fileno(stdin ), _O_BINARY);
|
||||
/* Sometimes missing, so ensure that it is defined: */
|
||||
#undef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#else
|
||||
#define USE_STD_STDIO
|
||||
#endif
|
||||
|
||||
#undef int16_t
|
||||
#define int16_t short
|
||||
|
||||
#undef int32_t
|
||||
#if LONG_MAX > 2147483647L
|
||||
#define int32_t int
|
||||
#elif LONG_MAX < 2147483647L
|
||||
#error this programme requires that 'long int' has at least 32-bits
|
||||
#else
|
||||
#define int32_t long
|
||||
#endif
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
#define min(x,y) ((x)<(y)?(x):(y))
|
||||
#define max(x,y) ((x)>(y)?(x):(y))
|
||||
|
||||
#define AL(a) (sizeof(a)/sizeof((a)[0])) /* Array Length */
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
#!/bin/sh
|
||||
# SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
# Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
build=$1
|
||||
test x$build = x && build=Release
|
||||
|
||||
rm -f CMakeCache.txt # Prevent interference from any in-tree build
|
||||
|
||||
mkdir -p $build
|
||||
cd $build
|
||||
|
||||
cmake -DCMAKE_BUILD_TYPE=$build -DBUILD_TESTS=ON .. &&
|
||||
make &&
|
||||
(make test || echo "FAILURE details in $build/Testing/Temporary/LastTest.log")
|
||||
#!/bin/sh
|
||||
# SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
# Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
case $1 in -j*) j=$1; shift;; esac # Support -jX for parallel build/test
|
||||
|
||||
build=$1
|
||||
test x$build = x && build=Release
|
||||
|
||||
rm -f CMakeCache.txt # Prevent interference from any in-tree build
|
||||
|
||||
mkdir -p $build
|
||||
cd $build
|
||||
|
||||
cmake -DCMAKE_BUILD_TYPE=$build .. &&
|
||||
make $j &&
|
||||
(ctest $j || echo "FAILURE details in $build/Testing/Temporary/LastTest.log")
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
@echo off
|
||||
rem SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
rem Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
set build=%1
|
||||
if x%build% == x set build=Release
|
||||
|
||||
rem Prevent interference from any in-tree build
|
||||
del/f CMakeCache.txt
|
||||
|
||||
mkdir %build%
|
||||
cd %build%
|
||||
|
||||
cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=%build% -DBUILD_TESTS=ON ..
|
||||
if errorlevel 1 goto end
|
||||
|
||||
nmake
|
||||
if errorlevel 1 goto end
|
||||
|
||||
nmake test
|
||||
if errorlevel 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
echo FAILURE details in Testing\Temporary\LastTest.log
|
||||
|
||||
:end
|
||||
@echo off
|
||||
rem SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
rem Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
set build=%1
|
||||
if x%build% == x set build=Release
|
||||
|
||||
rem Prevent interference from any in-tree build
|
||||
del/f CMakeCache.txt
|
||||
|
||||
mkdir %build%
|
||||
cd %build%
|
||||
|
||||
cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=%build% ..
|
||||
if errorlevel 1 goto end
|
||||
|
||||
nmake
|
||||
if errorlevel 1 goto end
|
||||
|
||||
nmake test
|
||||
if errorlevel 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
echo FAILURE details in Testing\Temporary\LastTest.log
|
||||
|
||||
:end
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
# SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
# Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
# Sanity-check of library installed on unix-like system
|
||||
|
||||
# This script checks the installation of the entire library (including lsr).
|
||||
#
|
||||
# Distros using three separate packages can do the following (in order):
|
||||
#
|
||||
# * Install soxr pkg (i.e. basically, just the shared object)
|
||||
# * ./inst-check-soxr
|
||||
# * Install soxr-lsr pkg (i.e. basically, just the shared object)
|
||||
# * ./inst-check-soxr-lsr
|
||||
# * Install the -dev pkg (i.e. examples, headers, & pkg-config)
|
||||
# * ./inst-check PATH-OF-INSTALLED-EXAMPLES-DIR (e.g. /usr/share/doc/libsoxr/examples)
|
||||
|
||||
# Where are the example source files:
|
||||
src=$1
|
||||
test x$src = x && src=/usr/local/share/doc/libsoxr/examples
|
||||
|
||||
dir="$(dirname $(readlink -f $0))"
|
||||
$dir/inst-check-soxr $src
|
||||
$dir/inst-check-soxr-lsr $src
|
|
@ -0,0 +1,52 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
# SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
# Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
# Sanity-check of sub-library installed on unix-like system
|
||||
|
||||
arg="$1" # path to installed examples (if dev pkg installed); otherwise omitted
|
||||
dir="$(dirname $(readlink -f $0))"
|
||||
|
||||
# Find the examples:
|
||||
src="$arg"
|
||||
test x"$src" = x && src="$dir/examples"
|
||||
cd $src
|
||||
|
||||
# Somewhere to put the binaries:
|
||||
tmp=`mktemp -d`
|
||||
|
||||
build_examples() {
|
||||
if [ x"$arg" = x ]; then
|
||||
echo "Examples in `pwd`; using local headers:" # for when dev pkg not installed
|
||||
libs=-l$1
|
||||
cflags=-I$dir/src
|
||||
else
|
||||
echo "Examples in `pwd`; using pkg-config:"
|
||||
libs=$(pkg-config --libs $1)
|
||||
cflags=$(pkg-config --cflags $1)
|
||||
fi
|
||||
for f in ?$2-*.[cC]; do
|
||||
cc=cc; echo $f | grep -q C$ && cc=c++
|
||||
out=$tmp/`echo $f | sed "s/.[cC]$//"`
|
||||
cmd="$cc $cflags -o $out $f $libs"
|
||||
echo $cmd; $cmd
|
||||
done
|
||||
}
|
||||
|
||||
# Determine library:
|
||||
if [ `basename $0` = inst-check-soxr ]; then
|
||||
build_examples soxr
|
||||
gen="dd if=/dev/urandom count=1000"
|
||||
$tmp/1-single-block 1 2 .
|
||||
$gen 2> /dev/null | $tmp/2-stream 2>&1 >$tmp/stdout
|
||||
$gen 2> /dev/null | $tmp/3-options-input-fn 6 7 2 2 0 2>&1 >$tmp/stdout
|
||||
$gen 2> /dev/null | $tmp/4-split-channels 7 6 2 2 3 2>&1 >$tmp/stdout # Clipping expected here
|
||||
$gen 2> /dev/null | $tmp/5-variable-rate 2>&1 >$tmp/stdout
|
||||
else
|
||||
build_examples soxr-lsr a # lsr has 'a' suffix on example number.
|
||||
$tmp/1a-lsr 1 2 .
|
||||
fi
|
||||
|
||||
# Tidy up:
|
||||
rm -rf $tmp
|
|
@ -1,49 +0,0 @@
|
|||
# SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
# Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
list (APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules)
|
||||
|
||||
find_package (FFTW)
|
||||
if (FFTW_FOUND)
|
||||
include_directories (${FFTW_INCLUDE_DIRS})
|
||||
link_libraries (${FFTW_LIBRARIES})
|
||||
set (HAVE_FFTW3 1)
|
||||
endif ()
|
||||
|
||||
find_package (sndfile)
|
||||
if (SNDFILE_FOUND)
|
||||
include_directories (${SNDFILE_INCLUDE_DIRS})
|
||||
link_libraries (${SNDFILE_LIBRARIES})
|
||||
set (HAVE_SNDFILE 1)
|
||||
endif ()
|
||||
|
||||
check_function_exists (lrintf HAVE_LRINTF)
|
||||
check_function_exists (alarm HAVE_ALARM)
|
||||
check_function_exists (signal HAVE_SIGNAL)
|
||||
check_include_files (sys/times.h HAVE_SYS_TIMES_H)
|
||||
make_exist (HAVE_LRINTF HAVE_ALARM HAVE_SIGNAL HAVE_SYS_TIMES_H)
|
||||
make_exist (HAVE_FFTW HAVE_SNDFILE)
|
||||
|
||||
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||
include_directories (${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
add_library (tests_lib SHARED util calc_snr)
|
||||
|
||||
link_libraries (tests_lib ${PROJECT_NAME}-lsr)
|
||||
|
||||
enable_testing ()
|
||||
|
||||
set (tests
|
||||
callback_hang_test callback_test downsample_test
|
||||
float_short_test misc_test multi_channel_test
|
||||
reset_test simple_test snr_bw_test termination_test varispeed_test)
|
||||
|
||||
foreach (test ${tests})
|
||||
add_executable (${test} ${test})
|
||||
add_test (lsr-${test} ${BIN}${test})
|
||||
set_property (TEST lsr-${test} PROPERTY ENVIRONMENT "SOXR_LSR_STRICT=1")
|
||||
endforeach ()
|
||||
|
||||
add_executable (multichan_throughput_test multichan_throughput_test)
|
||||
add_executable (throughput_test throughput_test )
|
||||
add_executable (sndfile-resample sndfile-resample)
|
|
@ -1,340 +0,0 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
|
@ -1,8 +0,0 @@
|
|||
The C source and header files in this directory have been copied from
|
||||
the `libsamplerate' project and are copyrighted by its authors -- see
|
||||
the notices within the files and the file `COPYING' for details.
|
||||
|
||||
They are used here to test libsoxr's optional libsamplerate-like
|
||||
wrapper. The only modifications made are to the file `snr_bw_test.c' to
|
||||
remove reliance on certain frequency response troughs that are specific
|
||||
to libsamplerate.
|
|
@ -1,242 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#if (HAVE_FFTW3 == 1)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <fftw3.h>
|
||||
|
||||
#define MAX_SPEC_LEN (1<<18)
|
||||
#define MAX_PEAKS 10
|
||||
|
||||
static void log_mag_spectrum (double *input, int len, double *magnitude) ;
|
||||
static void smooth_mag_spectrum (double *magnitude, int len) ;
|
||||
static double find_snr (const double *magnitude, int len, int expected_peaks) ;
|
||||
|
||||
typedef struct
|
||||
{ double peak ;
|
||||
int index ;
|
||||
} PEAK_DATA ;
|
||||
|
||||
double
|
||||
calculate_snr (float *data, int len, int expected_peaks)
|
||||
{ static double magnitude [MAX_SPEC_LEN] ;
|
||||
static double datacopy [MAX_SPEC_LEN] ;
|
||||
|
||||
double snr = 200.0 ;
|
||||
int k ;
|
||||
|
||||
if (len > MAX_SPEC_LEN)
|
||||
{ printf ("%s : line %d : data length too large.\n", __FILE__, __LINE__) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
for (k = 0 ; k < len ; k++)
|
||||
datacopy [k] = data [k] ;
|
||||
|
||||
/* Pad the data just a little to speed up the FFT. */
|
||||
while ((len & 0x1F) && len < MAX_SPEC_LEN)
|
||||
{ datacopy [len] = 0.0 ;
|
||||
len ++ ;
|
||||
} ;
|
||||
|
||||
log_mag_spectrum (datacopy, len, magnitude) ;
|
||||
smooth_mag_spectrum (magnitude, len / 2) ;
|
||||
|
||||
snr = find_snr (magnitude, len, expected_peaks) ;
|
||||
|
||||
return snr ;
|
||||
} /* calculate_snr */
|
||||
|
||||
/*==============================================================================
|
||||
** There is a slight problem with trying to measure SNR with the method used
|
||||
** here; the side lobes of the windowed FFT can look like a noise/aliasing peak.
|
||||
** The solution is to smooth the magnitude spectrum by wiping out troughs
|
||||
** between adjacent peaks as done here.
|
||||
** This removes side lobe peaks without affecting noise/aliasing peaks.
|
||||
*/
|
||||
|
||||
static void linear_smooth (double *mag, PEAK_DATA *larger, PEAK_DATA *smaller) ;
|
||||
|
||||
static void
|
||||
smooth_mag_spectrum (double *mag, int len)
|
||||
{ PEAK_DATA peaks [2] ;
|
||||
|
||||
int k ;
|
||||
|
||||
memset (peaks, 0, sizeof (peaks)) ;
|
||||
|
||||
/* Find first peak. */
|
||||
for (k = 1 ; k < len - 1 ; k++)
|
||||
{ if (mag [k - 1] < mag [k] && mag [k] >= mag [k + 1])
|
||||
{ peaks [0].peak = mag [k] ;
|
||||
peaks [0].index = k ;
|
||||
break ;
|
||||
} ;
|
||||
} ;
|
||||
|
||||
/* Find subsequent peaks ans smooth between peaks. */
|
||||
for (k = peaks [0].index + 1 ; k < len - 1 ; k++)
|
||||
{ if (mag [k - 1] < mag [k] && mag [k] >= mag [k + 1])
|
||||
{ peaks [1].peak = mag [k] ;
|
||||
peaks [1].index = k ;
|
||||
|
||||
if (peaks [1].peak > peaks [0].peak)
|
||||
linear_smooth (mag, &peaks [1], &peaks [0]) ;
|
||||
else
|
||||
linear_smooth (mag, &peaks [0], &peaks [1]) ;
|
||||
peaks [0] = peaks [1] ;
|
||||
} ;
|
||||
} ;
|
||||
|
||||
} /* smooth_mag_spectrum */
|
||||
|
||||
static void
|
||||
linear_smooth (double *mag, PEAK_DATA *larger, PEAK_DATA *smaller)
|
||||
{ int k ;
|
||||
|
||||
if (smaller->index < larger->index)
|
||||
{ for (k = smaller->index + 1 ; k < larger->index ; k++)
|
||||
mag [k] = (mag [k] < mag [k - 1]) ? 0.999 * mag [k - 1] : mag [k] ;
|
||||
}
|
||||
else
|
||||
{ for (k = smaller->index - 1 ; k >= larger->index ; k--)
|
||||
mag [k] = (mag [k] < mag [k + 1]) ? 0.999 * mag [k + 1] : mag [k] ;
|
||||
} ;
|
||||
|
||||
} /* linear_smooth */
|
||||
|
||||
/*==============================================================================
|
||||
*/
|
||||
|
||||
static int
|
||||
peak_compare (const void *vp1, const void *vp2)
|
||||
{ const PEAK_DATA *peak1, *peak2 ;
|
||||
|
||||
peak1 = (const PEAK_DATA*) vp1 ;
|
||||
peak2 = (const PEAK_DATA*) vp2 ;
|
||||
|
||||
return (peak1->peak < peak2->peak) ? 1 : -1 ;
|
||||
} /* peak_compare */
|
||||
|
||||
static double
|
||||
find_snr (const double *magnitude, int len, int expected_peaks)
|
||||
{ PEAK_DATA peaks [MAX_PEAKS] ;
|
||||
|
||||
int k, peak_count = 0 ;
|
||||
double snr ;
|
||||
|
||||
memset (peaks, 0, sizeof (peaks)) ;
|
||||
|
||||
/* Find the MAX_PEAKS largest peaks. */
|
||||
for (k = 1 ; k < len - 1 ; k++)
|
||||
{ if (magnitude [k - 1] < magnitude [k] && magnitude [k] >= magnitude [k + 1])
|
||||
{ if (peak_count < MAX_PEAKS)
|
||||
{ peaks [peak_count].peak = magnitude [k] ;
|
||||
peaks [peak_count].index = k ;
|
||||
peak_count ++ ;
|
||||
qsort (peaks, peak_count, sizeof (PEAK_DATA), peak_compare) ;
|
||||
}
|
||||
else if (magnitude [k] > peaks [MAX_PEAKS - 1].peak)
|
||||
{ peaks [MAX_PEAKS - 1].peak = magnitude [k] ;
|
||||
peaks [MAX_PEAKS - 1].index = k ;
|
||||
qsort (peaks, MAX_PEAKS, sizeof (PEAK_DATA), peak_compare) ;
|
||||
} ;
|
||||
} ;
|
||||
} ;
|
||||
|
||||
if (peak_count < expected_peaks)
|
||||
{ printf ("\n%s : line %d : bad peak_count (%d), expected %d.\n\n", __FILE__, __LINE__, peak_count, expected_peaks) ;
|
||||
return -1.0 ;
|
||||
} ;
|
||||
|
||||
/* Sort the peaks. */
|
||||
qsort (peaks, peak_count, sizeof (PEAK_DATA), peak_compare) ;
|
||||
|
||||
snr = peaks [0].peak ;
|
||||
for (k = 1 ; k < peak_count ; k++)
|
||||
if (fabs (snr - peaks [k].peak) > 10.0)
|
||||
return fabs (peaks [k].peak) ;
|
||||
|
||||
return snr ;
|
||||
} /* find_snr */
|
||||
|
||||
static void
|
||||
log_mag_spectrum (double *input, int len, double *magnitude)
|
||||
{ fftw_plan plan = NULL ;
|
||||
|
||||
double maxval ;
|
||||
int k ;
|
||||
|
||||
if (input == NULL || magnitude == NULL)
|
||||
return ;
|
||||
|
||||
plan = fftw_plan_r2r_1d (len, input, magnitude, FFTW_R2HC, FFTW_ESTIMATE | FFTW_PRESERVE_INPUT) ;
|
||||
if (plan == NULL)
|
||||
{ printf ("%s : line %d : create plan failed.\n", __FILE__, __LINE__) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
fftw_execute (plan) ;
|
||||
|
||||
fftw_destroy_plan (plan) ;
|
||||
|
||||
/* (k < N/2 rounded up) */
|
||||
maxval = 0.0 ;
|
||||
for (k = 1 ; k < len / 2 ; k++)
|
||||
{ magnitude [k] = sqrt (magnitude [k] * magnitude [k] + magnitude [len - k - 1] * magnitude [len - k - 1]) ;
|
||||
maxval = (maxval < magnitude [k]) ? magnitude [k] : maxval ;
|
||||
} ;
|
||||
|
||||
memset (magnitude + len / 2, 0, len / 2 * sizeof (magnitude [0])) ;
|
||||
|
||||
/* Don't care about DC component. Make it zero. */
|
||||
magnitude [0] = 0.0 ;
|
||||
|
||||
/* log magnitude. */
|
||||
for (k = 0 ; k < len ; k++)
|
||||
{ magnitude [k] = magnitude [k] / maxval ;
|
||||
magnitude [k] = (magnitude [k] < 1e-15) ? -200.0 : 20.0 * log10 (magnitude [k]) ;
|
||||
} ;
|
||||
|
||||
return ;
|
||||
} /* log_mag_spectrum */
|
||||
|
||||
#else /* ! (HAVE_LIBFFTW && HAVE_LIBRFFTW) */
|
||||
|
||||
double
|
||||
calculate_snr (float *data, int len, int expected_peaks)
|
||||
{ double snr = 200.0 ;
|
||||
|
||||
data = data ;
|
||||
len = len ;
|
||||
expected_peaks = expected_peaks ;
|
||||
|
||||
return snr ;
|
||||
} /* calculate_snr */
|
||||
|
||||
#endif
|
||||
|
|
@ -1,131 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
|
||||
#if HAVE_ALARM && HAVE_SIGNAL && HAVE_SIGALRM
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include <samplerate.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#define SHORT_BUFFER_LEN 512
|
||||
#define LONG_BUFFER_LEN (1 << 14)
|
||||
|
||||
typedef struct
|
||||
{ double ratio ;
|
||||
int count ;
|
||||
} SRC_PAIR ;
|
||||
|
||||
static void callback_hang_test (int converter) ;
|
||||
|
||||
static void alarm_handler (int number) ;
|
||||
static long input_callback (void *cb_data, float **data) ;
|
||||
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
/* Set up SIGALRM handler. */
|
||||
signal (SIGALRM, alarm_handler) ;
|
||||
|
||||
puts ("") ;
|
||||
callback_hang_test (SRC_ZERO_ORDER_HOLD) ;
|
||||
callback_hang_test (SRC_LINEAR) ;
|
||||
callback_hang_test (SRC_SINC_FASTEST) ;
|
||||
puts ("") ;
|
||||
|
||||
return 0 ;
|
||||
} /* main */
|
||||
|
||||
|
||||
static void
|
||||
callback_hang_test (int converter)
|
||||
{ static float output [LONG_BUFFER_LEN] ;
|
||||
static SRC_PAIR pairs [] =
|
||||
{
|
||||
{ 1.2, 5 }, { 1.1, 1 }, { 1.0, 1 }, { 3.0, 1 }, { 2.0, 1 }, { 0.3, 1 },
|
||||
{ 1.2, 0 }, { 1.1, 10 }, { 1.0, 1 }
|
||||
} ;
|
||||
|
||||
|
||||
SRC_STATE *src_state ;
|
||||
|
||||
double src_ratio = 1.0 ;
|
||||
int k, error ;
|
||||
|
||||
printf ("\tcallback_hang_test (%-28s) ....... ", src_get_name (converter)) ;
|
||||
fflush (stdout) ;
|
||||
|
||||
/* Perform sample rate conversion. */
|
||||
src_state = src_callback_new (input_callback, converter, 1, &error, NULL) ;
|
||||
if (src_state == NULL)
|
||||
{ printf ("\n\nLine %d : src_callback_new () failed : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
for (k = 0 ; k < ARRAY_LEN (pairs) ; k++)
|
||||
{ alarm (1) ;
|
||||
src_ratio = pairs [k].ratio ;
|
||||
src_callback_read (src_state, src_ratio, pairs [k].count, output) ;
|
||||
} ;
|
||||
|
||||
src_state = src_delete (src_state) ;
|
||||
|
||||
alarm (0) ;
|
||||
puts ("ok") ;
|
||||
|
||||
return ;
|
||||
} /* callback_hang_test */
|
||||
|
||||
static void
|
||||
alarm_handler (int number)
|
||||
{
|
||||
(void) number ;
|
||||
printf ("\n\n Error : Hang inside src_callback_read() detected. Exiting!\n\n") ;
|
||||
exit (1) ;
|
||||
} /* alarm_handler */
|
||||
|
||||
static long
|
||||
input_callback (void *cb_data, float **data)
|
||||
{
|
||||
static float buffer [20] ;
|
||||
|
||||
(void) cb_data ;
|
||||
*data = buffer ;
|
||||
|
||||
return ARRAY_LEN (buffer) ;
|
||||
} /* input_callback */
|
||||
|
||||
#else
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
puts ("\tCan't run this test on this platform.") ;
|
||||
return 0 ;
|
||||
} /* main */
|
||||
|
||||
#endif
|
|
@ -1,243 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2003-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <samplerate.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#define BUFFER_LEN 10000
|
||||
#define CB_READ_LEN 256
|
||||
|
||||
static void callback_test (int converter, double ratio) ;
|
||||
static void end_of_stream_test (int converter) ;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{ static double src_ratios [] =
|
||||
{ 1.0, 0.099, 0.1, 0.33333333, 0.789, 1.0001, 1.9, 3.1, 9.9
|
||||
} ;
|
||||
|
||||
int k ;
|
||||
|
||||
puts ("") ;
|
||||
|
||||
puts (" Zero Order Hold interpolator :") ;
|
||||
for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
|
||||
callback_test (SRC_ZERO_ORDER_HOLD, src_ratios [k]) ;
|
||||
|
||||
puts (" Linear interpolator :") ;
|
||||
for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
|
||||
callback_test (SRC_LINEAR, src_ratios [k]) ;
|
||||
|
||||
puts (" Sinc interpolator :") ;
|
||||
for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
|
||||
callback_test (SRC_SINC_FASTEST, src_ratios [k]) ;
|
||||
|
||||
puts ("") ;
|
||||
|
||||
puts (" End of stream test :") ;
|
||||
end_of_stream_test (SRC_ZERO_ORDER_HOLD) ;
|
||||
end_of_stream_test (SRC_LINEAR) ;
|
||||
end_of_stream_test (SRC_SINC_FASTEST) ;
|
||||
|
||||
puts ("") ;
|
||||
return 0 ;
|
||||
} /* main */
|
||||
|
||||
/*=====================================================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{ int channels ;
|
||||
long count, total ;
|
||||
int end_of_data ;
|
||||
float data [BUFFER_LEN] ;
|
||||
} TEST_CB_DATA ;
|
||||
|
||||
static long
|
||||
test_callback_func (void *cb_data, float **data)
|
||||
{ TEST_CB_DATA *pcb_data ;
|
||||
|
||||
long frames ;
|
||||
|
||||
if ((pcb_data = cb_data) == NULL)
|
||||
return 0 ;
|
||||
|
||||
if (data == NULL)
|
||||
return 0 ;
|
||||
|
||||
if (pcb_data->total - pcb_data->count > CB_READ_LEN)
|
||||
frames = CB_READ_LEN / pcb_data->channels ;
|
||||
else
|
||||
frames = (pcb_data->total - pcb_data->count) / pcb_data->channels ;
|
||||
|
||||
*data = pcb_data->data + pcb_data->count ;
|
||||
pcb_data->count += frames ;
|
||||
|
||||
return frames ;
|
||||
} /* test_callback_func */
|
||||
|
||||
|
||||
static void
|
||||
callback_test (int converter, double src_ratio)
|
||||
{ static TEST_CB_DATA test_callback_data ;
|
||||
static float output [BUFFER_LEN] ;
|
||||
|
||||
SRC_STATE *src_state ;
|
||||
|
||||
long read_count, read_total ;
|
||||
int error ;
|
||||
|
||||
printf ("\tcallback_test (SRC ratio = %6.4f) ........... ", src_ratio) ;
|
||||
fflush (stdout) ;
|
||||
|
||||
test_callback_data.channels = 2 ;
|
||||
test_callback_data.count = 0 ;
|
||||
test_callback_data.end_of_data = 0 ;
|
||||
test_callback_data.total = ARRAY_LEN (test_callback_data.data) ;
|
||||
|
||||
if ((src_state = src_callback_new (test_callback_func, converter, test_callback_data.channels, &error, &test_callback_data)) == NULL)
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
read_total = 0 ;
|
||||
do
|
||||
{ /* We will be throwing away output data, so just grab as much as possible. */
|
||||
read_count = ARRAY_LEN (output) / test_callback_data.channels ;
|
||||
read_count = src_callback_read (src_state, src_ratio, read_count, output) ;
|
||||
read_total += read_count ;
|
||||
}
|
||||
while (read_count > 0) ;
|
||||
|
||||
if ((error = src_error (src_state)) != 0)
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
src_state = src_delete (src_state) ;
|
||||
|
||||
if (fabs (read_total / src_ratio - ARRAY_LEN (test_callback_data.data)) > 2.0)
|
||||
{ printf ("\n\nLine %d : input / output length mismatch.\n\n", __LINE__) ;
|
||||
printf (" input len : %d\n", ARRAY_LEN (test_callback_data.data)) ;
|
||||
printf (" output len : %ld (should be %g +/- 2)\n\n", read_total,
|
||||
floor (0.5 + src_ratio * ARRAY_LEN (test_callback_data.data))) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
puts ("ok") ;
|
||||
|
||||
return ;
|
||||
} /* callback_test */
|
||||
|
||||
/*=====================================================================================
|
||||
*/
|
||||
|
||||
static long
|
||||
eos_callback_func (void *cb_data, float **data)
|
||||
{
|
||||
TEST_CB_DATA *pcb_data ;
|
||||
long frames ;
|
||||
|
||||
if (data == NULL)
|
||||
return 0 ;
|
||||
|
||||
if ((pcb_data = cb_data) == NULL)
|
||||
return 0 ;
|
||||
|
||||
/*
|
||||
** Return immediately if there is no more data.
|
||||
** In this case, the output pointer 'data' will not be set and
|
||||
** valgrind should not warn about it.
|
||||
*/
|
||||
if (pcb_data->end_of_data)
|
||||
return 0 ;
|
||||
|
||||
if (pcb_data->total - pcb_data->count > CB_READ_LEN)
|
||||
frames = CB_READ_LEN / pcb_data->channels ;
|
||||
else
|
||||
frames = (pcb_data->total - pcb_data->count) / pcb_data->channels ;
|
||||
|
||||
*data = pcb_data->data + pcb_data->count ;
|
||||
pcb_data->count += frames ;
|
||||
|
||||
/*
|
||||
** Set end_of_data so that the next call to the callback function will
|
||||
** return zero ocunt without setting the 'data' pointer.
|
||||
*/
|
||||
if (pcb_data->total < 2 * pcb_data->count)
|
||||
pcb_data->end_of_data = 1 ;
|
||||
|
||||
return frames ;
|
||||
} /* eos_callback_data */
|
||||
|
||||
|
||||
static void
|
||||
end_of_stream_test (int converter)
|
||||
{ static TEST_CB_DATA test_callback_data ;
|
||||
static float output [BUFFER_LEN] ;
|
||||
|
||||
SRC_STATE *src_state ;
|
||||
|
||||
double src_ratio = 0.3 ;
|
||||
long read_count, read_total ;
|
||||
int error ;
|
||||
|
||||
printf ("\t%-30s ........... ", src_get_name (converter)) ;
|
||||
fflush (stdout) ;
|
||||
|
||||
test_callback_data.channels = 2 ;
|
||||
test_callback_data.count = 0 ;
|
||||
test_callback_data.end_of_data = 0 ;
|
||||
test_callback_data.total = ARRAY_LEN (test_callback_data.data) ;
|
||||
|
||||
if ((src_state = src_callback_new (eos_callback_func, converter, test_callback_data.channels, &error, &test_callback_data)) == NULL)
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
read_total = 0 ;
|
||||
do
|
||||
{ /* We will be throwing away output data, so just grab as much as possible. */
|
||||
read_count = ARRAY_LEN (output) / test_callback_data.channels ;
|
||||
read_count = src_callback_read (src_state, src_ratio, read_count, output) ;
|
||||
read_total += read_count ;
|
||||
}
|
||||
while (read_count > 0) ;
|
||||
|
||||
if ((error = src_error (src_state)) != 0)
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
src_state = src_delete (src_state) ;
|
||||
|
||||
if (test_callback_data.end_of_data == 0)
|
||||
{ printf ("\n\nLine %d : test_callback_data.end_of_data should not be 0."
|
||||
" This is a bug in the test.\n\n", __LINE__) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
puts ("ok") ;
|
||||
return ;
|
||||
} /* end_of_stream_test */
|
|
@ -1,23 +0,0 @@
|
|||
# SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
# Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
# - Find FFTW
|
||||
# Find the native installation of this package: includes and libraries.
|
||||
#
|
||||
# FFTW_INCLUDES - where to find headers for this package.
|
||||
# FFTW_LIBRARIES - List of libraries when using this package.
|
||||
# FFTW_FOUND - True if this package can be found.
|
||||
|
||||
if (FFTW_INCLUDES)
|
||||
set (FFTW_FIND_QUIETLY TRUE)
|
||||
endif (FFTW_INCLUDES)
|
||||
|
||||
find_path (FFTW_INCLUDES fftw3.h)
|
||||
|
||||
find_library (FFTW_LIBRARIES NAMES fftw3)
|
||||
|
||||
include (FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args (
|
||||
FFTW DEFAULT_MSG FFTW_LIBRARIES FFTW_INCLUDES)
|
||||
|
||||
mark_as_advanced (FFTW_LIBRARIES FFTW_INCLUDES)
|
|
@ -1,23 +0,0 @@
|
|||
# SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
# Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
# - Find SNDFILE
|
||||
# Find the native installation of this package: includes and libraries.
|
||||
#
|
||||
# SNDFILE_INCLUDES - where to find headers for this package.
|
||||
# SNDFILE_LIBRARIES - List of libraries when using this package.
|
||||
# SNDFILE_FOUND - True if this package can be found.
|
||||
|
||||
if (SNDFILE_INCLUDES)
|
||||
set (SNDFILE_FIND_QUIETLY TRUE)
|
||||
endif (SNDFILE_INCLUDES)
|
||||
|
||||
find_path (SNDFILE_INCLUDES sndfile.h)
|
||||
|
||||
find_library (SNDFILE_LIBRARIES NAMES sndfile)
|
||||
|
||||
include (FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args (
|
||||
SNDFILE DEFAULT_MSG SNDFILE_LIBRARIES SNDFILE_INCLUDES)
|
||||
|
||||
mark_as_advanced (SNDFILE_LIBRARIES SNDFILE_INCLUDES)
|
|
@ -1,24 +0,0 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#if !defined soxsrc_lsr_tests_config_included
|
||||
#define soxsrc_lsr_tests_config_included
|
||||
|
||||
#define HAVE_ALARM @HAVE_ALARM@
|
||||
#define HAVE_FFTW3 @HAVE_FFTW3@
|
||||
#define HAVE_LRINTF @HAVE_LRINTF@
|
||||
#define HAVE_LRINT @HAVE_LRINT@
|
||||
#define HAVE_SIGNAL @HAVE_SIGNAL@
|
||||
#define HAVE_SNDFILE @HAVE_SNDFILE@
|
||||
#define HAVE_SYS_TIMES_H @HAVE_SYS_TIMES_H@
|
||||
|
||||
#if HAVE_SIGNAL
|
||||
#include <signal.h>
|
||||
#if defined SIGALRM
|
||||
#define HAVE_SIGALRM 1
|
||||
#else
|
||||
#define HAVE_SIGALRM 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2008-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <samplerate.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
static void
|
||||
downsample_test (int converter)
|
||||
{ static float in [1000], out [10] ;
|
||||
SRC_DATA data ;
|
||||
|
||||
printf (" downsample_test (%-28s) ....... ", src_get_name (converter)) ;
|
||||
fflush (stdout) ;
|
||||
|
||||
data.src_ratio = 1.0 / 255.0 ;
|
||||
data.input_frames = ARRAY_LEN (in) ;
|
||||
data.output_frames = ARRAY_LEN (out) ;
|
||||
data.data_in = in ;
|
||||
data.data_out = out ;
|
||||
|
||||
if (src_simple (&data, converter, 1))
|
||||
{ puts ("src_simple failed.") ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
puts ("ok") ;
|
||||
} /* downsample_test */
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
puts ("") ;
|
||||
|
||||
downsample_test (SRC_ZERO_ORDER_HOLD) ;
|
||||
downsample_test (SRC_LINEAR) ;
|
||||
downsample_test (SRC_SINC_FASTEST) ;
|
||||
downsample_test (SRC_SINC_MEDIUM_QUALITY) ;
|
||||
downsample_test (SRC_SINC_BEST_QUALITY) ;
|
||||
|
||||
puts ("") ;
|
||||
|
||||
return 0 ;
|
||||
} /* main */
|
|
@ -1,281 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2001-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU Lesser General Public License as published by
|
||||
** the Free Software Foundation; either version 2.1 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU Lesser General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU Lesser General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* Version 1.5 */
|
||||
|
||||
#ifndef FLOAT_CAST_HEADER
|
||||
#define FLOAT_CAST_HEADER
|
||||
|
||||
/*============================================================================
|
||||
** On Intel Pentium processors (especially PIII and probably P4), converting
|
||||
** from float to int is very slow. To meet the C specs, the code produced by
|
||||
** most C compilers targeting Pentium needs to change the FPU rounding mode
|
||||
** before the float to int conversion is performed.
|
||||
**
|
||||
** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It
|
||||
** is this flushing of the pipeline which is so slow.
|
||||
**
|
||||
** Fortunately the ISO C99 specifications define the functions lrint, lrintf,
|
||||
** llrint and llrintf which fix this problem as a side effect.
|
||||
**
|
||||
** On Unix-like systems, the configure process should have detected the
|
||||
** presence of these functions. If they weren't found we have to replace them
|
||||
** here with a standard C cast.
|
||||
*/
|
||||
|
||||
/*
|
||||
** The C99 prototypes for lrint and lrintf are as follows:
|
||||
**
|
||||
** long int lrintf (float x) ;
|
||||
** long int lrint (double x) ;
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/*
|
||||
** The presence of the required functions are detected during the configure
|
||||
** process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in
|
||||
** the config.h file.
|
||||
*/
|
||||
|
||||
#define HAVE_LRINT_REPLACEMENT 0
|
||||
|
||||
#if (HAVE_LRINT && HAVE_LRINTF)
|
||||
|
||||
/*
|
||||
** These defines enable functionality introduced with the 1999 ISO C
|
||||
** standard. They must be defined before the inclusion of math.h to
|
||||
** engage them. If optimisation is enabled, these functions will be
|
||||
** inlined. With optimisation switched off, you have to link in the
|
||||
** maths library using -lm.
|
||||
*/
|
||||
|
||||
#define _ISOC9X_SOURCE 1
|
||||
#define _ISOC99_SOURCE 1
|
||||
|
||||
#define __USE_ISOC9X 1
|
||||
#define __USE_ISOC99 1
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#elif (defined (__CYGWIN__))
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#undef HAVE_LRINT_REPLACEMENT
|
||||
#define HAVE_LRINT_REPLACEMENT 1
|
||||
|
||||
#undef lrint
|
||||
#undef lrintf
|
||||
|
||||
#define lrint double2int
|
||||
#define lrintf float2int
|
||||
|
||||
/*
|
||||
** The native CYGWIN lrint and lrintf functions are buggy:
|
||||
** http://sourceware.org/ml/cygwin/2005-06/msg00153.html
|
||||
** http://sourceware.org/ml/cygwin/2005-09/msg00047.html
|
||||
** and slow.
|
||||
** These functions (pulled from the Public Domain MinGW math.h header)
|
||||
** replace the native versions.
|
||||
*/
|
||||
|
||||
static inline long double2int (double in)
|
||||
{ long retval ;
|
||||
|
||||
__asm__ __volatile__
|
||||
( "fistpl %0"
|
||||
: "=m" (retval)
|
||||
: "t" (in)
|
||||
: "st"
|
||||
) ;
|
||||
|
||||
return retval ;
|
||||
} /* double2int */
|
||||
|
||||
static inline long float2int (float in)
|
||||
{ long retval ;
|
||||
|
||||
__asm__ __volatile__
|
||||
( "fistpl %0"
|
||||
: "=m" (retval)
|
||||
: "t" (in)
|
||||
: "st"
|
||||
) ;
|
||||
|
||||
return retval ;
|
||||
} /* float2int */
|
||||
|
||||
#elif (defined (WIN64) || defined(_WIN64))
|
||||
|
||||
/* Win64 section should be places before Win32 one, because
|
||||
** most likely both WIN32 and WIN64 will be defined in 64-bit case.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/* Win64 doesn't seem to have these functions, nor inline assembly.
|
||||
** Therefore implement inline versions of these functions here.
|
||||
*/
|
||||
#include <emmintrin.h>
|
||||
#include <mmintrin.h>
|
||||
|
||||
__inline long int
|
||||
lrint(double flt)
|
||||
{
|
||||
return _mm_cvtsd_si32(_mm_load_sd(&flt));
|
||||
}
|
||||
|
||||
__inline long int
|
||||
lrintf(float flt)
|
||||
{
|
||||
return _mm_cvtss_si32(_mm_load_ss(&flt));
|
||||
}
|
||||
|
||||
#elif (defined (WIN32) || defined (_WIN32))
|
||||
|
||||
#undef HAVE_LRINT_REPLACEMENT
|
||||
#define HAVE_LRINT_REPLACEMENT 1
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/*
|
||||
** Win32 doesn't seem to have these functions.
|
||||
** Therefore implement inline versions of these functions here.
|
||||
*/
|
||||
|
||||
__inline long int
|
||||
lrint (double flt)
|
||||
{ int intgr ;
|
||||
|
||||
_asm
|
||||
{ fld flt
|
||||
fistp intgr
|
||||
} ;
|
||||
|
||||
return intgr ;
|
||||
}
|
||||
|
||||
__inline long int
|
||||
lrintf (float flt)
|
||||
{ int intgr ;
|
||||
|
||||
_asm
|
||||
{ fld flt
|
||||
fistp intgr
|
||||
} ;
|
||||
|
||||
return intgr ;
|
||||
}
|
||||
|
||||
#elif (defined (__MWERKS__) && defined (macintosh))
|
||||
|
||||
/* This MacOS 9 solution was provided by Stephane Letz */
|
||||
|
||||
#undef HAVE_LRINT_REPLACEMENT
|
||||
#define HAVE_LRINT_REPLACEMENT 1
|
||||
#include <math.h>
|
||||
|
||||
#undef lrint
|
||||
#undef lrintf
|
||||
|
||||
#define lrint double2int
|
||||
#define lrintf float2int
|
||||
|
||||
inline int
|
||||
float2int (register float in)
|
||||
{ long res [2] ;
|
||||
|
||||
asm
|
||||
{ fctiw in, in
|
||||
stfd in, res
|
||||
}
|
||||
return res [1] ;
|
||||
} /* float2int */
|
||||
|
||||
inline int
|
||||
double2int (register double in)
|
||||
{ long res [2] ;
|
||||
|
||||
asm
|
||||
{ fctiw in, in
|
||||
stfd in, res
|
||||
}
|
||||
return res [1] ;
|
||||
} /* double2int */
|
||||
|
||||
#elif (defined (__MACH__) && defined (__APPLE__))
|
||||
|
||||
/* For Apple MacOSX. */
|
||||
|
||||
#undef HAVE_LRINT_REPLACEMENT
|
||||
#define HAVE_LRINT_REPLACEMENT 1
|
||||
#include <math.h>
|
||||
|
||||
#undef lrint
|
||||
#undef lrintf
|
||||
|
||||
#define lrint double2int
|
||||
#define lrintf float2int
|
||||
|
||||
inline static long
|
||||
float2int (register float in)
|
||||
{ int res [2] ;
|
||||
|
||||
__asm__ __volatile__
|
||||
( "fctiw %1, %1\n\t"
|
||||
"stfd %1, %0"
|
||||
: "=m" (res) /* Output */
|
||||
: "f" (in) /* Input */
|
||||
: "memory"
|
||||
) ;
|
||||
|
||||
return res [1] ;
|
||||
} /* lrintf */
|
||||
|
||||
inline static long
|
||||
double2int (register double in)
|
||||
{ int res [2] ;
|
||||
|
||||
__asm__ __volatile__
|
||||
( "fctiw %1, %1\n\t"
|
||||
"stfd %1, %0"
|
||||
: "=m" (res) /* Output */
|
||||
: "f" (in) /* Input */
|
||||
: "memory"
|
||||
) ;
|
||||
|
||||
return res [1] ;
|
||||
} /* lrint */
|
||||
|
||||
#else
|
||||
#ifndef __sgi
|
||||
#warning "Don't have the functions lrint() and lrintf()."
|
||||
#warning "Replacing these functions with a standard C cast."
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define lrint(dbl) ((long) (dbl))
|
||||
#define lrintf(flt) ((long) (flt))
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* FLOAT_CAST_HEADER */
|
||||
|
|
@ -1,192 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2003-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <samplerate.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#define BUFFER_LEN 10000
|
||||
|
||||
static void float_to_short_test (void) ;
|
||||
static void short_to_float_test (void) ;
|
||||
|
||||
static void float_to_int_test (void) ;
|
||||
static void int_to_float_test (void) ;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
puts ("") ;
|
||||
|
||||
float_to_short_test () ;
|
||||
short_to_float_test () ;
|
||||
|
||||
float_to_int_test () ;
|
||||
int_to_float_test () ;
|
||||
|
||||
puts ("") ;
|
||||
|
||||
return 0 ;
|
||||
} /* main */
|
||||
|
||||
/*=====================================================================================
|
||||
*/
|
||||
|
||||
static void
|
||||
float_to_short_test (void)
|
||||
{
|
||||
static float fpos [] =
|
||||
{ 0.95, 0.99, 1.0, 1.01, 1.1, 2.0, 11.1, 111.1, 2222.2, 33333.3
|
||||
} ;
|
||||
static float fneg [] =
|
||||
{ -0.95, -0.99, -1.0, -1.01, -1.1, -2.0, -11.1, -111.1, -2222.2, -33333.3
|
||||
} ;
|
||||
|
||||
static short out [MAX (ARRAY_LEN (fpos), ARRAY_LEN (fneg))] ;
|
||||
|
||||
int k ;
|
||||
|
||||
printf ("\tfloat_to_short_test ............................. ") ;
|
||||
|
||||
src_float_to_short_array (fpos, out, ARRAY_LEN (fpos)) ;
|
||||
|
||||
for (k = 0 ; k < ARRAY_LEN (fpos) ; k++)
|
||||
if (out [k] < 30000)
|
||||
{ printf ("\n\n\tLine %d : out [%d] == %d\n", __LINE__, k, out [k]) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
src_float_to_short_array (fneg, out, ARRAY_LEN (fneg)) ;
|
||||
|
||||
for (k = 0 ; k < ARRAY_LEN (fneg) ; k++)
|
||||
if (out [k] > -30000)
|
||||
{ printf ("\n\n\tLine %d : out [%d] == %d\n", __LINE__, k, out [k]) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
puts ("ok") ;
|
||||
|
||||
return ;
|
||||
} /* float_to_short_test */
|
||||
|
||||
/*-------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
short_to_float_test (void)
|
||||
{
|
||||
static short input [BUFFER_LEN] ;
|
||||
static short output [BUFFER_LEN] ;
|
||||
static float temp [BUFFER_LEN] ;
|
||||
|
||||
int k ;
|
||||
|
||||
printf ("\tshort_to_float_test ............................. ") ;
|
||||
|
||||
for (k = 0 ; k < ARRAY_LEN (input) ; k++)
|
||||
input [k] = (k * 0x8000) / ARRAY_LEN (input) ;
|
||||
|
||||
src_short_to_float_array (input, temp, ARRAY_LEN (temp)) ;
|
||||
src_float_to_short_array (temp, output, ARRAY_LEN (output)) ;
|
||||
|
||||
for (k = 0 ; k < ARRAY_LEN (input) ; k++)
|
||||
if (ABS (input [k] - output [k]) > 0)
|
||||
{ printf ("\n\n\tLine %d : index %d %d -> %d\n", __LINE__, k, input [k], output [k]) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
puts ("ok") ;
|
||||
|
||||
return ;
|
||||
} /* short_to_float_test */
|
||||
|
||||
/*=====================================================================================
|
||||
*/
|
||||
|
||||
static void
|
||||
float_to_int_test (void)
|
||||
{
|
||||
static float fpos [] =
|
||||
{ 0.95, 0.99, 1.0, 1.01, 1.1, 2.0, 11.1, 111.1, 2222.2, 33333.3
|
||||
} ;
|
||||
static float fneg [] =
|
||||
{ -0.95, -0.99, -1.0, -1.01, -1.1, -2.0, -11.1, -111.1, -2222.2, -33333.3
|
||||
} ;
|
||||
|
||||
static int out [MAX (ARRAY_LEN (fpos), ARRAY_LEN (fneg))] ;
|
||||
|
||||
int k ;
|
||||
|
||||
printf ("\tfloat_to_int_test ............................... ") ;
|
||||
|
||||
src_float_to_int_array (fpos, out, ARRAY_LEN (fpos)) ;
|
||||
|
||||
for (k = 0 ; k < ARRAY_LEN (fpos) ; k++)
|
||||
if (out [k] < 30000 * 0x10000)
|
||||
{ printf ("\n\n\tLine %d : out [%d] == %d\n", __LINE__, k, out [k]) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
src_float_to_int_array (fneg, out, ARRAY_LEN (fneg)) ;
|
||||
|
||||
for (k = 0 ; k < ARRAY_LEN (fneg) ; k++)
|
||||
if (out [k] > -30000 * 0x1000)
|
||||
{ printf ("\n\n\tLine %d : out [%d] == %d\n", __LINE__, k, out [k]) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
puts ("ok") ;
|
||||
|
||||
return ;
|
||||
} /* float_to_int_test */
|
||||
|
||||
/*-------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
int_to_float_test (void)
|
||||
{
|
||||
static int input [BUFFER_LEN] ;
|
||||
static int output [BUFFER_LEN] ;
|
||||
static float temp [BUFFER_LEN] ;
|
||||
|
||||
int k ;
|
||||
|
||||
printf ("\tint_to_float_test ............................... ") ;
|
||||
|
||||
for (k = 0 ; k < ARRAY_LEN (input) ; k++)
|
||||
input [k] = (k * 0x80000000) / ARRAY_LEN (input) ;
|
||||
|
||||
src_int_to_float_array (input, temp, ARRAY_LEN (temp)) ;
|
||||
src_float_to_int_array (temp, output, ARRAY_LEN (output)) ;
|
||||
|
||||
for (k = 0 ; k < ARRAY_LEN (input) ; k++)
|
||||
if (ABS (input [k] - output [k]) > 0)
|
||||
{ printf ("\n\n\tLine %d : index %d %d -> %d\n", __LINE__, k, input [k], output [k]) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
puts ("ok") ;
|
||||
|
||||
return ;
|
||||
} /* int_to_float_test */
|
||||
|
|
@ -1,175 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <samplerate.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
static void name_test (void) ;
|
||||
static void error_test (void) ;
|
||||
static void src_ratio_test (void) ;
|
||||
static void zero_input_test (int converter) ;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
puts ("") ;
|
||||
|
||||
printf (" version : %s\n\n", src_get_version ()) ;
|
||||
|
||||
/* Current max converter is SRC_LINEAR. */
|
||||
name_test () ;
|
||||
|
||||
error_test () ;
|
||||
|
||||
src_ratio_test () ;
|
||||
|
||||
zero_input_test (SRC_ZERO_ORDER_HOLD) ;
|
||||
zero_input_test (SRC_LINEAR) ;
|
||||
zero_input_test (SRC_SINC_FASTEST) ;
|
||||
|
||||
puts ("") ;
|
||||
return 0 ;
|
||||
} /* main */
|
||||
|
||||
static void
|
||||
name_test (void)
|
||||
{ const char *name ;
|
||||
int k = 0 ;
|
||||
|
||||
puts (" name_test :") ;
|
||||
|
||||
while (1)
|
||||
{ name = src_get_name (k) ;
|
||||
if (name == NULL)
|
||||
break ;
|
||||
printf ("\tName %d : %s\n", k, name) ;
|
||||
printf ("\tDesc %d : %s\n", k, src_get_description (k)) ;
|
||||
k ++ ;
|
||||
} ;
|
||||
|
||||
puts ("") ;
|
||||
|
||||
return ;
|
||||
} /* name_test */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{ double ratio ;
|
||||
int should_pass ;
|
||||
} RATIO_TEST ;
|
||||
|
||||
static RATIO_TEST ratio_test [] =
|
||||
{ { 1.0 / 256.1, 0 },
|
||||
{ 1.0 / 256.0, 1 },
|
||||
{ 1.0, 1 },
|
||||
{ 256.0, 1 },
|
||||
{ 256.1, 0 },
|
||||
{ -1.0, 0 }
|
||||
} ;
|
||||
|
||||
static void
|
||||
src_ratio_test (void)
|
||||
{ int k ;
|
||||
|
||||
puts (" src_ratio_test (SRC ratio must be in range [1/256, 256]):" ) ;
|
||||
|
||||
|
||||
for (k = 0 ; k < ARRAY_LEN (ratio_test) ; k++)
|
||||
{ if (ratio_test [k].should_pass && src_is_valid_ratio (ratio_test [k].ratio) == 0)
|
||||
{ printf ("\n\nLine %d : SRC ratio %f should have passed.\n\n", __LINE__, ratio_test [k].ratio) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
if (! ratio_test [k].should_pass && src_is_valid_ratio (ratio_test [k].ratio) != 0)
|
||||
{ printf ("\n\nLine %d : SRC ratio %f should not have passed.\n\n", __LINE__, ratio_test [k].ratio) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
printf ("\t SRC ratio (%9.5f) : %s ................... ok\n", ratio_test [k].ratio,
|
||||
(ratio_test [k].should_pass ? "pass" : "fail")) ;
|
||||
} ;
|
||||
|
||||
puts ("") ;
|
||||
|
||||
return ;
|
||||
} /* src_ratio_test */
|
||||
|
||||
static void
|
||||
error_test (void)
|
||||
{ const char *errorstr ;
|
||||
int k, errors = 0 ;
|
||||
|
||||
puts (" error_test :") ;
|
||||
|
||||
for (k = 0 ; 1 ; k++)
|
||||
{ errorstr = src_strerror (k) ;
|
||||
printf ("\t%-2d : %s\n", k, errorstr) ;
|
||||
if (errorstr == NULL)
|
||||
{ errors ++ ;
|
||||
continue ;
|
||||
} ;
|
||||
if (strstr (errorstr, "Placeholder.") == errorstr)
|
||||
break ;
|
||||
} ;
|
||||
|
||||
if (errors != 0)
|
||||
{ printf ("\n\nLine %d : Missing error numbers above.\n\n", __LINE__) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
puts ("") ;
|
||||
|
||||
return ;
|
||||
} /* error_test */
|
||||
|
||||
static void
|
||||
zero_input_test (int converter)
|
||||
{ SRC_DATA data ;
|
||||
SRC_STATE *state ;
|
||||
float out [100] ;
|
||||
int error ;
|
||||
|
||||
printf (" %s (%-26s) ........ ", __func__, src_get_name (converter)) ;
|
||||
fflush (stdout) ;
|
||||
|
||||
if ((state = src_new (converter, 1, &error)) == NULL)
|
||||
{ printf ("\n\nLine %d : src_new failed : %s.\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
data.data_in = (float *) 0xdeadbeef ;
|
||||
data.input_frames = 0 ;
|
||||
data.data_out = out ;
|
||||
data.output_frames = ARRAY_LEN (out) ;
|
||||
data.end_of_input = 0 ;
|
||||
data.src_ratio = 1.0 ;
|
||||
|
||||
if ((error = src_process (state, &data)))
|
||||
{ printf ("\n\nLine %d : src_new failed : %s.\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
state = src_delete (state) ;
|
||||
|
||||
puts ("ok") ;
|
||||
} /* zero_input_test */
|
|
@ -1,364 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <samplerate.h>
|
||||
|
||||
#include "util.h"
|
||||
#define BUFFER_LEN 50000
|
||||
#define BLOCK_LEN (12)
|
||||
|
||||
#define MAX_CHANNELS 10
|
||||
|
||||
static void simple_test (int converter, int channel_count, double target_snr) ;
|
||||
static void process_test (int converter, int channel_count, double target_snr) ;
|
||||
static void callback_test (int converter, int channel_count, double target_snr) ;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{ double target ;
|
||||
int k ;
|
||||
|
||||
puts ("\n Zero Order Hold interpolator :") ;
|
||||
target = 38.0 ;
|
||||
for (k = 1 ; k <= 3 ; k++)
|
||||
{ simple_test (SRC_ZERO_ORDER_HOLD, k, target) ;
|
||||
process_test (SRC_ZERO_ORDER_HOLD, k, target) ;
|
||||
callback_test (SRC_ZERO_ORDER_HOLD, k, target) ;
|
||||
} ;
|
||||
|
||||
puts ("\n Linear interpolator :") ;
|
||||
target = 79.0 ;
|
||||
for (k = 1 ; k <= 3 ; k++)
|
||||
{ simple_test (SRC_LINEAR, k, target) ;
|
||||
process_test (SRC_LINEAR, k, target) ;
|
||||
callback_test (SRC_LINEAR, k, target) ;
|
||||
} ;
|
||||
|
||||
puts ("\n Sinc interpolator :") ;
|
||||
target = 100.0 ;
|
||||
for (k = 1 ; k <= MAX_CHANNELS ; k++)
|
||||
{ simple_test (SRC_SINC_FASTEST, k, target) ;
|
||||
process_test (SRC_SINC_FASTEST, k, target) ;
|
||||
callback_test (SRC_SINC_FASTEST, k, target) ;
|
||||
} ;
|
||||
|
||||
puts ("") ;
|
||||
|
||||
return 0 ;
|
||||
} /* main */
|
||||
|
||||
/*==============================================================================
|
||||
*/
|
||||
|
||||
static float input_serial [BUFFER_LEN * MAX_CHANNELS] ;
|
||||
static float input_interleaved [BUFFER_LEN * MAX_CHANNELS] ;
|
||||
static float output_interleaved [BUFFER_LEN * MAX_CHANNELS] ;
|
||||
static float output_serial [BUFFER_LEN * MAX_CHANNELS] ;
|
||||
|
||||
static void
|
||||
simple_test (int converter, int channel_count, double target_snr)
|
||||
{ SRC_DATA src_data ;
|
||||
|
||||
double freq, snr ;
|
||||
int ch, error, frames ;
|
||||
|
||||
printf ("\t%-22s (%2d channel%c) ............ ", "simple_test", channel_count, channel_count > 1 ? 's' : ' ') ;
|
||||
fflush (stdout) ;
|
||||
|
||||
assert (channel_count <= MAX_CHANNELS) ;
|
||||
|
||||
memset (input_serial, 0, sizeof (input_serial)) ;
|
||||
memset (input_interleaved, 0, sizeof (input_interleaved)) ;
|
||||
memset (output_interleaved, 0, sizeof (output_interleaved)) ;
|
||||
memset (output_serial, 0, sizeof (output_serial)) ;
|
||||
|
||||
frames = BUFFER_LEN ;
|
||||
|
||||
/* Calculate channel_count separate windowed sine waves. */
|
||||
for (ch = 0 ; ch < channel_count ; ch++)
|
||||
{ freq = (200.0 + 33.333333333 * ch) / 44100.0 ;
|
||||
gen_windowed_sines (1, &freq, 1.0, input_serial + ch * frames, frames) ;
|
||||
} ;
|
||||
|
||||
/* Interleave the data in preparation for SRC. */
|
||||
interleave_data (input_serial, input_interleaved, frames, channel_count) ;
|
||||
|
||||
/* Choose a converstion ratio <= 1.0. */
|
||||
src_data.src_ratio = 0.95 ;
|
||||
|
||||
src_data.data_in = input_interleaved ;
|
||||
src_data.input_frames = frames ;
|
||||
|
||||
src_data.data_out = output_interleaved ;
|
||||
src_data.output_frames = frames ;
|
||||
|
||||
if ((error = src_simple (&src_data, converter, channel_count)))
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (fabs (src_data.output_frames_gen - src_data.src_ratio * src_data.input_frames) > 2)
|
||||
{ printf ("\n\nLine %d : bad output data length %ld should be %d.\n", __LINE__,
|
||||
src_data.output_frames_gen, (int) floor (src_data.src_ratio * src_data.input_frames)) ;
|
||||
printf ("\tsrc_ratio : %.4f\n", src_data.src_ratio) ;
|
||||
printf ("\tinput_len : %ld\n", src_data.input_frames) ;
|
||||
printf ("\toutput_len : %ld\n\n", src_data.output_frames_gen) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
/* De-interleave data so SNR can be calculated for each channel. */
|
||||
deinterleave_data (output_interleaved, output_serial, frames, channel_count) ;
|
||||
|
||||
for (ch = 0 ; ch < channel_count ; ch++)
|
||||
{ snr = calculate_snr (output_serial + ch * frames, frames, 1) ;
|
||||
if (snr < target_snr)
|
||||
{ printf ("\n\nLine %d: channel %d snr %f should be %f\n", __LINE__, ch, snr, target_snr) ;
|
||||
save_oct_float ("output.dat", input_serial, channel_count * frames, output_serial, channel_count * frames) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
} ;
|
||||
|
||||
puts ("ok") ;
|
||||
|
||||
return ;
|
||||
} /* simple_test */
|
||||
|
||||
/*==============================================================================
|
||||
*/
|
||||
|
||||
static void
|
||||
process_test (int converter, int channel_count, double target_snr)
|
||||
{ SRC_STATE *src_state ;
|
||||
SRC_DATA src_data ;
|
||||
|
||||
double freq, snr ;
|
||||
int ch, error, frames, current_in, current_out ;
|
||||
|
||||
printf ("\t%-22s (%2d channel%c) ............ ", "process_test", channel_count, channel_count > 1 ? 's' : ' ') ;
|
||||
fflush (stdout) ;
|
||||
|
||||
assert (channel_count <= MAX_CHANNELS) ;
|
||||
|
||||
memset (input_serial, 0, sizeof (input_serial)) ;
|
||||
memset (input_interleaved, 0, sizeof (input_interleaved)) ;
|
||||
memset (output_interleaved, 0, sizeof (output_interleaved)) ;
|
||||
memset (output_serial, 0, sizeof (output_serial)) ;
|
||||
|
||||
frames = BUFFER_LEN ;
|
||||
|
||||
/* Calculate channel_count separate windowed sine waves. */
|
||||
for (ch = 0 ; ch < channel_count ; ch++)
|
||||
{ freq = (400.0 + 11.333333333 * ch) / 44100.0 ;
|
||||
gen_windowed_sines (1, &freq, 1.0, input_serial + ch * frames, frames) ;
|
||||
} ;
|
||||
|
||||
/* Interleave the data in preparation for SRC. */
|
||||
interleave_data (input_serial, input_interleaved, frames, channel_count) ;
|
||||
|
||||
/* Perform sample rate conversion. */
|
||||
if ((src_state = src_new (converter, channel_count, &error)) == NULL)
|
||||
{ printf ("\n\nLine %d : src_new() failed : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
src_data.end_of_input = 0 ; /* Set this later. */
|
||||
|
||||
/* Choose a converstion ratio < 1.0. */
|
||||
src_data.src_ratio = 0.95 ;
|
||||
|
||||
src_data.data_in = input_interleaved ;
|
||||
src_data.data_out = output_interleaved ;
|
||||
|
||||
current_in = current_out = 0 ;
|
||||
|
||||
while (1)
|
||||
{ src_data.input_frames = MAX (MIN (BLOCK_LEN, frames - current_in), 0) ;
|
||||
src_data.output_frames = MAX (MIN (BLOCK_LEN, frames - current_out), 0) ;
|
||||
|
||||
if ((error = src_process (src_state, &src_data)))
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (src_data.end_of_input && src_data.output_frames_gen == 0)
|
||||
break ;
|
||||
|
||||
current_in += src_data.input_frames_used ;
|
||||
current_out += src_data.output_frames_gen ;
|
||||
|
||||
src_data.data_in += src_data.input_frames_used * channel_count ;
|
||||
src_data.data_out += src_data.output_frames_gen * channel_count ;
|
||||
|
||||
src_data.end_of_input = (current_in >= frames) ? 1 : 0 ;
|
||||
} ;
|
||||
|
||||
src_state = src_delete (src_state) ;
|
||||
|
||||
if (fabs (current_out - src_data.src_ratio * current_in) > 2)
|
||||
{ printf ("\n\nLine %d : bad output data length %d should be %d.\n", __LINE__,
|
||||
current_out, (int) floor (src_data.src_ratio * current_in)) ;
|
||||
printf ("\tsrc_ratio : %.4f\n", src_data.src_ratio) ;
|
||||
printf ("\tinput_len : %d\n", frames) ;
|
||||
printf ("\toutput_len : %d\n\n", current_out) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
/* De-interleave data so SNR can be calculated for each channel. */
|
||||
deinterleave_data (output_interleaved, output_serial, frames, channel_count) ;
|
||||
|
||||
for (ch = 0 ; ch < channel_count ; ch++)
|
||||
{ snr = calculate_snr (output_serial + ch * frames, frames, 1) ;
|
||||
if (snr < target_snr)
|
||||
{ printf ("\n\nLine %d: channel %d snr %f should be %f\n", __LINE__, ch, snr, target_snr) ;
|
||||
save_oct_float ("output.dat", input_serial, channel_count * frames, output_serial, channel_count * frames) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
} ;
|
||||
|
||||
puts ("ok") ;
|
||||
|
||||
return ;
|
||||
} /* process_test */
|
||||
|
||||
/*==============================================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{ int channels ;
|
||||
long total_frames ;
|
||||
long current_frame ;
|
||||
float *data ;
|
||||
} TEST_CB_DATA ;
|
||||
|
||||
static long
|
||||
test_callback_func (void *cb_data, float **data)
|
||||
{ TEST_CB_DATA *pcb_data ;
|
||||
|
||||
long frames ;
|
||||
|
||||
if ((pcb_data = cb_data) == NULL)
|
||||
return 0 ;
|
||||
|
||||
if (data == NULL)
|
||||
return 0 ;
|
||||
|
||||
*data = pcb_data->data + (pcb_data->current_frame * pcb_data->channels) ;
|
||||
|
||||
if (pcb_data->total_frames - pcb_data->current_frame < BLOCK_LEN)
|
||||
frames = pcb_data->total_frames - pcb_data->current_frame ;
|
||||
else
|
||||
frames = BLOCK_LEN ;
|
||||
|
||||
pcb_data->current_frame += frames ;
|
||||
|
||||
return frames ;
|
||||
} /* test_callback_func */
|
||||
|
||||
static void
|
||||
callback_test (int converter, int channel_count, double target_snr)
|
||||
{ TEST_CB_DATA test_callback_data ;
|
||||
SRC_STATE *src_state = NULL ;
|
||||
|
||||
double freq, snr, src_ratio ;
|
||||
int ch, error, frames, read_total, read_count ;
|
||||
|
||||
printf ("\t%-22s (%2d channel%c) ............ ", "callback_test", channel_count, channel_count > 1 ? 's' : ' ') ;
|
||||
fflush (stdout) ;
|
||||
|
||||
assert (channel_count <= MAX_CHANNELS) ;
|
||||
|
||||
memset (input_serial, 0, sizeof (input_serial)) ;
|
||||
memset (input_interleaved, 0, sizeof (input_interleaved)) ;
|
||||
memset (output_interleaved, 0, sizeof (output_interleaved)) ;
|
||||
memset (output_serial, 0, sizeof (output_serial)) ;
|
||||
memset (&test_callback_data, 0, sizeof (test_callback_data)) ;
|
||||
|
||||
frames = BUFFER_LEN ;
|
||||
|
||||
/* Calculate channel_count separate windowed sine waves. */
|
||||
for (ch = 0 ; ch < channel_count ; ch++)
|
||||
{ freq = (200.0 + 33.333333333 * ch) / 44100.0 ;
|
||||
gen_windowed_sines (1, &freq, 1.0, input_serial + ch * frames, frames) ;
|
||||
} ;
|
||||
|
||||
/* Interleave the data in preparation for SRC. */
|
||||
interleave_data (input_serial, input_interleaved, frames, channel_count) ;
|
||||
|
||||
/* Perform sample rate conversion. */
|
||||
src_ratio = 0.95 ;
|
||||
test_callback_data.channels = channel_count ;
|
||||
test_callback_data.total_frames = frames ;
|
||||
test_callback_data.current_frame = 0 ;
|
||||
test_callback_data.data = input_interleaved ;
|
||||
|
||||
if ((src_state = src_callback_new (test_callback_func, converter, channel_count, &error, &test_callback_data)) == NULL)
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
read_total = 0 ;
|
||||
while (read_total < frames)
|
||||
{ read_count = src_callback_read (src_state, src_ratio, frames - read_total, output_interleaved + read_total * channel_count) ;
|
||||
|
||||
if (read_count <= 0)
|
||||
break ;
|
||||
|
||||
read_total += read_count ;
|
||||
} ;
|
||||
|
||||
if ((error = src_error (src_state)) != 0)
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
src_state = src_delete (src_state) ;
|
||||
|
||||
if (fabs (read_total - src_ratio * frames) > 2)
|
||||
{ printf ("\n\nLine %d : bad output data length %d should be %d.\n", __LINE__,
|
||||
read_total, (int) floor (src_ratio * frames)) ;
|
||||
printf ("\tsrc_ratio : %.4f\n", src_ratio) ;
|
||||
printf ("\tinput_len : %d\n", frames) ;
|
||||
printf ("\toutput_len : %d\n\n", read_total) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
/* De-interleave data so SNR can be calculated for each channel. */
|
||||
deinterleave_data (output_interleaved, output_serial, frames, channel_count) ;
|
||||
|
||||
for (ch = 0 ; ch < channel_count ; ch++)
|
||||
{ snr = calculate_snr (output_serial + ch * frames, frames, 1) ;
|
||||
if (snr < target_snr)
|
||||
{ printf ("\n\nLine %d: channel %d snr %f should be %f\n", __LINE__, ch, snr, target_snr) ;
|
||||
save_oct_float ("output.dat", input_serial, channel_count * frames, output_serial, channel_count * frames) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
} ;
|
||||
|
||||
puts ("ok") ;
|
||||
|
||||
return ;
|
||||
} /* callback_test */
|
||||
|
|
@ -1,216 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2008-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <samplerate.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "util.h"
|
||||
#include "float_cast.h"
|
||||
|
||||
#define BUFFER_LEN (1<<17)
|
||||
|
||||
static float input [BUFFER_LEN] ;
|
||||
static float output [BUFFER_LEN] ;
|
||||
|
||||
static long
|
||||
throughput_test (int converter, int channels, long best_throughput)
|
||||
{ SRC_DATA src_data ;
|
||||
clock_t start_time, clock_time ;
|
||||
double duration ;
|
||||
long total_frames = 0, throughput ;
|
||||
int error ;
|
||||
|
||||
printf (" %-30s %2d ", src_get_name (converter), channels) ;
|
||||
fflush (stdout) ;
|
||||
|
||||
src_data.data_in = input ;
|
||||
src_data.input_frames = ARRAY_LEN (input) / channels ;
|
||||
|
||||
src_data.data_out = output ;
|
||||
src_data.output_frames = ARRAY_LEN (output) / channels ;
|
||||
|
||||
src_data.src_ratio = 0.99 ;
|
||||
|
||||
sleep (2) ;
|
||||
|
||||
start_time = clock () ;
|
||||
|
||||
do
|
||||
{
|
||||
if ((error = src_simple (&src_data, converter, channels)) != 0)
|
||||
{ puts (src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
total_frames += src_data.output_frames_gen ;
|
||||
|
||||
clock_time = clock () - start_time ;
|
||||
duration = (1.0 * clock_time) / CLOCKS_PER_SEC ;
|
||||
}
|
||||
while (duration < 5.0) ;
|
||||
|
||||
if (src_data.input_frames_used != src_data.input_frames)
|
||||
{ printf ("\n\nLine %d : input frames used %ld should be %ld\n", __LINE__, src_data.input_frames_used, src_data.input_frames) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (fabs (src_data.src_ratio * src_data.input_frames_used - src_data.output_frames_gen) > 2)
|
||||
{ printf ("\n\nLine %d : input / output length mismatch.\n\n", __LINE__) ;
|
||||
printf (" input len : %d\n", ARRAY_LEN (input) / channels) ;
|
||||
printf (" output len : %ld (should be %g +/- 2)\n\n", src_data.output_frames_gen,
|
||||
floor (0.5 + src_data.src_ratio * src_data.input_frames_used)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
throughput = lrint (floor (total_frames / duration)) ;
|
||||
|
||||
if (best_throughput == 0)
|
||||
{ best_throughput = MAX (throughput, best_throughput) ;
|
||||
printf ("%5.2f %10ld\n", duration, throughput) ;
|
||||
}
|
||||
else
|
||||
{ best_throughput = MAX (throughput, best_throughput) ;
|
||||
printf ("%5.2f %10ld %10ld\n", duration, throughput, best_throughput) ;
|
||||
}
|
||||
|
||||
return best_throughput ;
|
||||
} /* throughput_test */
|
||||
|
||||
static void
|
||||
single_run (void)
|
||||
{ const int max_channels = 10 ;
|
||||
int k ;
|
||||
|
||||
printf ("\n CPU name : %s\n", get_cpu_name ()) ;
|
||||
|
||||
puts (
|
||||
"\n"
|
||||
" Converter Channels Duration Throughput\n"
|
||||
" ---------------------------------------------------------------------"
|
||||
) ;
|
||||
|
||||
for (k = 1 ; k <= max_channels / 2 ; k++)
|
||||
throughput_test (SRC_SINC_FASTEST, k, 0) ;
|
||||
|
||||
puts ("") ;
|
||||
for (k = 1 ; k <= max_channels / 2 ; k++)
|
||||
throughput_test (SRC_SINC_MEDIUM_QUALITY, k, 0) ;
|
||||
|
||||
puts ("") ;
|
||||
for (k = 1 ; k <= max_channels ; k++)
|
||||
throughput_test (SRC_SINC_BEST_QUALITY, k, 0) ;
|
||||
|
||||
puts ("") ;
|
||||
return ;
|
||||
} /* single_run */
|
||||
|
||||
static void
|
||||
multi_run (int run_count)
|
||||
{ int k, ch ;
|
||||
|
||||
printf ("\n CPU name : %s\n", get_cpu_name ()) ;
|
||||
|
||||
puts (
|
||||
"\n"
|
||||
" Converter Channels Duration Throughput Best Throughput\n"
|
||||
" ----------------------------------------------------------------------------------------"
|
||||
) ;
|
||||
|
||||
for (ch = 1 ; ch <= 5 ; ch++)
|
||||
{ long sinc_fastest = 0, sinc_medium = 0, sinc_best = 0 ;
|
||||
|
||||
for (k = 0 ; k < run_count ; k++)
|
||||
{ sinc_fastest = throughput_test (SRC_SINC_FASTEST, ch, sinc_fastest) ;
|
||||
sinc_medium = throughput_test (SRC_SINC_MEDIUM_QUALITY, ch, sinc_medium) ;
|
||||
sinc_best = throughput_test (SRC_SINC_BEST_QUALITY, ch, sinc_best) ;
|
||||
|
||||
puts ("") ;
|
||||
|
||||
/* Let the CPU cool down. We might be running on a laptop. */
|
||||
sleep (10) ;
|
||||
} ;
|
||||
|
||||
puts (
|
||||
"\n"
|
||||
" Converter Best Throughput\n"
|
||||
" ------------------------------------------------"
|
||||
) ;
|
||||
|
||||
printf (" %-30s %10ld\n", src_get_name (SRC_SINC_FASTEST), sinc_fastest) ;
|
||||
printf (" %-30s %10ld\n", src_get_name (SRC_SINC_MEDIUM_QUALITY), sinc_medium) ;
|
||||
printf (" %-30s %10ld\n", src_get_name (SRC_SINC_BEST_QUALITY), sinc_best) ;
|
||||
} ;
|
||||
|
||||
puts ("") ;
|
||||
} /* multi_run */
|
||||
|
||||
static void
|
||||
usage_exit (const char * argv0)
|
||||
{ const char * cptr ;
|
||||
|
||||
if ((cptr = strrchr (argv0, '/')) != NULL)
|
||||
argv0 = cptr ;
|
||||
|
||||
printf (
|
||||
"Usage :\n"
|
||||
" %s - Single run of the throughput test.\n"
|
||||
" %s --best-of N - Do N runs of test a print bext result.\n"
|
||||
"\n",
|
||||
argv0, argv0) ;
|
||||
|
||||
exit (0) ;
|
||||
} /* usage_exit */
|
||||
|
||||
int
|
||||
main (int argc, char ** argv)
|
||||
{ double freq ;
|
||||
|
||||
memset (input, 0, sizeof (input)) ;
|
||||
freq = 0.01 ;
|
||||
gen_windowed_sines (1, &freq, 1.0, input, BUFFER_LEN) ;
|
||||
|
||||
if (argc == 1)
|
||||
single_run () ;
|
||||
else if (argc == 3 && strcmp (argv [1], "--best-of") == 0)
|
||||
{ int run_count = atoi (argv [2]) ;
|
||||
|
||||
if (run_count < 1 || run_count > 20)
|
||||
{ printf ("Please be sensible. Run count should be in range (1, 10].\n") ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
multi_run (run_count) ;
|
||||
}
|
||||
else
|
||||
usage_exit (argv [0]) ;
|
||||
|
||||
puts (
|
||||
" Duration is in seconds.\n"
|
||||
" Throughput is in frames/sec (more is better).\n"
|
||||
) ;
|
||||
|
||||
return 0 ;
|
||||
} /* main */
|
||||
|
|
@ -1,238 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <samplerate.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#define BUFFER_LEN 2048
|
||||
#define CB_READ_LEN 256
|
||||
|
||||
static void process_reset_test (int converter) ;
|
||||
static void callback_reset_test (int converter) ;
|
||||
|
||||
static float data_one [BUFFER_LEN] ;
|
||||
static float data_zero [BUFFER_LEN] ;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
puts ("") ;
|
||||
|
||||
process_reset_test (SRC_ZERO_ORDER_HOLD) ;
|
||||
process_reset_test (SRC_LINEAR) ;
|
||||
process_reset_test (SRC_SINC_FASTEST) ;
|
||||
|
||||
callback_reset_test (SRC_ZERO_ORDER_HOLD) ;
|
||||
callback_reset_test (SRC_LINEAR) ;
|
||||
callback_reset_test (SRC_SINC_FASTEST) ;
|
||||
|
||||
puts ("") ;
|
||||
|
||||
return 0 ;
|
||||
} /* main */
|
||||
|
||||
static void
|
||||
process_reset_test (int converter)
|
||||
{ static float output [BUFFER_LEN] ;
|
||||
|
||||
SRC_STATE *src_state ;
|
||||
SRC_DATA src_data ;
|
||||
int k, error ;
|
||||
|
||||
printf ("\tprocess_reset_test (%-28s) ....... ", src_get_name (converter)) ;
|
||||
fflush (stdout) ;
|
||||
|
||||
for (k = 0 ; k < BUFFER_LEN ; k++)
|
||||
{ data_one [k] = 1.0 ;
|
||||
data_zero [k] = 0.0 ;
|
||||
} ;
|
||||
|
||||
/* Get a converter. */
|
||||
if ((src_state = src_new (converter, 1, &error)) == NULL)
|
||||
{ printf ("\n\nLine %d : src_new() failed : %s.\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
/* Process a bunch of 1.0 valued samples. */
|
||||
src_data.data_in = data_one ;
|
||||
src_data.data_out = output ;
|
||||
src_data.input_frames = BUFFER_LEN ;
|
||||
src_data.output_frames = BUFFER_LEN ;
|
||||
src_data.src_ratio = 0.9 ;
|
||||
src_data.end_of_input = 1 ;
|
||||
|
||||
if ((error = src_process (src_state, &src_data)) != 0)
|
||||
{ printf ("\n\nLine %d : src_simple () returned error : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
/* Reset the state of the converter.*/
|
||||
src_reset (src_state) ;
|
||||
|
||||
/* Now process some zero data. */
|
||||
src_data.data_in = data_zero ;
|
||||
src_data.data_out = output ;
|
||||
src_data.input_frames = BUFFER_LEN ;
|
||||
src_data.output_frames = BUFFER_LEN ;
|
||||
src_data.src_ratio = 0.9 ;
|
||||
src_data.end_of_input = 1 ;
|
||||
|
||||
if ((error = src_process (src_state, &src_data)) != 0)
|
||||
{ printf ("\n\nLine %d : src_simple () returned error : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
/* Finally make sure that the output data is zero ie reset was sucessful. */
|
||||
for (k = 0 ; k < BUFFER_LEN / 2 ; k++)
|
||||
if (output [k] != 0.0)
|
||||
{ printf ("\n\nLine %d : output [%d] should be 0.0, is %f.\n", __LINE__, k, output [k]) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
/* Make sure that this function has been exported. */
|
||||
src_set_ratio (src_state, 1.0) ;
|
||||
|
||||
/* Delete converter. */
|
||||
src_state = src_delete (src_state) ;
|
||||
|
||||
puts ("ok") ;
|
||||
} /* process_reset_test */
|
||||
|
||||
/*==============================================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{ int channels ;
|
||||
long count, total ;
|
||||
float *data ;
|
||||
} TEST_CB_DATA ;
|
||||
|
||||
static long
|
||||
test_callback_func (void *cb_data, float **data)
|
||||
{ TEST_CB_DATA *pcb_data ;
|
||||
|
||||
long frames ;
|
||||
|
||||
if ((pcb_data = cb_data) == NULL)
|
||||
return 0 ;
|
||||
|
||||
if (data == NULL)
|
||||
return 0 ;
|
||||
|
||||
if (pcb_data->total - pcb_data->count > 0)
|
||||
frames = pcb_data->total - pcb_data->count ;
|
||||
else
|
||||
frames = 0 ;
|
||||
|
||||
*data = pcb_data->data + pcb_data->count ;
|
||||
pcb_data->count += frames ;
|
||||
|
||||
return frames ;
|
||||
} /* test_callback_func */
|
||||
|
||||
static void
|
||||
callback_reset_test (int converter)
|
||||
{ static TEST_CB_DATA test_callback_data ;
|
||||
|
||||
static float output [BUFFER_LEN] ;
|
||||
|
||||
SRC_STATE *src_state ;
|
||||
|
||||
double src_ratio = 1.1 ;
|
||||
long read_count, read_total ;
|
||||
int k, error ;
|
||||
|
||||
printf ("\tcallback_reset_test (%-28s) ....... ", src_get_name (converter)) ;
|
||||
fflush (stdout) ;
|
||||
|
||||
for (k = 0 ; k < ARRAY_LEN (data_one) ; k++)
|
||||
{ data_one [k] = 1.0 ;
|
||||
data_zero [k] = 0.0 ;
|
||||
} ;
|
||||
|
||||
if ((src_state = src_callback_new (test_callback_func, converter, 1, &error, &test_callback_data)) == NULL)
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
/* Process a bunch of 1.0 valued samples. */
|
||||
test_callback_data.channels = 1 ;
|
||||
test_callback_data.count = 0 ;
|
||||
test_callback_data.total = ARRAY_LEN (data_one) ;
|
||||
test_callback_data.data = data_one ;
|
||||
|
||||
read_total = 0 ;
|
||||
do
|
||||
{ read_count = (ARRAY_LEN (output) - read_total > CB_READ_LEN) ? CB_READ_LEN : ARRAY_LEN (output) - read_total ;
|
||||
read_count = src_callback_read (src_state, src_ratio, read_count, output + read_total) ;
|
||||
read_total += read_count ;
|
||||
}
|
||||
while (read_count > 0) ;
|
||||
|
||||
/* Check for errors. */
|
||||
if ((error = src_error (src_state)) != 0)
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
/* Reset the state of the converter.*/
|
||||
src_reset (src_state) ;
|
||||
|
||||
/* Process a bunch of 0.0 valued samples. */
|
||||
test_callback_data.channels = 1 ;
|
||||
test_callback_data.count = 0 ;
|
||||
test_callback_data.total = ARRAY_LEN (data_zero) ;
|
||||
test_callback_data.data = data_zero ;
|
||||
|
||||
/* Now process some zero data. */
|
||||
read_total = 0 ;
|
||||
do
|
||||
{ read_count = (ARRAY_LEN (output) - read_total > CB_READ_LEN) ? CB_READ_LEN : ARRAY_LEN (output) - read_total ;
|
||||
read_count = src_callback_read (src_state, src_ratio, read_count, output + read_total) ;
|
||||
read_total += read_count ;
|
||||
}
|
||||
while (read_count > 0) ;
|
||||
|
||||
/* Check for errors. */
|
||||
if ((error = src_error (src_state)) != 0)
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
/* Finally make sure that the output data is zero ie reset was sucessful. */
|
||||
for (k = 0 ; k < BUFFER_LEN / 2 ; k++)
|
||||
if (output [k] != 0.0)
|
||||
{ printf ("\n\nLine %d : output [%d] should be 0.0, is %f.\n\n", __LINE__, k, output [k]) ;
|
||||
save_oct_float ("output.dat", data_one, ARRAY_LEN (data_one), output, ARRAY_LEN (output)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
/* Make sure that this function has been exported. */
|
||||
src_set_ratio (src_state, 1.0) ;
|
||||
|
||||
/* Delete converter. */
|
||||
src_state = src_delete (src_state) ;
|
||||
|
||||
puts ("ok") ;
|
||||
} /* callback_reset_test */
|
||||
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <samplerate.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#define BUFFER_LEN 2048
|
||||
|
||||
static void simple_test (int converter, double ratio) ;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{ static double src_ratios [] =
|
||||
{ 1.0001, 0.099, 0.1, 0.33333333, 0.789, 1.9, 3.1, 9.9
|
||||
} ;
|
||||
|
||||
int k ;
|
||||
|
||||
puts ("") ;
|
||||
|
||||
puts (" Zero Order Hold interpolator :") ;
|
||||
for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
|
||||
simple_test (SRC_ZERO_ORDER_HOLD, src_ratios [k]) ;
|
||||
|
||||
puts (" Linear interpolator :") ;
|
||||
for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
|
||||
simple_test (SRC_LINEAR, src_ratios [k]) ;
|
||||
|
||||
puts (" Sinc interpolator :") ;
|
||||
for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
|
||||
simple_test (SRC_SINC_FASTEST, src_ratios [k]) ;
|
||||
|
||||
puts ("") ;
|
||||
|
||||
return 0 ;
|
||||
} /* main */
|
||||
|
||||
static void
|
||||
simple_test (int converter, double src_ratio)
|
||||
{ static float input [BUFFER_LEN], output [BUFFER_LEN] ;
|
||||
|
||||
SRC_DATA src_data ;
|
||||
|
||||
int input_len, output_len, error, terminate ;
|
||||
|
||||
printf ("\tsimple_test (SRC ratio = %6.4f) ........... ", src_ratio) ;
|
||||
fflush (stdout) ;
|
||||
|
||||
/* Calculate maximun input and output lengths. */
|
||||
if (src_ratio >= 1.0)
|
||||
{ output_len = BUFFER_LEN ;
|
||||
input_len = (int) floor (BUFFER_LEN / src_ratio) ;
|
||||
}
|
||||
else
|
||||
{ input_len = BUFFER_LEN ;
|
||||
output_len = (int) floor (BUFFER_LEN * src_ratio) ;
|
||||
} ;
|
||||
|
||||
/* Reduce input_len by 10 so output is longer than necessary. */
|
||||
input_len -= 10 ;
|
||||
|
||||
if (output_len > BUFFER_LEN)
|
||||
{ printf ("\n\nLine %d : output_len > BUFFER_LEN\n\n", __LINE__) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
memset (&src_data, 0, sizeof (src_data)) ;
|
||||
|
||||
src_data.data_in = input ;
|
||||
src_data.input_frames = input_len ;
|
||||
|
||||
src_data.src_ratio = src_ratio ;
|
||||
|
||||
src_data.data_out = output ;
|
||||
src_data.output_frames = BUFFER_LEN ;
|
||||
|
||||
if ((error = src_simple (&src_data, converter, 1)))
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
terminate = (int) ceil ((src_ratio >= 1.0) ? src_ratio : 1.0 / src_ratio) ;
|
||||
|
||||
if (fabs (src_data.output_frames_gen - src_ratio * input_len) > 2 * terminate)
|
||||
{ printf ("\n\nLine %d : bad output data length %ld should be %d.\n", __LINE__,
|
||||
src_data.output_frames_gen, (int) floor (src_ratio * input_len)) ;
|
||||
printf ("\tsrc_ratio : %.4f\n", src_ratio) ;
|
||||
printf ("\tinput_len : %d\n\toutput_len : %d\n\n", input_len, output_len) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
puts ("ok") ;
|
||||
|
||||
return ;
|
||||
} /* simple_test */
|
||||
|
|
@ -1,332 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#if (HAVE_SNDFILE)
|
||||
|
||||
#include <samplerate.h>
|
||||
#include <sndfile.h>
|
||||
|
||||
#define DEFAULT_CONVERTER SRC_SINC_MEDIUM_QUALITY
|
||||
|
||||
#define BUFFER_LEN 4096 /*-(1<<16)-*/
|
||||
|
||||
static void usage_exit (const char *progname) ;
|
||||
static sf_count_t sample_rate_convert (SNDFILE *infile, SNDFILE *outfile, int converter, double src_ratio, int channels, double * gain) ;
|
||||
static double apply_gain (float * data, long frames, int channels, double max, double gain) ;
|
||||
|
||||
int
|
||||
main (int argc, char *argv [])
|
||||
{ SNDFILE *infile, *outfile = NULL ;
|
||||
SF_INFO sfinfo ;
|
||||
|
||||
sf_count_t count ;
|
||||
double src_ratio = -1.0, gain = 1.0 ;
|
||||
int new_sample_rate = -1, k, converter, max_speed = SF_FALSE ;
|
||||
|
||||
if (argc == 2 && strcmp (argv [1], "--version") == 0)
|
||||
{ char buffer [64], *cptr ;
|
||||
|
||||
if ((cptr = strrchr (argv [0], '/')) != NULL)
|
||||
argv [0] = cptr + 1 ;
|
||||
if ((cptr = strrchr (argv [0], '\\')) != NULL)
|
||||
argv [0] = cptr + 1 ;
|
||||
|
||||
sf_command (NULL, SFC_GET_LIB_VERSION, buffer, sizeof (buffer)) ;
|
||||
|
||||
printf ("%s (%s,%s)\n", argv [0], src_get_version (), buffer) ;
|
||||
exit (0) ;
|
||||
} ;
|
||||
|
||||
if (argc != 5 && argc != 7 && argc != 8)
|
||||
usage_exit (argv [0]) ;
|
||||
|
||||
/* Set default converter. */
|
||||
converter = DEFAULT_CONVERTER ;
|
||||
|
||||
for (k = 1 ; k < argc - 2 ; k++)
|
||||
{ if (strcmp (argv [k], "--max-speed") == 0)
|
||||
max_speed = SF_TRUE ;
|
||||
else if (strcmp (argv [k], "-to") == 0)
|
||||
{ k ++ ;
|
||||
new_sample_rate = atoi (argv [k]) ;
|
||||
}
|
||||
else if (strcmp (argv [k], "-by") == 0)
|
||||
{ k ++ ;
|
||||
src_ratio = atof (argv [k]) ;
|
||||
}
|
||||
else if (strcmp (argv [k], "-c") == 0)
|
||||
{ k ++ ;
|
||||
converter = atoi (argv [k]) ;
|
||||
}
|
||||
else
|
||||
usage_exit (argv [0]) ;
|
||||
} ;
|
||||
|
||||
if (new_sample_rate <= 0 && src_ratio <= 0.0)
|
||||
usage_exit (argv [0]) ;
|
||||
|
||||
if (src_get_name (converter) == NULL)
|
||||
{ printf ("Error : bad converter number.\n") ;
|
||||
usage_exit (argv [0]) ;
|
||||
} ;
|
||||
|
||||
if (strcmp (argv [argc - 2], argv [argc - 1]) == 0)
|
||||
{ printf ("Error : input and output file names are the same.\n") ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if ((infile = sf_open (argv [argc - 2], SFM_READ, &sfinfo)) == NULL)
|
||||
{ printf ("Error : Not able to open input file '%s'\n", argv [argc - 2]) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
printf ("Input File : %s\n", argv [argc - 2]) ;
|
||||
printf ("Sample Rate : %d\n", sfinfo.samplerate) ;
|
||||
printf ("Input Frames : %ld\n\n", (long) sfinfo.frames) ;
|
||||
|
||||
if (new_sample_rate > 0)
|
||||
{ src_ratio = (1.0 * new_sample_rate) / sfinfo.samplerate ;
|
||||
sfinfo.samplerate = new_sample_rate ;
|
||||
}
|
||||
else if (src_is_valid_ratio (src_ratio))
|
||||
sfinfo.samplerate = (int) floor (sfinfo.samplerate * src_ratio) ;
|
||||
else
|
||||
{ printf ("Not able to determine new sample rate. Exiting.\n") ;
|
||||
sf_close (infile) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (fabs (src_ratio - 1.0) < 1e-20)
|
||||
{ printf ("Target samplerate and input samplerate are the same. Exiting.\n") ;
|
||||
sf_close (infile) ;
|
||||
exit (0) ;
|
||||
} ;
|
||||
|
||||
printf ("SRC Ratio : %f\n", src_ratio) ;
|
||||
printf ("Converter : %s\n\n", src_get_name (converter)) ;
|
||||
|
||||
if (src_is_valid_ratio (src_ratio) == 0)
|
||||
{ printf ("Error : Sample rate change out of valid range.\n") ;
|
||||
sf_close (infile) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
/* Delete the output file length to zero if already exists. */
|
||||
remove (argv [argc - 1]) ;
|
||||
|
||||
printf ("Output file : %s\n", argv [argc - 1]) ;
|
||||
printf ("Sample Rate : %d\n", sfinfo.samplerate) ;
|
||||
|
||||
do
|
||||
{ sf_close (outfile) ;
|
||||
|
||||
if ((outfile = sf_open (argv [argc - 1], SFM_WRITE, &sfinfo)) == NULL)
|
||||
{ printf ("Error : Not able to open output file '%s'\n", argv [argc - 1]) ;
|
||||
sf_close (infile) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (max_speed)
|
||||
{ /* This is mainly for the comparison program tests/src-evaluate.c */
|
||||
sf_command (outfile, SFC_SET_ADD_PEAK_CHUNK, NULL, SF_FALSE) ;
|
||||
}
|
||||
else
|
||||
{ /* Update the file header after every write. */
|
||||
sf_command (outfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) ;
|
||||
} ;
|
||||
|
||||
sf_command (outfile, SFC_SET_CLIPPING, NULL, SF_TRUE) ;
|
||||
|
||||
count = sample_rate_convert (infile, outfile, converter, src_ratio, sfinfo.channels, &gain) ;
|
||||
}
|
||||
while (count < 0) ;
|
||||
|
||||
printf ("Output Frames : %ld\n\n", (long) count) ;
|
||||
|
||||
sf_close (infile) ;
|
||||
sf_close (outfile) ;
|
||||
|
||||
return 0 ;
|
||||
} /* main */
|
||||
|
||||
/*==============================================================================
|
||||
*/
|
||||
|
||||
static sf_count_t
|
||||
sample_rate_convert (SNDFILE *infile, SNDFILE *outfile, int converter, double src_ratio, int channels, double * gain)
|
||||
{ static float input [BUFFER_LEN] ;
|
||||
static float output [BUFFER_LEN] ;
|
||||
|
||||
SRC_STATE *src_state ;
|
||||
SRC_DATA src_data ;
|
||||
int error ;
|
||||
double max = 0.0 ;
|
||||
sf_count_t output_count = 0 ;
|
||||
|
||||
sf_seek (infile, 0, SEEK_SET) ;
|
||||
sf_seek (outfile, 0, SEEK_SET) ;
|
||||
|
||||
/* Initialize the sample rate converter. */
|
||||
if ((src_state = src_new (converter, channels, &error)) == NULL)
|
||||
{ printf ("\n\nError : src_new() failed : %s.\n\n", src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
src_data.end_of_input = 0 ; /* Set this later. */
|
||||
|
||||
/* Start with zero to force load in while loop. */
|
||||
src_data.input_frames = 0 ;
|
||||
src_data.data_in = input ;
|
||||
|
||||
src_data.src_ratio = src_ratio ;
|
||||
|
||||
src_data.data_out = output ;
|
||||
src_data.output_frames = BUFFER_LEN /channels ;
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* If the input buffer is empty, refill it. */
|
||||
if (src_data.input_frames == 0)
|
||||
{ src_data.input_frames = sf_readf_float (infile, input, BUFFER_LEN / channels) ;
|
||||
src_data.data_in = input ;
|
||||
|
||||
/* The last read will not be a full buffer, so snd_of_input. */
|
||||
if (src_data.input_frames < BUFFER_LEN / channels)
|
||||
src_data.end_of_input = SF_TRUE ;
|
||||
} ;
|
||||
|
||||
if ((error = src_process (src_state, &src_data)))
|
||||
{ printf ("\nError : %s\n", src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
/* Terminate if done. */
|
||||
if (src_data.end_of_input && src_data.output_frames_gen == 0)
|
||||
break ;
|
||||
|
||||
max = apply_gain (src_data.data_out, src_data.output_frames_gen, channels, max, *gain) ;
|
||||
|
||||
/* Write output. */
|
||||
sf_writef_float (outfile, output, src_data.output_frames_gen) ;
|
||||
output_count += src_data.output_frames_gen ;
|
||||
|
||||
src_data.data_in += src_data.input_frames_used * channels ;
|
||||
src_data.input_frames -= src_data.input_frames_used ;
|
||||
} ;
|
||||
|
||||
src_state = src_delete (src_state) ;
|
||||
|
||||
if (max > 1.0)
|
||||
{ *gain = 1.0 / max ;
|
||||
printf ("\nOutput has clipped. Restarting conversion to prevent clipping.\n\n") ;
|
||||
return -1 ;
|
||||
} ;
|
||||
|
||||
return output_count ;
|
||||
} /* sample_rate_convert */
|
||||
|
||||
static double
|
||||
apply_gain (float * data, long frames, int channels, double max, double gain)
|
||||
{
|
||||
long k ;
|
||||
|
||||
for (k = 0 ; k < frames * channels ; k++)
|
||||
{ data [k] *= gain ;
|
||||
|
||||
if (fabs (data [k]) > max)
|
||||
max = fabs (data [k]) ;
|
||||
} ;
|
||||
|
||||
return max ;
|
||||
} /* apply_gain */
|
||||
|
||||
static void
|
||||
usage_exit (const char *progname)
|
||||
{ char lsf_ver [128] ;
|
||||
const char *cptr ;
|
||||
int k ;
|
||||
|
||||
if ((cptr = strrchr (progname, '/')) != NULL)
|
||||
progname = cptr + 1 ;
|
||||
|
||||
if ((cptr = strrchr (progname, '\\')) != NULL)
|
||||
progname = cptr + 1 ;
|
||||
|
||||
|
||||
sf_command (NULL, SFC_GET_LIB_VERSION, lsf_ver, sizeof (lsf_ver)) ;
|
||||
|
||||
printf ("\n"
|
||||
" A Sample Rate Converter using libsndfile for file I/O and Secret \n"
|
||||
" Rabbit Code (aka libsamplerate) for performing the conversion.\n"
|
||||
" It works on any file format supported by libsndfile with any \n"
|
||||
" number of channels (limited only by host memory).\n"
|
||||
"\n"
|
||||
" %s\n"
|
||||
" %s\n"
|
||||
"\n"
|
||||
" Usage : \n"
|
||||
" %s -to <new sample rate> [-c <number>] <input file> <output file>\n"
|
||||
" %s -by <amount> [-c <number>] <input file> <output file>\n"
|
||||
"\n", src_get_version (), lsf_ver, progname, progname) ;
|
||||
|
||||
puts (
|
||||
" The optional -c argument allows the converter type to be chosen from\n"
|
||||
" the following list :"
|
||||
"\n"
|
||||
) ;
|
||||
|
||||
for (k = 0 ; (cptr = src_get_name (k)) != NULL ; k++)
|
||||
printf (" %d : %s%s\n", k, cptr, k == DEFAULT_CONVERTER ? " (default)" : "") ;
|
||||
|
||||
puts ("") ;
|
||||
|
||||
exit (1) ;
|
||||
} /* usage_exit */
|
||||
|
||||
/*==============================================================================
|
||||
*/
|
||||
|
||||
#else /* (HAVE_SNFILE == 0) */
|
||||
|
||||
/* Alternative main function when libsndfile is not available. */
|
||||
|
||||
int
|
||||
main (void)
|
||||
{ puts (
|
||||
"\n"
|
||||
"****************************************************************\n"
|
||||
" This example program was compiled without libsndfile \n"
|
||||
" (http://www.mega-nerd.com/libsndfile/).\n"
|
||||
" It is therefore completely broken and non-functional.\n"
|
||||
"****************************************************************\n"
|
||||
"\n"
|
||||
) ;
|
||||
|
||||
return 0 ;
|
||||
} /* main */
|
||||
|
||||
#endif
|
||||
|
|
@ -1,401 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#if (HAVE_FFTW3)
|
||||
|
||||
#include <samplerate.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#define BUFFER_LEN 50000
|
||||
#define MAX_FREQS 4
|
||||
#define MAX_RATIOS 6
|
||||
#define MAX_SPEC_LEN (1<<15)
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846264338
|
||||
#endif
|
||||
|
||||
enum
|
||||
{ BOOLEAN_FALSE = 0,
|
||||
BOOLEAN_TRUE = 1
|
||||
} ;
|
||||
|
||||
typedef struct
|
||||
{ int freq_count ;
|
||||
double freqs [MAX_FREQS] ;
|
||||
|
||||
double src_ratio ;
|
||||
int pass_band_peaks ;
|
||||
|
||||
double snr ;
|
||||
double peak_value ;
|
||||
} SINGLE_TEST ;
|
||||
|
||||
typedef struct
|
||||
{ int converter ;
|
||||
int tests ;
|
||||
int do_bandwidth_test ;
|
||||
SINGLE_TEST test_data [10] ;
|
||||
} CONVERTER_TEST ;
|
||||
|
||||
static double snr_test (SINGLE_TEST *snr_test_data, int number, int converter, int verbose) ;
|
||||
static double find_peak (float *output, int output_len) ;
|
||||
static double bandwidth_test (int converter, int verbose) ;
|
||||
|
||||
int
|
||||
main (int argc, char *argv [])
|
||||
{ CONVERTER_TEST snr_test_data [] =
|
||||
{
|
||||
{ SRC_ZERO_ORDER_HOLD,
|
||||
8,
|
||||
BOOLEAN_FALSE,
|
||||
{ { 1, { 0.01111111111 }, 3.0, 1, 28.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 0.6, 1, 36.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 0.3, 1, 36.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 1.0, 1, 150.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 1.001, 1, 38.0, 1.0 },
|
||||
{ 2, { 0.011111, 0.324 }, 1.9999, 2, 14.0, .96 },
|
||||
{ 2, { 0.012345, 0.457 }, 0.456789, 1, 12.0, .96 },
|
||||
{ 1, { 0.3511111111 }, 1.33, 1, 10.0, 1.0 }
|
||||
}
|
||||
},
|
||||
|
||||
{ SRC_LINEAR,
|
||||
8,
|
||||
BOOLEAN_FALSE,
|
||||
{ { 1, { 0.01111111111 }, 3.0, 1, 73.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 0.6, 1, 73.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 0.3, 1, 73.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 1.0, 1, 150.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 1.001, 1, 77.0, 1.0 },
|
||||
{ 2, { 0.011111, 0.324 }, 1.9999, 2, 16.0, 0.96 },
|
||||
{ 2, { 0.012345, 0.457 }, 0.456789, 1, 26.0, 0.96 },
|
||||
{ 1, { 0.3511111111 }, 1.33, 1, 14.4, 0.99 }
|
||||
}
|
||||
},
|
||||
|
||||
{ SRC_SINC_FASTEST,
|
||||
9,
|
||||
BOOLEAN_TRUE,
|
||||
{ { 1, { 0.01111111111 }, 3.0, 1, 100.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 0.6, 1, 99.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 0.3, 1, 100.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 1.0, 1, 150.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 1.001, 1, 100.0, 1.0 },
|
||||
{ 2, { 0.011111, 0.324 }, 1.9999, 2, 97.0, 1.0 },
|
||||
{ 2, { 0.012345, 0.457 }, 0.456789, 1, 100.0, 0.5 },
|
||||
{ 2, { 0.011111, 0.45 }, 0.6, 1, 97.0, 0.5 },
|
||||
{ 1, { 0.3511111111 }, 1.33, 1, 97.0, 1.0 }
|
||||
}
|
||||
},
|
||||
|
||||
{ SRC_SINC_MEDIUM_QUALITY,
|
||||
9,
|
||||
BOOLEAN_TRUE,
|
||||
{ { 1, { 0.01111111111 }, 3.0, 1, 130.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 0.6, 1, 132.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 0.3, 1, 138.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 1.0, 1, 155.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 1.001, 1, 134.0, 1.0 },
|
||||
{ 2, { 0.011111, 0.324 }, 1.9999, 2, 127.0, 1.0 },
|
||||
{ 2, { 0.012345, 0.457 }, 0.456789, 1, 124.0, 0.5 },
|
||||
{ 2, { 0.011111, 0.45 }, 0.6, 1, 126.0, 0.5 },
|
||||
{ 1, { 0.43111111111 }, 1.33, 1, 121.0, 1.0 }
|
||||
}
|
||||
},
|
||||
|
||||
{ SRC_SINC_BEST_QUALITY,
|
||||
9,
|
||||
BOOLEAN_TRUE,
|
||||
{ { 1, { 0.01111111111 }, 3.0, 1, 147.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 0.6, 1, 147.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 0.3, 1, 147.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 1.0, 1, 155.0, 1.0 },
|
||||
{ 1, { 0.01111111111 }, 1.001, 1, 147.0, 1.0 },
|
||||
{ 2, { 0.011111, 0.324 }, 1.9999, 2, 147.0, 1.0 },
|
||||
{ 2, { 0.012345, 0.457 }, 0.456789, 1, 148.0, 0.5 },
|
||||
{ 2, { 0.011111, 0.45 }, 0.6, 1, 149.0, 0.5 },
|
||||
{ 1, { 0.43111111111 }, 1.33, 1, 145.0, 1.0 }
|
||||
}
|
||||
},
|
||||
} ; /* snr_test_data */
|
||||
|
||||
double best_snr, snr, freq3dB ;
|
||||
int j, k, converter, verbose = 0 ;
|
||||
|
||||
if (argc == 2 && strcmp (argv [1], "--verbose") == 0)
|
||||
verbose = 1 ;
|
||||
|
||||
puts ("") ;
|
||||
|
||||
for (j = 0 ; j < ARRAY_LEN (snr_test_data) ; j++)
|
||||
{ best_snr = 5000.0 ;
|
||||
|
||||
converter = snr_test_data [j].converter ;
|
||||
|
||||
printf (" Converter %d : %s\n", converter, src_get_name (converter)) ;
|
||||
printf (" %s\n", src_get_description (converter)) ;
|
||||
|
||||
for (k = 0 ; k < snr_test_data [j].tests ; k++)
|
||||
{ snr = snr_test (&(snr_test_data [j].test_data [k]), k, converter, verbose) ;
|
||||
if (best_snr > snr)
|
||||
best_snr = snr ;
|
||||
} ;
|
||||
|
||||
printf (" Worst case Signal-to-Noise Ratio : %.2f dB.\n", best_snr) ;
|
||||
|
||||
if (snr_test_data [j].do_bandwidth_test == BOOLEAN_FALSE)
|
||||
{ puts (" Bandwith test not performed on this converter.\n") ;
|
||||
continue ;
|
||||
}
|
||||
|
||||
freq3dB = bandwidth_test (converter, verbose) ;
|
||||
|
||||
printf (" Measured -3dB rolloff point : %5.2f %%.\n\n", freq3dB) ;
|
||||
} ;
|
||||
|
||||
return 0 ;
|
||||
} /* main */
|
||||
|
||||
/*==============================================================================
|
||||
*/
|
||||
|
||||
static double
|
||||
snr_test (SINGLE_TEST *test_data, int number, int converter, int verbose)
|
||||
{ static float data [BUFFER_LEN + 1] ;
|
||||
static float output [MAX_SPEC_LEN] ;
|
||||
|
||||
SRC_STATE *src_state ;
|
||||
SRC_DATA src_data ;
|
||||
|
||||
double output_peak, snr ;
|
||||
int k, output_len, input_len, error ;
|
||||
|
||||
if (verbose != 0)
|
||||
{ printf ("\tSignal-to-Noise Ratio Test %d.\n"
|
||||
"\t=====================================\n", number) ;
|
||||
printf ("\tFrequencies : [ ") ;
|
||||
for (k = 0 ; k < test_data->freq_count ; k++)
|
||||
printf ("%6.4f ", test_data->freqs [k]) ;
|
||||
|
||||
printf ("]\n\tSRC Ratio : %8.4f\n", test_data->src_ratio) ;
|
||||
}
|
||||
else
|
||||
{ printf ("\tSignal-to-Noise Ratio Test %d : ", number) ;
|
||||
fflush (stdout) ;
|
||||
} ;
|
||||
|
||||
/* Set up the output array. */
|
||||
if (test_data->src_ratio >= 1.0)
|
||||
{ output_len = MAX_SPEC_LEN ;
|
||||
input_len = (int) ceil (MAX_SPEC_LEN / test_data->src_ratio) ;
|
||||
if (input_len > BUFFER_LEN)
|
||||
input_len = BUFFER_LEN ;
|
||||
}
|
||||
else
|
||||
{ input_len = BUFFER_LEN ;
|
||||
output_len = (int) ceil (BUFFER_LEN * test_data->src_ratio) ;
|
||||
output_len &= ((-1) << 4) ;
|
||||
if (output_len > MAX_SPEC_LEN)
|
||||
output_len = MAX_SPEC_LEN ;
|
||||
input_len = (int) ceil (output_len / test_data->src_ratio) ;
|
||||
} ;
|
||||
|
||||
memset (output, 0, sizeof (output)) ;
|
||||
|
||||
/* Generate input data array. */
|
||||
gen_windowed_sines (test_data->freq_count, test_data->freqs, 1.0, data, input_len) ;
|
||||
|
||||
/* Perform sample rate conversion. */
|
||||
if ((src_state = src_new (converter, 1, &error)) == NULL)
|
||||
{ printf ("\n\nLine %d : src_new() failed : %s.\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
src_data.end_of_input = 1 ; /* Only one buffer worth of input. */
|
||||
|
||||
src_data.data_in = data ;
|
||||
src_data.input_frames = input_len ;
|
||||
|
||||
src_data.src_ratio = test_data->src_ratio ;
|
||||
|
||||
src_data.data_out = output ;
|
||||
src_data.output_frames = output_len ;
|
||||
|
||||
if ((error = src_process (src_state, &src_data)))
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
src_state = src_delete (src_state) ;
|
||||
|
||||
if (verbose != 0)
|
||||
printf ("\tOutput Len : %ld\n", src_data.output_frames_gen) ;
|
||||
|
||||
if (abs (src_data.output_frames_gen - output_len) > 4)
|
||||
{ printf ("\n\nLine %d : output data length should be %d.\n\n", __LINE__, output_len) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
/* Check output peak. */
|
||||
output_peak = find_peak (output, src_data.output_frames_gen) ;
|
||||
|
||||
if (verbose != 0)
|
||||
printf ("\tOutput Peak : %6.4f\n", output_peak) ;
|
||||
|
||||
if (fabs (output_peak - test_data->peak_value) > 0.01)
|
||||
{ printf ("\n\nLine %d : output peak (%6.4f) should be %6.4f\n\n", __LINE__, output_peak, test_data->peak_value) ;
|
||||
save_oct_float ("snr_test.dat", data, BUFFER_LEN, output, output_len) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
/* Calculate signal-to-noise ratio. */
|
||||
snr = calculate_snr (output, src_data.output_frames_gen, test_data->pass_band_peaks) ;
|
||||
|
||||
if (snr < 0.0)
|
||||
{ /* An error occurred. */
|
||||
save_oct_float ("snr_test.dat", data, BUFFER_LEN, output, src_data.output_frames_gen) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (verbose != 0)
|
||||
printf ("\tSNR Ratio : %.2f dB\n", snr) ;
|
||||
|
||||
if (snr < test_data->snr)
|
||||
{ printf ("\n\nLine %d : SNR (%5.2f) should be > %6.2f dB\n\n", __LINE__, snr, test_data->snr) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (verbose != 0)
|
||||
puts ("\t-------------------------------------\n\tPass\n") ;
|
||||
else
|
||||
puts ("Pass") ;
|
||||
|
||||
return snr ;
|
||||
} /* snr_test */
|
||||
|
||||
static double
|
||||
find_peak (float *data, int len)
|
||||
{ double peak = 0.0 ;
|
||||
int k = 0 ;
|
||||
|
||||
for (k = 0 ; k < len ; k++)
|
||||
if (fabs (data [k]) > peak)
|
||||
peak = fabs (data [k]) ;
|
||||
|
||||
return peak ;
|
||||
} /* find_peak */
|
||||
|
||||
|
||||
static double
|
||||
find_attenuation (double freq, int converter, int verbose)
|
||||
{ static float input [BUFFER_LEN] ;
|
||||
static float output [2 * BUFFER_LEN] ;
|
||||
|
||||
SRC_DATA src_data ;
|
||||
double output_peak ;
|
||||
int error ;
|
||||
|
||||
gen_windowed_sines (1, &freq, 1.0, input, BUFFER_LEN) ;
|
||||
|
||||
src_data.end_of_input = 1 ; /* Only one buffer worth of input. */
|
||||
|
||||
src_data.data_in = input ;
|
||||
src_data.input_frames = BUFFER_LEN ;
|
||||
|
||||
src_data.src_ratio = 1.999 ;
|
||||
|
||||
src_data.data_out = output ;
|
||||
src_data.output_frames = ARRAY_LEN (output) ;
|
||||
|
||||
if ((error = src_simple (&src_data, converter, 1)))
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
output_peak = find_peak (output, ARRAY_LEN (output)) ;
|
||||
|
||||
if (verbose)
|
||||
printf ("\tFreq : %6f InPeak : %6f OutPeak : %6f Atten : %6.2f dB\n",
|
||||
freq, 1.0, output_peak, 20.0 * log10 (1.0 / output_peak)) ;
|
||||
|
||||
return 20.0 * log10 (1.0 / output_peak) ;
|
||||
} /* find_attenuation */
|
||||
|
||||
static double
|
||||
bandwidth_test (int converter, int verbose)
|
||||
{ double f1, f2, a1, a2 ;
|
||||
double freq, atten ;
|
||||
|
||||
f1 = 0.35 ;
|
||||
a1 = find_attenuation (f1, converter, verbose) ;
|
||||
|
||||
f2 = 0.495 ;
|
||||
a2 = find_attenuation (f2, converter, verbose) ;
|
||||
|
||||
if (a1 > 3.0 || a2 < 3.0)
|
||||
{ printf ("\n\nLine %d : cannot bracket 3dB point.\n\n", __LINE__) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
while (a2 - a1 > 1.0)
|
||||
{ freq = f1 + 0.5 * (f2 - f1) ;
|
||||
atten = find_attenuation (freq, converter, verbose) ;
|
||||
|
||||
if (atten < 3.0)
|
||||
{ f1 = freq ;
|
||||
a1 = atten ;
|
||||
}
|
||||
else
|
||||
{ f2 = freq ;
|
||||
a2 = atten ;
|
||||
} ;
|
||||
} ;
|
||||
|
||||
freq = f1 + (3.0 - a1) * (f2 - f1) / (a2 - a1) ;
|
||||
|
||||
return 200.0 * freq ;
|
||||
} /* bandwidth_test */
|
||||
|
||||
#else /* (HAVE_FFTW3) == 0 */
|
||||
|
||||
/* Alternative main function when librfftw is not available. */
|
||||
|
||||
int
|
||||
main (void)
|
||||
{ puts ("\n"
|
||||
"****************************************************************\n"
|
||||
" This test cannot be run without FFTW (http://www.fftw.org/).\n"
|
||||
" Both the real and the complex versions of the library are\n"
|
||||
" required.") ;
|
||||
puts ("****************************************************************\n") ;
|
||||
|
||||
return 0 ;
|
||||
} /* main */
|
||||
|
||||
#endif
|
||||
|
|
@ -1,339 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <samplerate.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#define SHORT_BUFFER_LEN 2048
|
||||
#define LONG_BUFFER_LEN ((1 << 16) - 20)
|
||||
|
||||
static void simple_test (int converter) ;
|
||||
static void stream_test (int converter, double ratio) ;
|
||||
static void init_term_test (int converter, double ratio) ;
|
||||
|
||||
static int next_block_length (int reset) ;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{ static double src_ratios [] =
|
||||
{ 0.999900, 1.000100, 0.789012, 1.200000, 0.333333, 3.100000,
|
||||
0.125000, 8.000000, 0.099900, 9.990000, 0.100000, 10.00000
|
||||
} ;
|
||||
|
||||
int k ;
|
||||
|
||||
puts ("\n Zero Order Hold interpolator:") ;
|
||||
|
||||
for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
|
||||
init_term_test (SRC_ZERO_ORDER_HOLD, src_ratios [k]) ;
|
||||
puts ("") ;
|
||||
for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
|
||||
stream_test (SRC_ZERO_ORDER_HOLD, src_ratios [k]) ;
|
||||
|
||||
|
||||
puts ("\n Linear interpolator:") ;
|
||||
for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
|
||||
init_term_test (SRC_LINEAR, src_ratios [k]) ;
|
||||
puts ("") ;
|
||||
for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
|
||||
stream_test (SRC_LINEAR, src_ratios [k]) ;
|
||||
|
||||
|
||||
puts ("\n Sinc interpolator:") ;
|
||||
for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
|
||||
init_term_test (SRC_SINC_FASTEST, src_ratios [k]) ;
|
||||
puts ("") ;
|
||||
for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
|
||||
stream_test (SRC_SINC_FASTEST, src_ratios [k]) ;
|
||||
|
||||
puts ("") ;
|
||||
|
||||
simple_test (SRC_SINC_FASTEST) ;
|
||||
|
||||
return 0 ;
|
||||
} /* main */
|
||||
|
||||
static void
|
||||
simple_test (int converter)
|
||||
{
|
||||
int ilen = 199030, olen = 1000, error ;
|
||||
|
||||
{
|
||||
float in [ilen] ;
|
||||
float out [olen] ;
|
||||
double ratio = (1.0 * olen) / ilen ;
|
||||
SRC_DATA src_data =
|
||||
{ in, out,
|
||||
ilen, olen,
|
||||
0, 0, 0,
|
||||
ratio
|
||||
} ;
|
||||
|
||||
error = src_simple (&src_data, converter, 1) ;
|
||||
if (error)
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
} ;
|
||||
|
||||
return ;
|
||||
} /* simple_test */
|
||||
|
||||
static void
|
||||
init_term_test (int converter, double src_ratio)
|
||||
{ static float input [SHORT_BUFFER_LEN], output [SHORT_BUFFER_LEN] ;
|
||||
|
||||
SRC_DATA src_data ;
|
||||
|
||||
int k, input_len, output_len, error, terminate ;
|
||||
|
||||
printf ("\tinit_term_test (SRC ratio = %7.4f) .......... ", src_ratio) ;
|
||||
fflush (stdout) ;
|
||||
|
||||
/* Calculate maximun input and output lengths. */
|
||||
if (src_ratio >= 1.0)
|
||||
{ output_len = SHORT_BUFFER_LEN ;
|
||||
input_len = (int) floor (SHORT_BUFFER_LEN / src_ratio) ;
|
||||
}
|
||||
else
|
||||
{ input_len = SHORT_BUFFER_LEN ;
|
||||
output_len = (int) floor (SHORT_BUFFER_LEN * src_ratio) ;
|
||||
} ;
|
||||
|
||||
/* Reduce input_len by 10 so output is longer than necessary. */
|
||||
input_len -= 10 ;
|
||||
|
||||
for (k = 0 ; k < ARRAY_LEN (input) ; k++)
|
||||
input [k] = 1.0 ;
|
||||
|
||||
if (output_len > SHORT_BUFFER_LEN)
|
||||
{ printf ("\n\nLine %d : output_len > SHORT_BUFFER_LEN\n\n", __LINE__) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
src_data.data_in = input ;
|
||||
src_data.input_frames = input_len ;
|
||||
|
||||
src_data.src_ratio = src_ratio ;
|
||||
|
||||
src_data.data_out = output ;
|
||||
src_data.output_frames = SHORT_BUFFER_LEN ;
|
||||
|
||||
if ((error = src_simple (&src_data, converter, 1)))
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
terminate = (int) ceil ((src_ratio >= 1.0) ? 1 : 1.0 / src_ratio) ;
|
||||
|
||||
if (fabs (src_ratio * input_len - src_data.output_frames_gen) > terminate)
|
||||
{ printf ("\n\nLine %d : Bad output frame count.\n\n", __LINE__) ;
|
||||
printf ("\tterminate : %d\n", terminate) ;
|
||||
printf ("\tsrc_ratio : %.4f\n", src_ratio) ;
|
||||
printf ("\tinput_len : %d\n"
|
||||
"\tinput_len * src_ratio : %f\n", input_len, input_len * src_ratio) ;
|
||||
printf ("\toutput_frames_gen : %ld\n\n", src_data.output_frames_gen) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (abs (src_data.input_frames_used - input_len) > 1)
|
||||
{ printf ("\n\nLine %d : input_frames_used should be %d, is %ld.\n\n",
|
||||
__LINE__, input_len, src_data.input_frames_used) ;
|
||||
printf ("\tsrc_ratio : %.4f\n", src_ratio) ;
|
||||
printf ("\tinput_len : %d\n\tinput_used : %ld\n\n", input_len, src_data.input_frames_used) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (fabs (output [0]) < 0.1)
|
||||
{ printf ("\n\nLine %d : First output sample is bad.\n\n", __LINE__) ;
|
||||
printf ("\toutput [0] == %f\n\n", output [0]) ;
|
||||
exit (1) ;
|
||||
}
|
||||
|
||||
puts ("ok") ;
|
||||
|
||||
return ;
|
||||
} /* init_term_test */
|
||||
|
||||
static void
|
||||
stream_test (int converter, double src_ratio)
|
||||
{ static float input [LONG_BUFFER_LEN], output [LONG_BUFFER_LEN] ;
|
||||
|
||||
SRC_STATE *src_state ;
|
||||
SRC_DATA src_data ;
|
||||
|
||||
int input_len, output_len, current_in, current_out ;
|
||||
int k, error, terminate ;
|
||||
|
||||
printf ("\tstream_test (SRC ratio = %7.4f) .......... ", src_ratio) ;
|
||||
fflush (stdout) ;
|
||||
|
||||
/* Erik */
|
||||
for (k = 0 ; k < LONG_BUFFER_LEN ; k++) input [k] = k * 1.0 ;
|
||||
|
||||
/* Calculate maximun input and output lengths. */
|
||||
if (src_ratio >= 1.0)
|
||||
{ output_len = LONG_BUFFER_LEN ;
|
||||
input_len = (int) floor (LONG_BUFFER_LEN / src_ratio) ;
|
||||
}
|
||||
else
|
||||
{ input_len = LONG_BUFFER_LEN ;
|
||||
output_len = (int) floor (LONG_BUFFER_LEN * src_ratio) ;
|
||||
} ;
|
||||
|
||||
/* Reduce input_len by 10 so output is longer than necessary. */
|
||||
input_len -= 20 ;
|
||||
|
||||
if (output_len > LONG_BUFFER_LEN)
|
||||
{ printf ("\n\nLine %d : output_len > LONG_BUFFER_LEN\n\n", __LINE__) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
current_in = current_out = 0 ;
|
||||
|
||||
/* Perform sample rate conversion. */
|
||||
if ((src_state = src_new (converter, 1, &error)) == NULL)
|
||||
{ printf ("\n\nLine %d : src_new() failed : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
src_data.end_of_input = 0 ; /* Set this later. */
|
||||
|
||||
src_data.data_in = input ;
|
||||
|
||||
src_data.src_ratio = src_ratio ;
|
||||
|
||||
src_data.data_out = output ;
|
||||
src_data.output_frames = ARRAY_LEN (output) / 10 ;
|
||||
|
||||
terminate = 1 + (int) ceil ((src_ratio >= 1.0) ? src_ratio : 1.0 / src_ratio) ;
|
||||
|
||||
while (1)
|
||||
{
|
||||
src_data.input_frames = next_block_length (0) ;
|
||||
src_data.input_frames = MIN (src_data.input_frames, input_len - current_in) ;
|
||||
|
||||
src_data.output_frames = ARRAY_LEN (output) - current_out ;
|
||||
/*-Erik MIN (src_data.output_frames, output_len - current_out) ;-*/
|
||||
|
||||
src_data.end_of_input = (current_in >= input_len) ? 1 : 0 ;
|
||||
|
||||
if ((error = src_process (src_state, &src_data)))
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
printf (" src_data.input_frames : %ld\n", src_data.input_frames) ;
|
||||
printf (" src_data.output_frames : %ld\n\n", src_data.output_frames) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (src_data.end_of_input && src_data.output_frames_gen == 0)
|
||||
break ;
|
||||
|
||||
if (src_data.input_frames_used > src_data.input_frames)
|
||||
{ printf ("\n\nLine %d : input_frames_used > input_frames\n\n", __LINE__) ;
|
||||
printf (" src_data.input_frames : %ld\n", src_data.input_frames) ;
|
||||
printf (" src_data.input_frames_used : %ld\n", src_data.input_frames_used) ;
|
||||
printf (" src_data.output_frames : %ld\n", src_data.output_frames) ;
|
||||
printf (" src_data.output_frames_gen : %ld\n\n", src_data.output_frames_gen) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (src_data.input_frames_used < 0)
|
||||
{ printf ("\n\nLine %d : input_frames_used (%ld) < 0\n\n", __LINE__, src_data.input_frames_used) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (src_data.output_frames_gen < 0)
|
||||
{ printf ("\n\nLine %d : output_frames_gen (%ld) < 0\n\n", __LINE__, src_data.output_frames_gen) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
current_in += src_data.input_frames_used ;
|
||||
current_out += src_data.output_frames_gen ;
|
||||
|
||||
if (current_in > input_len + terminate)
|
||||
{ printf ("\n\nLine %d : current_in (%d) > input_len (%d + %d)\n\n", __LINE__, current_in, input_len, terminate) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (current_out > output_len)
|
||||
{ printf ("\n\nLine %d : current_out (%d) > output_len (%d)\n\n", __LINE__, current_out, output_len) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (src_data.input_frames_used > input_len)
|
||||
{ printf ("\n\nLine %d : input_frames_used (%ld) > %d\n\n", __LINE__, src_data.input_frames_used, input_len) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (src_data.output_frames_gen > output_len)
|
||||
{ printf ("\n\nLine %d : output_frames_gen (%ld) > %d\n\n", __LINE__, src_data.output_frames_gen, output_len) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (src_data.data_in == NULL && src_data.output_frames_gen == 0)
|
||||
break ;
|
||||
|
||||
|
||||
src_data.data_in += src_data.input_frames_used ;
|
||||
src_data.data_out += src_data.output_frames_gen ;
|
||||
} ;
|
||||
|
||||
src_state = src_delete (src_state) ;
|
||||
|
||||
if (fabs (current_out - src_ratio * input_len) > terminate)
|
||||
{ printf ("\n\nLine %d : bad output data length %d should be %2.1f +/- %d.\n", __LINE__,
|
||||
current_out, src_ratio * input_len, terminate) ;
|
||||
printf ("\tsrc_ratio : %.4f\n", src_ratio) ;
|
||||
printf ("\tinput_len : %d\n\tinput_used : %d\n", input_len, current_in) ;
|
||||
printf ("\toutput_len : %d\n\toutput_gen : %d\n\n", output_len, current_out) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (current_in != input_len)
|
||||
{ printf ("\n\nLine %d : unused input.\n", __LINE__) ;
|
||||
printf ("\tinput_len : %d\n", input_len) ;
|
||||
printf ("\tinput_frames_used : %d\n\n", current_in) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
puts ("ok") ;
|
||||
|
||||
return ;
|
||||
} /* stream_test */
|
||||
|
||||
static int
|
||||
next_block_length (int reset)
|
||||
{ static int block_lengths [] = /* Should be an odd length. */
|
||||
{ /*-2, 500, 5, 400, 10, 300, 20, 200, 50, 100, 70 -*/
|
||||
5, 400, 10, 300, 20, 200, 50, 100, 70
|
||||
} ;
|
||||
static int block_len_index = 0 ;
|
||||
|
||||
if (reset)
|
||||
block_len_index = 0 ;
|
||||
else
|
||||
block_len_index = (block_len_index + 1) % ARRAY_LEN (block_lengths) ;
|
||||
|
||||
return block_lengths [block_len_index] ;
|
||||
} /* next_block_length */
|
||||
|
|
@ -1,212 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2004-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <samplerate.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "util.h"
|
||||
#include "float_cast.h"
|
||||
|
||||
#define BUFFER_LEN (1<<16)
|
||||
|
||||
static float input [BUFFER_LEN] ;
|
||||
static float output [BUFFER_LEN] ;
|
||||
|
||||
static long
|
||||
throughput_test (int converter, long best_throughput)
|
||||
{ SRC_DATA src_data ;
|
||||
clock_t start_time, clock_time ;
|
||||
double duration ;
|
||||
long total_frames = 0, throughput ;
|
||||
int error ;
|
||||
|
||||
printf (" %-30s ", src_get_name (converter)) ;
|
||||
fflush (stdout) ;
|
||||
|
||||
src_data.data_in = input ;
|
||||
src_data.input_frames = ARRAY_LEN (input) ;
|
||||
|
||||
src_data.data_out = output ;
|
||||
src_data.output_frames = ARRAY_LEN (output) ;
|
||||
|
||||
src_data.src_ratio = 0.99 ;
|
||||
|
||||
sleep (2) ;
|
||||
|
||||
start_time = clock () ;
|
||||
|
||||
do
|
||||
{
|
||||
if ((error = src_simple (&src_data, converter, 1)) != 0)
|
||||
{ puts (src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
total_frames += src_data.output_frames_gen ;
|
||||
|
||||
clock_time = clock () - start_time ;
|
||||
duration = (1.0 * clock_time) / CLOCKS_PER_SEC ;
|
||||
}
|
||||
while (duration < 3.0) ;
|
||||
|
||||
if (src_data.input_frames_used != ARRAY_LEN (input))
|
||||
{ printf ("\n\nLine %d : input frames used %ld should be %d\n", __LINE__, src_data.input_frames_used, ARRAY_LEN (input)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (fabs (src_data.src_ratio * src_data.input_frames_used - src_data.output_frames_gen) > 2)
|
||||
{ printf ("\n\nLine %d : input / output length mismatch.\n\n", __LINE__) ;
|
||||
printf (" input len : %d\n", ARRAY_LEN (input)) ;
|
||||
printf (" output len : %ld (should be %g +/- 2)\n\n", src_data.output_frames_gen,
|
||||
floor (0.5 + src_data.src_ratio * src_data.input_frames_used)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
throughput = lrint (floor (total_frames / duration)) ;
|
||||
|
||||
if (best_throughput == 0)
|
||||
{ best_throughput = MAX (throughput, best_throughput) ;
|
||||
printf ("%5.2f %10ld\n", duration, throughput) ;
|
||||
}
|
||||
else
|
||||
{ best_throughput = MAX (throughput, best_throughput) ;
|
||||
printf ("%5.2f %10ld %10ld\n", duration, throughput, best_throughput) ;
|
||||
}
|
||||
|
||||
|
||||
return best_throughput ;
|
||||
} /* throughput_test */
|
||||
|
||||
static void
|
||||
single_run (void)
|
||||
{
|
||||
|
||||
printf ("\n CPU name : %s\n", get_cpu_name ()) ;
|
||||
|
||||
puts (
|
||||
"\n"
|
||||
" Converter Duration Throughput\n"
|
||||
" -----------------------------------------------------------"
|
||||
) ;
|
||||
|
||||
throughput_test (SRC_ZERO_ORDER_HOLD, 0) ;
|
||||
throughput_test (SRC_LINEAR, 0) ;
|
||||
throughput_test (SRC_SINC_FASTEST, 0) ;
|
||||
throughput_test (SRC_SINC_MEDIUM_QUALITY, 0) ;
|
||||
throughput_test (SRC_SINC_BEST_QUALITY, 0) ;
|
||||
|
||||
puts ("") ;
|
||||
return ;
|
||||
} /* single_run */
|
||||
|
||||
static void
|
||||
multi_run (int run_count)
|
||||
{ long zero_order_hold = 0, linear = 0 ;
|
||||
long sinc_fastest = 0, sinc_medium = 0, sinc_best = 0 ;
|
||||
int k ;
|
||||
|
||||
puts (
|
||||
"\n"
|
||||
" Converter Duration Throughput Best Throughput\n"
|
||||
" --------------------------------------------------------------------------------"
|
||||
) ;
|
||||
|
||||
for (k = 0 ; k < run_count ; k++)
|
||||
{ zero_order_hold = throughput_test (SRC_ZERO_ORDER_HOLD, zero_order_hold) ;
|
||||
linear = throughput_test (SRC_LINEAR, linear) ;
|
||||
sinc_fastest = throughput_test (SRC_SINC_FASTEST, sinc_fastest) ;
|
||||
sinc_medium = throughput_test (SRC_SINC_MEDIUM_QUALITY, sinc_medium) ;
|
||||
sinc_best = throughput_test (SRC_SINC_BEST_QUALITY, sinc_best) ;
|
||||
|
||||
puts ("") ;
|
||||
|
||||
/* Let the CPU cool down. We might be running on a laptop. */
|
||||
sleep (10) ;
|
||||
} ;
|
||||
|
||||
printf ("\n CPU name : %s\n", get_cpu_name ()) ;
|
||||
|
||||
puts (
|
||||
"\n"
|
||||
" Converter Best Throughput\n"
|
||||
" ------------------------------------------------"
|
||||
) ;
|
||||
printf (" %-30s %10ld\n", src_get_name (SRC_ZERO_ORDER_HOLD), zero_order_hold) ;
|
||||
printf (" %-30s %10ld\n", src_get_name (SRC_LINEAR), linear) ;
|
||||
printf (" %-30s %10ld\n", src_get_name (SRC_SINC_FASTEST), sinc_fastest) ;
|
||||
printf (" %-30s %10ld\n", src_get_name (SRC_SINC_MEDIUM_QUALITY), sinc_medium) ;
|
||||
printf (" %-30s %10ld\n", src_get_name (SRC_SINC_BEST_QUALITY), sinc_best) ;
|
||||
|
||||
puts ("") ;
|
||||
} /* multi_run */
|
||||
|
||||
static void
|
||||
usage_exit (const char * argv0)
|
||||
{ const char * cptr ;
|
||||
|
||||
if ((cptr = strrchr (argv0, '/')) != NULL)
|
||||
argv0 = cptr ;
|
||||
|
||||
printf (
|
||||
"Usage :\n"
|
||||
" %s - Single run of the throughput test.\n"
|
||||
" %s --best-of N - Do N runs of test a print bext result.\n"
|
||||
"\n",
|
||||
argv0, argv0) ;
|
||||
|
||||
exit (0) ;
|
||||
} /* usage_exit */
|
||||
|
||||
int
|
||||
main (int argc, char ** argv)
|
||||
{ double freq ;
|
||||
|
||||
memset (input, 0, sizeof (input)) ;
|
||||
freq = 0.01 ;
|
||||
gen_windowed_sines (1, &freq, 1.0, input, BUFFER_LEN) ;
|
||||
|
||||
if (argc == 1)
|
||||
single_run () ;
|
||||
else if (argc == 3 && strcmp (argv [1], "--best-of") == 0)
|
||||
{ int run_count = atoi (argv [2]) ;
|
||||
|
||||
if (run_count < 1 || run_count > 20)
|
||||
{ printf ("Please be sensible. Run count should be in range (1, 10].\n") ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
multi_run (run_count) ;
|
||||
}
|
||||
else
|
||||
usage_exit (argv [0]) ;
|
||||
|
||||
puts (
|
||||
" Duration is in seconds.\n"
|
||||
" Throughput is in samples/sec (more is better).\n"
|
||||
) ;
|
||||
|
||||
return 0 ;
|
||||
} /* main */
|
||||
|
|
@ -1,230 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846264338
|
||||
#endif
|
||||
|
||||
void
|
||||
gen_windowed_sines (int freq_count, const double *freqs, double max, float *output, int output_len)
|
||||
{ int k, freq ;
|
||||
double amplitude, phase ;
|
||||
|
||||
amplitude = max / freq_count ;
|
||||
|
||||
for (k = 0 ; k < output_len ; k++)
|
||||
output [k] = 0.0 ;
|
||||
|
||||
for (freq = 0 ; freq < freq_count ; freq++)
|
||||
{ phase = 0.9 * M_PI / freq_count ;
|
||||
|
||||
if (freqs [freq] <= 0.0 || freqs [freq] >= 0.5)
|
||||
{ printf ("\n%s : Error : freq [%d] == %g is out of range. Should be < 0.5.\n", __FILE__, freq, freqs [freq]) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
for (k = 0 ; k < output_len ; k++)
|
||||
output [k] += amplitude * sin (freqs [freq] * (2 * k) * M_PI + phase) ;
|
||||
} ;
|
||||
|
||||
/* Apply Hanning Window. */
|
||||
for (k = 0 ; k < output_len ; k++)
|
||||
output [k] *= 0.5 - 0.5 * cos ((2 * k) * M_PI / (output_len - 1)) ;
|
||||
|
||||
/* data [k] *= 0.3635819 - 0.4891775 * cos ((2 * k) * M_PI / (output_len - 1))
|
||||
+ 0.1365995 * cos ((4 * k) * M_PI / (output_len - 1))
|
||||
- 0.0106411 * cos ((6 * k) * M_PI / (output_len - 1)) ;
|
||||
*/
|
||||
|
||||
return ;
|
||||
} /* gen_windowed_sines */
|
||||
|
||||
void
|
||||
save_oct_float (char *filename, float *input, int in_len, float *output, int out_len)
|
||||
{ FILE *file ;
|
||||
int k ;
|
||||
|
||||
printf ("Dumping input and output data to file : %s.\n\n", filename) ;
|
||||
|
||||
if (! (file = fopen (filename, "w")))
|
||||
return ;
|
||||
|
||||
fprintf (file, "# Not created by Octave\n") ;
|
||||
|
||||
fprintf (file, "# name: input\n") ;
|
||||
fprintf (file, "# type: matrix\n") ;
|
||||
fprintf (file, "# rows: %d\n", in_len) ;
|
||||
fprintf (file, "# columns: 1\n") ;
|
||||
|
||||
for (k = 0 ; k < in_len ; k++)
|
||||
fprintf (file, "% g\n", input [k]) ;
|
||||
|
||||
fprintf (file, "# name: output\n") ;
|
||||
fprintf (file, "# type: matrix\n") ;
|
||||
fprintf (file, "# rows: %d\n", out_len) ;
|
||||
fprintf (file, "# columns: 1\n") ;
|
||||
|
||||
for (k = 0 ; k < out_len ; k++)
|
||||
fprintf (file, "% g\n", output [k]) ;
|
||||
|
||||
fclose (file) ;
|
||||
return ;
|
||||
} /* save_oct_float */
|
||||
|
||||
void
|
||||
save_oct_double (char *filename, double *input, int in_len, double *output, int out_len)
|
||||
{ FILE *file ;
|
||||
int k ;
|
||||
|
||||
printf ("Dumping input and output data to file : %s.\n\n", filename) ;
|
||||
|
||||
if (! (file = fopen (filename, "w")))
|
||||
return ;
|
||||
|
||||
fprintf (file, "# Not created by Octave\n") ;
|
||||
|
||||
fprintf (file, "# name: input\n") ;
|
||||
fprintf (file, "# type: matrix\n") ;
|
||||
fprintf (file, "# rows: %d\n", in_len) ;
|
||||
fprintf (file, "# columns: 1\n") ;
|
||||
|
||||
for (k = 0 ; k < in_len ; k++)
|
||||
fprintf (file, "% g\n", input [k]) ;
|
||||
|
||||
fprintf (file, "# name: output\n") ;
|
||||
fprintf (file, "# type: matrix\n") ;
|
||||
fprintf (file, "# rows: %d\n", out_len) ;
|
||||
fprintf (file, "# columns: 1\n") ;
|
||||
|
||||
for (k = 0 ; k < out_len ; k++)
|
||||
fprintf (file, "% g\n", output [k]) ;
|
||||
|
||||
fclose (file) ;
|
||||
return ;
|
||||
} /* save_oct_double */
|
||||
|
||||
void
|
||||
interleave_data (const float *in, float *out, int frames, int channels)
|
||||
{ int fr, ch ;
|
||||
|
||||
for (fr = 0 ; fr < frames ; fr++)
|
||||
for (ch = 0 ; ch < channels ; ch++)
|
||||
out [ch + channels * fr] = in [fr + frames * ch] ;
|
||||
|
||||
return ;
|
||||
} /* interleave_data */
|
||||
|
||||
void
|
||||
deinterleave_data (const float *in, float *out, int frames, int channels)
|
||||
{ int fr, ch ;
|
||||
|
||||
for (ch = 0 ; ch < channels ; ch++)
|
||||
for (fr = 0 ; fr < frames ; fr++)
|
||||
out [fr + frames * ch] = in [ch + channels * fr] ;
|
||||
|
||||
return ;
|
||||
} /* deinterleave_data */
|
||||
|
||||
void
|
||||
reverse_data (float *data, int datalen)
|
||||
{ int left, right ;
|
||||
float temp ;
|
||||
|
||||
left = 0 ;
|
||||
right = datalen - 1 ;
|
||||
|
||||
while (left < right)
|
||||
{ temp = data [left] ;
|
||||
data [left] = data [right] ;
|
||||
data [right] = temp ;
|
||||
left ++ ;
|
||||
right -- ;
|
||||
} ;
|
||||
|
||||
} /* reverse_data */
|
||||
|
||||
const char *
|
||||
get_cpu_name (void)
|
||||
{
|
||||
const char *name = "Unknown", *search = NULL ;
|
||||
static char buffer [512] ;
|
||||
FILE * file = NULL ;
|
||||
int is_pipe = 0 ;
|
||||
|
||||
#if defined (__linux__)
|
||||
file = fopen ("/proc/cpuinfo", "r") ;
|
||||
search = "model name" ;
|
||||
#elif defined (__APPLE__)
|
||||
file = popen ("/usr/sbin/system_profiler -detailLevel full SPHardwareDataType", "r") ;
|
||||
search = "Processor Name" ;
|
||||
is_pipe = 1 ;
|
||||
#elif defined (__FreeBSD__)
|
||||
file = popen ("sysctl -a", "r") ;
|
||||
search = "hw.model" ;
|
||||
is_pipe = 1 ;
|
||||
#else
|
||||
file = NULL ;
|
||||
#endif
|
||||
|
||||
if (file == NULL)
|
||||
return name ;
|
||||
|
||||
if (search == NULL)
|
||||
{ printf ("Error : search is NULL in function %s.\n", __func__) ;
|
||||
return name ;
|
||||
} ;
|
||||
|
||||
while (fgets (buffer, sizeof (buffer), file) != NULL)
|
||||
if (strstr (buffer, search))
|
||||
{ char *src, *dest ;
|
||||
|
||||
if ((src = strchr (buffer, ':')) != NULL)
|
||||
{ src ++ ;
|
||||
while (isspace (src [0]))
|
||||
src ++ ;
|
||||
name = src ;
|
||||
|
||||
/* Remove consecutive spaces. */
|
||||
src ++ ;
|
||||
for (dest = src ; src [0] ; src ++)
|
||||
{ if (isspace (src [0]) && isspace (dest [-1]))
|
||||
continue ;
|
||||
dest [0] = src [0] ;
|
||||
dest ++ ;
|
||||
} ;
|
||||
dest [0] = 0 ;
|
||||
break ;
|
||||
} ;
|
||||
} ;
|
||||
|
||||
if (is_pipe)
|
||||
pclose (file) ;
|
||||
else
|
||||
fclose (file) ;
|
||||
|
||||
return name ;
|
||||
} /* get_cpu_name */
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#define ABS(a) (((a) < 0) ? - (a) : (a))
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a,b) (((a) >= (b)) ? (a) : (b))
|
||||
|
||||
#define ARRAY_LEN(x) ((int) (sizeof (x) / sizeof ((x) [0])))
|
||||
|
||||
void gen_windowed_sines (int freq_count, const double *freqs, double max, float *output, int output_len) ;
|
||||
|
||||
void save_oct_float (char *filename, float *input, int in_len, float *output, int out_len) ;
|
||||
void save_oct_double (char *filename, double *input, int in_len, double *output, int out_len) ;
|
||||
|
||||
void interleave_data (const float *in, float *out, int frames, int channels) ;
|
||||
|
||||
void deinterleave_data (const float *in, float *out, int frames, int channels) ;
|
||||
|
||||
void reverse_data (float *data, int datalen) ;
|
||||
|
||||
double calculate_snr (float *data, int len, int expected_peaks) ;
|
||||
|
||||
const char * get_cpu_name (void) ;
|
||||
|
||||
#if OS_IS_WIN32
|
||||
/*
|
||||
** Extra Win32 hacks.
|
||||
**
|
||||
** Despite Microsoft claim of windows being POSIX compatibile it has '_sleep'
|
||||
** instead of 'sleep'.
|
||||
*/
|
||||
|
||||
#define sleep _sleep
|
||||
#endif
|
||||
|
|
@ -1,152 +0,0 @@
|
|||
/*
|
||||
** Copyright (C) 2006-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
|
||||
**
|
||||
** This program is free software; you can redistribute it and/or modify
|
||||
** it under the terms of the GNU General Public License as published by
|
||||
** the Free Software Foundation; either version 2 of the License, or
|
||||
** (at your option) any later version.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program; if not, write to the Free Software
|
||||
** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <samplerate.h>
|
||||
|
||||
#include "util.h"
|
||||
|
||||
#define BUFFER_LEN (1 << 16)
|
||||
|
||||
static void varispeed_test (int converter, double target_snr) ;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
puts ("") ;
|
||||
printf (" Zero Order Hold interpolator : ") ;
|
||||
varispeed_test (SRC_ZERO_ORDER_HOLD, 10.0) ;
|
||||
|
||||
printf (" Linear interpolator : ") ;
|
||||
varispeed_test (SRC_LINEAR, 10.0) ;
|
||||
|
||||
printf (" Sinc interpolator : ") ;
|
||||
varispeed_test (SRC_SINC_FASTEST, 115.0) ;
|
||||
|
||||
puts ("") ;
|
||||
|
||||
return 0 ;
|
||||
} /* main */
|
||||
|
||||
static void
|
||||
varispeed_test (int converter, double target_snr)
|
||||
{ static float input [BUFFER_LEN], output [BUFFER_LEN] ;
|
||||
double sine_freq, snr ;
|
||||
|
||||
SRC_STATE *src_state ;
|
||||
SRC_DATA src_data ;
|
||||
|
||||
int input_len, error ;
|
||||
|
||||
memset (input, 0, sizeof (input)) ;
|
||||
|
||||
input_len = ARRAY_LEN (input) / 2 ;
|
||||
|
||||
sine_freq = 0.0111 ;
|
||||
gen_windowed_sines (1, &sine_freq, 1.0, input, input_len) ;
|
||||
|
||||
/* Perform sample rate conversion. */
|
||||
if ((src_state = src_new (converter, 1, &error)) == NULL)
|
||||
{ printf ("\n\nLine %d : src_new() failed : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
src_data.end_of_input = 1 ;
|
||||
|
||||
src_data.data_in = input ;
|
||||
src_data.input_frames = input_len ;
|
||||
|
||||
src_data.src_ratio = 3.0 ;
|
||||
|
||||
src_data.data_out = output ;
|
||||
src_data.output_frames = ARRAY_LEN (output) ;
|
||||
|
||||
if ((error = src_set_ratio (src_state, 1.0 / src_data.src_ratio)))
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if ((error = src_process (src_state, &src_data)))
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
printf (" src_data.input_frames : %ld\n", src_data.input_frames) ;
|
||||
printf (" src_data.output_frames : %ld\n\n", src_data.output_frames) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (src_data.input_frames_used != input_len)
|
||||
{ printf ("\n\nLine %d : unused input.\n", __LINE__) ;
|
||||
printf ("\tinput_len : %d\n", input_len) ;
|
||||
printf ("\tinput_frames_used : %ld\n\n", src_data.input_frames_used) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
/* Copy the last output to the input. */
|
||||
memcpy (input, output, sizeof (input)) ;
|
||||
reverse_data (input, src_data.output_frames_gen) ;
|
||||
|
||||
if ((error = src_reset (src_state)))
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
src_data.end_of_input = 1 ;
|
||||
|
||||
src_data.data_in = input ;
|
||||
input_len = src_data.input_frames = src_data.output_frames_gen ;
|
||||
|
||||
src_data.data_out = output ;
|
||||
src_data.output_frames = ARRAY_LEN (output) ;
|
||||
|
||||
if ((error = src_set_ratio (src_state, 1.0 / src_data.src_ratio)))
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if ((error = src_process (src_state, &src_data)))
|
||||
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
|
||||
printf (" src_data.input_frames : %ld\n", src_data.input_frames) ;
|
||||
printf (" src_data.output_frames : %ld\n\n", src_data.output_frames) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
if (src_data.input_frames_used != input_len)
|
||||
{ printf ("\n\nLine %d : unused input.\n", __LINE__) ;
|
||||
printf ("\tinput_len : %d\n", input_len) ;
|
||||
printf ("\tinput_frames_used : %ld\n\n", src_data.input_frames_used) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
src_state = src_delete (src_state) ;
|
||||
|
||||
snr = calculate_snr (output, src_data.output_frames_gen, 1) ;
|
||||
|
||||
if (target_snr > snr)
|
||||
{ printf ("\n\nLine %d : snr (%3.1f) does not meet target (%3.1f)\n\n", __LINE__, snr, target_snr) ;
|
||||
save_oct_float ("varispeed.mat", input, src_data.input_frames, output, src_data.output_frames_gen) ;
|
||||
exit (1) ;
|
||||
} ;
|
||||
|
||||
puts ("ok") ;
|
||||
|
||||
return ;
|
||||
} /* varispeed_test */
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
|
||||
Cmake is able to configure, build (as either a DLL or a static library),
|
||||
and install libsoxr for general use on MS-Windows as on other OSs.
|
||||
However, for projects that prefer to maintain a more monolithic build
|
||||
structure using the MSVC compiler, the accompanying files may be useful.
|
||||
|
||||
* libsoxr.vcproj Builds a static lib for MSVC ver >= 9 (2008).
|
||||
* soxr-config.h Pre-configured for a typical Win32 system.
|
||||
SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
|
||||
Cmake is able to configure, build (as either a DLL or a static library),
|
||||
and install libsoxr for general use on MS-Windows as on other OSs.
|
||||
However, for projects that prefer to maintain a more monolithic build
|
||||
structure using the MSVC compiler, the accompanying files may be useful.
|
||||
|
||||
* libsoxr.vcproj Builds a static lib for MSVC ver >= 9 (2008).
|
||||
* soxr-config.h Pre-configured for a typical Win32 system.
|
||||
|
|
|
@ -1,25 +1,19 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* N.B. Pre-configured for typical Win32 systems. Normal procedure is to use
|
||||
* the cmake configuration and build system. See INSTALL. */
|
||||
/* N.B. Pre-configured for typical MS-Windows systems. However, the normal
|
||||
* procedure is to use the cmake configuration and build system. See INSTALL. */
|
||||
|
||||
#if !defined soxr_config_included
|
||||
#define soxr_config_included
|
||||
|
||||
#define SOXR_VERSION_MAJOR 0
|
||||
#define SOXR_VERSION_MINOR 0
|
||||
#define SOXR_VERSION_PATCH 1
|
||||
#define SOXR_VERSION "0.0.5"
|
||||
|
||||
#define HAVE_SINGLE_PRECISION 1
|
||||
#define HAVE_DOUBLE_PRECISION 1
|
||||
#define HAVE_VR 1
|
||||
#define HAVE_AVFFT 0
|
||||
#define HAVE_SIMD 1
|
||||
#define HAVE_FENV_H 0
|
||||
#define HAVE_LRINT 0
|
||||
#define WORDS_BIGENDIAN 0
|
||||
#define HAVE_AVFFT 0
|
||||
#define HAVE_SIMD 1
|
||||
#define HAVE_FENV_H 0
|
||||
#define HAVE_LRINT 0
|
||||
#define WORDS_BIGENDIAN 0
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
|
@ -39,17 +33,15 @@
|
|||
#if LONG_MAX > 2147483647L
|
||||
#define int32_t int
|
||||
#define int64_t long
|
||||
#define DBL (double)
|
||||
#elif LONG_MAX < 2147483647L
|
||||
#error this library requires that 'long int' has at least 32-bits
|
||||
#else
|
||||
#define int32_t long
|
||||
#if defined(_MSC_VER)
|
||||
#if defined _MSC_VER
|
||||
#define int64_t __int64
|
||||
#else
|
||||
#define int64_t long long
|
||||
#endif
|
||||
#define DBL
|
||||
#endif
|
||||
#define uint32_t unsigned int32_t
|
||||
#define uint64_t unsigned int64_t
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#if !defined soxr_config_included
|
||||
#define soxr_config_included
|
||||
|
||||
#define SOXR_VERSION "@PROJECT_VERSION@"
|
||||
#define HAVE_SINGLE_PRECISION @HAVE_SINGLE_PRECISION@
|
||||
#define HAVE_DOUBLE_PRECISION @HAVE_DOUBLE_PRECISION@
|
||||
#define HAVE_VR @HAVE_VR@
|
||||
#define HAVE_AVFFT @HAVE_AVFFT@
|
||||
#define HAVE_SIMD @HAVE_SIMD@
|
||||
#define HAVE_FENV_H @HAVE_FENV_H@
|
||||
|
@ -32,7 +30,6 @@
|
|||
#if LONG_MAX > 2147483647L
|
||||
#define int32_t int
|
||||
#define int64_t long
|
||||
#define DBL (double)
|
||||
#elif LONG_MAX < 2147483647L
|
||||
#error this library requires that 'long int' has at least 32-bits
|
||||
#else
|
||||
|
@ -42,7 +39,6 @@
|
|||
#else
|
||||
#define int64_t long long
|
||||
#endif
|
||||
#define DBL
|
||||
#endif
|
||||
#define uint32_t unsigned int32_t
|
||||
#define uint64_t unsigned int64_t
|
||||
|
|
|
@ -1,112 +1,110 @@
|
|||
# SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
# Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
add_definitions (${PROJECT_C_FLAGS} -DSOXR_LIB)
|
||||
|
||||
|
||||
|
||||
# Libsoxr configuration:
|
||||
|
||||
set (RDFT32 fft4g32)
|
||||
if (WITH_AVFFT AND AVCODEC_FOUND)
|
||||
set (RDFT32S avfft32s)
|
||||
elseif (WITH_PFFFT)
|
||||
set (RDFT32S pffft32s)
|
||||
elseif (WITH_SIMD)
|
||||
set (RDFT32S fft4g32s)
|
||||
endif ()
|
||||
|
||||
if (WITH_DOUBLE_PRECISION)
|
||||
set (DP_SOURCES rate64)
|
||||
endif ()
|
||||
|
||||
if (WITH_SINGLE_PRECISION)
|
||||
set (SP_SOURCES rate32 ${RDFT32})
|
||||
endif ()
|
||||
|
||||
if (HAVE_VR)
|
||||
set (VR_SOURCES vr32)
|
||||
endif ()
|
||||
|
||||
if (HAVE_SIMD)
|
||||
set (SIMD_SOURCES rate32s ${RDFT32S} simd)
|
||||
foreach (source ${SIMD_SOURCES})
|
||||
set_property (SOURCE ${source} PROPERTY COMPILE_FLAGS ${SIMD_C_FLAGS})
|
||||
endforeach ()
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
# Libsoxr:
|
||||
|
||||
add_library (${PROJECT_NAME} ${LIB_TYPE} ${PROJECT_NAME}.c data-io dbesi0 filter fft4g64
|
||||
${SP_SOURCES} ${VR_SOURCES} ${DP_SOURCES} ${SIMD_SOURCES})
|
||||
set_target_properties (${PROJECT_NAME} PROPERTIES
|
||||
VERSION "${SO_VERSION}"
|
||||
SOVERSION ${SO_VERSION_MAJOR}
|
||||
INSTALL_NAME_DIR ${LIB_INSTALL_DIR}
|
||||
LINK_INTERFACE_LIBRARIES ""
|
||||
PUBLIC_HEADER "${PROJECT_NAME}.h")
|
||||
if (BUILD_FRAMEWORK)
|
||||
set_target_properties (${PROJECT_NAME} PROPERTIES FRAMEWORK TRUE)
|
||||
elseif (NOT WIN32)
|
||||
set (TARGET_PCS ${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}.pc)
|
||||
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/lib${PROJECT_NAME}.pc.in ${TARGET_PCS})
|
||||
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
# LSR bindings:
|
||||
|
||||
if (WITH_LSR_BINDINGS)
|
||||
set (LSR ${PROJECT_NAME}-lsr)
|
||||
set (LSR_SO_VERSION 0.1.8)
|
||||
set (LSR_SO_VERSION_MAJOR 0)
|
||||
add_library (${LSR} ${LIB_TYPE} lsr)
|
||||
target_link_libraries (${LSR} ${PROJECT_NAME})
|
||||
set_target_properties (${LSR} PROPERTIES
|
||||
VERSION "${LSR_SO_VERSION}"
|
||||
SOVERSION ${LSR_SO_VERSION_MAJOR}
|
||||
INSTALL_NAME_DIR ${LIB_INSTALL_DIR}
|
||||
LINK_INTERFACE_LIBRARIES ""
|
||||
PUBLIC_HEADER "${LSR}.h")
|
||||
if (BUILD_FRAMEWORK)
|
||||
set_target_properties (${LSR} PROPERTIES FRAMEWORK TRUE)
|
||||
elseif (NOT WIN32)
|
||||
set (TARGET_PCS "${TARGET_PCS} ${CMAKE_CURRENT_BINARY_DIR}/lib${LSR}.pc")
|
||||
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/lib${LSR}.pc.in ${CMAKE_CURRENT_BINARY_DIR}/lib${LSR}.pc)
|
||||
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/lib${LSR}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
# Installation (from build from source):
|
||||
|
||||
install (TARGETS ${PROJECT_NAME} ${LSR}
|
||||
FRAMEWORK DESTINATION ${FRAMEWORK_INSTALL_DIR}
|
||||
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
|
||||
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
|
||||
PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR})
|
||||
|
||||
|
||||
|
||||
# Packaging (for unix-like distributions):
|
||||
|
||||
get_property (LIB1 TARGET ${PROJECT_NAME} PROPERTY LOCATION)
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set (LIB1 ${LIB1}.${SO_VERSION_MAJOR} ${LIB1}.${SO_VERSION})
|
||||
endif ()
|
||||
list (APPEND TARGET_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.h")
|
||||
if (WITH_LSR_BINDINGS)
|
||||
get_property (LIB2 TARGET ${LSR} PROPERTY LOCATION)
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set (LIB2 ${LIB2}.${LSR_SO_VERSION_MAJOR} ${LIB2}.${LSR_SO_VERSION})
|
||||
endif ()
|
||||
list (APPEND TARGET_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${LSR}.h")
|
||||
endif ()
|
||||
set (TARGET_LIBS ${LIB1} ${LIB2})
|
||||
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/libsoxr.src.in ${CMAKE_CURRENT_BINARY_DIR}/libsoxr.src)
|
||||
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/libsoxr-dev.src.in ${CMAKE_CURRENT_BINARY_DIR}/libsoxr-dev.src)
|
||||
# SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
# Licence for this file: LGPL v2.1 See LICENCE for details.
|
||||
|
||||
add_definitions (${PROJECT_C_FLAGS} -DSOXR_LIB)
|
||||
|
||||
|
||||
|
||||
# Libsoxr configuration:
|
||||
|
||||
set (RDFT32 fft4g32)
|
||||
if (WITH_AVFFT AND AVCODEC_FOUND)
|
||||
set (RDFT32 avfft32)
|
||||
set (RDFT32S avfft32s)
|
||||
elseif (WITH_PFFFT)
|
||||
#set (RDFT32 pffft32)
|
||||
set (RDFT32S pffft32s)
|
||||
elseif (WITH_SIMD)
|
||||
set (RDFT32S fft4g32s)
|
||||
endif ()
|
||||
|
||||
if (WITH_DOUBLE_PRECISION)
|
||||
set (DP_SOURCES rate64)
|
||||
endif ()
|
||||
|
||||
if (WITH_SINGLE_PRECISION)
|
||||
set (SP_SOURCES rate32 ${RDFT32})
|
||||
endif ()
|
||||
|
||||
if (HAVE_SIMD)
|
||||
set (SIMD_SOURCES rate32s ${RDFT32S} simd)
|
||||
foreach (source ${SIMD_SOURCES})
|
||||
set_property (SOURCE ${source} PROPERTY COMPILE_FLAGS ${SIMD_C_FLAGS})
|
||||
endforeach ()
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
# Libsoxr:
|
||||
|
||||
add_library (${PROJECT_NAME} ${LIB_TYPE} ${PROJECT_NAME}.c data-io dbesi0 filter fft4g64
|
||||
${SP_SOURCES} vr32 ${DP_SOURCES} ${SIMD_SOURCES})
|
||||
set_target_properties (${PROJECT_NAME} PROPERTIES
|
||||
VERSION "${SO_VERSION}"
|
||||
SOVERSION ${SO_VERSION_MAJOR}
|
||||
INSTALL_NAME_DIR ${LIB_INSTALL_DIR}
|
||||
LINK_INTERFACE_LIBRARIES ""
|
||||
PUBLIC_HEADER "${PROJECT_NAME}.h")
|
||||
if (BUILD_FRAMEWORK)
|
||||
set_target_properties (${PROJECT_NAME} PROPERTIES FRAMEWORK TRUE)
|
||||
elseif (NOT WIN32)
|
||||
set (TARGET_PCS ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc)
|
||||
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.pc.in ${TARGET_PCS})
|
||||
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
# LSR bindings:
|
||||
|
||||
if (WITH_LSR_BINDINGS)
|
||||
set (LSR ${PROJECT_NAME}-lsr)
|
||||
set (LSR_SO_VERSION 0.1.9)
|
||||
set (LSR_SO_VERSION_MAJOR 0)
|
||||
add_library (${LSR} ${LIB_TYPE} lsr)
|
||||
target_link_libraries (${LSR} ${PROJECT_NAME})
|
||||
set_target_properties (${LSR} PROPERTIES
|
||||
VERSION "${LSR_SO_VERSION}"
|
||||
SOVERSION ${LSR_SO_VERSION_MAJOR}
|
||||
INSTALL_NAME_DIR ${LIB_INSTALL_DIR}
|
||||
LINK_INTERFACE_LIBRARIES ""
|
||||
PUBLIC_HEADER "${LSR}.h")
|
||||
if (BUILD_FRAMEWORK)
|
||||
set_target_properties (${LSR} PROPERTIES FRAMEWORK TRUE)
|
||||
elseif (NOT WIN32)
|
||||
set (TARGET_PCS "${TARGET_PCS} ${CMAKE_CURRENT_BINARY_DIR}/${LSR}.pc")
|
||||
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/${LSR}.pc.in ${CMAKE_CURRENT_BINARY_DIR}/${LSR}.pc)
|
||||
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/${LSR}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
# Installation (from build from source):
|
||||
|
||||
install (TARGETS ${PROJECT_NAME} ${LSR}
|
||||
FRAMEWORK DESTINATION ${FRAMEWORK_INSTALL_DIR}
|
||||
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
|
||||
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
|
||||
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
|
||||
PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR})
|
||||
|
||||
|
||||
|
||||
# Packaging (for unix-like distributions):
|
||||
|
||||
get_property (LIB1 TARGET ${PROJECT_NAME} PROPERTY LOCATION)
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set (LIB1 ${LIB1}.${SO_VERSION_MAJOR} ${LIB1}.${SO_VERSION})
|
||||
endif ()
|
||||
list (APPEND TARGET_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.h")
|
||||
if (WITH_LSR_BINDINGS)
|
||||
get_property (LIB2 TARGET ${LSR} PROPERTY LOCATION)
|
||||
if (BUILD_SHARED_LIBS)
|
||||
set (LIB2 ${LIB2}.${LSR_SO_VERSION_MAJOR} ${LIB2}.${LSR_SO_VERSION})
|
||||
endif ()
|
||||
list (APPEND TARGET_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${LSR}.h")
|
||||
endif ()
|
||||
set (TARGET_LIBS ${LIB1} ${LIB2})
|
||||
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/libsoxr.src.in ${CMAKE_CURRENT_BINARY_DIR}/libsoxr.src)
|
||||
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/libsoxr-dev.src.in ${CMAKE_CURRENT_BINARY_DIR}/libsoxr-dev.src)
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#if defined SOXR_LIB
|
||||
|
||||
#define lsx_bessel_I_0 _soxr_bessel_I_0
|
||||
#define lsx_cdft_f _soxr_cdft_f
|
||||
#define lsx_cdft _soxr_cdft
|
||||
#define lsx_clear_fft_cache_f _soxr_clear_fft_cache_f
|
||||
#define lsx_clear_fft_cache _soxr_clear_fft_cache
|
||||
#define lsx_ddct_f _soxr_ddct_f
|
||||
#define lsx_ddct _soxr_ddct
|
||||
#define lsx_ddst_f _soxr_ddst_f
|
||||
#define lsx_ddst _soxr_ddst
|
||||
#define lsx_design_lpf _soxr_design_lpf
|
||||
#define lsx_dfct_f _soxr_dfct_f
|
||||
#define lsx_dfct _soxr_dfct
|
||||
#define lsx_dfst_f _soxr_dfst_f
|
||||
#define lsx_dfst _soxr_dfst
|
||||
#define lsx_fir_to_phase _soxr_fir_to_phase
|
||||
#define lsx_init_fft_cache_f _soxr_init_fft_cache_f
|
||||
#define lsx_init_fft_cache _soxr_init_fft_cache
|
||||
#define lsx_kaiser_beta _soxr_kaiser_beta
|
||||
#define lsx_kaiser_params _soxr_kaiser_params
|
||||
#define lsx_make_lpf _soxr_make_lpf
|
||||
#define lsx_ordered_convolve_f _soxr_ordered_convolve_f
|
||||
#define lsx_ordered_convolve _soxr_ordered_convolve
|
||||
#define lsx_ordered_partial_convolve_f _soxr_ordered_partial_convolve_f
|
||||
#define lsx_ordered_partial_convolve _soxr_ordered_partial_convolve
|
||||
#define lsx_rdft_f _soxr_rdft_f
|
||||
#define lsx_rdft _soxr_rdft
|
||||
#define lsx_safe_cdft_f _soxr_safe_cdft_f
|
||||
#define lsx_safe_cdft _soxr_safe_cdft
|
||||
#define lsx_safe_rdft_f _soxr_safe_rdft_f
|
||||
#define lsx_safe_rdft _soxr_safe_rdft
|
||||
|
||||
#endif
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#if defined SOXR_LIB
|
||||
|
||||
#define lsx_bessel_I_0 _soxr_bessel_I_0
|
||||
#define lsx_cdft_f _soxr_cdft_f
|
||||
#define lsx_cdft _soxr_cdft
|
||||
#define lsx_clear_fft_cache_f _soxr_clear_fft_cache_f
|
||||
#define lsx_clear_fft_cache _soxr_clear_fft_cache
|
||||
#define lsx_ddct_f _soxr_ddct_f
|
||||
#define lsx_ddct _soxr_ddct
|
||||
#define lsx_ddst_f _soxr_ddst_f
|
||||
#define lsx_ddst _soxr_ddst
|
||||
#define lsx_design_lpf _soxr_design_lpf
|
||||
#define lsx_dfct_f _soxr_dfct_f
|
||||
#define lsx_dfct _soxr_dfct
|
||||
#define lsx_dfst_f _soxr_dfst_f
|
||||
#define lsx_dfst _soxr_dfst
|
||||
#define lsx_fir_to_phase _soxr_fir_to_phase
|
||||
#define lsx_init_fft_cache_f _soxr_init_fft_cache_f
|
||||
#define lsx_init_fft_cache _soxr_init_fft_cache
|
||||
#define lsx_kaiser_beta _soxr_kaiser_beta
|
||||
#define lsx_kaiser_params _soxr_kaiser_params
|
||||
#define lsx_make_lpf _soxr_make_lpf
|
||||
#define lsx_ordered_convolve_f _soxr_ordered_convolve_f
|
||||
#define lsx_ordered_convolve _soxr_ordered_convolve
|
||||
#define lsx_ordered_partial_convolve_f _soxr_ordered_partial_convolve_f
|
||||
#define lsx_ordered_partial_convolve _soxr_ordered_partial_convolve
|
||||
#define lsx_rdft_f _soxr_rdft_f
|
||||
#define lsx_rdft _soxr_rdft
|
||||
#define lsx_safe_cdft_f _soxr_safe_cdft_f
|
||||
#define lsx_safe_cdft _soxr_safe_cdft
|
||||
#define lsx_safe_rdft_f _soxr_safe_rdft_f
|
||||
#define lsx_safe_rdft _soxr_safe_rdft
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#include <math.h>
|
||||
#include <libavcodec/avfft.h>
|
||||
#include "filter.h"
|
||||
|
||||
static void * forward_setup(int len) {return av_rdft_init((int)(log(len)/log(2)+.5),DFT_R2C);}
|
||||
static void * backward_setup(int len) {return av_rdft_init((int)(log(len)/log(2)+.5),IDFT_C2R);}
|
||||
static void rdft(int length, void * setup, float * h) {av_rdft_calc(setup, h); (void)length;}
|
||||
static int multiplier(void) {return 2;}
|
||||
static void nothing(void) {}
|
||||
|
||||
typedef void (* fn_t)(void);
|
||||
fn_t _soxr_rdft32_cb[] = {
|
||||
(fn_t)forward_setup,
|
||||
(fn_t)backward_setup,
|
||||
(fn_t)av_rdft_end,
|
||||
(fn_t)rdft,
|
||||
(fn_t)rdft,
|
||||
(fn_t)rdft,
|
||||
(fn_t)rdft,
|
||||
(fn_t)_soxr_ordered_convolve_f,
|
||||
(fn_t)_soxr_ordered_partial_convolve_f,
|
||||
(fn_t)multiplier,
|
||||
(fn_t)nothing,
|
||||
};
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#include <math.h>
|
||||
#include <libavcodec/avfft.h>
|
||||
#include "filter.h"
|
||||
|
||||
static void * forward_setup(int len) {return av_rdft_init((int)(log(len)/log(2)+.5),DFT_R2C);}
|
||||
static void * backward_setup(int len) {return av_rdft_init((int)(log(len)/log(2)+.5),IDFT_C2R);}
|
||||
static void rdft(int length, void * setup, float * h) {av_rdft_calc(setup, h); (void)length;}
|
||||
static int multiplier(void) {return 2;}
|
||||
static void nothing(void) {}
|
||||
|
||||
typedef void (* fn_t)(void);
|
||||
fn_t _soxr_rdft32_cb[] = {
|
||||
(fn_t)forward_setup,
|
||||
(fn_t)backward_setup,
|
||||
(fn_t)av_rdft_end,
|
||||
(fn_t)rdft,
|
||||
(fn_t)rdft,
|
||||
(fn_t)rdft,
|
||||
(fn_t)rdft,
|
||||
(fn_t)_soxr_ordered_convolve_f,
|
||||
(fn_t)_soxr_ordered_partial_convolve_f,
|
||||
(fn_t)multiplier,
|
||||
(fn_t)nothing,
|
||||
};
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#include <math.h>
|
||||
#include <libavcodec/avfft.h>
|
||||
#include "simd.h"
|
||||
|
||||
static void * forward_setup(int len) {return av_rdft_init((int)(log(len)/log(2)+.5),DFT_R2C);}
|
||||
static void * backward_setup(int len) {return av_rdft_init((int)(log(len)/log(2)+.5),IDFT_C2R);}
|
||||
static void rdft(int length, void * setup, float * h) {av_rdft_calc(setup, h); (void)length;}
|
||||
static int multiplier(void) {return 2;}
|
||||
static void nothing(void) {}
|
||||
|
||||
typedef void (* fn_t)(void);
|
||||
fn_t _soxr_rdft32s_cb[] = {
|
||||
(fn_t)forward_setup,
|
||||
(fn_t)backward_setup,
|
||||
(fn_t)av_rdft_end,
|
||||
(fn_t)rdft,
|
||||
(fn_t)rdft,
|
||||
(fn_t)rdft,
|
||||
(fn_t)rdft,
|
||||
(fn_t)_soxr_ordered_convolve_simd,
|
||||
(fn_t)_soxr_ordered_partial_convolve_simd,
|
||||
(fn_t)multiplier,
|
||||
(fn_t)nothing,
|
||||
};
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#include <math.h>
|
||||
#include <libavcodec/avfft.h>
|
||||
#include "simd.h"
|
||||
|
||||
static void * forward_setup(int len) {return av_rdft_init((int)(log(len)/log(2)+.5),DFT_R2C);}
|
||||
static void * backward_setup(int len) {return av_rdft_init((int)(log(len)/log(2)+.5),IDFT_C2R);}
|
||||
static void rdft(int length, void * setup, float * h) {av_rdft_calc(setup, h); (void)length;}
|
||||
static int multiplier(void) {return 2;}
|
||||
static void nothing(void) {}
|
||||
|
||||
typedef void (* fn_t)(void);
|
||||
fn_t _soxr_rdft32s_cb[] = {
|
||||
(fn_t)forward_setup,
|
||||
(fn_t)backward_setup,
|
||||
(fn_t)av_rdft_end,
|
||||
(fn_t)rdft,
|
||||
(fn_t)rdft,
|
||||
(fn_t)rdft,
|
||||
(fn_t)rdft,
|
||||
(fn_t)_soxr_ordered_convolve_simd,
|
||||
(fn_t)_soxr_ordered_partial_convolve_simd,
|
||||
(fn_t)multiplier,
|
||||
(fn_t)nothing,
|
||||
};
|
||||
|
|
|
@ -1,73 +1,75 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Concurrent Control with "Readers" and "Writers", P.J. Courtois et al, 1971 */
|
||||
|
||||
#if !defined ccrw2_included
|
||||
#define ccrw2_included
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#if defined _OPENMP
|
||||
|
||||
#include <omp.h>
|
||||
|
||||
typedef struct {
|
||||
int readcount, writecount; /* initial value = 0 */
|
||||
omp_lock_t mutex_1, mutex_2, mutex_3, w, r; /* initial value = 1 */
|
||||
} ccrw2_t; /* Problem #2: `writers-preference' */
|
||||
|
||||
#define ccrw2_become_reader(p) do {\
|
||||
omp_set_lock(&p.mutex_3);\
|
||||
omp_set_lock(&p.r);\
|
||||
omp_set_lock(&p.mutex_1);\
|
||||
if (++p.readcount == 1) omp_set_lock(&p.w);\
|
||||
omp_unset_lock(&p.mutex_1);\
|
||||
omp_unset_lock(&p.r);\
|
||||
omp_unset_lock(&p.mutex_3);\
|
||||
} while (0)
|
||||
#define ccrw2_cease_reading(p) do {\
|
||||
omp_set_lock(&p.mutex_1);\
|
||||
if (!--p.readcount) omp_unset_lock(&p.w);\
|
||||
omp_unset_lock(&p.mutex_1);\
|
||||
} while (0)
|
||||
#define ccrw2_become_writer(p) do {\
|
||||
omp_set_lock(&p.mutex_2);\
|
||||
if (++p.writecount == 1) omp_set_lock(&p.r);\
|
||||
omp_unset_lock(&p.mutex_2);\
|
||||
omp_set_lock(&p.w);\
|
||||
} while (0)
|
||||
#define ccrw2_cease_writing(p) do {\
|
||||
omp_unset_lock(&p.w);\
|
||||
omp_set_lock(&p.mutex_2);\
|
||||
if (!--p.writecount) omp_unset_lock(&p.r);\
|
||||
omp_unset_lock(&p.mutex_2);\
|
||||
} while (0)
|
||||
#define ccrw2_init(p) do {\
|
||||
omp_init_lock(&p.mutex_1);\
|
||||
omp_init_lock(&p.mutex_2);\
|
||||
omp_init_lock(&p.mutex_3);\
|
||||
omp_init_lock(&p.w);\
|
||||
omp_init_lock(&p.r);\
|
||||
} while (0)
|
||||
#define ccrw2_clear(p) do {\
|
||||
omp_destroy_lock(&p.r);\
|
||||
omp_destroy_lock(&p.w);\
|
||||
omp_destroy_lock(&p.mutex_3);\
|
||||
omp_destroy_lock(&p.mutex_2);\
|
||||
omp_destroy_lock(&p.mutex_1);\
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
typedef int ccrw2_t;
|
||||
#define ccrw2_become_reader(x) (void)(x)
|
||||
#define ccrw2_cease_reading(x) (void)(x)
|
||||
#define ccrw2_become_writer(x) (void)(x)
|
||||
#define ccrw2_cease_writing(x) (void)(x)
|
||||
#define ccrw2_init(x) (void)(x)
|
||||
#define ccrw2_clear(x) (void)(x)
|
||||
|
||||
#endif /* _OPENMP */
|
||||
|
||||
#endif
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Concurrent Control with "Readers" and "Writers", P.J. Courtois et al, 1971 */
|
||||
|
||||
#if !defined ccrw2_included
|
||||
#define ccrw2_included
|
||||
|
||||
#if defined SOXR_LIB
|
||||
#include "internal.h"
|
||||
#endif
|
||||
|
||||
#if defined _OPENMP
|
||||
|
||||
#include <omp.h>
|
||||
|
||||
typedef struct {
|
||||
int readcount, writecount; /* initial value = 0 */
|
||||
omp_lock_t mutex_1, mutex_2, mutex_3, w, r; /* initial value = 1 */
|
||||
} ccrw2_t; /* Problem #2: `writers-preference' */
|
||||
|
||||
#define ccrw2_become_reader(p) do {\
|
||||
omp_set_lock(&p.mutex_3);\
|
||||
omp_set_lock(&p.r);\
|
||||
omp_set_lock(&p.mutex_1);\
|
||||
if (++p.readcount == 1) omp_set_lock(&p.w);\
|
||||
omp_unset_lock(&p.mutex_1);\
|
||||
omp_unset_lock(&p.r);\
|
||||
omp_unset_lock(&p.mutex_3);\
|
||||
} while (0)
|
||||
#define ccrw2_cease_reading(p) do {\
|
||||
omp_set_lock(&p.mutex_1);\
|
||||
if (!--p.readcount) omp_unset_lock(&p.w);\
|
||||
omp_unset_lock(&p.mutex_1);\
|
||||
} while (0)
|
||||
#define ccrw2_become_writer(p) do {\
|
||||
omp_set_lock(&p.mutex_2);\
|
||||
if (++p.writecount == 1) omp_set_lock(&p.r);\
|
||||
omp_unset_lock(&p.mutex_2);\
|
||||
omp_set_lock(&p.w);\
|
||||
} while (0)
|
||||
#define ccrw2_cease_writing(p) do {\
|
||||
omp_unset_lock(&p.w);\
|
||||
omp_set_lock(&p.mutex_2);\
|
||||
if (!--p.writecount) omp_unset_lock(&p.r);\
|
||||
omp_unset_lock(&p.mutex_2);\
|
||||
} while (0)
|
||||
#define ccrw2_init(p) do {\
|
||||
omp_init_lock(&p.mutex_1);\
|
||||
omp_init_lock(&p.mutex_2);\
|
||||
omp_init_lock(&p.mutex_3);\
|
||||
omp_init_lock(&p.w);\
|
||||
omp_init_lock(&p.r);\
|
||||
} while (0)
|
||||
#define ccrw2_clear(p) do {\
|
||||
omp_destroy_lock(&p.r);\
|
||||
omp_destroy_lock(&p.w);\
|
||||
omp_destroy_lock(&p.mutex_3);\
|
||||
omp_destroy_lock(&p.mutex_2);\
|
||||
omp_destroy_lock(&p.mutex_1);\
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
typedef int ccrw2_t;
|
||||
#define ccrw2_become_reader(x) (void)(x)
|
||||
#define ccrw2_cease_reading(x) (void)(x)
|
||||
#define ccrw2_become_writer(x) (void)(x)
|
||||
#define ccrw2_cease_writing(x) (void)(x)
|
||||
#define ccrw2_init(x) (void)(x)
|
||||
#define ccrw2_clear(x) (void)(x)
|
||||
|
||||
#endif /* _OPENMP */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,249 +1,252 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "data-io.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
|
||||
#define DEINTERLEAVE_FROM(T,flag) do { \
|
||||
unsigned i; \
|
||||
size_t j; \
|
||||
T const * src = *src0; \
|
||||
if (ch > 1) \
|
||||
for (j = 0; j < n; ++j) for (i = 0; i < ch; ++i) dest[i][j] = (DEINTERLEAVE_TO)*src++; \
|
||||
else if (flag) memcpy(dest[0], src, n * sizeof(T)), src = &src[n]; \
|
||||
else for (j = 0; j < n; dest[0][j++] = (DEINTERLEAVE_TO)*src++); \
|
||||
*src0 = src; \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
#if HAVE_DOUBLE_PRECISION
|
||||
void _soxr_deinterleave(double * * dest, /* Round/clipping not needed here */
|
||||
soxr_datatype_t data_type, void const * * src0, size_t n, unsigned ch)
|
||||
{
|
||||
#define DEINTERLEAVE_TO double
|
||||
switch (data_type & 3) {
|
||||
case SOXR_FLOAT32: DEINTERLEAVE_FROM(float, 0); break;
|
||||
case SOXR_FLOAT64: DEINTERLEAVE_FROM(double, 1); break;
|
||||
case SOXR_INT32: DEINTERLEAVE_FROM(int32_t, 0); break;
|
||||
case SOXR_INT16: DEINTERLEAVE_FROM(int16_t, 0); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if HAVE_SINGLE_PRECISION
|
||||
void _soxr_deinterleave_f(float * * dest, /* Round/clipping not needed here */
|
||||
soxr_datatype_t data_type, void const * * src0, size_t n, unsigned ch)
|
||||
{
|
||||
#undef DEINTERLEAVE_TO
|
||||
#define DEINTERLEAVE_TO float
|
||||
switch (data_type & 3) {
|
||||
case SOXR_FLOAT32: DEINTERLEAVE_FROM(float, 1); break;
|
||||
case SOXR_FLOAT64: DEINTERLEAVE_FROM(double, 0); break;
|
||||
case SOXR_INT32: DEINTERLEAVE_FROM(int32_t, 0); break;
|
||||
case SOXR_INT16: DEINTERLEAVE_FROM(int16_t, 0); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#include "rint.h"
|
||||
|
||||
#if HAVE_FENV_H
|
||||
#include <fenv.h>
|
||||
#elif defined _MSC_VER
|
||||
#define FE_INVALID 1
|
||||
#define FE_DIVBYZERO 4
|
||||
#define FE_OVERFLOW 8
|
||||
#define FE_UNDERFLOW 16
|
||||
#define FE_INEXACT 32
|
||||
#define FE_ALL_EXCEPT (FE_INEXACT|FE_DIVBYZERO|FE_UNDERFLOW|FE_OVERFLOW|FE_INVALID)
|
||||
static __inline int fetestexcept(int excepts)
|
||||
{
|
||||
short status_word;
|
||||
__asm fnstsw status_word
|
||||
return status_word & excepts & FE_ALL_EXCEPT;
|
||||
}
|
||||
|
||||
static __inline int feclearexcept(int excepts)
|
||||
{
|
||||
int16_t status[14];
|
||||
__asm fnstenv status
|
||||
status[2] &= ~(excepts & FE_ALL_EXCEPT);
|
||||
__asm fldenv status
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if defined FE_INVALID && defined FPU_RINT32 && defined __STDC_VERSION__
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#pragma STDC FENV_ACCESS ON
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_DOUBLE_PRECISION
|
||||
#define FLOATX double
|
||||
|
||||
#define LSX_RINT_CLIP_2 lsx_rint32_clip_2
|
||||
#define LSX_RINT_CLIP lsx_rint32_clip
|
||||
#define RINT_CLIP rint32_clip
|
||||
#define RINT rint32
|
||||
#if defined FPU_RINT32
|
||||
#define FPU_RINT
|
||||
#endif
|
||||
#define RINT_T int32_t
|
||||
#define RINT_MAX 2147483647L
|
||||
#include "rint-clip.h"
|
||||
|
||||
#define LSX_RINT_CLIP_2 lsx_rint16_clip_2
|
||||
#define LSX_RINT_CLIP lsx_rint16_clip
|
||||
#define RINT_CLIP rint16_clip
|
||||
#define RINT rint16
|
||||
#if defined FPU_RINT16
|
||||
#define FPU_RINT
|
||||
#endif
|
||||
#define RINT_T int16_t
|
||||
#define RINT_MAX 32767
|
||||
#include "rint-clip.h"
|
||||
|
||||
#define LSX_RINT_CLIP_2 lsx_rint16_clip_2_dither
|
||||
#define LSX_RINT_CLIP lsx_rint16_clip_dither
|
||||
#define RINT_CLIP rint16_clip_dither
|
||||
#define RINT rint16
|
||||
#if defined FPU_RINT16
|
||||
#define FPU_RINT
|
||||
#endif
|
||||
#define RINT_T int16_t
|
||||
#define RINT_MAX 32767
|
||||
#define DITHER
|
||||
#include "rint-clip.h"
|
||||
|
||||
#undef FLOATX
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if HAVE_SINGLE_PRECISION
|
||||
#define FLOATX float
|
||||
|
||||
#define LSX_RINT_CLIP_2 lsx_rint32_clip_2_f
|
||||
#define LSX_RINT_CLIP lsx_rint32_clip_f
|
||||
#define RINT_CLIP rint32_clip_f
|
||||
#define RINT rint32
|
||||
#if defined FPU_RINT32
|
||||
#define FPU_RINT
|
||||
#endif
|
||||
#define RINT_T int32_t
|
||||
#define RINT_MAX 2147483647L
|
||||
#include "rint-clip.h"
|
||||
|
||||
#define LSX_RINT_CLIP_2 lsx_rint16_clip_2_f
|
||||
#define LSX_RINT_CLIP lsx_rint16_clip_f
|
||||
#define RINT_CLIP rint16_clip_f
|
||||
#define RINT rint16
|
||||
#if defined FPU_RINT16
|
||||
#define FPU_RINT
|
||||
#endif
|
||||
#define RINT_T int16_t
|
||||
#define RINT_MAX 32767
|
||||
#include "rint-clip.h"
|
||||
|
||||
#define LSX_RINT_CLIP_2 lsx_rint16_clip_2_dither_f
|
||||
#define LSX_RINT_CLIP lsx_rint16_clip_dither_f
|
||||
#define RINT_CLIP rint16_clip_dither_f
|
||||
#define RINT rint16
|
||||
#if defined FPU_RINT16
|
||||
#define FPU_RINT
|
||||
#endif
|
||||
#define RINT_T int16_t
|
||||
#define RINT_MAX 32767
|
||||
#define DITHER
|
||||
#include "rint-clip.h"
|
||||
|
||||
#undef FLOATX
|
||||
#endif
|
||||
|
||||
#if defined FE_INVALID && defined FPU_RINT32 && defined __STDC_VERSION__
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#pragma STDC FENV_ACCESS OFF
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define INTERLEAVE_TO(T,flag) do { \
|
||||
unsigned i; \
|
||||
size_t j; \
|
||||
T * dest = *dest0; \
|
||||
if (ch > 1) \
|
||||
for (j = 0; j < n; ++j) for (i = 0; i < ch; ++i) *dest++ = (T)src[i][j]; \
|
||||
else if (flag) memcpy(dest, src[0], n * sizeof(T)), dest = &dest[n]; \
|
||||
else for (j = 0; j < n; *dest++ = (T)src[0][j++]); \
|
||||
*dest0 = dest; \
|
||||
return 0; \
|
||||
} while (0)
|
||||
|
||||
#if HAVE_DOUBLE_PRECISION
|
||||
size_t /* clips */ _soxr_interleave(soxr_datatype_t data_type, void * * dest0,
|
||||
double const * const * src, size_t n, unsigned ch, unsigned long * seed)
|
||||
{
|
||||
switch (data_type & 3) {
|
||||
case SOXR_FLOAT32: INTERLEAVE_TO(float, 0);
|
||||
case SOXR_FLOAT64: INTERLEAVE_TO(double, 1);
|
||||
|
||||
case SOXR_INT32: if (ch == 1)
|
||||
return lsx_rint32_clip(dest0, src[0], n);
|
||||
return lsx_rint32_clip_2(dest0, src, ch, n);
|
||||
|
||||
case SOXR_INT16: if (seed) {
|
||||
if (ch == 1)
|
||||
return lsx_rint16_clip_dither(dest0, src[0], n, seed);
|
||||
return lsx_rint16_clip_2_dither(dest0, src, ch, n, seed);
|
||||
}
|
||||
if (ch == 1)
|
||||
return lsx_rint16_clip(dest0, src[0], n);
|
||||
return lsx_rint16_clip_2(dest0, src, ch, n);
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_SINGLE_PRECISION
|
||||
size_t /* clips */ _soxr_interleave_f(soxr_datatype_t data_type, void * * dest0,
|
||||
float const * const * src, size_t n, unsigned ch, unsigned long * seed)
|
||||
{
|
||||
switch (data_type & 3) {
|
||||
case SOXR_FLOAT32: INTERLEAVE_TO(float, 1);
|
||||
case SOXR_FLOAT64: INTERLEAVE_TO(double, 0);
|
||||
|
||||
case SOXR_INT32: if (ch == 1)
|
||||
return lsx_rint32_clip_f(dest0, src[0], n);
|
||||
return lsx_rint32_clip_2_f(dest0, src, ch, n);
|
||||
|
||||
case SOXR_INT16: if (seed) {
|
||||
if (ch == 1)
|
||||
return lsx_rint16_clip_dither_f(dest0, src[0], n, seed);
|
||||
return lsx_rint16_clip_2_dither_f(dest0, src, ch, n, seed);
|
||||
}
|
||||
if (ch == 1)
|
||||
return lsx_rint16_clip_f(dest0, src[0], n);
|
||||
return lsx_rint16_clip_2_f(dest0, src, ch, n);
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "data-io.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
|
||||
#define DEINTERLEAVE_FROM(T,flag) do { \
|
||||
unsigned i; \
|
||||
size_t j; \
|
||||
T const * src = *src0; \
|
||||
if (ch > 1) \
|
||||
for (j = 0; j < n; ++j) for (i = 0; i < ch; ++i) dest[i][j] = (DEINTERLEAVE_TO)*src++; \
|
||||
else if (flag) memcpy(dest[0], src, n * sizeof(T)), src = &src[n]; \
|
||||
else for (j = 0; j < n; dest[0][j++] = (DEINTERLEAVE_TO)*src++); \
|
||||
*src0 = src; \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
#if HAVE_DOUBLE_PRECISION
|
||||
void _soxr_deinterleave(double * * dest, /* Round/clipping not needed here */
|
||||
soxr_datatype_t data_type, void const * * src0, size_t n, unsigned ch)
|
||||
{
|
||||
#define DEINTERLEAVE_TO double
|
||||
switch (data_type & 3) {
|
||||
case SOXR_FLOAT32: DEINTERLEAVE_FROM(float, 0); break;
|
||||
case SOXR_FLOAT64: DEINTERLEAVE_FROM(double, 1); break;
|
||||
case SOXR_INT32: DEINTERLEAVE_FROM(int32_t, 0); break;
|
||||
case SOXR_INT16: DEINTERLEAVE_FROM(int16_t, 0); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if HAVE_SINGLE_PRECISION
|
||||
void _soxr_deinterleave_f(float * * dest, /* Round/clipping not needed here */
|
||||
soxr_datatype_t data_type, void const * * src0, size_t n, unsigned ch)
|
||||
{
|
||||
#undef DEINTERLEAVE_TO
|
||||
#define DEINTERLEAVE_TO float
|
||||
switch (data_type & 3) {
|
||||
case SOXR_FLOAT32: DEINTERLEAVE_FROM(float, 1); break;
|
||||
case SOXR_FLOAT64: DEINTERLEAVE_FROM(double, 0); break;
|
||||
case SOXR_INT32: DEINTERLEAVE_FROM(int32_t, 0); break;
|
||||
case SOXR_INT16: DEINTERLEAVE_FROM(int16_t, 0); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#include "rint.h"
|
||||
|
||||
#if HAVE_FENV_H
|
||||
#include <fenv.h>
|
||||
#define fe_test_invalid() fetestexcept(FE_INVALID)
|
||||
#define fe_clear_invalid() feclearexcept(FE_INVALID)
|
||||
#elif defined _MSC_VER
|
||||
#define FE_INVALID 1
|
||||
#if defined _WIN64
|
||||
#include <float.h>
|
||||
#define fe_test_invalid() (_statusfp() & _SW_INVALID)
|
||||
#define fe_clear_invalid _clearfp /* FIXME clears all */
|
||||
#else
|
||||
static __inline int fe_test_invalid()
|
||||
{
|
||||
short status_word;
|
||||
__asm fnstsw status_word
|
||||
return status_word & FE_INVALID;
|
||||
}
|
||||
|
||||
static __inline int fe_clear_invalid()
|
||||
{
|
||||
int16_t status[14];
|
||||
__asm fnstenv status
|
||||
status[2] &= ~FE_INVALID;
|
||||
__asm fldenv status
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if defined FE_INVALID && defined FPU_RINT32 && defined __STDC_VERSION__
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#pragma STDC FENV_ACCESS ON
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_DOUBLE_PRECISION
|
||||
#define FLOATX double
|
||||
|
||||
#define LSX_RINT_CLIP_2 lsx_rint32_clip_2
|
||||
#define LSX_RINT_CLIP lsx_rint32_clip
|
||||
#define RINT_CLIP rint32_clip
|
||||
#define RINT rint32
|
||||
#if defined FPU_RINT32
|
||||
#define FPU_RINT
|
||||
#endif
|
||||
#define RINT_T int32_t
|
||||
#define RINT_MAX 2147483647L
|
||||
#include "rint-clip.h"
|
||||
|
||||
#define LSX_RINT_CLIP_2 lsx_rint16_clip_2
|
||||
#define LSX_RINT_CLIP lsx_rint16_clip
|
||||
#define RINT_CLIP rint16_clip
|
||||
#define RINT rint16
|
||||
#if defined FPU_RINT16
|
||||
#define FPU_RINT
|
||||
#endif
|
||||
#define RINT_T int16_t
|
||||
#define RINT_MAX 32767
|
||||
#include "rint-clip.h"
|
||||
|
||||
#define LSX_RINT_CLIP_2 lsx_rint16_clip_2_dither
|
||||
#define LSX_RINT_CLIP lsx_rint16_clip_dither
|
||||
#define RINT_CLIP rint16_clip_dither
|
||||
#define RINT rint16
|
||||
#if defined FPU_RINT16
|
||||
#define FPU_RINT
|
||||
#endif
|
||||
#define RINT_T int16_t
|
||||
#define RINT_MAX 32767
|
||||
#define DITHER
|
||||
#include "rint-clip.h"
|
||||
|
||||
#undef FLOATX
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if HAVE_SINGLE_PRECISION
|
||||
#define FLOATX float
|
||||
|
||||
#define LSX_RINT_CLIP_2 lsx_rint32_clip_2_f
|
||||
#define LSX_RINT_CLIP lsx_rint32_clip_f
|
||||
#define RINT_CLIP rint32_clip_f
|
||||
#define RINT rint32
|
||||
#if defined FPU_RINT32
|
||||
#define FPU_RINT
|
||||
#endif
|
||||
#define RINT_T int32_t
|
||||
#define RINT_MAX 2147483647L
|
||||
#include "rint-clip.h"
|
||||
|
||||
#define LSX_RINT_CLIP_2 lsx_rint16_clip_2_f
|
||||
#define LSX_RINT_CLIP lsx_rint16_clip_f
|
||||
#define RINT_CLIP rint16_clip_f
|
||||
#define RINT rint16
|
||||
#if defined FPU_RINT16
|
||||
#define FPU_RINT
|
||||
#endif
|
||||
#define RINT_T int16_t
|
||||
#define RINT_MAX 32767
|
||||
#include "rint-clip.h"
|
||||
|
||||
#define LSX_RINT_CLIP_2 lsx_rint16_clip_2_dither_f
|
||||
#define LSX_RINT_CLIP lsx_rint16_clip_dither_f
|
||||
#define RINT_CLIP rint16_clip_dither_f
|
||||
#define RINT rint16
|
||||
#if defined FPU_RINT16
|
||||
#define FPU_RINT
|
||||
#endif
|
||||
#define RINT_T int16_t
|
||||
#define RINT_MAX 32767
|
||||
#define DITHER
|
||||
#include "rint-clip.h"
|
||||
|
||||
#undef FLOATX
|
||||
#endif
|
||||
|
||||
#if defined FE_INVALID && defined FPU_RINT32 && defined __STDC_VERSION__
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#pragma STDC FENV_ACCESS OFF
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define INTERLEAVE_TO(T,flag) do { \
|
||||
unsigned i; \
|
||||
size_t j; \
|
||||
T * dest = *dest0; \
|
||||
if (ch > 1) \
|
||||
for (j = 0; j < n; ++j) for (i = 0; i < ch; ++i) *dest++ = (T)src[i][j]; \
|
||||
else if (flag) memcpy(dest, src[0], n * sizeof(T)), dest = &dest[n]; \
|
||||
else for (j = 0; j < n; *dest++ = (T)src[0][j++]); \
|
||||
*dest0 = dest; \
|
||||
return 0; \
|
||||
} while (0)
|
||||
|
||||
#if HAVE_DOUBLE_PRECISION
|
||||
size_t /* clips */ _soxr_interleave(soxr_datatype_t data_type, void * * dest0,
|
||||
double const * const * src, size_t n, unsigned ch, unsigned long * seed)
|
||||
{
|
||||
switch (data_type & 3) {
|
||||
case SOXR_FLOAT32: INTERLEAVE_TO(float, 0);
|
||||
case SOXR_FLOAT64: INTERLEAVE_TO(double, 1);
|
||||
|
||||
case SOXR_INT32: if (ch == 1)
|
||||
return lsx_rint32_clip(dest0, src[0], n);
|
||||
return lsx_rint32_clip_2(dest0, src, ch, n);
|
||||
|
||||
case SOXR_INT16: if (seed) {
|
||||
if (ch == 1)
|
||||
return lsx_rint16_clip_dither(dest0, src[0], n, seed);
|
||||
return lsx_rint16_clip_2_dither(dest0, src, ch, n, seed);
|
||||
}
|
||||
if (ch == 1)
|
||||
return lsx_rint16_clip(dest0, src[0], n);
|
||||
return lsx_rint16_clip_2(dest0, src, ch, n);
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_SINGLE_PRECISION
|
||||
size_t /* clips */ _soxr_interleave_f(soxr_datatype_t data_type, void * * dest0,
|
||||
float const * const * src, size_t n, unsigned ch, unsigned long * seed)
|
||||
{
|
||||
switch (data_type & 3) {
|
||||
case SOXR_FLOAT32: INTERLEAVE_TO(float, 1);
|
||||
case SOXR_FLOAT64: INTERLEAVE_TO(double, 0);
|
||||
|
||||
case SOXR_INT32: if (ch == 1)
|
||||
return lsx_rint32_clip_f(dest0, src[0], n);
|
||||
return lsx_rint32_clip_2_f(dest0, src, ch, n);
|
||||
|
||||
case SOXR_INT16: if (seed) {
|
||||
if (ch == 1)
|
||||
return lsx_rint16_clip_dither_f(dest0, src[0], n, seed);
|
||||
return lsx_rint16_clip_2_dither_f(dest0, src, ch, n, seed);
|
||||
}
|
||||
if (ch == 1)
|
||||
return lsx_rint16_clip_f(dest0, src[0], n);
|
||||
return lsx_rint16_clip_2_f(dest0, src, ch, n);
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,39 +1,39 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#if !defined soxr_data_io_included
|
||||
#define soxr_data_io_included
|
||||
|
||||
#include "soxr.h"
|
||||
|
||||
void _soxr_deinterleave(
|
||||
double * * dest,
|
||||
soxr_datatype_t data_type,
|
||||
void const * * src0,
|
||||
size_t n,
|
||||
unsigned ch);
|
||||
|
||||
void _soxr_deinterleave_f(
|
||||
float * * dest,
|
||||
soxr_datatype_t data_type,
|
||||
void const * * src0,
|
||||
size_t n,
|
||||
unsigned ch);
|
||||
|
||||
size_t /* clips */ _soxr_interleave(
|
||||
soxr_datatype_t data_type,
|
||||
void * * dest,
|
||||
double const * const * src,
|
||||
size_t n,
|
||||
unsigned ch,
|
||||
unsigned long * seed);
|
||||
|
||||
size_t /* clips */ _soxr_interleave_f(
|
||||
soxr_datatype_t data_type,
|
||||
void * * dest,
|
||||
float const * const * src,
|
||||
size_t n,
|
||||
unsigned ch,
|
||||
unsigned long * seed);
|
||||
|
||||
#endif
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#if !defined soxr_data_io_included
|
||||
#define soxr_data_io_included
|
||||
|
||||
#include "soxr.h"
|
||||
|
||||
void _soxr_deinterleave(
|
||||
double * * dest,
|
||||
soxr_datatype_t data_type,
|
||||
void const * * src0,
|
||||
size_t n,
|
||||
unsigned ch);
|
||||
|
||||
void _soxr_deinterleave_f(
|
||||
float * * dest,
|
||||
soxr_datatype_t data_type,
|
||||
void const * * src0,
|
||||
size_t n,
|
||||
unsigned ch);
|
||||
|
||||
size_t /* clips */ _soxr_interleave(
|
||||
soxr_datatype_t data_type,
|
||||
void * * dest,
|
||||
double const * const * src,
|
||||
size_t n,
|
||||
unsigned ch,
|
||||
unsigned long * seed);
|
||||
|
||||
size_t /* clips */ _soxr_interleave_f(
|
||||
soxr_datatype_t data_type,
|
||||
void * * dest,
|
||||
float const * const * src,
|
||||
size_t n,
|
||||
unsigned ch,
|
||||
unsigned long * seed);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,149 +1,149 @@
|
|||
/* Copyright(C) 1996 Takuya OOURA
|
||||
|
||||
You may use, copy, modify this code for any purpose and
|
||||
without fee.
|
||||
|
||||
Package home: http://www.kurims.kyoto-u.ac.jp/~ooura/bessel.html
|
||||
*/
|
||||
|
||||
#include "filter.h"
|
||||
#define dbesi0 lsx_bessel_I_0
|
||||
|
||||
/* Bessel I_0(x) function in double precision */
|
||||
|
||||
#include <math.h>
|
||||
|
||||
double dbesi0(double x)
|
||||
{
|
||||
int k;
|
||||
double w, t, y;
|
||||
static double a[65] = {
|
||||
8.5246820682016865877e-11, 2.5966600546497407288e-9,
|
||||
7.9689994568640180274e-8, 1.9906710409667748239e-6,
|
||||
4.0312469446528002532e-5, 6.4499871606224265421e-4,
|
||||
0.0079012345761930579108, 0.071111111109207045212,
|
||||
0.444444444444724909, 1.7777777777777532045,
|
||||
4.0000000000000011182, 3.99999999999999998,
|
||||
1.0000000000000000001,
|
||||
1.1520919130377195927e-10, 2.2287613013610985225e-9,
|
||||
8.1903951930694585113e-8, 1.9821560631611544984e-6,
|
||||
4.0335461940910133184e-5, 6.4495330974432203401e-4,
|
||||
0.0079013012611467520626, 0.071111038160875566622,
|
||||
0.44444450319062699316, 1.7777777439146450067,
|
||||
4.0000000132337935071, 3.9999999968569015366,
|
||||
1.0000000003426703174,
|
||||
1.5476870780515238488e-10, 1.2685004214732975355e-9,
|
||||
9.2776861851114223267e-8, 1.9063070109379044378e-6,
|
||||
4.0698004389917945832e-5, 6.4370447244298070713e-4,
|
||||
0.0079044749458444976958, 0.071105052411749363882,
|
||||
0.44445280640924755082, 1.7777694934432109713,
|
||||
4.0000055808824003386, 3.9999977081165740932,
|
||||
1.0000004333949319118,
|
||||
2.0675200625006793075e-10, -6.1689554705125681442e-10,
|
||||
1.2436765915401571654e-7, 1.5830429403520613423e-6,
|
||||
4.2947227560776583326e-5, 6.3249861665073441312e-4,
|
||||
0.0079454472840953930811, 0.070994327785661860575,
|
||||
0.44467219586283000332, 1.7774588182255374745,
|
||||
4.0003038986252717972, 3.9998233869142057195,
|
||||
1.0000472932961288324,
|
||||
2.7475684794982708655e-10, -3.8991472076521332023e-9,
|
||||
1.9730170483976049388e-7, 5.9651531561967674521e-7,
|
||||
5.1992971474748995357e-5, 5.7327338675433770752e-4,
|
||||
0.0082293143836530412024, 0.069990934858728039037,
|
||||
0.44726764292723985087, 1.7726685170014087784,
|
||||
4.0062907863712704432, 3.9952750700487845355,
|
||||
1.0016354346654179322
|
||||
};
|
||||
static double b[70] = {
|
||||
6.7852367144945531383e-8, 4.6266061382821826854e-7,
|
||||
6.9703135812354071774e-6, 7.6637663462953234134e-5,
|
||||
7.9113515222612691636e-4, 0.0073401204731103808981,
|
||||
0.060677114958668837046, 0.43994941411651569622,
|
||||
2.7420017097661750609, 14.289661921740860534,
|
||||
59.820609640320710779, 188.78998681199150629,
|
||||
399.8731367825601118, 427.56411572180478514,
|
||||
1.8042097874891098754e-7, 1.2277164312044637357e-6,
|
||||
1.8484393221474274861e-5, 2.0293995900091309208e-4,
|
||||
0.0020918539850246207459, 0.019375315654033949297,
|
||||
0.15985869016767185908, 1.1565260527420641724,
|
||||
7.1896341224206072113, 37.354773811947484532,
|
||||
155.80993164266268457, 489.5211371158540918,
|
||||
1030.9147225169564806, 1093.5883545113746958,
|
||||
4.8017305613187493564e-7, 3.261317843912380074e-6,
|
||||
4.9073137508166159639e-5, 5.3806506676487583755e-4,
|
||||
0.0055387918291051866561, 0.051223717488786549025,
|
||||
0.42190298621367914765, 3.0463625987357355872,
|
||||
18.895299447327733204, 97.915189029455461554,
|
||||
407.13940115493494659, 1274.3088990480582632,
|
||||
2670.9883037012547506, 2815.7166284662544712,
|
||||
1.2789926338424623394e-6, 8.6718263067604918916e-6,
|
||||
1.3041508821299929489e-4, 0.001428224737372747892,
|
||||
0.014684070635768789378, 0.13561403190404185755,
|
||||
1.1152592585977393953, 8.0387088559465389038,
|
||||
49.761318895895479206, 257.2684232313529138,
|
||||
1066.8543146269566231, 3328.3874581009636362,
|
||||
6948.8586598121634874, 7288.4893398212481055,
|
||||
3.409350368197032893e-6, 2.3079025203103376076e-5,
|
||||
3.4691373283901830239e-4, 0.003794994977222908545,
|
||||
0.038974209677945602145, 0.3594948380414878371,
|
||||
2.9522878893539528226, 21.246564609514287056,
|
||||
131.28727387146173141, 677.38107093296675421,
|
||||
2802.3724744545046518, 8718.5731420798254081,
|
||||
18141.348781638832286, 18948.925349296308859
|
||||
};
|
||||
static double c[45] = {
|
||||
2.5568678676452702768e-15, 3.0393953792305924324e-14,
|
||||
6.3343751991094840009e-13, 1.5041298011833009649e-11,
|
||||
4.4569436918556541414e-10, 1.746393051427167951e-8,
|
||||
1.0059224011079852317e-6, 1.0729838945088577089e-4,
|
||||
0.05150322693642527738,
|
||||
5.2527963991711562216e-15, 7.202118481421005641e-15,
|
||||
7.2561421229904797156e-13, 1.482312146673104251e-11,
|
||||
4.4602670450376245434e-10, 1.7463600061788679671e-8,
|
||||
1.005922609132234756e-6, 1.0729838937545111487e-4,
|
||||
0.051503226936437300716,
|
||||
1.3365917359358069908e-14, -1.2932643065888544835e-13,
|
||||
1.7450199447905602915e-12, 1.0419051209056979788e-11,
|
||||
4.58047881980598326e-10, 1.7442405450073548966e-8,
|
||||
1.0059461453281292278e-6, 1.0729837434500161228e-4,
|
||||
0.051503226940658446941,
|
||||
5.3771611477352308649e-14, -1.1396193006413731702e-12,
|
||||
1.2858641335221653409e-11, -5.9802086004570057703e-11,
|
||||
7.3666894305929510222e-10, 1.6731837150730356448e-8,
|
||||
1.0070831435812128922e-6, 1.0729733111203704813e-4,
|
||||
0.051503227360726294675,
|
||||
3.7819492084858931093e-14, -4.8600496888588034879e-13,
|
||||
1.6898350504817224909e-12, 4.5884624327524255865e-11,
|
||||
1.2521615963377513729e-10, 1.8959658437754727957e-8,
|
||||
1.0020716710561353622e-6, 1.073037119856927559e-4,
|
||||
0.05150322383300230775
|
||||
};
|
||||
|
||||
w = fabs(x);
|
||||
if (w < 8.5) {
|
||||
t = w * w * 0.0625;
|
||||
k = 13 * ((int) t);
|
||||
y = (((((((((((a[k] * t + a[k + 1]) * t +
|
||||
a[k + 2]) * t + a[k + 3]) * t + a[k + 4]) * t +
|
||||
a[k + 5]) * t + a[k + 6]) * t + a[k + 7]) * t +
|
||||
a[k + 8]) * t + a[k + 9]) * t + a[k + 10]) * t +
|
||||
a[k + 11]) * t + a[k + 12];
|
||||
} else if (w < 12.5) {
|
||||
k = (int) w;
|
||||
t = w - k;
|
||||
k = 14 * (k - 8);
|
||||
y = ((((((((((((b[k] * t + b[k + 1]) * t +
|
||||
b[k + 2]) * t + b[k + 3]) * t + b[k + 4]) * t +
|
||||
b[k + 5]) * t + b[k + 6]) * t + b[k + 7]) * t +
|
||||
b[k + 8]) * t + b[k + 9]) * t + b[k + 10]) * t +
|
||||
b[k + 11]) * t + b[k + 12]) * t + b[k + 13];
|
||||
} else {
|
||||
t = 60 / w;
|
||||
k = 9 * ((int) t);
|
||||
y = ((((((((c[k] * t + c[k + 1]) * t +
|
||||
c[k + 2]) * t + c[k + 3]) * t + c[k + 4]) * t +
|
||||
c[k + 5]) * t + c[k + 6]) * t + c[k + 7]) * t +
|
||||
c[k + 8]) * sqrt(t) * exp(w);
|
||||
}
|
||||
return y;
|
||||
}
|
||||
/* Copyright(C) 1996 Takuya OOURA
|
||||
|
||||
You may use, copy, modify this code for any purpose and
|
||||
without fee.
|
||||
|
||||
Package home: http://www.kurims.kyoto-u.ac.jp/~ooura/bessel.html
|
||||
*/
|
||||
|
||||
#include "filter.h"
|
||||
#define dbesi0 lsx_bessel_I_0
|
||||
|
||||
/* Bessel I_0(x) function in double precision */
|
||||
|
||||
#include <math.h>
|
||||
|
||||
double dbesi0(double x)
|
||||
{
|
||||
int k;
|
||||
double w, t, y;
|
||||
static double a[65] = {
|
||||
8.5246820682016865877e-11, 2.5966600546497407288e-9,
|
||||
7.9689994568640180274e-8, 1.9906710409667748239e-6,
|
||||
4.0312469446528002532e-5, 6.4499871606224265421e-4,
|
||||
0.0079012345761930579108, 0.071111111109207045212,
|
||||
0.444444444444724909, 1.7777777777777532045,
|
||||
4.0000000000000011182, 3.99999999999999998,
|
||||
1.0000000000000000001,
|
||||
1.1520919130377195927e-10, 2.2287613013610985225e-9,
|
||||
8.1903951930694585113e-8, 1.9821560631611544984e-6,
|
||||
4.0335461940910133184e-5, 6.4495330974432203401e-4,
|
||||
0.0079013012611467520626, 0.071111038160875566622,
|
||||
0.44444450319062699316, 1.7777777439146450067,
|
||||
4.0000000132337935071, 3.9999999968569015366,
|
||||
1.0000000003426703174,
|
||||
1.5476870780515238488e-10, 1.2685004214732975355e-9,
|
||||
9.2776861851114223267e-8, 1.9063070109379044378e-6,
|
||||
4.0698004389917945832e-5, 6.4370447244298070713e-4,
|
||||
0.0079044749458444976958, 0.071105052411749363882,
|
||||
0.44445280640924755082, 1.7777694934432109713,
|
||||
4.0000055808824003386, 3.9999977081165740932,
|
||||
1.0000004333949319118,
|
||||
2.0675200625006793075e-10, -6.1689554705125681442e-10,
|
||||
1.2436765915401571654e-7, 1.5830429403520613423e-6,
|
||||
4.2947227560776583326e-5, 6.3249861665073441312e-4,
|
||||
0.0079454472840953930811, 0.070994327785661860575,
|
||||
0.44467219586283000332, 1.7774588182255374745,
|
||||
4.0003038986252717972, 3.9998233869142057195,
|
||||
1.0000472932961288324,
|
||||
2.7475684794982708655e-10, -3.8991472076521332023e-9,
|
||||
1.9730170483976049388e-7, 5.9651531561967674521e-7,
|
||||
5.1992971474748995357e-5, 5.7327338675433770752e-4,
|
||||
0.0082293143836530412024, 0.069990934858728039037,
|
||||
0.44726764292723985087, 1.7726685170014087784,
|
||||
4.0062907863712704432, 3.9952750700487845355,
|
||||
1.0016354346654179322
|
||||
};
|
||||
static double b[70] = {
|
||||
6.7852367144945531383e-8, 4.6266061382821826854e-7,
|
||||
6.9703135812354071774e-6, 7.6637663462953234134e-5,
|
||||
7.9113515222612691636e-4, 0.0073401204731103808981,
|
||||
0.060677114958668837046, 0.43994941411651569622,
|
||||
2.7420017097661750609, 14.289661921740860534,
|
||||
59.820609640320710779, 188.78998681199150629,
|
||||
399.8731367825601118, 427.56411572180478514,
|
||||
1.8042097874891098754e-7, 1.2277164312044637357e-6,
|
||||
1.8484393221474274861e-5, 2.0293995900091309208e-4,
|
||||
0.0020918539850246207459, 0.019375315654033949297,
|
||||
0.15985869016767185908, 1.1565260527420641724,
|
||||
7.1896341224206072113, 37.354773811947484532,
|
||||
155.80993164266268457, 489.5211371158540918,
|
||||
1030.9147225169564806, 1093.5883545113746958,
|
||||
4.8017305613187493564e-7, 3.261317843912380074e-6,
|
||||
4.9073137508166159639e-5, 5.3806506676487583755e-4,
|
||||
0.0055387918291051866561, 0.051223717488786549025,
|
||||
0.42190298621367914765, 3.0463625987357355872,
|
||||
18.895299447327733204, 97.915189029455461554,
|
||||
407.13940115493494659, 1274.3088990480582632,
|
||||
2670.9883037012547506, 2815.7166284662544712,
|
||||
1.2789926338424623394e-6, 8.6718263067604918916e-6,
|
||||
1.3041508821299929489e-4, 0.001428224737372747892,
|
||||
0.014684070635768789378, 0.13561403190404185755,
|
||||
1.1152592585977393953, 8.0387088559465389038,
|
||||
49.761318895895479206, 257.2684232313529138,
|
||||
1066.8543146269566231, 3328.3874581009636362,
|
||||
6948.8586598121634874, 7288.4893398212481055,
|
||||
3.409350368197032893e-6, 2.3079025203103376076e-5,
|
||||
3.4691373283901830239e-4, 0.003794994977222908545,
|
||||
0.038974209677945602145, 0.3594948380414878371,
|
||||
2.9522878893539528226, 21.246564609514287056,
|
||||
131.28727387146173141, 677.38107093296675421,
|
||||
2802.3724744545046518, 8718.5731420798254081,
|
||||
18141.348781638832286, 18948.925349296308859
|
||||
};
|
||||
static double c[45] = {
|
||||
2.5568678676452702768e-15, 3.0393953792305924324e-14,
|
||||
6.3343751991094840009e-13, 1.5041298011833009649e-11,
|
||||
4.4569436918556541414e-10, 1.746393051427167951e-8,
|
||||
1.0059224011079852317e-6, 1.0729838945088577089e-4,
|
||||
0.05150322693642527738,
|
||||
5.2527963991711562216e-15, 7.202118481421005641e-15,
|
||||
7.2561421229904797156e-13, 1.482312146673104251e-11,
|
||||
4.4602670450376245434e-10, 1.7463600061788679671e-8,
|
||||
1.005922609132234756e-6, 1.0729838937545111487e-4,
|
||||
0.051503226936437300716,
|
||||
1.3365917359358069908e-14, -1.2932643065888544835e-13,
|
||||
1.7450199447905602915e-12, 1.0419051209056979788e-11,
|
||||
4.58047881980598326e-10, 1.7442405450073548966e-8,
|
||||
1.0059461453281292278e-6, 1.0729837434500161228e-4,
|
||||
0.051503226940658446941,
|
||||
5.3771611477352308649e-14, -1.1396193006413731702e-12,
|
||||
1.2858641335221653409e-11, -5.9802086004570057703e-11,
|
||||
7.3666894305929510222e-10, 1.6731837150730356448e-8,
|
||||
1.0070831435812128922e-6, 1.0729733111203704813e-4,
|
||||
0.051503227360726294675,
|
||||
3.7819492084858931093e-14, -4.8600496888588034879e-13,
|
||||
1.6898350504817224909e-12, 4.5884624327524255865e-11,
|
||||
1.2521615963377513729e-10, 1.8959658437754727957e-8,
|
||||
1.0020716710561353622e-6, 1.073037119856927559e-4,
|
||||
0.05150322383300230775
|
||||
};
|
||||
|
||||
w = fabs(x);
|
||||
if (w < 8.5) {
|
||||
t = w * w * 0.0625;
|
||||
k = 13 * ((int) t);
|
||||
y = (((((((((((a[k] * t + a[k + 1]) * t +
|
||||
a[k + 2]) * t + a[k + 3]) * t + a[k + 4]) * t +
|
||||
a[k + 5]) * t + a[k + 6]) * t + a[k + 7]) * t +
|
||||
a[k + 8]) * t + a[k + 9]) * t + a[k + 10]) * t +
|
||||
a[k + 11]) * t + a[k + 12];
|
||||
} else if (w < 12.5) {
|
||||
k = (int) w;
|
||||
t = w - k;
|
||||
k = 14 * (k - 8);
|
||||
y = ((((((((((((b[k] * t + b[k + 1]) * t +
|
||||
b[k + 2]) * t + b[k + 3]) * t + b[k + 4]) * t +
|
||||
b[k + 5]) * t + b[k + 6]) * t + b[k + 7]) * t +
|
||||
b[k + 8]) * t + b[k + 9]) * t + b[k + 10]) * t +
|
||||
b[k + 11]) * t + b[k + 12]) * t + b[k + 13];
|
||||
} else {
|
||||
t = 60 / w;
|
||||
k = 9 * ((int) t);
|
||||
y = ((((((((c[k] * t + c[k + 1]) * t +
|
||||
c[k + 2]) * t + c[k + 3]) * t + c[k + 4]) * t +
|
||||
c[k + 5]) * t + c[k + 6]) * t + c[k + 7]) * t +
|
||||
c[k + 8]) * sqrt(t) * exp(w);
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,23 +1,23 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
void lsx_cdft(int, int, double *, int *, double *);
|
||||
void lsx_rdft(int, int, double *, int *, double *);
|
||||
void lsx_ddct(int, int, double *, int *, double *);
|
||||
void lsx_ddst(int, int, double *, int *, double *);
|
||||
void lsx_dfct(int, double *, double *, int *, double *);
|
||||
void lsx_dfst(int, double *, double *, int *, double *);
|
||||
|
||||
void lsx_cdft_f(int, int, float *, int *, float *);
|
||||
void lsx_rdft_f(int, int, float *, int *, float *);
|
||||
void lsx_ddct_f(int, int, float *, int *, float *);
|
||||
void lsx_ddst_f(int, int, float *, int *, float *);
|
||||
void lsx_dfct_f(int, float *, float *, int *, float *);
|
||||
void lsx_dfst_f(int, float *, float *, int *, float *);
|
||||
|
||||
#define dft_br_len(l) (2ul + (1ul << (int)(log(l / 2 + .5) / log(2.)) / 2))
|
||||
#define dft_sc_len(l) ((unsigned long)l / 2)
|
||||
|
||||
/* Over-allocate h by 2 to use these macros */
|
||||
#define LSX_PACK(h, n) h[1] = h[n]
|
||||
#define LSX_UNPACK(h, n) h[n] = h[1], h[n + 1] = h[1] = 0;
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
void lsx_cdft(int, int, double *, int *, double *);
|
||||
void lsx_rdft(int, int, double *, int *, double *);
|
||||
void lsx_ddct(int, int, double *, int *, double *);
|
||||
void lsx_ddst(int, int, double *, int *, double *);
|
||||
void lsx_dfct(int, double *, double *, int *, double *);
|
||||
void lsx_dfst(int, double *, double *, int *, double *);
|
||||
|
||||
void lsx_cdft_f(int, int, float *, int *, float *);
|
||||
void lsx_rdft_f(int, int, float *, int *, float *);
|
||||
void lsx_ddct_f(int, int, float *, int *, float *);
|
||||
void lsx_ddst_f(int, int, float *, int *, float *);
|
||||
void lsx_dfct_f(int, float *, float *, int *, float *);
|
||||
void lsx_dfst_f(int, float *, float *, int *, float *);
|
||||
|
||||
#define dft_br_len(l) (2ul + (1ul << (int)(log(l / 2 + .5) / log(2.)) / 2))
|
||||
#define dft_sc_len(l) ((unsigned long)l / 2)
|
||||
|
||||
/* Over-allocate h by 2 to use these macros */
|
||||
#define LSX_PACK(h, n) h[1] = h[n]
|
||||
#define LSX_UNPACK(h, n) h[n] = h[1], h[n + 1] = h[1] = 0;
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#include "filter.h"
|
||||
#define FFT4G_FLOAT
|
||||
#include "fft4g.c"
|
||||
|
||||
static void * null(void) {return 0;}
|
||||
static void forward (int length, void * setup, double * H) {lsx_safe_rdft_f(length, 1, H); (void)setup;}
|
||||
static void backward(int length, void * setup, double * H) {lsx_safe_rdft_f(length, -1, H); (void)setup;}
|
||||
static int multiplier(void) {return 2;}
|
||||
static void nothing(void) {}
|
||||
|
||||
typedef void (* fn_t)(void);
|
||||
fn_t _soxr_rdft32_cb[] = {
|
||||
(fn_t)null,
|
||||
(fn_t)null,
|
||||
(fn_t)nothing,
|
||||
(fn_t)forward,
|
||||
(fn_t)forward,
|
||||
(fn_t)backward,
|
||||
(fn_t)backward,
|
||||
(fn_t)_soxr_ordered_convolve_f,
|
||||
(fn_t)_soxr_ordered_partial_convolve_f,
|
||||
(fn_t)multiplier,
|
||||
(fn_t)nothing,
|
||||
};
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#include "filter.h"
|
||||
#define FFT4G_FLOAT
|
||||
#include "fft4g.c"
|
||||
|
||||
static void * null(void) {return 0;}
|
||||
static void forward (int length, void * setup, double * H) {lsx_safe_rdft_f(length, 1, H); (void)setup;}
|
||||
static void backward(int length, void * setup, double * H) {lsx_safe_rdft_f(length, -1, H); (void)setup;}
|
||||
static int multiplier(void) {return 2;}
|
||||
static void nothing(void) {}
|
||||
|
||||
typedef void (* fn_t)(void);
|
||||
fn_t _soxr_rdft32_cb[] = {
|
||||
(fn_t)null,
|
||||
(fn_t)null,
|
||||
(fn_t)nothing,
|
||||
(fn_t)forward,
|
||||
(fn_t)forward,
|
||||
(fn_t)backward,
|
||||
(fn_t)backward,
|
||||
(fn_t)_soxr_ordered_convolve_f,
|
||||
(fn_t)_soxr_ordered_partial_convolve_f,
|
||||
(fn_t)multiplier,
|
||||
(fn_t)nothing,
|
||||
};
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#include "filter.h"
|
||||
#include "simd.h"
|
||||
|
||||
static void * null(void) {return 0;}
|
||||
static void nothing(void) {}
|
||||
static void forward (int length, void * setup, float * H) {lsx_safe_rdft_f(length, 1, H); (void)setup;}
|
||||
static void backward(int length, void * setup, float * H) {lsx_safe_rdft_f(length, -1, H); (void)setup;}
|
||||
static int multiplier(void) {return 2;}
|
||||
|
||||
typedef void (* fn_t)(void);
|
||||
fn_t _soxr_rdft32s_cb[] = {
|
||||
(fn_t)null,
|
||||
(fn_t)null,
|
||||
(fn_t)nothing,
|
||||
(fn_t)forward,
|
||||
(fn_t)forward,
|
||||
(fn_t)backward,
|
||||
(fn_t)backward,
|
||||
(fn_t)_soxr_ordered_convolve_simd,
|
||||
(fn_t)_soxr_ordered_partial_convolve_simd,
|
||||
(fn_t)multiplier,
|
||||
(fn_t)nothing,
|
||||
};
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#include "filter.h"
|
||||
#include "simd.h"
|
||||
|
||||
static void * null(void) {return 0;}
|
||||
static void nothing(void) {}
|
||||
static void forward (int length, void * setup, float * H) {lsx_safe_rdft_f(length, 1, H); (void)setup;}
|
||||
static void backward(int length, void * setup, float * H) {lsx_safe_rdft_f(length, -1, H); (void)setup;}
|
||||
static int multiplier(void) {return 2;}
|
||||
|
||||
typedef void (* fn_t)(void);
|
||||
fn_t _soxr_rdft32s_cb[] = {
|
||||
(fn_t)null,
|
||||
(fn_t)null,
|
||||
(fn_t)nothing,
|
||||
(fn_t)forward,
|
||||
(fn_t)forward,
|
||||
(fn_t)backward,
|
||||
(fn_t)backward,
|
||||
(fn_t)_soxr_ordered_convolve_simd,
|
||||
(fn_t)_soxr_ordered_partial_convolve_simd,
|
||||
(fn_t)multiplier,
|
||||
(fn_t)nothing,
|
||||
};
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#include "filter.h"
|
||||
#include "fft4g.c"
|
||||
#include "soxr-config.h"
|
||||
|
||||
#if HAVE_DOUBLE_PRECISION
|
||||
static void * null(void) {return 0;}
|
||||
static void nothing(void) {}
|
||||
static void forward (int length, void * setup, double * H) {lsx_safe_rdft(length, 1, H); (void)setup;}
|
||||
static void backward(int length, void * setup, double * H) {lsx_safe_rdft(length, -1, H); (void)setup;}
|
||||
static int multiplier(void) {return 2;}
|
||||
|
||||
typedef void (* fn_t)(void);
|
||||
fn_t _soxr_rdft64_cb[] = {
|
||||
(fn_t)null,
|
||||
(fn_t)null,
|
||||
(fn_t)nothing,
|
||||
(fn_t)forward,
|
||||
(fn_t)forward,
|
||||
(fn_t)backward,
|
||||
(fn_t)backward,
|
||||
(fn_t)_soxr_ordered_convolve,
|
||||
(fn_t)_soxr_ordered_partial_convolve,
|
||||
(fn_t)multiplier,
|
||||
(fn_t)nothing,
|
||||
};
|
||||
#endif
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#include "filter.h"
|
||||
#include "fft4g.c"
|
||||
#include "soxr-config.h"
|
||||
|
||||
#if HAVE_DOUBLE_PRECISION
|
||||
static void * null(void) {return 0;}
|
||||
static void nothing(void) {}
|
||||
static void forward (int length, void * setup, double * H) {lsx_safe_rdft(length, 1, H); (void)setup;}
|
||||
static void backward(int length, void * setup, double * H) {lsx_safe_rdft(length, -1, H); (void)setup;}
|
||||
static int multiplier(void) {return 2;}
|
||||
|
||||
typedef void (* fn_t)(void);
|
||||
fn_t _soxr_rdft64_cb[] = {
|
||||
(fn_t)null,
|
||||
(fn_t)null,
|
||||
(fn_t)nothing,
|
||||
(fn_t)forward,
|
||||
(fn_t)forward,
|
||||
(fn_t)backward,
|
||||
(fn_t)backward,
|
||||
(fn_t)_soxr_ordered_convolve,
|
||||
(fn_t)_soxr_ordered_partial_convolve,
|
||||
(fn_t)multiplier,
|
||||
(fn_t)nothing,
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -1,92 +1,92 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
static int * LSX_FFT_BR;
|
||||
static DFT_FLOAT * LSX_FFT_SC;
|
||||
static int FFT_LEN = -1;
|
||||
static ccrw2_t FFT_CACHE_CCRW;
|
||||
|
||||
void LSX_INIT_FFT_CACHE(void)
|
||||
{
|
||||
if (FFT_LEN >= 0)
|
||||
return;
|
||||
assert(LSX_FFT_BR == NULL);
|
||||
assert(LSX_FFT_SC == NULL);
|
||||
assert(FFT_LEN == -1);
|
||||
ccrw2_init(FFT_CACHE_CCRW);
|
||||
FFT_LEN = 0;
|
||||
}
|
||||
|
||||
void LSX_CLEAR_FFT_CACHE(void)
|
||||
{
|
||||
assert(FFT_LEN >= 0);
|
||||
ccrw2_clear(FFT_CACHE_CCRW);
|
||||
free(LSX_FFT_BR);
|
||||
free(LSX_FFT_SC);
|
||||
LSX_FFT_SC = NULL;
|
||||
LSX_FFT_BR = NULL;
|
||||
FFT_LEN = -1;
|
||||
}
|
||||
|
||||
static bool UPDATE_FFT_CACHE(int len)
|
||||
{
|
||||
LSX_INIT_FFT_CACHE();
|
||||
assert(lsx_is_power_of_2(len));
|
||||
assert(FFT_LEN >= 0);
|
||||
ccrw2_become_reader(FFT_CACHE_CCRW);
|
||||
if (len > FFT_LEN) {
|
||||
ccrw2_cease_reading(FFT_CACHE_CCRW);
|
||||
ccrw2_become_writer(FFT_CACHE_CCRW);
|
||||
if (len > FFT_LEN) {
|
||||
int old_n = FFT_LEN;
|
||||
FFT_LEN = len;
|
||||
LSX_FFT_BR = realloc(LSX_FFT_BR, dft_br_len(FFT_LEN) * sizeof(*LSX_FFT_BR));
|
||||
LSX_FFT_SC = realloc(LSX_FFT_SC, dft_sc_len(FFT_LEN) * sizeof(*LSX_FFT_SC));
|
||||
if (!old_n) {
|
||||
LSX_FFT_BR[0] = 0;
|
||||
#if SOXR_LIB
|
||||
atexit(LSX_CLEAR_FFT_CACHE);
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
ccrw2_cease_writing(FFT_CACHE_CCRW);
|
||||
ccrw2_become_reader(FFT_CACHE_CCRW);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void DONE_WITH_FFT_CACHE(bool is_writer)
|
||||
{
|
||||
if (is_writer)
|
||||
ccrw2_cease_writing(FFT_CACHE_CCRW);
|
||||
else ccrw2_cease_reading(FFT_CACHE_CCRW);
|
||||
}
|
||||
|
||||
void LSX_SAFE_RDFT(int len, int type, DFT_FLOAT * d)
|
||||
{
|
||||
bool is_writer = UPDATE_FFT_CACHE(len);
|
||||
LSX_RDFT(len, type, d, LSX_FFT_BR, LSX_FFT_SC);
|
||||
DONE_WITH_FFT_CACHE(is_writer);
|
||||
}
|
||||
|
||||
void LSX_SAFE_CDFT(int len, int type, DFT_FLOAT * d)
|
||||
{
|
||||
bool is_writer = UPDATE_FFT_CACHE(len);
|
||||
LSX_CDFT(len, type, d, LSX_FFT_BR, LSX_FFT_SC);
|
||||
DONE_WITH_FFT_CACHE(is_writer);
|
||||
}
|
||||
|
||||
#undef UPDATE_FFT_CACHE
|
||||
#undef LSX_SAFE_RDFT
|
||||
#undef LSX_SAFE_CDFT
|
||||
#undef LSX_RDFT
|
||||
#undef LSX_INIT_FFT_CACHE
|
||||
#undef LSX_FFT_SC
|
||||
#undef LSX_FFT_BR
|
||||
#undef LSX_CLEAR_FFT_CACHE
|
||||
#undef LSX_CDFT
|
||||
#undef FFT_LEN
|
||||
#undef FFT_CACHE_CCRW
|
||||
#undef DONE_WITH_FFT_CACHE
|
||||
#undef DFT_FLOAT
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
static int * LSX_FFT_BR;
|
||||
static DFT_FLOAT * LSX_FFT_SC;
|
||||
static int FFT_LEN = -1;
|
||||
static ccrw2_t FFT_CACHE_CCRW;
|
||||
|
||||
void LSX_INIT_FFT_CACHE(void)
|
||||
{
|
||||
if (FFT_LEN >= 0)
|
||||
return;
|
||||
assert(LSX_FFT_BR == NULL);
|
||||
assert(LSX_FFT_SC == NULL);
|
||||
assert(FFT_LEN == -1);
|
||||
ccrw2_init(FFT_CACHE_CCRW);
|
||||
FFT_LEN = 0;
|
||||
}
|
||||
|
||||
void LSX_CLEAR_FFT_CACHE(void)
|
||||
{
|
||||
assert(FFT_LEN >= 0);
|
||||
ccrw2_clear(FFT_CACHE_CCRW);
|
||||
free(LSX_FFT_BR);
|
||||
free(LSX_FFT_SC);
|
||||
LSX_FFT_SC = NULL;
|
||||
LSX_FFT_BR = NULL;
|
||||
FFT_LEN = -1;
|
||||
}
|
||||
|
||||
static bool UPDATE_FFT_CACHE(int len)
|
||||
{
|
||||
LSX_INIT_FFT_CACHE();
|
||||
assert(lsx_is_power_of_2(len));
|
||||
assert(FFT_LEN >= 0);
|
||||
ccrw2_become_reader(FFT_CACHE_CCRW);
|
||||
if (len > FFT_LEN) {
|
||||
ccrw2_cease_reading(FFT_CACHE_CCRW);
|
||||
ccrw2_become_writer(FFT_CACHE_CCRW);
|
||||
if (len > FFT_LEN) {
|
||||
int old_n = FFT_LEN;
|
||||
FFT_LEN = len;
|
||||
LSX_FFT_BR = realloc(LSX_FFT_BR, dft_br_len(FFT_LEN) * sizeof(*LSX_FFT_BR));
|
||||
LSX_FFT_SC = realloc(LSX_FFT_SC, dft_sc_len(FFT_LEN) * sizeof(*LSX_FFT_SC));
|
||||
if (!old_n) {
|
||||
LSX_FFT_BR[0] = 0;
|
||||
#if SOXR_LIB
|
||||
atexit(LSX_CLEAR_FFT_CACHE);
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
ccrw2_cease_writing(FFT_CACHE_CCRW);
|
||||
ccrw2_become_reader(FFT_CACHE_CCRW);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void DONE_WITH_FFT_CACHE(bool is_writer)
|
||||
{
|
||||
if (is_writer)
|
||||
ccrw2_cease_writing(FFT_CACHE_CCRW);
|
||||
else ccrw2_cease_reading(FFT_CACHE_CCRW);
|
||||
}
|
||||
|
||||
void LSX_SAFE_RDFT(int len, int type, DFT_FLOAT * d)
|
||||
{
|
||||
bool is_writer = UPDATE_FFT_CACHE(len);
|
||||
LSX_RDFT(len, type, d, LSX_FFT_BR, LSX_FFT_SC);
|
||||
DONE_WITH_FFT_CACHE(is_writer);
|
||||
}
|
||||
|
||||
void LSX_SAFE_CDFT(int len, int type, DFT_FLOAT * d)
|
||||
{
|
||||
bool is_writer = UPDATE_FFT_CACHE(len);
|
||||
LSX_CDFT(len, type, d, LSX_FFT_BR, LSX_FFT_SC);
|
||||
DONE_WITH_FFT_CACHE(is_writer);
|
||||
}
|
||||
|
||||
#undef UPDATE_FFT_CACHE
|
||||
#undef LSX_SAFE_RDFT
|
||||
#undef LSX_SAFE_CDFT
|
||||
#undef LSX_RDFT
|
||||
#undef LSX_INIT_FFT_CACHE
|
||||
#undef LSX_FFT_SC
|
||||
#undef LSX_FFT_BR
|
||||
#undef LSX_CLEAR_FFT_CACHE
|
||||
#undef LSX_CDFT
|
||||
#undef FFT_LEN
|
||||
#undef FFT_CACHE_CCRW
|
||||
#undef DONE_WITH_FFT_CACHE
|
||||
#undef DFT_FLOAT
|
||||
|
|
|
@ -1,124 +1,124 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#ifndef fifo_included
|
||||
#define fifo_included
|
||||
|
||||
#if !defined FIFO_SIZE_T
|
||||
#define FIFO_SIZE_T size_t
|
||||
#endif
|
||||
|
||||
#if !defined FIFO_REALLOC
|
||||
#define FIFO_REALLOC(a,b,c) realloc(a,b)
|
||||
#undef FIFO_FREE
|
||||
#define FIFO_FREE free
|
||||
#undef FIFO_MALLOC
|
||||
#define FIFO_MALLOC malloc
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char * data;
|
||||
size_t allocation; /* Number of bytes allocated for data. */
|
||||
size_t item_size; /* Size of each item in data */
|
||||
size_t begin; /* Offset of the first byte to read. */
|
||||
size_t end; /* 1 + Offset of the last byte byte to read. */
|
||||
} fifo_t;
|
||||
|
||||
#if !defined FIFO_MIN
|
||||
#define FIFO_MIN 0x4000
|
||||
#endif
|
||||
|
||||
#if !defined UNUSED
|
||||
#define UNUSED
|
||||
#endif
|
||||
|
||||
UNUSED static void fifo_clear(fifo_t * f)
|
||||
{
|
||||
f->end = f->begin = 0;
|
||||
}
|
||||
|
||||
UNUSED static void * fifo_reserve(fifo_t * f, FIFO_SIZE_T n0)
|
||||
{
|
||||
size_t n = (size_t)n0;
|
||||
n *= f->item_size;
|
||||
|
||||
if (f->begin == f->end)
|
||||
fifo_clear(f);
|
||||
|
||||
while (1) {
|
||||
if (f->end + n <= f->allocation) {
|
||||
void *p = f->data + f->end;
|
||||
|
||||
f->end += n;
|
||||
return p;
|
||||
}
|
||||
if (f->begin > FIFO_MIN) {
|
||||
memmove(f->data, f->data + f->begin, f->end - f->begin);
|
||||
f->end -= f->begin;
|
||||
f->begin = 0;
|
||||
continue;
|
||||
}
|
||||
f->data = FIFO_REALLOC(f->data, f->allocation + n, f->allocation);
|
||||
f->allocation += n;
|
||||
if (!f->data)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
UNUSED static void * fifo_write(fifo_t * f, FIFO_SIZE_T n0, void const * data)
|
||||
{
|
||||
size_t n = (size_t)n0;
|
||||
void * s = fifo_reserve(f, n0);
|
||||
if (data)
|
||||
memcpy(s, data, n * f->item_size);
|
||||
return s;
|
||||
}
|
||||
|
||||
UNUSED static void fifo_trim_to(fifo_t * f, FIFO_SIZE_T n0)
|
||||
{
|
||||
size_t n = (size_t)n0;
|
||||
n *= f->item_size;
|
||||
f->end = f->begin + n;
|
||||
}
|
||||
|
||||
UNUSED static void fifo_trim_by(fifo_t * f, FIFO_SIZE_T n0)
|
||||
{
|
||||
size_t n = (size_t)n0;
|
||||
n *= f->item_size;
|
||||
f->end -= n;
|
||||
}
|
||||
|
||||
UNUSED static FIFO_SIZE_T fifo_occupancy(fifo_t * f)
|
||||
{
|
||||
return (FIFO_SIZE_T)((f->end - f->begin) / f->item_size);
|
||||
}
|
||||
|
||||
UNUSED static void * fifo_read(fifo_t * f, FIFO_SIZE_T n0, void * data)
|
||||
{
|
||||
size_t n = (size_t)n0;
|
||||
char * ret = f->data + f->begin;
|
||||
n *= f->item_size;
|
||||
if (n > (f->end - f->begin))
|
||||
return NULL;
|
||||
if (data)
|
||||
memcpy(data, ret, (size_t)n);
|
||||
f->begin += n;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define fifo_read_ptr(f) fifo_read(f, (FIFO_SIZE_T)0, NULL)
|
||||
|
||||
UNUSED static void fifo_delete(fifo_t * f)
|
||||
{
|
||||
FIFO_FREE(f->data);
|
||||
}
|
||||
|
||||
UNUSED static int fifo_create(fifo_t * f, FIFO_SIZE_T item_size)
|
||||
{
|
||||
f->item_size = (size_t)item_size;
|
||||
f->allocation = FIFO_MIN;
|
||||
fifo_clear(f);
|
||||
return !(f->data = FIFO_MALLOC(f->allocation));
|
||||
}
|
||||
|
||||
#endif
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#ifndef fifo_included
|
||||
#define fifo_included
|
||||
|
||||
#if !defined FIFO_SIZE_T
|
||||
#define FIFO_SIZE_T size_t
|
||||
#endif
|
||||
|
||||
#if !defined FIFO_REALLOC
|
||||
#define FIFO_REALLOC(a,b,c) realloc(a,b)
|
||||
#undef FIFO_FREE
|
||||
#define FIFO_FREE free
|
||||
#undef FIFO_MALLOC
|
||||
#define FIFO_MALLOC malloc
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char * data;
|
||||
size_t allocation; /* Number of bytes allocated for data. */
|
||||
size_t item_size; /* Size of each item in data */
|
||||
size_t begin; /* Offset of the first byte to read. */
|
||||
size_t end; /* 1 + Offset of the last byte byte to read. */
|
||||
} fifo_t;
|
||||
|
||||
#if !defined FIFO_MIN
|
||||
#define FIFO_MIN 0x4000
|
||||
#endif
|
||||
|
||||
#if !defined UNUSED
|
||||
#define UNUSED
|
||||
#endif
|
||||
|
||||
UNUSED static void fifo_clear(fifo_t * f)
|
||||
{
|
||||
f->end = f->begin = 0;
|
||||
}
|
||||
|
||||
UNUSED static void * fifo_reserve(fifo_t * f, FIFO_SIZE_T n0)
|
||||
{
|
||||
size_t n = (size_t)n0;
|
||||
n *= f->item_size;
|
||||
|
||||
if (f->begin == f->end)
|
||||
fifo_clear(f);
|
||||
|
||||
while (1) {
|
||||
if (f->end + n <= f->allocation) {
|
||||
void *p = f->data + f->end;
|
||||
|
||||
f->end += n;
|
||||
return p;
|
||||
}
|
||||
if (f->begin > FIFO_MIN) {
|
||||
memmove(f->data, f->data + f->begin, f->end - f->begin);
|
||||
f->end -= f->begin;
|
||||
f->begin = 0;
|
||||
continue;
|
||||
}
|
||||
f->data = FIFO_REALLOC(f->data, f->allocation + n, f->allocation);
|
||||
f->allocation += n;
|
||||
if (!f->data)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
UNUSED static void * fifo_write(fifo_t * f, FIFO_SIZE_T n0, void const * data)
|
||||
{
|
||||
size_t n = (size_t)n0;
|
||||
void * s = fifo_reserve(f, n0);
|
||||
if (data)
|
||||
memcpy(s, data, n * f->item_size);
|
||||
return s;
|
||||
}
|
||||
|
||||
UNUSED static void fifo_trim_to(fifo_t * f, FIFO_SIZE_T n0)
|
||||
{
|
||||
size_t n = (size_t)n0;
|
||||
n *= f->item_size;
|
||||
f->end = f->begin + n;
|
||||
}
|
||||
|
||||
UNUSED static void fifo_trim_by(fifo_t * f, FIFO_SIZE_T n0)
|
||||
{
|
||||
size_t n = (size_t)n0;
|
||||
n *= f->item_size;
|
||||
f->end -= n;
|
||||
}
|
||||
|
||||
UNUSED static FIFO_SIZE_T fifo_occupancy(fifo_t * f)
|
||||
{
|
||||
return (FIFO_SIZE_T)((f->end - f->begin) / f->item_size);
|
||||
}
|
||||
|
||||
UNUSED static void * fifo_read(fifo_t * f, FIFO_SIZE_T n0, void * data)
|
||||
{
|
||||
size_t n = (size_t)n0;
|
||||
char * ret = f->data + f->begin;
|
||||
n *= f->item_size;
|
||||
if (n > (f->end - f->begin))
|
||||
return NULL;
|
||||
if (data)
|
||||
memcpy(data, ret, (size_t)n);
|
||||
f->begin += n;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define fifo_read_ptr(f) fifo_read(f, (FIFO_SIZE_T)0, NULL)
|
||||
|
||||
UNUSED static void fifo_delete(fifo_t * f)
|
||||
{
|
||||
FIFO_FREE(f->data);
|
||||
}
|
||||
|
||||
UNUSED static int fifo_create(fifo_t * f, FIFO_SIZE_T item_size)
|
||||
{
|
||||
f->item_size = (size_t)item_size;
|
||||
f->allocation = FIFO_MIN;
|
||||
fifo_clear(f);
|
||||
return !(f->data = FIFO_MALLOC(f->allocation));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,245 +1,245 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#include "filter.h"
|
||||
|
||||
#include <math.h>
|
||||
#if !defined M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fft4g.h"
|
||||
#include "ccrw2.h"
|
||||
|
||||
#if 1 || HAVE_DOUBLE_PRECISION /* Always need this, for lsx_fir_to_phase. */
|
||||
#define DFT_FLOAT double
|
||||
#define DONE_WITH_FFT_CACHE done_with_fft_cache
|
||||
#define FFT_CACHE_CCRW fft_cache_ccrw
|
||||
#define FFT_LEN fft_len
|
||||
#define LSX_CDFT lsx_cdft
|
||||
#define LSX_CLEAR_FFT_CACHE lsx_clear_fft_cache
|
||||
#define LSX_FFT_BR lsx_fft_br
|
||||
#define LSX_FFT_SC lsx_fft_sc
|
||||
#define LSX_INIT_FFT_CACHE lsx_init_fft_cache
|
||||
#define LSX_RDFT lsx_rdft
|
||||
#define LSX_SAFE_CDFT lsx_safe_cdft
|
||||
#define LSX_SAFE_RDFT lsx_safe_rdft
|
||||
#define UPDATE_FFT_CACHE update_fft_cache
|
||||
#include "fft4g_cache.h"
|
||||
#endif
|
||||
|
||||
#if HAVE_SINGLE_PRECISION && !HAVE_AVFFT
|
||||
#define DFT_FLOAT float
|
||||
#define DONE_WITH_FFT_CACHE done_with_fft_cache_f
|
||||
#define FFT_CACHE_CCRW fft_cache_ccrw_f
|
||||
#define FFT_LEN fft_len_f
|
||||
#define LSX_CDFT lsx_cdft_f
|
||||
#define LSX_CLEAR_FFT_CACHE lsx_clear_fft_cache_f
|
||||
#define LSX_FFT_BR lsx_fft_br_f
|
||||
#define LSX_FFT_SC lsx_fft_sc_f
|
||||
#define LSX_INIT_FFT_CACHE lsx_init_fft_cache_f
|
||||
#define LSX_RDFT lsx_rdft_f
|
||||
#define LSX_SAFE_CDFT lsx_safe_cdft_f
|
||||
#define LSX_SAFE_RDFT lsx_safe_rdft_f
|
||||
#define UPDATE_FFT_CACHE update_fft_cache_f
|
||||
#include "fft4g_cache.h"
|
||||
#endif
|
||||
|
||||
#if HAVE_DOUBLE_PRECISION || !SOXR_LIB
|
||||
#define DFT_FLOAT double
|
||||
#define ORDERED_CONVOLVE lsx_ordered_convolve
|
||||
#define ORDERED_PARTIAL_CONVOLVE lsx_ordered_partial_convolve
|
||||
#include "rdft.h"
|
||||
#endif
|
||||
|
||||
#if HAVE_SINGLE_PRECISION
|
||||
#define DFT_FLOAT float
|
||||
#define ORDERED_CONVOLVE lsx_ordered_convolve_f
|
||||
#define ORDERED_PARTIAL_CONVOLVE lsx_ordered_partial_convolve_f
|
||||
#include "rdft.h"
|
||||
#endif
|
||||
|
||||
double lsx_kaiser_beta(double att, double tr_bw)
|
||||
{
|
||||
if (att >= 60) {
|
||||
static const double coefs[][4] = {
|
||||
{-6.784957e-10,1.02856e-05,0.1087556,-0.8988365+.001},
|
||||
{-6.897885e-10,1.027433e-05,0.10876,-0.8994658+.002},
|
||||
{-1.000683e-09,1.030092e-05,0.1087677,-0.9007898+.003},
|
||||
{-3.654474e-10,1.040631e-05,0.1087085,-0.8977766+.006},
|
||||
{8.106988e-09,6.983091e-06,0.1091387,-0.9172048+.015},
|
||||
{9.519571e-09,7.272678e-06,0.1090068,-0.9140768+.025},
|
||||
{-5.626821e-09,1.342186e-05,0.1083999,-0.9065452+.05},
|
||||
{-9.965946e-08,5.073548e-05,0.1040967,-0.7672778+.085},
|
||||
{1.604808e-07,-5.856462e-05,0.1185998,-1.34824+.1},
|
||||
{-1.511964e-07,6.363034e-05,0.1064627,-0.9876665+.18},
|
||||
};
|
||||
double realm = log(tr_bw/.0005)/log(2.);
|
||||
double const * c0 = coefs[range_limit( (int)realm, 0, (int)array_length(coefs)-1)];
|
||||
double const * c1 = coefs[range_limit(1+(int)realm, 0, (int)array_length(coefs)-1)];
|
||||
double b0 = ((c0[0]*att + c0[1])*att + c0[2])*att + c0[3];
|
||||
double b1 = ((c1[0]*att + c1[1])*att + c1[2])*att + c1[3];
|
||||
return b0 + (b1 - b0) * (realm - (int)realm);
|
||||
}
|
||||
if (att > 50 ) return .1102 * (att - 8.7);
|
||||
if (att > 20.96) return .58417 * pow(att -20.96, .4) + .07886 * (att - 20.96);
|
||||
return 0;
|
||||
}
|
||||
|
||||
double * lsx_make_lpf(
|
||||
int num_taps, double Fc, double beta, double rho, double scale)
|
||||
{
|
||||
int i, m = num_taps - 1;
|
||||
double * h = malloc((size_t)num_taps * sizeof(*h));
|
||||
double mult = scale / lsx_bessel_I_0(beta), mult1 = 1 / (.5 * m + rho);
|
||||
assert(Fc >= 0 && Fc <= 1);
|
||||
lsx_debug("make_lpf(n=%i Fc=%.7g β=%g ρ=%g scale=%g)",
|
||||
num_taps, Fc, beta, rho, scale);
|
||||
|
||||
if (h) for (i = 0; i <= m / 2; ++i) {
|
||||
double z = i - .5 * m, x = z * M_PI, y = z * mult1;
|
||||
h[i] = x? sin(Fc * x) / x : Fc;
|
||||
h[i] *= lsx_bessel_I_0(beta * sqrt(1 - y * y)) * mult;
|
||||
if (m - i != i)
|
||||
h[m - i] = h[i];
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
void lsx_kaiser_params(double att, double Fc, double tr_bw, double * beta, int * num_taps)
|
||||
{
|
||||
*beta = *beta < 0? lsx_kaiser_beta(att, tr_bw * .5 / Fc): *beta;
|
||||
att = att < 60? (att - 7.95) / (2.285 * M_PI * 2) :
|
||||
((.0007528358-1.577737e-05**beta)**beta+.6248022)**beta+.06186902;
|
||||
*num_taps = !*num_taps? (int)ceil(att/tr_bw + 1) : *num_taps;
|
||||
}
|
||||
|
||||
double * lsx_design_lpf(
|
||||
double Fp, /* End of pass-band */
|
||||
double Fs, /* Start of stop-band */
|
||||
double Fn, /* Nyquist freq; e.g. 0.5, 1, PI */
|
||||
double att, /* Stop-band attenuation in dB */
|
||||
int * num_taps, /* 0: value will be estimated */
|
||||
int k, /* >0: number of phases; <0: num_taps ≡ 1 (mod -k) */
|
||||
double beta) /* <0: value will be estimated */
|
||||
{
|
||||
int n = *num_taps, phases = max(k, 1), modulo = max(-k, 1);
|
||||
double tr_bw, Fc, rho = phases == 1? .5 : att < 120? .63 : .75;
|
||||
|
||||
Fp /= fabs(Fn), Fs /= fabs(Fn); /* Normalise to Fn = 1 */
|
||||
tr_bw = .5 * (Fs - Fp); /* Transition band-width: 6dB to stop points */
|
||||
tr_bw /= phases, Fs /= phases;
|
||||
tr_bw = min(tr_bw, .5 * Fs);
|
||||
Fc = Fs - tr_bw;
|
||||
assert(Fc - tr_bw >= 0);
|
||||
lsx_kaiser_params(att, Fc, tr_bw, &beta, num_taps);
|
||||
if (!n)
|
||||
*num_taps = phases > 1? *num_taps / phases * phases + phases - 1 :
|
||||
(*num_taps + modulo - 2) / modulo * modulo + 1;
|
||||
return Fn < 0? 0 : lsx_make_lpf(*num_taps, Fc, beta, rho, (double)phases);
|
||||
}
|
||||
|
||||
static double safe_log(double x)
|
||||
{
|
||||
assert(x >= 0);
|
||||
if (x)
|
||||
return log(x);
|
||||
lsx_debug("log(0)");
|
||||
return -26;
|
||||
}
|
||||
|
||||
void lsx_fir_to_phase(double * * h, int * len, int * post_len, double phase)
|
||||
{
|
||||
double * pi_wraps, * work, phase1 = (phase > 50 ? 100 - phase : phase) / 50;
|
||||
int i, work_len, begin, end, imp_peak = 0, peak = 0;
|
||||
double imp_sum = 0, peak_imp_sum = 0;
|
||||
double prev_angle2 = 0, cum_2pi = 0, prev_angle1 = 0, cum_1pi = 0;
|
||||
|
||||
for (i = *len, work_len = 2 * 2 * 8; i > 1; work_len <<= 1, i >>= 1);
|
||||
|
||||
work = calloc((size_t)work_len + 2, sizeof(*work)); /* +2: (UN)PACK */
|
||||
pi_wraps = malloc((((size_t)work_len + 2) / 2) * sizeof(*pi_wraps));
|
||||
|
||||
memcpy(work, *h, (size_t)*len * sizeof(*work));
|
||||
lsx_safe_rdft(work_len, 1, work); /* Cepstral: */
|
||||
LSX_UNPACK(work, work_len);
|
||||
|
||||
for (i = 0; i <= work_len; i += 2) {
|
||||
double angle = atan2(work[i + 1], work[i]);
|
||||
double detect = 2 * M_PI;
|
||||
double delta = angle - prev_angle2;
|
||||
double adjust = detect * ((delta < -detect * .7) - (delta > detect * .7));
|
||||
prev_angle2 = angle;
|
||||
cum_2pi += adjust;
|
||||
angle += cum_2pi;
|
||||
detect = M_PI;
|
||||
delta = angle - prev_angle1;
|
||||
adjust = detect * ((delta < -detect * .7) - (delta > detect * .7));
|
||||
prev_angle1 = angle;
|
||||
cum_1pi += fabs(adjust); /* fabs for when 2pi and 1pi have combined */
|
||||
pi_wraps[i >> 1] = cum_1pi;
|
||||
|
||||
work[i] = safe_log(sqrt(sqr(work[i]) + sqr(work[i + 1])));
|
||||
work[i + 1] = 0;
|
||||
}
|
||||
LSX_PACK(work, work_len);
|
||||
lsx_safe_rdft(work_len, -1, work);
|
||||
for (i = 0; i < work_len; ++i) work[i] *= 2. / work_len;
|
||||
|
||||
for (i = 1; i < work_len / 2; ++i) { /* Window to reject acausal components */
|
||||
work[i] *= 2;
|
||||
work[i + work_len / 2] = 0;
|
||||
}
|
||||
lsx_safe_rdft(work_len, 1, work);
|
||||
|
||||
for (i = 2; i < work_len; i += 2) /* Interpolate between linear & min phase */
|
||||
work[i + 1] = phase1 * i / work_len * pi_wraps[work_len >> 1] +
|
||||
(1 - phase1) * (work[i + 1] + pi_wraps[i >> 1]) - pi_wraps[i >> 1];
|
||||
|
||||
work[0] = exp(work[0]), work[1] = exp(work[1]);
|
||||
for (i = 2; i < work_len; i += 2) {
|
||||
double x = exp(work[i]);
|
||||
work[i ] = x * cos(work[i + 1]);
|
||||
work[i + 1] = x * sin(work[i + 1]);
|
||||
}
|
||||
|
||||
lsx_safe_rdft(work_len, -1, work);
|
||||
for (i = 0; i < work_len; ++i) work[i] *= 2. / work_len;
|
||||
|
||||
/* Find peak pos. */
|
||||
for (i = 0; i <= (int)(pi_wraps[work_len >> 1] / M_PI + .5); ++i) {
|
||||
imp_sum += work[i];
|
||||
if (fabs(imp_sum) > fabs(peak_imp_sum)) {
|
||||
peak_imp_sum = imp_sum;
|
||||
peak = i;
|
||||
}
|
||||
if (work[i] > work[imp_peak]) /* For debug check only */
|
||||
imp_peak = i;
|
||||
}
|
||||
while (peak && fabs(work[peak-1]) > fabs(work[peak]) && work[peak-1] * work[peak] > 0)
|
||||
--peak;
|
||||
|
||||
if (!phase1)
|
||||
begin = 0;
|
||||
else if (phase1 == 1)
|
||||
begin = peak - *len / 2;
|
||||
else {
|
||||
begin = (int)((.997 - (2 - phase1) * .22) * *len + .5);
|
||||
end = (int)((.997 + (0 - phase1) * .22) * *len + .5);
|
||||
begin = peak - (begin & ~3);
|
||||
end = peak + 1 + ((end + 3) & ~3);
|
||||
*len = end - begin;
|
||||
*h = realloc(*h, (size_t)*len * sizeof(**h));
|
||||
}
|
||||
for (i = 0; i < *len; ++i) (*h)[i] =
|
||||
work[(begin + (phase > 50 ? *len - 1 - i : i) + work_len) & (work_len - 1)];
|
||||
*post_len = phase > 50 ? peak - begin : begin + *len - (peak + 1);
|
||||
|
||||
lsx_debug("nPI=%g peak-sum@%i=%g (val@%i=%g); len=%i post=%i (%g%%)",
|
||||
pi_wraps[work_len >> 1] / M_PI, peak, peak_imp_sum, imp_peak,
|
||||
work[imp_peak], *len, *post_len, 100 - 100. * *post_len / (*len - 1));
|
||||
free(pi_wraps), free(work);
|
||||
}
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#include "filter.h"
|
||||
|
||||
#include <math.h>
|
||||
#if !defined M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "fft4g.h"
|
||||
#include "ccrw2.h"
|
||||
|
||||
#if 1 || HAVE_DOUBLE_PRECISION /* Always need this, for lsx_fir_to_phase. */
|
||||
#define DFT_FLOAT double
|
||||
#define DONE_WITH_FFT_CACHE done_with_fft_cache
|
||||
#define FFT_CACHE_CCRW fft_cache_ccrw
|
||||
#define FFT_LEN fft_len
|
||||
#define LSX_CDFT lsx_cdft
|
||||
#define LSX_CLEAR_FFT_CACHE lsx_clear_fft_cache
|
||||
#define LSX_FFT_BR lsx_fft_br
|
||||
#define LSX_FFT_SC lsx_fft_sc
|
||||
#define LSX_INIT_FFT_CACHE lsx_init_fft_cache
|
||||
#define LSX_RDFT lsx_rdft
|
||||
#define LSX_SAFE_CDFT lsx_safe_cdft
|
||||
#define LSX_SAFE_RDFT lsx_safe_rdft
|
||||
#define UPDATE_FFT_CACHE update_fft_cache
|
||||
#include "fft4g_cache.h"
|
||||
#endif
|
||||
|
||||
#if HAVE_SINGLE_PRECISION && !HAVE_AVFFT
|
||||
#define DFT_FLOAT float
|
||||
#define DONE_WITH_FFT_CACHE done_with_fft_cache_f
|
||||
#define FFT_CACHE_CCRW fft_cache_ccrw_f
|
||||
#define FFT_LEN fft_len_f
|
||||
#define LSX_CDFT lsx_cdft_f
|
||||
#define LSX_CLEAR_FFT_CACHE lsx_clear_fft_cache_f
|
||||
#define LSX_FFT_BR lsx_fft_br_f
|
||||
#define LSX_FFT_SC lsx_fft_sc_f
|
||||
#define LSX_INIT_FFT_CACHE lsx_init_fft_cache_f
|
||||
#define LSX_RDFT lsx_rdft_f
|
||||
#define LSX_SAFE_CDFT lsx_safe_cdft_f
|
||||
#define LSX_SAFE_RDFT lsx_safe_rdft_f
|
||||
#define UPDATE_FFT_CACHE update_fft_cache_f
|
||||
#include "fft4g_cache.h"
|
||||
#endif
|
||||
|
||||
#if HAVE_DOUBLE_PRECISION || !SOXR_LIB
|
||||
#define DFT_FLOAT double
|
||||
#define ORDERED_CONVOLVE lsx_ordered_convolve
|
||||
#define ORDERED_PARTIAL_CONVOLVE lsx_ordered_partial_convolve
|
||||
#include "rdft.h"
|
||||
#endif
|
||||
|
||||
#if HAVE_SINGLE_PRECISION
|
||||
#define DFT_FLOAT float
|
||||
#define ORDERED_CONVOLVE lsx_ordered_convolve_f
|
||||
#define ORDERED_PARTIAL_CONVOLVE lsx_ordered_partial_convolve_f
|
||||
#include "rdft.h"
|
||||
#endif
|
||||
|
||||
double lsx_kaiser_beta(double att, double tr_bw)
|
||||
{
|
||||
if (att >= 60) {
|
||||
static const double coefs[][4] = {
|
||||
{-6.784957e-10,1.02856e-05,0.1087556,-0.8988365+.001},
|
||||
{-6.897885e-10,1.027433e-05,0.10876,-0.8994658+.002},
|
||||
{-1.000683e-09,1.030092e-05,0.1087677,-0.9007898+.003},
|
||||
{-3.654474e-10,1.040631e-05,0.1087085,-0.8977766+.006},
|
||||
{8.106988e-09,6.983091e-06,0.1091387,-0.9172048+.015},
|
||||
{9.519571e-09,7.272678e-06,0.1090068,-0.9140768+.025},
|
||||
{-5.626821e-09,1.342186e-05,0.1083999,-0.9065452+.05},
|
||||
{-9.965946e-08,5.073548e-05,0.1040967,-0.7672778+.085},
|
||||
{1.604808e-07,-5.856462e-05,0.1185998,-1.34824+.1},
|
||||
{-1.511964e-07,6.363034e-05,0.1064627,-0.9876665+.18},
|
||||
};
|
||||
double realm = log(tr_bw/.0005)/log(2.);
|
||||
double const * c0 = coefs[range_limit( (int)realm, 0, (int)array_length(coefs)-1)];
|
||||
double const * c1 = coefs[range_limit(1+(int)realm, 0, (int)array_length(coefs)-1)];
|
||||
double b0 = ((c0[0]*att + c0[1])*att + c0[2])*att + c0[3];
|
||||
double b1 = ((c1[0]*att + c1[1])*att + c1[2])*att + c1[3];
|
||||
return b0 + (b1 - b0) * (realm - (int)realm);
|
||||
}
|
||||
if (att > 50 ) return .1102 * (att - 8.7);
|
||||
if (att > 20.96) return .58417 * pow(att -20.96, .4) + .07886 * (att - 20.96);
|
||||
return 0;
|
||||
}
|
||||
|
||||
double * lsx_make_lpf(
|
||||
int num_taps, double Fc, double beta, double rho, double scale)
|
||||
{
|
||||
int i, m = num_taps - 1;
|
||||
double * h = malloc((size_t)num_taps * sizeof(*h));
|
||||
double mult = scale / lsx_bessel_I_0(beta), mult1 = 1 / (.5 * m + rho);
|
||||
assert(Fc >= 0 && Fc <= 1);
|
||||
lsx_debug("make_lpf(n=%i Fc=%.7g β=%g ρ=%g scale=%g)",
|
||||
num_taps, Fc, beta, rho, scale);
|
||||
|
||||
if (h) for (i = 0; i <= m / 2; ++i) {
|
||||
double z = i - .5 * m, x = z * M_PI, y = z * mult1;
|
||||
h[i] = x? sin(Fc * x) / x : Fc;
|
||||
h[i] *= lsx_bessel_I_0(beta * sqrt(1 - y * y)) * mult;
|
||||
if (m - i != i)
|
||||
h[m - i] = h[i];
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
void lsx_kaiser_params(double att, double Fc, double tr_bw, double * beta, int * num_taps)
|
||||
{
|
||||
*beta = *beta < 0? lsx_kaiser_beta(att, tr_bw * .5 / Fc): *beta;
|
||||
att = att < 60? (att - 7.95) / (2.285 * M_PI * 2) :
|
||||
((.0007528358-1.577737e-05**beta)**beta+.6248022)**beta+.06186902;
|
||||
*num_taps = !*num_taps? (int)ceil(att/tr_bw + 1) : *num_taps;
|
||||
}
|
||||
|
||||
double * lsx_design_lpf(
|
||||
double Fp, /* End of pass-band */
|
||||
double Fs, /* Start of stop-band */
|
||||
double Fn, /* Nyquist freq; e.g. 0.5, 1, PI */
|
||||
double att, /* Stop-band attenuation in dB */
|
||||
int * num_taps, /* 0: value will be estimated */
|
||||
int k, /* >0: number of phases; <0: num_taps ≡ 1 (mod -k) */
|
||||
double beta) /* <0: value will be estimated */
|
||||
{
|
||||
int n = *num_taps, phases = max(k, 1), modulo = max(-k, 1);
|
||||
double tr_bw, Fc, rho = phases == 1? .5 : att < 120? .63 : .75;
|
||||
|
||||
Fp /= fabs(Fn), Fs /= fabs(Fn); /* Normalise to Fn = 1 */
|
||||
tr_bw = .5 * (Fs - Fp); /* Transition band-width: 6dB to stop points */
|
||||
tr_bw /= phases, Fs /= phases;
|
||||
tr_bw = min(tr_bw, .5 * Fs);
|
||||
Fc = Fs - tr_bw;
|
||||
assert(Fc - tr_bw >= 0);
|
||||
lsx_kaiser_params(att, Fc, tr_bw, &beta, num_taps);
|
||||
if (!n)
|
||||
*num_taps = phases > 1? *num_taps / phases * phases + phases - 1 :
|
||||
(*num_taps + modulo - 2) / modulo * modulo + 1;
|
||||
return Fn < 0? 0 : lsx_make_lpf(*num_taps, Fc, beta, rho, (double)phases);
|
||||
}
|
||||
|
||||
static double safe_log(double x)
|
||||
{
|
||||
assert(x >= 0);
|
||||
if (x)
|
||||
return log(x);
|
||||
lsx_debug("log(0)");
|
||||
return -26;
|
||||
}
|
||||
|
||||
void lsx_fir_to_phase(double * * h, int * len, int * post_len, double phase)
|
||||
{
|
||||
double * pi_wraps, * work, phase1 = (phase > 50 ? 100 - phase : phase) / 50;
|
||||
int i, work_len, begin, end, imp_peak = 0, peak = 0;
|
||||
double imp_sum = 0, peak_imp_sum = 0;
|
||||
double prev_angle2 = 0, cum_2pi = 0, prev_angle1 = 0, cum_1pi = 0;
|
||||
|
||||
for (i = *len, work_len = 2 * 2 * 8; i > 1; work_len <<= 1, i >>= 1);
|
||||
|
||||
work = calloc((size_t)work_len + 2, sizeof(*work)); /* +2: (UN)PACK */
|
||||
pi_wraps = malloc((((size_t)work_len + 2) / 2) * sizeof(*pi_wraps));
|
||||
|
||||
memcpy(work, *h, (size_t)*len * sizeof(*work));
|
||||
lsx_safe_rdft(work_len, 1, work); /* Cepstral: */
|
||||
LSX_UNPACK(work, work_len);
|
||||
|
||||
for (i = 0; i <= work_len; i += 2) {
|
||||
double angle = atan2(work[i + 1], work[i]);
|
||||
double detect = 2 * M_PI;
|
||||
double delta = angle - prev_angle2;
|
||||
double adjust = detect * ((delta < -detect * .7) - (delta > detect * .7));
|
||||
prev_angle2 = angle;
|
||||
cum_2pi += adjust;
|
||||
angle += cum_2pi;
|
||||
detect = M_PI;
|
||||
delta = angle - prev_angle1;
|
||||
adjust = detect * ((delta < -detect * .7) - (delta > detect * .7));
|
||||
prev_angle1 = angle;
|
||||
cum_1pi += fabs(adjust); /* fabs for when 2pi and 1pi have combined */
|
||||
pi_wraps[i >> 1] = cum_1pi;
|
||||
|
||||
work[i] = safe_log(sqrt(sqr(work[i]) + sqr(work[i + 1])));
|
||||
work[i + 1] = 0;
|
||||
}
|
||||
LSX_PACK(work, work_len);
|
||||
lsx_safe_rdft(work_len, -1, work);
|
||||
for (i = 0; i < work_len; ++i) work[i] *= 2. / work_len;
|
||||
|
||||
for (i = 1; i < work_len / 2; ++i) { /* Window to reject acausal components */
|
||||
work[i] *= 2;
|
||||
work[i + work_len / 2] = 0;
|
||||
}
|
||||
lsx_safe_rdft(work_len, 1, work);
|
||||
|
||||
for (i = 2; i < work_len; i += 2) /* Interpolate between linear & min phase */
|
||||
work[i + 1] = phase1 * i / work_len * pi_wraps[work_len >> 1] +
|
||||
(1 - phase1) * (work[i + 1] + pi_wraps[i >> 1]) - pi_wraps[i >> 1];
|
||||
|
||||
work[0] = exp(work[0]), work[1] = exp(work[1]);
|
||||
for (i = 2; i < work_len; i += 2) {
|
||||
double x = exp(work[i]);
|
||||
work[i ] = x * cos(work[i + 1]);
|
||||
work[i + 1] = x * sin(work[i + 1]);
|
||||
}
|
||||
|
||||
lsx_safe_rdft(work_len, -1, work);
|
||||
for (i = 0; i < work_len; ++i) work[i] *= 2. / work_len;
|
||||
|
||||
/* Find peak pos. */
|
||||
for (i = 0; i <= (int)(pi_wraps[work_len >> 1] / M_PI + .5); ++i) {
|
||||
imp_sum += work[i];
|
||||
if (fabs(imp_sum) > fabs(peak_imp_sum)) {
|
||||
peak_imp_sum = imp_sum;
|
||||
peak = i;
|
||||
}
|
||||
if (work[i] > work[imp_peak]) /* For debug check only */
|
||||
imp_peak = i;
|
||||
}
|
||||
while (peak && fabs(work[peak-1]) > fabs(work[peak]) && work[peak-1] * work[peak] > 0)
|
||||
--peak;
|
||||
|
||||
if (!phase1)
|
||||
begin = 0;
|
||||
else if (phase1 == 1)
|
||||
begin = peak - *len / 2;
|
||||
else {
|
||||
begin = (int)((.997 - (2 - phase1) * .22) * *len + .5);
|
||||
end = (int)((.997 + (0 - phase1) * .22) * *len + .5);
|
||||
begin = peak - (begin & ~3);
|
||||
end = peak + 1 + ((end + 3) & ~3);
|
||||
*len = end - begin;
|
||||
*h = realloc(*h, (size_t)*len * sizeof(**h));
|
||||
}
|
||||
for (i = 0; i < *len; ++i) (*h)[i] =
|
||||
work[(begin + (phase > 50 ? *len - 1 - i : i) + work_len) & (work_len - 1)];
|
||||
*post_len = phase > 50 ? peak - begin : begin + *len - (peak + 1);
|
||||
|
||||
lsx_debug("nPI=%g peak-sum@%i=%g (val@%i=%g); len=%i post=%i (%g%%)",
|
||||
pi_wraps[work_len >> 1] / M_PI, peak, peak_imp_sum, imp_peak,
|
||||
work[imp_peak], *len, *post_len, 100 - 100. * *post_len / (*len - 1));
|
||||
free(pi_wraps), free(work);
|
||||
}
|
||||
|
|
|
@ -1,39 +1,39 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#if !defined soxr_filter_included
|
||||
#define soxr_filter_included
|
||||
|
||||
#include "aliases.h"
|
||||
|
||||
double lsx_bessel_I_0(double x);
|
||||
void lsx_init_fft_cache(void);
|
||||
void lsx_clear_fft_cache(void);
|
||||
void lsx_init_fft_cache_f(void);
|
||||
void lsx_clear_fft_cache_f(void);
|
||||
#define lsx_is_power_of_2(x) !(x < 2 || (x & (x - 1)))
|
||||
void lsx_safe_rdft(int len, int type, double * d);
|
||||
void lsx_safe_cdft(int len, int type, double * d);
|
||||
void lsx_safe_rdft_f(int len, int type, float * d);
|
||||
void lsx_safe_cdft_f(int len, int type, float * d);
|
||||
void lsx_ordered_convolve(int n, void * not_used, double * a, const double * b);
|
||||
void lsx_ordered_convolve_f(int n, void * not_used, float * a, const float * b);
|
||||
void lsx_ordered_partial_convolve(int n, double * a, const double * b);
|
||||
void lsx_ordered_partial_convolve_f(int n, float * a, const float * b);
|
||||
|
||||
double lsx_kaiser_beta(double att, double tr_bw);
|
||||
double * lsx_make_lpf(int num_taps, double Fc, double beta, double rho,
|
||||
double scale);
|
||||
void lsx_kaiser_params(double att, double Fc, double tr_bw, double * beta, int * num_taps);
|
||||
double * lsx_design_lpf(
|
||||
double Fp, /* End of pass-band */
|
||||
double Fs, /* Start of stop-band */
|
||||
double Fn, /* Nyquist freq; e.g. 0.5, 1, PI; < 0: dummy run */
|
||||
double att, /* Stop-band attenuation in dB */
|
||||
int * num_taps, /* 0: value will be estimated */
|
||||
int k, /* >0: number of phases; <0: num_taps ≡ 1 (mod -k) */
|
||||
double beta); /* <0: value will be estimated */
|
||||
void lsx_fir_to_phase(double * * h, int * len,
|
||||
int * post_len, double phase0);
|
||||
|
||||
#endif
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#if !defined soxr_filter_included
|
||||
#define soxr_filter_included
|
||||
|
||||
#include "aliases.h"
|
||||
|
||||
double lsx_bessel_I_0(double x);
|
||||
void lsx_init_fft_cache(void);
|
||||
void lsx_clear_fft_cache(void);
|
||||
void lsx_init_fft_cache_f(void);
|
||||
void lsx_clear_fft_cache_f(void);
|
||||
#define lsx_is_power_of_2(x) !(x < 2 || (x & (x - 1)))
|
||||
void lsx_safe_rdft(int len, int type, double * d);
|
||||
void lsx_safe_cdft(int len, int type, double * d);
|
||||
void lsx_safe_rdft_f(int len, int type, float * d);
|
||||
void lsx_safe_cdft_f(int len, int type, float * d);
|
||||
void lsx_ordered_convolve(int n, void * not_used, double * a, const double * b);
|
||||
void lsx_ordered_convolve_f(int n, void * not_used, float * a, const float * b);
|
||||
void lsx_ordered_partial_convolve(int n, double * a, const double * b);
|
||||
void lsx_ordered_partial_convolve_f(int n, float * a, const float * b);
|
||||
|
||||
double lsx_kaiser_beta(double att, double tr_bw);
|
||||
double * lsx_make_lpf(int num_taps, double Fc, double beta, double rho,
|
||||
double scale);
|
||||
void lsx_kaiser_params(double att, double Fc, double tr_bw, double * beta, int * num_taps);
|
||||
double * lsx_design_lpf(
|
||||
double Fp, /* End of pass-band */
|
||||
double Fs, /* Start of stop-band */
|
||||
double Fn, /* Nyquist freq; e.g. 0.5, 1, PI; < 0: dummy run */
|
||||
double att, /* Stop-band attenuation in dB */
|
||||
int * num_taps, /* 0: value will be estimated */
|
||||
int k, /* >0: number of phases; <0: num_taps ≡ 1 (mod -k) */
|
||||
double beta); /* <0: value will be estimated */
|
||||
void lsx_fir_to_phase(double * * h, int * len,
|
||||
int * post_len, double phase0);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,151 +1,151 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#include "half_coefs.h"
|
||||
|
||||
#define FUNCTION h8
|
||||
#define CONVOLVE _ _ _ _ _ _ _ _
|
||||
#define h8_l 8
|
||||
#define COEFS half_fir_coefs_8
|
||||
#include "half-fir.h"
|
||||
|
||||
#define FUNCTION h9
|
||||
#define CONVOLVE _ _ _ _ _ _ _ _ _
|
||||
#define h9_l 9
|
||||
#define COEFS half_fir_coefs_9
|
||||
#include "half-fir.h"
|
||||
|
||||
#define FUNCTION h10
|
||||
#define CONVOLVE _ _ _ _ _ _ _ _ _ _
|
||||
#define h10_l 10
|
||||
#define COEFS half_fir_coefs_10
|
||||
#include "half-fir.h"
|
||||
|
||||
#define FUNCTION h11
|
||||
#define CONVOLVE _ _ _ _ _ _ _ _ _ _ _
|
||||
#define h11_l 11
|
||||
#define COEFS half_fir_coefs_11
|
||||
#include "half-fir.h"
|
||||
|
||||
#define FUNCTION h12
|
||||
#define CONVOLVE _ _ _ _ _ _ _ _ _ _ _ _
|
||||
#define h12_l 12
|
||||
#define COEFS half_fir_coefs_12
|
||||
#include "half-fir.h"
|
||||
|
||||
#define FUNCTION h13
|
||||
#define CONVOLVE _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
#define h13_l 13
|
||||
#define COEFS half_fir_coefs_13
|
||||
#include "half-fir.h"
|
||||
|
||||
static struct {int num_coefs; stage_fn_t fn; float att;} const half_firs[] = {
|
||||
{ 8, h8 , 136.51f},
|
||||
{ 9, h9 , 152.32f},
|
||||
{10, h10, 168.07f},
|
||||
{11, h11, 183.78f},
|
||||
{12, h12, 199.44f},
|
||||
{13, h13, 212.75f},
|
||||
};
|
||||
|
||||
#define HI_PREC_CLOCK
|
||||
|
||||
#define VAR_LENGTH p->n
|
||||
#define VAR_CONVOLVE while (j < FIR_LENGTH) _
|
||||
#define VAR_POLY_PHASE_BITS p->phase_bits
|
||||
|
||||
#define FUNCTION vpoly0
|
||||
#define FIR_LENGTH VAR_LENGTH
|
||||
#define CONVOLVE VAR_CONVOLVE
|
||||
#include "poly-fir0.h"
|
||||
|
||||
#define FUNCTION vpoly1
|
||||
#define COEF_INTERP 1
|
||||
#define PHASE_BITS VAR_POLY_PHASE_BITS
|
||||
#define FIR_LENGTH VAR_LENGTH
|
||||
#define CONVOLVE VAR_CONVOLVE
|
||||
#include "poly-fir.h"
|
||||
|
||||
#define FUNCTION vpoly2
|
||||
#define COEF_INTERP 2
|
||||
#define PHASE_BITS VAR_POLY_PHASE_BITS
|
||||
#define FIR_LENGTH VAR_LENGTH
|
||||
#define CONVOLVE VAR_CONVOLVE
|
||||
#include "poly-fir.h"
|
||||
|
||||
#define FUNCTION vpoly3
|
||||
#define COEF_INTERP 3
|
||||
#define PHASE_BITS VAR_POLY_PHASE_BITS
|
||||
#define FIR_LENGTH VAR_LENGTH
|
||||
#define CONVOLVE VAR_CONVOLVE
|
||||
#include "poly-fir.h"
|
||||
|
||||
#undef HI_PREC_CLOCK
|
||||
|
||||
#define U100_l 42
|
||||
#if RATE_SIMD_POLY
|
||||
#define U100_l_EXTRA _ _
|
||||
#define u100_l_EXTRA _
|
||||
#define U100_l_EXTRA_LENGTH 2
|
||||
#define u100_l_EXTRA_LENGTH 1
|
||||
#else
|
||||
#define U100_l_EXTRA
|
||||
#define u100_l_EXTRA
|
||||
#define U100_l_EXTRA_LENGTH 0
|
||||
#define u100_l_EXTRA_LENGTH 0
|
||||
#endif
|
||||
#define poly_fir_convolve_U100 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ U100_l_EXTRA
|
||||
#define FUNCTION U100_0
|
||||
#define FIR_LENGTH (U100_l + U100_l_EXTRA_LENGTH)
|
||||
#define CONVOLVE poly_fir_convolve_U100
|
||||
#include "poly-fir0.h"
|
||||
|
||||
#define u100_l 11
|
||||
#define poly_fir_convolve_u100 _ _ _ _ _ _ _ _ _ _ _ u100_l_EXTRA
|
||||
#define FUNCTION u100_0
|
||||
#define FIR_LENGTH (u100_l + u100_l_EXTRA_LENGTH)
|
||||
#define CONVOLVE poly_fir_convolve_u100
|
||||
#include "poly-fir0.h"
|
||||
|
||||
#define FUNCTION u100_1
|
||||
#define COEF_INTERP 1
|
||||
#define PHASE_BITS 8
|
||||
#define FIR_LENGTH (u100_l + u100_l_EXTRA_LENGTH)
|
||||
#define CONVOLVE poly_fir_convolve_u100
|
||||
#include "poly-fir.h"
|
||||
#define u100_1_b 8
|
||||
|
||||
#define FUNCTION u100_2
|
||||
#define COEF_INTERP 2
|
||||
#define PHASE_BITS 6
|
||||
#define FIR_LENGTH (u100_l + u100_l_EXTRA_LENGTH)
|
||||
#define CONVOLVE poly_fir_convolve_u100
|
||||
#include "poly-fir.h"
|
||||
#define u100_2_b 6
|
||||
|
||||
typedef struct {float scalar; stage_fn_t fn;} poly_fir1_t;
|
||||
typedef struct {float beta; poly_fir1_t interp[3];} poly_fir_t;
|
||||
|
||||
static poly_fir_t const poly_firs[] = {
|
||||
{-1, {{0, vpoly0}, { 7.2f, vpoly1}, {5.0f, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, { 9.4f, vpoly1}, {6.7f, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, {12.4f, vpoly1}, {7.8f, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, {13.6f, vpoly1}, {9.3f, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, {10.5f, vpoly2}, {8.4f, vpoly3}}},
|
||||
{-1, {{0, vpoly0}, {11.85f,vpoly2}, {9.0f, vpoly3}}},
|
||||
|
||||
{-1, {{0, vpoly0}, { 8.0f, vpoly1}, {5.3f, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, { 8.6f, vpoly1}, {5.7f, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, {10.6f, vpoly1}, {6.75f,vpoly2}}},
|
||||
{-1, {{0, vpoly0}, {12.6f, vpoly1}, {8.6f, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, { 9.6f, vpoly2}, {7.6f, vpoly3}}},
|
||||
{-1, {{0, vpoly0}, {11.4f, vpoly2}, {8.65f,vpoly3}}},
|
||||
|
||||
{10.62f, {{U100_l, U100_0}, {0, 0}, {0, 0}}},
|
||||
{11.28f, {{u100_l, u100_0}, {u100_1_b, u100_1}, {u100_2_b, u100_2}}},
|
||||
{-1, {{0, vpoly0}, { 9, vpoly1}, { 6, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, { 11, vpoly1}, { 7, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, { 13, vpoly1}, { 8, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, { 10, vpoly2}, { 8, vpoly3}}},
|
||||
{-1, {{0, vpoly0}, { 12, vpoly2}, { 9, vpoly3}}},
|
||||
};
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#include "half_coefs.h"
|
||||
|
||||
#define FUNCTION h8
|
||||
#define CONVOLVE _ _ _ _ _ _ _ _
|
||||
#define h8_l 8
|
||||
#define COEFS half_fir_coefs_8
|
||||
#include "half-fir.h"
|
||||
|
||||
#define FUNCTION h9
|
||||
#define CONVOLVE _ _ _ _ _ _ _ _ _
|
||||
#define h9_l 9
|
||||
#define COEFS half_fir_coefs_9
|
||||
#include "half-fir.h"
|
||||
|
||||
#define FUNCTION h10
|
||||
#define CONVOLVE _ _ _ _ _ _ _ _ _ _
|
||||
#define h10_l 10
|
||||
#define COEFS half_fir_coefs_10
|
||||
#include "half-fir.h"
|
||||
|
||||
#define FUNCTION h11
|
||||
#define CONVOLVE _ _ _ _ _ _ _ _ _ _ _
|
||||
#define h11_l 11
|
||||
#define COEFS half_fir_coefs_11
|
||||
#include "half-fir.h"
|
||||
|
||||
#define FUNCTION h12
|
||||
#define CONVOLVE _ _ _ _ _ _ _ _ _ _ _ _
|
||||
#define h12_l 12
|
||||
#define COEFS half_fir_coefs_12
|
||||
#include "half-fir.h"
|
||||
|
||||
#define FUNCTION h13
|
||||
#define CONVOLVE _ _ _ _ _ _ _ _ _ _ _ _ _
|
||||
#define h13_l 13
|
||||
#define COEFS half_fir_coefs_13
|
||||
#include "half-fir.h"
|
||||
|
||||
static struct {int num_coefs; stage_fn_t fn; float att;} const half_firs[] = {
|
||||
{ 8, h8 , 136.51f},
|
||||
{ 9, h9 , 152.32f},
|
||||
{10, h10, 168.07f},
|
||||
{11, h11, 183.78f},
|
||||
{12, h12, 199.44f},
|
||||
{13, h13, 212.75f},
|
||||
};
|
||||
|
||||
#define HI_PREC_CLOCK
|
||||
|
||||
#define VAR_LENGTH p->n
|
||||
#define VAR_CONVOLVE while (j < FIR_LENGTH) _
|
||||
#define VAR_POLY_PHASE_BITS p->phase_bits
|
||||
|
||||
#define FUNCTION vpoly0
|
||||
#define FIR_LENGTH VAR_LENGTH
|
||||
#define CONVOLVE VAR_CONVOLVE
|
||||
#include "poly-fir0.h"
|
||||
|
||||
#define FUNCTION vpoly1
|
||||
#define COEF_INTERP 1
|
||||
#define PHASE_BITS VAR_POLY_PHASE_BITS
|
||||
#define FIR_LENGTH VAR_LENGTH
|
||||
#define CONVOLVE VAR_CONVOLVE
|
||||
#include "poly-fir.h"
|
||||
|
||||
#define FUNCTION vpoly2
|
||||
#define COEF_INTERP 2
|
||||
#define PHASE_BITS VAR_POLY_PHASE_BITS
|
||||
#define FIR_LENGTH VAR_LENGTH
|
||||
#define CONVOLVE VAR_CONVOLVE
|
||||
#include "poly-fir.h"
|
||||
|
||||
#define FUNCTION vpoly3
|
||||
#define COEF_INTERP 3
|
||||
#define PHASE_BITS VAR_POLY_PHASE_BITS
|
||||
#define FIR_LENGTH VAR_LENGTH
|
||||
#define CONVOLVE VAR_CONVOLVE
|
||||
#include "poly-fir.h"
|
||||
|
||||
#undef HI_PREC_CLOCK
|
||||
|
||||
#define U100_l 42
|
||||
#if RATE_SIMD_POLY
|
||||
#define U100_l_EXTRA _ _
|
||||
#define u100_l_EXTRA _
|
||||
#define U100_l_EXTRA_LENGTH 2
|
||||
#define u100_l_EXTRA_LENGTH 1
|
||||
#else
|
||||
#define U100_l_EXTRA
|
||||
#define u100_l_EXTRA
|
||||
#define U100_l_EXTRA_LENGTH 0
|
||||
#define u100_l_EXTRA_LENGTH 0
|
||||
#endif
|
||||
#define poly_fir_convolve_U100 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ U100_l_EXTRA
|
||||
#define FUNCTION U100_0
|
||||
#define FIR_LENGTH (U100_l + U100_l_EXTRA_LENGTH)
|
||||
#define CONVOLVE poly_fir_convolve_U100
|
||||
#include "poly-fir0.h"
|
||||
|
||||
#define u100_l 11
|
||||
#define poly_fir_convolve_u100 _ _ _ _ _ _ _ _ _ _ _ u100_l_EXTRA
|
||||
#define FUNCTION u100_0
|
||||
#define FIR_LENGTH (u100_l + u100_l_EXTRA_LENGTH)
|
||||
#define CONVOLVE poly_fir_convolve_u100
|
||||
#include "poly-fir0.h"
|
||||
|
||||
#define FUNCTION u100_1
|
||||
#define COEF_INTERP 1
|
||||
#define PHASE_BITS 8
|
||||
#define FIR_LENGTH (u100_l + u100_l_EXTRA_LENGTH)
|
||||
#define CONVOLVE poly_fir_convolve_u100
|
||||
#include "poly-fir.h"
|
||||
#define u100_1_b 8
|
||||
|
||||
#define FUNCTION u100_2
|
||||
#define COEF_INTERP 2
|
||||
#define PHASE_BITS 6
|
||||
#define FIR_LENGTH (u100_l + u100_l_EXTRA_LENGTH)
|
||||
#define CONVOLVE poly_fir_convolve_u100
|
||||
#include "poly-fir.h"
|
||||
#define u100_2_b 6
|
||||
|
||||
typedef struct {float scalar; stage_fn_t fn;} poly_fir1_t;
|
||||
typedef struct {float beta; poly_fir1_t interp[3];} poly_fir_t;
|
||||
|
||||
static poly_fir_t const poly_firs[] = {
|
||||
{-1, {{0, vpoly0}, { 7.2f, vpoly1}, {5.0f, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, { 9.4f, vpoly1}, {6.7f, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, {12.4f, vpoly1}, {7.8f, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, {13.6f, vpoly1}, {9.3f, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, {10.5f, vpoly2}, {8.4f, vpoly3}}},
|
||||
{-1, {{0, vpoly0}, {11.85f,vpoly2}, {9.0f, vpoly3}}},
|
||||
|
||||
{-1, {{0, vpoly0}, { 8.0f, vpoly1}, {5.3f, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, { 8.6f, vpoly1}, {5.7f, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, {10.6f, vpoly1}, {6.75f,vpoly2}}},
|
||||
{-1, {{0, vpoly0}, {12.6f, vpoly1}, {8.6f, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, { 9.6f, vpoly2}, {7.6f, vpoly3}}},
|
||||
{-1, {{0, vpoly0}, {11.4f, vpoly2}, {8.65f,vpoly3}}},
|
||||
|
||||
{10.62f, {{U100_l, U100_0}, {0, 0}, {0, 0}}},
|
||||
{11.28f, {{u100_l, u100_0}, {u100_1_b, u100_1}, {u100_2_b, u100_2}}},
|
||||
{-1, {{0, vpoly0}, { 9, vpoly1}, { 6, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, { 11, vpoly1}, { 7, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, { 13, vpoly1}, { 8, vpoly2}}},
|
||||
{-1, {{0, vpoly0}, { 10, vpoly2}, { 8, vpoly3}}},
|
||||
{-1, {{0, vpoly0}, { 12, vpoly2}, { 9, vpoly3}}},
|
||||
};
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Down-sample by a factor of 2 using a FIR with odd length (LEN).*/
|
||||
/* Input must be preceded and followed by LEN >> 1 samples. */
|
||||
|
||||
#define _ sum += (input[-(2*j +1)] + input[(2*j +1)]) * COEFS[j], ++j;
|
||||
static void FUNCTION(stage_t * p, fifo_t * output_fifo)
|
||||
{
|
||||
sample_t const * input = stage_read_p(p);
|
||||
int i, num_out = (stage_occupancy(p) + 1) / 2;
|
||||
sample_t * output = fifo_reserve(output_fifo, num_out);
|
||||
|
||||
for (i = 0; i < num_out; ++i, input += 2) {
|
||||
int j = 0;
|
||||
sample_t sum = input[0] * .5f;
|
||||
CONVOLVE
|
||||
output[i] = sum;
|
||||
}
|
||||
fifo_read(&p->fifo, 2 * num_out, NULL);
|
||||
}
|
||||
#undef _
|
||||
#undef COEFS
|
||||
#undef CONVOLVE
|
||||
#undef FUNCTION
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Down-sample by a factor of 2 using a FIR with odd length (LEN).*/
|
||||
/* Input must be preceded and followed by LEN >> 1 samples. */
|
||||
|
||||
#define _ sum += (input[-(2*j +1)] + input[(2*j +1)]) * COEFS[j], ++j;
|
||||
static void FUNCTION(stage_t * p, fifo_t * output_fifo)
|
||||
{
|
||||
sample_t const * input = stage_read_p(p);
|
||||
int i, num_out = (stage_occupancy(p) + 1) / 2;
|
||||
sample_t * output = fifo_reserve(output_fifo, num_out);
|
||||
|
||||
for (i = 0; i < num_out; ++i, input += 2) {
|
||||
int j = 0;
|
||||
sample_t sum = input[0] * .5f;
|
||||
CONVOLVE
|
||||
output[i] = sum;
|
||||
}
|
||||
fifo_read(&p->fifo, 2 * num_out, NULL);
|
||||
}
|
||||
#undef _
|
||||
#undef COEFS
|
||||
#undef CONVOLVE
|
||||
#undef FUNCTION
|
||||
|
|
|
@ -1,57 +1,57 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#if defined __GNUC__
|
||||
#pragma GCC system_header
|
||||
#elif defined __SUNPRO_C
|
||||
#pragma disable_warn
|
||||
#elif defined _MSC_VER
|
||||
#pragma warning(push, 1)
|
||||
#endif
|
||||
|
||||
static const sample_t half_fir_coefs_8[] = {
|
||||
0.3115465451887802, -0.08734497241282892, 0.03681452335604365,
|
||||
-0.01518925831569441, 0.005454118437408876, -0.001564400922162005,
|
||||
0.0003181701445034203, -3.48001341225749e-5,
|
||||
};
|
||||
|
||||
static const sample_t half_fir_coefs_9[] = {
|
||||
0.3122703613711853, -0.08922155288172305, 0.03913974805854332,
|
||||
-0.01725059723447163, 0.006858970092378141, -0.002304518467568703,
|
||||
0.0006096426006051062, -0.0001132393923815236, 1.119795386287666e-5,
|
||||
};
|
||||
|
||||
static const sample_t half_fir_coefs_10[] = {
|
||||
0.3128545521327376, -0.09075671986104322, 0.04109637155154835,
|
||||
-0.01906629512749895, 0.008184039342054333, -0.0030766775017262,
|
||||
0.0009639607022414314, -0.0002358552746579827, 4.025184282444155e-5,
|
||||
-3.629779111541012e-6,
|
||||
};
|
||||
|
||||
static const sample_t half_fir_coefs_11[] = {
|
||||
0.3133358837508807, -0.09203588680609488, 0.04276515428384758,
|
||||
-0.02067356614745591, 0.00942253142371517, -0.003856330993895144,
|
||||
0.001363470684892284, -0.0003987400965541919, 9.058629923971627e-5,
|
||||
-1.428553070915318e-5, 1.183455238783835e-6,
|
||||
};
|
||||
|
||||
static const sample_t half_fir_coefs_12[] = {
|
||||
0.3137392991811407, -0.0931182192961332, 0.0442050575271454,
|
||||
-0.02210391200618091, 0.01057473015666001, -0.00462766983973885,
|
||||
0.001793630226239453, -0.0005961819959665878, 0.0001631475979359577,
|
||||
-3.45557865639653e-5, 5.06188341942088e-6, -3.877010943315563e-7,
|
||||
};
|
||||
|
||||
static const sample_t half_fir_coefs_13[] = {
|
||||
0.3140822554324578, -0.0940458550886253, 0.04545990399121566,
|
||||
-0.02338339450796002, 0.01164429409071052, -0.005380686021429845,
|
||||
0.002242915773871009, -0.000822047600000082, 0.0002572510962395222,
|
||||
-6.607320708956279e-5, 1.309926399120154e-5, -1.790719575255006e-6,
|
||||
1.27504961098836e-7,
|
||||
};
|
||||
|
||||
#if defined __SUNPRO_C
|
||||
#pragma enable_warn
|
||||
#elif defined _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#if defined __GNUC__
|
||||
#pragma GCC system_header
|
||||
#elif defined __SUNPRO_C
|
||||
#pragma disable_warn
|
||||
#elif defined _MSC_VER
|
||||
#pragma warning(push, 1)
|
||||
#endif
|
||||
|
||||
static const sample_t half_fir_coefs_8[] = {
|
||||
0.3115465451887802, -0.08734497241282892, 0.03681452335604365,
|
||||
-0.01518925831569441, 0.005454118437408876, -0.001564400922162005,
|
||||
0.0003181701445034203, -3.48001341225749e-5,
|
||||
};
|
||||
|
||||
static const sample_t half_fir_coefs_9[] = {
|
||||
0.3122703613711853, -0.08922155288172305, 0.03913974805854332,
|
||||
-0.01725059723447163, 0.006858970092378141, -0.002304518467568703,
|
||||
0.0006096426006051062, -0.0001132393923815236, 1.119795386287666e-5,
|
||||
};
|
||||
|
||||
static const sample_t half_fir_coefs_10[] = {
|
||||
0.3128545521327376, -0.09075671986104322, 0.04109637155154835,
|
||||
-0.01906629512749895, 0.008184039342054333, -0.0030766775017262,
|
||||
0.0009639607022414314, -0.0002358552746579827, 4.025184282444155e-5,
|
||||
-3.629779111541012e-6,
|
||||
};
|
||||
|
||||
static const sample_t half_fir_coefs_11[] = {
|
||||
0.3133358837508807, -0.09203588680609488, 0.04276515428384758,
|
||||
-0.02067356614745591, 0.00942253142371517, -0.003856330993895144,
|
||||
0.001363470684892284, -0.0003987400965541919, 9.058629923971627e-5,
|
||||
-1.428553070915318e-5, 1.183455238783835e-6,
|
||||
};
|
||||
|
||||
static const sample_t half_fir_coefs_12[] = {
|
||||
0.3137392991811407, -0.0931182192961332, 0.0442050575271454,
|
||||
-0.02210391200618091, 0.01057473015666001, -0.00462766983973885,
|
||||
0.001793630226239453, -0.0005961819959665878, 0.0001631475979359577,
|
||||
-3.45557865639653e-5, 5.06188341942088e-6, -3.877010943315563e-7,
|
||||
};
|
||||
|
||||
static const sample_t half_fir_coefs_13[] = {
|
||||
0.3140822554324578, -0.0940458550886253, 0.04545990399121566,
|
||||
-0.02338339450796002, 0.01164429409071052, -0.005380686021429845,
|
||||
0.002242915773871009, -0.000822047600000082, 0.0002572510962395222,
|
||||
-6.607320708956279e-5, 1.309926399120154e-5, -1.790719575255006e-6,
|
||||
1.27504961098836e-7,
|
||||
};
|
||||
|
||||
#if defined __SUNPRO_C
|
||||
#pragma enable_warn
|
||||
#elif defined _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
|
|
@ -1,46 +1,46 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#if !defined soxr_internal_included
|
||||
#define soxr_internal_included
|
||||
|
||||
#include "soxr-config.h"
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
#define min(a, b) ((a) <= (b) ? (a) : (b))
|
||||
#define max(a, b) ((a) >= (b) ? (a) : (b))
|
||||
|
||||
#define range_limit(x, lower, upper) (min(max(x, lower), upper))
|
||||
#define linear_to_dB(x) (log10(x) * 20)
|
||||
#define array_length(a) (sizeof(a)/sizeof(a[0]))
|
||||
#define AL(a) array_length(a)
|
||||
#define iAL(a) (int)AL(a)
|
||||
#define sqr(a) ((a) * (a))
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define UNUSED __attribute__ ((unused))
|
||||
#else
|
||||
#define UNUSED
|
||||
#endif
|
||||
|
||||
#if defined NDEBUG
|
||||
#ifdef __GNUC__
|
||||
void lsx_dummy(char const *, ...);
|
||||
#else
|
||||
static __inline void lsx_dummy(char const * x, ...) {}
|
||||
#endif
|
||||
#define lsx_debug if(0) lsx_dummy
|
||||
#else
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
UNUSED static void lsx_debug(char const * fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
fputc('\n', stderr);
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#if !defined soxr_internal_included
|
||||
#define soxr_internal_included
|
||||
|
||||
#include "soxr-config.h"
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
#define min(a, b) ((a) <= (b) ? (a) : (b))
|
||||
#define max(a, b) ((a) >= (b) ? (a) : (b))
|
||||
|
||||
#define range_limit(x, lower, upper) (min(max(x, lower), upper))
|
||||
#define linear_to_dB(x) (log10(x) * 20)
|
||||
#define array_length(a) (sizeof(a)/sizeof(a[0]))
|
||||
#define AL(a) array_length(a)
|
||||
#define iAL(a) (int)AL(a)
|
||||
#define sqr(a) ((a) * (a))
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define UNUSED __attribute__ ((unused))
|
||||
#else
|
||||
#define UNUSED
|
||||
#endif
|
||||
|
||||
#if defined NDEBUG
|
||||
#ifdef __GNUC__
|
||||
void lsx_dummy(char const *, ...);
|
||||
#else
|
||||
static __inline void lsx_dummy(char const * x, ...) {}
|
||||
#endif
|
||||
#define lsx_debug if(0) lsx_dummy
|
||||
#else
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
UNUSED static void lsx_debug(char const * fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vfprintf(stderr, fmt, args);
|
||||
fputc('\n', stderr);
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
set(TARGET_HEADERS "@TARGET_HEADERS@")
|
||||
set(TARGET_PCS "@TARGET_PCS@")
|
||||
set(TARGET_HEADERS "@TARGET_HEADERS@")
|
||||
set(TARGET_PCS "@TARGET_PCS@")
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
prefix=${CMAKE_INSTALL_PREFIX}
|
||||
exec_prefix=${CMAKE_INSTALL_PREFIX}
|
||||
libdir=${LIB_INSTALL_DIR}
|
||||
includedir=${INCLUDE_INSTALL_DIR}
|
||||
|
||||
Name: lib${LSR}
|
||||
Description: ${DESCRIPTION_SUMMARY} (with libsamplerate-like bindings)
|
||||
Requires: libsoxr
|
||||
Version: ${PROJECT_VERSION}
|
||||
Libs: -L${LIB_INSTALL_DIR} -l${LSR}
|
||||
Cflags: -I${INCLUDE_INSTALL_DIR}
|
|
@ -1,11 +0,0 @@
|
|||
prefix=${CMAKE_INSTALL_PREFIX}
|
||||
exec_prefix=${CMAKE_INSTALL_PREFIX}
|
||||
libdir=${LIB_INSTALL_DIR}
|
||||
includedir=${INCLUDE_INSTALL_DIR}
|
||||
|
||||
Name: lib${PROJECT_NAME}
|
||||
Description: ${DESCRIPTION_SUMMARY}
|
||||
Requires:
|
||||
Version: ${PROJECT_VERSION}
|
||||
Libs: -L${LIB_INSTALL_DIR} -l${PROJECT_NAME}
|
||||
Cflags: -I${INCLUDE_INSTALL_DIR}
|
|
@ -1 +1 @@
|
|||
set(TARGET_LIBS "@TARGET_LIBS@")
|
||||
set(TARGET_LIBS "@TARGET_LIBS@")
|
||||
|
|
|
@ -1,114 +1,114 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Wrapper mostly compatible with `libsamplerate'. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include "soxr.h"
|
||||
|
||||
/* Runtime casts: */
|
||||
typedef struct io_t {
|
||||
float *in,*out; long ilen,olen,idone,odone; int eoi; double oi_ratio;} io_t;
|
||||
#define SRC_DATA io_t
|
||||
typedef struct soxr SRC_STATE;
|
||||
#define src_callback_t soxr_input_fn_t
|
||||
#define SRC_ERROR soxr_error_t
|
||||
#define SRC_SRCTYPE unsigned
|
||||
|
||||
#include "soxr-lsr.h"
|
||||
#include "rint.h"
|
||||
|
||||
|
||||
soxr_error_t src_simple(io_t * p, unsigned id, int channels)
|
||||
{
|
||||
size_t idone, odone;
|
||||
soxr_error_t error;
|
||||
soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_LSR0Q + id, 0);
|
||||
char const * e = getenv("SOXR_LSR_NUM_THREADS");
|
||||
soxr_runtime_spec_t r_spec = soxr_runtime_spec(!(e && atoi(e) != 1));
|
||||
assert (channels > 0);
|
||||
assert (p->ilen >= 0);
|
||||
assert (p->olen >= 0);
|
||||
error = soxr_oneshot(1, p->oi_ratio, (unsigned)channels,
|
||||
p->in, (size_t)p->ilen, &idone, p->out, (size_t)p->olen, &odone,
|
||||
0, &q_spec, &r_spec);
|
||||
p->idone = (long)idone, p->odone = (long)odone;
|
||||
return error;
|
||||
}
|
||||
|
||||
soxr_t src_callback_new(soxr_input_fn_t fn, unsigned id, int channels, SRC_ERROR * error0, void * p)
|
||||
{
|
||||
soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_LSR0Q + id, 0);
|
||||
char const * e = getenv("SOXR_LSR_NUM_THREADS");
|
||||
soxr_runtime_spec_t r_spec = soxr_runtime_spec(!(e && atoi(e) != 1));
|
||||
soxr_error_t error;
|
||||
soxr_t soxr = 0;
|
||||
assert (channels > 0);
|
||||
/* To minimise latency e.g. for real-time playback:
|
||||
if (id == 2)
|
||||
r_spec.log2_large_dft_size = r_spec.log2_min_dft_size = 8;
|
||||
*/
|
||||
soxr = soxr_create(0, 0, (unsigned)channels, &error, 0, &q_spec, &r_spec);
|
||||
if (soxr)
|
||||
error = soxr_set_input_fn(soxr, fn, p, 0);
|
||||
*(int *)error0 = (int)(long)error;
|
||||
return soxr;
|
||||
}
|
||||
|
||||
soxr_error_t src_process(soxr_t p, io_t * io)
|
||||
{
|
||||
if (!p || !io) return "null pointer";
|
||||
soxr_set_error(p, soxr_set_io_ratio(p, 1/io->oi_ratio, (size_t)io->olen));
|
||||
|
||||
{ size_t idone , odone;
|
||||
soxr_process(p, io->in, (size_t)(io->eoi? ~io->ilen : io->ilen), /* hack */
|
||||
&idone, io->out, (size_t)io->olen, &odone);
|
||||
io->idone = (long)idone, io->odone = (long)odone;
|
||||
return soxr_error(p); }
|
||||
}
|
||||
|
||||
long src_callback_read(soxr_t p, double oi_ratio, long olen, float * obuf)
|
||||
{
|
||||
if (!p || olen < 0) return -1;
|
||||
soxr_set_error(p, soxr_set_io_ratio(p, 1/oi_ratio, (size_t)olen));
|
||||
return (long)soxr_output(p, obuf, (size_t)olen);
|
||||
}
|
||||
|
||||
void src_float_to_short_array(float const * src, short * dest, int len)
|
||||
{
|
||||
double d, N = 1. + SHRT_MAX;
|
||||
assert (src && dest);
|
||||
while (len--) d = src[len] * N, dest[len] = (short)(d > N - 1? (short)(N - 1) : d < -N? (short)-N : rint16(d));
|
||||
}
|
||||
|
||||
void src_short_to_float_array(short const * src, float * dest, int len)
|
||||
{
|
||||
assert (src && dest);
|
||||
while (len--) dest[len] = (float)(src[len] * (1 / (1. + SHRT_MAX)));
|
||||
}
|
||||
|
||||
void src_float_to_int_array(float const * src, int * dest, int len)
|
||||
{
|
||||
double d, N = 32768. * 65536.; /* N.B. int32, not int! (Also next fn.) */
|
||||
assert (src && dest);
|
||||
while (len--) d = src[len] * N, dest[len] = d >= N - 1? (int)(N - 1) : d < -N? (int)(-N) : rint32(d);
|
||||
}
|
||||
|
||||
void src_int_to_float_array(int const * src, float * dest, int len)
|
||||
{
|
||||
assert (src && dest);
|
||||
while (len--) dest[len] = (float)(src[len] * (1 / (32768. * 65536.)));
|
||||
}
|
||||
|
||||
static char const * const names[] = {"LSR best sinc", "LSR medium sinc", "LSR fastest sinc", "LSR ZOH", "LSR linear", "SoX VHQ"};
|
||||
char const * src_get_name(unsigned n) {return n < 5u + !getenv("SOXR_LSR_STRICT")? names[n] : 0;}
|
||||
char const * src_get_description(unsigned id) {return src_get_name(id);}
|
||||
char const * src_get_version(void) {return soxr_version();}
|
||||
char const * src_strerror(soxr_error_t error) {return error == (soxr_error_t)1? "Placeholder." : soxr_strerror(error);}
|
||||
int src_is_valid_ratio(double oi_ratio) {return getenv("SOXR_LSR_STRICT")? oi_ratio >= 1./256 && oi_ratio <= 256 : oi_ratio > 0;}
|
||||
soxr_error_t src_error(soxr_t p) {return soxr_error(p);}
|
||||
soxr_error_t src_reset(soxr_t p) {return soxr_clear(p);}
|
||||
soxr_t src_delete(soxr_t p) {soxr_delete(p); return 0;}
|
||||
soxr_error_t src_set_ratio(soxr_t p, double oi_ratio) {return soxr_set_io_ratio(p, 1/oi_ratio, 0);}
|
||||
soxr_t src_new(unsigned id, int channels, SRC_ERROR * error) {return src_callback_new(0, id, channels, error, 0);}
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Wrapper mostly compatible with `libsamplerate'. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include "soxr.h"
|
||||
|
||||
/* Runtime casts: */
|
||||
typedef struct io_t {
|
||||
float *in,*out; long ilen,olen,idone,odone; int eoi; double oi_ratio;} io_t;
|
||||
#define SRC_DATA io_t
|
||||
typedef struct soxr SRC_STATE;
|
||||
#define src_callback_t soxr_input_fn_t
|
||||
#define SRC_ERROR soxr_error_t
|
||||
#define SRC_SRCTYPE unsigned
|
||||
|
||||
#include "soxr-lsr.h"
|
||||
#include "rint.h"
|
||||
|
||||
soxr_error_t src_simple(io_t * p, unsigned id, int channels)
|
||||
{
|
||||
size_t idone, odone;
|
||||
soxr_error_t error;
|
||||
soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_LSR0Q + id, 0);
|
||||
char const * e = getenv("SOXR_LSR_NUM_THREADS");
|
||||
soxr_runtime_spec_t r_spec = soxr_runtime_spec(!(e && atoi(e) != 1));
|
||||
assert (channels > 0);
|
||||
assert (p->ilen >= 0);
|
||||
assert (p->olen >= 0);
|
||||
error = soxr_oneshot(1, p->oi_ratio, (unsigned)channels,
|
||||
p->in, (size_t)p->ilen, &idone, p->out, (size_t)p->olen, &odone,
|
||||
0, &q_spec, &r_spec);
|
||||
p->idone = (long)idone, p->odone = (long)odone;
|
||||
return error;
|
||||
}
|
||||
|
||||
soxr_t src_callback_new(soxr_input_fn_t fn, unsigned id, int channels, SRC_ERROR * error0, void * p)
|
||||
{
|
||||
soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_LSR0Q + id, 0);
|
||||
char const * e = getenv("SOXR_LSR_NUM_THREADS");
|
||||
soxr_runtime_spec_t r_spec = soxr_runtime_spec(!(e && atoi(e) != 1));
|
||||
soxr_error_t error;
|
||||
soxr_t soxr = 0;
|
||||
assert (channels > 0);
|
||||
/* To minimise latency e.g. for real-time playback:
|
||||
if (id == 2)
|
||||
r_spec.log2_large_dft_size = r_spec.log2_min_dft_size = 8;
|
||||
*/
|
||||
soxr = soxr_create(0, 0, (unsigned)channels, &error, 0, &q_spec, &r_spec);
|
||||
if (soxr)
|
||||
error = soxr_set_input_fn(soxr, fn, p, 0);
|
||||
if (error0)
|
||||
*(int *)error0 = (int)(ptrdiff_t)error;
|
||||
return soxr;
|
||||
}
|
||||
|
||||
soxr_error_t src_process(soxr_t p, io_t * io)
|
||||
{
|
||||
if (!p || !io) return "null pointer";
|
||||
soxr_set_error(p, soxr_set_io_ratio(p, 1/io->oi_ratio, (size_t)io->olen));
|
||||
|
||||
{ size_t idone , odone;
|
||||
soxr_process(p, io->in, (size_t)(io->eoi? ~io->ilen : io->ilen), /* hack */
|
||||
&idone, io->out, (size_t)io->olen, &odone);
|
||||
io->idone = (long)idone, io->odone = (long)odone;
|
||||
return soxr_error(p); }
|
||||
}
|
||||
|
||||
long src_callback_read(soxr_t p, double oi_ratio, long olen, float * obuf)
|
||||
{
|
||||
if (!p || olen < 0) return -1;
|
||||
soxr_set_error(p, soxr_set_io_ratio(p, 1/oi_ratio, (size_t)olen));
|
||||
return (long)soxr_output(p, obuf, (size_t)olen);
|
||||
}
|
||||
|
||||
void src_float_to_short_array(float const * src, short * dest, int len)
|
||||
{
|
||||
double d, N = 1. + SHRT_MAX;
|
||||
assert (src && dest);
|
||||
while (len--) d = src[len] * N, dest[len] = (short)(d > N - 1? (short)(N - 1) : d < -N? (short)-N : rint16(d));
|
||||
}
|
||||
|
||||
void src_short_to_float_array(short const * src, float * dest, int len)
|
||||
{
|
||||
assert (src && dest);
|
||||
while (len--) dest[len] = (float)(src[len] * (1 / (1. + SHRT_MAX)));
|
||||
}
|
||||
|
||||
void src_float_to_int_array(float const * src, int * dest, int len)
|
||||
{
|
||||
double d, N = 32768. * 65536.; /* N.B. int32, not int! (Also next fn.) */
|
||||
assert (src && dest);
|
||||
while (len--) d = src[len] * N, dest[len] = d >= N - 1? (int)(N - 1) : d < -N? (int)(-N) : rint32(d);
|
||||
}
|
||||
|
||||
void src_int_to_float_array(int const * src, float * dest, int len)
|
||||
{
|
||||
assert (src && dest);
|
||||
while (len--) dest[len] = (float)(src[len] * (1 / (32768. * 65536.)));
|
||||
}
|
||||
|
||||
static char const * const names[] = {"LSR best sinc", "LSR medium sinc", "LSR fastest sinc", "LSR ZOH", "LSR linear", "SoX VHQ"};
|
||||
char const * src_get_name(unsigned n) {return n < 5u + !getenv("SOXR_LSR_STRICT")? names[n] : 0;}
|
||||
char const * src_get_description(unsigned id) {return src_get_name(id);}
|
||||
char const * src_get_version(void) {return soxr_version();}
|
||||
char const * src_strerror(soxr_error_t error) {return error == (soxr_error_t)1? "Placeholder." : sizeof(int) >= sizeof(char *) || !error ? soxr_strerror(error) : "soxr error";}
|
||||
int src_is_valid_ratio(double oi_ratio) {return getenv("SOXR_LSR_STRICT")? oi_ratio >= 1./256 && oi_ratio <= 256 : oi_ratio > 0;}
|
||||
soxr_error_t src_error(soxr_t p) {return soxr_error(p);}
|
||||
soxr_error_t src_reset(soxr_t p) {return soxr_clear(p);}
|
||||
soxr_t src_delete(soxr_t p) {soxr_delete(p); return 0;}
|
||||
soxr_error_t src_set_ratio(soxr_t p, double oi_ratio) {return soxr_set_io_ratio(p, 1/oi_ratio, 0);}
|
||||
soxr_t src_new(unsigned id, int channels, SRC_ERROR * error) {return src_callback_new(0, id, channels, error, 0);}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,177 +1,177 @@
|
|||
/* Copyright (c) 2011 Julien Pommier ( pommier@modartt.com )
|
||||
|
||||
Based on original fortran 77 code from FFTPACKv4 from NETLIB,
|
||||
authored by Dr Paul Swarztrauber of NCAR, in 1985.
|
||||
|
||||
As confirmed by the NCAR fftpack software curators, the following
|
||||
FFTPACKv5 license applies to FFTPACKv4 sources. My changes are
|
||||
released under the same terms.
|
||||
|
||||
FFTPACK license:
|
||||
|
||||
http://www.cisl.ucar.edu/css/software/fftpack5/ftpk.html
|
||||
|
||||
Copyright (c) 2004 the University Corporation for Atmospheric
|
||||
Research ("UCAR"). All rights reserved. Developed by NCAR's
|
||||
Computational and Information Systems Laboratory, UCAR,
|
||||
www.cisl.ucar.edu.
|
||||
|
||||
Redistribution and use of the Software in source and binary forms,
|
||||
with or without modification, is permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
- Neither the names of NCAR's Computational and Information Systems
|
||||
Laboratory, the University Corporation for Atmospheric Research,
|
||||
nor the names of its sponsors or contributors may be used to
|
||||
endorse or promote products derived from this Software without
|
||||
specific prior written permission.
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notices, this list of conditions, and the disclaimer below.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions, and the disclaimer below in the
|
||||
documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
PFFFT : a Pretty Fast FFT.
|
||||
|
||||
This is basically an adaptation of the single precision fftpack
|
||||
(v4) as found on netlib taking advantage of SIMD instruction found
|
||||
on cpus such as intel x86 (SSE1), powerpc (Altivec), and arm (NEON).
|
||||
|
||||
For architectures where no SIMD instruction is available, the code
|
||||
falls back to a scalar version.
|
||||
|
||||
Restrictions:
|
||||
|
||||
- 1D transforms only, with 32-bit single precision.
|
||||
|
||||
- supports only transforms for inputs of length N of the form
|
||||
N=(2^a)*(3^b), a >= 5 and b >=0 (32, 48, 64, 96, 128, 144 etc
|
||||
are all acceptable lengths). Performance is best for 128<=N<=8192.
|
||||
|
||||
- all (float*) pointers in the functions below are expected to
|
||||
have an "simd-compatible" alignment, that is 16 bytes on x86 and
|
||||
powerpc CPUs.
|
||||
|
||||
You can allocate such buffers with the functions
|
||||
pffft_aligned_malloc / pffft_aligned_free (or with stuff like
|
||||
posix_memalign..)
|
||||
|
||||
*/
|
||||
|
||||
#ifndef PFFFT_H
|
||||
#define PFFFT_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* opaque struct holding internal stuff (precomputed twiddle factors)
|
||||
this struct can be shared by many threads as it contains only
|
||||
read-only data.
|
||||
*/
|
||||
typedef struct PFFFT_Setup PFFFT_Setup;
|
||||
|
||||
/* direction of the transform */
|
||||
typedef enum { PFFFT_FORWARD, PFFFT_BACKWARD } pffft_direction_t;
|
||||
|
||||
/* type of transform */
|
||||
typedef enum { PFFFT_REAL, PFFFT_COMPLEX } pffft_transform_t;
|
||||
|
||||
/*
|
||||
prepare for performing transforms of size N -- the returned
|
||||
PFFFT_Setup structure is read-only so it can safely be shared by
|
||||
multiple concurrent threads.
|
||||
*/
|
||||
static PFFFT_Setup *pffft_new_setup(int N, pffft_transform_t transform);
|
||||
static void pffft_destroy_setup(PFFFT_Setup *);
|
||||
/*
|
||||
Perform a Fourier transform , The z-domain data is stored in the
|
||||
most efficient order for transforming it back, or using it for
|
||||
convolution. If you need to have its content sorted in the
|
||||
"usual" way, that is as an array of interleaved complex numbers,
|
||||
either use pffft_transform_ordered , or call pffft_zreorder after
|
||||
the forward fft, and before the backward fft.
|
||||
|
||||
Transforms are not scaled: PFFFT_BACKWARD(PFFFT_FORWARD(x)) = N*x.
|
||||
Typically you will want to scale the backward transform by 1/N.
|
||||
|
||||
The 'work' pointer should point to an area of N (2*N for complex
|
||||
fft) floats, properly aligned. [del]If 'work' is NULL, then stack will
|
||||
be used instead (this is probably the beest strategy for small
|
||||
FFTs, say for N < 16384).[/del]
|
||||
|
||||
input and output may alias.
|
||||
*/
|
||||
static void pffft_transform(PFFFT_Setup *setup, const float *input, float *output, float *work, pffft_direction_t direction);
|
||||
|
||||
/*
|
||||
Similar to pffft_transform, but makes sure that the output is
|
||||
ordered as expected (interleaved complex numbers). This is
|
||||
similar to calling pffft_transform and then pffft_zreorder.
|
||||
|
||||
input and output may alias.
|
||||
*/
|
||||
static void pffft_transform_ordered(PFFFT_Setup *setup, const float *input, float *output, float *work, pffft_direction_t direction);
|
||||
|
||||
/*
|
||||
call pffft_zreorder(.., PFFFT_FORWARD) after pffft_transform(...,
|
||||
PFFFT_FORWARD) if you want to have the frequency components in
|
||||
the correct "canonical" order, as interleaved complex numbers.
|
||||
|
||||
(for real transforms, both 0-frequency and half frequency
|
||||
components, which are real, are assembled in the first entry as
|
||||
F(0)+i*F(n/2+1). Note that the original fftpack did place
|
||||
F(n/2+1) at the end of the arrays).
|
||||
|
||||
input and output should not alias.
|
||||
*/
|
||||
static void pffft_zreorder(PFFFT_Setup *setup, const float *input, float *output, pffft_direction_t direction);
|
||||
|
||||
/*
|
||||
Perform a multiplication of the frequency components of dft_a and
|
||||
dft_b and accumulate them into dft_ab. The arrays should have
|
||||
been obtained with pffft_transform(.., PFFFT_FORWARD) and should
|
||||
*not* have been reordered with pffft_zreorder (otherwise just
|
||||
perform the operation yourself as the dft coefs are stored as
|
||||
interleaved complex numbers).
|
||||
|
||||
the operation performed is: dft_ab += (dft_a * fdt_b)*scaling
|
||||
|
||||
The dft_a, dft_b and dft_ab pointers may alias.
|
||||
void pffft_zconvolve_accumulate(PFFFT_Setup *setup, const float *dft_a, const float *dft_b, float *dft_ab, float scaling);
|
||||
*/
|
||||
|
||||
/*
|
||||
the operation performed is: dft_ab = (dft_a * fdt_b)
|
||||
|
||||
The dft_a, dft_b and dft_ab pointers may alias.
|
||||
*/
|
||||
static void pffft_zconvolve(PFFFT_Setup *setup, const float *dft_a, const float *dft_b, float *dft_ab);
|
||||
|
||||
/* return 4 or 1 wether support SSE/Altivec instructions was enable when building pffft.c */
|
||||
int pffft_simd_size(void);
|
||||
|
||||
static void pffft_reorder_back(int length, void * setup, float * data, float * work);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/* Copyright (c) 2011 Julien Pommier ( pommier@modartt.com )
|
||||
|
||||
Based on original fortran 77 code from FFTPACKv4 from NETLIB,
|
||||
authored by Dr Paul Swarztrauber of NCAR, in 1985.
|
||||
|
||||
As confirmed by the NCAR fftpack software curators, the following
|
||||
FFTPACKv5 license applies to FFTPACKv4 sources. My changes are
|
||||
released under the same terms.
|
||||
|
||||
FFTPACK license:
|
||||
|
||||
http://www.cisl.ucar.edu/css/software/fftpack5/ftpk.html
|
||||
|
||||
Copyright (c) 2004 the University Corporation for Atmospheric
|
||||
Research ("UCAR"). All rights reserved. Developed by NCAR's
|
||||
Computational and Information Systems Laboratory, UCAR,
|
||||
www.cisl.ucar.edu.
|
||||
|
||||
Redistribution and use of the Software in source and binary forms,
|
||||
with or without modification, is permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
- Neither the names of NCAR's Computational and Information Systems
|
||||
Laboratory, the University Corporation for Atmospheric Research,
|
||||
nor the names of its sponsors or contributors may be used to
|
||||
endorse or promote products derived from this Software without
|
||||
specific prior written permission.
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notices, this list of conditions, and the disclaimer below.
|
||||
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions, and the disclaimer below in the
|
||||
documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
PFFFT : a Pretty Fast FFT.
|
||||
|
||||
This is basically an adaptation of the single precision fftpack
|
||||
(v4) as found on netlib taking advantage of SIMD instruction found
|
||||
on cpus such as intel x86 (SSE1), powerpc (Altivec), and arm (NEON).
|
||||
|
||||
For architectures where no SIMD instruction is available, the code
|
||||
falls back to a scalar version.
|
||||
|
||||
Restrictions:
|
||||
|
||||
- 1D transforms only, with 32-bit single precision.
|
||||
|
||||
- supports only transforms for inputs of length N of the form
|
||||
N=(2^a)*(3^b), a >= 5 and b >=0 (32, 48, 64, 96, 128, 144 etc
|
||||
are all acceptable lengths). Performance is best for 128<=N<=8192.
|
||||
|
||||
- all (float*) pointers in the functions below are expected to
|
||||
have an "simd-compatible" alignment, that is 16 bytes on x86 and
|
||||
powerpc CPUs.
|
||||
|
||||
You can allocate such buffers with the functions
|
||||
pffft_aligned_malloc / pffft_aligned_free (or with stuff like
|
||||
posix_memalign..)
|
||||
|
||||
*/
|
||||
|
||||
#ifndef PFFFT_H
|
||||
#define PFFFT_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* opaque struct holding internal stuff (precomputed twiddle factors)
|
||||
this struct can be shared by many threads as it contains only
|
||||
read-only data.
|
||||
*/
|
||||
typedef struct PFFFT_Setup PFFFT_Setup;
|
||||
|
||||
/* direction of the transform */
|
||||
typedef enum { PFFFT_FORWARD, PFFFT_BACKWARD } pffft_direction_t;
|
||||
|
||||
/* type of transform */
|
||||
typedef enum { PFFFT_REAL, PFFFT_COMPLEX } pffft_transform_t;
|
||||
|
||||
/*
|
||||
prepare for performing transforms of size N -- the returned
|
||||
PFFFT_Setup structure is read-only so it can safely be shared by
|
||||
multiple concurrent threads.
|
||||
*/
|
||||
static PFFFT_Setup *pffft_new_setup(int N, pffft_transform_t transform);
|
||||
static void pffft_destroy_setup(PFFFT_Setup *);
|
||||
/*
|
||||
Perform a Fourier transform , The z-domain data is stored in the
|
||||
most efficient order for transforming it back, or using it for
|
||||
convolution. If you need to have its content sorted in the
|
||||
"usual" way, that is as an array of interleaved complex numbers,
|
||||
either use pffft_transform_ordered , or call pffft_zreorder after
|
||||
the forward fft, and before the backward fft.
|
||||
|
||||
Transforms are not scaled: PFFFT_BACKWARD(PFFFT_FORWARD(x)) = N*x.
|
||||
Typically you will want to scale the backward transform by 1/N.
|
||||
|
||||
The 'work' pointer should point to an area of N (2*N for complex
|
||||
fft) floats, properly aligned. [del]If 'work' is NULL, then stack will
|
||||
be used instead (this is probably the beest strategy for small
|
||||
FFTs, say for N < 16384).[/del]
|
||||
|
||||
input and output may alias.
|
||||
*/
|
||||
static void pffft_transform(PFFFT_Setup *setup, const float *input, float *output, float *work, pffft_direction_t direction);
|
||||
|
||||
/*
|
||||
Similar to pffft_transform, but makes sure that the output is
|
||||
ordered as expected (interleaved complex numbers). This is
|
||||
similar to calling pffft_transform and then pffft_zreorder.
|
||||
|
||||
input and output may alias.
|
||||
*/
|
||||
static void pffft_transform_ordered(PFFFT_Setup *setup, const float *input, float *output, float *work, pffft_direction_t direction);
|
||||
|
||||
/*
|
||||
call pffft_zreorder(.., PFFFT_FORWARD) after pffft_transform(...,
|
||||
PFFFT_FORWARD) if you want to have the frequency components in
|
||||
the correct "canonical" order, as interleaved complex numbers.
|
||||
|
||||
(for real transforms, both 0-frequency and half frequency
|
||||
components, which are real, are assembled in the first entry as
|
||||
F(0)+i*F(n/2+1). Note that the original fftpack did place
|
||||
F(n/2+1) at the end of the arrays).
|
||||
|
||||
input and output should not alias.
|
||||
*/
|
||||
static void pffft_zreorder(PFFFT_Setup *setup, const float *input, float *output, pffft_direction_t direction);
|
||||
|
||||
/*
|
||||
Perform a multiplication of the frequency components of dft_a and
|
||||
dft_b and accumulate them into dft_ab. The arrays should have
|
||||
been obtained with pffft_transform(.., PFFFT_FORWARD) and should
|
||||
*not* have been reordered with pffft_zreorder (otherwise just
|
||||
perform the operation yourself as the dft coefs are stored as
|
||||
interleaved complex numbers).
|
||||
|
||||
the operation performed is: dft_ab += (dft_a * fdt_b)*scaling
|
||||
|
||||
The dft_a, dft_b and dft_ab pointers may alias.
|
||||
void pffft_zconvolve_accumulate(PFFFT_Setup *setup, const float *dft_a, const float *dft_b, float *dft_ab, float scaling);
|
||||
*/
|
||||
|
||||
/*
|
||||
the operation performed is: dft_ab = (dft_a * fdt_b)
|
||||
|
||||
The dft_a, dft_b and dft_ab pointers may alias.
|
||||
*/
|
||||
static void pffft_zconvolve(PFFFT_Setup *setup, const float *dft_a, const float *dft_b, float *dft_ab);
|
||||
|
||||
/* return 4 or 1 wether support SSE/Altivec instructions was enable when building pffft.c */
|
||||
int pffft_simd_size(void);
|
||||
|
||||
static void pffft_reorder_back(int length, void * setup, float * data, float * work);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,30 +1,32 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#define PFFFT_SIMD_DISABLE
|
||||
#include "pffft.c"
|
||||
#include "filter.h"
|
||||
|
||||
static void * setup(int len) {return pffft_new_setup(len, PFFFT_REAL);}
|
||||
static void delete_setup(void * setup) {pffft_destroy_setup(setup);}
|
||||
static void forward (int length, void * setup, float * h, float * scratch) {pffft_transform (setup, h, h, scratch, PFFFT_FORWARD); (void)length;}
|
||||
static void oforward (int length, void * setup, float * h, float * scratch) {pffft_transform_ordered(setup, h, h, scratch, PFFFT_FORWARD); (void)length;}
|
||||
static void backward (int length, void * setup, float * H, float * scratch) {pffft_transform (setup, H, H, scratch, PFFFT_BACKWARD);(void)length;}
|
||||
static void obackward(int length, void * setup, float * H, float * scratch) {pffft_transform_ordered(setup, H, H, scratch, PFFFT_BACKWARD);(void)length;}
|
||||
static void convolve(int length, void * setup, float * H, float const * with) { pffft_zconvolve(setup, H, with, H); (void)length;}
|
||||
static int multiplier(void) {return 1;}
|
||||
|
||||
typedef void (* fn_t)(void);
|
||||
fn_t _soxr_rdft32_cb[] = {
|
||||
(fn_t)setup,
|
||||
(fn_t)setup,
|
||||
(fn_t)delete_setup,
|
||||
(fn_t)forward,
|
||||
(fn_t)oforward,
|
||||
(fn_t)backward,
|
||||
(fn_t)obackward,
|
||||
(fn_t)convolve,
|
||||
(fn_t)_soxr_ordered_partial_convolve_f,
|
||||
(fn_t)multiplier,
|
||||
(fn_t)pffft_reorder_back,
|
||||
};
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#define _soxr_simd_aligned_free free
|
||||
#define _soxr_simd_aligned_malloc malloc
|
||||
#define PFFFT_SIMD_DISABLE
|
||||
#include "pffft.c"
|
||||
#include "filter.h"
|
||||
|
||||
static void * setup(int len) {return pffft_new_setup(len, PFFFT_REAL);}
|
||||
static void delete_setup(void * setup) {pffft_destroy_setup(setup);}
|
||||
static void forward (int length, void * setup, float * h, float * scratch) {pffft_transform (setup, h, h, scratch, PFFFT_FORWARD); (void)length;}
|
||||
static void oforward (int length, void * setup, float * h, float * scratch) {pffft_transform_ordered(setup, h, h, scratch, PFFFT_FORWARD); (void)length;}
|
||||
static void backward (int length, void * setup, float * H, float * scratch) {pffft_transform (setup, H, H, scratch, PFFFT_BACKWARD);(void)length;}
|
||||
static void obackward(int length, void * setup, float * H, float * scratch) {pffft_transform_ordered(setup, H, H, scratch, PFFFT_BACKWARD);(void)length;}
|
||||
static void convolve(int length, void * setup, float * H, float const * with) { pffft_zconvolve(setup, H, with, H); (void)length;}
|
||||
static int multiplier(void) {return 1;}
|
||||
|
||||
typedef void (* fn_t)(void);
|
||||
fn_t _soxr_rdft32_cb[] = {
|
||||
(fn_t)setup,
|
||||
(fn_t)setup,
|
||||
(fn_t)delete_setup,
|
||||
(fn_t)forward,
|
||||
(fn_t)oforward,
|
||||
(fn_t)backward,
|
||||
(fn_t)obackward,
|
||||
(fn_t)convolve,
|
||||
(fn_t)_soxr_ordered_partial_convolve_f,
|
||||
(fn_t)multiplier,
|
||||
(fn_t)pffft_reorder_back,
|
||||
};
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#include "pffft.c"
|
||||
|
||||
static void * setup(int len) {return pffft_new_setup(len, PFFFT_REAL);}
|
||||
static void forward (int length, void * setup, float * h, float * scratch) {pffft_transform (setup, h, h, scratch, PFFFT_FORWARD); (void)length;}
|
||||
static void oforward (int length, void * setup, float * h, float * scratch) {pffft_transform_ordered(setup, h, h, scratch, PFFFT_FORWARD); (void)length;}
|
||||
static void backward (int length, void * setup, float * H, float * scratch) {pffft_transform (setup, H, H, scratch, PFFFT_BACKWARD);(void)length;}
|
||||
static void obackward(int length, void * setup, float * H, float * scratch) {pffft_transform_ordered(setup, H, H, scratch, PFFFT_BACKWARD);(void)length;}
|
||||
static void convolve(int length, void * setup, float * H, float const * with) { pffft_zconvolve(setup, H, with, H); (void)length;}
|
||||
static int multiplier(void) {return 1;}
|
||||
|
||||
typedef void (* fn_t)(void);
|
||||
fn_t _soxr_rdft32s_cb[] = {
|
||||
(fn_t)setup,
|
||||
(fn_t)setup,
|
||||
(fn_t)pffft_destroy_setup,
|
||||
(fn_t)forward,
|
||||
(fn_t)oforward,
|
||||
(fn_t)backward,
|
||||
(fn_t)obackward,
|
||||
(fn_t)convolve,
|
||||
(fn_t)_soxr_ordered_partial_convolve_simd,
|
||||
(fn_t)multiplier,
|
||||
(fn_t)pffft_reorder_back,
|
||||
};
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#include "pffft.c"
|
||||
|
||||
static void * setup(int len) {return pffft_new_setup(len, PFFFT_REAL);}
|
||||
static void forward (int length, void * setup, float * h, float * scratch) {pffft_transform (setup, h, h, scratch, PFFFT_FORWARD); (void)length;}
|
||||
static void oforward (int length, void * setup, float * h, float * scratch) {pffft_transform_ordered(setup, h, h, scratch, PFFFT_FORWARD); (void)length;}
|
||||
static void backward (int length, void * setup, float * H, float * scratch) {pffft_transform (setup, H, H, scratch, PFFFT_BACKWARD);(void)length;}
|
||||
static void obackward(int length, void * setup, float * H, float * scratch) {pffft_transform_ordered(setup, H, H, scratch, PFFFT_BACKWARD);(void)length;}
|
||||
static void convolve(int length, void * setup, float * H, float const * with) { pffft_zconvolve(setup, H, with, H); (void)length;}
|
||||
static int multiplier(void) {return 1;}
|
||||
|
||||
typedef void (* fn_t)(void);
|
||||
fn_t _soxr_rdft32s_cb[] = {
|
||||
(fn_t)setup,
|
||||
(fn_t)setup,
|
||||
(fn_t)pffft_destroy_setup,
|
||||
(fn_t)forward,
|
||||
(fn_t)oforward,
|
||||
(fn_t)backward,
|
||||
(fn_t)obackward,
|
||||
(fn_t)convolve,
|
||||
(fn_t)_soxr_ordered_partial_convolve_simd,
|
||||
(fn_t)multiplier,
|
||||
(fn_t)pffft_reorder_back,
|
||||
};
|
||||
|
|
|
@ -1,98 +1,98 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Resample using an interpolated poly-phase FIR with length LEN.*/
|
||||
/* Input must be followed by LEN-1 samples. */
|
||||
|
||||
#define a (coef(p->shared->poly_fir_coefs, COEF_INTERP, FIR_LENGTH, phase, 0,j))
|
||||
#define b (coef(p->shared->poly_fir_coefs, COEF_INTERP, FIR_LENGTH, phase, 1,j))
|
||||
#define c (coef(p->shared->poly_fir_coefs, COEF_INTERP, FIR_LENGTH, phase, 2,j))
|
||||
#define d (coef(p->shared->poly_fir_coefs, COEF_INTERP, FIR_LENGTH, phase, 3,j))
|
||||
#if COEF_INTERP == 0
|
||||
#define _ sum += a *in[j], ++j;
|
||||
#elif COEF_INTERP == 1
|
||||
#define _ sum += (b *x + a)*in[j], ++j;
|
||||
#elif COEF_INTERP == 2
|
||||
#define _ sum += ((c *x + b)*x + a)*in[j], ++j;
|
||||
#elif COEF_INTERP == 3
|
||||
#define _ sum += (((d*x + c)*x + b)*x + a)*in[j], ++j;
|
||||
#else
|
||||
#error COEF_INTERP
|
||||
#endif
|
||||
|
||||
static void FUNCTION(stage_t * p, fifo_t * output_fifo)
|
||||
{
|
||||
sample_t const * input = stage_read_p(p);
|
||||
int i, num_in = stage_occupancy(p), max_num_out = 1 + (int)(num_in*p->out_in_ratio);
|
||||
sample_t * output = fifo_reserve(output_fifo, max_num_out);
|
||||
|
||||
#if defined HI_PREC_CLOCK
|
||||
#if FLOAT_HI_PREC_CLOCK
|
||||
if (p->use_hi_prec_clock) {
|
||||
float_step_t at = p->at.flt;
|
||||
for (i = 0; (int)at < num_in; ++i, at += p->step.flt) {
|
||||
sample_t const * in = input + (int)at;
|
||||
float_step_t frac = at - (int)at;
|
||||
int phase = (int)(frac * (1 << PHASE_BITS));
|
||||
#if COEF_INTERP > 0
|
||||
sample_t x = (sample_t)(frac * (1 << PHASE_BITS) - phase);
|
||||
#endif
|
||||
sample_t sum = 0;
|
||||
int j = 0;
|
||||
CONVOLVE
|
||||
output[i] = sum;
|
||||
}
|
||||
fifo_read(&p->fifo, (int)at, NULL);
|
||||
p->at.flt = at - (int)at;
|
||||
} else
|
||||
#else
|
||||
if (p->use_hi_prec_clock) {
|
||||
for (i = 0; p->at.integer < num_in; ++i,
|
||||
p->at.fix.ls.all += p->step.fix.ls.all,
|
||||
p->at.whole += p->step.whole + (p->at.fix.ls.all < p->step.fix.ls.all)) {
|
||||
sample_t const * in = input + p->at.integer;
|
||||
uint32_t frac = p->at.fraction;
|
||||
int phase = (int)(frac >> (32 - PHASE_BITS)); /* high-order bits */
|
||||
#if COEF_INTERP > 0 /* low-order bits, scaled to [0,1) */
|
||||
sample_t x = (sample_t)((frac << PHASE_BITS) * (1 / MULT32));
|
||||
#endif
|
||||
sample_t sum = 0;
|
||||
int j = 0;
|
||||
CONVOLVE
|
||||
output[i] = sum;
|
||||
}
|
||||
fifo_read(&p->fifo, p->at.integer, NULL);
|
||||
p->at.integer = 0;
|
||||
} else
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
for (i = 0; p->at.integer < num_in; ++i, p->at.whole += p->step.whole) {
|
||||
sample_t const * in = input + p->at.integer;
|
||||
uint32_t frac = p->at.fraction;
|
||||
int phase = (int)(frac >> (32 - PHASE_BITS)); /* high-order bits */
|
||||
#if COEF_INTERP > 0 /* low-order bits, scaled to [0,1) */
|
||||
sample_t x = (sample_t)((frac << PHASE_BITS) * (1 / MULT32));
|
||||
#endif
|
||||
sample_t sum = 0;
|
||||
int j = 0;
|
||||
CONVOLVE
|
||||
output[i] = sum;
|
||||
}
|
||||
fifo_read(&p->fifo, p->at.integer, NULL);
|
||||
p->at.integer = 0;
|
||||
}
|
||||
assert(max_num_out - i >= 0);
|
||||
fifo_trim_by(output_fifo, max_num_out - i);
|
||||
}
|
||||
|
||||
#undef _
|
||||
#undef a
|
||||
#undef b
|
||||
#undef c
|
||||
#undef d
|
||||
#undef COEF_INTERP
|
||||
#undef CONVOLVE
|
||||
#undef FIR_LENGTH
|
||||
#undef FUNCTION
|
||||
#undef PHASE_BITS
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Resample using an interpolated poly-phase FIR with length LEN.*/
|
||||
/* Input must be followed by LEN-1 samples. */
|
||||
|
||||
#define a (coef(p->shared->poly_fir_coefs, COEF_INTERP, FIR_LENGTH, phase, 0,j))
|
||||
#define b (coef(p->shared->poly_fir_coefs, COEF_INTERP, FIR_LENGTH, phase, 1,j))
|
||||
#define c (coef(p->shared->poly_fir_coefs, COEF_INTERP, FIR_LENGTH, phase, 2,j))
|
||||
#define d (coef(p->shared->poly_fir_coefs, COEF_INTERP, FIR_LENGTH, phase, 3,j))
|
||||
#if COEF_INTERP == 0
|
||||
#define _ sum += a *in[j], ++j;
|
||||
#elif COEF_INTERP == 1
|
||||
#define _ sum += (b *x + a)*in[j], ++j;
|
||||
#elif COEF_INTERP == 2
|
||||
#define _ sum += ((c *x + b)*x + a)*in[j], ++j;
|
||||
#elif COEF_INTERP == 3
|
||||
#define _ sum += (((d*x + c)*x + b)*x + a)*in[j], ++j;
|
||||
#else
|
||||
#error COEF_INTERP
|
||||
#endif
|
||||
|
||||
static void FUNCTION(stage_t * p, fifo_t * output_fifo)
|
||||
{
|
||||
sample_t const * input = stage_read_p(p);
|
||||
int i, num_in = stage_occupancy(p), max_num_out = 1 + (int)(num_in*p->out_in_ratio);
|
||||
sample_t * output = fifo_reserve(output_fifo, max_num_out);
|
||||
|
||||
#if defined HI_PREC_CLOCK
|
||||
#if FLOAT_HI_PREC_CLOCK
|
||||
if (p->use_hi_prec_clock) {
|
||||
float_step_t at = p->at.flt;
|
||||
for (i = 0; (int)at < num_in; ++i, at += p->step.flt) {
|
||||
sample_t const * in = input + (int)at;
|
||||
float_step_t frac = at - (int)at;
|
||||
int phase = (int)(frac * (1 << PHASE_BITS));
|
||||
#if COEF_INTERP > 0
|
||||
sample_t x = (sample_t)(frac * (1 << PHASE_BITS) - phase);
|
||||
#endif
|
||||
sample_t sum = 0;
|
||||
int j = 0;
|
||||
CONVOLVE
|
||||
output[i] = sum;
|
||||
}
|
||||
fifo_read(&p->fifo, (int)at, NULL);
|
||||
p->at.flt = at - (int)at;
|
||||
} else
|
||||
#else
|
||||
if (p->use_hi_prec_clock) {
|
||||
for (i = 0; p->at.integer < num_in; ++i,
|
||||
p->at.fix.ls.all += p->step.fix.ls.all,
|
||||
p->at.whole += p->step.whole + (p->at.fix.ls.all < p->step.fix.ls.all)) {
|
||||
sample_t const * in = input + p->at.integer;
|
||||
uint32_t frac = p->at.fraction;
|
||||
int phase = (int)(frac >> (32 - PHASE_BITS)); /* high-order bits */
|
||||
#if COEF_INTERP > 0 /* low-order bits, scaled to [0,1) */
|
||||
sample_t x = (sample_t)((frac << PHASE_BITS) * (1 / MULT32));
|
||||
#endif
|
||||
sample_t sum = 0;
|
||||
int j = 0;
|
||||
CONVOLVE
|
||||
output[i] = sum;
|
||||
}
|
||||
fifo_read(&p->fifo, p->at.integer, NULL);
|
||||
p->at.integer = 0;
|
||||
} else
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
for (i = 0; p->at.integer < num_in; ++i, p->at.whole += p->step.whole) {
|
||||
sample_t const * in = input + p->at.integer;
|
||||
uint32_t frac = p->at.fraction;
|
||||
int phase = (int)(frac >> (32 - PHASE_BITS)); /* high-order bits */
|
||||
#if COEF_INTERP > 0 /* low-order bits, scaled to [0,1) */
|
||||
sample_t x = (sample_t)((frac << PHASE_BITS) * (1 / MULT32));
|
||||
#endif
|
||||
sample_t sum = 0;
|
||||
int j = 0;
|
||||
CONVOLVE
|
||||
output[i] = sum;
|
||||
}
|
||||
fifo_read(&p->fifo, p->at.integer, NULL);
|
||||
p->at.integer = 0;
|
||||
}
|
||||
assert(max_num_out - i >= 0);
|
||||
fifo_trim_by(output_fifo, max_num_out - i);
|
||||
}
|
||||
|
||||
#undef _
|
||||
#undef a
|
||||
#undef b
|
||||
#undef c
|
||||
#undef d
|
||||
#undef COEF_INTERP
|
||||
#undef CONVOLVE
|
||||
#undef FIR_LENGTH
|
||||
#undef FUNCTION
|
||||
#undef PHASE_BITS
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Resample using a non-interpolated poly-phase FIR with length LEN.*/
|
||||
/* Input must be followed by LEN-1 samples. */
|
||||
|
||||
#define _ sum += (coef(p->shared->poly_fir_coefs, 0, FIR_LENGTH, rem, 0, j)) *at[j], ++j;
|
||||
|
||||
static void FUNCTION(stage_t * p, fifo_t * output_fifo)
|
||||
{
|
||||
sample_t const * input = stage_read_p(p);
|
||||
int i, num_in = stage_occupancy(p), max_num_out = 1 + (int)(num_in*p->out_in_ratio);
|
||||
sample_t * output = fifo_reserve(output_fifo, max_num_out);
|
||||
|
||||
for (i = 0; p->at.integer < num_in * p->L; ++i, p->at.integer += p->step.integer) {
|
||||
int div = p->at.integer / p->L, rem = p->at.integer % p->L;
|
||||
sample_t const * at = input + div;
|
||||
sample_t sum = 0;
|
||||
int j = 0;
|
||||
CONVOLVE
|
||||
output[i] = sum;
|
||||
}
|
||||
assert(max_num_out - i >= 0);
|
||||
fifo_trim_by(output_fifo, max_num_out - i);
|
||||
fifo_read(&p->fifo, p->at.integer / p->L, NULL);
|
||||
p->at.integer = p->at.integer % p->L;
|
||||
}
|
||||
|
||||
#undef _
|
||||
#undef CONVOLVE
|
||||
#undef FIR_LENGTH
|
||||
#undef FUNCTION
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
/* Resample using a non-interpolated poly-phase FIR with length LEN.*/
|
||||
/* Input must be followed by LEN-1 samples. */
|
||||
|
||||
#define _ sum += (coef(p->shared->poly_fir_coefs, 0, FIR_LENGTH, rem, 0, j)) *at[j], ++j;
|
||||
|
||||
static void FUNCTION(stage_t * p, fifo_t * output_fifo)
|
||||
{
|
||||
sample_t const * input = stage_read_p(p);
|
||||
int i, num_in = stage_occupancy(p), max_num_out = 1 + (int)(num_in*p->out_in_ratio);
|
||||
sample_t * output = fifo_reserve(output_fifo, max_num_out);
|
||||
|
||||
for (i = 0; p->at.integer < num_in * p->L; ++i, p->at.integer += p->step.integer) {
|
||||
int div = p->at.integer / p->L, rem = p->at.integer % p->L;
|
||||
sample_t const * at = input + div;
|
||||
sample_t sum = 0;
|
||||
int j = 0;
|
||||
CONVOLVE
|
||||
output[i] = sum;
|
||||
}
|
||||
assert(max_num_out - i >= 0);
|
||||
fifo_trim_by(output_fifo, max_num_out - i);
|
||||
fifo_read(&p->fifo, p->at.integer / p->L, NULL);
|
||||
p->at.integer = p->at.integer % p->L;
|
||||
}
|
||||
|
||||
#undef _
|
||||
#undef CONVOLVE
|
||||
#undef FIR_LENGTH
|
||||
#undef FUNCTION
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,9 +1,9 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#define sample_t float
|
||||
#define RATE_SIMD 0
|
||||
#define RDFT_CB _soxr_rdft32_cb
|
||||
#define RATE_CB _soxr_rate32_cb
|
||||
#define RATE_ID "single-precision"
|
||||
#include "rate.h"
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#define sample_t float
|
||||
#define RATE_SIMD 0
|
||||
#define RDFT_CB _soxr_rdft32_cb
|
||||
#define RATE_CB _soxr_rate32_cb
|
||||
#define RATE_ID "single-precision"
|
||||
#include "rate.h"
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#define sample_t float
|
||||
#define RATE_SIMD 1
|
||||
#define RDFT_CB _soxr_rdft32s_cb
|
||||
#define RATE_CB _soxr_rate32s_cb
|
||||
#define RATE_ID "single-precision-SIMD"
|
||||
#include "rate.h"
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#define sample_t float
|
||||
#define RATE_SIMD 1
|
||||
#define RDFT_CB _soxr_rdft32s_cb
|
||||
#define RATE_CB _soxr_rate32s_cb
|
||||
#define RATE_ID "single-precision-SIMD"
|
||||
#include "rate.h"
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#define sample_t double
|
||||
#define RATE_SIMD 0
|
||||
#define RDFT_CB _soxr_rdft64_cb
|
||||
#define RATE_CB _soxr_rate64_cb
|
||||
#define RATE_ID "double-precision"
|
||||
#include "rate.h"
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#define sample_t double
|
||||
#define RATE_SIMD 0
|
||||
#define RDFT_CB _soxr_rdft64_cb
|
||||
#define RATE_CB _soxr_rate64_cb
|
||||
#define RATE_ID "double-precision"
|
||||
#include "rate.h"
|
||||
|
|
|
@ -1,31 +1,31 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
void ORDERED_CONVOLVE(int n, void * not_used, DFT_FLOAT * a, const DFT_FLOAT * b)
|
||||
{
|
||||
int i;
|
||||
a[0] *= b[0];
|
||||
a[1] *= b[1];
|
||||
for (i = 2; i < n; i += 2) {
|
||||
DFT_FLOAT tmp = a[i];
|
||||
a[i ] = b[i ] * tmp - b[i+1] * a[i+1];
|
||||
a[i+1] = b[i+1] * tmp + b[i ] * a[i+1];
|
||||
}
|
||||
(void)not_used;
|
||||
}
|
||||
|
||||
void ORDERED_PARTIAL_CONVOLVE(int n, DFT_FLOAT * a, const DFT_FLOAT * b)
|
||||
{
|
||||
int i;
|
||||
a[0] *= b[0];
|
||||
for (i = 2; i < n; i += 2) {
|
||||
DFT_FLOAT tmp = a[i];
|
||||
a[i ] = b[i ] * tmp - b[i+1] * a[i+1];
|
||||
a[i+1] = b[i+1] * tmp + b[i ] * a[i+1];
|
||||
}
|
||||
a[1] = b[i] * a[i] - b[i+1] * a[i+1];
|
||||
}
|
||||
|
||||
#undef ORDERED_CONVOLVE
|
||||
#undef ORDERED_PARTIAL_CONVOLVE
|
||||
#undef DFT_FLOAT
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
void ORDERED_CONVOLVE(int n, void * not_used, DFT_FLOAT * a, const DFT_FLOAT * b)
|
||||
{
|
||||
int i;
|
||||
a[0] *= b[0];
|
||||
a[1] *= b[1];
|
||||
for (i = 2; i < n; i += 2) {
|
||||
DFT_FLOAT tmp = a[i];
|
||||
a[i ] = b[i ] * tmp - b[i+1] * a[i+1];
|
||||
a[i+1] = b[i+1] * tmp + b[i ] * a[i+1];
|
||||
}
|
||||
(void)not_used;
|
||||
}
|
||||
|
||||
void ORDERED_PARTIAL_CONVOLVE(int n, DFT_FLOAT * a, const DFT_FLOAT * b)
|
||||
{
|
||||
int i;
|
||||
a[0] *= b[0];
|
||||
for (i = 2; i < n; i += 2) {
|
||||
DFT_FLOAT tmp = a[i];
|
||||
a[i ] = b[i ] * tmp - b[i+1] * a[i+1];
|
||||
a[i+1] = b[i+1] * tmp + b[i ] * a[i+1];
|
||||
}
|
||||
a[1] = b[i] * a[i] - b[i+1] * a[i+1];
|
||||
}
|
||||
|
||||
#undef ORDERED_CONVOLVE
|
||||
#undef ORDERED_PARTIAL_CONVOLVE
|
||||
#undef DFT_FLOAT
|
||||
|
|
|
@ -1,153 +1,153 @@
|
|||
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#if defined DITHER
|
||||
|
||||
#define DITHERING (1./32)*(int)(((ran1>>=3)&31)-((ran2>>=3)&31))
|
||||
#define DITHER_RAND (seed = 1664525UL * seed + 1013904223UL) >> 3
|
||||
#define DITHER_VARS unsigned long ran1 = DITHER_RAND, ran2 = DITHER_RAND
|
||||
#define SEED_ARG , unsigned long * seed0
|
||||
#define SAVE_SEED *seed0 = seed
|
||||
#define COPY_SEED unsigned long seed = *seed0;
|
||||
#define COPY_SEED1 unsigned long seed1 = seed
|
||||
#define PASS_SEED1 , &seed1
|
||||
#define PASS_SEED0 , seed0
|
||||
|
||||
#else
|
||||
|
||||
#define DITHERING 0
|
||||
#define DITHER_VARS
|
||||
#define SEED_ARG
|
||||
#define SAVE_SEED
|
||||
#define COPY_SEED
|
||||
#define COPY_SEED1
|
||||
#define PASS_SEED1
|
||||
#define PASS_SEED0
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if defined FE_INVALID && defined FPU_RINT
|
||||
static void RINT_CLIP(RINT_T * const dest, FLOATX const * const src,
|
||||
unsigned stride, size_t i, size_t const n, size_t * const clips SEED_ARG)
|
||||
{
|
||||
COPY_SEED
|
||||
DITHER_VARS;
|
||||
for (; i < n; ++i) {
|
||||
double d = src[i] + DITHERING;
|
||||
dest[stride * i] = RINT(d);
|
||||
if (fetestexcept(FE_INVALID)) {
|
||||
feclearexcept(FE_INVALID);
|
||||
dest[stride * i] = d > 0? RINT_MAX : -RINT_MAX - 1;
|
||||
++*clips;
|
||||
}
|
||||
}
|
||||
SAVE_SEED;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static size_t LSX_RINT_CLIP(void * * const dest0, FLOATX const * const src,
|
||||
size_t const n SEED_ARG)
|
||||
{
|
||||
size_t i, clips = 0;
|
||||
RINT_T * dest = *dest0;
|
||||
COPY_SEED
|
||||
#if defined FE_INVALID && defined FPU_RINT
|
||||
#define _ dest[i] = RINT(src[i] + DITHERING), ++i,
|
||||
feclearexcept(FE_INVALID);
|
||||
for (i = 0; i < (n & ~7u);) {
|
||||
COPY_SEED1;
|
||||
DITHER_VARS;
|
||||
_ _ _ _ _ _ _ _ 0;
|
||||
if (fetestexcept(FE_INVALID)) {
|
||||
feclearexcept(FE_INVALID);
|
||||
RINT_CLIP(dest, src, 1, i - 8, i, &clips PASS_SEED1);
|
||||
}
|
||||
}
|
||||
RINT_CLIP(dest, src, 1, i, n, &clips PASS_SEED0);
|
||||
#else
|
||||
#define _ d = src[i] + DITHERING, dest[i++] = (RINT_T)(d > N - 1? ++clips, (RINT_T)(N - 1) : d < -N? ++clips, (RINT_T)(-N) : RINT(d)),
|
||||
const double N = 1. + RINT_MAX;
|
||||
double d;
|
||||
for (i = 0; i < (n & ~7u);) {
|
||||
DITHER_VARS;
|
||||
_ _ _ _ _ _ _ _ 0;
|
||||
}
|
||||
{
|
||||
DITHER_VARS;
|
||||
for (; i < n; _ 0);
|
||||
}
|
||||
#endif
|
||||
SAVE_SEED;
|
||||
*dest0 = dest + n;
|
||||
return clips;
|
||||
}
|
||||
#undef _
|
||||
|
||||
|
||||
|
||||
static size_t LSX_RINT_CLIP_2(void * * dest0, FLOATX const * const * srcs,
|
||||
unsigned const stride, size_t const n SEED_ARG)
|
||||
{
|
||||
unsigned j;
|
||||
size_t i, clips = 0;
|
||||
RINT_T * dest = *dest0;
|
||||
COPY_SEED
|
||||
#if defined FE_INVALID && defined FPU_RINT
|
||||
#define _ dest[stride * i] = RINT(src[i] + DITHERING), ++i,
|
||||
feclearexcept(FE_INVALID);
|
||||
for (j = 0; j < stride; ++j, ++dest) {
|
||||
FLOATX const * const src = srcs[j];
|
||||
for (i = 0; i < (n & ~7u);) {
|
||||
COPY_SEED1;
|
||||
DITHER_VARS;
|
||||
_ _ _ _ _ _ _ _ 0;
|
||||
if (fetestexcept(FE_INVALID)) {
|
||||
feclearexcept(FE_INVALID);
|
||||
RINT_CLIP(dest, src, stride, i - 8, i, &clips PASS_SEED1);
|
||||
}
|
||||
}
|
||||
RINT_CLIP(dest, src, stride, i, n, &clips PASS_SEED0);
|
||||
}
|
||||
#else
|
||||
#define _ d = src[i] + DITHERING, dest[stride * i++] = (RINT_T)(d > N - 1? ++clips, (RINT_T)(N - 1) : d < -N? ++clips, (RINT_T)(-N) : RINT(d)),
|
||||
const double N = 1. + RINT_MAX;
|
||||
double d;
|
||||
for (j = 0; j < stride; ++j, ++dest) {
|
||||
FLOATX const * const src = srcs[j];
|
||||
for (i = 0; i < (n & ~7u);) {
|
||||
DITHER_VARS;
|
||||
_ _ _ _ _ _ _ _ 0;
|
||||
}
|
||||
{
|
||||
DITHER_VARS;
|
||||
for (; i < n; _ 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
SAVE_SEED;
|
||||
*dest0 = dest + stride * (n - 1);
|
||||
return clips;
|
||||
}
|
||||
#undef _
|
||||
|
||||
#undef PASS_SEED0
|
||||
#undef PASS_SEED1
|
||||
#undef COPY_SEED1
|
||||
#undef COPY_SEED
|
||||
#undef SAVE_SEED
|
||||
#undef SEED_ARG
|
||||
#undef DITHER_VARS
|
||||
#undef DITHERING
|
||||
#undef DITHER
|
||||
|
||||
#undef RINT_MAX
|
||||
#undef RINT_T
|
||||
#undef FPU_RINT
|
||||
#undef RINT
|
||||
#undef RINT_CLIP
|
||||
#undef LSX_RINT_CLIP
|
||||
#undef LSX_RINT_CLIP_2
|
||||
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
|
||||
* Licence for this file: LGPL v2.1 See LICENCE for details. */
|
||||
|
||||
#if defined DITHER
|
||||
|
||||
#define DITHERING (1./32)*(int)(((ran1>>=3)&31)-((ran2>>=3)&31))
|
||||
#define DITHER_RAND (seed = 1664525UL * seed + 1013904223UL) >> 3
|
||||
#define DITHER_VARS unsigned long ran1 = DITHER_RAND, ran2 = DITHER_RAND
|
||||
#define SEED_ARG , unsigned long * seed0
|
||||
#define SAVE_SEED *seed0 = seed
|
||||
#define COPY_SEED unsigned long seed = *seed0;
|
||||
#define COPY_SEED1 unsigned long seed1 = seed
|
||||
#define PASS_SEED1 , &seed1
|
||||
#define PASS_SEED , &seed
|
||||
|
||||
#else
|
||||
|
||||
#define DITHERING 0
|
||||
#define DITHER_VARS
|
||||
#define SEED_ARG
|
||||
#define SAVE_SEED
|
||||
#define COPY_SEED
|
||||
#define COPY_SEED1
|
||||
#define PASS_SEED1
|
||||
#define PASS_SEED
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if defined FE_INVALID && defined FPU_RINT
|
||||
static void RINT_CLIP(RINT_T * const dest, FLOATX const * const src,
|
||||
unsigned stride, size_t i, size_t const n, size_t * const clips SEED_ARG)
|
||||
{
|
||||
COPY_SEED
|
||||
DITHER_VARS;
|
||||
for (; i < n; ++i) {
|
||||
double d = src[i] + DITHERING;
|
||||
dest[stride * i] = RINT(d);
|
||||
if (fe_test_invalid()) {
|
||||
fe_clear_invalid();
|
||||
dest[stride * i] = d > 0? RINT_MAX : -RINT_MAX - 1;
|
||||
++*clips;
|
||||
}
|
||||
}
|
||||
SAVE_SEED;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static size_t LSX_RINT_CLIP(void * * const dest0, FLOATX const * const src,
|
||||
size_t const n SEED_ARG)
|
||||
{
|
||||
size_t i, clips = 0;
|
||||
RINT_T * dest = *dest0;
|
||||
COPY_SEED
|
||||
#if defined FE_INVALID && defined FPU_RINT
|
||||
#define _ dest[i] = RINT(src[i] + DITHERING), ++i,
|
||||
fe_clear_invalid();
|
||||
for (i = 0; i < (n & ~7u);) {
|
||||
COPY_SEED1;
|
||||
DITHER_VARS;
|
||||
_ _ _ _ _ _ _ _ 0;
|
||||
if (fe_test_invalid()) {
|
||||
fe_clear_invalid();
|
||||
RINT_CLIP(dest, src, 1, i - 8, i, &clips PASS_SEED1);
|
||||
}
|
||||
}
|
||||
RINT_CLIP(dest, src, 1, i, n, &clips PASS_SEED);
|
||||
#else
|
||||
#define _ d = src[i] + DITHERING, dest[i++] = (RINT_T)(d > 0? d+.5 >= N? ++clips, N-1 : d+.5 : d-.5 <= -N-1? ++clips, -N:d-.5),
|
||||
const double N = 1. + RINT_MAX;
|
||||
double d;
|
||||
for (i = 0; i < (n & ~7u);) {
|
||||
DITHER_VARS;
|
||||
_ _ _ _ _ _ _ _ 0;
|
||||
}
|
||||
{
|
||||
DITHER_VARS;
|
||||
for (; i < n; _ 0);
|
||||
}
|
||||
#endif
|
||||
SAVE_SEED;
|
||||
*dest0 = dest + n;
|
||||
return clips;
|
||||
}
|
||||
#undef _
|
||||
|
||||
|
||||
|
||||
static size_t LSX_RINT_CLIP_2(void * * dest0, FLOATX const * const * srcs,
|
||||
unsigned const stride, size_t const n SEED_ARG)
|
||||
{
|
||||
unsigned j;
|
||||
size_t i, clips = 0;
|
||||
RINT_T * dest = *dest0;
|
||||
COPY_SEED
|
||||
#if defined FE_INVALID && defined FPU_RINT
|
||||
#define _ dest[stride * i] = RINT(src[i] + DITHERING), ++i,
|
||||
fe_clear_invalid();
|
||||
for (j = 0; j < stride; ++j, ++dest) {
|
||||
FLOATX const * const src = srcs[j];
|
||||
for (i = 0; i < (n & ~7u);) {
|
||||
COPY_SEED1;
|
||||
DITHER_VARS;
|
||||
_ _ _ _ _ _ _ _ 0;
|
||||
if (fe_test_invalid()) {
|
||||
fe_clear_invalid();
|
||||
RINT_CLIP(dest, src, stride, i - 8, i, &clips PASS_SEED1);
|
||||
}
|
||||
}
|
||||
RINT_CLIP(dest, src, stride, i, n, &clips PASS_SEED);
|
||||
}
|
||||
#else
|
||||
#define _ d = src[i] + DITHERING, dest[stride * i++] = (RINT_T)(d > 0? d+.5 >= N? ++clips, N-1 : d+.5 : d-.5 <= -N-1? ++clips, -N:d-.5),
|
||||
const double N = 1. + RINT_MAX;
|
||||
double d;
|
||||
for (j = 0; j < stride; ++j, ++dest) {
|
||||
FLOATX const * const src = srcs[j];
|
||||
for (i = 0; i < (n & ~7u);) {
|
||||
DITHER_VARS;
|
||||
_ _ _ _ _ _ _ _ 0;
|
||||
}
|
||||
{
|
||||
DITHER_VARS;
|
||||
for (; i < n; _ 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
SAVE_SEED;
|
||||
*dest0 = dest + stride * (n - 1);
|
||||
return clips;
|
||||
}
|
||||
#undef _
|
||||
|
||||
#undef PASS_SEED
|
||||
#undef PASS_SEED1
|
||||
#undef COPY_SEED1
|
||||
#undef COPY_SEED
|
||||
#undef SAVE_SEED
|
||||
#undef SEED_ARG
|
||||
#undef DITHER_VARS
|
||||
#undef DITHERING
|
||||
#undef DITHER
|
||||
|
||||
#undef RINT_MAX
|
||||
#undef RINT_T
|
||||
#undef FPU_RINT
|
||||
#undef RINT
|
||||
#undef RINT_CLIP
|
||||
#undef LSX_RINT_CLIP
|
||||
#undef LSX_RINT_CLIP_2
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue