parent
3b240d1cd5
commit
60f7677132
@ -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 @@ |
|||||||
 |
|
||||||
|
|
||||||
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` |  | |
|
||||||
|
|
||||||
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; |
|
||||||
} |
|
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> Erik de Castro 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. |
|
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. |
|
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 */ |
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue