Giter Club home page Giter Club logo

libsamplerate's Introduction

libsndfile

C/C++ CI

libsndfile is a C library for reading and writing files containing sampled audio data.

Authors

The libsndfile project was originally developed and maintained by Erik de Castro Lopo [email protected] aka @erikd. The project was developed on Github at https://github.com/erikd/libsndfile.

After the release of version 1.0.30, @erikd transferred the project to the libsndfile team, see AUTHORS for details.

Hacking

The canonical source code repository for libsndfile is at https://github.com/libsndfile/libsndfile.

You can grab the source code using:

git clone https://github.com/libsndfile/libsndfile.git

For building for Android see BuildingForAndroid.

There are currently two build systems: the traditional GNU autotool based one and modern CMake based build system. Use of the CMake build system is documented below.

Setting up a build environment for libsndfile on Debian or Ubuntu is as simple as:

sudo apt install autoconf autogen automake build-essential libasound2-dev \
  libflac-dev libogg-dev libtool libvorbis-dev libopus-dev libmp3lame-dev \
  libmpg123-dev pkg-config python

For other Linux distributions or any of the *BSDs, the setup should be similar although the package install tools and package names may be slightly different.

Similarly on Mac OS X, assuming brew is already installed:

brew install autoconf autogen automake flac libogg libtool libvorbis opus mpg123 pkg-config

Once the build environment has been set up, building and testing libsndfile is as simple as:

autoreconf -vif
./configure --enable-werror
make
make check

The CMake build system

Although Autotools is the primary and recommended build toolchain, CMake meta build generator is also available. The build process with CMake takes place in two stages. First, standard build files are created from configuration scripts. Then the platform's native build tools are used for the actual building. CMake can produce Microsoft Visual Studio project and solution files, Unix Makefiles, Xcode projects and many more.

Some IDE support CMake natively or with plugins, check you IDE documentation for details.

Requirements

  1. C99-compliant compiler toolchain (tested with GCC, Clang and Visual Studio 2015)
  2. CMake 3.1.3 or newer

There are some recommended packages to enable all features of libsndfile:

  1. Ogg, Vorbis and FLAC libraries and headers to enable these formats support
  2. ALSA development package under Linux to build sndfile-play utility
  3. Sndio development package under BSD to build sndfile-play utility

Building from command line

CMake can handle out-of-place builds, enabling several builds from the same source tree, and cross-compilation. The ability to build a directory tree outside the source tree is a key feature, ensuring that if a build directory is removed, the source files remain unaffected.

mkdir CMakeBuild
cd CMakeBuild

Then run cmake command with directory where CMakeLists.txt script is located as argument (relative paths are supported):

cmake ..

This command will configure and write build script or solution to CMakeBuild directory. CMake is smart enough to create Unix makefiles under Linux or Visual Studio solution if you have Visual Studio installed, but you can configure generator with -G command line parameter:

cmake .. -G"Unix Makefiles"

The build procedure depends on the selected generator. With "Unix Makefiles" you can type:

make & make install

With "Visual Studio" and some other generators you can open solution or project from CMakeBuild directory and build using IDE.

Finally, you can use unified command:

cmake --build .

CMake also provides Qt-based cross platform GUI, cmake-gui. Using it is trivial and does not require detailed explanations.

Configuring CMake

You can pass additional options with /D<parameter>=<value> when you run cmake command. Some useful system options:

  • CMAKE_C_FLAGS - additional C compiler flags
  • CMAKE_BUILD_TYPE - configuration type, DEBUG, RELEASE, RELWITHDEBINFO or MINSIZEREL. DEBUG is default
  • CMAKE_INSTALL_PREFIX - build install location, the same as --prefix option of configure script

