Do our own resampling

custom
jacqueline 2 years ago
parent 3b240d1cd5
commit 60f7677132
  1. 11
      lib/libsamplerate/CMakeLists.txt
  2. 13
      lib/libsamplerate/libsamplerate-0.2.2/AUTHORS
  3. 150
      lib/libsamplerate/libsamplerate-0.2.2/CMakeLists.txt
  4. 25
      lib/libsamplerate/libsamplerate-0.2.2/COPYING
  5. 1181
      lib/libsamplerate/libsamplerate-0.2.2/ChangeLog
  6. 106
      lib/libsamplerate/libsamplerate-0.2.2/INSTALL
  7. 158
      lib/libsamplerate/libsamplerate-0.2.2/Makefile.am
  8. 81
      lib/libsamplerate/libsamplerate-0.2.2/NEWS
  9. 27
      lib/libsamplerate/libsamplerate-0.2.2/Octave/Readme.md
  10. 35
      lib/libsamplerate/libsamplerate-0.2.2/Octave/generate_filter.m
  11. 134
      lib/libsamplerate/libsamplerate-0.2.2/Octave/make_filter.m
  12. 70
      lib/libsamplerate/libsamplerate-0.2.2/Octave/measure_filter.m
  13. 62
      lib/libsamplerate/libsamplerate-0.2.2/README.md
  14. 30
      lib/libsamplerate/libsamplerate-0.2.2/Win32/libsamplerate-0.def
  15. 119
      lib/libsamplerate/libsamplerate-0.2.2/autogen.sh
  16. 81
      lib/libsamplerate/libsamplerate-0.2.2/cmake/ClipMode.cmake
  17. 88
      lib/libsamplerate/libsamplerate-0.2.2/cmake/FindFFTW3.cmake
  18. 63
      lib/libsamplerate/libsamplerate-0.2.2/cmake/FindFLAC.cmake
  19. 57
      lib/libsamplerate/libsamplerate-0.2.2/cmake/FindOgg.cmake
  20. 64
      lib/libsamplerate/libsamplerate-0.2.2/cmake/FindOpus.cmake
  21. 57
      lib/libsamplerate/libsamplerate-0.2.2/cmake/FindSndFile.cmake
  22. 204
      lib/libsamplerate/libsamplerate-0.2.2/cmake/FindVorbis.cmake
  23. 1
      lib/libsamplerate/libsamplerate-0.2.2/cmake/SampleRateConfig.cmake.in
  24. 76
      lib/libsamplerate/libsamplerate-0.2.2/config.h.cmake
  25. 400
      lib/libsamplerate/libsamplerate-0.2.2/configure.ac
  26. 19
      lib/libsamplerate/libsamplerate-0.2.2/docs/CMakeLists.txt
  27. 56
      lib/libsamplerate/libsamplerate-0.2.2/docs/SRC.css
  28. BIN
      lib/libsamplerate/libsamplerate-0.2.2/docs/SRC.png
  29. 8
      lib/libsamplerate/libsamplerate-0.2.2/docs/_config.yml
  30. 49
      lib/libsamplerate/libsamplerate-0.2.2/docs/_layouts/default.html
  31. 46
      lib/libsamplerate/libsamplerate-0.2.2/docs/api.md
  32. 88
      lib/libsamplerate/libsamplerate-0.2.2/docs/api_callback.md
  33. 146
      lib/libsamplerate/libsamplerate-0.2.2/docs/api_full.md
  34. 145
      lib/libsamplerate/libsamplerate-0.2.2/docs/api_misc.md
  35. 71
      lib/libsamplerate/libsamplerate-0.2.2/docs/api_simple.md
  36. 37
      lib/libsamplerate/libsamplerate-0.2.2/docs/bugs.md
  37. 15
      lib/libsamplerate/libsamplerate-0.2.2/docs/download.md
  38. 193
      lib/libsamplerate/libsamplerate-0.2.2/docs/faq.md
  39. BIN
      lib/libsamplerate/libsamplerate-0.2.2/docs/foo_dsp_src9.png
  40. 38
      lib/libsamplerate/libsamplerate-0.2.2/docs/history.md
  41. 160
      lib/libsamplerate/libsamplerate-0.2.2/docs/index.md
  42. 12
      lib/libsamplerate/libsamplerate-0.2.2/docs/license.md
  43. 17
      lib/libsamplerate/libsamplerate-0.2.2/docs/lists.md
  44. BIN
      lib/libsamplerate/libsamplerate-0.2.2/docs/paypal.png
  45. 84
      lib/libsamplerate/libsamplerate-0.2.2/docs/quality.md
  46. 15
      lib/libsamplerate/libsamplerate-0.2.2/docs/win32.md
  47. 31
      lib/libsamplerate/libsamplerate-0.2.2/examples/CMakeLists.txt
  48. 1125
      lib/libsamplerate/libsamplerate-0.2.2/examples/audio_out.c
  49. 25
      lib/libsamplerate/libsamplerate-0.2.2/examples/audio_out.h
  50. 234
      lib/libsamplerate/libsamplerate-0.2.2/examples/timewarp-file.c
  51. 246
      lib/libsamplerate/libsamplerate-0.2.2/examples/varispeed-play.c
  52. 189
      lib/libsamplerate/libsamplerate-0.2.2/include/samplerate.h
  53. 58
      lib/libsamplerate/libsamplerate-0.2.2/libsamplerate.spec.in
  54. 67
      lib/libsamplerate/libsamplerate-0.2.2/m4/ax_append_compile_flags.m4
  55. 71
      lib/libsamplerate/libsamplerate-0.2.2/m4/ax_append_flag.m4
  56. 65
      lib/libsamplerate/libsamplerate-0.2.2/m4/ax_append_link_flags.m4
  57. 74
      lib/libsamplerate/libsamplerate-0.2.2/m4/ax_check_compile_flag.m4
  58. 74
      lib/libsamplerate/libsamplerate-0.2.2/m4/ax_check_link_flag.m4
  59. 87
      lib/libsamplerate/libsamplerate-0.2.2/m4/ax_compiler_vendor.m4
  60. 492
      lib/libsamplerate/libsamplerate-0.2.2/m4/ax_compiler_version.m4
  61. 56
      lib/libsamplerate/libsamplerate-0.2.2/m4/ax_recursive_eval.m4
  62. 37
      lib/libsamplerate/libsamplerate-0.2.2/m4/ax_require_defined.m4
  63. 26
      lib/libsamplerate/libsamplerate-0.2.2/m4/check_signal.m4
  64. 124
      lib/libsamplerate/libsamplerate-0.2.2/m4/clip_mode.m4
  65. 12
      lib/libsamplerate/libsamplerate-0.2.2/samplerate.pc.in
  66. 169
      lib/libsamplerate/libsamplerate-0.2.2/src/CMakeLists.txt
  67. 45
      lib/libsamplerate/libsamplerate-0.2.2/src/Version_script.in
  68. 47
      lib/libsamplerate/libsamplerate-0.2.2/src/check_asm.sh
  69. 252
      lib/libsamplerate/libsamplerate-0.2.2/src/common.h
  70. 2498
      lib/libsamplerate/libsamplerate-0.2.2/src/fastest_coeffs.h
  71. 340273
      lib/libsamplerate/libsamplerate-0.2.2/src/high_qual_coeffs.h
  72. 22472
      lib/libsamplerate/libsamplerate-0.2.2/src/mid_qual_coeffs.h
  73. 528
      lib/libsamplerate/libsamplerate-0.2.2/src/samplerate.c
  74. 301
      lib/libsamplerate/libsamplerate-0.2.2/src/src_linear.c
  75. 1252
      lib/libsamplerate/libsamplerate-0.2.2/src/src_sinc.c
  76. 290
      lib/libsamplerate/libsamplerate-0.2.2/src/src_zoh.c
  77. 95
      lib/libsamplerate/libsamplerate-0.2.2/tests/CMakeLists.txt
  78. 243
      lib/libsamplerate/libsamplerate-0.2.2/tests/calc_snr.c
  79. 127
      lib/libsamplerate/libsamplerate-0.2.2/tests/callback_hang_test.c
  80. 238
      lib/libsamplerate/libsamplerate-0.2.2/tests/callback_test.c
  81. 134
      lib/libsamplerate/libsamplerate-0.2.2/tests/clone_test.c
  82. 61
      lib/libsamplerate/libsamplerate-0.2.2/tests/downsample_test.c
  83. 192
      lib/libsamplerate/libsamplerate-0.2.2/tests/float_short_test.c
  84. 208
      lib/libsamplerate/libsamplerate-0.2.2/tests/misc_test.c
  85. 368
      lib/libsamplerate/libsamplerate-0.2.2/tests/multi_channel_test.c
  86. 261
      lib/libsamplerate/libsamplerate-0.2.2/tests/multichan_throughput_test.c
  87. 108
      lib/libsamplerate/libsamplerate-0.2.2/tests/nullptr_test.c
  88. 236
      lib/libsamplerate/libsamplerate-0.2.2/tests/reset_test.c
  89. 168
      lib/libsamplerate/libsamplerate-0.2.2/tests/simple_test.c
  90. 404
      lib/libsamplerate/libsamplerate-0.2.2/tests/snr_bw_test.c
  91. 530
      lib/libsamplerate/libsamplerate-0.2.2/tests/src-evaluate.c
  92. 149
      lib/libsamplerate/libsamplerate-0.2.2/tests/streaming_test.c
  93. 342
      lib/libsamplerate/libsamplerate-0.2.2/tests/termination_test.c
  94. 253
      lib/libsamplerate/libsamplerate-0.2.2/tests/throughput_test.c
  95. 228
      lib/libsamplerate/libsamplerate-0.2.2/tests/util.c
  96. 41
      lib/libsamplerate/libsamplerate-0.2.2/tests/util.h
  97. 275
      lib/libsamplerate/libsamplerate-0.2.2/tests/varispeed_test.c
  98. 2
      src/audio/CMakeLists.txt
  99. 12
      src/audio/audio_task.cpp
  100. 7
      src/audio/i2s_audio_output.cpp
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,11 +0,0 @@
# Copyright 2023 jacqueline <me@jacqueline.id.au>
#
# SPDX-License-Identifier: GPL-3.0-only
idf_component_register()
set(LIBSAMPLERATE_EXAMPLES false)
set(LIBSAMPLERATE_INSTALL false)
set(BUILD_TESTING false)
add_subdirectory(libsamplerate-0.2.2)
target_link_libraries(${COMPONENT_LIB} INTERFACE samplerate)

@ -1,13 +0,0 @@
Original author:
Erik de Castro Lopo <erikd@mega-nerd.com>
Current maintainers:
After the release of version 0.1.9, @erikd transferred the project to
[the libsndfile team](https://github.com/libsndfile) consisting of:
* Erik de Castro Lopo aka @erikd
* David Seifert aka @SoapGentoo
* Arthur Taylor aka @arthurt
* @evpobr

@ -1,150 +0,0 @@
cmake_minimum_required(VERSION 3.1..3.18)
# Policies
# Include file check macros honor CMAKE_REQUIRED_LIBRARIES, CMake >= 3.12
if(POLICY CMP0075)
cmake_policy(SET CMP0075 NEW)
endif()
# MSVC runtime library flags are selected by an abstraction, CMake >= 3.15
# This policy still need to be set even with cmake_minimum_required() command above.
if(POLICY CMP0091)
cmake_policy(SET CMP0091 NEW)
endif()
project(libsamplerate VERSION 0.2.2 LANGUAGES C)
# Configuration
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
set(IS_ROOT_PROJECT ON)
else()
set(IS_ROOT_PROJECT OFF)
endif()
option(LIBSAMPLERATE_EXAMPLES "Enable to generate examples" ${IS_ROOT_PROJECT})
option(LIBSAMPLERATE_INSTALL "Enable to add install directives" ${IS_ROOT_PROJECT})
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED TRUE)
include(TestBigEndian)
include(CheckFunctionExists)
include(CheckIncludeFile)
include(CheckLibraryExists)
include(CheckSymbolExists)
include(GNUInstallDirs)
include(CTest)
if(DEFINED LIBSAMPLERATE_TESTS)
message(DEPRECATION "LIBSAMPLERATE_TESTS option deprecated, use BUILD_TESTING option instead.")
set(BUILD_TESTING ${LIBSAMPLERATE_TESTS})
endif()
add_definitions(-DHAVE_CONFIG_H)
include_directories(${PROJECT_BINARY_DIR})
if(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif()
if(NOT (WIN32 OR APPLE OR CYGWIN OR HAIKU OR BEOS))
find_library(MATH_LIBRARY m)
if(MATH_LIBRARY)
set(LIBM_REQUIRED 1)
if(LIBM_REQUIRED)
list(APPEND CMAKE_REQUIRED_LIBRARIES m)
if(LIBM_REQUIRED)
link_libraries(${MATH_LIBRARY})
endif()
endif()
endif()
endif()
option(LIBSAMPLERATE_SSE2_LRINT "Implement lrintf using SSE2 on x86 CPUs if possible" OFF)
if(LIBSAMPLERATE_SSE2_LRINT)
add_definitions(-DENABLE_SSE2_LRINT)
endif()
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
option(LIBSAMPLERATE_ENABLE_SANITIZERS "Enable ASAN and UBSAN" OFF)
if(LIBSAMPLERATE_ENABLE_SANITIZERS)
# Use ASAN and UBSAN, make it fail on any error, improve stack traces
set(sanitizer_flags -fsanitize=address,undefined -fno-sanitize-recover=all -fno-omit-frame-pointer)
add_compile_options(${sanitizer_flags})
string(REPLACE ";" " " sanitizer_flags "${sanitizer_flags}")
string(APPEND CMAKE_EXE_LINKER_FLAGS " ${sanitizer_flags}")
string(APPEND CMAKE_MODULE_LINKER_FLAGS " ${sanitizer_flags}")
string(APPEND CMAKE_SHARED_LINKER_FLAGS " ${sanitizer_flags}")
endif()
endif()
test_big_endian(CPU_IS_BIG_ENDIAN)
if(CPU_IS_BIG_ENDIAN)
set(CPU_IS_LITTLE_ENDIAN 0)
else()
set(CPU_IS_LITTLE_ENDIAN 1)
endif()
check_include_file(stdbool.h HAVE_STDBOOL_H)
check_include_file(unistd.h HAVE_UNISTD_H)
check_include_file(immintrin.h HAVE_IMMINTRIN_H)
# For examples and tests
find_package(PkgConfig)
if(LIBSAMPLERATE_EXAMPLES OR BUILD_TESTING)
if((NOT VCPKG_TOOLCHAIN) AND PKG_CONFIG_FOUND AND (NOT CMAKE_VERSION VERSION_LESS 3.6))
pkg_check_modules(SndFile sndfile IMPORTED_TARGET)
if(SndFile_FOUND)
set(SNDFILE_TARGET PkgConfig::SndFile)
endif()
else()
find_package(SndFile)
if(SndFile_FOUND)
set(SNDFILE_TARGET SndFile::sndfile)
endif()
endif()
set(HAVE_SNDFILE ${SndFile_FOUND})
endif()
# SampleRate library
add_subdirectory(src)
# Tests
# BUILD_TESTING is declared by CTest module and is ON by default
if(BUILD_TESTING)
add_subdirectory(tests)
endif()
# Examples
if(LIBSAMPLERATE_EXAMPLES)
add_subdirectory(examples)
endif()
configure_file(config.h.cmake config.h)
if(LIBSAMPLERATE_INSTALL)
add_subdirectory(docs)
endif()
# Packaging support
# See https://cmake.org/cmake/help/v3.12/release/3.12.html#cpack
if(CMAKE_VERSION VERSION_LESS 3.12)
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
endif()
include(CPack)

@ -1,25 +0,0 @@
Copyright (c) 2012-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. 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.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

File diff suppressed because it is too large Load Diff

@ -1,106 +0,0 @@
Install Instructions for libsamplerate
======================================
The following instructions explain how to install libsamplerate under
Linux and other Unix-like systems, including macOS. (For Windows,
see http://libsndfile.github.io/libsamplerate/win32.html).
Preliminaries
-------------
1) Included with libsamplerate are example programs which use libsndfile:
http://libsndfile.github.io/libsndfile/
for file I/O. If you want to build them, you need to
ensure that libsndfile is correctly installed first. If it is, the
command "pkg-config --cflags --libs sndfile" should print out
something like this:
-lsndfile
If pkg-config doesn't exist, you will need need to install it. If
pkg-config cannot find libsndfile, you may need to install it. If you
install from from a Linux distribution package, make sure you also
install the libsndfile-devel package which contains the header files.
If libsndfile is installed, you may need to set the PKG_CONFIG_PATH
environment variable. If libsndfile is installed in /usr/local/lib,
you will need to set PKG_CONFIG_PATH using:
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
2) The included tests suite for libsamplerate needs libfftw3 which is
available here:
http://www.fftw.org/
If FFTW3 is not available, libsamplerate should still compile and
install without problems, but the test suite will not be as
comprehensive as it normally is.
Building
--------
Building and verifying libsamplerate is a four or five step process.
1) The first step is to run configure
./configure
which should print out something like the following:
checking build system type...
...
...
-=-=-=-=-=-=-=-=-= Configuration Complete =-=-=-=-=-=-=-=-=-=-
Configuration summary :
Version : ..................... X.Y.Z
Enable debugging : ............ no
Tools :
Compiler is GCC : ............. yes
GCC major version : ........... 3
Extra tools required for testing and examples :
Use FFTW : .................... yes
Have libsndfile : ............. yes
Installation directories :
Library directory : ........... /usr/local/lib
Program directory : ........... /usr/local/bin
Pkgconfig directory : ......... /usr/local/lib/pkgconfig
Compiling some other packages against libsamplerate may require
the addition of "/usr/local/lib/pkgconfig" to the
PKG_CONFIG_PATH environment variable.
There are a number of configure options. See the output of
configure when run with the --help command line option.
2) If all goes well with the above then compiling the library can be
done with
make
3) When that has finished, the test suite can be run using:
make check
4) The final step is to install the library. This step needs to be
carried out as the root user (or with sudo):
make install
This command will by default install the library in the directory
/usr/local/lib. It can be installed in other locations by using the
--prefix option in step 1).
5) On Linux, one more step is required, the registering of the library
with the system. This is done by running the following command
(also as the root user):
ldconfig -v

@ -1,158 +0,0 @@
## Process this file with automake to produce Makefile.in
DISTCHECK_CONFIGURE_FLAGS = --enable-werror
AM_CPPFLAGS = -I$(top_srcdir)/include
EXTRA_DIST = README.md autogen.sh libsamplerate.spec.in samplerate.pc.in \
Octave/generate_filter.m Octave/make_filter.m Octave/measure_filter.m \
Octave/Readme.md Win32/libsamplerate-0.def
pkgconfig_DATA = samplerate.pc
# Some people prefer "make test" to "make check".
test:
$(MAKE) check
########
# src/ #
########
lib_LTLIBRARIES = src/libsamplerate.la
include_HEADERS = include/samplerate.h
EXTRA_DIST += cmake CMakeLists.txt config.h.cmake docs/CMakeLists.txt \
examples/CMakeLists.txt src/CMakeLists.txt tests/CMakeLists.txt \
src/config.h.in src/Version_script.in src/check_asm.sh \
tests/streaming_test.c
CLEANFILES = src/src_sinc.s
# MinGW requires -no-undefined if a DLL is to be built.
src_libsamplerate_la_LDFLAGS = -no-undefined -version-info $(SHARED_VERSION_INFO) $(SHLIB_VERSION_ARG)
src_libsamplerate_la_SOURCES = src/samplerate.c src/src_sinc.c src/src_zoh.c src/src_linear.c \
src/common.h src/fastest_coeffs.h src/mid_qual_coeffs.h src/high_qual_coeffs.h
#-------------------------------------------------------------------------------
# An extra check for bad asm.
check-asm: src/check_asm.sh src/src_sinc.s src/src_linear.s src/src_zoh.s
@echo
@echo
$(top_srcdir)/src/check_asm.sh src/src_sinc.s
$(top_srcdir)/src/check_asm.sh src/src_linear.s
$(top_srcdir)/src/check_asm.sh src/src_zoh.s
@echo
@echo
.c.s:
$(CC) -S $(CFLAGS) $(CPPFLAGS) $(DEFAULT_INCLUDES) $< -o $@
# Disable autoheader.
AUTOHEADER=echo
########
# docs/ #
########
dist_doc_DATA = docs/SRC.png docs/SRC.css docs/index.md docs/license.md docs/history.md \
docs/download.md docs/lists.md docs/quality.md docs/win32.md docs/faq.md docs/api.md \
docs/api_simple.md docs/api_callback.md docs/api_full.md docs/api_misc.md docs/bugs.md
#############
# examples/ #
#############
if HAVE_LIBSNDFILE
noinst_PROGRAMS = examples/varispeed-play examples/timewarp-file
examples_varispeed_play_SOURCES = examples/varispeed-play.c examples/audio_out.c examples/audio_out.h
examples_varispeed_play_CFLAGS = $(SNDFILE_CFLAGS) $(AUDIO_CFLAGS)
examples_varispeed_play_LDADD = src/libsamplerate.la $(SNDFILE_LIBS) $(AUDIO_LIBS)
examples_timewarp_file_SOURCES = examples/timewarp-file.c
examples_timewarp_file_CFLAGS = $(SNDFILE_CFLAGS)
examples_timewarp_file_LDADD = src/libsamplerate.la $(SNDFILE_LIBS)
endif
##########
# tests/ #
##########
TESTS = \
tests/callback_hang_test \
tests/callback_test \
tests/clone_test \
tests/downsample_test \
tests/float_short_test \
tests/misc_test \
tests/multi_channel_test \
tests/nullptr_test \
tests/reset_test \
tests/simple_test \
tests/snr_bw_test \
tests/termination_test \
tests/throughput_test \
tests/varispeed_test
check_PROGRAMS = \
$(TESTS) \
tests/multichan_throughput_test \
tests/src-evaluate
#===============================================================================
tests_misc_test_SOURCES = tests/misc_test.c tests/util.c tests/util.h
tests_misc_test_LDADD = src/libsamplerate.la
tests_termination_test_SOURCES = tests/termination_test.c tests/util.c tests/util.h
tests_termination_test_LDADD = src/libsamplerate.la
tests_callback_hang_test_SOURCES = tests/callback_hang_test.c tests/util.c tests/util.h
tests_callback_hang_test_LDADD = src/libsamplerate.la
tests_simple_test_SOURCES = tests/simple_test.c tests/util.c tests/util.h
tests_simple_test_LDADD = src/libsamplerate.la
tests_reset_test_SOURCES = tests/reset_test.c tests/util.c tests/util.h
tests_reset_test_LDADD = src/libsamplerate.la
tests_multi_channel_test_SOURCES = tests/multi_channel_test.c tests/util.c tests/calc_snr.c
tests_multi_channel_test_CFLAGS = $(FFTW3_CFLAGS)
tests_multi_channel_test_LDADD = src/libsamplerate.la $(FFTW3_LIBS)
tests_snr_bw_test_SOURCES = tests/snr_bw_test.c tests/calc_snr.c tests/util.c tests/util.h
tests_snr_bw_test_CFLAGS = $(FFTW3_CFLAGS)
tests_snr_bw_test_LDADD = src/libsamplerate.la $(FFTW3_LIBS)
tests_callback_test_SOURCES = tests/callback_test.c tests/util.c tests/util.h
tests_callback_test_LDADD = src/libsamplerate.la
tests_float_short_test_SOURCES = tests/float_short_test.c tests/util.c tests/util.h
tests_float_short_test_LDADD = src/libsamplerate.la
tests_downsample_test_SOURCES = tests/downsample_test.c tests/util.c tests/util.h
tests_downsample_test_LDADD = src/libsamplerate.la
tests_varispeed_test_SOURCES = tests/varispeed_test.c tests/util.c tests/util.h tests/calc_snr.c
tests_varispeed_test_CFLAGS = $(FFTW3_CFLAGS)
tests_varispeed_test_LDADD = src/libsamplerate.la $(FFTW3_LIBS)
tests_clone_test_SOURCES = tests/clone_test.c tests/util.c tests/util.h
tests_clone_test_LDADD = src/libsamplerate.la
tests_nullptr_test_SOURCES = tests/nullptr_test.c tests/util.c tests/util.h
tests_nullptr_test_LDADD = src/libsamplerate.la
# This program is for evaluating other sample rate converters.
tests_throughput_test_SOURCES = tests/throughput_test.c tests/util.c tests/calc_snr.c
tests_throughput_test_CFLAGS = $(FFTW3_CFLAGS)
tests_throughput_test_LDADD = src/libsamplerate.la $(FFTW3_LIBS)
tests_multichan_throughput_test_SOURCES = tests/multichan_throughput_test.c tests/util.c tests/calc_snr.c
tests_multichan_throughput_test_CFLAGS = $(FFTW3_CFLAGS)
tests_multichan_throughput_test_LDADD = src/libsamplerate.la $(FFTW3_LIBS)
tests_src_evaluate_SOURCES = tests/src-evaluate.c tests/calc_snr.c tests/util.c
tests_src_evaluate_CFLAGS = $(SNDFILE_CFLAGS) $(FFTW3_CFLAGS)
tests_src_evaluate_LDADD = $(SNDFILE_LIBS) $(FFTW3_LIBS)

