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