Useful libsndfile options:

  • BUILD_SHARED_LIBS - build shared library (DLL under Windows) when ON, build static library otherwise. This option is OFF by default.

  • BUILD_PROGRAMS - build libsndfile's utilities from programs/ directory, ON by default.

  • BUILD_EXAMPLES - build examples, ON by default.

  • BUILD_TESTING - build tests. Then you can run tests with ctest command, ON by default. Setting BUILD_SHARED_LIBS to ON disables this option.

  • ENABLE_EXTERNAL_LIBS - enable Ogg, Vorbis, FLAC and Opus support. This option is available and set to ON if all dependency libraries were found.

  • ENABLE_MPEG - MP3 support. This option is available and set to ON if all dependency libraries were found.

  • ENABLE_BOW_DOCS - enable black-on-white documentation theme, OFF by default.

  • ENABLE_EXPERIMENTAL - enable experimental code. Don't use it if you are not sure. This option is OFF by default.

  • ENABLE_CPACK - enable CPack support. This option is ON by default.

  • ENABLE_PACKAGE_CONFIG - generate and install package config file.

  • INSTALL_PKGCONFIG_MODULE - generate and install pkg-config module.

  • INSTALL_MANPAGES - install man pages for programs. This option is ON by default

  • ENABLE_STATIC_RUNTIME - enable static runtime on Windows platform (MSVC and MinGW), OFF by default.

    Note: For MSVC compiler this option is deprecated for CMake >= 3.15, see policy CMP0091. Use CMAKE_MSVC_RUNTIME_LIBRARY option instead.

    Note: For MinGW toolchain this option is experimental. If you enabled it and then disabled again, you need to clear CMake cache (delete CMakeCache.txt).

  • ENABLE_COMPATIBLE_LIBSNDFILE_NAME - set DLL name to libsndfile-1.dll (canonical name) on Windows platform, sndfile.dll otherwise, OFF by default. Library name can be different depending on platform. The well known DLL name on Windows platform is libsndfile-1.dll, because the only way to build Windows library before was MinGW toolchain with Autotools. This name is native for MinGW ecosystem, Autotools constructs it using MinGW platform rules from sndfile target. But when you build with CMake using native Windows compiler, the name is sndfile.dll. This is name for native Windows platform, because Windows has no library naming rules. It is preferred because you can search library using package manager or CMake's find_library command on any platform using the same sndfile name.

  • ENABLE_SSE2 - add compiler flag to enable SSE2 if required, ON by default.

    This option is for X86 and GCC compatible compilers configurations only.

    If you compile for other SIMD set, e.g. AVX2, you may want to set ENABLE_SSE2 to OFF.

    Note: This option is not active for X64 configuration, because SSE2 is always available in this mode and all optimizations are enabled by default.

Deprecated options:

  • DISABLE_EXTERNAL_LIBS - disable Ogg, Vorbis and FLAC support. Replaced by ENABLE_EXTERNAL_LIBS
  • BUILD_STATIC_LIBS - build static library. Use BUILD_SHARED_LIBS instead

Linking from CMake projects

First you need to add FindOgg.cmake, FindVorbis.cmake, FindFLAC.cmake and FindOpus.cmake files to some directory inside your CMake project (usually cmake) and add it to CMAKE_MODULE_PATH:

project(SomeApplication)

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

Now you can search libsndfile library from your CMakeLists.txt with this command:

find_package(SndFile)

SndFile_FOUND is set to ON when library is found.

If libsndfile dependency is critical, you can add REQUIRED to find_package:

find_package(SndFile REQUIRED)

With with option find_package will terminate configuration process if libsndfile is not found.

You can also add version check:

find_package(SndFile 1.0.29)

find_package will report error, if libsndfile version is < 1.0.29.

You can combine REQUIRED and version if you need.

To link libsndfile library use:

target_link_libraries(my_application PRIVATE SndFile::sndfile)

Notes for Windows users

System CRT library

First advice about Visual Studio system CRT libraries, it is system code linked as static or dynamic library to every C application.

You can find related option in Visual Studio project properties:

C/C++ -> Code Generation -> Runtime Library

Dynamic version of system CRT library is default and it means that end user needs to have the same runtime library installed on his system. Most likely it is so, but if it is not, the user will see this error message using libsndfile DLL:

"The program can't start because <crt-dll-name>.dll is missing from your computer. Try reinstalling the program to fix this problem. "

To avoid this, you may want to enable static CRT library linking. In this case the size of your DLL will increase slightly the size will increase slightly, but you can redistribute the libsndfile DLL without having to install the correct version of the system CRT library.

CMake project will use dynamic system CRT libraries by default, just like Visual Studio does. But you can change it using ENABLE_STATIC_RUNTIME or CMAKE_MSVC_RUNTIME_LIBRARY options.

Note: You cannot use both options at the same time, it will lead to a configuration error.

If you have CMake >= 3.15 you should use CMAKE_MSVC_RUNTIME_LIBRARY option.

This will enable static linking:

cmake .. -D"MultiThreaded$<$<CONFIG:Debug>:Debug>"

You can use libsndfile ENABLE_STATIC_RUNTIME option to to control CRT library linking for CMake project: OFF or unset (default) for dynamic, and ON for static linking:

cmake .. -DENABLE_STATIC_RUNTIME=ON

Note: This option is deprecated and may be removed in far future because we have standard option CMAKE_MSVC_RUNTIME_LIBRARY now.

Using Vcpkg package manager

Second advice is about Ogg, Vorbis FLAC and Opus support. Searching external libraries under Windows is a little bit tricky. The best way is to use Vcpkg.

Install Vcpkg and then add this parameter to cmake command line:

-DCMAKE_TOOLCHAIN_FILE=<path-to-vcpkg>/scripts/buildsystems/vcpkg.cmake

You also need to set VCPKG_TARGET_TRIPLET if you want to use static libraries:

-DVCPKG_TARGET_TRIPLET=x64-windows-static

Then you need to install static libogg, libvorbis, libflac, libopus, mpg123 and mp3lame Vcpkg packages.

After 1.1.0beta2 you don't need to install dependencies manually. Libsndfile now supports Vcpkg manifest mode and all dependencies are installed automatically.