@ -1,81 +0,0 @@
Version 0.2.2 (2021-09-05)
* Fix CMake overlinking for examples (#146)
* Switch to GCC's visibility for hiding more implementation details
* Check GNU ld instead of gcc for exported symbols control logic in
configure.ac
* Disable static builds using Autotools by default. If you want static
libraries, pass --enable-static to ./configure
* ABI version incompatibility between Autotools and CMake build on Apple
platforms.
* Fixes and improvements for CMake build system.
* Fixes and improvements for Autotools build system.
* Switch to .xz over .bz2 for release tarballs.
* Minor bug fixes and updates.
Version 0.2.1 (2021-01-23)
* Fix incorrect passing of -version-info to libtool, causing a
regression on versioned file name of the shared library (#140).
* Fix time resolution on GNU/Hurd for throughput_test
* Update AUTHORS and release manager details
Version 0.2.0 (2021-01-21)
* API:
* Add `src_clone()` function to clone a SRC_STATE* handle
* Cleanup Autotools build system.
* Require C99 compiler
* Move `sndfile-resample` to sndfile-tools package
* Add missing `src_get_channels`() export to windows def file
* Fix macOS compile errors and modernize audio api on that platform
* Add Octave scripts to generate filter coefficients
* Fix two potential undefined behaviours
* Fix a buffer out-of-bounds read error in src/src_sinc.c
* Improve multichan_throughput_test
* Replace buggy implementationg of Duffs device by regular loop
* CMake:
* Fix CMake generated shared library ABI compliance with Autotools build
* Documentation:
* Move site to new URL: http://libsndfile.github.io/libsamplerate/
* Convert documentation pages from HTML to Markdown
* Use GitHub's Jekyll static site generator to generate static HTML pages
for site
Version 0.1.9 (2016-09-23)
* Relicense under 2 clause BSD license.
* Minor bug fixes and upates.
Version 0.1.8 (2011-08-15)
* Minor bug fixes and upates.
Version 0.1.7 (2009-02-14)
* Fix a segfault which occurs when memcpy is passed a bad length parameter.
* Fix compilation under MSVC.
Version 0.1.6 (2009-01-27)
* Minor bug fix in test suite (account for rounding error on x86_64).
Version 0.1.5 (2009-01-11)
* Optimisation resulting dramatic throughput improvements.
Version 0.1.4 (2008-07-02)
* Fix bug which causes a segfault with extremely low conversion ratios.
Version 0.1.3 (2008-03-23)
* Huge improvement to the quality of conversion with the
SRC_SINC_MEDIUM_QUALITY and SRC_SINC_BEST_QUALITY converters.
* Minor bug fixes.
Version 0.1.2 (2004-09-12)
* Fixed where callback based API wasn't being reset properly.
* Minor bug fixes.
Version 0.1.1 (2004-07-17)
* Fixed bug in callback based API.
* Fixed a bug brought to light by aggressive optimisations of gcc-3.4.
* Minor bug fixes.
Version 0.1.0 (2004-03-14)
* Added callback based API.
* Added a pair of functions for doing short to float and float to short
conversions on an arrays of data.
* Many minor bug fixes.

@ -1,27 +0,0 @@
# Generating Filter Coefficients
The scripts below are used in [GNU Octave][GNU Octave] which should be available
on most platforms including Linux, Mac and Windows.
On Debian and other Debian derived Linux distributions, Octave can be installed
using: `sudo apt install octave octave-signal`.
Filter coefficients can be generated as follows by running the `octave` command
in the same directory as the scripts and this Readme file:
```
octave:1> pkg load signal
octave:2> f = make_filter (8, 128, 100.3) ;
# f = make_fip_filter (8, 128, 100.3) ;
# Coeff. count : 4922
# Fudge factor : 1.2018769
# Pass band width : 0.0039062499 (should be 0.0039062500)
# Stop band atten. : 100.71 dB
# -3dB band Width : 0.490
# half length : 2464
# increment : 128
```
The parameters above generate the coefficient set used in `src/fastest_coeffs.h`.
[GNU Octave]: https://www.gnu.org/software/octave/

@ -1,35 +0,0 @@
function f = generate_filter (cycles, fudge_factor, increment, atten)
if nargin != 4,
error ("Need four args.") ;
endif
# Calclate N and make sure it is even.
N = fix (4 * cycles * fudge_factor * increment) ;
if rem (N, 2) != 0,
N = N - 1 ;
endif
# Generate the Sinc function.
m = -((N-1)/2):((N-1)/2) ;
f = sinc (m / fudge_factor / increment) ;
# Genertate the window function and apply it.
w = kaiser (N, (atten + 0.5) / 10) ;
w = w' ;
f = f .* w ;
f = f / sum (f) ;
endfunction
# Do not edit or modify anything in this comment block.
# The arch-tag line is a file identity tag for the GNU Arch
# revision control system.
#
# arch-tag: 7e57a3cb-3f5c-4346-bfcd-4da1e758e2a7

@ -1,134 +0,0 @@
function f = make_filter (cycles, increment, atten, filename)
# This works :
#
# f = make_filter (67, 128, 100.3) ;
# f = make_filter (13, 128, 100.5) ;
# f = make_filter (185, 4, 157.0) ;
#=======================================================================
if nargin < 3,
error ('Try make_filter (12, 32, 88, "output.txt")') ;
endif
if nargin < 4,
filename = 0 ;
elseif (isstr (filename) == 0),
error ("Fourth parameter must be a file name.") ;
endif
fudge_factor1 = 1.0 ;
f1 = generate_filter (cycles, fudge_factor1, increment, atten) ;
[stop_atten stop_band_start1 minus_3db] = measure_filter (f1, atten) ;
printf (" fudge_factor : %15.13f stop_band_start : %15.13f 1\n", fudge_factor1, stop_band_start1) ;
fudge_factor2 = 1.25 ;
f2 = generate_filter (cycles, fudge_factor2, increment, atten) ;
[stop_atten stop_band_start2 minus_3db] = measure_filter (f2, atten) ;
printf (" fudge_factor : %15.13f stop_band_start : %15.13f 2\n", fudge_factor2, stop_band_start2) ;
f = f1 ;
fudge_factor = fudge_factor1 ;
stop_band_start = stop_band_start1 ;
while ((stop_band_start1 - stop_band_start2) > 0.0000000001)
if (stop_band_start1 < stop_band_start2)
printf ("stop_band_start1 < stop_band_start2\n") ;
break ;
endif
fudge_factor = fudge_factor1 + (fudge_factor2 - fudge_factor1) / 2 ;
f = generate_filter (cycles, fudge_factor, increment, atten) ;
[stop_atten stop_band_start minus_3db] = measure_filter (f, atten) ;
if (stop_band_start > 1.0)
printf ("A %10.8f %10.8f %10.8f\n", fudge_factor1, fudge_factor, fudge_factor2) ;
continue ;
endif
if (stop_band_start < 0.5 / increment)
f2 = f ;
stop_band_start2 = stop_band_start ;
fudge_factor2 = fudge_factor ;
choice = 2 ;
else
f1 = f ;
stop_band_start1 = stop_band_start ;
fudge_factor1 = fudge_factor ;
choice = 1 ;
endif
printf (" fudge_factor : %15.13f stop_band_start : %15.13f %d\n", fudge_factor, stop_band_start, choice) ;
endwhile
printf ("\n") ;
#-------------------------------------------------------------------------------
# Grab only half the coefficients.
N = length (f) ;
f = increment * f' ;
if rem (length (f), 2) == 0,
index = find (f == max (f)) ;
index = min (index) - 1 ;
half_f = f (index:length (f)) ;
else
error ("Length should be even.") ;
endif
trailing_zeros = 4 - rem (length (half_f), 4) ;
#-------------------------------------------------------------------------------
# Print analysis.
printf ("# f = make_filter (%d, %d, %4.1f) ;\n", cycles, increment, atten) ;
printf ("# Coeff. count : %d\n", N) ;
printf ("# Fudge factor : %9.7f\n", fudge_factor) ;
printf ("# Pass band width : %12.10f (should be %12.10f)\n", stop_band_start, 0.5 / increment) ;
printf ("# Stop band atten. : %5.2f dB\n", abs (stop_atten)) ;
printf ("# -3dB band Width : %5.3f\n", 0.5 / increment / minus_3db) ;
printf ("# half length : %d\n", length (half_f) + trailing_zeros) ;
printf ("# increment : %d\n", increment) ;
if filename,
file = fopen (filename, "w") ;
if file == 0,
str = sprintf ("Error, not able to open '%s'", filename)
error (str) ;
endif
fprintf (file, "/*\n") ;
fprintf (file, "** f = make_filter (%d, %d, %4.1f) ;\n", cycles, increment, atten) ;
fprintf (file, "** Pass band width : %9.7f (should be %9.7f)\n", stop_band_start, 0.5 / increment) ;
fprintf (file, "** Stop band atten. : %5.2f dB\n", abs (stop_atten)) ;
fprintf (file, "** -3dB band width : %5.3f\n", 0.5 / increment / minus_3db) ;
fprintf (file, "** half length : %d\n", length (half_f)) ;
fprintf (file, "** increment : %d\n", increment) ;
fprintf (file, "*/\n\n") ;
for val = half_f,
fprintf (file, "% 24.20e,\n", val) ;
endfor
if trailing_zeros > 0,
for val = 2:trailing_zeros,
fprintf (file, " 0,\n") ;
endfor
fprintf (file, " 0\n") ;
endif
fclose (file) ;
endif
endfunction
# Do not edit or modify anything in this comment block.
# The arch-tag line is a file identity tag for the GNU Arch
# revision control system.
#
# arch-tag: 2f1ff4fa-ea6a-4e54-a5f8-dad55def9834

@ -1,70 +0,0 @@
function [stop_atten stop_band_start minus_3db] = measure_filter (f, atten)
spec_len = 400000 ;
# Calculate the spectrum.
spec = 20 * log10 (abs (fft ([f zeros(1, spec_len - length (f))]))) ;
spec = spec (1:spec_len/2) ;
#-------------------------------------------------------------------------------
# Find the first null which starts off the stop band.
first_null = 0 ;
for k = 2:length (spec) - 1,
if spec (k) < -0.8 * atten && spec (k-1) > spec (k) && spec (k) < spec (k + 1),
first_null = k ;
break
endif
endfor
#-------------------------------------------------------------------------------
# Find the stop band minimum attenuation.
stop_atten = max (spec (first_null:length (spec))) ;
#-------------------------------------------------------------------------------
# Find the x position on the transition band which has the same attenuation.
atten_start = 0 ;
for k = 1:first_null,
if spec (k) > stop_atten && spec (k + 1) < stop_atten,
atten_start = k ;
break ;
endif
endfor
atten_start = atten_start - 1 ; # Arrays are 1 based so subtract 1.
stop_band_start = atten_start + (stop_atten - spec (atten_start)) / (spec (atten_start+1) - spec (atten_start)) ;
stop_band_start = stop_band_start / spec_len ;
#-------------------------------------------------------------------------------
# Find -3db point.
minus_3db = 0 ;
for k = 1:first_null,
if spec (k) > -3.0 && spec (k + 1) < -3.0,
minus_3db = k ;
break ;
endif
endfor
minus_3db = minus_3db - 1 ; # Arrays are 1 based so subtract 1.
minus_3db = minus_3db + (stop_atten - spec (minus_3db)) / (spec (minus_3db+1) - spec (minus_3db)) ;
minus_3db = minus_3db / spec_len ;
endfunction
# Do not edit or modify anything in this comment block.
# The arch-tag line is a file identity tag for the GNU Arch
# revision control system.
#
# arch-tag: cc2bc9a2-d387-4fed-aa0a-570e91f17c99

@ -1,62 +0,0 @@
![Logo](docs/SRC.png)
This is libsamplerate, `0.2.2`.
libsamplerate (also known as Secret Rabbit Code) is a library for performing sample rate conversion of audio data.
* The [`src/`](https://github.com/libsndfile/libsamplerate/tree/master/src) directory contains the source code for library itself.
* The [`docs/`](https://github.com/libsndfile/libsamplerate/tree/master/docs) directory contains the libsamplerate documentation.
* The [`examples/`](https://github.com/libsndfile/libsamplerate/tree/master/examples) directory contains examples of how to write code using libsamplerate.
* The [`tests/`](https://github.com/libsndfile/libsamplerate/tree/master/tests) directory contains programs which link against libsamplerate and test its functionality.
* The [`Win32/`](https://github.com/libsndfile/libsamplerate/tree/master/Win32) directory contains files to allow libsamplerate to compile under Win32 with the Microsoft Visual C++ compiler.
Additional references:
* [Official website](http://libsndfile.github.io/libsamplerate//)
* [GitHub](https://github.com/libsndfile/libsamplerate)
---
## Build Status
| Branch | Status |
|----------------|-------------------------------------------------------------------------------------------------------------------|
| `master` | ![Build](https://github.com/libsndfile/libsamplerate/workflows/Build/badge.svg) |
Branches [actively built](https://github.com/libsndfile/libsamplerate/actions) by GitHub Actions.
---
## Win32
There are detailed instructions for building libsamplerate on Win32 in the file [`docs/win32.md`](https://github.com/libsndfile/libsamplerate/tree/master/docs/win32.md).
## macOS
Building on macOS should be the same as building it on any other Unix platform.
## Other Platforms
To compile libsamplerate on platforms which have a Bourne compatible shell, an ANSI C compiler and a make utility should require no more that the following three commands:
```bash
./configure
make
make install
```
## CMake
There is a new [CMake](https://cmake.org/download/)-based build system available:
```bash
mkdir build
cd build
cmake ..
make
```
* Use `cmake -DCMAKE_BUILD_TYPE=Release ..` to make a release build.
* Use `cmake -DBUILD_SHARED_LIBS=ON ..` to build a shared library.
## Contacts
libsamplerate was written by [Erik de Castro Lopo](mailto:erikd@mega-nerd.com).

@ -1,30 +0,0 @@
EXPORTS
src_new @1
src_delete @2
src_get_name @10
src_get_description @11
src_get_version @12
src_process @20
src_reset @21
src_set_ratio @22
src_clone @23
src_error @30
src_strerror @31
src_simple @40
src_is_valid_ratio @50
src_callback_new @60
src_callback_read @61
src_short_to_float_array @70
src_float_to_short_array @71
src_int_to_float_array @80
src_float_to_int_array @81
src_get_channels @90

@ -1,119 +0,0 @@
#!/bin/sh
# Run this to set up the build system: configure, makefiles, etc.
# (based on the version in enlightenment's cvs)
package="libsamplerate"
olddir=`pwd`
srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
cd "$srcdir"
DIE=0
echo "checking for autoconf... "
(autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have autoconf installed to compile $package."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
VERSIONGREP="sed -e s/.*[^0-9\.]\([0-9][0-9]*\.[0-9][0-9]*\).*/\1/"
VERSIONMKMAJ="sed -e s/\([0-9][0-9]*\)[^0-9].*/\\1/"
VERSIONMKMIN="sed -e s/.*[0-9][0-9]*\.//"
# do we need automake?
if test -r Makefile.am; then
AM_OPTIONS=`fgrep AUTOMAKE_OPTIONS Makefile.am`
AM_NEEDED=`echo $AM_OPTIONS | $VERSIONGREP`
if test x"$AM_NEEDED" = "x$AM_OPTIONS"; then
AM_NEEDED=""
fi
if test -z $AM_NEEDED; then
echo -n "checking for automake... "
AUTOMAKE=automake
ACLOCAL=aclocal
if ($AUTOMAKE --version < /dev/null > /dev/null 2>&1); then
echo "yes"
else
echo "no"
AUTOMAKE=
fi
else
echo -n "checking for automake $AM_NEEDED or later... "
majneeded=`echo $AM_NEEDED | $VERSIONMKMAJ`
minneeded=`echo $AM_NEEDED | $VERSIONMKMIN`
for am in automake-$AM_NEEDED automake$AM_NEEDED \
automake automake-1.7 automake-1.8 automake-1.9 automake-1.10; do
($am --version < /dev/null > /dev/null 2>&1) || continue
ver=`$am --version < /dev/null | head -n 1 | $VERSIONGREP`
maj=`echo $ver | $VERSIONMKMAJ`
min=`echo $ver | $VERSIONMKMIN`
if test $maj -eq $majneeded -a $min -ge $minneeded; then
AUTOMAKE=$am
echo $AUTOMAKE
break
fi
done
test -z $AUTOMAKE && echo "no"
echo -n "checking for aclocal $AM_NEEDED or later... "
for ac in aclocal-$AM_NEEDED aclocal$AM_NEEDED \
aclocal aclocal-1.7 aclocal-1.8 aclocal-1.9 aclocal-1.10; do
($ac --version < /dev/null > /dev/null 2>&1) || continue
ver=`$ac --version < /dev/null | head -n 1 | $VERSIONGREP`
maj=`echo $ver | $VERSIONMKMAJ`
min=`echo $ver | $VERSIONMKMIN`
if test $maj -eq $majneeded -a $min -ge $minneeded; then
ACLOCAL=$ac
echo $ACLOCAL
break
fi
done
test -z $ACLOCAL && echo "no"
fi
test -z $AUTOMAKE || test -z $ACLOCAL && {
echo
echo "You must have automake installed to compile $package."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
exit 1
}
fi
echo -n "checking for libtool... "
for LIBTOOLIZE in libtoolize glibtoolize nope; do
($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 && break
done
if test x$LIBTOOLIZE = xnope; then
echo "nope."
LIBTOOLIZE=libtoolize
else
echo $LIBTOOLIZE
fi
($LIBTOOLIZE --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "You must have libtool installed to compile $package."
echo "Download the appropriate package for your system,"
echo "or get the source from one of the GNU ftp sites"
echo "listed in http://www.gnu.org/order/ftp.html"
DIE=1
}
if test "$DIE" -eq 1; then
exit 1
fi
echo "Generating configuration files for $package, please wait...."
echo " $ACLOCAL $ACLOCAL_FLAGS"
$ACLOCAL $ACLOCAL_FLAGS || exit 1
echo " $LIBTOOLIZE --automake"
$LIBTOOLIZE --automake || exit 1
echo " autoheader"
autoheader || exit 1
echo " $AUTOMAKE --add-missing $AUTOMAKE_FLAGS"
$AUTOMAKE --add-missing $AUTOMAKE_FLAGS || exit 1
echo " autoconf"
autoconf || exit 1

@ -1,81 +0,0 @@
macro(CLIP_MODE)
set(CLIP_MODE_POSITIVE_MESSAGE "Target processor clips on positive float to int conversion")
set(CLIP_MODE_NEGATIVE_MESSAGE "Target processor clips on negative float to int conversion")
message(STATUS "Checking processor clipping capabilities...")
if(CMAKE_CROSSCOMPILING)
set(CLIP_MSG "disabled")
set(CPU_CLIPS_POSITIVE FALSE CACHE BOOL ${CLIP_MODE_POSITIVE_MESSAGE})
set(CPU_CLIPS_NEGATIVE FALSE CACHE BOOL ${CLIP_MODE_NEGATIVE_MESSAGE})
else()
include(CheckCSourceRuns)
include(CMakePushCheckState)
cmake_push_check_state(RESET)
if(MATH_LIBRARY)
list(APPEND CMAKE_REQUIRED_LIBRARIES ${MATH_LIBRARY})
endif()
check_c_source_runs(
"
#include <math.h>
int main (void)
{ double fval ;
int k, ival ;
fval = 1.0 * 0x7FFFFFFF ;
for (k = 0 ; k < 100 ; k++)
{ ival = (lrint (fval)) >> 24 ;
if (ival != 127)
return 1 ;
fval *= 1.2499999 ;
} ;
return 0 ;
}
"
CPU_CLIPS_POSITIVE)
check_c_source_runs(
"
#include <math.h>
int main (void)
{ double fval ;
int k, ival ;
fval = -8.0 * 0x10000000 ;
for (k = 0 ; k < 100 ; k++)
{ ival = (lrint (fval)) >> 24 ;
if (ival != -128)
return 1 ;
fval *= 1.2499999 ;
} ;
return 0 ;
}
"
CPU_CLIPS_NEGATIVE)
cmake_pop_check_state()
if(CPU_CLIPS_POSITIVE AND CPU_CLIPS_NEGATIVE)
set(CLIP_MSG "both")
elseif(CPU_CLIPS_POSITIVE)
set(CLIP_MSG "positive")
elseif(CPU_CLIPS_NEGATIVE)
set(CLIP_MSG "negative")
else()
set(CLIP_MSG "none")
endif()
endif()
message(STATUS "Checking processor clipping capabilities... ${CLIP_MSG}")
endmacro()

@ -1,88 +0,0 @@
# Adapted from: https://github.com/wjakob/layerlab/blob/master/cmake/FindFFTW.cmake
# Copyright (c) 2015, Wenzel Jakob
# All rights reserved.
#
# 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.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# - Find FFTW3
# Find the native FFTW3 includes and library
#
# Cache variables:
#
# FFTW3_INCLUDE_DIR - where to find fftw3.h
# FFTW3_LIBRARY - Path to FFTW3 libray.
# FFTW3_ROOT - Root of FFTW3 installation.
#
# User variables:
#
# FFTW3_INCLUDE_DIRS - where to find fftw3.h
# FFTW3_LIBRARIES - List of libraries when using FFTW3.
# FFTW3_FOUND - True if FFTW3 found.
if(FFTW3_INCLUDE_DIR)
# Already in cache, be silent
set(FFTW3_FIND_QUIETLY TRUE)
endif(FFTW3_INCLUDE_DIR)
find_package(PkgConfig QUIET)
pkg_check_modules(PC_FFTW3 QUIET fftw3)
set(FFTW3_VERSION ${PC_FFTW3_VERSION})
find_path(FFTW3_INCLUDE_DIR fftw3.h
HINTS
${PC_FFTW3_INCLUDEDIR}
${PC_FFTW3_INCLUDE_DIRS}
${FFTW3_ROOT})
find_library(FFTW3_LIBRARY NAMES fftw3
HINTS
${PC_FFTW3_LIBDIR}
${PC_FFTW3_LIBRARY_DIRS}
${FFTW3_ROOT})
# handle the QUIETLY and REQUIRED arguments and set FFTW3_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(FFTW3
REQUIRED_VARS
FFTW3_LIBRARY
FFTW3_INCLUDE_DIR
VERSION_VAR
FFTW3_VERSION)
if(FFTW3_FOUND)
set(FFTW3_LIBRARIES ${FFTW3_LIBRARY})
set(FFTW3_INCLUDE_DIRS ${FFTW3_INCLUDE_DIR})
if(NOT TARGET FFTW3::fftw3)
add_library(FFTW3::fftw3 UNKNOWN IMPORTED)
set_target_properties(FFTW3::fftw3 PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${FFTW3_INCLUDE_DIR}"
IMPORTED_LOCATION "${FFTW3_LIBRARY}"
)
endif()
endif()
mark_as_advanced(FFTW3_LIBRARY FFTW3_INCLUDE_DIR)

@ -1,63 +0,0 @@
# - Find FLAC
# Find the native FLAC includes and libraries
#
# FLAC_INCLUDE_DIRS - where to find FLAC headers.
# FLAC_LIBRARIES - List of libraries when using libFLAC.
# FLAC_FOUND - True if libFLAC found.
# FLAC_DEFINITIONS - FLAC compile definitons
if(FLAC_INCLUDE_DIR)
# Already in cache, be silent
set(FLAC_FIND_QUIETLY TRUE)
endif()
find_package(Ogg QUIET)
find_package(PkgConfig QUIET)
pkg_check_modules(PC_FLAC QUIET flac)
set(FLAC_VERSION ${PC_FLAC_VERSION})
find_path(FLAC_INCLUDE_DIR FLAC/stream_decoder.h
HINTS
${PC_FLAC_INCLUDEDIR}
${PC_FLAC_INCLUDE_DIRS}
${FLAC_ROOT})
# MSVC built libraries can name them *_static, which is good as it
# distinguishes import libraries from static libraries with the same extension.
find_library(FLAC_LIBRARY
NAMES
FLAC
libFLAC
libFLAC_dynamic
libFLAC_static
HINTS
${PC_FLAC_LIBDIR}
${PC_FLAC_LIBRARY_DIRS}
${FLAC_ROOT})
# Handle the QUIETLY and REQUIRED arguments and set FLAC_FOUND to TRUE if
# all listed variables are TRUE.
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(FLAC
REQUIRED_VARS
FLAC_LIBRARY
FLAC_INCLUDE_DIR
Ogg_FOUND
VERSION_VAR
FLAC_VERSION)
if(FLAC_FOUND)
set(FLAC_INCLUDE_DIRS ${FLAC_INCLUDE_DIR} ${Ogg_INCLUDE_DIRS})
set(FLAC_LIBRARIES ${FLAC_LIBRARY} ${Ogg_LIBRARIES})
if(NOT TARGET FLAC::FLAC)
add_library(FLAC::FLAC UNKNOWN IMPORTED)
set_target_properties(FLAC::FLAC PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${FLAC_INCLUDE_DIR}"
IMPORTED_LOCATION "${FLAC_LIBRARY}"
INTERFACE_LINK_LIBRARIES Ogg::ogg)
endif()
endif()
mark_as_advanced(FLAC_INCLUDE_DIR FLAC_LIBRARY)

@ -1,57 +0,0 @@
# - Find ogg
# Find the native ogg includes and libraries
#
# Ogg_INCLUDE_DIRS - where to find ogg.h, etc.
# Ogg_LIBRARIES - List of libraries when using ogg.
# Ogg_FOUND - True if ogg found.
if(Ogg_INCLUDE_DIR)
# Already in cache, be silent
set(Ogg_FIND_QUIETLY TRUE)
endif()
find_package(PkgConfig QUIET)
pkg_check_modules(PC_Ogg QUIET ogg)
set(Ogg_VERSION ${PC_Ogg_VERSION})
find_path(Ogg_INCLUDE_DIR ogg/ogg.h
HINTS
${PC_Ogg_INCLUDEDIR}
${PC_Ogg_INCLUDE_DIRS}
${Ogg_ROOT})
# MSVC built ogg may be named ogg_static.
# The provided project files name the library with the lib prefix.
find_library(Ogg_LIBRARY
NAMES
ogg
ogg_static
libogg
libogg_static
HINTS
${PC_Ogg_LIBDIR}
${PC_Ogg_LIBRARY_DIRS}
${Ogg_ROOT})
# Handle the QUIETLY and REQUIRED arguments and set Ogg_FOUND
# to TRUE if all listed variables are TRUE.
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Ogg
REQUIRED_VARS
Ogg_LIBRARY
Ogg_INCLUDE_DIR
VERSION_VAR
Ogg_VERSION)
if(Ogg_FOUND)
set(Ogg_LIBRARIES ${Ogg_LIBRARY})
set(Ogg_INCLUDE_DIRS ${Ogg_INCLUDE_DIR})
if(NOT TARGET Ogg::ogg)
add_library(Ogg::ogg UNKNOWN IMPORTED)
set_target_properties(Ogg::ogg PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Ogg_INCLUDE_DIR}"
IMPORTED_LOCATION "${Ogg_LIBRARY}")
endif()
endif()
mark_as_advanced(Ogg_INCLUDE_DIR Ogg_LIBRARY)

@ -1,64 +0,0 @@
# - Find opus
# Find the native opus includes and libraries
#
# OPUS_INCLUDE_DIRS - where to find opus.h, etc.
# OPUS_LIBRARIES - List of libraries when using opus.
# OPUS_FOUND - True if Opus found.
if(OPUS_INCLUDE_DIR)
# Already in cache, be silent
set(OPUS_FIND_QUIETLY TRUE)
endif()
find_package(Ogg QUIET)
find_package(PkgConfig QUIET)
pkg_check_modules(PC_OPUS QUIET opus)
set(OPUS_VERSION ${PC_OPUS_VERSION})
find_path(OPUS_INCLUDE_DIR opus/opus.h
HINTS
${PC_OPUS_INCLUDEDIR}
${PC_OPUS_INCLUDE_DIRS}
${OPUS_ROOT})
# MSVC built opus may be named opus_static.
# The provided project files name the library with the lib prefix.
find_library(OPUS_LIBRARY
NAMES
opus
opus_static
libopus
libopus_static
HINTS
${PC_OPUS_LIBDIR}
${PC_OPUS_LIBRARY_DIRS}
${OPUS_ROOT})
# Handle the QUIETLY and REQUIRED arguments and set OPUS_FOUND
# to TRUE if all listed variables are TRUE.
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Opus
REQUIRED_VARS
OPUS_LIBRARY
OPUS_INCLUDE_DIR
Ogg_FOUND
VERSION_VAR
OPUS_VERSION)
if(OPUS_FOUND)
set(OPUS_LIBRARIES ${OPUS_LIBRARY})
set(OPUS_INCLUDE_DIRS ${OPUS_INCLUDE_DIR} ${Ogg_INCLUDE_DIRS})
if(NOT TARGET Opus::opus)
add_library(Opus::opus UNKNOWN IMPORTED)
set_target_properties(Opus::opus PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${OPUS_INCLUDE_DIR}"
IMPORTED_LOCATION "${OPUS_LIBRARY}"
INTERFACE_LINK_LIBRARIES Ogg::ogg)
endif()
endif()
mark_as_advanced(OPUS_INCLUDE_DIR OPUS_LIBRARY)

@ -1,57 +0,0 @@
# Variables defined:
# SNDFILE_FOUND
# SNDFILE_INCLUDE_DIR
# SNDFILE_LIBRARY
#
# Environment variables used:
# SNDFILE_ROOT
if(SndFile_INCLUDE_DIR)
# Already in cache, be silent
set(SndFile_FIND_QUIETLY TRUE)
endif(SndFile_INCLUDE_DIR)
find_package(PkgConfig QUIET)
pkg_check_modules(PC_SndFile QUIET sndfile)
set(SndFile_VERSION ${PC_SndFile_VERSION})
find_package(Vorbis COMPONENTS Enc QUIET)
find_package(FLAC QUIET)
find_package(Opus QUIET)
find_path(SndFile_INCLUDE_DIR sndfile.h
HINTS
${PC_SndFile_INCLUDEDIR}
${PC_SndFile_INCLUDE_DIRS}
${SndFile_ROOT})
find_library(SndFile_LIBRARY NAMES sndfile
HINTS
${PC_SndFile_LIBDIR}
${PC_SndFile_LIBRARY_DIRS}
${SndFile_ROOT})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SndFile
REQUIRED_VARS
SndFile_LIBRARY
SndFile_INCLUDE_DIR
VERSION_VAR
SndFile_VERSION)
if(SndFile_FOUND)
set(SndFile_LIBRARIES ${SndFile_LIBRARY} ${Vorbis_Enc_LIBRARIES} ${FLAC_LIBRARIES} ${OPUS_LIBRARIES})
set(SndFile_INCLUDE_DIRS ${SndFile_INCLUDE_DIR} ${Vorbis_Enc_INCLUDE_DIRS} ${FLAC_INCLUDE_DIRS} ${OPUS_INCLUDE_DIRS})
if(NOT TARGET SndFile::sndfile)
add_library(SndFile::sndfile UNKNOWN IMPORTED)
set_target_properties(SndFile::sndfile PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${SndFile_INCLUDE_DIR}"
IMPORTED_LOCATION "${SndFile_LIBRARY}"
INTERFACE_LINK_LIBRARIES "Vorbis::vorbisenc;Opus::opus;FLAC::FLAC")
endif()
endif()
mark_as_advanced(SndFile_LIBRARY SndFile_INCLUDE_DIR)

@ -1,204 +0,0 @@
#[=======================================================================[.rst:
FindVorbis
----------
Finds the native vorbis, vorbisenc amd vorbisfile includes and libraries.
Imported Targets
^^^^^^^^^^^^^^^^
This module provides the following imported targets, if found:
``Vorbis::vorbis``
The Vorbis library
``Vorbis::vorbisenc``
The VorbisEnc library
``Vorbis::vorbisfile``
The VorbisFile library
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``Vorbis_Vorbis_INCLUDE_DIRS``
List of include directories when using vorbis.
``Vorbis_Enc_INCLUDE_DIRS``
List of include directories when using vorbisenc.
``Vorbis_File_INCLUDE_DIRS``
List of include directories when using vorbisfile.
``Vorbis_Vorbis_LIBRARIES``
List of libraries when using vorbis.
``Vorbis_Enc_LIBRARIES``
List of libraries when using vorbisenc.
``Vorbis_File_LIBRARIES``
List of libraries when using vorbisfile.
``Vorbis_FOUND``
True if vorbis and requested components found.
``Vorbis_Vorbis_FOUND``
True if vorbis found.
``Vorbis_Enc_FOUND``
True if vorbisenc found.
``Vorbis_Enc_FOUND``
True if vorbisfile found.
Cache variables
^^^^^^^^^^^^^^^
The following cache variables may also be set:
``Vorbis_Vorbis_INCLUDE_DIR``
The directory containing ``vorbis/vorbis.h``.
``Vorbis_Enc_INCLUDE_DIR``
The directory containing ``vorbis/vorbisenc.h``.
``Vorbis_File_INCLUDE_DIR``
The directory containing ``vorbis/vorbisenc.h``.
``Vorbis_Vorbis_LIBRARY``
The path to the vorbis library.
``Vorbis_Enc_LIBRARY``
The path to the vorbisenc library.
``Vorbis_File_LIBRARY``
The path to the vorbisfile library.
Hints
^^^^^
A user may set ``Vorbis_ROOT`` to a vorbis installation root to tell this module where to look.
#]=======================================================================]
if(Vorbis_Vorbis_INCLUDE_DIR)
# Already in cache, be silent
set(Vorbis_FIND_QUIETLY TRUE)
endif()
set(Vorbis_Vorbis_FIND_QUIETLY TRUE)
set(Vorbis_Enc_FIND_QUIETLY TRUE)
set(Vorbis_File_FIND_QUIETLY TRUE)
find_package(Ogg QUIET)
find_package(PkgConfig QUIET)
pkg_check_modules(PC_Vorbis_Vorbis QUIET vorbis)
pkg_check_modules(PC_Vorbis_Enc QUIET vorbisenc)
pkg_check_modules(PC_Vorbis_File QUIET vorbisfile)
set(Vorbis_VERSION ${PC_Vorbis_Vorbis_VERSION})
find_path(Vorbis_Vorbis_INCLUDE_DIR vorbis/codec.h
HINTS
${PC_Vorbis_Vorbis_INCLUDEDIR}
${PC_Vorbis_Vorbis_INCLUDE_DIRS}
${Vorbis_ROOT})
find_path(Vorbis_Enc_INCLUDE_DIR vorbis/vorbisenc.h
HINTS
${PC_Vorbis_Enc_INCLUDEDIR}
${PC_Vorbis_Enc_INCLUDE_DIRS}
${Vorbis_ROOT})
find_path(Vorbis_File_INCLUDE_DIR vorbis/vorbisfile.h
HINTS
${PC_Vorbis_File_INCLUDEDIR}
${PC_Vorbis_File_INCLUDE_DIRS}
${Vorbis_ROOT})
find_library(Vorbis_Vorbis_LIBRARY
NAMES
vorbis
vorbis_static
libvorbis
libvorbis_static
HINTS
${PC_Vorbis_Vorbis_LIBDIR}
${PC_Vorbis_Vorbis_LIBRARY_DIRS}
${Vorbis_ROOT})
find_library(Vorbis_Enc_LIBRARY
NAMES
vorbisenc
vorbisenc_static
libvorbisenc
libvorbisenc_static
HINTS
${PC_Vorbis_Enc_LIBDIR}
${PC_Vorbis_Enc_LIBRARY_DIRS}
${Vorbis_ROOT})
find_library(Vorbis_File_LIBRARY
NAMES
vorbisfile
vorbisfile_static
libvorbisfile
libvorbisfile_static
HINTS
${PC_Vorbis_File_LIBDIR}
${PC_Vorbis_File_LIBRARY_DIRS}
${Vorbis_ROOT})
include(FindPackageHandleStandardArgs)
if(Vorbis_Vorbis_LIBRARY AND Vorbis_Vorbis_INCLUDE_DIR AND Ogg_FOUND)
set(Vorbis_Vorbis_FOUND TRUE)
endif()
if(Vorbis_Enc_LIBRARY AND Vorbis_Enc_INCLUDE_DIR AND Vorbis_Vorbis_FOUND)
set(Vorbis_Enc_FOUND TRUE)
endif()
if(Vorbis_Vorbis_FOUND AND Vorbis_File_LIBRARY AND Vorbis_File_INCLUDE_DIR)
set(Vorbis_File_FOUND TRUE)
endif()
find_package_handle_standard_args(Vorbis
REQUIRED_VARS
Vorbis_Vorbis_LIBRARY
Vorbis_Vorbis_INCLUDE_DIR
Ogg_FOUND
HANDLE_COMPONENTS
VERSION_VAR Vorbis_VERSION)
if(Vorbis_Vorbis_FOUND)
set(Vorbis_Vorbis_INCLUDE_DIRS ${Vorbis_Vorbis_INCLUDE_DIR} ${Ogg_INCLUDE_DIRS})
set(Vorbis_Vorbis_LIBRARIES ${Vorbis_Vorbis_LIBRARY} ${Ogg_LIBRARIES})
if(NOT TARGET Vorbis::vorbis)
add_library(Vorbis::vorbis UNKNOWN IMPORTED)
set_target_properties(Vorbis::vorbis PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Vorbis_Vorbis_INCLUDE_DIR}"
IMPORTED_LOCATION "${Vorbis_Vorbis_LIBRARY}"
INTERFACE_LINK_LIBRARIES Ogg::ogg
)
endif()
if(Vorbis_Enc_FOUND)
set(Vorbis_Enc_INCLUDE_DIRS ${Vorbis_Enc_INCLUDE_DIR} ${Ogg_INCLUDE_DIRS})
set(Vorbis_Enc_LIBRARIES ${Vorbis_Enc_LIBRARY} ${Vorbis_Vorbis_LIBRARIES})
if(NOT TARGET Vorbis::vorbisenc)
add_library(Vorbis::vorbisenc UNKNOWN IMPORTED)
set_target_properties(Vorbis::vorbisenc PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Vorbis_Enc_INCLUDE_DIR}"
IMPORTED_LOCATION "${Vorbis_Enc_LIBRARY}"
INTERFACE_LINK_LIBRARIES Vorbis::vorbis
)
endif()
endif()
if(Vorbis_File_FOUND)
set(Vorbis_File_INCLUDE_DIRS ${Vorbis_File_INCLUDE_DIR} ${Ogg_INCLUDE_DIRS})
set(Vorbis_File_LIBRARIES ${Vorbis_File_LIBRARY} ${Vorbis_Vorbis_LIBRARIES})
if(NOT TARGET Vorbis::vorbisfile)
add_library(Vorbis::vorbisfile UNKNOWN IMPORTED)
set_target_properties(Vorbis::vorbisfile PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${Vorbis_File_INCLUDE_DIR}"
IMPORTED_LOCATION "${Vorbis_File_LIBRARY}"
INTERFACE_LINK_LIBRARIES Vorbis::vorbis
)
endif()
endif()
endif()
mark_as_advanced(Vorbis_Vorbis_INCLUDE_DIR Vorbis_Vorbis_LIBRARY)
mark_as_advanced(Vorbis_Enc_INCLUDE_DIR Vorbis_Enc_LIBRARY)
mark_as_advanced(Vorbis_File_INCLUDE_DIR Vorbis_File_LIBRARY)

@ -1 +0,0 @@
include(${CMAKE_CURRENT_LIST_DIR}/SampleRateTargets.cmake)

@ -1,76 +0,0 @@
/* config.h - generated by CMake. */
/* Name of package */
#define PACKAGE "${PROJECT_NAME}"
/* Version number of package */
#define VERSION "${PROJECT_VERSION}"
/* Target processor clips on negative float to int conversion. */
#cmakedefine01 CPU_CLIPS_NEGATIVE
/* Target processor clips on positive float to int conversion. */
#cmakedefine01 CPU_CLIPS_POSITIVE
/* Target processor is big endian. */
#cmakedefine01 CPU_IS_BIG_ENDIAN
/* Target processor is little endian. */
#cmakedefine01 CPU_IS_LITTLE_ENDIAN
/* Define to 1 if you have the `alarm' function. */
#cmakedefine01 HAVE_ALARM
/* Define to 1 if you have the <alsa/asoundlib.h> header file. */
#cmakedefine01 HAVE_ALSA
/* Set to 1 if you have libfftw3. */
#cmakedefine01 HAVE_FFTW3
/* Define if you have C99's lrint function. */
#cmakedefine01 HAVE_LRINT
/* Define if you have C99's lrintf function. */
#cmakedefine01 HAVE_LRINTF
/* Define to 1 if you have the <immintrin.h> header file. */
#cmakedefine HAVE_IMMINTRIN_H
/* Define if you have signal SIGALRM. */
#cmakedefine01 HAVE_SIGALRM
/* Define to 1 if you have the `signal' function. */
#cmakedefine01 HAVE_SIGNAL
/* Set to 1 if you have libsndfile. */
#cmakedefine01 HAVE_SNDFILE
/* Define to 1 if you have the <stdbool.h> header file. */
#cmakedefine HAVE_STDBOOL_H
/* Define to 1 if you have the <stdint.h> header file. */
#cmakedefine01 HAVE_STDINT_H
/* Define to 1 if you have the <sys/times.h> header file. */
#cmakedefine01 HAVE_SYS_TIMES_H
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H
/* Define to 1 if the compiler supports simple visibility declarations. */
#cmakedefine HAVE_VISIBILITY
/* define fast samplerate convertor */
#cmakedefine ENABLE_SINC_FAST_CONVERTER
/* define balanced samplerate convertor */
#cmakedefine ENABLE_SINC_MEDIUM_CONVERTER
/* define best samplerate convertor */
#cmakedefine ENABLE_SINC_BEST_CONVERTER
/* The size of `int', as computed by sizeof. */
#define SIZEOF_INT ${SIZEOF_INT}
/* The size of `long', as computed by sizeof. */
#define SIZEOF_LONG ${SIZEOF_LONG}

@ -1,400 +0,0 @@
# Copyright (C) 2002-2021 Erik de Castro Lopo (erikd AT mega-nerd DOT com).
dnl Require autoconf version >= 2.69)
AC_PREREQ([2.69])
AC_INIT([libsamplerate],[0.2.2],[erikd@mega-nerd.com],
[libsamplerate],[https://github.com/libsndfile/libsamplerate/])
dnl Check whether we want to set defaults for CFLAGS, CPPFLAGS and LDFLAGS
AC_MSG_CHECKING([whether configure should try to set CFLAGS/CPPFLAGS/LDFLAGS])
AS_IF([test "x${CFLAGS+set}" = "xset" || test "x${CPPFLAGS+set}" = "xset" || test "x${LDFLAGS+set}" = "xset"], [
enable_flags_setting=no
: ${CFLAGS=""}
], [
enable_flags_setting=yes
dnl Set to empty flags so AC_PROG_CC does not add -g -O2
CFLAGS=""
])
AC_MSG_RESULT([${enable_flags_setting}])
dnl Put config stuff in 'build-aux'.
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_SRCDIR([src/samplerate.c])
AC_CANONICAL_HOST
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_HEADERS([src/config.h])
AM_INIT_AUTOMAKE([1.14 foreign dist-xz no-dist-gzip subdir-objects serial-tests])
AM_SILENT_RULES([yes])
dnl ====================================================================================
AC_PROG_CC
AC_PROG_CC_C99
AS_IF([test "x$ac_cv_prog_cc_c99" = "xno"], [
AC_MSG_ERROR([libsamplerate requires a C99 capable compiler!])
])
AC_LANG([C])
AX_COMPILER_VENDOR
AX_COMPILER_VERSION
AC_PROG_SED
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
AC_PROG_MKDIR_P
PKG_PROG_PKG_CONFIG
dnl Catch ancient versions of pkg-config below 0.27
AX_REQUIRE_DEFINED([PKG_INSTALLDIR])
PKG_INSTALLDIR
LT_INIT([disable-static])
LT_PROG_RC
dnl ====================================================================================
dnl Rules for library version information:
dnl
dnl 1. Start with version information of `0:0:0' for each libtool library.
dnl 2. Update the version information only immediately before a public release of
dnl your software. More frequent updates are unnecessary, and only guarantee
dnl that the current interface number gets larger faster.
dnl 3. If the library source code has changed at all since the last update, then
dnl increment revision (`c:r:a' becomes `c:r+1:a').
dnl 4. If any interfaces have been added, removed, or changed since the last update,
dnl increment current, and set revision to 0.
dnl 5. If any interfaces have been added since the last public release, then increment
dnl age.
dnl 6. If any interfaces have been removed since the last public release, then set age
dnl to 0.
dnl This is libtool version of library, we add it to `--version-info` property.
m4_define([lt_current], [2])
m4_define([lt_revision], [2])
m4_define([lt_age], [2])
dnl This is ABI version for linker scripts, CMake uses the same format for
dnl VERSION property of shared library.
dnl The formula is: c:r:a -> c-a:a:r
m4_define([abi_version_major], [m4_eval(lt_current - lt_age)])
m4_define([abi_version_minor], [lt_age])
m4_define([abi_version_patch], [lt_revision])
dnl ====================================================================================
AC_CHECK_HEADERS([stdbool.h stdint.h sys/times.h unistd.h immintrin.h])
dnl ====================================================================================
dnl Couple of initializations here. Fill in real values later.
SHLIB_VERSION_ARG=""
dnl ====================================================================================
dnl Finished checking, handle options.
AC_ARG_ENABLE([werror],
[AS_HELP_STRING([--enable-werror], [enable -Werror in all Makefiles])])
AC_ARG_ENABLE([cpu-clip],
[AS_HELP_STRING([--disable-cpu-clip], [disable tricky cpu specific clipper])])
AC_ARG_ENABLE([sse2-lrint],
[AS_HELP_STRING([--enable-sse2-lrint], [implement lrintf using SSE2 on x86 CPUs if possible])])
AC_ARG_ENABLE([sndfile],
[AS_HELP_STRING([--disable-sndfile], [disable support for sndfile (default=autodetect)])], [], [enable_sndfile=auto])
AC_ARG_ENABLE([alsa],
[AS_HELP_STRING([--disable-alsa], [disable ALSA support in the varispeed-play example program (default=autodetect)])], [], [enable_alsa=auto])
AC_ARG_ENABLE([fftw],
[AS_HELP_STRING([--disable-fftw], [disable usage of FFTW (default=autodetect)])], [], [enable_fftw=auto])
AC_ARG_ENABLE([sinc_fast],
[AS_HELP_STRING([--disable-sinc-fast], [disable sinc fast converter support (default=autodetect)])], [], [enable_sinc_fast=yes])
AC_ARG_ENABLE([sinc_medium],
[AS_HELP_STRING([--disable-sinc-medium], [disable sinc balanced converter support (default=autodetect)])], [], [enable_sinc_medium=yes])
AC_ARG_ENABLE([sinc_best],
[AS_HELP_STRING([--disable-sinc-best], [disable sinc best converter support (default=autodetect)])], [], [enable_sinc_best=yes])
dnl ====================================================================================
dnl Check types and their sizes.
AC_CHECK_SIZEOF(int,0)
AC_CHECK_SIZEOF(long,0)
AC_CHECK_SIZEOF(float,4)
AC_CHECK_SIZEOF(double,8)
dnl ====================================================================================
dnl Determine endian-ness of host processor.
AC_C_BIGENDIAN([
dnl big-endian
ac_cv_c_big_endian=1
ac_cv_c_little_endian=0
], [
dnl little-endian
ac_cv_c_big_endian=0
ac_cv_c_little_endian=1
])
AC_DEFINE_UNQUOTED([CPU_IS_BIG_ENDIAN], [${ac_cv_c_big_endian}], [Host processor is big endian.])
AC_DEFINE_UNQUOTED([CPU_IS_LITTLE_ENDIAN], [${ac_cv_c_little_endian}], [Host processor is little endian.])
dnl ====================================================================================
dnl Check for functions.
AC_CHECK_FUNCS([malloc calloc free memcpy memmove alarm signal])
AS_CASE([${host_os}],
dnl These system don't have libm, or don't need it
dnl The list is from LT_LIB_M of libtool-2.4.6 with mingw added to it.
[darwin*|mingw*|cygwin*|haiku*|beos*|cegcc*|pw32*],[],
[*], [
AC_SEARCH_LIBS([floor], [m], [], [
AC_MSG_ERROR([unable to find the floor() function!])
])
])
AC_CHECK_FUNCS([floor ceil fmod lrint lrintf])
AC_CHECK_SIGNAL(SIGALRM)
dnl ====================================================================================
dnl Determine if the processor can do clipping on float to int conversions.
AS_IF([test "x$enable_cpu_clip" != "xno"], [
AC_C_CLIP_MODE
], [
AS_ECHO(["checking processor clipping capabilities... disabled"])
ac_cv_c_clip_positive=0
ac_cv_c_clip_negative=0
])
AC_DEFINE_UNQUOTED([CPU_CLIPS_POSITIVE], [${ac_cv_c_clip_positive}], [Host processor clips on positive float to int conversion.])
AC_DEFINE_UNQUOTED([CPU_CLIPS_NEGATIVE], [${ac_cv_c_clip_negative}], [Host processor clips on negative float to int conversion.])
dnl ====================================================================================
dnl Determine if the user enabled lrint implementations using SSE2.
AS_IF([test "x$enable_sse2_lrint" = "xyes"], [
CFLAGS="$CFLAGS -DENABLE_SSE2_LRINT"
])
dnl ====================================================================================
dnl Check for libsndfile which is required for the test and example programs.
AS_IF([test "x$enable_sndfile" != "xno"], [
PKG_CHECK_MODULES([SNDFILE], [sndfile >= 1.0.6], [
AC_DEFINE([HAVE_SNDFILE], [1], [Set to 1 if you have libsndfile])
enable_sndfile="yes"
], [
AS_IF([test "x$enable_sndfile" = "xyes"], [
dnl explicitly passed --enable-sndfile, hence error out loud and clearly
AC_MSG_ERROR([You explicitly requested libsndfile support, but libsndfile could not be found!])
], [
dnl did not explicitly pass --enable-sndfile, relying on default automagic on
enable_sndfile="no (auto)"
])
])
])
AM_CONDITIONAL([HAVE_LIBSNDFILE], [test "x$enable_sndfile" = "xyes"])
dnl ====================================================================================
dnl Check for ALSA.
AS_IF([test "x$enable_alsa" != "xno"], [
PKG_CHECK_MODULES([ALSA], [alsa], [
AC_DEFINE([HAVE_ALSA], [1], [Set to 1 if you have alsa])
enable_alsa="yes"
], [
AS_IF([test "x$enable_alsa" = "xyes"], [
dnl explicitly passed --enable-alsa, hence error out loud and clearly
AC_MSG_ERROR([You explicitly requested alsa support, but alsa could not be found!])
], [
dnl did not explicitly pass --enable-alsa, relying on default automagic on
enable_alsa="no (auto)"
])
])
])
dnl ====================================================================================
dnl Check for libfftw3 which is required for the test and example programs.
AS_IF([test "x$enable_fftw" != "xno"], [
PKG_CHECK_MODULES([FFTW3], [fftw3 >= 3.0.0], [
AC_DEFINE([HAVE_FFTW3], [1], [Set to 1 if you have fftw3])
enable_fftw="yes"
], [
AS_IF([test "x$enable_fftw" = "xyes"], [
dnl explicitly passed --enable-fftw, hence error out loud and clearly
AC_MSG_ERROR([You explicitly requested FFTW3 support, but FFTW3 could not be found!])
], [
dnl did not explicitly pass --enable-fftw, relying on default automagic on
enable_fftw="no (auto)"
])
])
])
dnl ====================================================================================
dnl Set Sinc Quality.
AS_IF([test "x$enable_sinc_fast" != "xno"], [
AC_DEFINE_UNQUOTED([ENABLE_SINC_FAST_CONVERTER], [${enable_sinc_fast}], [Enable sinc fast converter.])
], [
enable_sinc_fast="no"
])
AS_IF([test "x$enable_sinc_medium" != "xno"], [
AC_DEFINE_UNQUOTED([ENABLE_SINC_MEDIUM_CONVERTER], [${enable_sinc_medium}], [Enable sinc balanced converter.])
], [
enable_sinc_medium="no"
])
AS_IF([test "x$enable_sinc_best" != "xno"], [
AC_DEFINE_UNQUOTED([ENABLE_SINC_BEST_CONVERTER], [${enable_sinc_best}], [Enable sinc best converter.])
], [
enable_sinc_best="no"
])
dnl ====================================================================================
dnl Compiler stuff.
AS_IF([test "x$enable_flags_setting" = "xyes"], [
AX_APPEND_COMPILE_FLAGS([-DHAVE_CONFIG_H -O2 -pipe -DNDEBUG], [CFLAGS])
AS_CASE([${host_os}],
[darwin*], [
ldflags_test="-Wl,-dead_strip_dylibs"],
[linux*], [
ldflags_test="-Wl,-O1 -Wl,--as-needed -Wl,--no-undefined -Wl,--gc-sections"]
)
AX_APPEND_LINK_FLAGS([${ldflags_test}], [LDFLAGS])
])
dnl ====================================================================================
dnl Exported symbols control.
saved_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -fvisibility=hidden -Werror"
AC_MSG_CHECKING([if compiler supports visibility attributes])
AC_LANG_PUSH([C])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
__attribute__((visibility("default"))) int foo(void);
__attribute__((visibility("hidden"))) int bar(void);
int foo(void) { return 0; }
int bar(void) { return 1; }]], [])],
[have_visibility=yes],[have_visibility=no])
AC_LANG_POP([C])
AC_MSG_RESULT([$have_visibility])
CFLAGS="$saved_CFLAGS"
AS_IF([test "x$have_visibility" = "xyes"], [
AC_DEFINE([HAVE_VISIBILITY], [1], [Define to 1 if the compiler supports simple visibility declarations.])
])
AS_IF([test "x$lt_cv_prog_gnu_ld" = "xyes"], [
AS_CASE([${host_os}],
[mingw*|cygwin*], [
SHLIB_VERSION_ARG="-export-symbols \$(top_srcdir)/Win32/libsamplerate-0.def"],
[*], [
SHLIB_VERSION_ARG="-Wl,--version-script=\$(top_builddir)/src/Version_script"
])
])
dnl ====================================================================================
dnl Warning flags.
AS_IF([test "x$enable_werror" = "xyes"], [
AX_APPEND_COMPILE_FLAGS([-Werror], [CFLAGS])
])
AX_APPEND_COMPILE_FLAGS([-W -Wstrict-prototypes -Wmissing-prototypes -Wall -Waggregate-return -Wcast-align -Wcast-qual -Wnested-externs -Wshadow -Wpointer-arith], [CFLAGS])
dnl ====================================================================================
dnl Set OS-specific audio-out flags.
AUDIO_CFLAGS=""
AUDIO_LIBS=""
AS_CASE([${host_os}],
[darwin*], [dnl this requires 10.5+
AUDIO_LIBS="-framework CoreAudio"],
[mingw32*], [
AUDIO_LIBS="-lwinmm"],
[linux*], [dnl have OSS as fallback if no ALSA
AS_IF([test "x$enable_alsa" = "xyes"], [
AUDIO_LIBS="$ALSA_LIBS"
AUDIO_CFLAGS="$ALSA_CFLAGS"])],
[])
dnl ====================================================================================
dnl Now use the information from the checking stage.
AC_SUBST(SHLIB_VERSION_ARG)
AC_SUBST([SHARED_VERSION_INFO], [lt_current:lt_revision:lt_age])
AC_SUBST(AUDIO_CFLAGS)
AC_SUBST(AUDIO_LIBS)
AC_CONFIG_FILES([
Makefile
src/Version_script
libsamplerate.spec
samplerate.pc
])
AC_OUTPUT
dnl ====================================================================================
AX_RECURSIVE_EVAL([$libdir], [full_absolute_libdir])
AX_RECURSIVE_EVAL([$bindir], [full_absolute_bindir])
AX_RECURSIVE_EVAL([$pkgconfigdir], [full_absolute_pkgconfigdir])
AX_RECURSIVE_EVAL([$htmldir], [full_absolute_htmldir])
AC_MSG_RESULT([
-=-=-=-=-=-=-=-=-=-= Configuration Complete =-=-=-=-=-=-=-=-=-=-=-
Configuration summary :
libsamplerate version : ............... ${VERSION}
Host CPU : ............................ ${host_cpu}
Host Vendor : ......................... ${host_vendor}
Host OS : ............................. ${host_os}
CFLAGS : .............................. ${CFLAGS}
CPPFLAGS : ............................ ${CPPFLAGS}
LDFLAGS : ............................. ${LDFLAGS}
Tools :
C Compiler Vendor is : ................ ${ax_cv_c_compiler_vendor} (${ax_cv_c_compiler_version})
Extra tools required for testing and examples :
Have libsndfile : ..................... ${enable_sndfile}
Have ALSA : ........................... ${enable_alsa}
Have FFTW : ........................... ${enable_fftw}
Converter configuration :
Sinc fast : ........................... ${enable_sinc_fast}
Sinc balanced : ....................... ${enable_sinc_medium}
Sinc best : ........................... ${enable_sinc_best}
Installation directories :
Library directory : ................... ${full_absolute_libdir}
Program directory : ................... ${full_absolute_bindir}
Pkgconfig directory : ................. ${full_absolute_pkgconfigdir}
HTML docs directory : ................. ${full_absolute_htmldir}
Compiling some other packages against libsamplerate may require
the addition of '$full_absolute_pkgconfigdir' to the
PKG_CONFIG_PATH environment variable.
])

@ -1,19 +0,0 @@
install(
FILES
api.md
api_callback.md
api_full.md
api_misc.md
api_simple.md
bugs.md
download.md
faq.md
history.md
index.md
license.md
lists.md
quality.md
win32.md
SRC.png
DESTINATION
${CMAKE_INSTALL_DOCDIR})

@ -1,56 +0,0 @@
a:link {
color: #FB1465;
}
a:active, a:visited {
color: #FB1465;
}
body {
background: black;
color: white;
font-family: arial, helvetica, sans-serif;
}
h1, h2, h3, h4, h5, h6 {
color: #FB1465;
}
code, kbd, samp, var {
font-family: courier, monospace;
font-size: 1em;
}
main {
padding-left: 3%;
padding-right: 3%;
}
pre {
font-family: courier, monospace;
font-size: 1em;
}
.image-logo {
display: block;
margin-left: auto;
margin-right: auto;
margin-bottom: 1em;
}
.indent_block {
margin-left: 10%;
margin-right: 10%;
}
.nf {
font-weight: bold;
}
.container {
display: flex;
}
.content {
flex: 1;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

@ -1,8 +0,0 @@
---
author: Erik de Castro Lopo, erikd@mega-nerd.com
description: An audio Sample Rate Conversion library
keywords: libsamplerate, sound, resample, audio, dsp, Linux
version: 0.2.1
markdown: kramdown
---

@ -1,49 +0,0 @@
<!DOCTYPE html">
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="{{ site.description | page.description }}">
<meta name="keywords" content="{{ site.keywords | page.keywords }}">
<title>{{ page.title }}</title>
<link rel="stylesheet" href="SRC.css" type="text/css" media="all">
</HEAD>
<body>
<footer>
<img src="SRC.png" class="image-logo" height=100 width=760 alt="SRC.png">
</footer>
<div class="container">
<div class="navbar">
<nav>
<a href="index.html">Home</a><br>
<a href="license.html">License</a><br>
<a href="history.html">History</a><br>
<a href="download.html">Download</a><br>
<a href="quality.html">Quality</a><br>
<a href="api.html">API</a><br>
<a href="bugs.html">Bug Reporting</a><br>
<a href="win32.html">On Win32</a><br>
<a href="faq.html">FAQ</a><br>
<a href="lists.html">Mailing Lists</a><br>
<a href="https://github.com/libsndfile/libsamplerate/blob/master/ChangeLog">ChangeLog</a><br>
</nav>
<div class="block">
<p>Author:<br>&nbsp;Erik&nbsp;de&nbsp;Castro&nbsp;Lopo</p>
</div>
</div>
<div class="content">
<main>
<article>
{{ content }}
</article>
</main>
</div>
</div>
</body>
</html>

@ -1,46 +0,0 @@
---
layout: default
---
# Applications Programming Interface
The publically callable functions of libsamplerate are all listed in the
**\<samplerate.h\>** header file. In order to use any of the functionality of
libsamplerate, you need to add
```c
#include <samplerate.h>
```
to the top of any function that call any of the following functions. You will
also need to link you binary with the libsamplerate library.
The API allows three methods for accessing the capabilities of the library:
- A [simple interface](api_simple.md) which can sample rate convert a single
block of samples (one or more channels) in one go. The simple API is less
capable than the full API.
- A [more fully featured interface](api_full.md) which allows time varying
sample rate conversion on streaming data (again one or more channels).
- A [callback interface](api_callback.md) which has the same functionality as
the interface above but allows the details of input and output to be
separated. The output is generated by call a read function and the library
calls a user supplied callback function to obtain its input. This interface is
particularly well suited to applications where the output sample rate is
varied with time.
**NB :** All three access methods are able to process multi channel interleaved
data.
The parts of the API which are common to all three interfaces are:
- The [error reporting](api_misc.md#error-reporting) mechanisim.
- The available [converter](api_misc.md#converters) types.
- The [SRC_DATA](api_misc.md#src_data) struct.
All three versions of the API are restricted to operating on buffers of ISO C
Standard **float** data. However, there are two [auxiliary functions](api_misc.md#auxiliary-functions)
for converting arrays of float data to and from short data.
**Note:** The **tests/** and **examples/** directories of the source code
distribution contain numerous example programs showing the use of the library.

@ -1,88 +0,0 @@
---
layout: default
---
# Callback API
The callback API consists of the following functions :
```c
typedef long (*src_callback_t) (void *cb_data, float **data) ;
SRC_STATE* src_callback_new (src_callback_t func,
int converter_type, int channels,
int *error, void* cb_data) ;
SRC_STATE* src_delete (SRC_STATE *state) ;
long src_callback_read (SRC_STATE *state, double src_ratio,
long frames, float *data) ;
int src_reset (SRC_STATE *state) ;
int src_set_ratio (SRC_STATE *state, double new_ratio) ;
```
Like the [simple API](api_simple.md) and the [full API](api_full.md), the
callback based API is able to operate on interleaved multi channel data.
An example of the use of the callback based API can be found in the
**varispeed-play** program in the **examples/** directory of the source code
tarball.
## Initialisation
```c
SRC_STATE* src_callback_new (src_callback_t func,
int converter_type, int channels,
int *error, void* cb_data) ;
```
The **src_callback_new** function returns an anonymous pointer to a sample rate
converter callback object, src_state. This is the same type of object as that
returned by [src\_new](api_full.md#initialisation), but with different internal
state. Although these are the same object type, they cannot be used
interchangeably. If an error occurs the function returns a NULL pointer and
fills in the error value pointed to by the **error** pointer supplied by the
caller.
The caller then passes the SRC_STATE object to the **src_callback_read**
function to pull data out of the converter. When the caller is finished with the
converter they should pass it to the clean up function [src_delete](api_full.md#cleanup).
The **func** parameter is a user supplied function which must match the
**src_callback_t** type signature while **cb_data** is a pointer to data which
be passed as the first parameter to the user supplied callback function. This
function is called by the converter whenever it needs input data as a result of
being calls to **src_callback_read**.
If the converter was initialised to work with more than one channel, the
callback function must work with mutiple channels of interleaved data. The
callback function should return the number of frames it supplying to the
converter. For multi channel files, this return value should be the number of
floats divided by the number of channels.
The converter must be one of the supplied converter types documented [here](api_misc.md#converters).
The caller then passes the SRC_STATE pointer to the **src_callback_read**
function to pull data out of the converter.
## Callback Read
```c
long src_callback_read (SRC_STATE *state, double src_ratio,
long frames, float *data) ;
```
The **src_callback_read** function is passed the [**SRC_STATE**](api_misc.md#src_data)
pointer returned by **src_callback_new**, the coversion ratio
(output_sample_rate / input_sample_rate), the maximum number of output frames to
generate and a pointer to a buffer in which to place the output data. For multi
channel files, the data int the output buffer is stored in interleaved format.
The **src_callback_read** function returns the number of frames generated or
zero if an error occurs or it runs out of input (ie the user supplied callback
function returns zero and there is no more data buffered internally). If an
error has occurred, the function [src_error](api_misc.md#error-reporting)
will return non-zero.
See also : [**src_set_ratio**](api_full.md#set-ratio)

@ -1,146 +0,0 @@
---
layout: default
---
# Full API
The full API consists of the following functions :
```c
SRC_STATE* src_new (int converter_type, int channels, int *error) ;
SRC_STATE* src_delete (SRC_STATE *state) ;
int src_process (SRC_STATE *state, SRC_DATA *data) ;
int src_reset (SRC_STATE *state) ;
int src_set_ratio (SRC_STATE *state, double new_ratio) ;
```
## Initialisation
```c
SRC_STATE* src_new (int converter_type, int channels, int *error) ;
```
The **src\_new** function returns an anonymous pointer to a sample rate
converter object, src\_state. If an error occurs the function returns a
NULL pointer and fills in the error value pointed to by the **error**
pointer supplied by the caller. The converter must be one of the
supplied converter types documented [here](api_misc.md#converters).
## Cleanup
```c
SRC_STATE* src_delete (SRC_STATE *state) ;
```
The **src\_delete** function frees up all memory allocated for the given
sample rate converter object and returns a NULL pointer. The caller is
responsible for freeing any memory passed to the sample rate converter
via the pointer to the **SRC\_DATA** struct.
## Process
```c
int src_process (SRC_STATE *state, SRC_DATA *data) ;
```
The **src\_process** function processes the data provided by the caller
in an **SRC\_DATA** struct using the sample rate converter object
specified by the **SRC\_STATE** pointer. When operating on streaming
data, this function can be called over and over again, with each new
call providing new input data and returning new output data.
The **SRC\_DATA** struct passed as the second parameter to the
**src\_process** function has the following fields:
```c
typedef struct
{ const float *data_in;
float *data_out;
long input_frames, output_frames ;
long input_frames_used, output_frames_gen ;
int end_of_input ;
double src_ratio ;
} SRC_DATA ;
```
The fields of this struct which must be filled in by the caller are:
data_in
: A pointer to the input data samples.
input_frames
: The number of frames of data pointed to by data_in.
data_out
: A pointer to the output data samples.
output_frames
: Maximum number of frames pointer to by data_out.
src_ratio
: Equal to output_sample_rate / input_sample_rate.
end_of_input
: Equal to 0 if more input data is available and 1 otherwise.
Note that the data\_in and data\_out arrays may not overlap. If they do,
the library will return an error code.
When the **src\_process** function returns **output\_frames\_gen** will
be set to the number of output frames generated and
**input\_frames\_used** will be set to the number of input frames
consumed to generate the provided number of output frames.
The **src\_process** function returns non-zero if an error occurs. The
non-zero error return value can be decoded into a text string using the
function documented [here](api_misc.md#error-reporting).
## Reset
```c
int src_reset (SRC_STATE *state) ;
```
The **src\_reset** function resets the internal state of the sample rate
converter object to the same state it had immediately after its creation
using **src\_new**. This should be called whenever a sample rate
converter is to be used on two separate, unrelated pieces of audio.
## Clone
```c
SRC_STATE* src_clone (SRC_STATE *state, int *error) ;
```
The **src_clone** function creates a copy of the internal state of the sample
rate converter object. The output of the next call to **src\_process** will be
identical for both the original and cloned state (given the same **SRC_DATA**
input). This could be used to later resume sample rate conversion at a specific
location in a stream with the same state, which may be useful in real-time
applications.
If an error occurs the function returns a NULL pointer and fills in the
error value pointed to by the **error** pointer supplied by the caller.
## Set Ratio
```c
int src_set_ratio (SRC_STATE *state, double new_ratio) ;
```
When using the **src_process** or **src_callback_process** APIs and updating the
**src_ratio** field of the **SRC_STATE** struct, the library will try to
smoothly transition between the conversion ratio of the last call and the
conversion ratio of the current call.
If the user wants to bypass this smooth transition and achieve a step response in
the conversion ratio, the **src_set_ratio** function can be used to set the
starting conversion ratio of the next call to **src_process** or
**src_callback_process**.
This function returns non-zero on error and the error return value can be
decoded into a text string using the function documented [here](api_misc.md#error-reporting).

@ -1,145 +0,0 @@
---
layout: default
---
# Miscellaneous API Documentation
## Error Reporting
Most of the API functions either return an integer error (ie **src_simple** and
**src_process**) or return an integer error value via an int pointer parameter
(**src_new**). These integer error values can be converted into human-readable
text strings by calling the function:
```c
const char* src_strerror (int error) ;
```
which will return an error string for valid error numbers, the string
\"No Error\" for an error value of zero or a NULL pointer if no error message
has been defined for that error value.
## Converters
Secret Rabbit Code has a number of different converters which can be selected
using the **converter_type** parameter when calling **src_simple** or
**src_new**. Currently, the five converters available are:
```c
enum
{
SRC_SINC_BEST_QUALITY = 0,
SRC_SINC_MEDIUM_QUALITY = 1,
SRC_SINC_FASTEST = 2,
SRC_ZERO_ORDER_HOLD = 3,
SRC_LINEAR = 4
} ;
```
As new converters are added, they will be given a number corresponding to the next
integer.
The details of these converters are as follows:
- **SRC_SINC_BEST_QUALITY** - This is a bandlimited interpolator derived from
the mathematical **sinc** function and this is the highest quality sinc based
converter, providing a worst case Signal-to-Noise Ratio (SNR) of 97 decibels
(dB) at a bandwidth of 97%. All three SRC_SINC_* converters are based on the
techniques of [Julius O. Smith](http://ccrma.stanford.edu/~jos/resample/)
although this code was developed independently.
- **SRC_SINC_MEDIUM_QUALITY** - This is another bandlimited interpolator much
like the previous one. It has an SNR of 97dB and a bandwidth of 90%. The speed
of the conversion is much faster than the previous one.
- **SRC_SINC_FASTEST** - This is the fastest bandlimited interpolator and has an
SNR of 97dB and a bandwidth of 80%.
- **SRC_ZERO_ORDER_HOLD** - A Zero Order Hold converter (interpolated value is
equal to the last value). The quality is poor but the conversion speed is
blindlingly fast. Be aware that this interpolator is not bandlimited, and the
user is responsible for adding anti-aliasing filtering.
- **SRC_LINEAR** - A linear converter. Again the quality is poor, but the
conversion speed is blindingly fast. This interpolator is also not bandlimited,
and the user is responsible for adding anti-aliasing filtering.
There are two functions that give either a (text string) name or description for
each converter:
```c
const char *src_get_name (int converter_type) ;
const char *src_get_description (int converter_type) ;
```
The name will typically be a short string for use in a dialog box, while the
description string is longer.
Both of these functions return a NULL pointer if there is no converter for the
given **converter_type** value. Since the converters have consecutive
**converter_type** values, the caller is easily able to figure out the number of
converters at run time. This enables a binary dynamically linked against an old
version of the library to know about converters from later versions of the
library as they become available.
## SRC_DATA
Both the simple and the full featured versions of the API use the **SRC_DATA**
struct to pass audio and control data into the sample rate converter. This
struct is defined as:
```c
typedef struct
{ const float *data_in;
float *data_out ;
long input_frames, output_frames ;
long input_frames_used, output_frames_gen ;
int end_of_input ;
double src_ratio ;
} SRC_DATA ;
```
The **data_in** pointer is used to pass audio data into the converter while the
**data_out** pointer supplies the converter with an array to hold the
converter's output. For a converter which has been configured for multichannel
operation, these pointers need to point to a single array of interleaved data.
The **input_frames** and **output_frames** fields supply the converter with the
lengths of the arrays (in frames) pointed to by the **data_in** and **data_out**
pointers respectively. For monophonic data, these values would indicate the
length of the arrays while for multi channel data these values would be equal to
the length of the array divided by the number of channels.
The **end_of_input** field is only used when the sample rate converter is used
by calling the **src_process** function. In this case it should be set to zero
if more buffers are to be passed to the converter and 1 if the current buffer is
the last.
Finally, the **src_ratio** field specifies the conversion ratio defined as the
output sample rate divided by the input sample rate. For a connected set of
buffers, this value can vary on each call to **src_process** resulting in a
time varying sample rate conversion process. For time varying sample rate
conversions, the ratio will be linearly interpolated between the **src_ratio**
value of the previous call to **src_process** and the value for the current
call.
The **input_frames_used** and **output_frames_gen** fields are set by the
converter to inform the caller of the number of frames consumed from the
**data_in** array and the number of frames generated in the **data_out** array
respectively. These values are for the current call to **src_process** only.
## Auxiliary Functions
There are four auxiliary functions for converting arrays of float data to and
from short or int data. These functions are defined as:
```c
void src_short_to_float_array (const short *in, float *out, int len) ;
void src_float_to_short_array (const float *in, short *out, int len) ;
void src_int_to_float_array (const int *in, float *out, int len) ;
void src_float_to_int_array (const float *in, int *out, int len) ;
```
The float data is assumed to be in the range [-1.0, 1.0] and it is automatically
scaled on the conversion to and from float. On the float to short/int conversion
path, any data values which would overflow the range of short/int data are
clipped.

@ -1,71 +0,0 @@
---
layout: default
---
# Simple API
**Important Note:** The simple API is not designed to work on small chunks of a
larger piece of audio. If you attempt to use it this way you are doing it wrong
and will not get the results you want. For processing audio data in chunks you
**must** use the [full api](api_full.md) or the [callback based api](api_callback.md).
The simple API consists of a single function:
```c
int src_simple (SRC_DATA *data, int converter_type, int channels) ;
```
The use of this function rather than the more fully featured API requires the
caller to know the total length of the input data before hand and that all input
and output data can be held in the system's memory at once. It also assumes that
there is a single constant ratio between input and output sample rates.
Dealing with the easy stuff first, the **converter_type** parameter should be
one of the values defined in **samplerate.h** and documented [here](api_misc.md#converters)
while the **channels** parameter specifies the number of interleaved channels
that the sample rate converter is being asked to process (number of input
channels and output channels is always equal). There is no hard upper limit on
the number of channels; it is limited purely by the amount of memory available.
The first parameter to **src_simple** is a pointer to an **SRC_DATA** struct
(more info [here](api_misc.md#src_data)) defined as follows:
```c
typedef struct
{ const float *data_in;
float *data_out ;
long input_frames, output_frames ;
long input_frames_used, output_frames_gen ;
int end_of_input ;
double src_ratio ;
} SRC_DATA ;
```
The fields of this struct which must be filled in by the caller are:
data_in
: A pointer to the input data samples.
input_frames
: The number of frames of data pointed to by data_in.
data_out
: A pointer to the output data samples.
output_frames
: Maximum number of frames pointer to by data_out.
src_ratio
: Equal to output_sample_rate / input_sample_rate.
When the **src_simple** function returns **output_frames_gen** will be set to
the number of output frames generated and **input_frames_used** will be set to
the number of input frames used to generate the provided number of output
frames.
The **src_simple** function returns a non-zero value when an error occurs. See
[here](api_misc.md#error-reporting) for how to convert the error value into a
text string.

@ -1,37 +0,0 @@
---
layout: default
---
# Bug Reporting
If you are a user and have a problem using libsamplerate with another piece of
software, you should contact the author of that other software and get them to
explore their use of this library and possibly submit a bug report. If you are a
coder and think you have found a bug in libsamplerate then read on.
Secret Rabbit Code is an extremely complex piece of code but I do think that it
is relatively bug free. In addition, the source code distribution includes a
comprehensive test suite for regression testing. This means it is extremely
unlikely that new bugs creep in when modifications are made to the code.
SRC is also not the most simple library to use which means that I do get a
number of bug reports which turn out to be bugs in the user's program rather
than bugs in SRC. Up until now, I have investigated each bug report as
thoroughly as possible. Unfortunately, this chews up a lot of my time which
could otherwise be spent improving SRC, working on other Free Software or
spending time with my family.
I have therefore decided, that I cannot investigate any bug report unless the
person reporting the problem can supply me with a short self contained test
program or a modification to one of the existing test programs in the tests/
directory of the source code distribution. The test program should meet the
following criteria:
- Written in C or C++.
- Does not use any libraries or header files other than the ones which are
standard for the relevant languages. (Of course libsamplerate can be used :-)).
- It is the minimal program which can adequately display the problem.
- It clearly displays the criteria for pass or fail.
Supplying a good test program will maximize the speed with which your bug report
gets dealt with.

@ -1,15 +0,0 @@
---
layout: default
---
# Download
The latest version of Secret Rabbit Code is {{ site.version }}.
Download it on [GitHub releases page](https://github.com/libsndfile/libsamplerate/releases/latest).
Compiling libsamplerate is relatively easy. The INSTALL file in the top level
directory gives instructions on compiling and installing libsamplerate on
Unix-like systems (including MacOSX). For Win32 there are instructions in the
docs/ directory of the tarball. These instructions are mirrored
[here](win32.md).

@ -1,193 +0,0 @@
---
layout: default
---
# Frequently Asked Questions
1. [Q1 : Is it normal for the output of libsamplerate to be louder than its input?](#Q001)
2. [Q2 : On Unix/Linux/MacOSX, what is the best way of detecting the presence and location of libsamplerate and its header file using autoconf?](#Q002)
3. [Q3 : If I upsample and downsample to the original rate, for example 44.1-\>96-\>44.1, do I get an identical signal as the one before the up/down resampling?](#Q003)
4. [Q4 : If I ran src\_simple (libsamplerate) on small chunks (160 frames) would that sound bad?](#Q004)
5. [Q5 : I\'m using libsamplerate but the high quality settings sound worse than the SRC\_LINEAR converter. Why?](#Q005)
6. [Q6 : I\'m use the SRC\_SINC\_\* converters and up-sampling by a ratio of 2. I reset the converter and put in 1000 samples and I expect to get 2000 samples out, but I\'m getting less than that. Why?](#Q006)
7. [Q7 : I have input and output sample rates that are integer values, but the API wants me to divide one by the other and put the result in a floating point number. Won\'t this case problems for long running conversions?](#Q007)
## Q1 : Is it normal for the output of libsamplerate to be louder than its input? {#Q001}
The output of libsamplerate will be roughly the same volume as the input.
However, even if the input is strictly in the range (-1.0, 1.0), it is still
possible for the output to contain peak values outside this range.
Consider four consecutive samples of [0.5 0.999 0.999 0.5]. If we are up
sampling by a factor of two we need to insert samples between each of the
existing samples. Its pretty obvious then, that the sample between the two 0.999
values should and will be bigger than 0.999.
This means that anyone using libsamplerate should normalize its output before
doing things like saving the audio to a 16 bit WAV file.
## Q2 : On Unix/Linux/MacOSX, what is the best way of detecting the presence and location of libsamplerate and its header file using autoconf? {#Q002}
libsamplerate uses the pkg-config (man pkg-config) method of registering itself
with the host system. The best way of detecting its presence is using something
like this in configure.ac (or configure.in):
PKG_CHECK_MODULES(SAMPLERATE, samplerate >= 0.1.3,
ac_cv_samplerate=1, ac_cv_samplerate=0)
AC_DEFINE_UNQUOTED([HAVE_SAMPLERATE],${ac_cv_samplerate},
[Set to 1 if you have libsamplerate.])
AC_SUBST(SAMPLERATE_CFLAGS)
AC_SUBST(SAMPLERATE_LIBS)
This will automatically set the **SAMPLERATE_CFLAGS** and **SAMPLERATE_LIBS**
variables which can be used in Makefile.am or Makefile.in like this:
SAMPLERATE_CFLAGS = @SAMPLERATE_CFLAGS@
SAMPLERATE_LIBS = @SAMPLERATE_LIBS@
If you install libsamplerate from source, you will probably need to set the
**PKG_CONFIG_PATH** environment variable's suggested at the end of the
libsamplerate configure process. For instance on my system I get this:
-=-=-=-=-=-=-=-=-=-= Configuration Complete =-=-=-=-=-=-=-=-=-=-=-
Configuration summary :
Version : ..................... 0.1.3
Enable debugging : ............ no
Tools :
Compiler is GCC : ............. yes
GCC major version : ........... 3
Extra tools required for testing and examples :
Have FFTW : ................... yes
Have libsndfile : ............. yes
Have libefence : .............. no
Installation directories :
Library directory : ........... /usr/local/lib
Program directory : ........... /usr/local/bin
Pkgconfig directory : ......... /usr/local/lib/pkgconfig
## Q3 : If I upsample and downsample to the original rate, for example 44.1->96->44.1, do I get an identical signal as the one before the up/down resampling? {#Q003}
The short answer is that for the general case, no, you don't. The long answer is
that for some signals, with some converters, you will get very, very close.
In order to resample correctly (ie using the **SRC_SINC_*** converters),
filtering needs to be applied, regardless of whether its upsampling or
downsampling. This filter needs to attenuate all frequencies above 0.5 times the
minimum of the source and destination sample rate (call this fshmin). Since the
filter needed to achieve full attenuation at this point, it has to start rolling
off a some frequency below this point. It is this rolloff of the very highest
frequencies which causes some of the loss.
The other factor is that the filter itself can introduce transient artifacts
which causes the output to be different to the input.
## Q4 : If I ran src_simple on small chunks (say 160 frames) would that sound bad? {#Q004}
Well if you are after odd sound effects, it might sound OK. If you are after
high quality sample rate conversion you will be disappointed.
The src_simple() was designed to provide a simple to use interface for people
who wanted to do sample rate conversion on say, a whole file all at once.
## Q5 : I'm using libsamplerate but the high quality settings sound worse than the SRC_LINEAR converter. Why? {#Q005}
There are two possible problems. Firstly, if you are using the src_simple()
function on successive blocks of a stream of samples, you will get bad results.
The src_simple() function is designed for use on a whole sound file, all at
once, not on contiguous segments of the same sound file. To fix the problem, you
need to move to the src_process() API or the callback based API.
If you are already using the src_process() API or the callback based API and the
high quality settings sound worse than SRC_LINEAR, then you have other problems.
Read on for more debugging hints.
All of the higher quality converters need to keep state while doing conversions
on segments of a large chunk of audio. This state information is kept inside the
private data pointed to by the SRC_STATE pointer returned by the src_new()
function. This means, that when you want to start doing sample rate conversion
on a stream of data, you should call src_new() to get a new SRC_STATE pointer
(or alternatively, call src_reset() on an existing SRC_STATE pointer). You
should then pass this SRC_STATE pointer to the src_process() function with each
new block of audio data. When you have completed the conversion, you can then
call src_delete() on the SRC_STATE pointer.
If you are doing all of the above correctly, you need to examine your usage of
the values passed to src\_process() in the [SRC_DATA](api_misc.md#src_data)
struct. Specifically:
- Check that input_frames and output_frames fields are being set in terms of
frames (number of sample values times channels) instead of just the number of
samples.
- Check that you are using the return values input_frames_used and
output_frames_gen to update your source and destination pointers correctly.
- Check that you are updating the data_in and data_out pointers correctly for
each successive call.
While doing the above, it is probably useful to compare what you are doing to
what is done in the example programs in the examples/ directory of the source
code tarball.
If you have done all of the above and are still having problems then its
probably time to email the author with the smallest chunk of code that
adequately demonstrates your problem. This chunk should not need to be any more
than 100 lines of code.
## Q6 : I'm use the SRC_SINC_* converters and up-sampling by a ratio of 2. I reset the converter and put in 1000 samples and I expect to get 2000 samples out, but I'm getting less than that. Why? {#Q006}
The short answer is that there is a transport delay inside the converter itself.
Long answer follows.
By way of example, the first time you call src_process() you might only get 1900
samples out. However, after that first call all subsequent calls will probably
get you about 2000 samples out for every 1000 samples you put in.
The main problems people have with this transport delay is that they need to
read out an exact number of samples and the transport delay scews this up. The
best way to overcome this problem is to always supply more samples on the input
than is actually needed to create the required number of output samples. With
reference to the example above, if you always supply 1500 samples at the input,
you will always get 2000 samples at the output. You will always need to keep
track of the number of input frames used on each call to src_process() and deal
with these values appropriately.
## Q7 : I have input and output sample rates that are integer values, but the API wants me to divide one by the other and put the result in a floating point number. Won't this case problems for long running conversions? {#Q007}
The short answer is no, the precision of the ratio is many orders of magnitude
more than is really needed.
For the long answer, lets do come calculations. Firstly, the `src_ratio` field
is double precision floating point number which has [53 bits of precision](http://en.wikipedia.org/wiki/Double_precision).
That means that the maximum error in your ratio converted to a double is one bit
in 2^53 which means the double float value would be wrong by one sample
after 9007199254740992 samples have passed or wrong by more than half a sample
wrong after half that many (4503599627370496 samples) have passed.
Now if for example our output sample rate is 96kHz then
4503599627370496 samples at 96kHz is 46912496118 seconds
46912496118 seconds is 781874935 minutes
781874935 minutes is 13031248 hours
13031248 hours is 542968 days
542968 days is 1486 years
So, after 1486 years, the input will be wrong by more than half of one sampling
period.
All this assumes that the crystal oscillators uses to sample the audio stream is
perfect. This is not the case. According to [this web site](http://www.ieee-uffc.org/freqcontrol/quartz/vig/vigcomp.htm),
the accuracy of standard crystal oscillators (XO, TCXO, OCXO) is at best 1 in
100 million. The `src_ratio` is therefore 45035996 times more accurate than the
crystal clock source used to sample the original audio signal and any potential
problem with the `src_ratio` being a floating point number will be completely
swamped by sampling inaccuracies.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

@ -1,38 +0,0 @@
---
layout: default
---
# History
- Version 0.0.0 (Oct 06 2002) First alpha release (friends and family only).
- Version 0.0.2 (Oct 10 2002) Second alpha release (fools rush in ....).
- ...
- Version 0.0.7 (Nov 17 2002) The last mono only version.
- Version 0.0.9 (Nov 21 2002) Full multi channel support. First pass at
documentation. Still not ready for release.
- Version 0.0.11 (Nov 26 2002) Incorporated some suggestions from Conrad Parker.
- Version 0.0.12 (Nov 28 2002) First public release.
- Version 0.0.13 (Dec 03 2002) Fixes for MacOSX and Solaris.
- Version 0.0.14 (Jan 13 2003) Now compiles on Win32. Major code speedup. Minor
bug fixes.
- Version 0.0.15 (May 02 2003) Minor bug fixes.
- Version 0.1.0 (Mar 14 2004) Add callback API, functions for short to float and
float to short conversion. Minor bug fixes.
- Version 0.1.1 (Jul 17 2004) Callback API bug fix. Bugfix for aggressive
gcc-3.4 optimisations.
- Version 0.1.2 (Sep 12 2004) Callback API reset bug fix.
- Version 0.1.3 (Mar 23 2008) Huge quality improvements to two best SINC based
converters.
- Version 0.1.4 (Jul 02 2008) Fix segfault when using extremely low conversion
ratios.
- Version 0.1.5 (Jan 11 2009) Optimisation resulting in dramatic throughput
improvements ([See here.](http://www.mega-nerd.com/erikd/Blog/CodeHacking/SecretRabbitCode/rel_0_1_5.html)).
- Version 0.1.6 (Jan 27 2009) Minor bug fix in test suite (account for rounding
error on x86_64).
- Version 0.1.7 (Feb 14 2009) Fix a segfault bug. Fix compilation under MSVC.
- Version 0.1.8 (Aug 15 2011) Minor bug fixes and updates.
- Version 0.1.9 (Sep 19 2016) Fix for a segfault. Relicense under BSD license.
- Version 0.2.0 (Jan 21 2021) Cleaned up build system.
- Version 0.2.1 (Jan 23 2021) Fix libtool ABI versioning.
- Version 0.2.2 (Sep 05 2021) Fix ABI version incompatibility between Autotools
and CMake build on Apple platforms. Minor bug fixes and updates.

@ -1,160 +0,0 @@
---
layout: default
title: Libsamplerate home page
---
{: .indent_block}
*"Choosing a sample rate coverter wasn't easy. We ran numerous tests with Secret
Rabbit Code and other sample rate converters, then compared them all. In the
end, SRC outperformed the others, including some extremely well known and
popular software. We had one issue with SRC, but after emailing Erik, he got
back to us immediately with an answer. Choosing SRC was a no brainer."*
Ryan Smith, International Marketing Manager,
[Emersys Corp.](http://emersys.co.kr/), South Korea.
Product : [Maven3D](http://maven3d.com)
**S**ecret **R**abbit **C**ode (aka libsamplerate) is a **S**ample **R**ate
**C**onverter for audio. One example of where such a thing would be useful is
converting audio from the CD sample rate of 44.1kHz to the 48kHz sample rate
used by DAT players.
**SRC** is capable of arbitrary and time varying conversions, from downsampling
by a factor of 256 to upsampling by the same factor. Arbitrary in this case
means that the ratio of input and output sample rates can be an irrational
number. The conversion ratio can also vary with time for speeding up and slowing
down effects.
**SRC** provides a small set of converters to allow quality to be traded off
against computation cost. The current best converter provides a signal-to-noise
ratio of 145dB with -3dB passband extending from DC to 96% of the theoretical
best bandwidth for a given pair of input and output sample rates.
Since the library has few dependencies beyond that provided by the standard C
library, it should compile and work on just about any operating system. It is
known to work on Linux, MacOSX, [Win32](win32.md) and Solaris. With some
relatively minor hacking it should also be relatively easy to port it to
embedded systems and digital signal processors.
In addition, the library comes with a comprehensive test suite which can
validate the performance of the library on new platforms.
## Download
Check latest version on
[GitHub Releases page](https://github.com/libsndfile/libsamplerate/releases).
Binaries and source packages are signed by current release manager David Seifert aka
@SoapGentoo. You can verify signatures with his public GPG key (`0xA47620E801E47E95`):
```
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2
mQINBFppABgBEAC42ZiNvV7BTIgR6TQy0YnF54fx3mVRP1u8Mq00UZa7reAsNKh7
1H60j0W4s6+4pVVIKGfpVGxLwUdJe+KVCYw1Cd3YW6uMf5zZrC/ZWqnJiH/n6S6o
1l4INII2o6YbGBnzIWBPRo7PlOL+mvgKTLpBSJPnhD8XDGN5wRiV8rL2+6Dptg0F
nJt7oxECGF3OD3gk6HMel0o82CVkIqMtNaX1L/bhcdF7K0Rp2MXPZMmpn1izW5sI
asN1G9+w+Zwj7kMJzq1Aw3ac+rsX4SEYdvXjS2QhDHQUIr6LXri3D2WbcEqIZj2R
JVoVwblsrG11dYXFDBbgrq4NhgTBsxHYDlkr/qF2W+kbPC/nhSqTVZeCYvTBZbOQ
+RqyN/I0izukglnWmV1jGijFA8snyP8efx732hw/24zRYmtXOtnEITUpw8WOeZCq
6uiHaQ+eopnY2ojBg9BI7WZm0AFn58xxT9soMsyFOUFgXTqaWFZWlJ3fhZE8/0v8
JEu/kPGE5aJReT3b34B+Bojkj74XR+h2u7iJJBHMTE8RwGoUOZHer/XsL9xlcdks
I+7TCjiq++ShaSSt2XsJmw2BhREohrjW/2KkwmvT3b44RMpKPB4WTH+++aqJQNeM
IqmswOMoZvzEZezInj7WVY/r0WEei1Y6wt1tBrJ/cFf1oQBM1UmphxcrfQARAQAB
tB9EYXZpZCBTZWlmZXJ0IDxzb2FwQGdlbnRvby5vcmc+iQJUBBMBCgA+BQsJCAcD
BRUKCQgLBRYCAwEAAh4BAheAAhsBFiEEMdlcq22A0mIkShdQpHYg6AHkfpUFAl/V
CvoFCQkuceIACgkQpHYg6AHkfpXYxA//aiJW1NwunpmzEc62id8lRMnoLHWVjISZ
b+xSlm+hk4LYq+ZbthJDzKcT86/3DJOSE1zQw9wLuCao9IW2UfFJQBtR+TAfbagG
0Yyk/kMcLoFJxnG1ywdJWypCAauuIhia52Z7PmmjsBbFwr6LygDwSQmZAyACMAs7
TLQe+yERc2RNDsIEsquLSxxRF0Spk9gagWtKgrPc2XBjuNtQDwW7JgsOUoEeHyxC
29fRUjC3o/pG2I6iAZp17OROZI5yl4TSORrSBDGIi2sayxyxP0x+IPKtrCUcBGNx
wGp+56bP/V0hA6sgCPh/iwvqLoeibso6l/Kd4ltVAEQnHTd6fr8g+wLEUXfbJVTR
7aeFUoaFmWjSPlQrNr6HlxSLV/kRx9kVJp1Pn16vkfVBF7fG7iDLiqphwEeQg5ND
nmGeKAbRRNxFHyBHf0XRsaYiFZQckguO+71XSRtVx8/YP5nyNbtl9y1h/4JlT6Gy
t7hb5twYFQyQrKss83E/Bo1sRdHpj0ibtqb4ZbYANbh482E6yFhAkuo8YjVTJipI
1Ve8EBKnX3R+pDt147uyysNvtPVXML+sWpGSMVSm4NA8uT3F5nqxVwj+SeXy3Wq/
CHQ2VBKGBC655G+wFD5C6O7cTx2MwH+2H8tzhWm+gFlI3MFKEXa/PC+YUC/diYcb
BrApavriTRa5Ag0EWmkAZgEQAPXMD3mZI+ChvBysXZWksC88/uSEwFeb3XkcRm7v
04GN7hcz+bfrmnUTB3tuE/ZQgv+u7ZjetvH1aEKieznn/GjnWoOBoJusOYvfAQeF
0mQVi118QiOZRCnEZpkz+RY9TiXVgrZJg+AGqHZ3Ol4GkInEV2NWgH37Xal+HkFl
rwI2U7mL0kZRG+LAVCQHKzqU0R0HE1XyJ4qf0awtG5Qi/TZvgXBdZPDXgr8i9Vlf
UUu10c2XnXM0Av/YAlZmBFjVYrSOUCFenqSVqL+s9sTCVdWlJrGjrr3Ja4uT3kl2
rLva0AR4oSQoxt8adKohmFz0vzOkQtCoRzhrCwoo3JvNjKdSNoOP1nSsxlO5ji8r
ih5d+ajPgi580XyHLnrvG7vobR48qqscv1hizKuCgTacOTe6Db2Gqc8xF6v8HhJa
KwWJtmFllIfN/tIvZ6BbbgHQn0IGf4CYnWf0SksPZqpBmTRpD2jfBxcj2UEg+AR3
LARjuyUVpFJScyu6ExQG+6O+ByLL31iWP5MgUrza1rIpriPa3NT3rZ3DG2pvQrS3
ySsrPzH7VRX8L1ThSMSzjwF96aMsd14s7XzR4EzNuWwZDukfs0yavZk6l4o1M0mb
tbJi7hE4cz13KRHYvIkKMdZGYUnzRzZUDlsj2imakk3BR6GXnxZ1ST6062g+QxiL
AJFLABEBAAGJBHIEGAEKACYCGwIWIQQx2VyrbYDSYiRKF1CkdiDoAeR+lQUCX9UL
DQUJCS5xpwJAwXQgBBkBCgAdFiEEuNUxXaAAcsCoYIifzjbhFyAuOEIFAlppAGYA
CgkQzjbhFyAuOELmrQ/9H9wrWsWa21STZdxUmyU2sh9VXAWEHl1Ey0fVTznDM0Fl
zx5YSR/TmmnE36rpaz31Ttkx8SP914oV+mMgseecdya9Bf6uZL9Cv7V3KEsJBRL/
ncrOWQBHP/Xy1X+mLD6A19xq7H4RihSLj0LeK2YVjrJzJ7wMf4mKXuBayQeAHImU
WRCRTbmK3umh2nB5V0iPd/XZEIiYtiTPe+7E/va6+0bBvOumF3a+Z0iui7eU4hFC
7Jk71D0dcg09SlIaNoMOrw7cMC3j2pMdKtsj8+0I6WBv14PhhqPAsnjdf7I/4NfK
L7Jav8T/gDS01uA2Jxm72d+wr+eSjOBXa6x8CEbTqfkjAGxsWENThCp6zDkaXSDd
JsV0va47vjzG8+wTDAvPy5IxIM/KZZdl4uWM+mF5K+q+eSTOHe7aLF2OdcussoBA
A18zm994dAkG1COX/qpxanxx2bv/2IvCGPg+x6JtAN8ji2kncWu3dWGQdE5XbVjc
fDwgsUPpp04G27Mr/x+HpEbgZ5SdA0dAqJktlNvCcHALhlblCWrsh/1QNjT/2iG8
wsjcpEy/s4tWAuV4PTa4xvZ1JPS7Z7Eo5aBy9ZGOWG9SrHEiHnhkUsiswbHBOEjd
pBSkmNElDcv9fRUahVCTPfvWBATFDrQyMjJBSm+cV8c/iFQM7isVSu8W7E0eetsJ
EKR2IOgB5H6Vv9sP/1dxTvH0N0UoEoxIG/hnirEkbRpljdvqy4/uikYBKyQgSbo8
VITTjea7gIhDztil9WZYt35jbOmoaGM2Z6TP2LEDOWgljYUNq9pl9Sc2GS8cNtEO
WxExzGOc1Flo730dX3A85Ks3+0WPXZjLDcRRcPVkFd5WLQQDV1YVYopWkuQBC+Br
4q3uv+sk+bw6gDa9+zFBbDuegdsYuTXrFHoxHz2GRv9Yb7ULCMgpFeNKDgtQq91u
RqewoTwQp9tlp91LH/hh7R0Q4DRgeFDkLnVRXwSKjVvCrT5cBgImGwtFTGS4egoy
MDKd/KKjZllp1ahRCln1XfmFQyQVMVvuF/JTtt31n6KwXwK2yxIlXB01xvRH+Ees
AWeRYWKWXydaAY/9Ve0/PLFlgsr/XUGvt0GoEKe7odD3nZgg6015+/8JTroKw19L
NZkhdfFMl11Zi0j5k3UbyzjYVpFSd8K2o0VoOG1LFsPp8tlRxNoVzpId0CX1au/p
y1H7Wy/39mzriRG3rw+mJAQbBjN09putCltXFXpOEWk08n/N3vufCVQUoSu/2Bqw
2HYj8VtToQp+O5dG3XxvDHINtInP1yr2Wcw2plna0KoXLwv/lZgDm3LN+eCWpG6d
N/xk25DTSqTHArUQIEkhcHYK6GnyxUcvoKtG88hXtqEPYXiK08FZYAUPTnDYuQIN
BFppAIkBEADDjvQZUs1NoqJpxkD2QDBudU1DBCaeI1D6CancMtb5FebPUxgFlDMd
CBGOun48dY5i87gDhT/qS3gP/Mv9rjKJmcG9JHfhpXdW73owxrcsQ96nxxVJNEVl
UHJw00z8C9eGWqr0SzSoE33K/PkzSkgtsaotF6+3uCerWulweulmGa5dpVfV0mbS
aVw8VmrhZ5NmCeodyy/lR85rPik5pb32NT6v7xBkgkfS0VYtPB2E5gW1pXX/jEOi
Mfq9idOEP9lxrNXV9j49Lr0JQCwAcrYbQ2+VPe6eacJEjzJ/6HiUqhPrYdnvydmb
hU+xmv2NjGp2UnDZDEhzQfwm6fMx+8Nx2uPzCnXQGoyRBwiC/KcdW0F1ZPKdSXqH
NKoOF62pLvIMSmfI3ZVOrTohArfr1kFEYVDv9Nl7oY+qg2rZEc2srOF74a9Z46bR
TDPsEQzE2UMCvu3+rofhSD7aRotlKeDCvbe2s0yE4Man457Xc3LXh8Gva8CzCOLE
2eMhNTsHIZk68WgXp3/uvE4Xy42myrk1AV8XXDdlWgx0Kc/I6tE59O5NVPSfuGvH
1a15KKx0F6euEnYDKKpQ5PDR6dSn61po0tfbt96m044G/xQFjrfhHei4jji9Ogd9
vlXVAi2vn3+NCSHFP5l3igLByBHy9iLIdmz7yQuus/1nwRmxOHOf2QARAQABiQI8
BBgBCgAmAhsMFiEEMdlcq22A0mIkShdQpHYg6AHkfpUFAl/VCxkFCQkucZAACgkQ
pHYg6AHkfpVPSRAAmheYkYJmtDbkzPBBnj5mbCIQN1/G5PI9eixc/TXWFOXtcjU1
mJlJpSidHJyLRrx7r0c+N+s8vnY/JuUBsNoMJMER+Mv/CFW4iFi59V534SyAb2S0
7NINJnFNkXBY62CDz9KsMuv/MdSv2yLhPH2Tfrm/eDRQesj1PanE4U1cgjWyJRc/
IOlaRHvTasWDLgwbQi8ykt+4xUWzL/YKHzB+KyyzBK7vPBXqySX8ka4BOw7SDwG5
lX2gtmhk4AGBwVChLXKflqVx1WXj4DPOt0kmOKVnKFyvUijK58M0A2FMgFMXDTIS
DRtoZPdx/rkODXxgS+W+27NcYAnxJiM0cQqizEnQh7PQ1KzgdChPejYXMKe9lwdn
ssMUxrBpbuAuagEf+pebNjD2eaNR4p8kfaDdGn53q55ysDvoyxKvnVQGSk1FAR9Q
s4N5a4f02U7dzlyEhEfIcuUlRCfnlpn4n725YIhHheDig5zKWoEZCkNIfiRcGzDl
8Drj+tlZiUR+gDkIoWSBaCkKbIQlc8qCYy6Hm7oZBaol6xKlUnTMK2rjK8fR4i8r
bVDWBAaWj3jcDHJ0Jg3fS/qBpeya/JXMp89TR8NK5Ys7PZpWbor+puXBYyXDAVx3
rXQ7JBA5klHPxrgjso1S/LqwscKLENtrVjdjhryLBmPifrmofJRnrpiHIEa5Ag0E
WmkAswEQAL0hKwsRybQzkNGpJP+ElLSwFHd7XQhr+qIwLllpumWtnIK/DHmv8SpW
FqAYajmRTXipFcBHH25x2jIIliZidn0a9826l+sMzrFadMC6/W4pitP71TeqZzwn
pAuHs14YL7Wiy0aJQnfbCpRzPq3kYyOXmhmY7lPWO0WdUpR6W8wUbleK5XOVDDRx
aIC/M3hhDOxZOMzQ+pdn4BaOFQQ0ygsRkqOudbuc0R1giYRt1i6gMeT8gfzL9jlw
HcJ+aVnxdUQQ4uC47oKo/+lg7qh7LsiW79pQC1Bcdm8lhRmqtxe6ub60ecjax3XU
1ILIEfIFCv6M7LRUAwz0bqk35spgkJqrGGKkdeWEKAFHg2QWR2F0zy+HdlPLfKxO
uhaccpwc9EJtf744GS0SXa2AXr32j56n7CFcEjFcIQPBC6OJn6eA3hOVUYGZ7SrT
4fsmZiFAdGEkvLKFuNhju1Hj2EJQUY1pm4GSBco7BR8x+QqoYrt5clU3WxRMNfTR
0Rtuzsh4xskXNVMMgvKOahAtxENv2M2Cx6zJPVL5dmaysP7d6QRVeOQA5PwkcZ5Q
qK6JtDZj2jpaKQH4Za715kiIcdqMDSkwxa6avc0kARHvfFcBR4hwDm1GAlaKG7eH
8TOGGQIk8x2F3s4l8mTJVLWTP/uJYnkYBdqANYo5t1NIQLvwLFV3ABEBAAGJAjwE
GAEKACYCGyAWIQQx2VyrbYDSYiRKF1CkdiDoAeR+lQUCX9ULIwUJCS5xcAAKCRCk
diDoAeR+leekD/sF7aHH0W35ckWrXZlfSp0qHPWrBUaLBI9OAUHenRhgs4SbK0D4
wqEiu0C5iDQojpXAeALQ8g/1pUsZ1yuFqYbGYWrHkA0Pm+P3tAGB4LMZ41YfvROP
uaiW/+IMJbWllgRtaDt8/NtCgs30WI9I+az5M29HcGfvEwEUykrBx3dE9T+1ui3O
capdd+GMvdAAsX5PyVkjWgZ7GrZeH8mG7UysYfT4qthxEtQfZ/u8ceSduKA46ugh
C2eafIDNvluqn7BU4oKxME61u6C8BN2yHLI6LV0Tr4z5H8joVbM4BSFMwLVGlsXf
HhB8kLiErN6bXolxsjARlmYiD9S9H2AcYidr6RYXf2EVFSpBG59xn1WTDN+DsHQf
7btNPEPl/OPxa3OQjG+xn8USddiP0N0B4xsyzMNCCKDgvXXcIhX55KG9eh3Tc98S
fEyhxu8ybZBIGmTJysPKxijfvSgQF+RPNTsz9lvXqkoK7RTgeYMschpjJEznCLbt
M6eTDb5z0G5uLXh6+dYxtDOlPogI5OHd+G51LwCjvrQ+AtIUCgafuemwA9mpFT2b
svb/qcxSVUb44bVaNHn1JHebX2YbokGtBOm1x2PI5fT8n6YIIYz3jKYOZAYdUT7x
6qURyNjOfG4aPJIATwuh4GSNuxUG40+yuT+XfQF24mu1esS1J3wzRloJ7w==
=K3x+
-----END PGP PUBLIC KEY BLOCK-----
```

@ -1,12 +0,0 @@
---
layout: default
---
# License
From its first release in 2002, Secret Rabbit Code was under a dual licensing
scheme where people could chose to use it under the terms of the GNU General
Public License or pay for a commercial use license.
In 2016, thanks to a generous offer from Epic Games International, Secret Rabbit
Code was relicensed under the 2-clause BSD license.

@ -1,17 +0,0 @@
---
layout: default
---
# Mailing Lists
There are currently two mailings lists for Secret Rabbit Code:
- **src-announce\@mega-nerd.com**  
[Subscribe](mailto:src-announce-request@mega-nerd.com?subject=subscribe)
A read only announcement list.
- **src\@mega-nerd.com**  
[Subscribe](mailto:src-request@mega-nerd.com?subject=subscribe)
A general list which will also carry all the email from the announce
list. Posting to this list is restricted to subscribers.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 770 B

@ -1,84 +0,0 @@
---
layout: default
---
# SRC Quality
**This document not yet complete.**
When measuring the performance of a Sample Rate Converter, there are three
factors to consider:
- **Signal-to-Noise Ratio** - a measure of how much noise the sample rate
conversion process adds to the signal. This is measured in decibels (dB) and
the higher this value the better. For most sample rate converters, the SNR
will vary depending on the input signal and the ratio between input and output
sample rates. The only valid comparison of SNR is between the worst case for
each converter.
- **Bandwidth** - most sample rate converters attenuate high frequencies as part
of their operation. Bandwidth can be measured by finding the frequency where
the attenuation is 3dB and expressing that as a percentage of the full
bandwidth at that sampling rate.
- **Speed** - the faster the better **:-)**.
There are a number of sample rate converters available for downloading but I
will limit the comparison of Secret Rabbit Code to the following:
- [sndfile-resample](http://libsndfile.github.io/libsamplerate/download.html)
which is a program (which uses libsamplerate) from the **examples/** directory
of the Secret Rabbit Code source code distribution.
- [Resample](https://ccrma.stanford.edu/~jos/resample/) by Julius O Smiths which
seems to have been the first high quality converter available as source code.
- [ResampAudio](http://www.tsp.ece.mcgill.ca/MMSP/Documents/Software/AFsp/ResampAudio.html)
which is part of [Audio File Programs and Routines](http://www.tsp.ece.mcgill.ca/MMSP/Documents/Software/AFsp/AFsp.html)
by Peter Kabal.
- [SoX](http://home.sprynet.com/~cbagwell/sox.html) which is maintained by Chris
Bagwell. SoX is also able to perform some low quality sample rate conversions
but these will not be investigated.
- [Shibatch](http://shibatch.sourceforge.net/) which seems to be a frequency
domain sample rate converter. Unfortunately, this converter does not handle
arbitrary conversion ratios and hence could not be properly compared to the
other converters.
- [sr-convert](http://sr-convert.sourceforge.net/) is another converter which
does not handle arbitrary conversion ratios.
It should be noted that the first three converters above are based on the
algorithm by [Julius O. Smith](http://www-ccrma.stanford.edu/~jos/resample/)
which emulates the conversion of the digital signal to an analogue one and then
samples the analogue signal at the new sample rate.
## Methodology
Measuring the SNR of a converter is relatively straightforward. Generate an
input signal consisting of a windowed sine wave, sample rate convert it and
measure the signal-to-noise ratio of the output signal. A typical length for the
original file is 30000 samples.
The bandwidth of a sample rate converter is a little more difficult to measure.
Currently this is done by generating two short files containing a windowed sine
wave. The frequencies of the sine waves are 0.35 and 0.495 of the sample rate.
These files are then upsampled by a factor of 2 using the converter under test.
If the attenuation of the lower frequency is less than 3dB and higher frequency
is more than 3dB, it is then possible to iteratively increase the lower
frequency and decrease the upper frequency keeping the -3dB point bracketed.
When the distance between the upper and lower frequency is sufficiently small,
it is possible to obtain a very accurate estimate of the -3dB frequency.
The speed of a sample rate converter is easy to measure; simply perform a
conversion on a large file or a number of smaller files and time the conversion
process.
The above measurement techniques are built into a test program which is
delivered with the Secret Rabbit Code source code distribution. This program is
able to test the first four of the above converters.
## SoX
SoX provides three methods of resampling; a linear interpolator, a polyphase
resampler and the Julius O. Smith simulated analogue filter method.
## Shibatch
Shibach
**More Coming Soon.**

@ -1,15 +0,0 @@
---
layout: default
---
# Compiling on Win32
You can use [CMake](https://cmake.org/) to generate Visual Studio project. The
configuration process is described [here](https://cmake.org/runningcmake/).
The libsamplerate library itself does not require any dependencies, but if you
want to build examples and tests, you will need the [libsndfile](https://github.com/libsndfile/libsndfile)
and [FFTW](http://www.fftw.org/) libraries. The easiest way to install them is
to use a package manager, such as [Vcpkg](https://github.com/microsoft/vcpkg). Their README.md contains detailed
installation instructions for supported platforms. Libsamplerate requires the
`libsndfile` and `fftw3` packages.

@ -1,31 +0,0 @@
find_package(ALSA)
set(HAVE_ALSA ${ALSA_FOUND} PARENT_SCOPE)
# ALSA::ALSA target is exported since CMake >= 3.12, create it for
# old CMake versions
if(ALSA_FOUND)
if(NOT TARGET ALSA::ALSA)
add_library(ALSA::ALSA UNKNOWN IMPORTED)
set_target_properties(ALSA::ALSA PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${ALSA_INCLUDE_DIRS}"
IMPORTED_LOCATION "${ALSA_LIBRARIES}")
endif()
endif()
add_executable(timewarp-file timewarp-file.c)
target_link_libraries(timewarp-file
PRIVATE
samplerate
$<$<BOOL:${SndFile_FOUND}>:${SNDFILE_TARGET}>)
add_executable(varispeed-play varispeed-play.c audio_out.c audio_out.h)
target_link_libraries(varispeed-play
PRIVATE
samplerate
$<$<BOOL:${SndFile_FOUND}>:${SNDFILE_TARGET}>)
if(WIN32)
target_link_libraries(varispeed-play PRIVATE winmm)
elseif(APPLE)
target_link_libraries(varispeed-play PRIVATE "-framework CoreAudio")
elseif(ALSA_FOUND)
target_link_libraries(varispeed-play PRIVATE ALSA::ALSA)
endif()

File diff suppressed because it is too large Load Diff

@ -1,25 +0,0 @@
/*
** Copyright (c) 1999-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
typedef struct AUDIO_OUT AUDIO_OUT ;
typedef int (*get_audio_callback_t) (void *callback_data, float *samples, int frames) ;
/* A general audio output function (Linux/ALSA, Linux/OSS, Win32, MacOSX,
** Solaris) which retrieves data using the callback function in the above
** struct.
**
** audio_open - opens the device and returns an anonymous pointer to its
** own private data.
*/
AUDIO_OUT *audio_open (int channels, int samplerate) ;
void audio_play (get_audio_callback_t callback, AUDIO_OUT *audio_out, void *callback_data) ;
void audio_close (AUDIO_OUT *audio_data) ;

@ -1,234 +0,0 @@
/*
** Copyright (c) 2005-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include <math.h>
#if (HAVE_SNDFILE)
#include <samplerate.h>
#include <sndfile.h>
#define ARRAY_LEN(x) ((int) (sizeof (x) / sizeof ((x) [0])))
#define DEFAULT_CONVERTER SRC_SINC_MEDIUM_QUALITY
#define BUFFER_LEN 1024
#define INPUT_STEP_SIZE 8
typedef struct
{ sf_count_t index ;
double ratio ;
} TIMEWARP_FACTOR ;
static void usage_exit (const char *progname) ;
static sf_count_t timewarp_convert (SNDFILE *infile, SNDFILE *outfile, int converter, int channels) ;
int
main (int argc, char *argv [])
{ SNDFILE *infile, *outfile ;
SF_INFO sfinfo ;
sf_count_t count ;
if (argc != 3)
usage_exit (argv [0]) ;
putchar ('\n') ;
printf ("Input File : %s\n", argv [argc - 2]) ;
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) ;
} ;
if (INPUT_STEP_SIZE * sfinfo.channels > BUFFER_LEN)
{ printf ("\n\nError : INPUT_STEP_SIZE * sfinfo.channels > BUFFER_LEN\n\n") ;
exit (1) ;
} ;
/* Delete the output file length to zero if already exists. */
remove (argv [argc - 1]) ;
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) ;
} ;
sf_command (outfile, SFC_SET_CLIPPING, NULL, SF_TRUE) ;
printf ("Output file : %s\n", argv [argc - 1]) ;
printf ("Converter : %s\n", src_get_name (DEFAULT_CONVERTER)) ;
count = timewarp_convert (infile, outfile, DEFAULT_CONVERTER, sfinfo.channels) ;
printf ("Output Frames : %ld\n\n", (long) count) ;
sf_close (infile) ;
sf_close (outfile) ;
return 0 ;
} /* main */
/*==============================================================================
*/
static TIMEWARP_FACTOR warp [] =
{ { 0 , 1.00000001 },
{ 20000 , 1.01000000 },
{ 20200 , 1.00000001 },
{ 40000 , 1.20000000 },
{ 40300 , 1.00000001 },
{ 60000 , 1.10000000 },
{ 60400 , 1.00000001 },
{ 80000 , 1.50000000 },
{ 81000 , 1.00000001 },
} ;
static sf_count_t
timewarp_convert (SNDFILE *infile, SNDFILE *outfile, int converter, int channels)
{ static float input [BUFFER_LEN] ;
static float output [BUFFER_LEN] ;
SRC_STATE *src_state ;
SRC_DATA src_data ;
int error, warp_index = 0 ;
sf_count_t input_count = 0, 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 ;
if (warp [0].index > 0)
src_data.src_ratio = 1.0 ;
else
{ src_data.src_ratio = warp [0].ratio ;
warp_index ++ ;
} ;
src_data.data_out = output ;
src_data.output_frames = BUFFER_LEN /channels ;
while (1)
{
if (warp_index < ARRAY_LEN (warp) - 1 && input_count >= warp [warp_index].index)
{ src_data.src_ratio = warp [warp_index].ratio ;
warp_index ++ ;
} ;
/* If the input buffer is empty, refill it. */
if (src_data.input_frames == 0)
{ src_data.input_frames = (long) sf_readf_float (infile, input, INPUT_STEP_SIZE) ;
input_count += src_data.input_frames ;
src_data.data_in = input ;
/* The last read will not be a full buffer, so snd_of_input. */
if (src_data.input_frames < INPUT_STEP_SIZE)
src_data.end_of_input = SF_TRUE ;
} ;
/* Process current block. */
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 ;
/* 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_delete (src_state) ;
return output_count ;
} /* timewarp_convert */
/*------------------------------------------------------------------------------
*/
static void
usage_exit (const char *progname)
{ const char *cptr ;
if ((cptr = strrchr (progname, '/')) != NULL)
progname = cptr + 1 ;
if ((cptr = strrchr (progname, '\\')) != NULL)
progname = cptr + 1 ;
printf ("\n"
" A program demonstrating the time warping capabilities of libsamplerate."
" It uses libsndfile for file I/O and Secret Rabbit Code (aka libsamplerate)"
" for performing the warping.\n"
" It works on any file format supported by libsndfile with any \n"
" number of channels (limited only by host memory).\n"
"\n"
" The warping is dependant on a table hard code into the source code.\n"
"\n"
" libsamplerate version : %s\n"
"\n"
" Usage : \n"
" %s <input file> <output file>\n"
"\n", src_get_version (), progname) ;
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"
" (https://github.com/libsndfile/libsndfile/).\n"
" It is therefore completely broken and non-functional.\n"
"****************************************************************\n"
"\n"
) ;
return 0 ;
} /* main */
#endif

@ -1,246 +0,0 @@
/*
** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include <math.h>
#if (HAVE_SNDFILE)
#include <samplerate.h>
#include <sndfile.h>
#include "audio_out.h"
#define ARRAY_LEN(x) ((int) (sizeof (x) / sizeof ((x) [0])))
#define BUFFER_LEN 4096
#define VARISPEED_BLOCK_LEN 64
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define SRC_MAGIC ((int) ('S' << 16) + ('R' << 8) + ('C'))
#define SNDFILE_MAGIC ((int) ('s' << 24) + ('n' << 20) + ('d' << 16) + ('f' << 12) + ('i' << 8) + ('l' << 4) + 'e')
#ifndef M_PI
#define M_PI 3.14159265358979323846264338
#endif
typedef struct
{ int magic ;
SNDFILE *sndfile ;
SF_INFO sfinfo ;
float buffer [BUFFER_LEN] ;
} SNDFILE_CB_DATA ;
typedef struct
{ int magic ;
SNDFILE_CB_DATA sf ;
int freq_point ;
SRC_STATE *src_state ;
} SRC_CB_DATA ;
static int varispeed_get_data (SRC_CB_DATA *data, float *samples, int frames) ;
static void varispeed_play (const char *filename, int converter) ;
static long src_input_callback (void *cb_data, float **data) ;
int
main (int argc, char *argv [])
{ const char *cptr, *progname, *filename ;
int k, converter ;
converter = SRC_SINC_FASTEST ;
progname = argv [0] ;
if ((cptr = strrchr (progname, '/')) != NULL)
progname = cptr + 1 ;
if ((cptr = strrchr (progname, '\\')) != NULL)
progname = cptr + 1 ;
printf ("\n"
" %s\n"
"\n"
" This is a demo program which plays the given file at a slowly \n"
" varying speed. Lots of fun with drum loops and full mixes.\n"
"\n"
" It uses Secret Rabbit Code (aka libsamplerate) to perform the \n"
" vari-speeding and libsndfile for file I/O.\n"
"\n", progname) ;
if (argc == 2)
filename = argv [1] ;
else if (argc == 4 && strcmp (argv [1], "-c") == 0)
{ filename = argv [3] ;
converter = atoi (argv [2]) ;
}
else
{ printf (" Usage :\n\n %s [-c <number>] <input file>\n\n", 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\n", k, cptr) ;
puts ("") ;
exit (1) ;
} ;
varispeed_play (filename, converter) ;
return 0 ;
} /* main */
/*==============================================================================
*/
static void
varispeed_play (const char *filename, int converter)
{ SRC_CB_DATA data ;
AUDIO_OUT *audio_out ;
int error ;
memset (&data, 0, sizeof (data)) ;
data.magic = SRC_MAGIC ;
data.sf.magic = SNDFILE_MAGIC ;
if ((data.sf.sndfile = sf_open (filename, SFM_READ, &data.sf.sfinfo)) == NULL)
{ puts (sf_strerror (NULL)) ;
exit (1) ;
} ;
/* Initialize the sample rate converter. */
if ((data.src_state = src_callback_new (src_input_callback, converter, data.sf.sfinfo.channels, &error, &data.sf)) == NULL)
{ printf ("\n\nError : src_new() failed : %s.\n\n", src_strerror (error)) ;
exit (1) ;
} ;
printf (
" Playing : %s\n"
" Converter : %s\n"
"\n"
" Press <control-c> to exit.\n"
"\n",
filename, src_get_name (converter)) ;
if ((audio_out = audio_open (data.sf.sfinfo.channels, data.sf.sfinfo.samplerate)) == NULL)
{ printf ("\n\nError : audio_open () failed.\n") ;
exit (1) ;
} ;
/* Pass the data and the callbacl function to audio_play */
audio_play ((get_audio_callback_t) varispeed_get_data, audio_out, &data) ;
/* Cleanup */
audio_close (audio_out) ;
sf_close (data.sf.sndfile) ;
src_delete (data.src_state) ;
} /* varispeed_play */
static long
src_input_callback (void *cb_data, float **audio)
{ SNDFILE_CB_DATA * data = (SNDFILE_CB_DATA *) cb_data ;
const int input_frames = ARRAY_LEN (data->buffer) / data->sfinfo.channels ;
int read_frames ;
if (data->magic != SNDFILE_MAGIC)
{ printf ("\n\n%s:%d Eeeek, something really bad happened!\n", __FILE__, __LINE__) ;
exit (1) ;
} ;
for (read_frames = 0 ; read_frames < input_frames ; )
{ sf_count_t position ;
read_frames += (int) sf_readf_float (data->sndfile, data->buffer + read_frames * data->sfinfo.channels, input_frames - read_frames) ;
position = sf_seek (data->sndfile, 0, SEEK_CUR) ;
if (position < 0 || position == data->sfinfo.frames)
sf_seek (data->sndfile, 0, SEEK_SET) ;
} ;
*audio = & (data->buffer [0]) ;
return input_frames ;
} /* src_input_callback */
/*==============================================================================
*/
static int
varispeed_get_data (SRC_CB_DATA *data, float *samples, int out_frames)
{ float *output ;
int rc, out_frame_count ;
if (data->magic != SRC_MAGIC)
{ printf ("\n\n%s:%d Eeeek, something really bad happened!\n", __FILE__, __LINE__) ;
exit (1) ;
} ;
for (out_frame_count = 0 ; out_frame_count < out_frames ; out_frame_count += VARISPEED_BLOCK_LEN)
{ double src_ratio = 1.0 - 0.5 * sin (data->freq_point * 2 * M_PI / 20000) ;
data->freq_point ++ ;
output = samples + out_frame_count * data->sf.sfinfo.channels ;
if ((rc = src_callback_read (data->src_state, src_ratio, VARISPEED_BLOCK_LEN, output)) < VARISPEED_BLOCK_LEN)
{ printf ("\nError : src_callback_read short output (%d instead of %d)\n\n", rc, VARISPEED_BLOCK_LEN) ;
exit (1) ;
} ;
} ;
return out_frames ;
} /* varispeed_get_data */
/*==============================================================================
*/
#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.zip.com.au/~erikd/libsndfile/).\n"
" It is therefore completely broken and non-functional.\n"
"****************************************************************\n"
"\n"
) ;
return 0 ;
} /* main */
#endif

@ -1,189 +0,0 @@
/*
** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
/*
** API documentation is available here:
** http://libsndfile.github.io/libsamplerate/api.html
*/
#ifndef SAMPLERATE_H
#define SAMPLERATE_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Opaque data type SRC_STATE. */
typedef struct SRC_STATE_tag SRC_STATE ;
/* SRC_DATA is used to pass data to src_simple() and src_process(). */
typedef struct
{ const float *data_in ;
float *data_out ;
long input_frames, output_frames ;
long input_frames_used, output_frames_gen ;
int end_of_input ;
float src_ratio ;
} SRC_DATA ;
/*
** User supplied callback function type for use with src_callback_new()
** and src_callback_read(). First parameter is the same pointer that was
** passed into src_callback_new(). Second parameter is pointer to a
** pointer. The user supplied callback function must modify *data to
** point to the start of the user supplied float array. The user supplied
** function must return the number of frames that **data points to.
*/
typedef long (*src_callback_t) (void *cb_data, float **data) ;
/*
** Standard initialisation function : return an anonymous pointer to the
** internal state of the converter. Choose a converter from the enums below.
** Error returned in *error.
*/
SRC_STATE* src_new (int converter_type, int channels, int *error) ;
/*
** Clone a handle : return an anonymous pointer to a new converter
** containing the same internal state as orig. Error returned in *error.
*/
SRC_STATE* src_clone (SRC_STATE* orig, int *error) ;
/*
** Initilisation for callback based API : return an anonymous pointer to the
** internal state of the converter. Choose a converter from the enums below.
** The cb_data pointer can point to any data or be set to NULL. Whatever the
** value, when processing, user supplied function "func" gets called with
** cb_data as first parameter.
*/
SRC_STATE* src_callback_new (src_callback_t func, int converter_type, int channels,
int *error, void* cb_data) ;
/*
** Cleanup all internal allocations.
** Always returns NULL.
*/
SRC_STATE* src_delete (SRC_STATE *state) ;
/*
** Standard processing function.
** Returns non zero on error.
*/
int src_process (SRC_STATE *state, SRC_DATA *data) ;
/*
** Callback based processing function. Read up to frames worth of data from
** the converter int *data and return frames read or -1 on error.
*/
long src_callback_read (SRC_STATE *state, float src_ratio, long frames, float *data) ;
/*
** Simple interface for performing a single conversion from input buffer to
** output buffer at a fixed conversion ratio.
** Simple interface does not require initialisation as it can only operate on
** a single buffer worth of audio.
*/
int src_simple (SRC_DATA *data, int converter_type, int channels) ;
/*
** This library contains a number of different sample rate converters,
** numbered 0 through N.
**
** Return a string giving either a name or a more full description of each
** sample rate converter or NULL if no sample rate converter exists for
** the given value. The converters are sequentially numbered from 0 to N.
*/
const char *src_get_name (int converter_type) ;
const char *src_get_description (int converter_type) ;
const char *src_get_version (void) ;
/*
** Set a new SRC ratio. This allows step responses
** in the conversion ratio.
** Returns non zero on error.
*/
int src_set_ratio (SRC_STATE *state, float new_ratio) ;
/*
** Get the current channel count.
** Returns negative on error, positive channel count otherwise
*/
int src_get_channels (SRC_STATE *state) ;
/*
** Reset the internal SRC state.
** Does not modify the quality settings.
** Does not free any memory allocations.
** Returns non zero on error.
*/
int src_reset (SRC_STATE *state) ;
/*
** Return TRUE if ratio is a valid conversion ratio, FALSE
** otherwise.
*/
int src_is_valid_ratio (float ratio) ;
/*
** Return an error number.
*/
int src_error (SRC_STATE *state) ;
/*
** Convert the error number into a string.
*/
const char* src_strerror (int error) ;
/*
** The following enums can be used to set the interpolator type
** using the function src_set_converter().
*/
enum
{
SRC_SINC_BEST_QUALITY = 0,
SRC_SINC_MEDIUM_QUALITY = 1,
SRC_SINC_FASTEST = 2,
SRC_ZERO_ORDER_HOLD = 3,
SRC_LINEAR = 4,
} ;
/*
** Extra helper functions for converting from short to float and
** back again.
*/
void src_short_to_float_array (const short *in, float *out, int len) ;
void src_float_to_short_array (const float *in, short *out, int len) ;
void src_int_to_float_array (const int *in, float *out, int len) ;
void src_float_to_int_array (const float *in, int *out, int len) ;
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* SAMPLERATE_H */

@ -1,58 +0,0 @@
%define name @PACKAGE@
%define version @VERSION@
%define release 1
%define prefix /usr
Summary: A library to do sample rate conversion for audio.
Name: %{name}
Version: %{version}
Release: %{release}
Prefix: %{prefix}
Copyright: BSD
Group: Libraries/Sound
Source: http://www.mega-nerd.com/SRC/libsamplerate-%{version}.tar.gz
URL: https://github.com/libsndfile/libsamplerate/
BuildRoot: /var/tmp/%{name}-%{version}
%description
libsamplerate is a C library capable of arbitrary and time varying
conversions; from downsampling by a factor of 12 to upsampling by the
same factor. The conversion ratio can also vary with time for speeding
up and slowing down effects.
%package devel
Summary: Libraries, includes, etc to develop libsamplerate applications
Group: Libraries
%description devel
Libraries, include files, etc you can use to develop libsamplerate applications.
%prep
%setup
%build
./configure --prefix=%{prefix}
make
%install
if [ -d $RPM_BUILD_ROOT ]; then rm -rf $RPM_BUILD_ROOT; fi
mkdir -p $RPM_BUILD_ROOT
make prefix=$RPM_BUILD_ROOT%{prefix} install
%clean
if [ -d $RPM_BUILD_ROOT ]; then rm -rf $RPM_BUILD_ROOT; fi
%files
%defattr(-,root,root)
%doc AUTHORS COPYING ChangeLog INSTALL NEWS README doc
%prefix/lib/libsamplerate.so.*
%files devel
%defattr(-,root,root)
%{prefix}/lib/libsamplerate.a
%{prefix}/lib/libsamplerate.la
%{prefix}/lib/libsamplerate.so
%{prefix}/include/samplerate.h
%{prefix}/lib/pkgconfig/samplerate.pc

@ -1,67 +0,0 @@
# ============================================================================
# https://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html
# ============================================================================
#
# SYNOPSIS
#
# AX_APPEND_COMPILE_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS], [INPUT])
#
# DESCRIPTION
#
# For every FLAG1, FLAG2 it is checked whether the compiler works with the
# flag. If it does, the flag is added FLAGS-VARIABLE
#
# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
# CFLAGS) is used. During the check the flag is always added to the
# current language's flags.
#
# If EXTRA-FLAGS is defined, it is added to the current language's default
# flags (e.g. CFLAGS) when the check is done. The check is thus made with
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
# force the compiler to issue an error when a bad flag is given.
#
# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
#
# NOTE: This macro depends on the AX_APPEND_FLAG and
# AX_CHECK_COMPILE_FLAG. Please keep this macro in sync with
# AX_APPEND_LINK_FLAGS.
#
# LICENSE
#
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.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 3 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, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 6
AC_DEFUN([AX_APPEND_COMPILE_FLAGS],
[AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG])
AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
for flag in $1; do
AX_CHECK_COMPILE_FLAG([$flag], [AX_APPEND_FLAG([$flag], [$2])], [], [$3], [$4])
done
])dnl AX_APPEND_COMPILE_FLAGS

@ -1,71 +0,0 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_append_flag.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
#
# DESCRIPTION
#
# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
# added in between.
#
# If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
# FLAG.
#
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.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 3 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, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 7
AC_DEFUN([AX_APPEND_FLAG],
[dnl
AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF
AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])
AS_VAR_SET_IF(FLAGS,[
AS_CASE([" AS_VAR_GET(FLAGS) "],
[*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
[
AS_VAR_APPEND(FLAGS,[" $1"])
AC_RUN_LOG([: FLAGS="$FLAGS"])
])
],
[
AS_VAR_SET(FLAGS,[$1])
AC_RUN_LOG([: FLAGS="$FLAGS"])
])
AS_VAR_POPDEF([FLAGS])dnl
])dnl AX_APPEND_FLAG

@ -1,65 +0,0 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_append_link_flags.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_APPEND_LINK_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS], [INPUT])
#
# DESCRIPTION
#
# For every FLAG1, FLAG2 it is checked whether the linker works with the
# flag. If it does, the flag is added FLAGS-VARIABLE
#
# If FLAGS-VARIABLE is not specified, the linker's flags (LDFLAGS) is
# used. During the check the flag is always added to the linker's flags.
#
# If EXTRA-FLAGS is defined, it is added to the linker's default flags
# when the check is done. The check is thus made with the flags: "LDFLAGS
# EXTRA-FLAGS FLAG". This can for example be used to force the linker to
# issue an error when a bad flag is given.
#
# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
#
# NOTE: This macro depends on the AX_APPEND_FLAG and AX_CHECK_LINK_FLAG.
# Please keep this macro in sync with AX_APPEND_COMPILE_FLAGS.
#
# LICENSE
#
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.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 3 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, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 6
AC_DEFUN([AX_APPEND_LINK_FLAGS],
[AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
for flag in $1; do
AX_CHECK_LINK_FLAG([$flag], [AX_APPEND_FLAG([$flag], [m4_default([$2], [LDFLAGS])])], [], [$3], [$4])
done
])dnl AX_APPEND_LINK_FLAGS

