Replaces libsamplerate with libspeexdsppull/1639/head
| @@ -14,7 +14,7 @@ ifeq ($(ARCH), lin) | |||||
| LDFLAGS += -rdynamic \ | LDFLAGS += -rdynamic \ | ||||
| -lpthread -lGL -ldl \ | -lpthread -lGL -ldl \ | ||||
| $(shell pkg-config --libs gtk+-2.0) \ | $(shell pkg-config --libs gtk+-2.0) \ | ||||
| -Ldep/lib -lGLEW -lglfw -ljansson -lsamplerate -lcurl -lzip -lrtaudio -lrtmidi | |||||
| -Ldep/lib -lGLEW -lglfw -ljansson -lspeexdsp -lcurl -lzip -lrtaudio -lrtmidi | |||||
| TARGET = Rack | TARGET = Rack | ||||
| endif | endif | ||||
| @@ -23,7 +23,7 @@ ifeq ($(ARCH), mac) | |||||
| CXXFLAGS += -DAPPLE -stdlib=libc++ | CXXFLAGS += -DAPPLE -stdlib=libc++ | ||||
| LDFLAGS += -stdlib=libc++ -lpthread -ldl \ | LDFLAGS += -stdlib=libc++ -lpthread -ldl \ | ||||
| -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo \ | -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo \ | ||||
| -Ldep/lib -lGLEW -lglfw -ljansson -lsamplerate -lcurl -lzip -lrtaudio -lrtmidi | |||||
| -Ldep/lib -lGLEW -lglfw -ljansson -lspeexdsp -lcurl -lzip -lrtaudio -lrtmidi | |||||
| TARGET = Rack | TARGET = Rack | ||||
| BUNDLE = dist/$(TARGET).app | BUNDLE = dist/$(TARGET).app | ||||
| endif | endif | ||||
| @@ -34,7 +34,7 @@ ifeq ($(ARCH), win) | |||||
| -Wl,--export-all-symbols,--out-implib,libRack.a -mwindows \ | -Wl,--export-all-symbols,--out-implib,libRack.a -mwindows \ | ||||
| -lgdi32 -lopengl32 -lcomdlg32 -lole32 \ | -lgdi32 -lopengl32 -lcomdlg32 -lole32 \ | ||||
| -Ldep/lib -lglew32 -lglfw3dll -lcurl -lzip -lrtaudio -lrtmidi \ | -Ldep/lib -lglew32 -lglfw3dll -lcurl -lzip -lrtaudio -lrtmidi \ | ||||
| -Wl,-Bstatic -ljansson -lsamplerate | |||||
| -Wl,-Bstatic -ljansson -lspeexdsp | |||||
| TARGET = Rack.exe | TARGET = Rack.exe | ||||
| OBJECTS = Rack.res | OBJECTS = Rack.res | ||||
| endif | endif | ||||
| @@ -109,7 +109,7 @@ ifeq ($(ARCH), mac) | |||||
| cp dep/lib/libGLEW.2.1.0.dylib $(BUNDLE)/Contents/MacOS/ | cp dep/lib/libGLEW.2.1.0.dylib $(BUNDLE)/Contents/MacOS/ | ||||
| cp dep/lib/libglfw.3.dylib $(BUNDLE)/Contents/MacOS/ | cp dep/lib/libglfw.3.dylib $(BUNDLE)/Contents/MacOS/ | ||||
| cp dep/lib/libjansson.4.dylib $(BUNDLE)/Contents/MacOS/ | cp dep/lib/libjansson.4.dylib $(BUNDLE)/Contents/MacOS/ | ||||
| cp dep/lib/libsamplerate.0.dylib $(BUNDLE)/Contents/MacOS/ | |||||
| cp dep/lib/libspeexdsp.1.dylib $(BUNDLE)/Contents/MacOS/ | |||||
| cp dep/lib/libcurl.4.dylib $(BUNDLE)/Contents/MacOS/ | cp dep/lib/libcurl.4.dylib $(BUNDLE)/Contents/MacOS/ | ||||
| cp dep/lib/libzip.5.dylib $(BUNDLE)/Contents/MacOS/ | cp dep/lib/libzip.5.dylib $(BUNDLE)/Contents/MacOS/ | ||||
| cp dep/lib/librtmidi.4.dylib $(BUNDLE)/Contents/MacOS/ | cp dep/lib/librtmidi.4.dylib $(BUNDLE)/Contents/MacOS/ | ||||
| @@ -118,7 +118,7 @@ ifeq ($(ARCH), mac) | |||||
| install_name_tool -change /usr/local/lib/libGLEW.2.1.0.dylib @executable_path/libGLEW.2.1.0.dylib $(BUNDLE)/Contents/MacOS/Rack | install_name_tool -change /usr/local/lib/libGLEW.2.1.0.dylib @executable_path/libGLEW.2.1.0.dylib $(BUNDLE)/Contents/MacOS/Rack | ||||
| install_name_tool -change lib/libglfw.3.dylib @executable_path/libglfw.3.dylib $(BUNDLE)/Contents/MacOS/Rack | install_name_tool -change lib/libglfw.3.dylib @executable_path/libglfw.3.dylib $(BUNDLE)/Contents/MacOS/Rack | ||||
| install_name_tool -change $(PWD)/dep/lib/libjansson.4.dylib @executable_path/libjansson.4.dylib $(BUNDLE)/Contents/MacOS/Rack | install_name_tool -change $(PWD)/dep/lib/libjansson.4.dylib @executable_path/libjansson.4.dylib $(BUNDLE)/Contents/MacOS/Rack | ||||
| install_name_tool -change $(PWD)/dep/lib/libsamplerate.0.dylib @executable_path/libsamplerate.0.dylib $(BUNDLE)/Contents/MacOS/Rack | |||||
| install_name_tool -change $(PWD)/dep/lib/libspeexdsp.1.dylib @executable_path/libspeexdsp.1.dylib $(BUNDLE)/Contents/MacOS/Rack | |||||
| install_name_tool -change $(PWD)/dep/lib/libcurl.4.dylib @executable_path/libcurl.4.dylib $(BUNDLE)/Contents/MacOS/Rack | install_name_tool -change $(PWD)/dep/lib/libcurl.4.dylib @executable_path/libcurl.4.dylib $(BUNDLE)/Contents/MacOS/Rack | ||||
| install_name_tool -change $(PWD)/dep/lib/libzip.5.dylib @executable_path/libzip.5.dylib $(BUNDLE)/Contents/MacOS/Rack | install_name_tool -change $(PWD)/dep/lib/libzip.5.dylib @executable_path/libzip.5.dylib $(BUNDLE)/Contents/MacOS/Rack | ||||
| install_name_tool -change $(PWD)/dep/lib/librtmidi.4.dylib @executable_path/librtmidi.4.dylib $(BUNDLE)/Contents/MacOS/Rack | install_name_tool -change $(PWD)/dep/lib/librtmidi.4.dylib @executable_path/librtmidi.4.dylib $(BUNDLE)/Contents/MacOS/Rack | ||||
| @@ -146,7 +146,7 @@ ifeq ($(ARCH), win) | |||||
| cp dep/bin/libcurl-4.dll dist/Rack/ | cp dep/bin/libcurl-4.dll dist/Rack/ | ||||
| cp dep/bin/libjansson-4.dll dist/Rack/ | cp dep/bin/libjansson-4.dll dist/Rack/ | ||||
| cp dep/bin/librtmidi-4.dll dist/Rack/ | cp dep/bin/librtmidi-4.dll dist/Rack/ | ||||
| cp dep/bin/libsamplerate-0.dll dist/Rack/ | |||||
| cp dep/bin/libspeexdsp-1.dll dist/Rack/ | |||||
| cp dep/bin/libzip-5.dll dist/Rack/ | cp dep/bin/libzip-5.dll dist/Rack/ | ||||
| cp dep/bin/librtaudio.dll dist/Rack/ | cp dep/bin/librtaudio.dll dist/Rack/ | ||||
| mkdir -p dist/Rack/plugins | mkdir -p dist/Rack/plugins | ||||
| @@ -161,7 +161,7 @@ ifeq ($(ARCH), lin) | |||||
| mkdir -p dist/Rack | mkdir -p dist/Rack | ||||
| cp -R LICENSE* res dist/Rack/ | cp -R LICENSE* res dist/Rack/ | ||||
| cp Rack Rack.sh dist/Rack/ | cp Rack Rack.sh dist/Rack/ | ||||
| cp dep/lib/libsamplerate.so.0 dist/Rack/ | |||||
| cp dep/lib/libspeexdsp.so dist/Rack/ | |||||
| cp dep/lib/libjansson.so.4 dist/Rack/ | cp dep/lib/libjansson.so.4 dist/Rack/ | ||||
| cp dep/lib/libGLEW.so.2.1 dist/Rack/ | cp dep/lib/libGLEW.so.2.1 dist/Rack/ | ||||
| cp dep/lib/libglfw.so.3 dist/Rack/ | cp dep/lib/libglfw.so.3 dist/Rack/ | ||||
| @@ -26,7 +26,7 @@ ifeq ($(ARCH),lin) | |||||
| glew = lib/libGLEW.so | glew = lib/libGLEW.so | ||||
| glfw = lib/libglfw.so | glfw = lib/libglfw.so | ||||
| jansson = lib/libjansson.so | jansson = lib/libjansson.so | ||||
| libsamplerate = lib/libsamplerate.so | |||||
| libspeexdsp = lib/libspeexdsp.so | |||||
| libcurl = lib/libcurl.so | libcurl = lib/libcurl.so | ||||
| libzip = lib/libzip.so | libzip = lib/libzip.so | ||||
| rtmidi = lib/librtmidi.so | rtmidi = lib/librtmidi.so | ||||
| @@ -37,7 +37,7 @@ ifeq ($(ARCH),mac) | |||||
| glew = lib/libGLEW.dylib | glew = lib/libGLEW.dylib | ||||
| glfw = lib/libglfw.dylib | glfw = lib/libglfw.dylib | ||||
| jansson = lib/libjansson.dylib | jansson = lib/libjansson.dylib | ||||
| libsamplerate = lib/libsamplerate.dylib | |||||
| libspeexdsp = lib/libspeexdsp.dylib | |||||
| libcurl = lib/libcurl.dylib | libcurl = lib/libcurl.dylib | ||||
| libzip = lib/libzip.dylib | libzip = lib/libzip.dylib | ||||
| rtmidi = lib/librtmidi.dylib | rtmidi = lib/librtmidi.dylib | ||||
| @@ -48,7 +48,7 @@ ifeq ($(ARCH),win) | |||||
| glew = bin/glew32.dll | glew = bin/glew32.dll | ||||
| glfw = bin/glfw3.dll | glfw = bin/glfw3.dll | ||||
| jansson = bin/libjansson-4.dll | jansson = bin/libjansson-4.dll | ||||
| libsamplerate = bin/libsamplerate-0.dll | |||||
| libspeexdsp = bin/libspeexdsp.dll | |||||
| libcurl = bin/libcurl-4.dll | libcurl = bin/libcurl-4.dll | ||||
| libzip = bin/libzip-5.dll | libzip = bin/libzip-5.dll | ||||
| rtmidi = bin/librtmidi-4.dll | rtmidi = bin/librtmidi-4.dll | ||||
| @@ -71,7 +71,7 @@ endif | |||||
| .NOTPARALLEL: | .NOTPARALLEL: | ||||
| all: $(glew) $(glfw) $(jansson) $(libsamplerate) $(libcurl) $(libzip) $(rtmidi) $(rtaudio) | |||||
| all: $(glew) $(glfw) $(jansson) $(libspeexdsp) $(libcurl) $(libzip) $(rtmidi) $(rtaudio) | |||||
| @echo "" | @echo "" | ||||
| @echo "#######################################" | @echo "#######################################" | ||||
| @echo "# Built all dependencies successfully #" | @echo "# Built all dependencies successfully #" | ||||
| @@ -99,12 +99,12 @@ $(jansson): | |||||
| $(MAKE) -C jansson-2.10 | $(MAKE) -C jansson-2.10 | ||||
| $(MAKE) -C jansson-2.10 install | $(MAKE) -C jansson-2.10 install | ||||
| $(libsamplerate): | |||||
| $(WGET) http://www.mega-nerd.com/SRC/libsamplerate-0.1.9.tar.gz | |||||
| $(UNTAR) libsamplerate-0.1.9.tar.gz | |||||
| cd libsamplerate-0.1.9 && ./configure --prefix="$(LOCAL)" --disable-fftw --disable-sndfile | |||||
| $(MAKE) -C libsamplerate-0.1.9/src | |||||
| $(MAKE) -C libsamplerate-0.1.9/src install | |||||
| $(libspeexdsp): | |||||
| $(WGET) https://github.com/xiph/speexdsp/archive/SpeexDSP-1.2rc3.tar.gz | |||||
| $(UNTAR) SpeexDSP-1.2rc3.tar.gz | |||||
| cd speexdsp-SpeexDSP-1.2rc3 && ./autogen.sh && ./configure --prefix="$(LOCAL)" | |||||
| $(MAKE) -C speexdsp-SpeexDSP-1.2rc3 | |||||
| $(MAKE) -C speexdsp-SpeexDSP-1.2rc3 install | |||||
| $(libcurl): | $(libcurl): | ||||
| $(WGET) https://github.com/curl/curl/releases/download/curl-7_56_0/curl-7.56.0.tar.gz | $(WGET) https://github.com/curl/curl/releases/download/curl-7_56_0/curl-7.56.0.tar.gz | ||||
| @@ -1,8 +1,8 @@ | |||||
| #pragma once | #pragma once | ||||
| #include <assert.h> | #include <assert.h> | ||||
| #include <samplerate.h> | |||||
| #include <string.h> | #include <string.h> | ||||
| #include <speex/speex_resampler.h> | |||||
| #include "frame.hpp" | #include "frame.hpp" | ||||
| @@ -10,50 +10,51 @@ namespace rack { | |||||
| template<int CHANNELS> | template<int CHANNELS> | ||||
| struct SampleRateConverter { | struct SampleRateConverter { | ||||
| SRC_STATE *state; | |||||
| SRC_DATA data; | |||||
| SpeexResamplerState *state = NULL; | |||||
| bool noConversion = true; | |||||
| int inRate = 44100; | |||||
| int outRate = 44100; | |||||
| SampleRateConverter() { | SampleRateConverter() { | ||||
| int error; | int error; | ||||
| state = src_new(SRC_SINC_FASTEST, CHANNELS, &error); | |||||
| assert(!error); | |||||
| data.src_ratio = 1.0; | |||||
| data.end_of_input = false; | |||||
| state = speex_resampler_init(CHANNELS, inRate, outRate, SPEEX_RESAMPLER_QUALITY_DEFAULT, &error); | |||||
| assert(error == RESAMPLER_ERR_SUCCESS); | |||||
| } | } | ||||
| ~SampleRateConverter() { | ~SampleRateConverter() { | ||||
| src_delete(state); | |||||
| speex_resampler_destroy(state); | |||||
| } | } | ||||
| /** output_sample_rate / input_sample_rate */ | |||||
| void setRatio(float r) { | |||||
| src_set_ratio(state, r); | |||||
| data.src_ratio = r; | |||||
| void setRates(int in, int out) { | |||||
| if (in != inRate || out != outRate) { // speex doesn't optimize setting the rates to the existing values. | |||||
| int error = speex_resampler_set_rate(state, in, out); | |||||
| assert(error == RESAMPLER_ERR_SUCCESS); | |||||
| inRate = in; | |||||
| outRate = out; | |||||
| noConversion = in == out; | |||||
| } | |||||
| } | } | ||||
| void setRatioSmooth(float r) { | |||||
| data.src_ratio = r; | |||||
| void setRatioSmooth(float ratio) DEPRECATED { | |||||
| // FIXME: this doesn't do a smooth change -- speex doesn't appear to support that. | |||||
| const int base = 1000; | |||||
| setRates(base, ratio * base); | |||||
| } | } | ||||
| /** `in` and `out` are interlaced with the number of channels */ | /** `in` and `out` are interlaced with the number of channels */ | ||||
| void process(const Frame<CHANNELS> *in, int *inFrames, Frame<CHANNELS> *out, int *outFrames) { | void process(const Frame<CHANNELS> *in, int *inFrames, Frame<CHANNELS> *out, int *outFrames) { | ||||
| /* | |||||
| if (nearf(data.src_ratio, 1.0)) { | |||||
| int len = mini(*inFrames, *outFrames); | |||||
| if (noConversion) { | |||||
| int len = std::min(*inFrames, *outFrames); | |||||
| memcpy(out, in, len * sizeof(Frame<CHANNELS>)); | memcpy(out, in, len * sizeof(Frame<CHANNELS>)); | ||||
| *inFrames = len; | *inFrames = len; | ||||
| *outFrames = len; | *outFrames = len; | ||||
| return; | return; | ||||
| } | } | ||||
| */ | |||||
| // Old versions of libsamplerate use float* here instead of const float* | |||||
| data.data_in = (float*) in; | |||||
| data.input_frames = *inFrames; | |||||
| data.data_out = (float*) out; | |||||
| data.output_frames = *outFrames; | |||||
| src_process(state, &data); | |||||
| *inFrames = data.input_frames_used; | |||||
| *outFrames = data.output_frames_gen; | |||||
| speex_resampler_process_interleaved_float(state, (const float*)in, (unsigned int*)inFrames, (float*)out, (unsigned int*)outFrames); | |||||
| } | } | ||||
| void reset() { | void reset() { | ||||
| src_reset(state); | |||||
| int error = speex_resampler_reset_mem(state); | |||||
| assert(error == RESAMPLER_ERR_SUCCESS); | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -169,7 +169,7 @@ void AudioInterface::step() { | |||||
| // Once full, sample rate convert the input | // Once full, sample rate convert the input | ||||
| // inputBuffer -> SRC -> inputSrcBuffer | // inputBuffer -> SRC -> inputSrcBuffer | ||||
| if (inputBuffer.full()) { | if (inputBuffer.full()) { | ||||
| inputSrc.setRatio(sampleRate / engineGetSampleRate()); | |||||
| inputSrc.setRates(engineGetSampleRate(), sampleRate); | |||||
| int inLen = inputBuffer.size(); | int inLen = inputBuffer.size(); | ||||
| int outLen = inputSrcBuffer.capacity(); | int outLen = inputSrcBuffer.capacity(); | ||||
| inputSrc.process(inputBuffer.startData(), &inLen, inputSrcBuffer.endData(), &outLen); | inputSrc.process(inputBuffer.startData(), &inLen, inputSrcBuffer.endData(), &outLen); | ||||
| @@ -211,7 +211,7 @@ void AudioInterface::stepStream(const float *input, float *output, int numFrames | |||||
| } | } | ||||
| // Pass output through sample rate converter | // Pass output through sample rate converter | ||||
| outputSrc.setRatio(engineGetSampleRate() / sampleRate); | |||||
| outputSrc.setRates(sampleRate, engineGetSampleRate()); | |||||
| int inLen = numFrames; | int inLen = numFrames; | ||||
| int outLen = outputBuffer.capacity(); | int outLen = outputBuffer.capacity(); | ||||
| outputSrc.process(inputFrames, &inLen, outputBuffer.endData(), &outLen); | outputSrc.process(inputFrames, &inLen, outputBuffer.endData(), &outLen); | ||||