However, you can turn off the manifest mode and return to the classic mode using the VCPKG_MANIFEST_MODE parameter from the command line:

-DVCPKG_MANIFEST_MODE=OFF

In classic mode, you need to install the required libraries manually:

vcpkg install libvorbis:x64-windows-static libflac:x64-windows-static
opus:x64-windows-static mp3lame:x86-windows-static mpg123:x86-windows-static
libvorbis:x86-windows-static libflac:x86-windows-static
opus:x86-windows-static mp3lame:x86-windows-static mpg123:x86-windows-static

Note: Use must use the same CRT library for external libraries and the libsndfile library itself. For *-static triplets Vcpkg uses static CRT.

Submitting Patches

See CONTRIBUTING.md for details.

libsamplerate's People

Contributors

balazskiss avatar bclswl0827 avatar be-ing avatar bobo1239 avatar brad0 avatar coypoop avatar danra avatar djmaster avatar enzo1982 avatar erikd avatar evpobr avatar flamefire avatar glynternet avatar gnu-srs avatar hoyes avatar jackz314 avatar janstary avatar jerpelea avatar jpaasen avatar jrlanglois avatar milasudril avatar physsong avatar rfomin avatar sezero avatar soapgentoo avatar stefan-balke avatar talaviram avatar umlaeute avatar uniontech-lilinjie avatar varikvalefor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libsamplerate's Issues

src_simple does not produce any output for small ratios with SRC_SINC_*

Documenting bug found in #87:

When a ratio smaller or equal to 1/214 is used with src_simple and one of the SINC converters no output is produced no matter how big the input is.

Code reproducing this:

static void
src_simple_produces_output_test (int converter, int channels, double src_ratio)
{	
	// Choose a suitable number of frames.
        // Here set to something VERY high to prove the point, do not use for unit tests!
	const long NUM_FRAMES = 100000000;
	int error;
	
	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. Converter=%d, channels = %d, ratio=%g\n\n", __LINE__, converter, channels, src_ratio) ;
		exit (1) ;
		} ;
	if (src_data.output_frames_gen == 0)
	{	printf ("\n\nLine %d : No output frames generated. Converter=%d, channels = %d, ratio=%g\n\n", __LINE__, converter, channels, src_ratio) ;
		exit (1) ;
		} ;
	free(input);
	free(output);
}

// Call
src_simple_produces_output_test(SRC_SINC_FASTEST, 1, 1./214);
// Output: No output frames generated. Converter=2, channels = 1, ratio=0.0046729

Using the advanced method (repeatable callingsrc_process with chunks of the input) the first output sample for a ratio of 1/215 is produced after about 4992 input frames, so the transport delay does not seem to be the cause. Also increasing the input frame count does not change anything.

Possible cause (from most likely to least likely):

Cut new release

Hi @erikd
in order to fix the resample collision problem in Gentoo, could you please issue a new tarball for libsamplerate?
Thanks!

Duplicate frame in output with src_ratio = 1.0

I have a simple array of floats containing a sequence of numbers such as 1.0, 2.0, 3.0, ... 64.0 I want to process through libsamplerate. Surprisingly, when the ratio is set to 1.0, the first frame in the output buffer is duplicated, that is 1.0, 1.0, 2.0, 3.0, ... instead of the expected 1.0, 2.0, 3.0, 4.0, ....

I'm using libsamplerate 0.1.9 on Debian Stretch, GCC 6.3.0 (64 bit arch). I'm pretty sure there is something wrong on my side, even if I have triple checked it so far. Or maybe it is the expected behavior? Full code below:

#include <samplerate.h>
#include <cstdio>


int main()
{
	SRC_STATE* rsmp_state;
	SRC_DATA   rsmp_data;

	const int IN_FRAMES  = 64;
	const int OUT_FRAMES = 32;

	float* in  = new float[IN_FRAMES];
	float* out = new float[OUT_FRAMES];

	for (int i = 0; i < IN_FRAMES; i++)
		in[i] = (float) i + 1;

	rsmp_state = src_new(SRC_LINEAR, 1, nullptr);

	rsmp_data.data_in       = in; 
	rsmp_data.input_frames  = IN_FRAMES; 
	rsmp_data.data_out      = out; 
	rsmp_data.output_frames = OUT_FRAMES;
	rsmp_data.end_of_input  = false;
	rsmp_data.src_ratio     = 1.0;

	src_process(rsmp_state, &rsmp_data);

	//for (int i = 0; i < IN_FRAMES; i++)  printf("%d) %f\n", i, in[i]);
	for (int i = 0; i < OUT_FRAMES; i++) printf("%d) %f\n", i, out[i]);

	src_delete(rsmp_state);
	delete in;
	delete out;
}

Potential Bad memory access bug

Hi Erik,

I have written a self-contained test to display the problem we are seeing in our project that uses libsamplerate to do sample rate conversions. I have attached the entire libsamplerate directory along with my changes here. Additionally, I have also written up a brief description of the issue and my test below.
I would like to understand if this is indeed a potential bug or an improper use of the library. Looking forward to your thoughts.