@ -1,74 +0,0 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
#
# DESCRIPTION
#
# Check whether the given FLAG works with the current language's compiler
# or gives an error. (Warnings, however, are ignored)
#
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
# success/failure.
#
# If EXTRA-FLAGS is defined, it is added to the current language's default
# flags (e.g. CFLAGS) when the check is done. The check is thus made with
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
# force the compiler to issue an error when a bad flag is given.
#
# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
#
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.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 3 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, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 5
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
[AS_VAR_SET(CACHEVAR,[yes])],
[AS_VAR_SET(CACHEVAR,[no])])
_AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
AS_VAR_IF(CACHEVAR,yes,
[m4_default([$2], :)],
[m4_default([$3], :)])
AS_VAR_POPDEF([CACHEVAR])dnl
])dnl AX_CHECK_COMPILE_FLAGS

@ -1,74 +0,0 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
#
# DESCRIPTION
#
# Check whether the given FLAG works with the linker or gives an error.
# (Warnings, however, are ignored)
#
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
# success/failure.
#
# If EXTRA-FLAGS is defined, it is added to the linker's default flags
# when the check is done. The check is thus made with the flags: "LDFLAGS
# EXTRA-FLAGS FLAG". This can for example be used to force the linker to
# issue an error when a bad flag is given.
#
# INPUT gives an alternative input source to AC_LINK_IFELSE.
#
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.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 3 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, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 5
AC_DEFUN([AX_CHECK_LINK_FLAG],
[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl
AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [
ax_check_save_flags=$LDFLAGS
LDFLAGS="$LDFLAGS $4 $1"
AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
[AS_VAR_SET(CACHEVAR,[yes])],
[AS_VAR_SET(CACHEVAR,[no])])
LDFLAGS=$ax_check_save_flags])
AS_VAR_IF(CACHEVAR,yes,
[m4_default([$2], :)],
[m4_default([$3], :)])
AS_VAR_POPDEF([CACHEVAR])dnl
])dnl AX_CHECK_LINK_FLAGS

@ -1,87 +0,0 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_COMPILER_VENDOR
#
# DESCRIPTION
#
# Determine the vendor of the C/C++ compiler, e.g., gnu, intel, ibm, sun,
# hp, borland, comeau, dec, cray, kai, lcc, metrowerks, sgi, microsoft,
# watcom, etc. The vendor is returned in the cache variable
# $ax_cv_c_compiler_vendor for C and $ax_cv_cxx_compiler_vendor for C++.
#
# LICENSE
#
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
# Copyright (c) 2008 Matteo Frigo
#
# 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 3 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, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 16
AC_DEFUN([AX_COMPILER_VENDOR],
[AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor,
dnl Please add if possible support to ax_compiler_version.m4
[# note: don't check for gcc first since some other compilers define __GNUC__
vendors="intel: __ICC,__ECC,__INTEL_COMPILER
ibm: __xlc__,__xlC__,__IBMC__,__IBMCPP__
pathscale: __PATHCC__,__PATHSCALE__
clang: __clang__
cray: _CRAYC
fujitsu: __FUJITSU
gnu: __GNUC__
sun: __SUNPRO_C,__SUNPRO_CC
hp: __HP_cc,__HP_aCC
dec: __DECC,__DECCXX,__DECC_VER,__DECCXX_VER
borland: __BORLANDC__,__CODEGEARC__,__TURBOC__
comeau: __COMO__
kai: __KCC
lcc: __LCC__
sgi: __sgi,sgi
microsoft: _MSC_VER
metrowerks: __MWERKS__
watcom: __WATCOMC__
portland: __PGI
tcc: __TINYC__
unknown: UNKNOWN"
for ventest in $vendors; do
case $ventest in
*:) vendor=$ventest; continue ;;
*) vencpp="defined("`echo $ventest | sed 's/,/) || defined(/g'`")" ;;
esac
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[
#if !($vencpp)
thisisanerror;
#endif
])], [break])
done
ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=`echo $vendor | cut -d: -f1`
])
])