Thanks,
Hari

Description:

Our project code follows the model in callback_test.c (ie: setup a callback using src_callback_new() with converter = SRC_SINC_FASTEST, numChannels = 32; calls to src_callback_read() till the requested # of samples are read).

We have discovered an intermittent issue where the audio data we receive after a call to src_callback_read() contains Nan values in the output buffer at a valid index (ie: within the total read samples returned by src_callback_read()). We traced this down to the calc_output_multi() function which is called by sinc_multichan_vari_process() in src_sinc.c. Specifically, in the scenarios where the issue happens, the data_index that calc_output_multi() calculates when applying the left half of the filter evaluates to a negative value (which leads to accessing uninitialized/unowned memory).


To simplify this, I have written a short self-contained test (called filterdata_integrity_test.c) under the tests directory. This test is similar to callback_test.c, ie: it sets up a callback using src_callback_new() with converter = SRC_SINC_FASTEST, numChannels = 2 (for simplicity); calls to src_callback_read() till the requested # of samples are read). The notable differences from my test and callback_test.c are:
i) Setting the src_ratio to a different value on every callback (by calling src_set_ratio()) -> this replicates the scenario in our project when the issue occurs
ii) Adding integrity checks on the audio data that is generated in the output buffer
All of the relevant changes also have comments next to them.

Note: I have also made an un-invasive change to src/src_sinc.c at line 437 to exit(1) whenever the data_index hits a negative value in calc_output_stereo() (since this is the only way I have found to catch the issue when it happens). I hit this exit every time I run the filterdata_integrity_test.

libsamplerate-0.1.8.zip

export SRC_STATE size?

I'd like to save and restore SRC_STATE, so I can rerender a resampled output incrementally. For this, I think I just need to know the size of SRC_STATE, then I can use memcpy to serialize and deserialize. So I think a new src_size method is needed. But I could use that to redo src_clone, from commit 945b993, in a generic way and get rid of those individual *_copy functions.

Any interest in a PR? Or is this already possible?

cmake: cpack picks wrong version number

As noted in title: make package_source with cmake generates libsamplerate-0.1.1-Source.tar.gz
Notice 0.1.1 instead of current 0.1.9. I don't know if this facility is actually meant to be used
but still.. This is with cmake-3.9.6.

BUILD SHARED_LIBS and CMAKE_BUILD_TYPE menus not available with cmake-gui

Is that intentional? Maybe you need something like the following in CMakeLists.txt?