@ -1,492 +0,0 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_compiler_version.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_COMPILER_VERSION
#
# DESCRIPTION
#
# This macro retrieves the compiler version and returns it in the cache
# variable $ax_cv_c_compiler_version for C and $ax_cv_cxx_compiler_version
# for C++.
#
# Version is returned as epoch:major.minor.patchversion
#
# Epoch is used in order to have an increasing version number in case of
# marketing change.
#
# Epoch use: * borland compiler use chronologically 0turboc for turboc
# era,
#
# 1borlanc BORLANDC++ before 5, 2cppbuilder for cppbuilder era,
# 3borlancpp for return of BORLANDC++ (after version 5.5),
# 4cppbuilder for cppbuilder with year version,
# and 5xe for XE era.
#
# An empty string is returned otherwise.
#
# LICENSE
#
# Copyright (c) 2014 Bastien ROUCARIES <roucaries.bastien+autoconf@gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 9
# for intel
AC_DEFUN([_AX_COMPILER_VERSION_INTEL],
[ dnl
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_major,
[__INTEL_COMPILER/100],,
AC_MSG_FAILURE([[[$0]] unknown intel compiler version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor,
[(__INTEL_COMPILER%100)/10],,
AC_MSG_FAILURE([[[$0]] unknown intel compiler version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch,
[(__INTEL_COMPILER%10)],,
AC_MSG_FAILURE([[[$0]] unknown intel compiler version]))
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch"
])
# for IBM
AC_DEFUN([_AX_COMPILER_VERSION_IBM],
[ dnl
dnl check between z/OS C/C++ and XL C/C++
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([],
[
#if defined(__COMPILER_VER__)
choke me;
#endif
])],
[
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_major,
[__xlC__/100],,
AC_MSG_FAILURE([[[$0]] unknown IBM compiler major version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor,
[__xlC__%100],,
AC_MSG_FAILURE([[[$0]] unknown IBM compiler minor version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch,
[__xlC_ver__/0x100],,
AC_MSG_FAILURE([[[$0]] unknown IBM compiler patch version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_build,
[__xlC_ver__%0x100],,
AC_MSG_FAILURE([[[$0]] unknown IBM compiler build version]))
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_build"
],
[
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch,
[__xlC__%1000],,
AC_MSG_FAILURE([[[$0]] unknown IBM compiler patch version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor,
[(__xlC__/10000)%10],,
AC_MSG_FAILURE([[[$0]] unknown IBM compiler minor version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_major,
[(__xlC__/100000)%10],,
AC_MSG_FAILURE([[[$0]] unknown IBM compiler major version]))
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch"
])
])
# for pathscale
AC_DEFUN([_AX_COMPILER_VERSION_PATHSCALE],[
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_major,
__PATHCC__,,
AC_MSG_FAILURE([[[$0]] unknown pathscale major]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor,
__PATHCC_MINOR__,,
AC_MSG_FAILURE([[[$0]] unknown pathscale minor]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch,
[__PATHCC_PATCHLEVEL__],,
AC_MSG_FAILURE([[[$0]] unknown pathscale patch level]))
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch"
])
# for clang
AC_DEFUN([_AX_COMPILER_VERSION_CLANG],[
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_major,
__clang_major__,,
AC_MSG_FAILURE([[[$0]] unknown clang major]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor,
__clang_minor__,,
AC_MSG_FAILURE([[[$0]] unknown clang minor]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch,
[__clang_patchlevel__],,0)
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch"
])
# for crayc
AC_DEFUN([_AX_COMPILER_VERSION_CRAY],[
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_major,
_RELEASE,,
AC_MSG_FAILURE([[[$0]] unknown crayc release]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor,
_RELEASE_MINOR,,
AC_MSG_FAILURE([[[$0]] unknown crayc minor]))
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor"
])
# for fujitsu
AC_DEFUN([_AX_COMPILER_VERSION_FUJITSU],[
AC_COMPUTE_INT(ax_cv_[]_AC_LANG_ABBREV[]_compiler_version,
__FCC_VERSION,,
AC_MSG_FAILURE([[[$0]]unknown fujitsu release]))
])
# for GNU
AC_DEFUN([_AX_COMPILER_VERSION_GNU],[
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_major,
__GNUC__,,
AC_MSG_FAILURE([[[$0]] unknown gcc major]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor,
__GNUC_MINOR__,,
AC_MSG_FAILURE([[[$0]] unknown gcc minor]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch,
[__GNUC_PATCHLEVEL__],,
AC_MSG_FAILURE([[[$0]] unknown gcc patch level]))
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch"
])
# For sun
AC_DEFUN([_AX_COMPILER_VERSION_SUN],[
m4_define([_AX_COMPILER_VERSION_SUN_NUMBER],
[
#if defined(__SUNPRO_CC)
__SUNPRO_CC
#else
__SUNPRO_C
#endif
])
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_until59,
!!(_AX_COMPILER_VERSION_SUN_NUMBER < 0x1000),,
AC_MSG_FAILURE([[[$0]] unknown sun release version]))
AS_IF([test "X$_ax_[]_AC_LANG_ABBREV[]_compiler_version_until59" = X1],
[dnl
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch,
_AX_COMPILER_VERSION_SUN_NUMBER % 0x10,,
AC_MSG_FAILURE([[[$0]] unknown sun patch version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor,
(_AX_COMPILER_VERSION_SUN_NUMBER / 0x10) % 0x10,,
AC_MSG_FAILURE([[[$0]] unknown sun minor version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_major,
(_AX_COMPILER_VERSION_SUN_NUMBER / 0x100),,
AC_MSG_FAILURE([[[$0]] unknown sun major version]))
],
[dnl
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch,
_AX_COMPILER_VERSION_SUN_NUMBER % 0x10,,
AC_MSG_FAILURE([[[$0]] unknown sun patch version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor,
(_AX_COMPILER_VERSION_SUN_NUMBER / 0x100) % 0x100,,
AC_MSG_FAILURE([[[$0]] unknown sun minor version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_major,
(_AX_COMPILER_VERSION_SUN_NUMBER / 0x1000),,
AC_MSG_FAILURE([[[$0]] unknown sun major version]))
])
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch"
])
AC_DEFUN([_AX_COMPILER_VERSION_HP],[
m4_define([_AX_COMPILER_VERSION_HP_NUMBER],
[
#if defined(__HP_cc)
__HP_cc
#else
__HP_aCC
#endif
])
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_untilA0121,
!!(_AX_COMPILER_VERSION_HP_NUMBER <= 1),,
AC_MSG_FAILURE([[[$0]] unknown hp release version]))
AS_IF([test "X$_ax_[]_AC_LANG_ABBREV[]_compiler_version_untilA0121" = X1],
[dnl By default output last version with this behavior.
dnl it is so old
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="01.21.00"
],
[dnl
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch,
(_AX_COMPILER_VERSION_HP_NUMBER % 100),,
AC_MSG_FAILURE([[[$0]] unknown hp release version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor,
((_AX_COMPILER_VERSION_HP_NUMBER / 100)%100),,
AC_MSG_FAILURE([[[$0]] unknown hp minor version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_major,
((_AX_COMPILER_VERSION_HP_NUMBER / 10000)%100),,
AC_MSG_FAILURE([[[$0]] unknown hp major version]))
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch"
])
])
AC_DEFUN([_AX_COMPILER_VERSION_DEC],[dnl
m4_define([_AX_COMPILER_VERSION_DEC_NUMBER],
[
#if defined(__DECC_VER)
__DECC_VER
#else
__DECCXX_VER
#endif
])
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch,
(_AX_COMPILER_VERSION_DEC_NUMBER % 10000),,
AC_MSG_FAILURE([[[$0]] unknown dec release version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor,
((_AX_COMPILER_VERSION_DEC_NUMBER / 100000UL)%100),,
AC_MSG_FAILURE([[[$0]] unknown dec minor version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_major,
((_AX_COMPILER_VERSION_DEC_NUMBER / 10000000UL)%100),,
AC_MSG_FAILURE([[[$0]] unknown dec major version]))
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch"
])
# borland
AC_DEFUN([_AX_COMPILER_VERSION_BORLAND],[dnl
m4_define([_AX_COMPILER_VERSION_TURBOC_NUMBER],
[
#if defined(__TURBOC__)
__TURBOC__
#else
choke me
#endif
])
m4_define([_AX_COMPILER_VERSION_BORLANDC_NUMBER],
[
#if defined(__BORLANDC__)
__BORLANDC__
#else
__CODEGEARC__
#endif
])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(,
_AX_COMPILER_VERSION_TURBOC_NUMBER)],
[dnl TURBOC
AC_COMPUTE_INT(
_ax_[]_AC_LANG_ABBREV[]_compiler_version_turboc_raw,
_AX_COMPILER_VERSION_TURBOC_NUMBER,,
AC_MSG_FAILURE([[[$0]] unknown turboc version]))
AS_IF(
[test $_ax_[]_AC_LANG_ABBREV[]_compiler_version_turboc_raw -lt 661 || test $_ax_[]_AC_LANG_ABBREV[]_compiler_version_turboc_raw -gt 1023],
[dnl compute normal version
AC_COMPUTE_INT(
_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor,
_AX_COMPILER_VERSION_TURBOC_NUMBER % 0x100,,
AC_MSG_FAILURE([[[$0]] unknown turboc minor version]))
AC_COMPUTE_INT(
_ax_[]_AC_LANG_ABBREV[]_compiler_version_major,
(_AX_COMPILER_VERSION_TURBOC_NUMBER/0x100)%0x100,,
AC_MSG_FAILURE([[[$0]] unknown turboc major version]))
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="0turboc:$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor"],
[dnl special version
AS_CASE([$_ax_[]_AC_LANG_ABBREV[]_compiler_version_turboc_raw],
[661],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="0turboc:1.00"],
[662],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="0turboc:1.01"],
[663],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="0turboc:2.00"],
[
AC_MSG_WARN([[[$0]] unknown turboc version between 0x295 and 0x400 please report bug])
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version=""
])
])
],
# borlandc
[
AC_COMPUTE_INT(
_ax_[]_AC_LANG_ABBREV[]_compiler_version_borlandc_raw,
_AX_COMPILER_VERSION_BORLANDC_NUMBER,,
AC_MSG_FAILURE([[[$0]] unknown borlandc version]))
AS_CASE([$_ax_[]_AC_LANG_ABBREV[]_compiler_version_borlandc_raw],
dnl BORLANDC++ before 5.5
[512] ,[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="1borlanc:2.00"],
[1024],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="1borlanc:3.00"],
[1024],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="1borlanc:3.00"],
[1040],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="1borlanc:3.1"],
[1106],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="1borlanc:4.0"],
[1280],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="1borlanc:5.0"],
[1312],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="1borlanc:5.02"],
dnl C++ Builder era
[1328],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="2cppbuilder:3.0"],
[1344],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="2cppbuilder:4.0"],
dnl BORLANDC++ after 5.5
[1360],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="3borlancpp:5.5"],
[1361],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="3borlancpp:5.51"],
[1378],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="3borlancpp:5.6.4"],
dnl C++ Builder with year number
[1392],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="4cppbuilder:2006"],
[1424],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="4cppbuilder:2007"],
[1555],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="4cppbuilder:2009"],
[1569],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="4cppbuilder:2010"],
dnl XE version
[1584],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="5xe"],
[1600],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="5xe:2"],
[1616],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="5xe:3"],
[1632],[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="5xe:4"],
[
AC_MSG_WARN([[[$0]] Unknown borlandc compiler version $_ax_[]_AC_LANG_ABBREV[]_compiler_version_borlandc_raw please report bug])
])
])
])
# COMO
AC_DEFUN([_AX_COMPILER_VERSION_COMEAU],
[ dnl
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor,
[__COMO_VERSION__%100],,
AC_MSG_FAILURE([[[$0]] unknown comeau compiler minor version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_major,
[(__COMO_VERSION__/100)%10],,
AC_MSG_FAILURE([[[$0]] unknown comeau compiler major version]))
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor"
])
# KAI
AC_DEFUN([_AX_COMPILER_VERSION_KAI],[
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch,
[__KCC_VERSION%100],,
AC_MSG_FAILURE([[[$0]] unknown kay compiler patch version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor,
[(__KCC_VERSION/100)%10],,
AC_MSG_FAILURE([[[$0]] unknown kay compiler minor version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_major,
[(__KCC_VERSION/1000)%10],,
AC_MSG_FAILURE([[[$0]] unknown kay compiler major version]))
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch"
])
dnl LCC
dnl LCC does not output version...
# SGI
AC_DEFUN([_AX_COMPILER_VERSION_SGI],[
m4_define([_AX_COMPILER_VERSION_SGI_NUMBER],
[
#if defined(_COMPILER_VERSION)
_COMPILER_VERSION
#else
_SGI_COMPILER_VERSION
#endif
])
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch,
[_AX_COMPILER_VERSION_SGI_NUMBER%10],,
AC_MSG_FAILURE([[[$0]] unknown SGI compiler patch version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor,
[(_AX_COMPILER_VERSION_SGI_NUMBER/10)%10],,
AC_MSG_FAILURE([[[$0]] unknown SGI compiler minor version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_major,
[(_AX_COMPILER_VERSION_SGI_NUMBER/100)%10],,
AC_MSG_FAILURE([[[$0]] unknown SGI compiler major version]))
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch"
])
# microsoft
AC_DEFUN([_AX_COMPILER_VERSION_MICROSOFT],[
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor,
_MSC_VER%100,,
AC_MSG_FAILURE([[[$0]] unknown microsoft compiler minor version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_major,
(_MSC_VER/100)%100,,
AC_MSG_FAILURE([[[$0]] unknown microsoft compiler major version]))
dnl could be overridden
_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch=0
_ax_[]_AC_LANG_ABBREV[]_compiler_version_build=0
# special case for version 6
AS_IF([test "X$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major" = "X12"],
[AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch,
_MSC_FULL_VER%1000,,
_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch=0)])
# for version 7
AS_IF([test "X$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major" = "X13"],
[AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch,
_MSC_FULL_VER%1000,,
AC_MSG_FAILURE([[[$0]] unknown microsoft compiler patch version]))
])
# for version > 8
AS_IF([test $_ax_[]_AC_LANG_ABBREV[]_compiler_version_major -ge 14],
[AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch,
_MSC_FULL_VER%10000,,
AC_MSG_FAILURE([[[$0]] unknown microsoft compiler patch version]))
])
AS_IF([test $_ax_[]_AC_LANG_ABBREV[]_compiler_version_major -ge 15],
[AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_build,
_MSC_BUILD,,
AC_MSG_FAILURE([[[$0]] unknown microsoft compiler build version]))
])
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_build"
])
# for metrowerks
AC_DEFUN([_AX_COMPILER_VERSION_METROWERKS],[dnl
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch,
__MWERKS__%0x100,,
AC_MSG_FAILURE([[[$0]] unknown metrowerks compiler patch version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor,
(__MWERKS__/0x100)%0x10,,
AC_MSG_FAILURE([[[$0]] unknown metrowerks compiler minor version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_major,
(__MWERKS__/0x1000)%0x10,,
AC_MSG_FAILURE([[[$0]] unknown metrowerks compiler major version]))
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch"
])
# for watcom
AC_DEFUN([_AX_COMPILER_VERSION_WATCOM],[dnl
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor,
__WATCOMC__%100,,
AC_MSG_FAILURE([[[$0]] unknown watcom compiler minor version]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_major,
(__WATCOMC__/100)%100,,
AC_MSG_FAILURE([[[$0]] unknown watcom compiler major version]))
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor"
])
# for PGI
AC_DEFUN([_AX_COMPILER_VERSION_PORTLAND],[
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_major,
__PGIC__,,
AC_MSG_FAILURE([[[$0]] unknown pgi major]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor,
__PGIC_MINOR__,,
AC_MSG_FAILURE([[[$0]] unknown pgi minor]))
AC_COMPUTE_INT(_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch,
[__PGIC_PATCHLEVEL__],,
AC_MSG_FAILURE([[[$0]] unknown pgi patch level]))
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version="$_ax_[]_AC_LANG_ABBREV[]_compiler_version_major.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_minor.$_ax_[]_AC_LANG_ABBREV[]_compiler_version_patch"
])
# tcc
AC_DEFUN([_AX_COMPILER_VERSION_TCC],[
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version=[`tcc -v | $SED 's/^[ ]*tcc[ ]\+version[ ]\+\([0-9.]\+\).*/\1/g'`]
])
# main entry point
AC_DEFUN([AX_COMPILER_VERSION],[dnl
AC_REQUIRE([AX_COMPILER_VENDOR])
AC_REQUIRE([AC_PROG_SED])
AC_CACHE_CHECK([for _AC_LANG compiler version],
ax_cv_[]_AC_LANG_ABBREV[]_compiler_version,
[ dnl
AS_CASE([$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor],
[intel],[_AX_COMPILER_VERSION_INTEL],
[ibm],[_AX_COMPILER_VERSION_IBM],
[pathscale],[_AX_COMPILER_VERSION_PATHSCALE],
[clang],[_AX_COMPILER_VERSION_CLANG],
[cray],[_AX_COMPILER_VERSION_CRAY],
[fujitsu],[_AX_COMPILER_VERSION_FUJITSU],
[gnu],[_AX_COMPILER_VERSION_GNU],
[sun],[_AX_COMPILER_VERSION_SUN],
[hp],[_AX_COMPILER_VERSION_HP],
[dec],[_AX_COMPILER_VERSION_DEC],
[borland],[_AX_COMPILER_VERSION_BORLAND],
[comeau],[_AX_COMPILER_VERSION_COMEAU],
[kai],[_AX_COMPILER_VERSION_KAI],
[sgi],[_AX_COMPILER_VERSION_SGI],
[microsoft],[_AX_COMPILER_VERSION_MICROSOFT],
[metrowerks],[_AX_COMPILER_VERSION_METROWERKS],
[watcom],[_AX_COMPILER_VERSION_WATCOM],
[portland],[_AX_COMPILER_VERSION_PORTLAND],
[tcc],[_AX_COMPILER_VERSION_TCC],
[ax_cv_[]_AC_LANG_ABBREV[]_compiler_version=""])
])
])

@ -1,56 +0,0 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_recursive_eval.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_RECURSIVE_EVAL(VALUE, RESULT)
#
# DESCRIPTION
#
# Interpolate the VALUE in loop until it doesn't change, and set the
# result to $RESULT. WARNING: It's easy to get an infinite loop with some
# unsane input.
#
# LICENSE
#
# Copyright (c) 2008 Alexandre Duret-Lutz <adl@gnu.org>
#
# 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, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 1
AC_DEFUN([AX_RECURSIVE_EVAL],
[_lcl_receval="$1"
$2=`(test "x$prefix" = xNONE && prefix="$ac_default_prefix"
test "x$exec_prefix" = xNONE && exec_prefix="${prefix}"
_lcl_receval_old=''
while test "[$]_lcl_receval_old" != "[$]_lcl_receval"; do
_lcl_receval_old="[$]_lcl_receval"
eval _lcl_receval="\"[$]_lcl_receval\""
done
echo "[$]_lcl_receval")`])

@ -1,37 +0,0 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_require_defined.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_REQUIRE_DEFINED(MACRO)
#
# DESCRIPTION
#
# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
# been defined and thus are available for use. This avoids random issues
# where a macro isn't expanded. Instead the configure script emits a
# non-fatal:
#
# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
#
# It's like AC_REQUIRE except it doesn't expand the required macro.
#
# Here's an example:
#
# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
#
# LICENSE
#
# Copyright (c) 2014 Mike Frysinger <vapier@gentoo.org>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 2
AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
])dnl AX_REQUIRE_DEFINED

@ -1,26 +0,0 @@
dnl @synopsis AC_CHECK_SIGNAL(SIGNAME)
dnl
dnl
dnl @category C
dnl @author Erik de Castro Lopo <erikd AT mega-nerd DOT com>
dnl @version 1.0 Jul 07 2007
AC_DEFUN([AC_CHECK_SIGNAL],
[AC_CACHE_CHECK(for $1,
ac_cv_signal_$1,
[
AC_TRY_LINK([
#include <signal.h>
], signal($1, SIG_DFL) ;, ac_cv_signal_$1=yes, ac_cv_signal_$1=no)
])
if test "$ac_cv_signal_$1" = yes; then
AC_DEFINE(HAVE_$1, 1,
[Define if you have signal $1.])
fi
])# AC_CHECK_SIGNAL
## AC_CHECK_SIGNALS

@ -1,124 +0,0 @@
dnl @synopsis AC_C_CLIP_MODE
dnl
dnl Determine the clipping mode when converting float to int.
dnl @version 1.0 May 17 2003
dnl @author Erik de Castro Lopo <erikd AT mega-nerd DOT com>
dnl
dnl Permission to use, copy, modify, distribute, and sell this file for any
dnl purpose is hereby granted without fee, provided that the above copyright
dnl and this permission notice appear in all copies. No representations are
dnl made about the suitability of this software for any purpose. It is
dnl provided "as is" without express or implied warranty.
dnl Find the clipping mode in the following way:
dnl 1) If we are not cross compiling test it.
dnl 2) IF we are cross compiling, assume that clipping isn't done correctly.
AC_DEFUN([AC_C_CLIP_MODE],
[AC_CACHE_CHECK(processor clipping capabilities,
ac_cv_c_clip_type,
# Initialize to unknown
ac_cv_c_clip_positive=unknown
ac_cv_c_clip_negative=unknown
if test $ac_cv_c_clip_positive = unknown ; then
AC_TRY_RUN(
[[
#define _ISOC9X_SOURCE 1
#define _ISOC99_SOURCE 1
#define __USE_ISOC99 1
#define __USE_ISOC9X 1
#include <math.h>
int main (void)
{ double fval ;
int k, ival ;
fval = 1.0 * 0x7FFFFFFF ;
for (k = 0 ; k < 100 ; k++)
{ ival = (lrint (fval)) >> 24 ;
if (ival != 127)
return 1 ;
fval *= 1.2499999 ;
} ;
return 0 ;
}
]],
ac_cv_c_clip_positive=yes,
ac_cv_c_clip_positive=no,
ac_cv_c_clip_positive=unknown
)
AC_TRY_RUN(
[[
#define _ISOC9X_SOURCE 1
#define _ISOC99_SOURCE 1
#define __USE_ISOC99 1
#define __USE_ISOC9X 1
#include <math.h>
int main (void)
{ double fval ;
int k, ival ;
fval = -8.0 * 0x10000000 ;
for (k = 0 ; k < 100 ; k++)
{ ival = (lrint (fval)) >> 24 ;
if (ival != -128)
return 1 ;
fval *= 1.2499999 ;
} ;
return 0 ;
}
]],
ac_cv_c_clip_negative=yes,
ac_cv_c_clip_negative=no,
ac_cv_c_clip_negative=unknown
)
fi
if test $ac_cv_c_clip_positive = yes ; then
ac_cv_c_clip_positive=1
else
ac_cv_c_clip_positive=0
fi
if test $ac_cv_c_clip_negative = yes ; then
ac_cv_c_clip_negative=1
else
ac_cv_c_clip_negative=0
fi
[[
case "$ac_cv_c_clip_positive$ac_cv_c_clip_negative" in
"00")
ac_cv_c_clip_type="none"
;;
"10")
ac_cv_c_clip_type="positive"
;;
"01")
ac_cv_c_clip_type="negative"
;;
"11")
ac_cv_c_clip_type="both"
;;
esac
]]
)
]
)# AC_C_CLIP_MODE

@ -1,12 +0,0 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: samplerate
Description: An audio Sample Rate Conversion library
Requires:
Version: @VERSION@
Libs: -L${libdir} -lsamplerate
Libs.private: @LIBS@
Cflags: -I${includedir}

@ -1,169 +0,0 @@
option(LIBSAMPLERATE_COMPATIBLE_NAME "Use old dll name on Windows platform" OFF)
option(LIBSAMPLERATE_ENABLE_SINC_FAST_CONVERTER "Enable Fastest Sinc Interpolator converter" ON)
option(LIBSAMPLERATE_ENABLE_SINC_MEDIUM_CONVERTER "Enable Medium Sinc Interpolator converter" ON)
option(LIBSAMPLERATE_ENABLE_SINC_BEST_CONVERTER "Enable Best Sinc Interpolator converter" ON)
option(LIBSAMPLERATE_INSTALL_PKGCONFIG_MODULE "Install samplerate.pc PkgConfig module." ON)
set(ENABLE_SINC_FAST_CONVERTER ${LIBSAMPLERATE_ENABLE_SINC_FAST_CONVERTER} PARENT_SCOPE)
set(ENABLE_SINC_MEDIUM_CONVERTER ${LIBSAMPLERATE_ENABLE_SINC_MEDIUM_CONVERTER} PARENT_SCOPE)
set(ENABLE_SINC_BEST_CONVERTER ${LIBSAMPLERATE_ENABLE_SINC_BEST_CONVERTER} PARENT_SCOPE)
include(CMakePushCheckState)
include(CheckCSourceCompiles)
include(ClipMode)
include(CMakePackageConfigHelpers)
# This will set CPU_CLIPS_NEGATIVE and CPU_CLIPS_POSITIVE
clip_mode()
# check for symbol visibility attributes support
cmake_push_check_state()
set(CMAKE_REQUIRED_FLAGS "-fvisibility=hidden -Werror")
check_c_source_compiles("__attribute__((visibility(\"default\"))) int foo(void);
__attribute__((visibility(\"hidden\"))) int bar(void);
int foo (void) {return 0;}
int bar (void) {return 1;}
int main(void) {return 0;}" HAVE_VISIBILITY)
cmake_pop_check_state()
add_library(samplerate
common.h
fastest_coeffs.h
high_qual_coeffs.h
mid_qual_coeffs.h
samplerate.c
${PROJECT_SOURCE_DIR}/include/samplerate.h
src_linear.c
src_sinc.c
src_zoh.c
$<$<AND:$<BOOL:${WIN32}>,$<BOOL:${BUILD_SHARED_LIBS}>>:../Win32/libsamplerate-0.def>)
# ALIAS to use if libsamplerate is included from other project with add_subdirectory()
add_library(SampleRate::samplerate ALIAS samplerate)
# CMake generates wrong DLL names for MinGW and Cygwin, fix it
if(BUILD_SHARED_LIBS AND WIN32)
if(LIBSAMPLERATE_COMPATIBLE_NAME)
if(MSVC)
set_target_properties(samplerate PROPERTIES OUTPUT_NAME "libsamplerate-${libsamplerate_VERSION_MAJOR}")
else()
set_target_properties(samplerate PROPERTIES OUTPUT_NAME "samplerate-${libsamplerate_VERSION_MAJOR}")
endif()
else()
if(MINGW OR CYGWIN)
set_target_properties(samplerate PROPERTIES RUNTIME_OUTPUT_NAME "samplerate-${libsamplerate_VERSION_MAJOR}")
endif()
endif()
if(OS2)
# OS/2 doesn't support a DLL name longer than 8 characters.
set_target_properties(samplerate PROPERTIES OUTPUT_NAME "SAMPRATE")
set_target_properties(samplerate PROPERTIES PREFIX "")
endif()
endif()
target_include_directories(samplerate
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
if(LIBM_REQUIRED)
target_link_libraries(samplerate PRIVATE m)
endif()
# Set public header
set_property(TARGET samplerate PROPERTY PUBLIC_HEADER ${PROJECT_SOURCE_DIR}/include/samplerate.h)
if(BUILD_SHARED_LIBS)
# Set ABI version. This is critical for Unix-like OSes
set_target_properties(samplerate PROPERTIES
VERSION ${libsamplerate_VERSION}
SOVERSION ${libsamplerate_VERSION_MAJOR})
# Use Version_script to export ABI set
if(UNIX AND (NOT APPLE))
if((CMAKE_C_COMPILER_ID STREQUAL "GNU") OR
(CMAKE_C_COMPILER_ID STREQUAL "Clang") OR
(CMAKE_C_COMPILER_ID STREQUAL "Intel"))
set(PACKAGE ${PROJECT_NAME})
configure_file(Version_script.in Version_script)
unset(PACKAGE)
if(CMAKE_VERSION VERSION_LESS 3.13)
# This works
set_property(TARGET samplerate APPEND_STRING PROPERTY
LINK_FLAGS "-Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/Version_script")
else()
# This works even better, e.g. for Clang it uses `-Xlinker` option,
# but requires CMake >= 3.13.
target_link_options(samplerate
PRIVATE
"LINKER:--version-script,${CMAKE_CURRENT_BINARY_DIR}/Version_script")
endif()
endif()
endif()
# keep in sync with configure.ac
set (LIBSAMPLERATE_ABI_VERSION_CURRENT 2)
set (LIBSAMPLERATE_ABI_VERSION_REVISION 2)
set (LIBSAMPLERATE_ABI_VERSION_AGE 2)
math (EXPR LIBSAMPLERATE_MACHO_COMPATIBILITY_VERSION "${LIBSAMPLERATE_ABI_VERSION_CURRENT} + 1")
set (LIBSAMPLERATE_MACHO_CURRENT_VERSION "${LIBSAMPLERATE_MACHO_COMPATIBILITY_VERSION}.${LIBSAMPLERATE_ABI_VERSION_REVISION}.0")
if (APPLE)
if (NOT (CMAKE_VERSION VERSION_LESS 3.17))
set_target_properties (samplerate PROPERTIES
MACHO_CURRENT_VERSION ${LIBSAMPLERATE_MACHO_CURRENT_VERSION}
MACHO_COMPATIBILITY_VERSION ${LIBSAMPLERATE_MACHO_COMPATIBILITY_VERSION}
)
else ()
message (FATAL_ERROR "Apple platform requires cmake >= 3.17 to build dylib.")
endif ()
endif ()
endif()
# Istallation
if(LIBSAMPLERATE_INSTALL)
install(TARGETS samplerate EXPORT SampleRateTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
# pkg-config module
if(LIBSAMPLERATE_INSTALL_PKGCONFIG_MODULE)
set(prefix ${CMAKE_INSTALL_PREFIX})
set(exec_prefix "\${prefix}")
set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
set(VERSION "${PROJECT_VERSION}")
if(LIBM_REQUIRED)
set(LIBS "-lm")
endif()
configure_file(../samplerate.pc.in samplerate.pc @ONLY)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/samplerate.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
endif()
set(CMAKE_INSTALL_PACKAGEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/SampleRate")
configure_package_config_file(../cmake/SampleRateConfig.cmake.in SampleRateConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_PACKAGEDIR})
write_basic_package_version_file(SampleRateConfigVersion.cmake COMPATIBILITY SameMajorVersion)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/SampleRateConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/SampleRateConfigVersion.cmake
DESTINATION
${CMAKE_INSTALL_PACKAGEDIR})
install(EXPORT SampleRateTargets
NAMESPACE SampleRate::
DESTINATION ${CMAKE_INSTALL_PACKAGEDIR})
endif()

@ -1,45 +0,0 @@
#
# Export file for libsamplerate
#
# Only the symbols listed in the global section will be callable from
# applications linking to libsamplerate.
#
@PACKAGE@.so.0.0
{
global:
src_new ;
src_delete ;
src_get_name ;
src_get_description ;
src_get_version ;
src_process ;
src_reset ;
src_error ;
src_strerror ;
src_simple ;
src_is_valid_ratio ;
src_set_ratio ;
local:
*;
};
@PACKAGE@.so.0.1
{
global:
src_callback_new ;
src_callback_read ;
src_short_to_float_array ;
src_float_to_short_array ;
src_int_to_float_array ;
src_float_to_int_array ;
src_get_channels ;
} @PACKAGE@.so.0.0;
@PACKAGE@.so.0.2
{
global:
src_clone ;
} @PACKAGE@.so.0.1;

@ -1,47 +0,0 @@
#!/bin/sh
# 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.
#=======================================================================
# This short test script compiles the file src_sinc.c into assembler
# output and the greps the assembler output for the fldcw (FPU Load
# Control Word) instruction which is very detrimental to the perfromance
# of floating point code.
echo -n " Checking assembler output for bad code : "
if [ $# -ne 1 ]; then
echo "Error : Need the name of the input file."
exit 1
fi
filename=$1
if [ ! -f $filename ];then
echo "Error : Can't find file $filename."
exit 1
fi
count=`grep fldcw $filename | wc -l`
if [ $count -gt 0 ]; then
echo -e "\n\nError : found $count bad instructions.\n\n"
exit 1
fi
echo "ok"

@ -1,252 +0,0 @@
/*
** Copyright (c) 2002-2021, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifndef COMMON_H_INCLUDED
#define COMMON_H_INCLUDED
#include <stdint.h>
#ifdef HAVE_STDBOOL_H
#include <stdbool.h>
#endif
#if defined(__x86_64__) || defined(_M_X64)
# define HAVE_SSE2_INTRINSICS
#elif defined(ENABLE_SSE2_LRINT) && (defined(_M_IX86) || defined(__i386__))
# if defined(_MSC_VER)
# define HAVE_SSE2_INTRINSICS
# elif defined(__clang__)
# ifdef __SSE2__
# define HAVE_SSE2_INTRINSICS
# elif (__has_attribute(target))
# define HAVE_SSE2_INTRINSICS
# define USE_TARGET_ATTRIBUTE
# endif
# elif defined(__GNUC__)
# ifdef __SSE2__
# define HAVE_SSE2_INTRINSICS
# elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))
# define HAVE_SSE2_INTRINSICS
# define USE_TARGET_ATTRIBUTE
# endif
# endif
#endif
#ifdef HAVE_SSE2_INTRINSICS
#ifdef HAVE_IMMINTRIN_H
#include <immintrin.h>
#else
#include <emmintrin.h>
#endif
#endif /* HAVE_SSE2_INTRINSICS */
#include <math.h>
#ifdef HAVE_VISIBILITY
#define LIBSAMPLERATE_DLL_PRIVATE __attribute__ ((visibility ("hidden")))
#elif defined (__APPLE__)
#define LIBSAMPLERATE_DLL_PRIVATE __private_extern__
#else
#define LIBSAMPLERATE_DLL_PRIVATE
#endif
#define SRC_MAX_RATIO 256
#define SRC_MAX_RATIO_STR "256"
#define SRC_MIN_RATIO_DIFF (1e-20)
#ifndef MAX
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
#define ARRAY_LEN(x) ((int) (sizeof (x) / sizeof ((x) [0])))
#define OFFSETOF(type,member) ((int) (&((type*) 0)->member))
#define MAKE_MAGIC(a,b,c,d,e,f) ((a) + ((b) << 4) + ((c) << 8) + ((d) << 12) + ((e) << 16) + ((f) << 20))
/*
** Inspiration : http://sourcefrog.net/weblog/software/languages/C/unused.html
*/
#ifdef UNUSED
#elif defined (__GNUC__)
# define UNUSED(x) UNUSED_ ## x __attribute__ ((unused))
#elif defined (__LCLINT__)
# define UNUSED(x) /*@unused@*/ x
#else
# define UNUSED(x) x
#endif
#ifdef __GNUC__
# define WARN_UNUSED __attribute__ ((warn_unused_result))
#else
# define WARN_UNUSED
#endif
#include "samplerate.h"
enum
{ SRC_FALSE = 0,
SRC_TRUE = 1,
} ;
enum SRC_MODE
{
SRC_MODE_PROCESS = 0,
SRC_MODE_CALLBACK = 1
} ;
typedef enum SRC_ERROR
{
SRC_ERR_NO_ERROR = 0,
SRC_ERR_MALLOC_FAILED,
SRC_ERR_BAD_STATE,
SRC_ERR_BAD_DATA,
SRC_ERR_BAD_DATA_PTR,
SRC_ERR_NO_PRIVATE,
SRC_ERR_BAD_SRC_RATIO,
SRC_ERR_BAD_PROC_PTR,
SRC_ERR_SHIFT_BITS,
SRC_ERR_FILTER_LEN,
SRC_ERR_BAD_CONVERTER,
SRC_ERR_BAD_CHANNEL_COUNT,
SRC_ERR_SINC_BAD_BUFFER_LEN,
SRC_ERR_SIZE_INCOMPATIBILITY,
SRC_ERR_BAD_PRIV_PTR,
SRC_ERR_BAD_SINC_STATE,
SRC_ERR_DATA_OVERLAP,
SRC_ERR_BAD_CALLBACK,
SRC_ERR_BAD_MODE,
SRC_ERR_NULL_CALLBACK,
SRC_ERR_NO_VARIABLE_RATIO,
SRC_ERR_SINC_PREPARE_DATA_BAD_LEN,
SRC_ERR_BAD_INTERNAL_STATE,
/* This must be the last error number. */
SRC_ERR_MAX_ERROR
} SRC_ERROR ;
typedef struct SRC_STATE_VT_tag
{
/* Varispeed process function. */
SRC_ERROR (*vari_process) (SRC_STATE *state, SRC_DATA *data) ;
/* Constant speed process function. */
SRC_ERROR (*const_process) (SRC_STATE *state, SRC_DATA *data) ;
/* State reset. */
void (*reset) (SRC_STATE *state) ;
/* State clone. */
SRC_STATE *(*copy) (SRC_STATE *state) ;
/* State close. */
void (*close) (SRC_STATE *state) ;
} SRC_STATE_VT ;
struct SRC_STATE_tag
{
SRC_STATE_VT *vt ;
float last_ratio, last_position ;
SRC_ERROR error ;
int channels ;
/* SRC_MODE_PROCESS or SRC_MODE_CALLBACK */
enum SRC_MODE mode ;
/* Data specific to SRC_MODE_CALLBACK. */
src_callback_t callback_func ;
void *user_callback_data ;
long saved_frames ;
const float *saved_data ;
/* Pointer to data to converter specific data. */
void *private_data ;
} ;
/* In src_sinc.c */
const char* sinc_get_name (int src_enum) ;
const char* sinc_get_description (int src_enum) ;
SRC_STATE *sinc_state_new (int converter_type, int channels, SRC_ERROR *error) ;
/* In src_linear.c */
const char* linear_get_name (int src_enum) ;
const char* linear_get_description (int src_enum) ;
SRC_STATE *linear_state_new (int channels, SRC_ERROR *error) ;
/* In src_zoh.c */
const char* zoh_get_name (int src_enum) ;
const char* zoh_get_description (int src_enum) ;
SRC_STATE *zoh_state_new (int channels, SRC_ERROR *error) ;
/*----------------------------------------------------------
** SIMD optimized math functions.
*/
#ifdef HAVE_SSE2_INTRINSICS
static inline int
#ifdef USE_TARGET_ATTRIBUTE
__attribute__((target("sse2")))
#endif
psf_lrintf (float x)
{
return _mm_cvtss_si32 (_mm_load_ss (&x)) ;
}
static inline int
#ifdef USE_TARGET_ATTRIBUTE
__attribute__((target("sse2")))
#endif
psf_lrint (float x)
{
return _mm_cvtsd_si32 (_mm_load_sd (&x)) ;
}
#else
static inline int psf_lrintf (float x)
{
return lrintf (x) ;
} /* psf_lrintf */
static inline int psf_lrint (float x)
{
return lrint (x) ;
} /* psf_lrint */
#endif
/*----------------------------------------------------------
** Common static inline functions.
*/
static inline float
fmod_one (float x)
{ float res ;
res = x - psf_lrint (x) ;
if (res < 0.0)
return res + 1.0 ;
return res ;
} /* fmod_one */
static inline int
is_bad_src_ratio (float ratio)
{ return (ratio < (1.0 / SRC_MAX_RATIO) || ratio > (1.0 * SRC_MAX_RATIO)) ;
} /* is_bad_src_ratio */
#endif /* COMMON_H_INCLUDED */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,528 +0,0 @@
/*
** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "samplerate.h"
#include "common.h"
static SRC_STATE *psrc_set_converter (int converter_type, int channels, int *error) ;
SRC_STATE *
src_new (int converter_type, int channels, int *error)
{
return psrc_set_converter (converter_type, channels, error) ;
} /* src_new */
SRC_STATE*
src_clone (SRC_STATE* orig, int *error)
{
if (!orig)
{
if (error)
*error = SRC_ERR_BAD_STATE ;
return NULL ;
}
if (error)
*error = SRC_ERR_NO_ERROR ;
SRC_STATE *state = orig->vt->copy (orig) ;
if (!state)
if (error)
*error = SRC_ERR_MALLOC_FAILED ;
return state ;
}
SRC_STATE*
src_callback_new (src_callback_t func, int converter_type, int channels, int *error, void* cb_data)
{ SRC_STATE *state ;
if (func == NULL)
{ if (error)
*error = SRC_ERR_BAD_CALLBACK ;
return NULL ;
} ;
if (error != NULL)
*error = 0 ;
if ((state = src_new (converter_type, channels, error)) == NULL)
return NULL ;
src_reset (state) ;
state->mode = SRC_MODE_CALLBACK ;
state->callback_func = func ;
state->user_callback_data = cb_data ;
return state ;
} /* src_callback_new */
SRC_STATE *
src_delete (SRC_STATE *state)
{
if (state)
state->vt->close (state) ;
return NULL ;
} /* src_state */
int
src_process (SRC_STATE *state, SRC_DATA *data)
{
int error ;
if (state == NULL)
return SRC_ERR_BAD_STATE ;
if (state->mode != SRC_MODE_PROCESS)
return SRC_ERR_BAD_MODE ;
/* Check for valid SRC_DATA first. */
if (data == NULL)
return SRC_ERR_BAD_DATA ;
/* And that data_in and data_out are valid. */
if ((data->data_in == NULL && data->input_frames > 0)
|| (data->data_out == NULL && data->output_frames > 0))
return SRC_ERR_BAD_DATA_PTR ;
/* Check src_ratio is in range. */
if (is_bad_src_ratio (data->src_ratio))
return SRC_ERR_BAD_SRC_RATIO ;
if (data->input_frames < 0)
data->input_frames = 0 ;
if (data->output_frames < 0)
data->output_frames = 0 ;
if (data->data_in < data->data_out)
{ if (data->data_in + data->input_frames * state->channels > data->data_out)
{ /*-printf ("\n\ndata_in: %p data_out: %p\n",
(void*) (data->data_in + data->input_frames * psrc->channels), (void*) data->data_out) ;-*/
return SRC_ERR_DATA_OVERLAP ;
} ;
}
else if (data->data_out + data->output_frames * state->channels > data->data_in)
{ /*-printf ("\n\ndata_in : %p ouput frames: %ld data_out: %p\n", (void*) data->data_in, data->output_frames, (void*) data->data_out) ;
printf ("data_out: %p (%p) data_in: %p\n", (void*) data->data_out,
(void*) (data->data_out + data->input_frames * psrc->channels), (void*) data->data_in) ;-*/
return SRC_ERR_DATA_OVERLAP ;
} ;
/* Set the input and output counts to zero. */
data->input_frames_used = 0 ;
data->output_frames_gen = 0 ;
/* Special case for when last_ratio has not been set. */
if (state->last_ratio < (1.0 / SRC_MAX_RATIO))
state->last_ratio = data->src_ratio ;
/* Now process. */
if (fabs (state->last_ratio - data->src_ratio) < 1e-15)
error = state->vt->const_process (state, data) ;
else
error = state->vt->vari_process (state, data) ;
return error ;
} /* src_process */
long
src_callback_read (SRC_STATE *state, float src_ratio, long frames, float *data)
{
SRC_DATA src_data ;
long output_frames_gen ;
int error = 0 ;
if (state == NULL)
return 0 ;
if (frames <= 0)
return 0 ;
if (state->mode != SRC_MODE_CALLBACK)
{ state->error = SRC_ERR_BAD_MODE ;
return 0 ;
} ;
if (state->callback_func == NULL)
{ state->error = SRC_ERR_NULL_CALLBACK ;
return 0 ;
} ;
memset (&src_data, 0, sizeof (src_data)) ;
/* Check src_ratio is in range. */
if (is_bad_src_ratio (src_ratio))
{ state->error = SRC_ERR_BAD_SRC_RATIO ;
return 0 ;
} ;
/* Switch modes temporarily. */
src_data.src_ratio = src_ratio ;
src_data.data_out = data ;
src_data.output_frames = frames ;
src_data.data_in = state->saved_data ;
src_data.input_frames = state->saved_frames ;
output_frames_gen = 0 ;
while (output_frames_gen < frames)
{ /* Use a dummy array for the case where the callback function
** returns without setting the ptr.
*/
float dummy [1] ;
if (src_data.input_frames == 0)
{ float *ptr = dummy ;
src_data.input_frames = state->callback_func (state->user_callback_data, &ptr) ;
src_data.data_in = ptr ;
if (src_data.input_frames == 0)
src_data.end_of_input = 1 ;
} ;
/*
** Now call process function. However, we need to set the mode
** to SRC_MODE_PROCESS first and when we return set it back to
** SRC_MODE_CALLBACK.
*/
state->mode = SRC_MODE_PROCESS ;
error = src_process (state, &src_data) ;
state->mode = SRC_MODE_CALLBACK ;
if (error != 0)
break ;
src_data.data_in += src_data.input_frames_used * state->channels ;
src_data.input_frames -= src_data.input_frames_used ;
src_data.data_out += src_data.output_frames_gen * state->channels ;
src_data.output_frames -= src_data.output_frames_gen ;
output_frames_gen += src_data.output_frames_gen ;
if (src_data.end_of_input == SRC_TRUE && src_data.output_frames_gen == 0)
break ;
} ;
state->saved_data = src_data.data_in ;
state->saved_frames = src_data.input_frames ;
if (error != 0)
{ state->error = (SRC_ERROR) error ;
return 0 ;
} ;
return output_frames_gen ;
} /* src_callback_read */
/*==========================================================================
*/
int
src_set_ratio (SRC_STATE *state, float new_ratio)
{
if (state == NULL)
return SRC_ERR_BAD_STATE ;
if (is_bad_src_ratio (new_ratio))
return SRC_ERR_BAD_SRC_RATIO ;
state->last_ratio = new_ratio ;
return SRC_ERR_NO_ERROR ;
} /* src_set_ratio */
int
src_get_channels (SRC_STATE *state)
{
if (state == NULL)
return -SRC_ERR_BAD_STATE ;
return state->channels ;
} /* src_get_channels */
int
src_reset (SRC_STATE *state)
{
if (state == NULL)
return SRC_ERR_BAD_STATE ;
state->vt->reset (state) ;
state->last_position = 0.0 ;
state->last_ratio = 0.0 ;
state->saved_data = NULL ;
state->saved_frames = 0 ;
state->error = SRC_ERR_NO_ERROR ;
return SRC_ERR_NO_ERROR ;
} /* src_reset */
/*==============================================================================
** Control functions.
*/
const char *
src_get_name (int converter_type)
{ const char *desc ;
if ((desc = sinc_get_name (converter_type)) != NULL)
return desc ;
if ((desc = zoh_get_name (converter_type)) != NULL)
return desc ;
if ((desc = linear_get_name (converter_type)) != NULL)
return desc ;
return NULL ;
} /* src_get_name */
const char *
src_get_description (int converter_type)
{ const char *desc ;
if ((desc = sinc_get_description (converter_type)) != NULL)
return desc ;
if ((desc = zoh_get_description (converter_type)) != NULL)
return desc ;
if ((desc = linear_get_description (converter_type)) != NULL)
return desc ;
return NULL ;
} /* src_get_description */
const char *
src_get_version (void)
{ return PACKAGE "-" VERSION " (c) 2002-2008 Erik de Castro Lopo" ;
} /* src_get_version */
int
src_is_valid_ratio (float ratio)
{
if (is_bad_src_ratio (ratio))
return SRC_FALSE ;
return SRC_TRUE ;
} /* src_is_valid_ratio */
/*==============================================================================
** Error reporting functions.
*/
int
src_error (SRC_STATE *state)
{ if (state)
return state->error ;
return SRC_ERR_NO_ERROR ;
} /* src_error */
const char*
src_strerror (int error)
{
switch (error)
{ case SRC_ERR_NO_ERROR :
return "No error." ;
case SRC_ERR_MALLOC_FAILED :
return "Malloc failed." ;
case SRC_ERR_BAD_STATE :
return "SRC_STATE pointer is NULL." ;
case SRC_ERR_BAD_DATA :
return "SRC_DATA pointer is NULL." ;
case SRC_ERR_BAD_DATA_PTR :
return "SRC_DATA->data_out or SRC_DATA->data_in is NULL." ;
case SRC_ERR_NO_PRIVATE :
return "Internal error. No private data." ;
case SRC_ERR_BAD_SRC_RATIO :
return "SRC ratio outside [1/" SRC_MAX_RATIO_STR ", " SRC_MAX_RATIO_STR "] range." ;
case SRC_ERR_BAD_SINC_STATE :
return "src_process() called without reset after end_of_input." ;
case SRC_ERR_BAD_PROC_PTR :
return "Internal error. No process pointer." ;
case SRC_ERR_SHIFT_BITS :
return "Internal error. SHIFT_BITS too large." ;
case SRC_ERR_FILTER_LEN :
return "Internal error. Filter length too large." ;
case SRC_ERR_BAD_CONVERTER :
return "Bad converter number." ;
case SRC_ERR_BAD_CHANNEL_COUNT :
return "Channel count must be >= 1." ;
case SRC_ERR_SINC_BAD_BUFFER_LEN :
return "Internal error. Bad buffer length. Please report this." ;
case SRC_ERR_SIZE_INCOMPATIBILITY :
return "Internal error. Input data / internal buffer size difference. Please report this." ;
case SRC_ERR_BAD_PRIV_PTR :
return "Internal error. Private pointer is NULL. Please report this." ;
case SRC_ERR_DATA_OVERLAP :
return "Input and output data arrays overlap." ;
case SRC_ERR_BAD_CALLBACK :
return "Supplied callback function pointer is NULL." ;
case SRC_ERR_BAD_MODE :
return "Calling mode differs from initialisation mode (ie process v callback)." ;
case SRC_ERR_NULL_CALLBACK :
return "Callback function pointer is NULL in src_callback_read ()." ;
case SRC_ERR_NO_VARIABLE_RATIO :
return "This converter only allows constant conversion ratios." ;
case SRC_ERR_SINC_PREPARE_DATA_BAD_LEN :
return "Internal error : Bad length in prepare_data ()." ;
case SRC_ERR_BAD_INTERNAL_STATE :
return "Error : Someone is trampling on my internal state." ;
case SRC_ERR_MAX_ERROR :
return "Placeholder. No error defined for this error number." ;
default : break ;
}
return NULL ;
} /* src_strerror */
/*==============================================================================
** Simple interface for performing a single conversion from input buffer to
** output buffer at a fixed conversion ratio.
*/
int
src_simple (SRC_DATA *src_data, int converter, int channels)
{ SRC_STATE *src_state ;
int error ;
if ((src_state = src_new (converter, channels, &error)) == NULL)
return error ;
src_data->end_of_input = 1 ; /* Only one buffer worth of input. */
error = src_process (src_state, src_data) ;
src_delete (src_state) ;
return error ;
} /* src_simple */
void
src_short_to_float_array (const short *in, float *out, int len)
{
for (int i = 0 ; i < len ; i++)
{ out [i] = (float) (in [i] / (1.0 * 0x8000)) ;
} ;
return ;
} /* src_short_to_float_array */
void
src_float_to_short_array (const float *in, short *out, int len)
{
for (int i = 0 ; i < len ; i++)
{ float scaled_value ;
scaled_value = in [i] * 32768.f ;
if (scaled_value >= 32767.f)
out [i] = 32767 ;
else if (scaled_value <= -32768.f)
out [i] = -32768 ;
else
out [i] = (short) (psf_lrintf (scaled_value)) ;
}
} /* src_float_to_short_array */
void
src_int_to_float_array (const int *in, float *out, int len)
{
for (int i = 0 ; i < len ; i++)
{ out [i] = (float) (in [i] / (8.0 * 0x10000000)) ;
} ;
return ;
} /* src_int_to_float_array */
void
src_float_to_int_array (const float *in, int *out, int len)
{ float scaled_value ;
for (int i = 0 ; i < len ; i++)
{ scaled_value = in [i] * (8.0 * 0x10000000) ;
#if CPU_CLIPS_POSITIVE == 0
if (scaled_value >= (1.0 * 0x7FFFFFFF))
{ out [i] = 0x7fffffff ;
continue ;
} ;
#endif
#if CPU_CLIPS_NEGATIVE == 0
if (scaled_value <= (-8.0 * 0x10000000))
{ out [i] = -1 - 0x7fffffff ;
continue ;
} ;
#endif
out [i] = (int) psf_lrint (scaled_value) ;
} ;
} /* src_float_to_int_array */
/*==============================================================================
** Private functions.
*/
static SRC_STATE *
psrc_set_converter (int converter_type, int channels, int *error)
{
SRC_ERROR temp_error;
SRC_STATE *state ;
switch (converter_type)
{
#ifdef ENABLE_SINC_BEST_CONVERTER
case SRC_SINC_BEST_QUALITY :
state = sinc_state_new (converter_type, channels, &temp_error) ;
break ;
#endif
#ifdef ENABLE_SINC_MEDIUM_CONVERTER
case SRC_SINC_MEDIUM_QUALITY :
state = sinc_state_new (converter_type, channels, &temp_error) ;
break ;
#endif
#ifdef ENABLE_SINC_FAST_CONVERTER
case SRC_SINC_FASTEST :
state = sinc_state_new (converter_type, channels, &temp_error) ;
break ;
#endif
case SRC_ZERO_ORDER_HOLD :
state = zoh_state_new (channels, &temp_error) ;
break ;
case SRC_LINEAR :
state = linear_state_new (channels, &temp_error) ;
break ;
default :
temp_error = SRC_ERR_BAD_CONVERTER ;
state = NULL ;
break ;
}
if (error)
*error = (int) temp_error ;
return state ;
} /* psrc_set_converter */

@ -1,301 +0,0 @@
/*
** Copyright (c) 2002-2021, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "common.h"
static SRC_ERROR linear_vari_process (SRC_STATE *state, SRC_DATA *data) ;
static void linear_reset (SRC_STATE *state) ;
static SRC_STATE *linear_copy (SRC_STATE *state) ;
static void linear_close (SRC_STATE *state) ;
/*========================================================================================
*/
#define LINEAR_MAGIC_MARKER MAKE_MAGIC ('l', 'i', 'n', 'e', 'a', 'r')
#define SRC_DEBUG 0
typedef struct
{ int linear_magic_marker ;
bool dirty ;
long in_count, in_used ;
long out_count, out_gen ;
float *last_value ;
} LINEAR_DATA ;
static SRC_STATE_VT linear_state_vt =
{
linear_vari_process,
linear_vari_process,
linear_reset,
linear_copy,
linear_close
} ;
/*----------------------------------------------------------------------------------------
*/
static SRC_ERROR
linear_vari_process (SRC_STATE *state, SRC_DATA *data)
{ LINEAR_DATA *priv ;
float src_ratio, input_index, rem ;
int ch ;
if (data->input_frames <= 0)
return SRC_ERR_NO_ERROR ;
if (state->private_data == NULL)
return SRC_ERR_NO_PRIVATE ;
priv = (LINEAR_DATA*) state->private_data ;
if (!priv->dirty)
{ /* If we have just been reset, set the last_value data. */
for (ch = 0 ; ch < state->channels ; ch++)
priv->last_value [ch] = data->data_in [ch] ;
priv->dirty = true ;
} ;
priv->in_count = data->input_frames * state->channels ;
priv->out_count = data->output_frames * state->channels ;
priv->in_used = priv->out_gen = 0 ;
src_ratio = state->last_ratio ;
if (is_bad_src_ratio (src_ratio))
return SRC_ERR_BAD_INTERNAL_STATE ;
input_index = state->last_position ;
/* Calculate samples before first sample in input array. */
while (input_index < 1.0 && priv->out_gen < priv->out_count)
{
if (priv->in_used + state->channels * (1.0 + input_index) >= priv->in_count)
break ;
if (priv->out_count > 0 && fabs (state->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
src_ratio = state->last_ratio + priv->out_gen * (data->src_ratio - state->last_ratio) / priv->out_count ;
for (ch = 0 ; ch < state->channels ; ch++)
{ data->data_out [priv->out_gen] = (float) (priv->last_value [ch] + input_index *
((float) data->data_in [ch] - priv->last_value [ch])) ;
priv->out_gen ++ ;
} ;
/* Figure out the next index. */
input_index += 1.0 / src_ratio ;
} ;
rem = fmod_one (input_index) ;
priv->in_used += state->channels * psf_lrint (input_index - rem) ;
input_index = rem ;
/* Main processing loop. */
while (priv->out_gen < priv->out_count && priv->in_used + state->channels * input_index < priv->in_count)
{
if (priv->out_count > 0 && fabs (state->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
src_ratio = state->last_ratio + priv->out_gen * (data->src_ratio - state->last_ratio) / priv->out_count ;
#if SRC_DEBUG
if (priv->in_used < state->channels && input_index < 1.0)
{ printf ("Whoops!!!! in_used : %ld channels : %d input_index : %f\n", priv->in_used, state->channels, input_index) ;
exit (1) ;
} ;
#endif
for (ch = 0 ; ch < state->channels ; ch++)
{ data->data_out [priv->out_gen] = (float) (data->data_in [priv->in_used - state->channels + ch] + input_index *
((float) data->data_in [priv->in_used + ch] - data->data_in [priv->in_used - state->channels + ch])) ;
priv->out_gen ++ ;
} ;
/* Figure out the next index. */
input_index += 1.0 / src_ratio ;
rem = fmod_one (input_index) ;
priv->in_used += state->channels * psf_lrint (input_index - rem) ;
input_index = rem ;
} ;
if (priv->in_used > priv->in_count)
{ input_index += (priv->in_used - priv->in_count) / state->channels ;
priv->in_used = priv->in_count ;
} ;
state->last_position = input_index ;
if (priv->in_used > 0)
for (ch = 0 ; ch < state->channels ; ch++)
priv->last_value [ch] = data->data_in [priv->in_used - state->channels + ch] ;
/* Save current ratio rather then target ratio. */
state->last_ratio = src_ratio ;
data->input_frames_used = priv->in_used / state->channels ;
data->output_frames_gen = priv->out_gen / state->channels ;
return SRC_ERR_NO_ERROR ;
} /* linear_vari_process */
/*------------------------------------------------------------------------------
*/
LIBSAMPLERATE_DLL_PRIVATE const char*
linear_get_name (int src_enum)
{
if (src_enum == SRC_LINEAR)
return "Linear Interpolator" ;
return NULL ;
} /* linear_get_name */
LIBSAMPLERATE_DLL_PRIVATE const char*
linear_get_description (int src_enum)
{
if (src_enum == SRC_LINEAR)
return "Linear interpolator, very fast, poor quality." ;
return NULL ;
} /* linear_get_descrition */
static LINEAR_DATA *
linear_data_new (int channels)
{
assert (channels > 0) ;
LINEAR_DATA *priv = (LINEAR_DATA *) calloc (1, sizeof (LINEAR_DATA)) ;
if (priv)
{
priv->linear_magic_marker = LINEAR_MAGIC_MARKER ;
priv->last_value = (float *) calloc (channels, sizeof (float)) ;
if (!priv->last_value)
{
free (priv) ;
priv = NULL ;
}
}
return priv ;
}
LIBSAMPLERATE_DLL_PRIVATE SRC_STATE *
linear_state_new (int channels, SRC_ERROR *error)
{
assert (channels > 0) ;
assert (error != NULL) ;
SRC_STATE *state = (SRC_STATE *) calloc (1, sizeof (SRC_STATE)) ;
if (!state)
{
*error = SRC_ERR_MALLOC_FAILED ;
return NULL ;
}
state->channels = channels ;
state->mode = SRC_MODE_PROCESS ;
state->private_data = linear_data_new (state->channels) ;
if (!state->private_data)
{
free (state) ;
*error = SRC_ERR_MALLOC_FAILED ;
return NULL ;
}
state->vt = &linear_state_vt ;
linear_reset (state) ;
*error = SRC_ERR_NO_ERROR ;
return state ;
}
/*===================================================================================
*/
static void
linear_reset (SRC_STATE *state)
{ LINEAR_DATA *priv = NULL ;
priv = (LINEAR_DATA*) state->private_data ;
if (priv == NULL)
return ;
priv->dirty = false ;
memset (priv->last_value, 0, sizeof (priv->last_value [0]) * state->channels) ;
return ;
} /* linear_reset */
SRC_STATE *
linear_copy (SRC_STATE *state)
{
assert (state != NULL) ;
if (state->private_data == NULL)
return NULL ;
SRC_STATE *to = (SRC_STATE *) calloc (1, sizeof (SRC_STATE)) ;
if (!to)
return NULL ;
memcpy (to, state, sizeof (SRC_STATE)) ;
LINEAR_DATA* from_priv = (LINEAR_DATA*) state->private_data ;
LINEAR_DATA *to_priv = (LINEAR_DATA *) calloc (1, sizeof (LINEAR_DATA)) ;
if (!to_priv)
{
free (to) ;
return NULL ;
}
memcpy (to_priv, from_priv, sizeof (LINEAR_DATA)) ;
to_priv->last_value = (float *) malloc (sizeof (float) * state->channels) ;
if (!to_priv->last_value)
{
free (to) ;
free (to_priv) ;
return NULL ;
}
memcpy (to_priv->last_value, from_priv->last_value, sizeof (float) * state->channels) ;
to->private_data = to_priv ;
return to ;
} /* linear_copy */
static void
linear_close (SRC_STATE *state)
{
if (state)
{
LINEAR_DATA *linear = (LINEAR_DATA *) state->private_data ;
if (linear)
{
if (linear->last_value)
{
free (linear->last_value) ;
linear->last_value = NULL ;
}
free (linear) ;
linear = NULL ;
}
free (state) ;
state = NULL ;
}
} /* linear_close */

File diff suppressed because it is too large Load Diff

@ -1,290 +0,0 @@
/*
** Copyright (c) 2002-2021, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "common.h"
static SRC_ERROR zoh_vari_process (SRC_STATE *state, SRC_DATA *data) ;
static void zoh_reset (SRC_STATE *state) ;
static SRC_STATE *zoh_copy (SRC_STATE *state) ;
static void zoh_close (SRC_STATE *state) ;
/*========================================================================================
*/
#define ZOH_MAGIC_MARKER MAKE_MAGIC ('s', 'r', 'c', 'z', 'o', 'h')
typedef struct
{ int zoh_magic_marker ;
bool dirty ;
long in_count, in_used ;
long out_count, out_gen ;
float *last_value ;
} ZOH_DATA ;
static SRC_STATE_VT zoh_state_vt =
{
zoh_vari_process,
zoh_vari_process,
zoh_reset,
zoh_copy,
zoh_close
} ;
/*----------------------------------------------------------------------------------------
*/
static SRC_ERROR
zoh_vari_process (SRC_STATE *state, SRC_DATA *data)
{ ZOH_DATA *priv ;
float src_ratio, input_index, rem ;
int ch ;
if (data->input_frames <= 0)
return SRC_ERR_NO_ERROR ;
if (state->private_data == NULL)
return SRC_ERR_NO_PRIVATE ;
priv = (ZOH_DATA*) state->private_data ;
if (!priv->dirty)
{ /* If we have just been reset, set the last_value data. */
for (ch = 0 ; ch < state->channels ; ch++)
priv->last_value [ch] = data->data_in [ch] ;
priv->dirty = true ;
} ;
priv->in_count = data->input_frames * state->channels ;
priv->out_count = data->output_frames * state->channels ;
priv->in_used = priv->out_gen = 0 ;
src_ratio = state->last_ratio ;
if (is_bad_src_ratio (src_ratio))
return SRC_ERR_BAD_INTERNAL_STATE ;
input_index = state->last_position ;
/* Calculate samples before first sample in input array. */
while (input_index < 1.0 && priv->out_gen < priv->out_count)
{
if (priv->in_used + state->channels * input_index >= priv->in_count)
break ;
if (priv->out_count > 0 && fabs (state->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
src_ratio = state->last_ratio + priv->out_gen * (data->src_ratio - state->last_ratio) / priv->out_count ;
for (ch = 0 ; ch < state->channels ; ch++)
{ data->data_out [priv->out_gen] = priv->last_value [ch] ;
priv->out_gen ++ ;
} ;
/* Figure out the next index. */
input_index += 1.0 / src_ratio ;
} ;
rem = fmod_one (input_index) ;
priv->in_used += state->channels * psf_lrint (input_index - rem) ;
input_index = rem ;
/* Main processing loop. */
while (priv->out_gen < priv->out_count && priv->in_used + state->channels * input_index <= priv->in_count)
{
if (priv->out_count > 0 && fabs (state->last_ratio - data->src_ratio) > SRC_MIN_RATIO_DIFF)
src_ratio = state->last_ratio + priv->out_gen * (data->src_ratio - state->last_ratio) / priv->out_count ;
for (ch = 0 ; ch < state->channels ; ch++)
{ data->data_out [priv->out_gen] = data->data_in [priv->in_used - state->channels + ch] ;
priv->out_gen ++ ;
} ;
/* Figure out the next index. */
input_index += 1.0 / src_ratio ;
rem = fmod_one (input_index) ;
priv->in_used += state->channels * psf_lrint (input_index - rem) ;
input_index = rem ;
} ;
if (priv->in_used > priv->in_count)
{ input_index += (priv->in_used - priv->in_count) / state->channels ;
priv->in_used = priv->in_count ;
} ;
state->last_position = input_index ;
if (priv->in_used > 0)
for (ch = 0 ; ch < state->channels ; ch++)
priv->last_value [ch] = data->data_in [priv->in_used - state->channels + ch] ;
/* Save current ratio rather then target ratio. */
state->last_ratio = src_ratio ;
data->input_frames_used = priv->in_used / state->channels ;
data->output_frames_gen = priv->out_gen / state->channels ;
return SRC_ERR_NO_ERROR ;
} /* zoh_vari_process */
/*------------------------------------------------------------------------------
*/
LIBSAMPLERATE_DLL_PRIVATE const char*
zoh_get_name (int src_enum)
{
if (src_enum == SRC_ZERO_ORDER_HOLD)
return "ZOH Interpolator" ;
return NULL ;
} /* zoh_get_name */
LIBSAMPLERATE_DLL_PRIVATE const char*
zoh_get_description (int src_enum)
{
if (src_enum == SRC_ZERO_ORDER_HOLD)
return "Zero order hold interpolator, very fast, poor quality." ;
return NULL ;
} /* zoh_get_descrition */
static ZOH_DATA *
zoh_data_new (int channels)
{
assert (channels > 0) ;
ZOH_DATA *priv = (ZOH_DATA *) calloc (1, sizeof (ZOH_DATA)) ;
if (priv)
{
priv->zoh_magic_marker = ZOH_MAGIC_MARKER ;
priv->last_value = (float *) calloc (channels, sizeof (float)) ;
if (!priv->last_value)
{
free (priv) ;
priv = NULL ;
}
}
return priv ;
}
LIBSAMPLERATE_DLL_PRIVATE SRC_STATE *
zoh_state_new (int channels, SRC_ERROR *error)
{
assert (channels > 0) ;
assert (error != NULL) ;
SRC_STATE *state = (SRC_STATE *) calloc (1, sizeof (SRC_STATE)) ;
if (!state)
{
*error = SRC_ERR_MALLOC_FAILED ;
return NULL ;
}
state->channels = channels ;
state->mode = SRC_MODE_PROCESS ;
state->private_data = zoh_data_new (state->channels) ;
if (!state->private_data)
{
free (state) ;
*error = SRC_ERR_MALLOC_FAILED ;
return NULL ;
}
state->vt = &zoh_state_vt ;
zoh_reset (state) ;
*error = SRC_ERR_NO_ERROR ;
return state ;
}
/*===================================================================================
*/
static void
zoh_reset (SRC_STATE *state)
{ ZOH_DATA *priv ;
priv = (ZOH_DATA*) state->private_data ;
if (priv == NULL)
return ;
priv->dirty = false ;
memset (priv->last_value, 0, sizeof (float) * state->channels) ;
return ;
} /* zoh_reset */
static SRC_STATE *
zoh_copy (SRC_STATE *state)
{
assert (state != NULL) ;
if (state->private_data == NULL)
return NULL ;
SRC_STATE *to = (SRC_STATE *) calloc (1, sizeof (SRC_STATE)) ;
if (!to)
return NULL ;
memcpy (to, state, sizeof (SRC_STATE)) ;
ZOH_DATA* from_priv = (ZOH_DATA*) state->private_data ;
ZOH_DATA *to_priv = (ZOH_DATA *) calloc (1, sizeof (ZOH_DATA)) ;
if (!to_priv)
{
free (to) ;
return NULL ;
}
memcpy (to_priv, from_priv, sizeof (ZOH_DATA)) ;
to_priv->last_value = (float *) malloc (sizeof (float) * state->channels) ;
if (!to_priv->last_value)
{
free (to) ;
free (to_priv) ;
return NULL ;
}
memcpy (to_priv->last_value, from_priv->last_value, sizeof (float) * state->channels) ;
to->private_data = to_priv ;
return to ;
} /* zoh_copy */
static void
zoh_close (SRC_STATE *state)
{
if (state)
{
ZOH_DATA *zoh = (ZOH_DATA *) state->private_data ;
if (zoh)
{
if (zoh->last_value)
{
free (zoh->last_value) ;
zoh->last_value = NULL ;
}
free (zoh) ;
zoh = NULL ;
}
free (state) ;
state = NULL ;
}
} /* zoh_close */

@ -1,95 +0,0 @@
check_include_file(sys/times.h HAVE_SYS_TIMES_H)
check_function_exists(alarm HAVE_ALARM)
check_function_exists(signal HAVE_SIGNAL)
check_symbol_exists(SIGALRM signal.h HAVE_SIGALRM)
if((NOT VCPKG_TOOLCHAIN) AND PKG_CONFIG_FOUND AND (NOT CMAKE_VERSION VERSION_LESS 3.6))
pkg_check_modules(FFTW3 fftw3 IMPORTED_TARGET)
if(FFTW3_FOUND)
add_library(FFTW3::fftw3 INTERFACE IMPORTED)
target_link_libraries(FFTW3::fftw3 INTERFACE PkgConfig::FFTW3)
endif()
else()
find_package(FFTW3)
endif()
set(HAVE_FFTW3 ${FFTW3_FOUND} PARENT_SCOPE)
add_executable(misc_test misc_test.c util.c util.h)
target_link_libraries(misc_test PRIVATE samplerate)
add_test(NAME misc_test COMMAND misc_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
add_executable(termination_test termination_test.c util.c util.h)
target_link_libraries(termination_test PRIVATE samplerate)
add_test(NAME termination_test COMMAND termination_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
add_executable(callback_hang_test callback_hang_test.c util.c util.h)
target_link_libraries(callback_hang_test PRIVATE samplerate)
add_test(NAME callback_hang_test COMMAND callback_hang_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
add_executable(downsample_test downsample_test.c util.c util.h)
target_link_libraries(downsample_test PRIVATE samplerate)
add_test(NAME downsample_test COMMAND downsample_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
add_executable(simple_test simple_test.c util.c util.h)
target_link_libraries(simple_test PRIVATE samplerate)
add_test(NAME simple_test COMMAND simple_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
add_executable(callback_test callback_test.c util.c util.h)
target_link_libraries(callback_test PRIVATE samplerate)
add_test(NAME callback_test COMMAND callback_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
add_executable(reset_test reset_test.c util.c util.h)
target_link_libraries(reset_test PRIVATE samplerate)
add_test(NAME reset_test COMMAND reset_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
add_executable(clone_test clone_test.c util.c util.h)
target_link_libraries(clone_test PRIVATE samplerate)
add_test(NAME clone_test COMMAND clone_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
add_executable(nullptr_test nullptr_test.c util.c util.h)
target_link_libraries(nullptr_test PRIVATE samplerate)
add_test(NAME nullptr_test COMMAND nullptr_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
add_executable(multi_channel_test multi_channel_test.c calc_snr.c util.c util.h)
target_link_libraries(multi_channel_test
PRIVATE
samplerate
$<$<BOOL:${FFTW3_FOUND}>:FFTW3::fftw3>
)
add_test(NAME multi_channel_test COMMAND multi_channel_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
add_executable(varispeed_test varispeed_test.c calc_snr.c util.c util.h)
target_link_libraries(varispeed_test
PRIVATE samplerate
$<$<BOOL:${FFTW3_FOUND}>:FFTW3::fftw3>
)
add_test(NAME varispeed_test COMMAND varispeed_test util.c util.h WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
add_executable(float_short_test float_short_test.c)
target_link_libraries(float_short_test PRIVATE samplerate)
add_test(NAME float_short_test COMMAND float_short_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
add_executable(snr_bw_test snr_bw_test.c calc_snr.c util.c util.h)
target_link_libraries(snr_bw_test
PRIVATE
samplerate
$<$<BOOL:${FFTW3_FOUND}>:FFTW3::fftw3>
)
add_test(NAME snr_bw_test COMMAND snr_bw_test util.c util.h WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
add_executable(throughput_test throughput_test.c util.c util.h)
target_link_libraries(throughput_test PRIVATE samplerate)
add_executable(multichan_throughput_test multichan_throughput_test.c util.c util.h)
target_link_libraries(multichan_throughput_test PRIVATE samplerate)
add_executable(src-evaluate src-evaluate.c util.c util.h calc_snr.c)
target_link_libraries(src-evaluate
PRIVATE
samplerate
$<$<BOOL:${FFTW3_FOUND}>:FFTW3::fftw3>
$<$<BOOL:${SndFile_FOUND}>:${SNDFILE_TARGET}>
)

@ -1,243 +0,0 @@
/*
** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "util.h"
#if (HAVE_FFTW3)
#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) ;
maxval = 0.0 ;
for (k = 1 ; k < len / 2 ; k++)
{ /*
** From : http://www.fftw.org/doc/Real_002dto_002dReal-Transform-Kinds.html#Real_002dto_002dReal-Transform-Kinds
**
** FFTW_R2HC computes a real-input DFT with output in halfcomplex format, i.e. real and imaginary parts
** for a transform of size n stored as:
**
** r0, r1, r2, ..., rn/2, i(n+1)/2-1, ..., i2, i1
*/
double re = magnitude [k] ;
double im = magnitude [len - k] ;
magnitude [k] = sqrt (re * re + im * im) ;
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,127 +0,0 @@
/*
** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#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) ;
#ifdef ENABLE_SINC_FAST_CONVERTER
callback_hang_test (SRC_SINC_FASTEST) ;
#endif
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,238 +0,0 @@
/*
** Copyright (c) 2003-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#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]) ;
#ifdef ENABLE_SINC_FAST_CONVERTER
puts (" Sinc interpolator :") ;
for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
callback_test (SRC_SINC_FASTEST, src_ratios [k]) ;
#endif
puts ("") ;
puts (" End of stream test :") ;
end_of_stream_test (SRC_ZERO_ORDER_HOLD) ;
end_of_stream_test (SRC_LINEAR) ;
#ifdef ENABLE_SINC_FAST_CONVERTER
end_of_stream_test (SRC_SINC_FASTEST) ;
#endif
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_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 ;
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) ;
} ;
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) ;
}
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_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,134 +0,0 @@
/*
** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <samplerate.h>
#include "util.h"
#define BUFFER_LEN (1 << 16)
#define NUM_CHANNELS 2
#define FRAMES_PER_PASS (BUFFER_LEN >> 1)
static void
clone_test (int converter)
{ static float input_serial [BUFFER_LEN * NUM_CHANNELS], input_interleaved [BUFFER_LEN * NUM_CHANNELS] ;
static float output [BUFFER_LEN * NUM_CHANNELS], output_cloned [BUFFER_LEN * NUM_CHANNELS] ;
double sine_freq ;
SRC_STATE* src_state ;
SRC_STATE* src_state_cloned ;
SRC_DATA src_data, src_data_cloned ;
int error, frame, ch, idx ;
printf (" clone_test (%-28s) ....... ", src_get_name (converter)) ;
fflush (stdout) ;
memset (input_serial, 0, sizeof (input_serial)) ;
memset (input_interleaved, 0, sizeof (input_interleaved)) ;
memset (output, 0, sizeof (output)) ;
memset (output_cloned, 0, sizeof (output_cloned)) ;
/* Fill input buffer with an n-channel interleaved sine wave */
sine_freq = 0.0111 ;
gen_windowed_sines (1, &sine_freq, 1.0, input_serial, BUFFER_LEN) ;
gen_windowed_sines (1, &sine_freq, 1.0, input_serial + BUFFER_LEN, BUFFER_LEN) ;
interleave_data (input_serial, input_interleaved, BUFFER_LEN, NUM_CHANNELS) ;
if ((src_state = src_new (converter, NUM_CHANNELS, &error)) == NULL)
{ printf ("\n\nLine %d : src_new() failed : %s\n\n", __LINE__, src_strerror (error)) ;
exit (1) ;
} ;
/* Perform initial pass using first half of buffer so that src_state has non-trivial state */
src_data.src_ratio = 1.1 ;
src_data.input_frames = FRAMES_PER_PASS ;
src_data.output_frames = FRAMES_PER_PASS ;
src_data.data_in = input_interleaved ;
src_data.data_out = output ;
src_data.output_frames_gen = 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) ;
} ;
/* Clone handle */
if ((src_state_cloned = src_clone (src_state, &error)) == NULL)
{ printf ("\n\nLine %d : src_clone() failed : %s\n\n", __LINE__, src_strerror (error)) ;
exit (1) ;
} ;
/* Process second half of buffer with both handles */
src_data.data_in = input_interleaved + FRAMES_PER_PASS ;
src_data_cloned = src_data ;
src_data_cloned.data_out = output_cloned ;
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 ((error = src_process (src_state_cloned, &src_data_cloned)))
{ 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) ;
} ;
/* Check that both handles generated the same number of output frames */
if (src_data.output_frames_gen != src_data_cloned.output_frames_gen)
{ printf ("\n\nLine %d : cloned output_frames_gen (%ld) != original (%ld)\n\n", __LINE__,
src_data_cloned.output_frames_gen, src_data.output_frames_gen) ;
exit (1) ;
} ;
for (ch = 0 ; ch < NUM_CHANNELS ; ch++)
{ for (frame = 0 ; frame < src_data.output_frames_gen ; frame++)
{ idx = ch * NUM_CHANNELS + ch ;
if (output[idx] != output_cloned[idx])
{ printf ("\n\nLine %d : cloned data does not equal original data at channel %d, frame %d\n\n",
__LINE__, ch, frame) ;
exit (1) ;
} ;
} ;
} ;
src_delete (src_state) ;
src_delete (src_state_cloned) ;
puts ("ok") ;
} /* clone_test */
int
main (void)
{
puts("");
clone_test (SRC_ZERO_ORDER_HOLD) ;
clone_test (SRC_LINEAR) ;
#ifdef ENABLE_SINC_FAST_CONVERTER
clone_test (SRC_SINC_FASTEST) ;
#endif
puts("");
return 0 ;
} /* main */

@ -1,61 +0,0 @@
/*
** Copyright (c) 2008-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#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) ;
#ifdef ENABLE_SINC_FAST_CONVERTER
downsample_test (SRC_SINC_FASTEST) ;
#endif
#ifdef ENABLE_SINC_MEDIUM_CONVERTER
downsample_test (SRC_SINC_MEDIUM_QUALITY) ;
#endif
#ifdef ENABLE_SINC_BEST_CONVERTER
downsample_test (SRC_SINC_BEST_QUALITY) ;
#endif
puts ("") ;
return 0 ;
} /* main */

@ -1,192 +0,0 @@
/*
** Copyright (c) 2003-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#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.95f, 0.99f, 1.0f, 1.01f, 1.1f, 2.0f, 11.1f, 111.1f, 2222.2f, 33333.3f,
// Some "almost 1" as corner cases
(float) (32767.0 / 32768.0), (float) ((32767.0 + 0.4) / 32768.0), (float) ((32767. + 0.5) / 32768.0),
(float) ((32767.0 + 0.6) / 32768.0), (float) ((32767.0 + 0.9) / 32768.0),
} ;
static float fneg [] =
{ -0.95f, -0.99f, -1.0f, -1.01f, -1.1f, -2.0f, -11.1f, -111.1f, -2222.2f, -33333.3f,
// Some "almost 1" as corner cases
(float) (-32767.0 / 32768.0), (float) (-(32767.0 + 0.4) / 32768.0), (float) (-(32767.0 + 0.5) / 32768.0),
(float) (-(32767.0 + 0.6) / 32768.0), (float) (-(32767.0 + 0.9) / 32768.0),
} ;
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.95f, 0.99f, 1.0f, 1.01f, 1.1f, 2.0f, 11.1f, 111.1f, 2222.2f, 33333.3f
} ;
static float fneg [] =
{ -0.95f, -0.99f, -1.0f, -1.01f, -1.1f, -2.0f, -11.1f, -111.1f, -2222.2f, -33333.3f
} ;
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,208 +0,0 @@
/*
** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#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) ;
static void get_channels_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) ;
#ifdef ENABLE_SINC_FAST_CONVERTER
zero_input_test (SRC_SINC_FASTEST) ;
#endif
get_channels_test (SRC_ZERO_ORDER_HOLD) ;
get_channels_test (SRC_LINEAR) ;
#ifdef ENABLE_SINC_FAST_CONVERTER
get_channels_test (SRC_SINC_FASTEST) ;
#endif
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 *) (size_t) 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 */
static void get_channels_test(int converter)
{
SRC_STATE *state;
int channels_in, channels_out;
const char *errorstr;
state = NULL;
if ((channels_out = src_get_channels(state)) >= 0)
{
printf ("\n\nLine %d : Return value should be negative, was : %d.\n\n", __LINE__, channels_out) ;
exit (1) ;
}
errorstr = src_strerror(-channels_out);
if (!strstr(errorstr, "NULL"))
{
printf ("\n\nLine %d : Inverted output should be valid error code mentioning a NULL pointer, was : %s.\n\n", __LINE__, errorstr) ;
exit (1) ;
}
for (channels_in = 1; channels_in <= 8; channels_in++)
{
int error;
state = src_new(converter, channels_in, &error);
if ((channels_out = src_get_channels(state)) != channels_in)
{
printf ("\n\nLine %d : Return value should be %d, was : %d.\n\n", __LINE__, channels_in, channels_out) ;
exit (1) ;
}
state = src_delete(state);
}
}

@ -1,368 +0,0 @@
/*
** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#if (HAVE_FFTW3)
#include <fftw3.h>
#else
static inline void
fftw_cleanup (void)
{ return ;
}
#endif
#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) ;
} ;
#ifdef ENABLE_SINC_FAST_CONVERTER
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) ;
} ;
#endif
fftw_cleanup () ;
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,261 +0,0 @@
/*
** Copyright (c) 2008-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <math.h>
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#endif
#include <samplerate.h>
#include "util.h"
#define BUFFER_LEN (1<<17)
static float input [BUFFER_LEN] ;
#if (defined(ENABLE_SINC_FAST_CONVERTER) || defined(ENABLE_SINC_MEDIUM_CONVERTER) || \
defined(ENABLE_SINC_BEST_CONVERTER))
static float output [BUFFER_LEN] ;
static void
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 ;
#ifdef _WIN32
Sleep (2000) ;
#else
sleep (2) ;
#endif
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)
{ printf ("%5.2f %10ld\n", duration, throughput) ;
}
else
{ *best_throughput = MAX (throughput, *best_throughput) ;
printf ("%5.2f %10ld %10ld\n", duration, throughput, *best_throughput) ;
}
} /* throughput_test */
#endif
static void
single_run (void)
{
#if (defined(ENABLE_SINC_FAST_CONVERTER) || defined(ENABLE_SINC_MEDIUM_CONVERTER) || \
defined(ENABLE_SINC_BEST_CONVERTER))
const int max_channels = 10 ;
int k ;
#endif
printf ("\n CPU name : %s\n", get_cpu_name ()) ;
puts (
"\n"
" Converter Channels Duration Throughput\n"
" ---------------------------------------------------------------------"
) ;
#ifdef ENABLE_SINC_FAST_CONVERTER
for (k = 1 ; k <= max_channels / 2 ; k++)
throughput_test (SRC_SINC_FASTEST, k, 0) ;
puts ("") ;
#endif
#ifdef ENABLE_SINC_MEDIUM_CONVERTER
for (k = 1 ; k <= max_channels / 2 ; k++)
throughput_test (SRC_SINC_MEDIUM_QUALITY, k, 0) ;
puts ("") ;
#endif
#ifdef ENABLE_SINC_BEST_CONVERTER
for (k = 1 ; k <= max_channels ; k++)
throughput_test (SRC_SINC_BEST_QUALITY, k, 0) ;
puts ("") ;
#endif
return ;
} /* single_run */
static void
multi_run (int run_count)
{ int channels[] = {1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 18};
printf ("\n CPU name : %s\n", get_cpu_name ()) ;
puts (
"\n"
" Converter Channels Duration Throughput Best Throughput\n"
" ----------------------------------------------------------------------------------------"
) ;
for (int i = 0 ; i < ARRAY_LEN(channels) ; i++)
{
#ifdef ENABLE_SINC_FAST_CONVERTER
long sinc_fastest = 0 ;
#endif
#ifdef ENABLE_SINC_MEDIUM_CONVERTER
long sinc_medium = 0 ;
#endif
#ifdef ENABLE_SINC_BEST_CONVERTER
long sinc_best = 0 ;
#endif
int ch = channels[i];
for (int k = 0 ; k < run_count ; k++)
{
#ifdef ENABLE_SINC_FAST_CONVERTER
throughput_test (SRC_SINC_FASTEST, ch, &sinc_fastest) ;
#endif
#ifdef ENABLE_SINC_MEDIUM_CONVERTER
throughput_test (SRC_SINC_MEDIUM_QUALITY, ch, &sinc_medium) ;
#endif
#ifdef ENABLE_SINC_BEST_CONVERTER
throughput_test (SRC_SINC_BEST_QUALITY, ch, &sinc_best) ;
#endif
puts ("") ;
/* Let the CPU cool down. We might be running on a laptop. */
#ifdef _WIN32
Sleep (10000) ;
#else
sleep (10) ;
#endif
} ;
printf (
"\n"
" Converter (channels: %d) Best Throughput\n"
" ------------------------------------------------\n",
ch
) ;
#ifdef ENABLE_SINC_FAST_CONVERTER
printf (" %-30s %10ld\n", src_get_name (SRC_SINC_FASTEST), sinc_fastest) ;
#endif
#ifdef ENABLE_SINC_MEDIUM_CONVERTER
printf (" %-30s %10ld\n", src_get_name (SRC_SINC_MEDIUM_QUALITY), sinc_medium) ;
#endif
#ifdef ENABLE_SINC_BEST_CONVERTER
printf (" %-30s %10ld\n", src_get_name (SRC_SINC_BEST_QUALITY), sinc_best) ;
#endif
} ;
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,108 +0,0 @@
/*
** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <samplerate.h>
#include "util.h"
#define BUFFER_LEN (1 << 16)
#define NUM_CHANNELS 1
static void
nullptr_test (int converter)
{ static float input [BUFFER_LEN * NUM_CHANNELS] ;
static float output [BUFFER_LEN * NUM_CHANNELS] ;
SRC_STATE* src_state ;
SRC_DATA src_data, src_data2 ;
int error ;
printf (" nullptr_test (%-28s) ....... ", src_get_name (converter)) ;
fflush (stdout) ;
memset (input, 0, sizeof (input)) ;
memset (output, 0, sizeof (output)) ;
if ((src_state = src_new (converter, NUM_CHANNELS, &error)) == NULL)
{ printf ("\n\nLine %d : src_new() failed : %s\n\n", __LINE__, src_strerror (error)) ;
exit (1) ;
} ;
src_data.src_ratio = 1.1 ;
src_data.input_frames = BUFFER_LEN ;
src_data.output_frames = BUFFER_LEN ;
src_data.data_in = input ;
src_data.data_out = output ;
src_data.output_frames_gen = 0 ;
if ((error = src_process (src_state, &src_data)))
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
exit (1) ;
} ;
//Input is zero-length
src_data2 = src_data;
src_data2.data_in = NULL;
src_data2.input_frames = 0;
if ((error = src_process (src_state, &src_data2)))
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
exit (1) ;
} ;
//Output is zero-length
src_data2 = src_data;
src_data2.data_out = NULL;
src_data2.output_frames = 0;
if ((error = src_process (src_state, &src_data2)))
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
exit (1) ;
} ;
//Input and output are zero-length
src_data2 = src_data;
src_data2.data_in = NULL;
src_data2.data_out = NULL;
src_data2.input_frames = 0;
src_data2.output_frames = 0;
if ((error = src_process (src_state, &src_data2)))
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
exit (1) ;
} ;
src_state = src_delete (src_state) ;
puts ("ok") ;
} /* nullptr_test */
int
main (void)
{
puts("");
nullptr_test (SRC_ZERO_ORDER_HOLD) ;
nullptr_test (SRC_LINEAR) ;
#ifdef ENABLE_SINC_FAST_CONVERTER
nullptr_test (SRC_SINC_FASTEST) ;
#endif
puts("");
return 0 ;
} /* main */

@ -1,236 +0,0 @@
/*
** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#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) ;
#ifdef ENABLE_SINC_FAST_CONVERTER
process_reset_test (SRC_SINC_FASTEST) ;
#endif
callback_reset_test (SRC_ZERO_ORDER_HOLD) ;
callback_reset_test (SRC_LINEAR) ;
#ifdef ENABLE_SINC_FAST_CONVERTER
callback_reset_test (SRC_SINC_FASTEST) ;
#endif
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 successful. */
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 successful. */
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,168 +0,0 @@
/*
** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#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) ;
static void src_simple_produces_output (int converter, int channels, double src_ratio) ;
static void src_simple_produces_output_test (int converter, double src_ratio) ;
int
main (void)
{ static double src_ratios [] =
{ 1.0001, 0.099, 0.1, 0.33333333, 0.789, 1.9, 3.1, 9.9, 256.0, 1.0 / 256.0
} ;
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]) ;
src_simple_produces_output_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]) ;
src_simple_produces_output_test (SRC_LINEAR, src_ratios [k]) ;
}
#ifdef ENABLE_SINC_FAST_CONVERTER
puts (" Sinc interpolator :") ;
for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
{ simple_test (SRC_SINC_FASTEST, src_ratios [k]) ;
src_simple_produces_output_test (SRC_SINC_FASTEST, src_ratios [k]) ;
}
#endif
puts ("") ;
return 0 ;
} /* main */
static void
src_simple_produces_output_test (int converter, double src_ratio)
{
for (int channels = 1; channels <= 9; channels++)
src_simple_produces_output(converter, channels, src_ratio);
}
static void
src_simple_produces_output (int converter, int channels, double src_ratio)
{
// Choose a suitable number of frames.
// At least 256 so a conversion ratio of 1/256 can produce any output
const long NUM_FRAMES = 1000;
int error;
printf ("\tproduces_output\t(SRC ratio = %6.4f, channels = %d) ... ", src_ratio, channels) ;
fflush (stdout) ;
float *input = calloc (NUM_FRAMES * channels, sizeof (float));
float *output = calloc (NUM_FRAMES * channels, sizeof (float));
SRC_DATA src_data;
memset (&src_data, 0, sizeof (src_data)) ;
src_data.data_in = input;
src_data.data_out = output;
src_data.input_frames = NUM_FRAMES;
src_data.output_frames = NUM_FRAMES;
src_data.src_ratio = src_ratio;
if ((error = src_simple (&src_data, converter, channels)))
{ printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
exit (1) ;
} ;
if (src_data.input_frames_used == 0)
{ printf ("\n\nLine %d : No input frames used.\n\n", __LINE__) ;
exit (1) ;
} ;
if (src_data.output_frames_gen == 0)
{ printf ("\n\nLine %d : No output frames generated.\n\n", __LINE__) ;
exit (1) ;
} ;
free(input);
free(output);
puts ("ok") ;
}
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\t(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,404 +0,0 @@
/*
** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#if (HAVE_FFTW3)
#include <fftw3.h>
#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, 1.0 },
{ 2, { 0.012345, 0.457 }, 0.456789, 1, 12.0, 1.0 },
{ 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, 15.0, 0.94 },
{ 2, { 0.012345, 0.457 }, 0.456789, 1, 25.0, 0.96 },
{ 1, { 0.3511111111 }, 1.33, 1, 22.0, 0.99 }
}
},
#ifdef ENABLE_SINC_FAST_CONVERTER
{ 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 }
}
},
#endif
#ifdef ENABLE_SINC_MEDIUM_CONVERTER
{ SRC_SINC_MEDIUM_QUALITY,
9,
BOOLEAN_TRUE,
{ { 1, { 0.01111111111 }, 3.0, 1, 145.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, 157.0, 1.0 },
{ 1, { 0.01111111111 }, 1.001, 1, 148.0, 1.0 },
{ 2, { 0.011111, 0.324 }, 1.9999, 2, 127.0, 1.0 },
{ 2, { 0.012345, 0.457 }, 0.456789, 1, 123.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 }
}
},
#endif
#ifdef ENABLE_SINC_BEST_CONVERTER
{ 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, 148.0, 1.0 },
{ 1, { 0.01111111111 }, 1.0, 1, 155.0, 1.0 },
{ 1, { 0.01111111111 }, 1.001, 1, 148.0, 1.0 },
{ 2, { 0.011111, 0.324 }, 1.9999, 2, 146.0, 1.0 },
{ 2, { 0.012345, 0.457 }, 0.456789, 1, 147.0, 0.5 },
{ 2, { 0.011111, 0.45 }, 0.6, 1, 144.0, 0.5 },
{ 1, { 0.43111111111 }, 1.33, 1, 145.0, 1.0 }
}
},
#endif
} ; /* 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) ;
} ;
fftw_cleanup () ;
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 &= ((~0u) << 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 ((int) (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,530 +0,0 @@
/*
** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include <ctype.h>
#if defined(_WIN32)
#define popen _popen
#define pclose _pclose
#endif
#if (HAVE_FFTW3 && HAVE_SNDFILE && HAVE_SYS_TIMES_H)
#include <time.h>
#include <sys/times.h>
#include <sndfile.h>
#include <math.h>
#include <sys/utsname.h>
#include "util.h"
#define MAX_FREQS 4
#define BUFFER_LEN 80000
#define SAFE_STRNCAT(dest,src,len) \
{ int safe_strncat_count ; \
safe_strncat_count = (len) - strlen (dest) - 1 ; \
strncat ((dest), (src), safe_strncat_count) ; \
(dest) [(len) - 1] = 0 ; \
} ;
typedef struct
{ int freq_count ;
double freqs [MAX_FREQS] ;
int output_samplerate ;
int pass_band_peaks ;
double peak_value ;
} SNR_TEST ;
typedef struct
{ const char *progname ;
const char *version_cmd ;
const char *version_start ;
const char *convert_cmd ;
int format ;
} RESAMPLE_PROG ;
static char *get_progname (char *) ;
static void usage_exit (const char *, const RESAMPLE_PROG *prog, int count) ;
static void measure_program (const RESAMPLE_PROG *prog, int verbose) ;
static void generate_source_wav (const char *filename, const double *freqs, int freq_count, int format) ;
static const char* get_machine_details (void) ;
static char version_string [512] ;
int
main (int argc, char *argv [])
{ static RESAMPLE_PROG resample_progs [] =
{ { "sndfile-resample",
"examples/sndfile-resample --version",
"libsamplerate",
"examples/sndfile-resample --max-speed -c 0 -to %d source.wav destination.wav",
SF_FORMAT_WAV | SF_FORMAT_PCM_32
},
{ "sox",
"sox -h 2>&1",
"sox",
"sox source.wav -r %d destination.wav resample 0.835",
SF_FORMAT_WAV | SF_FORMAT_PCM_32
},
{ "ResampAudio",
"ResampAudio --version",
"ResampAudio",
"ResampAudio -f cutoff=0.41,atten=100,ratio=128 -s %d source.wav destination.wav",
SF_FORMAT_WAV | SF_FORMAT_PCM_32
},
/*-
{ /+*
** The Shibatch converter doesn't work for all combinations of
** source and destination sample rates. Therefore it can't be
** included in this test.
*+/
"shibatch",
"ssrc",
"Shibatch",
"ssrc --rate %d source.wav destination.wav",
SF_FORMAT_WAV | SF_FORMAT_PCM_32
},-*/
/*-
{ /+*
** The resample program is not able to match the bandwidth and SNR
** specs or sndfile-resample and hence will not be tested.
*+/
"resample",
"resample -version",
"resample",
"resample -to %d source.wav destination.wav",
SF_FORMAT_WAV | SF_FORMAT_FLOAT
},-*/
/*-
{ "mplayer",
"mplayer -v 2>&1",
"MPlayer ",
"mplayer -ao pcm -srate %d source.wav >/dev/null 2>&1 && mv audiodump.wav destination.wav",
SF_FORMAT_WAV | SF_FORMAT_PCM_32
},-*/
} ; /* resample_progs */
char *progname ;
int prog = 0, verbose = 0 ;
progname = get_progname (argv [0]) ;
printf ("\n %s : evaluate a sample rate converter.\n", progname) ;
if (argc == 3 && strcmp ("--verbose", argv [1]) == 0)
{ verbose = 1 ;
prog = atoi (argv [2]) ;
}
else if (argc == 2)
{ verbose = 0 ;
prog = atoi (argv [1]) ;
}
else
usage_exit (progname, resample_progs, ARRAY_LEN (resample_progs)) ;
if (prog < 0 || prog >= ARRAY_LEN (resample_progs))
usage_exit (progname, resample_progs, ARRAY_LEN (resample_progs)) ;
measure_program (& (resample_progs [prog]), verbose) ;
puts ("") ;
return 0 ;
} /* main */
/*==============================================================================
*/
static char *
get_progname (char *progname)
{ char *cptr ;
if ((cptr = strrchr (progname, '/')) != NULL)
progname = cptr + 1 ;
if ((cptr = strrchr (progname, '\\')) != NULL)
progname = cptr + 1 ;
return progname ;
} /* get_progname */
static void
usage_exit (const char *progname, const RESAMPLE_PROG *prog, int count)
{ int k ;
printf ("\n Usage : %s <number>\n\n", progname) ;
puts (" where <number> specifies the program to test:\n") ;
for (k = 0 ; k < count ; k++)
printf (" %d : %s\n", k, prog [k].progname) ;
puts ("\n"
" Obviously to test a given program you have to have it available on\n"
" your system. See http://libsndfile.github.io/libsamplerate/quality.html for\n"
" the download location of these programs.\n") ;
exit (1) ;
} /* usage_exit */
static const char*
get_machine_details (void)
{ static char namestr [262] ;
struct utsname name ;
if (uname (&name) != 0)
{ snprintf (namestr, sizeof (namestr), "Unknown") ;
return namestr ;
} ;
snprintf (namestr, sizeof (namestr), "%s (%s %s %s)", name.nodename,
name.machine, name.sysname, name.release) ;
return namestr ;
} /* get_machine_details */
/*==============================================================================
*/
static void
get_version_string (const RESAMPLE_PROG *prog)
{ FILE *file ;
char *cptr ;
/* Default. */
snprintf (version_string, sizeof (version_string), "no version") ;
if (prog->version_cmd == NULL)
return ;
if ((file = popen (prog->version_cmd, "r")) == NULL)
return ;
while ((cptr = fgets (version_string, sizeof (version_string), file)) != NULL)
{
if (strstr (cptr, prog->version_start) != NULL)
break ;
version_string [0] = 0 ;
} ;
pclose (file) ;
/* Remove trailing newline. */
if ((cptr = strchr (version_string, '\n')) != NULL)
cptr [0] = 0 ;
/* Remove leading whitespace from version string. */
cptr = version_string ;
while (cptr [0] != 0 && isspace (cptr [0]))
cptr ++ ;
if (cptr != version_string)
{ strncpy (version_string, cptr, sizeof (version_string) - 1) ;
version_string [sizeof (version_string) - 1] = 0 ;
} ;
return ;
} /* get_version_string */
static void
generate_source_wav (const char *filename, const double *freqs, int freq_count, int format)
{ static float buffer [BUFFER_LEN] ;
SNDFILE *sndfile ;
SF_INFO sfinfo ;
sfinfo.channels = 1 ;
sfinfo.samplerate = 44100 ;
sfinfo.format = format ;
if ((sndfile = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
{ printf ("Line %d : cound not open '%s' : %s\n", __LINE__, filename, sf_strerror (NULL)) ;
exit (1) ;
} ;
sf_command (sndfile, SFC_SET_ADD_PEAK_CHUNK, NULL, SF_FALSE) ;
gen_windowed_sines (freq_count, freqs, 0.9, buffer, ARRAY_LEN (buffer)) ;
if (sf_write_float (sndfile, buffer, ARRAY_LEN (buffer)) != ARRAY_LEN (buffer))
{ printf ("Line %d : sf_write_float short write.\n", __LINE__) ;
exit (1) ;
} ;
sf_close (sndfile) ;
} /* generate_source_wav */
static double
measure_destination_wav (char *filename, int *output_samples, int expected_peaks)
{ static float buffer [250000] ;
SNDFILE *sndfile ;
SF_INFO sfinfo ;
double snr ;
if ((sndfile = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
{ printf ("Line %d : Cound not open '%s' : %s\n", __LINE__, filename, sf_strerror (NULL)) ;
exit (1) ;
} ;
if (sfinfo.channels != 1)
{ printf ("Line %d : Bad channel count (%d). Should be 1.\n", __LINE__, sfinfo.channels) ;
exit (1) ;
} ;
if (sfinfo.frames > ARRAY_LEN (buffer))
{ printf ("Line %d : Too many frames (%ld) of data in file.\n", __LINE__, (long) sfinfo.frames) ;
exit (1) ;
} ;
*output_samples = (int) sfinfo.frames ;
if (sf_read_float (sndfile, buffer, sfinfo.frames) != sfinfo.frames)
{ printf ("Line %d : Bad read.\n", __LINE__) ;
exit (1) ;
} ;
sf_close (sndfile) ;
snr = calculate_snr (buffer, sfinfo.frames, expected_peaks) ;
return snr ;
} /* measure_desination_wav */
static double
measure_snr (const RESAMPLE_PROG *prog, int *output_samples, int verbose)
{ static SNR_TEST snr_test [] =
{
{ 1, { 0.211111111111 }, 48000, 1, 1.0 },
{ 1, { 0.011111111111 }, 132301, 1, 1.0 },
{ 1, { 0.111111111111 }, 92301, 1, 1.0 },
{ 1, { 0.011111111111 }, 26461, 1, 1.0 },
{ 1, { 0.011111111111 }, 13231, 1, 1.0 },
{ 1, { 0.011111111111 }, 44101, 1, 1.0 },
{ 2, { 0.311111, 0.49 }, 78199, 2, 1.0 },
{ 2, { 0.011111, 0.49 }, 12345, 1, 0.5 },
{ 2, { 0.0123456, 0.4 }, 20143, 1, 0.5 },
{ 2, { 0.0111111, 0.4 }, 26461, 1, 0.5 },
{ 1, { 0.381111111111 }, 58661, 1, 1.0 }
} ; /* snr_test */
static char command [256] ;
double snr, worst_snr = 500.0 ;
int k , retval, sample_count ;
*output_samples = 0 ;
for (k = 0 ; k < ARRAY_LEN (snr_test) ; k++)
{ remove ("source.wav") ;
remove ("destination.wav") ;
if (verbose)
printf (" SNR test #%d : ", k) ;
fflush (stdout) ;
generate_source_wav ("source.wav", snr_test [k].freqs, snr_test [k].freq_count, prog->format) ;
snprintf (command, sizeof (command), prog->convert_cmd, snr_test [k].output_samplerate) ;
SAFE_STRNCAT (command, " >/dev/null 2>&1", sizeof (command)) ;
if ((retval = system (command)) != 0)
printf ("system returned %d\n", retval) ;
snr = measure_destination_wav ("destination.wav", &sample_count, snr_test->pass_band_peaks) ;
*output_samples += sample_count ;
if (fabs (snr) < fabs (worst_snr))
worst_snr = fabs (snr) ;
if (verbose)
printf ("%6.2f dB\n", snr) ;
} ;
return worst_snr ;
} /* measure_snr */
/*------------------------------------------------------------------------------
*/
static double
measure_destination_peak (const char *filename)
{ static float data [2 * BUFFER_LEN] ;
SNDFILE *sndfile ;
SF_INFO sfinfo ;
double peak = 0.0 ;
int k = 0 ;
if ((sndfile = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
{ printf ("Line %d : failed to open file %s\n", __LINE__, filename) ;
exit (1) ;
} ;
if (sfinfo.channels != 1)
{ printf ("Line %d : bad channel count.\n", __LINE__) ;
exit (1) ;
} ;
if (sfinfo.frames > ARRAY_LEN (data) + 4 || sfinfo.frames < ARRAY_LEN (data) - 100)
{ printf ("Line %d : bad frame count (got %d, expected %d).\n", __LINE__, (int) sfinfo.frames, ARRAY_LEN (data)) ;
exit (1) ;
} ;
if (sf_read_float (sndfile, data, sfinfo.frames) != sfinfo.frames)
{ printf ("Line %d : bad read.\n", __LINE__) ;
exit (1) ;
} ;
sf_close (sndfile) ;
for (k = 0 ; k < (int) sfinfo.frames ; k++)
if (fabs (data [k]) > peak)
peak = fabs (data [k]) ;
return peak ;
} /* measure_destination_peak */
static double
find_attenuation (double freq, const RESAMPLE_PROG *prog, int verbose)
{ static char command [256] ;
double output_peak ;
int retval ;
char *filename ;
filename = "destination.wav" ;
generate_source_wav ("source.wav", &freq, 1, prog->format) ;
remove (filename) ;
snprintf (command, sizeof (command), prog->convert_cmd, 88189) ;
SAFE_STRNCAT (command, " >/dev/null 2>&1", sizeof (command)) ;
if ((retval = system (command)) != 0)
printf ("system returned %d\n", retval) ;
output_peak = measure_destination_peak (filename) ;
if (verbose)
printf (" freq : %f peak : %f\n", freq, output_peak) ;
return fabs (20.0 * log10 (output_peak)) ;
} /* find_attenuation */
static double
bandwidth_test (const RESAMPLE_PROG *prog, int verbose)
{ double f1, f2, a1, a2 ;
double freq, atten ;
f1 = 0.35 ;
a1 = find_attenuation (f1, prog, verbose) ;
f2 = 0.49999 ;
a2 = find_attenuation (f2, prog, verbose) ;
if (fabs (a1) < 1e-2 && a2 < 3.0)
return -1.0 ;
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, prog, 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 */
static void
measure_program (const RESAMPLE_PROG *prog, int verbose)
{ double snr, bandwidth, conversion_rate ;
int output_samples ;
struct tms time_data ;
time_t time_now ;
printf ("\n Machine : %s\n", get_machine_details ()) ;
time_now = time (NULL) ;
printf (" Date : %s", ctime (&time_now)) ;
get_version_string (prog) ;
printf (" Program : %s\n", version_string) ;
printf (" Command : %s\n\n", prog->convert_cmd) ;
snr = measure_snr (prog, &output_samples, verbose) ;
printf (" Worst case SNR : %6.2f dB\n", snr) ;
times (&time_data) ;
conversion_rate = (1.0 * output_samples * sysconf (_SC_CLK_TCK)) / time_data.tms_cutime ;
printf (" Conversion rate : %5.0f samples/sec\n", conversion_rate) ;
bandwidth = bandwidth_test (prog, verbose) ;
if (bandwidth > 0.0)
printf (" Measured bandwidth : %5.2f %%\n", bandwidth) ;
else
printf (" Could not measure bandwidth (no -3dB point found).\n") ;
return ;
} /* measure_program */
/*##############################################################################
*/
#else
int
main (void)
{ puts ("\n"
"****************************************************************\n"
" This program has been compiled without :\n"
" 1) FFTW (http://www.fftw.org/).\n"
" 2) libsndfile (http://www.zip.com.au/~erikd/libsndfile/).\n"
" Without these two libraries there is not much it can do.\n"
"****************************************************************\n") ;
return 0 ;
} /* main */
#endif /* (HAVE_FFTW3 && HAVE_SNDFILE) */

@ -1,149 +0,0 @@
/*
** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <samplerate.h>
#include "util.h"
#define BUFFER_LEN (1<<15)
#define BLOCK_LEN 100
static void stream_test (int converter, double ratio) ;
int
main (void)
{ static double src_ratios [] =
{ 0.3, 0.9, 1.1, 3.0
} ;
int k ;
puts ("\n Zero Order Hold interpolator:") ;
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++)
stream_test (SRC_LINEAR, src_ratios [k]) ;
puts ("\n Sinc interpolator:") ;
for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
stream_test (SRC_SINC_FASTEST, src_ratios [k]) ;
puts ("") ;
return 0 ;
} /* main */
static void
stream_test (int converter, double src_ratio)
{ static float input [BUFFER_LEN], output [BUFFER_LEN] ;
SRC_STATE *src_state ;
SRC_DATA src_data ;
int input_len, output_len, current_in, current_out ;
int error, terminate ;
printf ("\tstreaming_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) ;
} ;
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.input_frames = BLOCK_LEN ;
src_data.src_ratio = src_ratio ;
src_data.data_out = output ;
src_data.output_frames = BLOCK_LEN ;
while (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", src_data.output_frames) ;
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 ;
src_data.data_out += src_data.output_frames_gen ;
src_data.input_frames = MIN (BLOCK_LEN, input_len - current_in) ;
src_data.output_frames = MIN (BLOCK_LEN, output_len - current_out) ;
src_data.end_of_input = (current_in >= input_len) ? 1 : 0 ;
} ;
src_state = src_delete (src_state) ;
terminate = (int) ceil ((src_ratio >= 1.0) ? src_ratio : 1.0 / src_ratio) ;
if (fabs (current_out - src_ratio * input_len) > 2 * terminate)
{ printf ("\n\nLine %d : bad output data length %d should be %d.\n", __LINE__,
current_out, (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) ;
} ;
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 */

@ -1,342 +0,0 @@
/*
** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#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)
#ifdef ENABLE_SINC_FAST_CONVERTER
static void simple_test (int converter) ;
#endif
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]) ;
#ifdef ENABLE_SINC_FAST_CONVERTER
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) ;
#endif
return 0 ;
} /* main */
#ifdef ENABLE_SINC_FAST_CONVERTER
static void
simple_test (int converter)
{
// MSVC doesn't support variable-length arrays
#define ilen 199030
#define olen 1000
int 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 */
#endif
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 (labs (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.0f ;
/* 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,253 +0,0 @@
/*
** Copyright (c) 2004-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <math.h>
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#endif
#include <samplerate.h>
#include "util.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 ;
#ifdef _WIN32
Sleep (2000) ;
#else
sleep (2) ;
#endif
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 ;
#ifdef __GNU__ /* Clock resolution is 10ms on GNU/Hurd */
duration = (10000.0 * clock_time) / CLOCKS_PER_SEC ;
#else
duration = (1.0 * clock_time) / CLOCKS_PER_SEC ;
#endif
}
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) ;
#ifdef ENABLE_SINC_FAST_CONVERTER
throughput_test (SRC_SINC_FASTEST, 0) ;
#endif
#ifdef ENABLE_SINC_MEDIUM_CONVERTER
throughput_test (SRC_SINC_MEDIUM_QUALITY, 0) ;
#endif
#ifdef ENABLE_SINC_BEST_CONVERTER
throughput_test (SRC_SINC_BEST_QUALITY, 0) ;
#endif
puts ("") ;
return ;
} /* single_run */
static void
multi_run (int run_count)
{ long zero_order_hold = 0, linear = 0 ;
#ifdef ENABLE_SINC_FAST_CONVERTER
long sinc_fastest = 0 ;
#endif
#ifdef ENABLE_SINC_MEDIUM_CONVERTER
long sinc_medium = 0 ;
#endif
#ifdef ENABLE_SINC_BEST_CONVERTER
long sinc_best = 0 ;
#endif
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) ;
#ifdef ENABLE_SINC_FAST_CONVERTER
sinc_fastest = throughput_test (SRC_SINC_FASTEST, sinc_fastest) ;
#endif
#ifdef ENABLE_SINC_MEDIUM_CONVERTER
sinc_medium = throughput_test (SRC_SINC_MEDIUM_QUALITY, sinc_medium) ;
#endif
#ifdef ENABLE_SINC_BEST_CONVERTER
sinc_best = throughput_test (SRC_SINC_BEST_QUALITY, sinc_best) ;
#endif
puts ("") ;
/* Let the CPU cool down. We might be running on a laptop. */
#ifdef _WIN32
Sleep (10000) ;
#else
sleep (10) ;
#endif
} ;
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) ;
#ifdef ENABLE_SINC_FAST_CONVERTER
printf (" %-30s %10ld\n", src_get_name (SRC_SINC_FASTEST), sinc_fastest) ;
#endif
#ifdef ENABLE_SINC_MEDIUM_CONVERTER
printf (" %-30s %10ld\n", src_get_name (SRC_SINC_MEDIUM_QUALITY), sinc_medium) ;
#endif
#ifdef ENABLE_SINC_BEST_CONVERTER
printf (" %-30s %10ld\n", src_get_name (SRC_SINC_BEST_QUALITY), sinc_best) ;
#endif
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,228 +0,0 @@
/*
** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#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] = (float) (output [k] + (amplitude * sin (freqs [freq] * (2 * k) * M_PI + phase))) ;
} ;
/* Apply Hanning Window. */
for (k = 0 ; k < output_len ; k++)
output [k] = (float) (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
(void) search ;
(void) buffer ;
(void) file ;
(void) is_pipe ;
return name;
#endif
#if defined (__linux__) || defined (__APPLE__) || defined (__FreeBSD__)
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 ;
#endif
} /* get_cpu_name */

@ -1,41 +0,0 @@
/*
** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#define ABS(a) (((a) < 0) ? - (a) : (a))
#ifndef MAX
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#endif
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
#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) ;
#define ASSERT(condition) \
if (!(condition)) \
{ printf ("Condition failed on Line %d : %s\n\n", __LINE__, #condition) ; \
exit (1) ; \
} ;

@ -1,275 +0,0 @@
/*
** Copyright (c) 2006-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
** All rights reserved.
**
** This code is released under 2-clause BSD license. Please see the
** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <samplerate.h>
#include "util.h"
#if HAVE_FFTW3
#include <fftw3.h>
#else
#define fftw_cleanup()
#endif
#define BUFFER_LEN (1 << 14)
static void varispeed_test (int converter, double target_snr) ;
static void varispeed_bounds_test (int converter) ;
static void set_ratio_test (int converter, int channels, double initial_ratio, double second_ratio) ;
int
main (void)
{
puts ("\n Varispeed SNR test") ;
printf (" Zero Order Hold interpolator : ") ;
fflush (stdout) ;
varispeed_test (SRC_ZERO_ORDER_HOLD, 10.0) ;
puts ("ok") ;
printf (" Linear interpolator : ") ;
fflush (stdout) ;
varispeed_test (SRC_LINEAR, 10.0) ;
puts ("ok") ;
#ifdef ENABLE_SINC_FAST_CONVERTER
printf (" Sinc interpolator : ") ;
fflush (stdout) ;
varispeed_test (SRC_SINC_FASTEST, 115.0) ;
puts ("ok") ;
#endif
puts ("\n Varispeed bounds test") ;
printf (" Zero Order Hold interpolator : ") ;
fflush (stdout) ;
varispeed_bounds_test (SRC_ZERO_ORDER_HOLD) ;
puts ("ok") ;
printf (" Linear interpolator : ") ;
fflush (stdout) ;
varispeed_bounds_test (SRC_LINEAR) ;
puts ("ok") ;
#ifdef ENABLE_SINC_FAST_CONVERTER
printf (" Sinc interpolator : ") ;
fflush (stdout) ;
varispeed_bounds_test (SRC_SINC_FASTEST) ;
puts ("ok") ;
#endif
fftw_cleanup () ;
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) ;
} ;
return ;
} /* varispeed_test */
static void
varispeed_bounds_test (int converter)
{ double ratios [] = { 0.1, 0.01, 20 } ;
int chan, r1, r2 ;
for (chan = 1 ; chan <= 9 ; chan ++)
for (r1 = 0 ; r1 < ARRAY_LEN (ratios) ; r1++)
for (r2 = 0 ; r2 < ARRAY_LEN (ratios) ; r2 ++)
if (r1 != r2)
set_ratio_test (converter, chan, ratios [r1], ratios [r2]) ;
} /* varispeed_bounds_test */
static void
set_ratio_test (int converter, int channels, double initial_ratio, double second_ratio)
{ const int total_input_frames = BUFFER_LEN ;
/* Maximum upsample ratio is 20, use a value beigger. */
const int total_output_frames = 25 * BUFFER_LEN ;
/* Interested in array boundary conditions, so all zero data here is fine. */
float *input = calloc (total_input_frames * channels, sizeof (float)) ;
float *output = calloc (total_output_frames * channels, sizeof (float)) ;
char details [128] ;
const int max_loop_count = 100000 ;
const int chunk_size = 128 ;
SRC_STATE *src_state ;
SRC_DATA src_data ;
int error, k, total_frames_used, total_frames_gen ;
snprintf (details, sizeof (details), "%d channels, ratio %g -> %g", channels, initial_ratio, second_ratio) ;
if ((src_state = src_new (converter, channels, &error)) == NULL)
{ printf ("\n\nLine %d : src_new () failed : %s\n\n", __LINE__, src_strerror (error)) ;
exit (1) ;
} ;
total_frames_used = 0 ;
total_frames_gen = 0 ;
memset (&src_data, 0, sizeof (src_data)) ;
src_data.end_of_input = 0 ;
src_data.src_ratio = initial_ratio ;
src_data.data_in = input ;
src_data.data_out = output ;
src_data.input_frames = chunk_size ;
src_data.output_frames = total_output_frames ;
/* Use a max_loop_count here to enable the detection of infinite loops
** (due to end of input not being detected.
*/
for (k = 0 ; k < max_loop_count ; k ++)
{ if (k == 1)
{ /* Hard switch to second_ratio after processing one chunk. */
src_data.src_ratio = second_ratio ;
if ((error = src_set_ratio (src_state, second_ratio)))
{ printf ("\n\nLine %d : %s : %s\n\n", __LINE__, details, src_strerror (error)) ;
exit (1) ;
} ;
} ;
if ((error = src_process (src_state, &src_data)) != 0)
{ printf ("\n\nLine %d : %s : %s\n\n", __LINE__, details, src_strerror (error)) ;
exit (1) ;
} ;
if (src_data.end_of_input && src_data.output_frames_gen == 0)
break ;
total_frames_used += src_data.input_frames_used ;
total_frames_gen += src_data.output_frames_gen ;
src_data.data_in += src_data.input_frames_used * channels ;
src_data.data_out += src_data.output_frames_gen * channels ;
src_data.input_frames = total_input_frames - total_frames_used ;
src_data.output_frames = total_output_frames - total_frames_gen ;
src_data.end_of_input = total_frames_used >= total_input_frames ? 1 : 0 ;
} ;
ASSERT (k < max_loop_count) ;
ASSERT (total_frames_gen > 0) ;
for (k = 0 ; k < total_frames_gen * channels ; k ++)
ASSERT (! isnan (output [k])) ;
src_state = src_delete (src_state) ;
free (input) ;
free (output) ;
return ;
} /* set_ratio_test */

@ -5,7 +5,7 @@
idf_component_register(
SRCS "audio_task.cpp" "chunk.cpp" "fatfs_audio_input.cpp"
"stream_message.cpp" "i2s_audio_output.cpp" "stream_buffer.cpp" "track_queue.cpp"
"stream_event.cpp" "stream_info.cpp" "audio_fsm.cpp" "sink_mixer.cpp"
"stream_event.cpp" "stream_info.cpp" "audio_fsm.cpp" "sink_mixer.cpp" "resample.cpp"
INCLUDE_DIRS "include"
REQUIRES "codecs" "drivers" "cbor" "result" "tasks" "span" "memory" "tinyfsm" "database" "system_fsm" "playlist" "libsamplerate")

@ -34,6 +34,7 @@
#include "freertos/queue.h"
#include "freertos/ringbuf.h"
#include "pipeline.hpp"
#include "sample.hpp"
#include "sink_mixer.hpp"
#include "span.hpp"
@ -225,7 +226,7 @@ auto AudioTask::BeginDecoding(InputStream& stream) -> bool {
codecs::ICodec::OutputFormat format = res.second.value();
StreamInfo::Pcm new_format{
.channels = format.num_channels,
.bits_per_sample = format.bits_per_sample,
.bits_per_sample = 32,
.sample_rate = format.sample_rate_hz,
};
@ -255,7 +256,8 @@ auto AudioTask::ContinueDecoding(InputStream& stream) -> bool {
while (!stream.data().empty()) {
OutputStream writer{codec_buffer_.get()};
auto res = codec_->ContinueStream(stream.data(), writer.data());
auto res =
codec_->ContinueStream(stream.data(), writer.data_as<sample::Sample>());
stream.consume(res.first);
@ -266,7 +268,7 @@ auto AudioTask::ContinueDecoding(InputStream& stream) -> bool {
return false;
}
} else {
writer.add(res.second->bytes_written);
writer.add(res.second->samples_written * sizeof(sample::Sample));
InputStream reader{codec_buffer_.get()};
SendToSink(reader);
@ -295,12 +297,12 @@ auto AudioTask::FinishDecoding(InputStream& stream) -> void {
InputStream padded_stream{mad_buffer.get()};
OutputStream writer{codec_buffer_.get()};
auto res = codec_->ContinueStream(stream.data(), writer.data());
auto res = codec_->ContinueStream(stream.data(), writer.data_as<sample::Sample>());
if (res.second.has_error()) {
return;
}
writer.add(res.second->bytes_written);
writer.add(res.second->samples_written * sizeof(sample::Sample));
InputStream reader{codec_buffer_.get()};
SendToSink(reader);

@ -117,11 +117,18 @@ auto I2SAudioOutput::AdjustVolumeDown() -> bool {
auto I2SAudioOutput::PrepareFormat(const StreamInfo::Pcm& orig)
-> StreamInfo::Pcm {
/*
return StreamInfo::Pcm{
.channels = std::min<uint8_t>(orig.channels, 2),
.bits_per_sample = std::clamp<uint8_t>(orig.bits_per_sample, 16, 32),
.sample_rate = std::clamp<uint32_t>(orig.sample_rate, 8000, 96000),
};
*/
return StreamInfo::Pcm{
.channels = std::min<uint8_t>(orig.channels, 2),
.bits_per_sample = 16,
.sample_rate = 48000,
};
}
auto I2SAudioOutput::Configure(const StreamInfo::Pcm& pcm) -> void {

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save