IF (NOT DEFINED CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "")
    MESSAGE(STATUS "Setting build type to 'Debug' as none was specified.")
    SET(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
    SET_PROPERTY(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
ENDIF ()
SET(CMAKE_CONFIGURATION_TYPES "${CMAKE_BUILD_TYPE}")
MESSAGE(STATUS "Build Type: ${CMAKE_BUILD_TYPE}")

OPTION(BUILD_SHARED_LIBS "Build dynamic library" OFF)

Missing points at the last buffer

To start off, thank you so much for the great tool, erikd!

But I have found an issue and, after some trials-and-errors, came up with a simple solution. I would like to share---

When src_process is called multiple times with a connected set of buffers, the last half_filter_chan_len points from the input buffer are not processed. In other words, you will lose these data points (which was 47 samples when I tried with SRC_SINC_MEDIUM_QUALITY, see below). This is because the while loop on line 375 in src_sinc.c breaks when filter->out_gen equals filter->out_count. Logically it makes sense, except that it should further generate output (half_filter_chan_len points more) for the very last buffer, because the processing of the very first buffer was done for filter->out_count MINUS half_filter_chan_len.

To resolve this issue, I am simply changing line 375 to while (1) and let the separate termination check do the work (lines 390 and 393). And I am making sure, in my application, to allocate the data_out buffer big enough to absorb this in addition to the expected output buffer size.

The same logic should apply to other functions--sinc_stereo_vari_process, sinc_quad_vari_process, sinc_hex_vari_process, and sinc_multichan_vari_process, but I'm not using them and I can't check this issue in these functions. I would let others do it. But this change works well for my application, auxlab, so I'm using my own hacked version of libsamplerate for auxlab for now (as of 3/20/2019).

The easiest way to replicate the issue is the following:

float * buffer_in = (float*)calloc(sizeof(float), 10000); // input buffer size is 10000 points
float * buffer_out = (float*)calloc(sizeof(float), 10000); // output is the same size; testing src_ratio = 1
// prepare the buffer
int errcode;
SRC_STATE* handle = src_new(SRC_SINC_MEDIUM_QUALITY, 1, &errcode);
SRC_DATA data;
data.src_ratio = 1;
data.data_in = buffer_in;
data.data_out = buffer_out;
data.input_frames = 5000; // half the buffer
data.output_frames = 5000; 
data.end_of_input = 0; 
errcode = src_process(handle, &data); // processing the first half
//after the call, 
//data.input_frames_used was 5000 but
//data.output_frames_gen was 4953, which is 5000 minus half_filter_chan_len in src_sinc.c
data.data_in = buffer_in + data.input_frames_used ;
data.data_out = buffer_out + data.output_frames_gen;
data.end_of_input = 1; 
errcode = src_process(handle, &data); // processing the second half
//Now you get 
//data.input_frames_used would be still 5000 (i.e., all input buffer has been read)
//data.output_frames_gen would be 5000. And, this is not right. We should have gotten 5047 points.

This hack will get you all the output data, without missing the last 47 points.
Hope this helps.

Win compilation error

When compiling on windows I get the following warning and errors:

.\examples\audio_out.c(715): warning C4133: 'return': incompatible types - from 'WIN32_AUDIO_OUT *' to 'AUDIO_OUT *'
.\examples\audio_out.c(826): error C2065: 'sample_count': undeclared identifier
.\examples\audio_out.c(827): error C2065: 'sample_count': undeclared identifier
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\cl.exe"' : return code '0x2'

I looked that the lines of code in audio_out.c and couldn't find an obvious error. I think I may be missing some header file but can't figure it out.

[docu] src_callback_read result on error documented inconsistently

For the function src_callback_read the documentation on what is reported on error is inconsistent.

Using -1 for error makes that case distinguishable from "no more input", however I guess at that point it might be a breaking change. So I guess the documentation in the header should be updated and maybe tests for the error cases added to avoid possible confusion

src_process rejects data_in = NULL even when input_frames = 0

Hi Erik,

I found that src_process throws an error when called with data_in = NULL and input_frames = 0.

I was calling it like that with end_of_input set to finish a resampling process. I think it's a bit unintuitive that this doesn't work and the documentation also does not indicate that it might be forbidden.

A work-around is to set data_in to a dummy value like (float *) 1 in the special case of finishing the resampling process with no more frames to resample.

So my suggestion is to accept data_in = NULL when input_frames = 0 or, alternatively, mention in the API docs that data_in must not be NULL even when passing no input frames. I think just accepting NULL in this case would be the better solution, though.

Here is an example program that illustrates the issue: finish-test.c.gz

Thanks,
Robert

C++ wrapper

I was considering to write a C++ wrapper for the C classes for our project to slightly ease the use.

Is there some interest to have this in the upstream project as e.g. libsamplerate.hpp with some tests? @erikd

It would be:

  • wrapper around SRC_STATE with copy/move operators (C++11 required)
  • overloads for src_short_to_float_array and friends as to_float_array and from_float_array

Doc omission regarding `src_process`

https://github.com/erikd/libsamplerate/blob/master/src/samplerate.h#L86

Doc is here: http://www.mega-nerd.com/SRC/api_simple.html

Documentation doesn't mention what happens if the output buffer is not big enough to hold the samplerate-converted input buffer.

It isn't certain if this will return an error or simply fill the output buffer, correctly making a note of how many input samples have been consumed in the data structure.

It would be very helpful to have this documented, as it would save a development test-cycle.

Stale library versions?

Compiling 0.1.9 says

/bin/sh ../libtool  --tag=CC   --mode=link /usr/bin/clang  -pipe -Os -arch x86_64 -std=gnu99 -W -Wstrict-prototypes -Wmissing-prototypes  -Waggregate-return -Wcast-align -Wcast-qual -Wnested-externs -Wshadow -Wpointer-arith -pipe -no-undefined -version-info 1:8:1  -L/opt/local/lib -Wl,-headerpad_max_install_names -arch x86_64 -o libsamplerate.la -rpath /opt/local/lib samplerate.lo src_sinc.lo  src_zoh.lo src_linear.lo  -lm -lm

What is -version-info 1:8:1?

It also says

libtool: link: /usr/bin/clang -dynamiclib  -o .libs/libsamplerate.0.dylib  .libs/samplerate.o .libs/src_sinc.o .libs/src_zoh.o .libs/src_linear.o   -L/opt/local/lib -lm  -Os -arch x86_64 -Wl,-headerpad_max_install_names -arch x86_64   -install_name  /opt/local/lib/libsamplerate.0.dylib -compatibility_version 2 -current_version 2.8 -Wl,-single_module^M^M

What is -compatibility_version 2?

Tags

Hi Erik,

thanks for this great lib!

I'd like to make it easier to ship with tools like anaconda and python.

It would be nice, if you could tag the commit which represents the current version
so that I can refer to it while building.

Thanks Stefan

Speed question

Are you considering for libsamplerate use of hardware instructions we can find in modern processors (SIMD) / GPUs? This can greatly affect the speed of resampling.
Will this impact on library precision?

./configure --enable-option-checking uses unknown options

This is 0.1.9 on MacOS 10.13.2.
Turning on --enable-option-checking as the only arg to ./configure says:

/Users/hans/src/libsamplerate-0.1.9/Cfg/missing: Unknown `--is-lightweight' option
Try `/Users/hans/src/libsamplerate-0.1.9/Cfg/missing --help' for more information
configure: WARNING: 'missing' script is too old or missing

Also, it continues to run, instead of exiting on an unknown option.

Issue with make_filter.m generating "newer" fastest_coeffs.h

I re-ran the make_filter.m Octave script with f = make_filter (8, 128, 100.3)
I am using octave-6.1.0-w64-installer.exe for Windows.
When I replaced the newly-generated coefficients into fastest_coeffs.h and recompile, I am getting far worse results than the original fastest coefficients.
I have a test .wav file with two tones (400Hz and 700Hz) sampled at 8000 samples/second. When I run this through the resampler app (using -c 2 -to 16000) I get great results with the old coefficients but the newly-generated coefficients produce significant artifacts/harmonics near the high end frequency spectrum. The ONLY thing changed is the coefficient table.
I'm assuming that changes may have been made to the octave scripts since the original fastest coefficient table was generated, and these changes may be causing this issue. Since there's no history in the repo for the octave scripts (that I can see), I can't try older octave scripts to see if I can reproduce the older coefficients.
I've attached the newly-generated coefficients from the octave scripts.
fast-new.txt

Compiler Warning: Redifinition of MIN and MAX macros

I'm getting a 'macro redefinition' compiler warning when including libsamplerate.

One of the system libraries I include (macOS 10.14/usr/include/sys/param.h) redefines MIN and MAX:

/* Macros for min/max. */
#ifndef MIN
#define MIN(a, b) (((a)<(b))?(a):(b))
#endif /* MIN */
#ifndef MAX
#define MAX(a, b) (((a)>(b))?(a):(b))
#endif  /* MAX */

How about doing the same inside this library?

os x failure

yIDType DEPRECATED_IN_MAC_OS_X_VERSION_10_6_AND_LATER;
^
In file included from audio_out.c:435:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Carbon.framework/Versions/A/Headers/Carbon.h:67:
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Carbon.framework/Frameworks/Ink.framework/Headers/Ink.h:200:51: error: expected ';' after top level
declarator
typedef struct OpaqueInkTextRef* InkTextRef DEPRECATED_IN_MAC_OS_X_VERSION_10_14_AND_LATER;
^
;

Include Octave scripts used to generate filter coeffs

The filter coeffs in src/*_coeffs.h seem to be generated by some GNU Octave scripts. Comments list the functions and parameters used like:

f = make_src_filter (cycles = 69, incr = 2381, atten = 160.000000)

The Octave files, however, are excluded from this repository in .gitignore even though there are commits referencing them, like 87992ca.

It would be great if the scripts could be included in this repo.

float_to_short_test fails on PowerPC running OpenBSD

This is current git on OpenBSD 6.5/macppc (meaning powerpc).
Running 'make check' fails with the following:

tests/float_short_test

   float_to_short_test .............................
   Line 64 : out [1] == -1

*** Error 1 in /home/hans/src/libsamplerate (Makefile:1877 'check')

AUDIO_OUT related compilation failure

When compiling on linux with ALSA, I get the following errors:

audio_out.c: In function ‘audio_play’:
audio_out.c:1014:16: error: dereferencing pointer to incomplete type ‘AUDIO_OUT {aka struct AUDIO_OUT_s}’
   if (audio_out->magic == ALSA_MAGIC)
                ^~

Const-correctness?

Is this OK:

SRC_DATA data{};
data.data_in=const_cast<float*>(buffer_in);

That is, can I be sure that the library does not touch buffer_in? If so add const, or at least annotate that in the documentation.

fftw3 not found

./configure does not find fftw3, because configure.ac wants
PKG_CHECK_MODULES(FFTW3, fftw3 >= 0.15.0, ac_cv_fftw3=1, ac_cv_fftw3=0)

What is 0.15.0 of fftw3? It installs fftw 3.x.y, obviously.

Why do we require a certain version in the first place?

Include version in public header

It would be helpful for consumers to know the version of the library during compilation.

So I propose to define at least LIBSAMPLERATE_VERSION in samplerate.h.

A good way done by other projects is to have _VERSION a string, and _VERSION_[MAJOR|MINOR|PATCH] as 3 additional defines.

Examples: https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core/version.hpp or https://github.com/esp8266/Arduino/blob/master/tools/sdk/include/version.h

Boost uses a single number: https://www.boost.org/doc/libs/1_70_0/boost/version.hpp

Example uses:

#ifndef LIBSAMPLERATE_VERSION_MAJOR
  code for pre 0.1.10
#elif LIBSAMPLERATE_VERSION_MAJOR >=1
  code for 1.x
#elif ...

Require C99 compiler also in CMake

The autoconf already requires a C99 compiler. I suggest to do the same for CMake which simplifies the code, config and removes the whole float_convert header.

Deprecated Visual Studio Code building

Hello,
I tried to make the files following the instructions here
However it doesn't work, providing a modern VC path seems to give troubles.
Tried to modify the PROG_LINK_FLAGS variable by fixing manually some headers (it couldn't find stdio.h for instance, so I provided it from MinGW), but it doesn't seem to recognize it.
Isn't there a more modern way to build all this ?

condition for using Version_script and the win32 def file

Our current configure.ac checks gcc (and only gcc) being the compiler
when deciding whether to use Version_script or the win32 def file:
https://github.com/libsndfile/libsamplerate/blob/master/configure.ac#L265

However, the linker should be one checked. Do you think the following
is correct: @SoapGentoo, @evpobr? If it is I can make a PR for it.

diff --git a/configure.ac b/configure.ac
index 0e2117c..4691e09 100644
--- a/configure.ac
+++ b/configure.ac
@@ -260,14 +260,13 @@ AS_IF([test "x$enable_werror" = "xyes"], [
 AX_APPEND_COMPILE_FLAGS([-W -Wstrict-prototypes -Wmissing-prototypes -Wall -Waggregate-return -Wcast-align -Wcast-qual -Wnested-externs -Wshadow -Wpointer-arith], [CFLAGS])
 
 dnl ====================================================================================
-dnl  GCC stuff.
+dnl  Exported symbols control.
 
-AS_IF([test "x$ax_cv_c_compiler_vendor" = "xgnu"], [
-		# OS specific tweaks.
+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"],
-			[linux*|kfreebsd*-gnu*|gnu*], [
+			[*], [
 				SHLIB_VERSION_ARG="-Wl,--version-script=\$(top_builddir)/src/Version_script"
 			])
 	])

BUG: Use C99 flexible arrays instead of type[1] trailing member

Related to #68 as it requires C99 (although C99 features are already used)

C99 flexible arrays are used at some points, e.g.: https://github.com/erikd/libsamplerate/blob/2647fd9bac5f11f24b5f1ee55806671f81520f66/src/src_sinc.c#L57

At other the idiom of having a trailing float[1] member is used: https://github.com/erikd/libsamplerate/blob/2647fd9bac5f11f24b5f1ee55806671f81520f66/src/src_linear.c#L34

A SO answer highly recommends using the C99 feature: https://stackoverflow.com/a/247040/1930508 with a comment that using float[1] may produce incorrect code: https://lkml.org/lkml/2015/2/18/407

Furthermore to much memory is allocated (1 additional float): https://github.com/erikd/libsamplerate/blob/2647fd9bac5f11f24b5f1ee55806671f81520f66/src/src_linear.c#L174

Bottom line:

  • Require C99 compiler
  • Use flexible arrays instead of trailing float[1]

The autoconf in 0.1.9 dose not support aarch64

The config.sub and config.guess should be updated to include aarch64 in 0.1.9 since I cannot see that these files are included in the repo I guess they are copied from somewhere. When looking through my host machine I located them under /usr/share/misc and they do include aarch64.

Undefined behavior due to shifts on signed integers

As found in #65 (comment) using bit shifts on signed integers is undefined behavior. Reason for that is the difference between a "regular shift" (shr) and "arithmetic shift" (sar) where the former just shifts bits while the latter preserves the sign bit in all cases. Also there is a rounding difference for positive and negative numbers.

Examples:

-1 = b11111111
-1 shr 1 = b01111111 = 127
-1 sar 1 = b11111111 = -1

-10 sar 2 = -3
10 sar 2 = 2

This may not be a problem in practice as usually int >> value is translated to sar but I found 1 compiler where it is translated to shr: https://godbolt.org/z/sj_uO6

Not sure if/how to solve this as i >> value is meant as floor(i/2^value) while (int)(i/2^value) is trunc(i/2^value) and hence cannot be "optimized" to a shift.

examples/audio_out.c fails on newer MacOS

examples/audio_out.c fails to build on MacOS 10.13.2,
because it includes Carbon.h which does not exist.
Apparently, the MacOS audio subsystem has changed again
(to proactively leverage the synergy of the frameworks).

src_process fails to properly handle chunked input

There is a bug when using src_process with sufficiently small chunks of input data. Although the result of passing the input data in chunks should be exactly the same as when passing them as 1 block the test shows that this is not the case and NO output is generated. See #87 for a reproducer.

This seems to be the issue that was discussed at #55 but now can be reproduced using (IMO) valid code: It sets the end_of_input once it got the final samples but the output_frames_gen is still zero.

Make CMake tests and install directives optional

When using libsamplerate via CMake and as a submodule, all targets related to tests/examples clog up generated workspace. It should be make optional f.i. with:

option(LIBSAMPLERATE_TESTS OFF "Enable to generate test targets)

Same applies to install(...) directives.

global buffer overflow in calc_output_single (src_sinc.c)

On 0.1.8:

# sndfile-resample -to 24000 -c 1 $FILE out
==13807==ERROR: AddressSanitizer: global-buffer-overflow on address 0x7f44bc709a3c at pc 0x7f44bc6b1d6b bp 0x7fffec8f5e20 sp 0x7fffec8f5e18                                                                       
READ of size 4 at 0x7f44bc709a3c thread T0                                                                                                                                                                        
    #0 0x7f44bc6b1d6a in calc_output_single /tmp/portage/media-libs/libsamplerate-0.1.8-r1/work/libsamplerate-0.1.8/src/src_sinc.c:296:48                                                                         
    #1 0x7f44bc6b1d6a in sinc_mono_vari_process /tmp/portage/media-libs/libsamplerate-0.1.8-r1/work/libsamplerate-0.1.8/src/src_sinc.c:400                                                                        
    #2 0x7f44bc6a3659 in src_process /tmp/portage/media-libs/libsamplerate-0.1.8-r1/work/libsamplerate-0.1.8/src/samplerate.c:174:11                                                                              
    #3 0x51369a in sample_rate_convert /tmp/portage/media-libs/libsamplerate-0.1.8-r1/work/libsamplerate-0.1.8/examples/sndfile-resample.c:221:16                                                                 
    #4 0x51369a in main /tmp/portage/media-libs/libsamplerate-0.1.8-r1/work/libsamplerate-0.1.8/examples/sndfile-resample.c:163                                                                                   
    #5 0x7f44bb55278f in __libc_start_main /tmp/portage/sys-libs/glibc-2.23-r3/work/glibc-2.23/csu/../csu/libc-start.c:289                                                                                        
    #6 0x419f88 in _init (/usr/bin/sndfile-resample+0x419f88)                                                                                                                                                     
                                                                                                                                                                                                                  
0x7f44bc709a3c is located 0 bytes to the right of global variable 'slow_mid_qual_coeffs' defined in '/tmp/portage/media-libs/libsamplerate-0.1.8-r1/work/libsamplerate-0.1.8/src/mid_qual_coeffs.h:37:3' (0x7f44bc6f3ba0) of size 89756                                                                                                                                                                                             
SUMMARY: AddressSanitizer: global-buffer-overflow /tmp/portage/media-libs/libsamplerate-0.1.8-r1/work/libsamplerate-0.1.8/src/src_sinc.c:296:48 in calc_output_single                                             
Shadow bytes around the buggy address:                                                                                                                                                                            
  0x0fe9178d92f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                                                                                                                                                 
  0x0fe9178d9300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                                                                                                                                                 
  0x0fe9178d9310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                                                                                                                                                 
  0x0fe9178d9320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                                                                                                                                                 
  0x0fe9178d9330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00                                                                                                                                                 
=>0x0fe9178d9340: 00 00 00 00 00 00 00[04]f9 f9 f9 f9 f9 f9 f9 f9                                                                                                                                                 
  0x0fe9178d9350: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9                                                                                                                                                 
  0x0fe9178d9360: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9                                                                                                                                                 
  0x0fe9178d9370: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9                                                                                                                                                 
  0x0fe9178d9380: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9                                                                                                                                                 
  0x0fe9178d9390: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9                                                                                                                                                 
Shadow byte legend (one shadow byte represents 8 application bytes):                                                                                                                                              
  Addressable:           00                                                                                                                                                                                       
  Partially addressable: 01 02 03 04 05 06 07                                                                                                                                                                     
  Heap left redzone:       fa                                                                                                                                                                                     
  Freed heap region:       fd                                                                                                                                                                                     
  Stack left redzone:      f1                                                                                                                                                                                     
  Stack mid redzone:       f2                                                                                                                                                                                     
  Stack right redzone:     f3                                                                                                                                                                                     
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==13807==ABORTING

Reproducer:
https://github.com/asarubbo/poc/blob/master/00262-libsamplerate-globaloverflow-calc_output_single

build instructions for ios

Do you have a guide how to compile this as a fat library for all required ios architectures (x86_64, armv6, armv7, ...)?

Calculate transport delay

It'd be very helpful to know the transport delay that a given converter at a given ratio exhibits.
I'd suggest a function like:

/*
**  Calculate the transport delay (number of samples that are buffered
**  on average) that a given converter exhibits, when resampling at the 
**  specified SRC ratio.
**  Returns the transport delay, measured in output samples.
*/
double src_get_delay (int converter_type, double src_ratio) ;

For the linear and ZOH converters the calculation is very easy (something along 1 + 1/src_ratio if I recall correctly), but I'm not able to come up with an expression for the sinc converters (which are perhaps the most interesting cases, where the transport delay is significant).

semantic versioning regression: `0.1.8` followed by `0.1.0`

Debian/buster (currently "stable") ships with libsamplerate0_0.1.9-2, which includes a dynamic library file:

/usr/lib/x86_64-linux-gnu/libsamplerate.so.0.1.8

compiling the latest and greatest libsamplerate-0.2.0 i get a file:

/usr/lib/x86_64-linux-gnu/libsamplerate.so.0.1.0

This decrements the micro release, which is plain wrong!!

the new libsamplerate also introduces a new symbol src_clone, which would - according to semantic versioning - warrants a:

  • reset of the micro version to 0
  • increment of the minor version to 2

please fix this and make a bugfix release asap.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.