├── src ├── ext │ ├── getopt │ │ ├── unistd.h │ │ ├── getopt.c │ │ └── getopt.h │ ├── kissfft │ │ ├── COPYING │ │ ├── kiss_fft_log.h │ │ ├── kiss_fftr.h │ │ ├── kiss_fft.h │ │ ├── kiss_fftr.c │ │ └── _kiss_fft_guts.h │ ├── speex │ │ └── COPYING │ └── float_cast │ │ └── float_cast.h ├── common │ ├── Log.cpp │ ├── SampleFilter.h │ ├── FixedVector.h │ ├── Allocators.cpp │ ├── mathmisc.h │ ├── Log.h │ ├── mathmisc.cpp │ ├── Profiler.h │ ├── sysutils.h │ ├── sysutils.cpp │ ├── StretchCalculator.h │ ├── SingleThreadRingBuffer.h │ ├── Thread.h │ └── FFT.h ├── test │ ├── test.cpp │ ├── TestAllocators.cpp │ ├── TestVectorOpsComplex.cpp │ └── TestStretchCalculator.cpp ├── faster │ ├── SilentAudioCurve.h │ ├── HighFrequencyAudioCurve.h │ ├── PercussiveAudioCurve.h │ ├── HighFrequencyAudioCurve.cpp │ ├── SilentAudioCurve.cpp │ ├── AudioCurveCalculator.cpp │ ├── CompoundAudioCurve.h │ ├── PercussiveAudioCurve.cpp │ ├── CompoundAudioCurve.cpp │ ├── AudioCurveCalculator.h │ ├── SincWindow.h │ └── StretcherChannelData.h └── finer │ ├── Peak.h │ └── BinSegmenter.h ├── ladspa-lv2 ├── lv2-plugin.list ├── ladspa-plugin.list ├── lv2-plugin.map ├── ladspa-plugin.map ├── ladspa-rubberband.cat ├── ladspa-rubberband.rdf ├── rubberband.lv2 │ └── manifest.ttl ├── libmain-ladspa.cpp ├── libmain-lv2.cpp ├── RubberBandLivePitchShifter.h ├── RubberBandR3PitchShifter.h └── RubberBandPitchShifter.h ├── vamp ├── vamp-plugin.list ├── vamp-plugin.map ├── vamp-rubberband.cat ├── libmain.cpp └── RubberBandVampPlugin.h ├── dotnet ├── rubberband-dll │ ├── stdafx.cpp │ ├── targetver.h │ ├── stdafx.h │ └── dllmain.cpp ├── rubberband-sharp │ ├── rubberband-sharp.csproj │ ├── rubberband-sharp.targets │ ├── rubberband-sharp.nuspec │ └── Install.ps1 ├── rubberband-dll.vcxproj.filters ├── README.md └── rubberband.sln ├── cross ├── windows-cl.txt ├── windows-clang.txt ├── macos-arm64.txt ├── macos-x86_64.txt ├── macos-universal.txt ├── ios-simulator.txt └── ios.txt ├── otherbuilds ├── docker │ ├── run.sh │ └── Dockerfile.in ├── deploy │ ├── win.bat │ ├── macos.sh │ └── source.sh ├── check.sh ├── Android.mk └── Makefile.ios ├── rubberband.pc.in ├── .hgignore ├── .github └── workflows │ ├── macos-ios.yml │ └── windows.yml ├── meson_options.txt ├── .build.yml ├── CONTRIBUTING.md ├── .hgtags ├── com └── breakfastquay │ └── rubberband │ └── RubberBandLiveShifter.java └── single └── RubberBandSingle.cpp /src/ext/getopt/unistd.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ladspa-lv2/lv2-plugin.list: -------------------------------------------------------------------------------- 1 | _lv2_descriptor 2 | -------------------------------------------------------------------------------- /ladspa-lv2/ladspa-plugin.list: -------------------------------------------------------------------------------- 1 | _ladspa_descriptor 2 | -------------------------------------------------------------------------------- /vamp/vamp-plugin.list: -------------------------------------------------------------------------------- 1 | _vampGetPluginDescriptor 2 | -------------------------------------------------------------------------------- /dotnet/rubberband-dll/stdafx.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | -------------------------------------------------------------------------------- /ladspa-lv2/lv2-plugin.map: -------------------------------------------------------------------------------- 1 | { 2 | global: lv2_descriptor; 3 | local: *; 4 | }; 5 | -------------------------------------------------------------------------------- /ladspa-lv2/ladspa-plugin.map: -------------------------------------------------------------------------------- 1 | { 2 | global: ladspa_descriptor; 3 | local: *; 4 | }; 5 | -------------------------------------------------------------------------------- /vamp/vamp-plugin.map: -------------------------------------------------------------------------------- 1 | { 2 | global: vampGetPluginDescriptor; 3 | local: *; 4 | }; 5 | -------------------------------------------------------------------------------- /vamp/vamp-rubberband.cat: -------------------------------------------------------------------------------- 1 | vamp:vamp-rubberband:rubberband::Time > Timestretch Analysis 2 | -------------------------------------------------------------------------------- /cross/windows-cl.txt: -------------------------------------------------------------------------------- 1 | 2 | [properties] 3 | needs_exe_wrapper = false 4 | 5 | [binaries] 6 | c = 'cl' 7 | cpp = 'cl' 8 | 9 | 10 | -------------------------------------------------------------------------------- /cross/windows-clang.txt: -------------------------------------------------------------------------------- 1 | 2 | [properties] 3 | needs_exe_wrapper = false 4 | 5 | [binaries] 6 | c = 'clang' 7 | cpp = 'clang++' 8 | 9 | 10 | -------------------------------------------------------------------------------- /otherbuilds/docker/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | revision=$(hg id | sed 's/[^0-9a-z].*$//') 4 | 5 | cat Dockerfile.in | perl -p -e "s/\[\[REVISION\]\]/$revision/g" > Dockerfile 6 | 7 | sudo docker build -f Dockerfile . 8 | 9 | -------------------------------------------------------------------------------- /rubberband.pc.in: -------------------------------------------------------------------------------- 1 | prefix=%PREFIX% 2 | exec_prefix=${prefix} 3 | libdir=${exec_prefix}/lib 4 | includedir=${prefix}/include 5 | 6 | Name: rubberband 7 | Version: %VERSION% 8 | Description: 9 | Libs: -L${libdir} -lrubberband 10 | Cflags: -I${includedir} 11 | -------------------------------------------------------------------------------- /src/ext/kissfft/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2003-2010 Mark Borgerding . All rights reserved. 2 | 3 | KISS FFT is provided under: 4 | 5 | SPDX-License-Identifier: BSD-3-Clause 6 | 7 | Being under the terms of the BSD 3-clause "New" or "Revised" License, 8 | according with: 9 | 10 | LICENSES/BSD-3-Clause 11 | 12 | -------------------------------------------------------------------------------- /dotnet/rubberband-dll/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /dotnet/rubberband-sharp/rubberband-sharp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | rubberband_sharp 6 | 1.0.0.0 7 | 1.0.0.0 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /cross/macos-arm64.txt: -------------------------------------------------------------------------------- 1 | [host_machine] 2 | cpu_family = 'aarch64' 3 | cpu = 'aarch64' 4 | system = 'darwin' 5 | endian = 'little' 6 | 7 | [properties] 8 | needs_exe_wrapper = false 9 | 10 | [binaries] 11 | c = 'cc' 12 | cpp = 'c++' 13 | strip = 'strip' 14 | pkgconfig = 'pkg-config' 15 | 16 | [built-in options] 17 | c_args = ['-arch', 'arm64'] 18 | cpp_args = ['-arch', 'arm64'] 19 | cpp_link_args = ['-arch', 'arm64'] 20 | 21 | 22 | -------------------------------------------------------------------------------- /cross/macos-x86_64.txt: -------------------------------------------------------------------------------- 1 | [host_machine] 2 | cpu_family = 'x86_64' 3 | cpu = 'x86_64' 4 | system = 'darwin' 5 | endian = 'little' 6 | 7 | [properties] 8 | needs_exe_wrapper = false 9 | 10 | [binaries] 11 | c = 'cc' 12 | cpp = 'c++' 13 | strip = 'strip' 14 | pkgconfig = 'pkg-config' 15 | 16 | [built-in options] 17 | c_args = ['-arch', 'x86_64'] 18 | cpp_args = ['-arch', 'x86_64', '-stdlib=libc++'] 19 | cpp_link_args = ['-arch', 'x86_64', '-stdlib=libc++'] 20 | 21 | -------------------------------------------------------------------------------- /.hgignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | Makefile 3 | autom4te* 4 | bin/* 5 | lib/* 6 | obj/* 7 | .vs/* 8 | *.user 9 | *.nupkg 10 | *.a 11 | *.so 12 | *.o 13 | *.orig 14 | *.log 15 | *.bak 16 | config.status 17 | doc/html 18 | *.rej 19 | cov-int 20 | *~ 21 | x64/Debug/ 22 | x64/Release/ 23 | Release/ 24 | Debug/ 25 | build 26 | build_* 27 | build-* 28 | UpgradeLog* 29 | out-*/ 30 | playlist-out/* 31 | formant-out-*/ 32 | out*.wav 33 | packages/ 34 | otherbuilds/docker/Dockerfile 35 | -------------------------------------------------------------------------------- /dotnet/rubberband-dll/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 11 | // Windows Header Files 12 | #include 13 | 14 | #include 15 | 16 | // reference additional headers your program requires here 17 | -------------------------------------------------------------------------------- /ladspa-lv2/ladspa-rubberband.cat: -------------------------------------------------------------------------------- 1 | ladspa:ladspa-rubberband:rubberband-pitchshifter-mono::Frequency > Pitch shifters 2 | ladspa:ladspa-rubberband:rubberband-pitchshifter-stereo::Frequency > Pitch shifters 3 | ladspa:ladspa-rubberband:rubberband-r3-pitchshifter-mono::Frequency > Pitch shifters 4 | ladspa:ladspa-rubberband:rubberband-r3-pitchshifter-stereo::Frequency > Pitch shifters 5 | ladspa:ladspa-rubberband:rubberband-live-pitchshifter-mono::Frequency > Pitch shifters 6 | ladspa:ladspa-rubberband:rubberband-live-pitchshifter-stereo::Frequency > Pitch shifters 7 | -------------------------------------------------------------------------------- /dotnet/rubberband-sharp/rubberband-sharp.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rubberband-dll-Win32.dll 5 | PreserveNewest 6 | 7 | 8 | rubberband-dll-x64.dll 9 | PreserveNewest 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /cross/macos-universal.txt: -------------------------------------------------------------------------------- 1 | [host_machine] 2 | cpu_family = 'aarch64' 3 | cpu = 'aarch64' 4 | system = 'darwin' 5 | endian = 'little' 6 | 7 | [properties] 8 | needs_exe_wrapper = false 9 | 10 | [binaries] 11 | c = 'cc' 12 | cpp = 'c++' 13 | strip = 'strip' 14 | pkgconfig = 'pkg-config' 15 | 16 | [built-in options] 17 | c_args = ['-arch', 'arm64', '-arch', 'x86_64', '-mmacosx-version-min=10.7'] 18 | cpp_args = ['-arch', 'arm64', '-arch', 'x86_64', '-stdlib=libc++', '-mmacosx-version-min=10.7'] 19 | cpp_link_args = ['-arch', 'arm64', '-arch', 'x86_64', '-stdlib=libc++', '-mmacosx-version-min=10.7'] 20 | 21 | 22 | -------------------------------------------------------------------------------- /cross/ios-simulator.txt: -------------------------------------------------------------------------------- 1 | [constants] 2 | sysroot = '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk' 3 | common_args = [ '-isysroot', sysroot, '-arch', 'x86_64', '-mios-version-min=8' ] 4 | 5 | [host_machine] 6 | cpu_family = 'x86_64' 7 | cpu = 'x86_64' 8 | system = 'darwin' 9 | endian = 'little' 10 | 11 | [properties] 12 | needs_exe_wrapper = true 13 | 14 | [binaries] 15 | c = 'cc' 16 | cpp = 'c++' 17 | strip = 'strip' 18 | 19 | [built-in options] 20 | c_args = common_args 21 | cpp_args = common_args + [ '-stdlib=libc++' ] 22 | cpp_link_args = cpp_args 23 | -------------------------------------------------------------------------------- /cross/ios.txt: -------------------------------------------------------------------------------- 1 | [constants] 2 | sysroot = '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk' 3 | common_args = [ '-isysroot', sysroot, '-arch', 'arm64', '-arch', 'armv7', '-mios-version-min=8' ] 4 | 5 | [host_machine] 6 | cpu_family = 'aarch64' 7 | cpu = 'aarch64' 8 | system = 'darwin' 9 | endian = 'little' 10 | 11 | [properties] 12 | needs_exe_wrapper = true 13 | 14 | [binaries] 15 | c = 'cc' 16 | cpp = 'c++' 17 | strip = 'strip' 18 | 19 | [built-in options] 20 | b_bitcode = true 21 | c_args = common_args 22 | cpp_args = common_args + [ '-stdlib=libc++' ] 23 | cpp_link_args = cpp_args 24 | -------------------------------------------------------------------------------- /ladspa-lv2/ladspa-rubberband.rdf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | ]> 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /.github/workflows/macos-ios.yml: -------------------------------------------------------------------------------- 1 | name: macOS and iOS CI 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | jobs: 8 | build: 9 | 10 | runs-on: macos-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: deps 15 | run: brew install libsndfile libsamplerate vamp-plugin-sdk meson ninja 16 | - name: configure macos 17 | run: meson setup build_macos 18 | - name: configure ios 19 | run: meson setup build_ios --cross-file cross/ios.txt 20 | - name: make macos 21 | run: ninja -C build_macos 22 | - name: make ios 23 | run: ninja -C build_ios 24 | - name: unit test macos 25 | run: meson test -C build_macos 26 | - name: check otherbuilds 27 | run: otherbuilds/check.sh 28 | 29 | 30 | -------------------------------------------------------------------------------- /otherbuilds/docker/Dockerfile.in: -------------------------------------------------------------------------------- 1 | FROM ubuntu:22.04 2 | MAINTAINER Chris Cannam 3 | 4 | RUN apt-get update && \ 5 | apt-get install -y \ 6 | software-properties-common \ 7 | build-essential \ 8 | pkg-config \ 9 | libsamplerate0-dev \ 10 | libsndfile1-dev \ 11 | libfftw3-dev \ 12 | ladspa-sdk \ 13 | lv2-dev \ 14 | vamp-plugin-sdk \ 15 | libboost-test-dev \ 16 | mercurial \ 17 | ninja-build \ 18 | plocate 19 | 20 | RUN apt-get install -y \ 21 | openjdk-21-jdk 22 | 23 | WORKDIR /root 24 | 25 | ADD https://github.com/mesonbuild/meson/releases/download/1.5.2/meson-1.5.2.tar.gz . 26 | RUN tar xvf meson-1.5.2.tar.gz 27 | RUN ln -s $(pwd)/meson-1.5.2/meson.py /usr/bin/meson 28 | 29 | RUN hg clone -u [[REVISION]] https://hg.sr.ht/~breakfastquay/rubberband 30 | 31 | WORKDIR rubberband 32 | 33 | RUN meson setup build 34 | RUN ninja -C build 35 | RUN meson test -C build 36 | 37 | WORKDIR build 38 | 39 | RUN java -Djava.library.path=$(pwd) -cp rubberband-test.jar com.breakfastquay.rubberband.test.RubberBandTest 40 | -------------------------------------------------------------------------------- /ladspa-lv2/rubberband.lv2/manifest.ttl: -------------------------------------------------------------------------------- 1 | @prefix lv2: . 2 | @prefix rdfs: . 3 | @prefix rubberband: . 4 | 5 | rubberband:mono 6 | a lv2:Plugin ; 7 | lv2:binary ; 8 | rdfs:seeAlso . 9 | 10 | rubberband:r3mono 11 | a lv2:Plugin ; 12 | lv2:binary ; 13 | rdfs:seeAlso . 14 | 15 | rubberband:livemono 16 | a lv2:Plugin ; 17 | lv2:binary ; 18 | rdfs:seeAlso . 19 | 20 | rubberband:stereo 21 | a lv2:Plugin ; 22 | lv2:binary ; 23 | rdfs:seeAlso . 24 | 25 | rubberband:r3stereo 26 | a lv2:Plugin ; 27 | lv2:binary ; 28 | rdfs:seeAlso . 29 | 30 | rubberband:livestereo 31 | a lv2:Plugin ; 32 | lv2:binary ; 33 | rdfs:seeAlso . 34 | 35 | -------------------------------------------------------------------------------- /src/ext/kissfft/kiss_fft_log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2003-2010, Mark Borgerding. All rights reserved. 3 | * This file is part of KISS FFT - https://github.com/mborgerding/kissfft 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | * See COPYING file for more information. 7 | */ 8 | 9 | #ifndef kiss_fft_log_h 10 | #define kiss_fft_log_h 11 | 12 | #define ERROR 1 13 | #define WARNING 2 14 | #define INFO 3 15 | #define DEBUG 4 16 | 17 | #define STRINGIFY(x) #x 18 | #define TOSTRING(x) STRINGIFY(x) 19 | 20 | #if defined(NDEBUG) 21 | # define KISS_FFT_LOG_MSG(severity, ...) ((void)0) 22 | #else 23 | # define KISS_FFT_LOG_MSG(severity, ...) \ 24 | fprintf(stderr, "[" #severity "] " __FILE__ ":" TOSTRING(__LINE__) " "); \ 25 | fprintf(stderr, __VA_ARGS__); \ 26 | fprintf(stderr, "\n") 27 | #endif 28 | 29 | #define KISS_FFT_ERROR(...) KISS_FFT_LOG_MSG(ERROR, __VA_ARGS__) 30 | #define KISS_FFT_WARNING(...) KISS_FFT_LOG_MSG(WARNING, __VA_ARGS__) 31 | #define KISS_FFT_INFO(...) KISS_FFT_LOG_MSG(INFO, __VA_ARGS__) 32 | #define KISS_FFT_DEBUG(...) KISS_FFT_LOG_MSG(DEBUG, __VA_ARGS__) 33 | 34 | 35 | 36 | #endif /* kiss_fft_log_h */ -------------------------------------------------------------------------------- /src/common/Log.cpp: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #include "Log.h" 25 | 26 | namespace RubberBand 27 | { 28 | 29 | int Log::m_defaultDebugLevel = 0; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/test/test.cpp: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #define BOOST_TEST_MODULE RubberBand 25 | #ifndef BOOST_TEST_DYN_LINK 26 | #define BOOST_TEST_DYN_LINK 27 | #endif 28 | #include 29 | -------------------------------------------------------------------------------- /dotnet/rubberband-sharp/rubberband-sharp.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | rubberband-sharp 5 | 1.0.0 6 | Rubber Band Library .NET Wrapper 7 | JonathanG@iQmetrix.com 8 | C# wrapper for the Rubber Band Library audio time-stretching and pitch-shifting library. 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.github/workflows/windows.yml: -------------------------------------------------------------------------------- 1 | name: Windows CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: windows-2022 9 | 10 | steps: 11 | - uses: actions/checkout@v4 12 | - uses: microsoft/setup-msbuild@v2 13 | - uses: actions/setup-python@v5 14 | with: 15 | python-version: '3.x' 16 | - name: pipdeps 17 | run: | 18 | pip install meson 19 | pip install ninja 20 | - name: chocodeps 21 | uses: crazy-max/ghaction-chocolatey@v3 22 | with: 23 | args: install libsndfile 24 | - name: make 25 | run: | 26 | meson setup build 27 | ninja -C build 28 | - name: test 29 | run: | 30 | meson test -C build 31 | - name: vcstatic 32 | run: | 33 | msbuild otherbuilds\rubberband-library.vcxproj /t:Build /p:Configuration=Release 34 | - name: dotnet 35 | run: | 36 | msbuild dotnet\rubberband.sln "/t:Restore;Build" 37 | 38 | ## (Commented out as cl not in path - to fix) 39 | # - name: single 40 | # run: | 41 | # cl main\main.cpp single\RubberBandSingle.cpp .\src\ext\getopt\getopt.c src\ext\getopt\getopt_long.c "C:\Program Files\libsndfile\lib\sndfile.lib" /O2 /std:c++14 /D_USE_MATH_DEFINES /DNOMINMAX /EHs /I"C:\Program Files\libsndfile\include" /link /out:test_single.exe 42 | -------------------------------------------------------------------------------- /src/ext/kissfft/kiss_fftr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2003-2004, Mark Borgerding. All rights reserved. 3 | * This file is part of KISS FFT - https://github.com/mborgerding/kissfft 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | * See COPYING file for more information. 7 | */ 8 | 9 | #ifndef KISS_FTR_H 10 | #define KISS_FTR_H 11 | 12 | #include "kiss_fft.h" 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | 18 | /* 19 | 20 | Real optimized version can save about 45% cpu time vs. complex fft of a real seq. 21 | 22 | 23 | 24 | */ 25 | 26 | typedef struct kiss_fftr_state *kiss_fftr_cfg; 27 | 28 | 29 | kiss_fftr_cfg KISS_FFT_API kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem); 30 | /* 31 | nfft must be even 32 | 33 | If you don't care to allocate space, use mem = lenmem = NULL 34 | */ 35 | 36 | 37 | void KISS_FFT_API kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata); 38 | /* 39 | input timedata has nfft scalar points 40 | output freqdata has nfft/2+1 complex points 41 | */ 42 | 43 | void KISS_FFT_API kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata); 44 | /* 45 | input freqdata has nfft/2+1 complex points 46 | output timedata has nfft scalar points 47 | */ 48 | 49 | #define kiss_fftr_free KISS_FFT_FREE 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | #endif 55 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | 2 | option('fft', 3 | type: 'combo', 4 | choices: ['auto', 'builtin', 'kissfft', 'fftw', 'sleef', 'vdsp', 'ipp'], 5 | value: 'auto', 6 | description: 'FFT library to use. The default (auto) will use vDSP if available, the builtin implementation otherwise.') 7 | 8 | option('resampler', 9 | type: 'combo', 10 | choices: ['auto', 'builtin', 'libsamplerate', 'speex', 'libspeexdsp', 'ipp'], 11 | value: 'auto', 12 | description: 'Resampler library to use. The default (auto) simply uses the builtin implementation.') 13 | 14 | option('ipp_path', 15 | type: 'string', 16 | value: '', 17 | description: 'Path to Intel IPP libraries, if selected for any of the other options.') 18 | 19 | option('extra_include_dirs', 20 | type: 'array', 21 | value: [], 22 | description: 'Additional local header directories to search for dependencies.') 23 | 24 | option('extra_lib_dirs', 25 | type: 'array', 26 | value: [], 27 | description: 'Additional local library directories to search for dependencies.') 28 | 29 | option('jni', type: 'feature', value: 'auto') 30 | option('ladspa', type: 'feature', value: 'auto') 31 | option('lv2', type: 'feature', value: 'auto') 32 | option('vamp', type: 'feature', value: 'auto') 33 | option('cmdline', type: 'feature', value: 'auto') 34 | option('tests', type: 'feature', value: 'auto') 35 | -------------------------------------------------------------------------------- /src/common/SampleFilter.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_SAMPLE_FILTER_H 25 | #define RUBBERBAND_SAMPLE_FILTER_H 26 | 27 | #include 28 | 29 | namespace RubberBand 30 | { 31 | 32 | template 33 | class SampleFilter 34 | { 35 | public: 36 | virtual ~SampleFilter() { } 37 | virtual int getSize() const = 0; 38 | virtual void push(T) = 0; 39 | virtual T get() const = 0; 40 | virtual void reset() = 0; 41 | }; 42 | 43 | } 44 | 45 | #endif 46 | 47 | -------------------------------------------------------------------------------- /dotnet/rubberband-dll.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Header Files 20 | 21 | 22 | Header Files 23 | 24 | 25 | 26 | 27 | Source Files 28 | 29 | 30 | Source Files 31 | 32 | 33 | Source Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /vamp/libmain.cpp: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #include 25 | #include 26 | 27 | #include "RubberBandVampPlugin.h" 28 | 29 | static Vamp::PluginAdapter rubberBandAdapter; 30 | 31 | const VampPluginDescriptor *vampGetPluginDescriptor(unsigned int version, 32 | unsigned int index) 33 | { 34 | if (version < 1) return 0; 35 | 36 | switch (index) { 37 | case 0: return rubberBandAdapter.getDescriptor(); 38 | default: return 0; 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /src/common/FixedVector.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_FIXED_VECTOR_H 25 | #define RUBBERBAND_FIXED_VECTOR_H 26 | 27 | #include "Allocators.h" 28 | #include 29 | 30 | namespace RubberBand 31 | { 32 | 33 | template 34 | class FixedVector : public std::vector> 35 | { 36 | public: 37 | using std::vector>::vector; 38 | 39 | private: 40 | FixedVector(const FixedVector &) =delete; 41 | FixedVector(FixedVector &&) =delete; 42 | FixedVector &operator=(const FixedVector &) =delete; 43 | FixedVector &operator=(FixedVector &&) =delete; 44 | }; 45 | 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/faster/SilentAudioCurve.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_SILENT_AUDIO_CURVE_H 25 | #define RUBBERBAND_SILENT_AUDIO_CURVE_H 26 | 27 | #include "AudioCurveCalculator.h" 28 | 29 | namespace RubberBand 30 | { 31 | 32 | class SilentAudioCurve : public AudioCurveCalculator 33 | { 34 | public: 35 | SilentAudioCurve(Parameters parameters); 36 | virtual ~SilentAudioCurve(); 37 | 38 | virtual float processFloat(const float *R__ mag, int increment); 39 | virtual double processDouble(const double *R__ mag, int increment); 40 | virtual void reset(); 41 | virtual const char *getUnit() const { return "bool"; } 42 | }; 43 | 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /ladspa-lv2/libmain-ladspa.cpp: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #define RB_PLUGIN_LADSPA 1 25 | #undef RB_PLUGIN_LV2 26 | #include "RubberBandPitchShifter.cpp" 27 | #include "RubberBandR3PitchShifter.cpp" 28 | #include "RubberBandLivePitchShifter.cpp" 29 | 30 | #include 31 | 32 | extern "C" { 33 | 34 | const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) 35 | { 36 | if (index < 2) { 37 | return RubberBandPitchShifter::getDescriptor(index); 38 | } else if (index < 4) { 39 | return RubberBandR3PitchShifter::getDescriptor(index - 2); 40 | } else { 41 | return RubberBandLivePitchShifter::getDescriptor(index - 4); 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /otherbuilds/deploy/win.bat: -------------------------------------------------------------------------------- 1 | 2 | echo on 3 | 4 | set STARTPWD=%CD% 5 | set ORIGINALPATH=%PATH% 6 | set PATH=C:\Program Files (x86)\Windows Kits\10\bin\x64;%PATH% 7 | 8 | set vcvarsall="C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" 9 | 10 | if not exist %vcvarsall% ( 11 | @ echo "Could not find MSVC vars batch file" 12 | @ exit /b 2 13 | ) 14 | 15 | set VERSION=%1 16 | shift 17 | if "%VERSION%" == "" ( 18 | @echo "Usage: win.bat " 19 | exit /b 1 20 | ) 21 | 22 | @echo Building version %VERSION% 23 | 24 | call %vcvarsall% amd64 25 | if errorlevel 1 exit /b %errorlevel% 26 | 27 | del /q /s build 28 | 29 | meson setup build --buildtype release "-Dextra_include_dirs=C:\Program Files\libsndfile\include" "-Dextra_lib_dirs=C:\Program Files\libsndfile\lib" "-Db_vscrt=mt" 30 | if errorlevel 1 exit /b %errorlevel% 31 | 32 | ninja -C build 33 | if errorlevel 1 exit /b %errorlevel% 34 | 35 | cd build 36 | ren rubberband-program.exe rubberband.exe 37 | ren rubberband-program-r3.exe rubberband-r3.exe 38 | set NAME=Christopher Cannam 39 | signtool sign /v /n "%NAME%" /t http://time.certum.pl /fd sha1 /a rubberband.exe 40 | if errorlevel 1 exit /b %errorlevel% 41 | 42 | cd .. 43 | set DIR=rubberband-%VERSION%-gpl-executable-windows 44 | del /q /s %DIR% 45 | mkdir %DIR% 46 | copy build\rubberband.exe %DIR% 47 | copy build\rubberband-r3.exe %DIR% 48 | copy "c:\Program Files\libsndfile\bin\sndfile.dll" %DIR% 49 | copy COPYING %DIR%\COPYING.txt 50 | copy README.md %DIR%\README.txt 51 | copy CHANGELOG %DIR%\CHANGELOG.txt 52 | 53 | set PATH=%ORIGINALPATH% 54 | cd %STARTPWD% 55 | @echo Done, now test and zip the directory %DIR% 56 | 57 | -------------------------------------------------------------------------------- /ladspa-lv2/libmain-lv2.cpp: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #define RB_PLUGIN_LV2 1 25 | #undef RB_PLUGIN_LADSPA 26 | #include "RubberBandPitchShifter.cpp" 27 | #include "RubberBandR3PitchShifter.cpp" 28 | #include "RubberBandLivePitchShifter.cpp" 29 | 30 | #include 31 | 32 | extern "C" { 33 | 34 | LV2_SYMBOL_EXPORT 35 | const LV2_Descriptor *lv2_descriptor(uint32_t index) 36 | { 37 | if (index < 2) { 38 | return RubberBandPitchShifter::getDescriptor(index); 39 | } else if (index < 4) { 40 | return RubberBandR3PitchShifter::getDescriptor(index - 2); 41 | } else { 42 | return RubberBandLivePitchShifter::getDescriptor(index - 4); 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /.build.yml: -------------------------------------------------------------------------------- 1 | image: ubuntu/22.04 2 | packages: 3 | - pkg-config 4 | - libsamplerate0-dev 5 | - libsndfile1-dev 6 | - libfftw3-dev 7 | - ladspa-sdk 8 | - lv2-dev 9 | - vamp-plugin-sdk 10 | - libboost-test-dev 11 | - ninja-build 12 | - openjdk-21-jdk 13 | - wget 14 | sources: 15 | - hg+https://hg.sr.ht/~breakfastquay/rubberband 16 | tasks: 17 | - install-meson: | 18 | mkdir -p tmp/meson 19 | cd tmp/meson 20 | wget https://github.com/mesonbuild/meson/releases/download/1.5.2/meson-1.5.2.tar.gz 21 | tar xvf meson-1.5.2.tar.gz 22 | sudo ln -s $(pwd)/meson-1.5.2/meson.py /usr/bin/meson 23 | - setup: | 24 | cd rubberband 25 | meson setup build 26 | meson setup build_speex -Dresampler=speex 27 | meson setup build_libsamplerate -Dresampler=libsamplerate 28 | meson setup build_fftw -Dfft=fftw 29 | meson setup build_kissfft -Dfft=kissfft 30 | - build: | 31 | cd rubberband 32 | ninja -C build 33 | meson test -C build 34 | java -Djava.library.path=build -cp build/rubberband-test.jar com.breakfastquay.rubberband.test.RubberBandTest 35 | build/rubberband -V 36 | ninja -C build_speex 37 | meson test -C build_speex 38 | build_speex/rubberband -V 39 | ninja -C build_libsamplerate 40 | meson test -C build_libsamplerate 41 | build_libsamplerate/rubberband -V 42 | ninja -C build_fftw 43 | meson test -C build_fftw 44 | build_fftw/rubberband -V 45 | ninja -C build_kissfft 46 | meson test -C build_kissfft 47 | build_kissfft/rubberband -V 48 | ./otherbuilds/check.sh 49 | triggers: 50 | - action: email 51 | condition: always 52 | to: chris.cannam@breakfastquay.com 53 | 54 | -------------------------------------------------------------------------------- /src/faster/HighFrequencyAudioCurve.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_HIGHFREQUENCY_AUDIO_CURVE_H 25 | #define RUBBERBAND_HIGHFREQUENCY_AUDIO_CURVE_H 26 | 27 | #include "AudioCurveCalculator.h" 28 | 29 | namespace RubberBand 30 | { 31 | 32 | class HighFrequencyAudioCurve : public AudioCurveCalculator 33 | { 34 | public: 35 | HighFrequencyAudioCurve(Parameters parameters); 36 | 37 | virtual ~HighFrequencyAudioCurve(); 38 | 39 | virtual float processFloat(const float *R__ mag, int increment); 40 | virtual double processDouble(const double *R__ mag, int increment); 41 | virtual void reset(); 42 | virtual const char *getUnit() const { return "Vbin"; } 43 | }; 44 | 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /otherbuilds/check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | 4 | if [ ! -d /Applications ]; then 5 | # Assumed to be Linux 6 | 7 | echo " *** Building static library using Linux-specific Makefile" 8 | make -f otherbuilds/Makefile.linux clean 9 | make -f otherbuilds/Makefile.linux 10 | 11 | echo " *** Linking against static library" 12 | g++ -std=c++11 main/main.cpp lib/librubberband.a -I. -Isrc -o test_static -lsndfile -lpthread 13 | 14 | echo " *** Running build from Linux-specific Makefile" 15 | ./test_static -V 16 | 17 | echo " *** Building with single-file source" 18 | g++ -O3 -std=c++11 main/main.cpp single/RubberBandSingle.cpp -o test_single -lsndfile 19 | 20 | echo " *** Running build from single-file source" 21 | ./test_single -V 22 | 23 | echo " *** OK" 24 | 25 | else 26 | 27 | echo " *** Building static library using macOS-specific Makefile" 28 | make -f otherbuilds/Makefile.macos clean 29 | make -f otherbuilds/Makefile.macos 30 | 31 | echo " *** Linking against static library" 32 | c++ -std=c++11 main/main.cpp lib/librubberband.a -I. -Isrc -o test_static -I/opt/homebrew/include -L/opt/homebrew/lib -lsndfile -framework Accelerate 33 | 34 | echo " *** Running build from macOS-specific Makefile" 35 | ./test_static -V 36 | 37 | echo " *** Building with single-file source" 38 | c++ -O3 -std=c++11 main/main.cpp single/RubberBandSingle.cpp -o test_single -I/opt/homebrew/include -L/opt/homebrew/lib -lsndfile -framework Accelerate 39 | 40 | echo " *** Running build from single-file source" 41 | ./test_single -V 42 | 43 | echo " *** Building static library using iOS-specific Makefile" 44 | make -f otherbuilds/Makefile.ios clean 45 | make -f otherbuilds/Makefile.ios 46 | 47 | fi 48 | -------------------------------------------------------------------------------- /src/faster/PercussiveAudioCurve.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_PERCUSSIVE_AUDIO_CURVE_H 25 | #define RUBBERBAND_PERCUSSIVE_AUDIO_CURVE_H 26 | 27 | #include "AudioCurveCalculator.h" 28 | 29 | namespace RubberBand 30 | { 31 | 32 | class PercussiveAudioCurve : public AudioCurveCalculator 33 | { 34 | public: 35 | PercussiveAudioCurve(Parameters parameters); 36 | 37 | virtual ~PercussiveAudioCurve(); 38 | 39 | virtual void setFftSize(int newSize); 40 | 41 | virtual float processFloat(const float *R__ mag, int increment); 42 | virtual double processDouble(const double *R__ mag, int increment); 43 | 44 | 45 | virtual void reset(); 46 | virtual const char *getUnit() const { return "bin/total"; } 47 | 48 | protected: 49 | double *R__ m_prevMag; 50 | }; 51 | 52 | } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/ext/speex/COPYING: -------------------------------------------------------------------------------- 1 | Copyright 2002-2007 Xiph.org Foundation 2 | Copyright 2002-2007 Jean-Marc Valin 3 | Copyright 2005-2007 Analog Devices Inc. 4 | Copyright 2005-2007 Commonwealth Scientific and Industrial Research 5 | Organisation (CSIRO) 6 | Copyright 1993, 2002, 2006 David Rowe 7 | Copyright 2003 EpicGames 8 | Copyright 1992-1994 Jutta Degener, Carsten Bormann 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions 12 | are met: 13 | 14 | - Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | 17 | - Redistributions in binary form must reproduce the above copyright 18 | notice, this list of conditions and the following disclaimer in the 19 | documentation and/or other materials provided with the distribution. 20 | 21 | - Neither the name of the Xiph.org Foundation nor the names of its 22 | contributors may be used to endorse or promote products derived from 23 | this software without specific prior written permission. 24 | 25 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR 29 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 30 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 31 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 32 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 33 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 34 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | -------------------------------------------------------------------------------- /src/common/Allocators.cpp: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #include "Allocators.h" 25 | 26 | #ifdef HAVE_IPP 27 | #include 28 | #endif 29 | 30 | #include 31 | using std::cerr; 32 | using std::endl; 33 | 34 | namespace RubberBand { 35 | 36 | #ifdef HAVE_IPP 37 | 38 | template <> 39 | float *allocate(size_t count) 40 | { 41 | float *ptr = ippsMalloc_32f(count); 42 | if (!ptr) throw (std::bad_alloc()); 43 | return ptr; 44 | } 45 | 46 | template <> 47 | double *allocate(size_t count) 48 | { 49 | double *ptr = ippsMalloc_64f(count); 50 | if (!ptr) throw (std::bad_alloc()); 51 | return ptr; 52 | } 53 | 54 | template <> 55 | void deallocate(float *ptr) 56 | { 57 | if (ptr) ippsFree((void *)ptr); 58 | } 59 | 60 | template <> 61 | void deallocate(double *ptr) 62 | { 63 | if (ptr) ippsFree((void *)ptr); 64 | } 65 | 66 | #endif 67 | 68 | } 69 | 70 | -------------------------------------------------------------------------------- /dotnet/README.md: -------------------------------------------------------------------------------- 1 | 2 | This directory contains a .NET interface for Rubber Band Library, 3 | generously contributed by Jonathan Gilbert under a BSD-like 4 | licence. The directory `rubberband-sharp` contains a managed-code 5 | interface to Rubber Band in C#. It loads and uses the DLL defined in 6 | `rubberband-dll`, that wraps the Rubber Band Library with an API 7 | understood by the `rubberband-sharp` code. 8 | 9 | If you make use of this interface, please ensure you comply with the 10 | terms of its licence, in addition to the GPL licence accompanying 11 | Rubber Band Library itself: 12 | 13 | ``` 14 | [files in rubberband-dll and rubberband-sharp] 15 | 16 | Copyright 2018-2019 Jonathan Gilbert 17 | 18 | Permission is hereby granted, free of charge, to any person 19 | obtaining a copy of this software and associated documentation 20 | files (the "Software"), to deal in the Software without 21 | restriction, including without limitation the rights to use, copy, 22 | modify, merge, publish, distribute, sublicense, and/or sell copies 23 | of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be 27 | included in all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 30 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 31 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 32 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR 33 | ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 34 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 35 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 36 | 37 | Except as contained in this notice, the name of Jonathan Gilbert 38 | shall not be used in advertising or otherwise to promote the sale, 39 | use or other dealings in this Software without prior written 40 | authorization. 41 | ``` 42 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | 2 | Rubber Band is an open source library with a commercial licence 3 | option. It is developed and maintained with care, prioritising 4 | reliability, output quality, compatibility across releases and 5 | platforms, and performance, in roughly that order. 6 | 7 | ## Bug reports 8 | 9 | We welcome and encourage bug reports for the Rubber Band 10 | Library. We're happy to receive them by almost any channel. The most 11 | usual are [as Github issues](https://github.com/breakfastquay/rubberband/issues) 12 | or [by contacting us directly](https://breakfastquay.com/contact.html). 13 | 14 | Please try to provide enough information for us to reproduce the 15 | problem. At the minimum this includes details of platform, compiler, 16 | and library configuration, as well as a description of the expected 17 | and problematic behaviour. We appreciate that describing issues 18 | relating to audio output can be tricky, and we may ask you to send or 19 | provide further information such as audio examples. 20 | 21 | ## Pull requests 22 | 23 | Please be aware that we **cannot directly merge** pull requests. This 24 | is partly for technical reasons (the Github repository for the library 25 | is a read-only mirror of an upstream repo) and partly for control of 26 | copyright and provenance. 27 | 28 | Github pull requests may still be appropriate if you have small fixes, 29 | particularly fixes to the build system or documentation, that would be 30 | convenient to upstream. We will gratefully read and consider PRs, 31 | especially of this sort. 32 | 33 | If you have any more substantial changes you would like to see 34 | included, please contact us directly to discuss. 35 | 36 | ## Other ways to contribute 37 | 38 | An excellent way to contribute to the continued development of Rubber 39 | Band Library is to [buy a commercial licence](https://breakfastquay.com/technology/license.html). 40 | 41 | For enhancements and other new development work, it may be possible to 42 | engage [Particular Programs Ltd](https://particularprograms.co.uk/) at 43 | a commercial rate. Please contact us for details. 44 | 45 | -------------------------------------------------------------------------------- /src/faster/HighFrequencyAudioCurve.cpp: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #include "HighFrequencyAudioCurve.h" 25 | 26 | namespace RubberBand 27 | { 28 | 29 | 30 | HighFrequencyAudioCurve::HighFrequencyAudioCurve(Parameters parameters) : 31 | AudioCurveCalculator(parameters) 32 | { 33 | } 34 | 35 | HighFrequencyAudioCurve::~HighFrequencyAudioCurve() 36 | { 37 | } 38 | 39 | void 40 | HighFrequencyAudioCurve::reset() 41 | { 42 | } 43 | 44 | float 45 | HighFrequencyAudioCurve::processFloat(const float *R__ mag, int) 46 | { 47 | float result = 0.0; 48 | 49 | const int sz = m_lastPerceivedBin; 50 | 51 | for (int n = 0; n <= sz; ++n) { 52 | result = result + mag[n] * n; 53 | } 54 | 55 | return result; 56 | } 57 | 58 | double 59 | HighFrequencyAudioCurve::processDouble(const double *R__ mag, int) 60 | { 61 | double result = 0.0; 62 | 63 | const int sz = m_lastPerceivedBin; 64 | 65 | for (int n = 0; n <= sz; ++n) { 66 | result = result + mag[n] * n; 67 | } 68 | 69 | return result; 70 | } 71 | 72 | } 73 | 74 | -------------------------------------------------------------------------------- /dotnet/rubberband-dll/dllmain.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | rubberband-dll 3 | 4 | A consumer of the rubberband static library that simply exposes 5 | its functionality as a DLL. 6 | 7 | Copyright 2018-2019 Jonathan Gilbert 8 | 9 | Permission is hereby granted, free of charge, to any person 10 | obtaining a copy of this software and associated documentation 11 | files (the "Software"), to deal in the Software without 12 | restriction, including without limitation the rights to use, copy, 13 | modify, merge, publish, distribute, sublicense, and/or sell copies 14 | of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be 18 | included in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR 24 | ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 25 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | 28 | Except as contained in this notice, the name of Jonathan Gilbert 29 | shall not be used in advertising or otherwise to promote the sale, 30 | use or other dealings in this Software without prior written 31 | authorization. 32 | */ 33 | 34 | #include "stdafx.h" 35 | 36 | BOOL APIENTRY DllMain( HMODULE hModule, 37 | DWORD ul_reason_for_call, 38 | LPVOID lpReserved 39 | ) 40 | { 41 | switch (ul_reason_for_call) 42 | { 43 | case DLL_PROCESS_ATTACH: 44 | case DLL_THREAD_ATTACH: 45 | case DLL_THREAD_DETACH: 46 | case DLL_PROCESS_DETACH: 47 | break; 48 | } 49 | return TRUE; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /src/faster/SilentAudioCurve.cpp: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #include "SilentAudioCurve.h" 25 | 26 | #include 27 | 28 | namespace RubberBand 29 | { 30 | 31 | 32 | SilentAudioCurve::SilentAudioCurve(Parameters parameters) : 33 | AudioCurveCalculator(parameters) 34 | { 35 | } 36 | 37 | SilentAudioCurve::~SilentAudioCurve() 38 | { 39 | } 40 | 41 | void 42 | SilentAudioCurve::reset() 43 | { 44 | } 45 | 46 | float 47 | SilentAudioCurve::processFloat(const float *R__ mag, int) 48 | { 49 | const int hs = m_lastPerceivedBin; 50 | static float threshold = powf(10.f, -6); 51 | 52 | for (int i = 0; i <= hs; ++i) { 53 | if (mag[i] > threshold) return 0.f; 54 | } 55 | 56 | return 1.f; 57 | } 58 | 59 | double 60 | SilentAudioCurve::processDouble(const double *R__ mag, int) 61 | { 62 | const int hs = m_lastPerceivedBin; 63 | static double threshold = pow(10.0, -6); 64 | 65 | for (int i = 0; i <= hs; ++i) { 66 | if (mag[i] > threshold) return 0.f; 67 | } 68 | 69 | return 1.f; 70 | } 71 | 72 | } 73 | 74 | -------------------------------------------------------------------------------- /.hgtags: -------------------------------------------------------------------------------- 1 | 96e35b8aaa60f222373f00461789d4f168b968c5 v1.5 2 | 4f58b07497637bfd09a8980e8c594be0975ac55e v1.6 3 | 85022d42d8dc37c4c18debccbd349aea46e9e2fd v1.7 4 | 85022d42d8dc37c4c18debccbd349aea46e9e2fd v1.7 5 | 61fe85a73bc32955feeb6fe17e668d9f522adde4 v1.7 6 | 61fe85a73bc32955feeb6fe17e668d9f522adde4 v1.7 7 | efbc861f9b9460068c48a250232d343ffa7d5726 v1.7 8 | 551952b2e7a6bf5b1196778638c8cdc3c40b108f v1.8 9 | 77466ee7ffb5b07efda9b1dbed858379c987a9da v1.8.1 10 | 77466ee7ffb5b07efda9b1dbed858379c987a9da v1.8.1 11 | d4911a276d96f6232a68c6b8448056d3946043b9 v1.8.1 12 | fa6a54be7e6bf0c5adffd19ccec622481a8140a5 v1.8.2 13 | 37b18c17c042eafc39483ffb58837de844ba3289 v1.9 14 | 7af7a76bbb1dc75f630555e22ca8f6ae9da79529 v1.9.1 15 | 8584d22881ba41a97a9c79f6e091ff65b463970b v1.9.2 16 | 4a6f7059b6b77fb34a9f29037f3ece47755e99a0 v2.0.0 17 | 190ba65557c06823ef576d5d62b99e2d27771759 v2.0.1 18 | 4e2177c66756fecacccf211df5f8a97d01070ef0 v2.0.2 19 | 590cb5c496f868d9806db5205bfe22ddeb7f5767 v3.0.0-beta1 20 | acc04c20175ebc3f8138c4e14c9108cb33024fb1 v3.0.0-beta2 21 | acc04c20175ebc3f8138c4e14c9108cb33024fb1 v3.0.0-beta2 22 | ed9acf241b1076e84ba0b41dc9d8edd904f69f25 v3.0.0-beta2 23 | 58b588a580a126adb16de96f8eade96111758085 v3.0.0-beta3 24 | 58b588a580a126adb16de96f8eade96111758085 v3.0.0-beta3 25 | 78a701fb6daa670fc49648816f040a70689c86a7 v3.0.0-beta3 26 | 54e5351b46cf10bff0daa9ea85e3868c6f7d75e2 v3.0.0-beta4 27 | 54e5351b46cf10bff0daa9ea85e3868c6f7d75e2 v3.0.0-beta4 28 | cc3dd8ef4e14005142a80cc1a32e48764c0f14ad v3.0.0-beta4 29 | cc3dd8ef4e14005142a80cc1a32e48764c0f14ad v3.0.0-beta4 30 | 458a655243ae31e3fcb15d33598bf8a944f9e4cd v3.0.0-beta4 31 | f00a6735b95c336c136b9eb3eccf10e4b8adbeef v3.0.0 32 | f00a6735b95c336c136b9eb3eccf10e4b8adbeef v3.0.0 33 | 59872cfc6f234eabbe777218cd9818e6c8be35d2 v3.0.0 34 | 137ef076894f20b488a65ba2c755219b8ea8cd2c v3.1.0 35 | b7f4072d02d551ba39e11d95fdeb5478f371076c v3.1.1 36 | d2aebfc83e21e7ce597cdb59029eb8500e53c24c v3.1.2 37 | 46d8430844d6454ed140d4e8631372a6c65e856a v3.2.0 38 | 83d096887e1b9042f9e4a8f1b975d18539e82f22 v3.2.1 39 | 55367f2e76c9ee79582c8bebdd63b14c98e459be v3.3.0 40 | 1ea2558505589ca7dab9fd6dd6facd97cd119aaf v4.0.0 41 | -------------------------------------------------------------------------------- /src/faster/AudioCurveCalculator.cpp: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #include "AudioCurveCalculator.h" 25 | 26 | #include 27 | 28 | namespace RubberBand 29 | { 30 | 31 | static const int MaxPerceivedFreq = 16000; 32 | 33 | AudioCurveCalculator::AudioCurveCalculator(Parameters parameters) : 34 | m_sampleRate(parameters.sampleRate), 35 | m_fftSize(parameters.fftSize) 36 | { 37 | recalculateLastPerceivedBin(); 38 | } 39 | 40 | AudioCurveCalculator::~AudioCurveCalculator() 41 | { 42 | } 43 | 44 | void 45 | AudioCurveCalculator::setSampleRate(int newRate) 46 | { 47 | m_sampleRate = newRate; 48 | recalculateLastPerceivedBin(); 49 | } 50 | 51 | void 52 | AudioCurveCalculator::setFftSize(int newSize) 53 | { 54 | m_fftSize = newSize; 55 | recalculateLastPerceivedBin(); 56 | } 57 | 58 | void 59 | AudioCurveCalculator::recalculateLastPerceivedBin() 60 | { 61 | if (m_sampleRate == 0) { 62 | m_lastPerceivedBin = 0; 63 | return; 64 | } 65 | m_lastPerceivedBin = ((MaxPerceivedFreq * m_fftSize) / m_sampleRate); 66 | if (m_lastPerceivedBin > m_fftSize/2) { 67 | m_lastPerceivedBin = m_fftSize/2; 68 | } 69 | } 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/common/mathmisc.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_MATHMISC_H 25 | #define RUBBERBAND_MATHMISC_H 26 | 27 | #include "sysutils.h" 28 | 29 | #ifndef M_PI 30 | #define M_PI 3.14159265358979323846 31 | #endif // M_PI 32 | 33 | namespace RubberBand { 34 | 35 | inline double mod(double x, double y) { 36 | return x - (y * floor(x / y)); 37 | } 38 | inline float modf(float x, float y) { 39 | return x - (y * float(floor(x / y))); 40 | } 41 | 42 | inline double princarg(double a) { 43 | return mod(a + M_PI, -2.0 * M_PI) + M_PI; 44 | } 45 | inline float princargf(float a) { 46 | return modf(a + (float)M_PI, -2.f * (float)M_PI) + (float)M_PI; 47 | } 48 | 49 | inline int binForFrequency(double f, int fftSize, double sampleRate) { 50 | return int(round(f * double(fftSize) / sampleRate)); 51 | } 52 | inline double frequencyForBin(int b, int fftSize, double sampleRate) { 53 | return (double(b) * sampleRate) / double(fftSize); 54 | } 55 | 56 | void pickNearestRational(double ratio, int maxDenom, int &num, int &denom); 57 | 58 | size_t roundUp(size_t value); // to nearest power of two 59 | 60 | size_t roundUpDiv(double divisionOf, size_t divisor); 61 | 62 | } 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /vamp/RubberBandVampPlugin.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_VAMP_PLUGIN_H 25 | #define RUBBERBAND_VAMP_PLUGIN_H 26 | 27 | #include 28 | 29 | #include "RubberBandStretcher.h" 30 | 31 | class RubberBandVampPlugin : public Vamp::Plugin 32 | { 33 | public: 34 | RubberBandVampPlugin(float inputSampleRate); 35 | virtual ~RubberBandVampPlugin(); 36 | 37 | bool initialise(size_t channels, size_t stepSize, size_t blockSize); 38 | void reset(); 39 | 40 | InputDomain getInputDomain() const { return TimeDomain; } 41 | 42 | std::string getIdentifier() const; 43 | std::string getName() const; 44 | std::string getDescription() const; 45 | std::string getMaker() const; 46 | int getPluginVersion() const; 47 | std::string getCopyright() const; 48 | 49 | ParameterList getParameterDescriptors() const; 50 | float getParameter(std::string id) const; 51 | void setParameter(std::string id, float value); 52 | 53 | OutputList getOutputDescriptors() const; 54 | 55 | FeatureSet process(const float *const *inputBuffers, 56 | Vamp::RealTime timestamp); 57 | 58 | FeatureSet getRemainingFeatures(); 59 | 60 | protected: 61 | class Impl; 62 | Impl *m_d; 63 | }; 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /otherbuilds/Android.mk: -------------------------------------------------------------------------------- 1 | 2 | LOCAL_MODULE := rubberband 3 | LOCAL_MODULE_FILENAME := librubberband-jni 4 | 5 | LOCAL_C_INCLUDES := $(LOCAL_PATH)/rubberband $(LOCAL_PATH)/rubberband/src 6 | 7 | RUBBERBAND_PATH := rubberband 8 | RUBBERBAND_SRC_PATH := $(RUBBERBAND_PATH)/src 9 | 10 | RUBBERBAND_JNI_FILES := \ 11 | $(RUBBERBAND_SRC_PATH)/jni/RubberBandStretcherJNI.cpp 12 | 13 | RUBBERBAND_SRC_FILES := \ 14 | $(RUBBERBAND_SRC_PATH)/rubberband-c.cpp \ 15 | $(RUBBERBAND_SRC_PATH)/RubberBandStretcher.cpp \ 16 | $(RUBBERBAND_SRC_PATH)/faster/AudioCurveCalculator.cpp \ 17 | $(RUBBERBAND_SRC_PATH)/faster/CompoundAudioCurve.cpp \ 18 | $(RUBBERBAND_SRC_PATH)/faster/HighFrequencyAudioCurve.cpp \ 19 | $(RUBBERBAND_SRC_PATH)/faster/SilentAudioCurve.cpp \ 20 | $(RUBBERBAND_SRC_PATH)/faster/PercussiveAudioCurve.cpp \ 21 | $(RUBBERBAND_SRC_PATH)/faster/R2Stretcher.cpp \ 22 | $(RUBBERBAND_SRC_PATH)/faster/StretcherChannelData.cpp \ 23 | $(RUBBERBAND_SRC_PATH)/faster/StretcherProcess.cpp \ 24 | $(RUBBERBAND_SRC_PATH)/common/Allocators.cpp \ 25 | $(RUBBERBAND_SRC_PATH)/common/BQResampler.cpp \ 26 | $(RUBBERBAND_SRC_PATH)/common/FFT.cpp \ 27 | $(RUBBERBAND_SRC_PATH)/common/Log.cpp \ 28 | $(RUBBERBAND_SRC_PATH)/common/Profiler.cpp \ 29 | $(RUBBERBAND_SRC_PATH)/common/Resampler.cpp \ 30 | $(RUBBERBAND_SRC_PATH)/common/StretchCalculator.cpp \ 31 | $(RUBBERBAND_SRC_PATH)/common/sysutils.cpp \ 32 | $(RUBBERBAND_SRC_PATH)/common/mathmisc.cpp \ 33 | $(RUBBERBAND_SRC_PATH)/common/Thread.cpp \ 34 | $(RUBBERBAND_SRC_PATH)/finer/R3Stretcher.cpp 35 | 36 | LOCAL_SRC_FILES += \ 37 | $(RUBBERBAND_JNI_FILES) \ 38 | $(RUBBERBAND_SRC_FILES) 39 | 40 | LOCAL_CFLAGS_DEBUG := \ 41 | -g \ 42 | -DWANT_TIMING \ 43 | -DFFT_MEASUREMENT 44 | 45 | LOCAL_CFLAGS_RELEASE := \ 46 | -O3 \ 47 | -ffast-math \ 48 | -ftree-vectorize \ 49 | -DNO_TIMING \ 50 | -DNO_TIMING_COMPLETE_NOOP 51 | 52 | LOCAL_CFLAGS := \ 53 | -Wall \ 54 | -I$(RUBBERBAND_PATH) \ 55 | -I$(RUBBERBAND_SRC_PATH) \ 56 | -DUSE_BQRESAMPLER \ 57 | -DUSE_BUILTIN_FFT \ 58 | -DLACK_POSIX_MEMALIGN \ 59 | -DUSE_OWN_ALIGNED_MALLOC \ 60 | -DLACK_SINCOS \ 61 | -DNO_EXCEPTIONS \ 62 | -DNO_THREADING \ 63 | -DNO_THREAD_CHECKS \ 64 | $(LOCAL_CFLAGS_RELEASE) 65 | 66 | LOCAL_LDLIBS += -llog 67 | 68 | TARGET_ARCH_ABI := armeabi-v7a 69 | LOCAL_ARM_MODE := arm 70 | LOCAL_ARM_NEON := true 71 | 72 | include $(BUILD_SHARED_LIBRARY) 73 | 74 | -------------------------------------------------------------------------------- /src/faster/CompoundAudioCurve.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_COMPOUND_AUDIO_CURVE_H 25 | #define RUBBERBAND_COMPOUND_AUDIO_CURVE_H 26 | 27 | #include "PercussiveAudioCurve.h" 28 | #include "HighFrequencyAudioCurve.h" 29 | #include "../common/SampleFilter.h" 30 | 31 | namespace RubberBand 32 | { 33 | 34 | class CompoundAudioCurve : public AudioCurveCalculator 35 | { 36 | public: 37 | CompoundAudioCurve(Parameters parameters); 38 | 39 | virtual ~CompoundAudioCurve(); 40 | 41 | enum Type { 42 | PercussiveDetector, 43 | CompoundDetector, 44 | SoftDetector 45 | }; 46 | virtual void setType(Type); // default is CompoundDetector 47 | 48 | virtual void setFftSize(int newSize); 49 | 50 | virtual float processFloat(const float *R__ mag, int increment); 51 | virtual double processDouble(const double *R__ mag, int increment); 52 | 53 | virtual void reset(); 54 | 55 | protected: 56 | PercussiveAudioCurve m_percussive; 57 | HighFrequencyAudioCurve m_hf; 58 | 59 | SampleFilter *m_hfFilter; 60 | SampleFilter *m_hfDerivFilter; 61 | 62 | Type m_type; 63 | 64 | double m_lastHf; 65 | double m_lastResult; 66 | int m_risingCount; 67 | 68 | double processFiltering(double percussive, double hf); 69 | }; 70 | 71 | } 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /otherbuilds/deploy/macos.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | if [ ! -f ../rba/deploy/macos/notarize.sh ]; then 4 | echo "Need notarize script in ../rba/deploy/macos" 5 | fi 6 | 7 | version=$(grep '^ *version:' meson.build | head -1 | sed "s/^.*'\([0-9][0-9.]*\)'.*$/\1/") 8 | echo 9 | echo "Packaging command-line utility for Mac for Rubber Band v$version..." 10 | echo 11 | if [ -f /usr/local/lib/libsndfile.dylib ]; then 12 | echo "(WARNING: libsndfile dynamic library found in /usr/local/lib!" 13 | echo "Be sure that you aren't about to combine this external dependency" 14 | echo "with the hardened runtime)" 15 | fi 16 | 17 | echo -n "Proceed [Yn] ? " 18 | read yn 19 | case "$yn" in "") ;; [Yy]) ;; *) exit 3;; esac 20 | echo "Proceeding" 21 | 22 | rm -rf build_arm64 build_x86_64 tmp_pack 23 | PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/ meson build_arm64 --cross-file ./cross/macos-arm64.txt 24 | PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/ meson build_x86_64 --cross-file ./cross/macos-x86_64.txt 25 | ninja -C build_arm64 26 | ninja -C build_x86_64 27 | mkdir tmp_pack 28 | lipo build_arm64/rubberband build_x86_64/rubberband -create -output tmp_pack/rubberband 29 | lipo build_arm64/rubberband-r3 build_x86_64/rubberband-r3 -create -output tmp_pack/rubberband-r3 30 | 31 | echo 32 | echo "Check the following version number: it should read $version" 33 | tmp_pack/rubberband -V 34 | echo 35 | echo "So should this one:" 36 | tmp_pack/rubberband-r3 -V 37 | echo 38 | 39 | key="Developer ID Application: Particular Programs Ltd (73F996B92S)" 40 | mkdir -p packages 41 | ( cd tmp_pack 42 | codesign -s "$key" -fv --options runtime rubberband 43 | codesign -s "$key" -fv --options runtime rubberband-r3 44 | zipfile="rubberband-$version-gpl-executable-macos.zip" 45 | rm -f "$zipfile" 46 | zip "$zipfile" rubberband rubberband-r3 47 | # ditto -c -k rubberband rubberband-r3 "$zipfile" #!!! "can't archive multiple sources" 48 | ../../rba/deploy/macos/notarize.sh "$zipfile" com.breakfastquay.rubberband 49 | ) 50 | package_dir="rubberband-$version-gpl-executable-macos" 51 | rm -rf "$package_dir" 52 | mkdir "$package_dir" 53 | cp tmp_pack/rubberband "$package_dir" 54 | cp tmp_pack/rubberband-r3 "$package_dir" 55 | cp CHANGELOG README.md COPYING "$package_dir" 56 | tar cvjf "$package_dir.tar.bz2" "$package_dir" 57 | mv "$package_dir.tar.bz2" packages/ 58 | rm -rf "$package_dir" 59 | echo 60 | echo "Done, package is in packages/$package_dir.tar.bz2" 61 | 62 | -------------------------------------------------------------------------------- /src/ext/float_cast/float_cast.h: -------------------------------------------------------------------------------- 1 | #ifndef ERIKD_FLOATCAST_H 2 | #define ERIKD_FLOATCAST_H 3 | 4 | /* 5 | ** Copyright (C) 2001 Erik de Castro Lopo 6 | ** 7 | ** Permission to use, copy, modify, distribute, and sell this file for any 8 | ** purpose is hereby granted without fee, provided that the above copyright 9 | ** and this permission notice appear in all copies. No representations are 10 | ** made about the suitability of this software for any purpose. It is 11 | ** provided "as is" without express or implied warranty. 12 | */ 13 | 14 | /* Version 1.1 */ 15 | 16 | 17 | /*============================================================================ 18 | ** On Intel Pentium processors (especially PIII and probably P4), converting 19 | ** from float to int is very slow. To meet the C specs, the code produced by 20 | ** most C compilers targeting Pentium needs to change the FPU rounding mode 21 | ** before the float to int conversion is performed. 22 | ** 23 | ** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It 24 | ** is this flushing of the pipeline which is so slow. 25 | ** 26 | ** Fortunately the ISO C99 specifications define the functions lrint, lrintf, 27 | ** llrint and llrintf which fix this problem as a side effect. 28 | ** 29 | ** On Unix-like systems, the configure process should have detected the 30 | ** presence of these functions. If they weren't found we have to replace them 31 | ** here with a standard C cast. 32 | */ 33 | 34 | /* 35 | ** The C99 prototypes for lrint and lrintf are as follows: 36 | ** 37 | ** long int lrintf (float x) ; 38 | ** long int lrint (double x) ; 39 | */ 40 | 41 | #if (defined (_WIN64)) 42 | 43 | #include 44 | __inline long int lrint(double flt) { return (long int)flt; } 45 | __inline long int lrintf(float flt) { return (long int)flt; } 46 | 47 | #elif (defined (WIN32) || defined (_WIN32)) 48 | 49 | #include 50 | 51 | /* Win32 doesn't seem to have these functions. 52 | ** Therefore implement inline versions of these functions here. 53 | */ 54 | 55 | __inline long int 56 | lrint (double flt) 57 | { int intgr; 58 | 59 | _asm 60 | { fld flt 61 | fistp intgr 62 | } ; 63 | 64 | return intgr ; 65 | } 66 | 67 | __inline long int 68 | lrintf (float flt) 69 | { int intgr; 70 | 71 | _asm 72 | { fld flt 73 | fistp intgr 74 | } ; 75 | 76 | return intgr ; 77 | } 78 | 79 | #endif 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /com/breakfastquay/rubberband/RubberBandLiveShifter.java: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2022 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | package com.breakfastquay.rubberband; 25 | 26 | public class RubberBandLiveShifter 27 | { 28 | public RubberBandLiveShifter(int sampleRate, int channels, 29 | int options) { 30 | handle = 0; 31 | initialise(sampleRate, channels, options); 32 | } 33 | 34 | public native void dispose(); 35 | 36 | public native void reset(); 37 | 38 | public native void setPitchScale(double scale); 39 | 40 | public native int getChannelCount(); 41 | public native double getPitchScale(); 42 | 43 | public native int getStartDelay(); 44 | 45 | public native void setFormantOption(int options); 46 | 47 | public native int getBlockSize(); 48 | 49 | public native void shift(float[][] input, int inOffset, float[][] output, int outOffset); 50 | public void shift(float[][] input, float[][] output) { 51 | shift(input, 0, output, 0); 52 | } 53 | 54 | private native void initialise(int sampleRate, int channels, int options); 55 | private long handle; 56 | 57 | public static final int OptionWindowShort = 0x00000000; 58 | public static final int OptionWindowMedium = 0x00100000; 59 | 60 | public static final int OptionFormantShifted = 0x00000000; 61 | public static final int OptionFormantPreserved = 0x01000000; 62 | 63 | public static final int OptionChannelsApart = 0x00000000; 64 | public static final int OptionChannelsTogether = 0x10000000; 65 | 66 | static { 67 | System.loadLibrary("rubberband-jni"); 68 | } 69 | }; 70 | 71 | -------------------------------------------------------------------------------- /src/common/Log.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_LOG_H 25 | #define RUBBERBAND_LOG_H 26 | 27 | #include 28 | #include 29 | 30 | namespace RubberBand { 31 | 32 | class Log { 33 | public: 34 | Log(std::function _log0, 35 | std::function _log1, 36 | std::function _log2) : 37 | m_log0(_log0), 38 | m_log1(_log1), 39 | m_log2(_log2), 40 | m_debugLevel(m_defaultDebugLevel) { } 41 | 42 | Log(const Log &other) =default; 43 | Log(Log &&other) =default; 44 | Log &operator=(const Log &other) =default; 45 | Log &operator=(Log &&other) =default; 46 | 47 | void setDebugLevel(int level) { m_debugLevel = level; } 48 | int getDebugLevel() const { return m_debugLevel; } 49 | 50 | static void setDefaultDebugLevel(int level) { m_defaultDebugLevel = level; } 51 | 52 | void log(int level, const char *message) const { 53 | if (level <= m_debugLevel) m_log0(message); 54 | } 55 | void log(int level, const char *message, double arg0) const { 56 | if (level <= m_debugLevel) m_log1(message, arg0); 57 | } 58 | void log(int level, const char *message, double arg0, double arg1) const { 59 | if (level <= m_debugLevel) m_log2(message, arg0, arg1); 60 | } 61 | 62 | private: 63 | std::function m_log0; 64 | std::function m_log1; 65 | std::function m_log2; 66 | int m_debugLevel; 67 | static int m_defaultDebugLevel; 68 | }; 69 | 70 | } 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /src/common/mathmisc.cpp: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #include "mathmisc.h" 25 | 26 | namespace RubberBand { 27 | 28 | void pickNearestRational(double ratio, int max_denom, int &num, int &denom) 29 | { 30 | // Farey algorithm, see 31 | // https://www.johndcook.com/blog/2010/10/20/best-rational-approximation/ 32 | double a = 0.0, b = 1.0, c = 1.0, d = 0.0; 33 | double pa = a, pb = b, pc = c, pd = d; 34 | double eps = 1e-9; 35 | while (b <= max_denom && d <= max_denom) { 36 | double mediant = (a + c) / (b + d); 37 | if (fabs(ratio - mediant) < eps) { 38 | if (b + d <= max_denom) { 39 | num = a + c; 40 | denom = b + d; 41 | return; 42 | } else if (d > b) { 43 | num = c; 44 | denom = d; 45 | return; 46 | } else { 47 | num = a; 48 | denom = b; 49 | return; 50 | } 51 | } 52 | if (ratio > mediant) { 53 | pa = a; pb = b; 54 | a += c; b += d; 55 | } else { 56 | pc = c; pd = d; 57 | c += a; d += b; 58 | } 59 | } 60 | if (fabs(ratio - (pc / pd)) < fabs(ratio - (pa / pb))) { 61 | num = pc; 62 | denom = pd; 63 | } else { 64 | num = pa; 65 | denom = pb; 66 | } 67 | } 68 | 69 | size_t roundUp(size_t value) 70 | { 71 | if (!(value & (value - 1))) return value; 72 | size_t bits = 0; 73 | while (value) { ++bits; value >>= 1; } 74 | value = size_t(1) << bits; 75 | return value; 76 | } 77 | 78 | size_t roundUpDiv(double divisionOf, size_t divisor) 79 | { 80 | if (divisionOf < 0.0) return 0; 81 | return roundUp(size_t(ceil(divisionOf / double(divisor)))); 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /otherbuilds/deploy/source.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | version=$(meson introspect --projectinfo meson.build -i | grep '"version"' | sed -e 's/^.*: "//' -e 's/".*$//') 4 | check() { 5 | text="$1" 6 | echo -n "$text [yN] " 7 | read yn 8 | case "$yn" in [Yy]) ;; *) echo "Exiting"; exit 3 ;; esac 9 | } 10 | echo 11 | echo "Preparing to make source package for Rubber Band v$version..." 12 | echo 13 | grep '^ *version:' meson.build | head -1 14 | check "Is the above version number (in meson.build) correct?" 15 | echo 16 | echo "The dynamic library version should have a point increment for each" 17 | echo "release, a minor increment for backward-compatible ABI changes, and" 18 | echo "a major increment for incompatible ABI changes." 19 | echo 20 | grep 'rubberband_dynamic_library_version' meson.build | head -1 21 | check "Is the above library version (from meson.build) correct?" 22 | echo 23 | echo "The API major version should increment for incompatible API changes," 24 | echo "and the minor version should increment for backward-compatible API" 25 | echo "changes." 26 | echo 27 | grep 'RUBBERBAND.*VERSION' rubberband/RubberBandStretcher.h 28 | check "Are the above version and API versions (from the C++ header) correct?" 29 | echo 30 | echo "The C header should contain the same versions as the C++ header." 31 | echo 32 | grep 'RUBBERBAND.*VERSION' rubberband/rubberband-c.h 33 | check "Are the above version and API versions (from the C header) correct?" 34 | echo 35 | echo "The LV2 plugin RDF should contain 2x the API minor version for minorVersion" 36 | echo "and an LV2-specific microVersion field, for the mono and stereo plugins." 37 | echo 38 | grep 'Version' ladspa-lv2/rubberband.lv2/lv2-rubberband.ttl 39 | check "Are the above minor and micro versions (from the LV2 plugin RDF) correct?" 40 | echo 41 | grep '^PROJECT_NUMBER' Doxyfile 42 | check "Is the above version (from Doxyfile) correct?" 43 | echo 44 | echo "The CHANGELOG should start with a list of changes for this release." 45 | head -3 CHANGELOG 46 | check "The first three lines of the CHANGELOG are above. Are they correct?" 47 | 48 | hgid=$(hg id | awk '{ print $1; }') 49 | case "$hgid" in 50 | *+) echo "ERROR: Working copy has been modified, please review and commit" 51 | echo "as appropriate before continuing" 52 | exit 1 53 | ;; 54 | *);; 55 | esac 56 | 57 | echo 58 | check "All version checks passed. Continue?" 59 | 60 | echo 61 | echo "Going ahead..." 62 | mkdir -p packages 63 | output="packages/rubberband-$version.tar.bz2" 64 | hg archive --exclude otherbuilds/deploy "$output" 65 | 66 | echo "Checking that the package compiles..." 67 | tmpdir=$(mktemp -d) 68 | cleanup() { 69 | rm -rf "$tmpdir" 70 | } 71 | trap cleanup 0 72 | prevdir=$(pwd) 73 | ( cd "$tmpdir" 74 | tar xvf "$prevdir/$output" 75 | cd "rubberband-$version" 76 | meson build 77 | ninja -C build 78 | ) 79 | 80 | echo 81 | echo "Checked, package is in $output" 82 | -------------------------------------------------------------------------------- /dotnet/rubberband-sharp/Install.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | rubberband-sharp 3 | 4 | A consumer of the rubberband DLL that wraps the RubberBandStretcher 5 | object exposed by the DLL in a managed .NET type. 6 | 7 | Copyright 2018-2019 Jonathan Gilbert 8 | 9 | Permission is hereby granted, free of charge, to any person 10 | obtaining a copy of this software and associated documentation 11 | files (the "Software"), to deal in the Software without 12 | restriction, including without limitation the rights to use, copy, 13 | modify, merge, publish, distribute, sublicense, and/or sell copies 14 | of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be 18 | included in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR 24 | ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 25 | CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | 28 | Except as contained in this notice, the name of Jonathan Gilbert 29 | shall not be used in advertising or otherwise to promote the sale, 30 | use or other dealings in this Software without prior written 31 | authorization. 32 | #> 33 | 34 | Param 35 | ( 36 | $InstallPath, 37 | $ToolsPath, 38 | $Package, 39 | $Project 40 | ) 41 | 42 | # Save current project state. 43 | $Project.Save() 44 | 45 | # Load project XML. 46 | $ProjectFullName = $Project.FullName 47 | 48 | $Doc = New-Object System.Xml.XmlDocument 49 | $Doc.Load($ProjectFullName) 50 | 51 | $Namespace = 'http://schemas.microsoft.com/developer/msbuild/2003' 52 | 53 | # Find the node containing the file. The tag "Content" may be replace by "None" depending of the case, check your .csproj file. 54 | $ContentNodes = Select-Xml "//msb:Project/msb:ItemGroup/msb:Content[starts-with(@Include, 'rubberband-dll-') and (substring(@Include, string-length(@Include) - 3) = '.dll')]" $Doc -Namespace @{msb = $Namespace} 55 | 56 | #check if the node exists. 57 | If ($ContentNodes -ne $Null) 58 | { 59 | $CopyNodeName = "CopyToOutputDirectory" 60 | 61 | ForEach ($ContentNode In $ContentNodes) 62 | { 63 | $NoneNode = $Doc.CreateElement("None", $Namespace) 64 | $NoneNode.SetAttribute("Include", $ContentNode.Node.Attributes["Include"].Value) 65 | 66 | $CopyNode = $Doc.CreateElement($CopyNodeName, $Namespace) 67 | $CopyNode.InnerText = "PreserveNewest" 68 | 69 | $NoneNode.AppendChild($CopyNode) 70 | 71 | $ContentNode.Node.ParentNode.ReplaceChild($NoneNode, $ContentNode.Node) 72 | } 73 | 74 | $DTE = $Project.DTE 75 | 76 | $Project.Select("vsUISelectionTypeSelect") 77 | 78 | $DTE.ExecuteCommand("Project.UnloadProject") 79 | $Doc.Save($ProjectFullName) 80 | $DTE.ExecuteCommand("Project.ReloadProject") 81 | } 82 | -------------------------------------------------------------------------------- /src/test/TestAllocators.cpp: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef BOOST_TEST_DYN_LINK 25 | #define BOOST_TEST_DYN_LINK 26 | #endif 27 | #include 28 | 29 | #include "../common/VectorOps.h" 30 | #include "../common/Allocators.h" 31 | 32 | #include 33 | #include 34 | 35 | using namespace RubberBand; 36 | 37 | BOOST_AUTO_TEST_SUITE(TestAllocators) 38 | 39 | #define COMPARE_ARRAY(a, b) \ 40 | for (int cmp_i = 0; cmp_i < (int)(sizeof(a)/sizeof(a[0])); ++cmp_i) { \ 41 | BOOST_CHECK_SMALL(a[cmp_i] - b[cmp_i], 1e-14); \ 42 | } 43 | 44 | #define COMPARE_N(a, b, n) \ 45 | for (int cmp_i = 0; cmp_i < n; ++cmp_i) { \ 46 | BOOST_CHECK_SMALL(a[cmp_i] - b[cmp_i], 1e-14); \ 47 | } 48 | 49 | BOOST_AUTO_TEST_CASE(alloc_dealloc) 50 | { 51 | double *v = allocate(4); 52 | v[0] = 0.1; 53 | v[1] = 2.0; 54 | v[2] = -0.3; 55 | v[3] = 4.0; 56 | double *e = allocate(4); 57 | e[0] = -0.3; 58 | e[1] = 4.0; 59 | e[2] = 0.1; 60 | e[3] = 2.0; 61 | v_fftshift(v, 4); 62 | COMPARE_N(v, e, 4); 63 | deallocate(v); 64 | deallocate(e); 65 | } 66 | 67 | BOOST_AUTO_TEST_CASE(alloc_zero) 68 | { 69 | double *v = allocate_and_zero(4); 70 | BOOST_CHECK_EQUAL(v[0], 0.f); 71 | BOOST_CHECK_EQUAL(v[1], 0.f); 72 | BOOST_CHECK_EQUAL(v[2], 0.f); 73 | BOOST_CHECK_EQUAL(v[3], 0.f); 74 | deallocate(v); 75 | } 76 | 77 | BOOST_AUTO_TEST_CASE(alloc_dealloc_channels) 78 | { 79 | double **v = allocate_channels(2, 4); 80 | v[0][0] = 0.1; 81 | v[0][1] = 2.0; 82 | v[0][2] = -0.3; 83 | v[0][3] = 4.0; 84 | v[1][0] = -0.3; 85 | v[1][1] = 4.0; 86 | v[1][2] = 0.1; 87 | v[1][3] = 2.0; 88 | v_fftshift(v[0], 4); 89 | COMPARE_N(v[0], v[1], 4); 90 | deallocate_channels(v, 2); 91 | } 92 | 93 | BOOST_AUTO_TEST_CASE(stl) 94 | { 95 | std::vector > v; 96 | v.push_back(0.1); 97 | v.push_back(2.0); 98 | v.push_back(-0.3); 99 | v.push_back(4.0); 100 | double e[] = { -0.3, 4.0, 0.1, 2.0 }; 101 | v_fftshift(v.data(), 4); 102 | COMPARE_N(v.data(), e, 4); 103 | } 104 | 105 | BOOST_AUTO_TEST_SUITE_END() 106 | 107 | -------------------------------------------------------------------------------- /src/common/Profiler.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_PROFILER_H 25 | #define RUBBERBAND_PROFILER_H 26 | 27 | //#define NO_TIMING 1 28 | //#define WANT_TIMING 1 29 | //#define PROFILE_CLOCKS 1 30 | 31 | // Define NO_TIMING or NDEBUG to switch off profilers 32 | #ifdef NDEBUG 33 | #define NO_TIMING 1 34 | #endif 35 | 36 | // But we always allow WANT_TIMING to switch them back on again 37 | #ifdef WANT_TIMING 38 | #undef NO_TIMING 39 | #endif 40 | 41 | #ifndef NO_TIMING 42 | #include 43 | #endif 44 | 45 | #ifndef NO_TIMING 46 | #include 47 | #include 48 | #endif 49 | 50 | namespace RubberBand { 51 | 52 | #ifndef NO_TIMING 53 | 54 | class Profiler 55 | { 56 | public: 57 | Profiler(const char *name); 58 | ~Profiler(); 59 | 60 | void end(); // same action as dtor 61 | 62 | static void dump(); 63 | 64 | // Unlike the other functions, this is only defined if NO_TIMING 65 | // is not set (because it uses std::string which is otherwise 66 | // unused here). So, treat this as a tricksy internal function 67 | // rather than an API call and guard any call to it appropriately. 68 | static std::string getReport(); 69 | 70 | protected: 71 | const char *const m_c; 72 | std::chrono::time_point m_start; 73 | bool m_showOnDestruct; 74 | bool m_ended; 75 | 76 | typedef std::pair TimePair; 77 | typedef std::map ProfileMap; 78 | typedef std::map WorstCallMap; 79 | static ProfileMap m_profiles; 80 | static WorstCallMap m_worstCalls; 81 | static void add(const char *, double); 82 | }; 83 | 84 | #else 85 | 86 | #ifdef NO_TIMING_COMPLETE_NOOP 87 | 88 | // Fastest for release builds, but annoying because it can't be linked 89 | // with code built in debug mode (expecting non-inline functions), so 90 | // not preferred during development 91 | 92 | class Profiler 93 | { 94 | public: 95 | Profiler(const char *) { } 96 | ~Profiler() { } 97 | 98 | void end() { } 99 | static void dump() { } 100 | }; 101 | 102 | #else 103 | 104 | class Profiler 105 | { 106 | public: 107 | Profiler(const char *); 108 | ~Profiler(); 109 | 110 | void end(); 111 | static void dump(); 112 | }; 113 | 114 | #endif 115 | #endif 116 | 117 | } 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /single/RubberBandSingle.cpp: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | /* 25 | RubberBandSingle.cpp 26 | 27 | This is a single-file compilation unit for Rubber Band Library. 28 | 29 | To use the library in your project without building it separately, 30 | include in your code either rubberband/RubberBandStretcher.h 31 | and/or rubberband/RubberBandLiveShifter.h for use in C++, or 32 | rubberband/rubberband-c.h if you need the C interface, then add 33 | this single C++ source file to your build. 34 | 35 | Don't move this file into your source tree - keep it in the same 36 | place relative to the other Rubber Band code, so that the relative 37 | include paths work, and just add it to your list of build files. 38 | 39 | This produces a build using the built-in FFT and resampler 40 | implementations, except on Apple platforms, where the vDSP FFT is 41 | used (and where you will need the Accelerate framework when 42 | linking). It should work correctly on any supported platform, but 43 | may not be the fastest configuration available. For further 44 | customisation, consider using the full build system to make a 45 | standalone library. 46 | */ 47 | 48 | #ifndef ALREADY_CONFIGURED 49 | 50 | #define USE_BQRESAMPLER 1 51 | 52 | #define NO_TIMING 1 53 | #define NO_THREADING 1 54 | #define NO_THREAD_CHECKS 1 55 | 56 | #if defined(__APPLE__) 57 | #define HAVE_VDSP 1 58 | #else 59 | #define USE_BUILTIN_FFT 1 60 | #endif 61 | 62 | #endif 63 | 64 | #include "../src/faster/AudioCurveCalculator.cpp" 65 | #include "../src/faster/CompoundAudioCurve.cpp" 66 | #include "../src/faster/HighFrequencyAudioCurve.cpp" 67 | #include "../src/faster/SilentAudioCurve.cpp" 68 | #include "../src/faster/PercussiveAudioCurve.cpp" 69 | #include "../src/common/Log.cpp" 70 | #include "../src/common/Profiler.cpp" 71 | #include "../src/common/FFT.cpp" 72 | #include "../src/common/Resampler.cpp" 73 | #include "../src/common/BQResampler.cpp" 74 | #include "../src/common/Allocators.cpp" 75 | #include "../src/common/StretchCalculator.cpp" 76 | #include "../src/common/sysutils.cpp" 77 | #include "../src/common/mathmisc.cpp" 78 | #include "../src/common/Thread.cpp" 79 | #include "../src/faster/StretcherChannelData.cpp" 80 | #include "../src/faster/R2Stretcher.cpp" 81 | #include "../src/faster/StretcherProcess.cpp" 82 | #include "../src/finer/R3Stretcher.cpp" 83 | #include "../src/finer/R3LiveShifter.cpp" 84 | 85 | #include "../src/RubberBandStretcher.cpp" 86 | #include "../src/RubberBandLiveShifter.cpp" 87 | #include "../src/rubberband-c.cpp" 88 | 89 | -------------------------------------------------------------------------------- /src/common/sysutils.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_SYSUTILS_H 25 | #define RUBBERBAND_SYSUTILS_H 26 | 27 | #ifdef __clang__ 28 | # define R__ __restrict__ 29 | #else 30 | # ifdef __GNUC__ 31 | # define R__ __restrict__ 32 | # endif 33 | #endif 34 | 35 | #ifdef _MSC_VER 36 | # if _MSC_VER < 1800 37 | # include "float_cast/float_cast.h" 38 | # endif 39 | # ifndef R__ 40 | # define R__ __restrict 41 | # endif 42 | #endif 43 | 44 | #ifndef R__ 45 | # define R__ 46 | #endif 47 | 48 | #ifndef RUBBERBAND_ENABLE_WARNINGS 49 | #if defined(_MSC_VER) 50 | #pragma warning(disable:4127; disable:4244; disable:4267) 51 | #elif defined(__GNUC__) 52 | #pragma GCC diagnostic ignored "-Wconversion" 53 | #elif defined(__clang__) 54 | #pragma clang diagnostic ignored "-Wsign-conversion" 55 | #pragma clang diagnostic ignored "-Wfloat-conversion" 56 | #pragma clang diagnostic ignored "-Wimplicit-float-conversion" 57 | #pragma clang diagnostic ignored "-Wshorten-64-to-32" 58 | #endif 59 | #endif 60 | 61 | #ifdef __clang__ 62 | # define RTENTRY__ __attribute__((annotate("realtime"))) 63 | #else 64 | # define RTENTRY__ 65 | #endif 66 | 67 | #if defined(_MSC_VER) 68 | # include 69 | # include 70 | # define alloca _alloca 71 | # define getpid _getpid 72 | #else 73 | # if defined(__MINGW32__) 74 | # include 75 | # elif defined(__GNUC__) 76 | # ifndef alloca 77 | # define alloca __builtin_alloca 78 | # endif 79 | # elif defined(HAVE_ALLOCA_H) 80 | # include 81 | # else 82 | # ifndef __USE_MISC 83 | # define __USE_MISC 84 | # endif 85 | # include 86 | # endif 87 | #endif 88 | 89 | #if defined(_MSC_VER) && _MSC_VER < 1700 90 | # define uint8_t unsigned __int8 91 | # define uint16_t unsigned __int16 92 | # define uint32_t unsigned __int32 93 | #elif defined(_MSC_VER) 94 | # define ssize_t long 95 | # include 96 | #else 97 | # include 98 | #endif 99 | 100 | #include 101 | 102 | namespace RubberBand { 103 | 104 | #ifdef PROCESS_SAMPLE_TYPE 105 | typedef PROCESS_SAMPLE_TYPE process_t; 106 | #else 107 | typedef double process_t; 108 | #endif 109 | 110 | extern const char *system_get_platform_tag(); 111 | extern bool system_is_multiprocessor(); 112 | 113 | #ifdef _WIN32 114 | struct timeval { long tv_sec; long tv_usec; }; 115 | void gettimeofday(struct timeval *p, void *tz); 116 | #endif // _WIN32 117 | 118 | } // end namespace 119 | 120 | #endif 121 | 122 | -------------------------------------------------------------------------------- /src/faster/PercussiveAudioCurve.cpp: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #include "PercussiveAudioCurve.h" 25 | 26 | #include "../common/Allocators.h" 27 | #include "../common/VectorOps.h" 28 | 29 | #include 30 | #include 31 | namespace RubberBand 32 | { 33 | 34 | 35 | PercussiveAudioCurve::PercussiveAudioCurve(Parameters parameters) : 36 | AudioCurveCalculator(parameters) 37 | { 38 | m_prevMag = allocate_and_zero(m_fftSize/2 + 1); 39 | } 40 | 41 | PercussiveAudioCurve::~PercussiveAudioCurve() 42 | { 43 | deallocate(m_prevMag); 44 | } 45 | 46 | void 47 | PercussiveAudioCurve::reset() 48 | { 49 | v_zero(m_prevMag, m_fftSize/2 + 1); 50 | } 51 | 52 | void 53 | PercussiveAudioCurve::setFftSize(int newSize) 54 | { 55 | m_prevMag = reallocate(m_prevMag, m_fftSize/2 + 1, newSize/2 + 1); 56 | AudioCurveCalculator::setFftSize(newSize); 57 | reset(); 58 | } 59 | 60 | float 61 | PercussiveAudioCurve::processFloat(const float *R__ mag, int) 62 | { 63 | static float threshold = powf(10.f, 0.15f); // 3dB rise in square of magnitude 64 | static float zeroThresh = powf(10.f, -8); 65 | 66 | int count = 0; 67 | int nonZeroCount = 0; 68 | 69 | const int sz = m_lastPerceivedBin; 70 | 71 | for (int n = 1; n <= sz; ++n) { 72 | float v = 0.f; 73 | if (m_prevMag[n] > zeroThresh) v = mag[n] / m_prevMag[n]; 74 | else if (mag[n] > zeroThresh) v = threshold; 75 | bool above = (v >= threshold); 76 | if (above) ++count; 77 | if (mag[n] > zeroThresh) ++nonZeroCount; 78 | } 79 | 80 | v_convert(m_prevMag, mag, sz + 1); 81 | 82 | if (nonZeroCount == 0) return 0; 83 | else return float(count) / float(nonZeroCount); 84 | } 85 | 86 | double 87 | PercussiveAudioCurve::processDouble(const double *R__ mag, int) 88 | { 89 | static double threshold = pow(10., 0.15); // 3dB rise in square of magnitude 90 | static double zeroThresh = pow(10., -8); 91 | 92 | int count = 0; 93 | int nonZeroCount = 0; 94 | 95 | const int sz = m_lastPerceivedBin; 96 | 97 | for (int n = 1; n <= sz; ++n) { 98 | double v = 0.0; 99 | if (m_prevMag[n] > zeroThresh) v = mag[n] / m_prevMag[n]; 100 | else if (mag[n] > zeroThresh) v = threshold; 101 | bool above = (v >= threshold); 102 | if (above) ++count; 103 | if (mag[n] > zeroThresh) ++nonZeroCount; 104 | } 105 | 106 | v_copy(m_prevMag, mag, sz + 1); 107 | 108 | if (nonZeroCount == 0) return 0; 109 | else return double(count) / double(nonZeroCount); 110 | } 111 | 112 | 113 | } 114 | 115 | -------------------------------------------------------------------------------- /otherbuilds/Makefile.ios: -------------------------------------------------------------------------------- 1 | 2 | CXX := clang++ -stdlib=libc++ -std=c++11 3 | CC := clang 4 | 5 | OPTFLAGS := -DNDEBUG -ffast-math -O3 -ftree-vectorize 6 | 7 | # For the device 8 | ARCHFLAGS_DEV := -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk -miphoneos-version-min=6 -arch armv7 -arch arm64 -fembed-bitcode 9 | 10 | # Or for the simulator 11 | ARCHFLAGS_SIM := -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk -miphoneos-version-min=6 -arch x86_64 -fembed-bitcode 12 | 13 | CXXFLAGS_ANY := $(OPTFLAGS) -I. -Isrc -Irubberband -DUSE_BQRESAMPLER -DHAVE_VDSP -DNO_THREAD_CHECKS -DUSE_PTHREADS -DNO_TIMING -DMALLOC_IS_ALIGNED -DNDEBUG 14 | 15 | CXXFLAGS_DEV := $(ARCHFLAGS_DEV) $(CXXFLAGS_ANY) 16 | CXXFLAGS_SIM := $(ARCHFLAGS_SIM) $(CXXFLAGS_ANY) 17 | 18 | CFLAGS_DEV := $(ARCHFLAGS_DEV) $(OPTFLAGS) 19 | CFLAGS_SIM := $(ARCHFLAGS_SIM) $(OPTFLAGS) 20 | 21 | AR := ar 22 | LIPO := lipo 23 | MKDIR := mkdir -p 24 | 25 | LIBNAME := librubberband 26 | 27 | STATIC_TARGET := lib/$(LIBNAME).a 28 | STATIC_TARGET_DEV := lib/$(LIBNAME).dev.a 29 | STATIC_TARGET_SIM := lib/$(LIBNAME).sim.a 30 | 31 | default: lib $(STATIC_TARGET) 32 | all: lib $(STATIC_TARGET) 33 | static: lib $(STATIC_TARGET) 34 | 35 | PUBLIC_INCLUDES := \ 36 | rubberband/rubberband-c.h \ 37 | rubberband/RubberBandStretcher.h 38 | 39 | LIBRARY_SOURCES := \ 40 | src/rubberband-c.cpp \ 41 | src/RubberBandStretcher.cpp \ 42 | src/faster/AudioCurveCalculator.cpp \ 43 | src/faster/CompoundAudioCurve.cpp \ 44 | src/faster/HighFrequencyAudioCurve.cpp \ 45 | src/faster/SilentAudioCurve.cpp \ 46 | src/faster/PercussiveAudioCurve.cpp \ 47 | src/faster/R2Stretcher.cpp \ 48 | src/faster/StretcherChannelData.cpp \ 49 | src/faster/StretcherProcess.cpp \ 50 | src/common/Allocators.cpp \ 51 | src/common/BQResampler.cpp \ 52 | src/common/FFT.cpp \ 53 | src/common/Log.cpp \ 54 | src/common/Profiler.cpp \ 55 | src/common/Resampler.cpp \ 56 | src/common/StretchCalculator.cpp \ 57 | src/common/sysutils.cpp \ 58 | src/common/mathmisc.cpp \ 59 | src/common/Thread.cpp \ 60 | src/finer/R3Stretcher.cpp 61 | 62 | LIBRARY_OBJECTS_DEV := $(LIBRARY_SOURCES:.cpp=.dev.o) 63 | LIBRARY_OBJECTS_DEV := $(LIBRARY_OBJECTS_DEV:.c=.dev.o) 64 | 65 | LIBRARY_OBJECTS_SIM := $(LIBRARY_SOURCES:.cpp=.sim.o) 66 | LIBRARY_OBJECTS_SIM := $(LIBRARY_OBJECTS_SIM:.c=.sim.o) 67 | 68 | $(STATIC_TARGET): $(STATIC_TARGET_DEV) $(STATIC_TARGET_SIM) 69 | rm -f $@ 70 | $(LIPO) -create -output $@ $^ 71 | @echo 72 | @echo "Build complete." 73 | @echo 74 | @echo "Please note that you cannot legally distribute the Rubber Band Library in an" 75 | @echo "iOS app on the App Store, unless you have first obtained a commercial licence." 76 | @echo 77 | 78 | $(STATIC_TARGET_DEV): $(LIBRARY_OBJECTS_DEV) 79 | rm -f $@ 80 | $(AR) rsc $@ $^ 81 | 82 | $(STATIC_TARGET_SIM): $(LIBRARY_OBJECTS_SIM) 83 | rm -f $@ 84 | $(AR) rsc $@ $^ 85 | 86 | %.dev.o: %.c 87 | $(CC) -c $(CFLAGS_DEV) -o $@ $< 88 | 89 | %.dev.o: %.cpp 90 | $(CXX) -c $(CXXFLAGS_DEV) -o $@ $< 91 | 92 | %.sim.o: %.c 93 | $(CC) -c $(CFLAGS_SIM) -o $@ $< 94 | 95 | %.sim.o: %.cpp 96 | $(CXX) -c $(CXXFLAGS_SIM) -o $@ $< 97 | 98 | lib: 99 | $(MKDIR) $@ 100 | 101 | clean: 102 | rm -f $(LIBRARY_OBJECTS_DEV) $(LIBRARY_OBJECTS_SIM) 103 | 104 | distclean: clean 105 | rm -f $(STATIC_TARGET_DEV) $(STATIC_TARGET_SIM) 106 | 107 | depend: 108 | touch otherbuilds/Makefile.dev_depends otherbuilds/Makefile.sim_depends 109 | makedepend -f otherbuilds/Makefile.dev_depends -o.dev.o -Y $(LIBRARY_SOURCES) 110 | makedepend -f otherbuilds/Makefile.sim_depends -o.sim.o -Y $(LIBRARY_SOURCES) 111 | 112 | -include otherbuilds/Makefile.dev_depends 113 | -include otherbuilds/Makefile.sim_depends 114 | -------------------------------------------------------------------------------- /src/ext/getopt/getopt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1987, 1993, 1994 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. All advertising materials mentioning features or use of this software 14 | * must display the following acknowledgement: 15 | * This product includes software developed by the University of 16 | * California, Berkeley and its contributors. 17 | * 4. Neither the name of the University nor the names of its contributors 18 | * may be used to endorse or promote products derived from this software 19 | * without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 | * SUCH DAMAGE. 32 | */ 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | #ifdef _MSC_VER 39 | #pragma warning (disable: 4131; disable: 4706) 40 | #endif 41 | 42 | int opterr = 1, /* if error message should be printed */ 43 | optind = 1, /* index into parent argv vector */ 44 | optopt, /* character checked for validity */ 45 | optreset; /* reset getopt */ 46 | char *optarg; /* argument associated with option */ 47 | 48 | #define BADCH (int)'?' 49 | #define BADARG (int)':' 50 | #define EMSG "" 51 | 52 | /* 53 | * getopt -- 54 | * Parse argc/argv argument vector. 55 | */ 56 | int 57 | getopt(nargc, nargv, ostr) 58 | int nargc; 59 | char * const *nargv; 60 | const char *ostr; 61 | { 62 | static char *place = EMSG; /* option letter processing */ 63 | char *oli; /* option letter list index */ 64 | 65 | if (optreset || !*place) { /* update scanning pointer */ 66 | optreset = 0; 67 | if (optind >= nargc || *(place = nargv[optind]) != '-') { 68 | place = EMSG; 69 | return (-1); 70 | } 71 | if (place[1] && *++place == '-') { /* found "--" */ 72 | ++optind; 73 | place = EMSG; 74 | return (-1); 75 | } 76 | } /* option letter okay? */ 77 | if ((optopt = (int)*place++) == (int)':' || 78 | !(oli = strchr(ostr, optopt))) { 79 | /* 80 | * if the user didn't specify '-' as an option, 81 | * assume it means -1. 82 | */ 83 | if (optopt == (int)'-') 84 | return (-1); 85 | if (!*place) 86 | ++optind; 87 | if (opterr && *ostr != ':' && optopt != BADCH) 88 | (void)fprintf(stderr, "%s: illegal option -- %c\n", 89 | "progname", optopt); 90 | return (BADCH); 91 | } 92 | if (*++oli != ':') { /* don't need argument */ 93 | optarg = NULL; 94 | if (!*place) 95 | ++optind; 96 | } 97 | else { /* need an argument */ 98 | if (*place) /* no white space */ 99 | optarg = place; 100 | else if (nargc <= ++optind) { /* no arg */ 101 | place = EMSG; 102 | if (*ostr == ':') 103 | return (BADARG); 104 | if (opterr) 105 | (void)fprintf(stderr, 106 | "%s: option requires an argument -- %c\n", 107 | "progname", optopt); 108 | return (BADCH); 109 | } 110 | else /* white space */ 111 | optarg = nargv[optind]; 112 | place = EMSG; 113 | ++optind; 114 | } 115 | return (optopt); /* dump back option letter */ 116 | } 117 | -------------------------------------------------------------------------------- /src/ext/getopt/getopt.h: -------------------------------------------------------------------------------- 1 | /* $NetBSD: getopt.h,v 1.4 2000/07/07 10:43:54 ad Exp $ */ 2 | /* $FreeBSD: src/include/getopt.h,v 1.1 2002/09/29 04:14:30 eric Exp $ */ 3 | 4 | /*- 5 | * Copyright (c) 2000 The NetBSD Foundation, Inc. 6 | * All rights reserved. 7 | * 8 | * This code is derived from software contributed to The NetBSD Foundation 9 | * by Dieter Baron and Thomas Klausner. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions 13 | * are met: 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in the 18 | * documentation and/or other materials provided with the distribution. 19 | * 3. All advertising materials mentioning features or use of this software 20 | * must display the following acknowledgement: 21 | * This product includes software developed by the NetBSD 22 | * Foundation, Inc. and its contributors. 23 | * 4. Neither the name of The NetBSD Foundation nor the names of its 24 | * contributors may be used to endorse or promote products derived 25 | * from this software without specific prior written permission. 26 | * 27 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 | * POSSIBILITY OF SUCH DAMAGE. 38 | */ 39 | 40 | #ifndef _GETOPT_H_ 41 | #define _GETOPT_H_ 42 | 43 | #ifdef _WIN32 44 | /* from */ 45 | # ifdef __cplusplus 46 | # define __BEGIN_DECLS extern "C" { 47 | # define __END_DECLS } 48 | # else 49 | # define __BEGIN_DECLS 50 | # define __END_DECLS 51 | # endif 52 | # define __P(args) args 53 | #endif 54 | 55 | /*#ifndef _WIN32 56 | #include 57 | #include 58 | #endif*/ 59 | 60 | #ifdef _WIN32 61 | # if !defined(GETOPT_API) 62 | # define GETOPT_API __declspec(dllimport) 63 | # endif 64 | #endif 65 | 66 | /* 67 | * Gnu like getopt_long() and BSD4.4 getsubopt()/optreset extensions 68 | */ 69 | #if !defined(_POSIX_SOURCE) && !defined(_XOPEN_SOURCE) 70 | #define no_argument 0 71 | #define required_argument 1 72 | #define optional_argument 2 73 | 74 | struct option { 75 | /* name of long option */ 76 | const char *name; 77 | /* 78 | * one of no_argument, required_argument, and optional_argument: 79 | * whether option takes an argument 80 | */ 81 | int has_arg; 82 | /* if not NULL, set *flag to val when option found */ 83 | int *flag; 84 | /* if flag not NULL, value to set *flag to; else return value */ 85 | int val; 86 | }; 87 | 88 | __BEGIN_DECLS 89 | GETOPT_API int getopt_long __P((int, char * const *, const char *, 90 | const struct option *, int *)); 91 | __END_DECLS 92 | #endif 93 | 94 | #ifdef _WIN32 95 | /* These are global getopt variables */ 96 | __BEGIN_DECLS 97 | 98 | GETOPT_API extern int opterr, /* if error message should be printed */ 99 | optind, /* index into parent argv vector */ 100 | optopt, /* character checked for validity */ 101 | optreset; /* reset getopt */ 102 | GETOPT_API extern char* optarg; /* argument associated with option */ 103 | 104 | /* Original getopt */ 105 | GETOPT_API int getopt __P((int, char * const *, const char *)); 106 | 107 | __END_DECLS 108 | #endif 109 | 110 | #endif /* !_GETOPT_H_ */ 111 | -------------------------------------------------------------------------------- /src/common/sysutils.cpp: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #include "sysutils.h" 25 | 26 | #ifdef _WIN32 27 | #include 28 | #include 29 | #include 30 | #else /* !_WIN32 */ 31 | #include 32 | #ifdef __APPLE__ 33 | #include 34 | #include 35 | #include 36 | #else /* !__APPLE__, !_WIN32 */ 37 | #include 38 | #include 39 | #endif /* !__APPLE__, !_WIN32 */ 40 | #endif /* !_WIN32 */ 41 | 42 | #ifdef __sun 43 | #include 44 | #endif 45 | 46 | #include 47 | #include 48 | 49 | #ifdef HAVE_IPP 50 | #include 51 | #include 52 | #endif 53 | 54 | #ifdef HAVE_VDSP 55 | #include 56 | #include 57 | #endif 58 | 59 | #ifdef _WIN32 60 | #include 61 | #endif 62 | 63 | 64 | namespace RubberBand { 65 | 66 | const char * 67 | system_get_platform_tag() 68 | { 69 | #ifdef _WIN32 70 | return "win32"; 71 | #else /* !_WIN32 */ 72 | #ifdef __APPLE__ 73 | return "osx"; 74 | #else /* !__APPLE__ */ 75 | #ifdef __LINUX__ 76 | if (sizeof(long) == 8) { 77 | return "linux64"; 78 | } else { 79 | return "linux"; 80 | } 81 | #else /* !__LINUX__ */ 82 | return "posix"; 83 | #endif /* !__LINUX__ */ 84 | #endif /* !__APPLE__ */ 85 | #endif /* !_WIN32 */ 86 | } 87 | 88 | bool 89 | system_is_multiprocessor() 90 | { 91 | static bool tested = false, mp = false; 92 | 93 | if (tested) return mp; 94 | int count = 0; 95 | 96 | #ifdef _WIN32 97 | 98 | SYSTEM_INFO sysinfo; 99 | GetSystemInfo(&sysinfo); 100 | count = sysinfo.dwNumberOfProcessors; 101 | 102 | #else /* !_WIN32 */ 103 | #ifdef __APPLE__ 104 | 105 | size_t sz = sizeof(count); 106 | if (sysctlbyname("hw.ncpu", &count, &sz, NULL, 0)) { 107 | count = 0; 108 | mp = false; 109 | } else { 110 | mp = (count > 1); 111 | } 112 | 113 | #else /* !__APPLE__, !_WIN32 */ 114 | #ifdef __sun 115 | 116 | processorid_t i, n; 117 | n = sysconf(_SC_CPUID_MAX); 118 | for (i = 0; i <= n; ++i) { 119 | int status = p_online(i, P_STATUS); 120 | if (status == P_ONLINE) { 121 | ++count; 122 | } 123 | if (count > 1) break; 124 | } 125 | 126 | #else /* !__sun, !__APPLE__, !_WIN32 */ 127 | 128 | //... 129 | 130 | FILE *cpuinfo = fopen("/proc/cpuinfo", "r"); 131 | if (!cpuinfo) return false; 132 | 133 | char buf[256]; 134 | while (!feof(cpuinfo)) { 135 | if (!fgets(buf, 256, cpuinfo)) break; 136 | if (!strncmp(buf, "processor", 9)) { 137 | ++count; 138 | } 139 | if (count > 1) break; 140 | } 141 | 142 | fclose(cpuinfo); 143 | 144 | #endif /* !__sun, !__APPLE__, !_WIN32 */ 145 | #endif /* !__APPLE__, !_WIN32 */ 146 | #endif /* !_WIN32 */ 147 | 148 | mp = (count > 1); 149 | tested = true; 150 | return mp; 151 | } 152 | 153 | #ifdef _WIN32 154 | 155 | void gettimeofday(struct timeval *tv, void * /* tz */) 156 | { 157 | union { 158 | long long ns100; 159 | FILETIME ft; 160 | } now; 161 | 162 | ::GetSystemTimeAsFileTime(&now.ft); 163 | tv->tv_usec = (long)((now.ns100 / 10LL) % 1000000LL); 164 | tv->tv_sec = (long)((now.ns100 - 116444736000000000LL) / 10000000LL); 165 | } 166 | 167 | #endif 168 | 169 | } 170 | 171 | 172 | 173 | -------------------------------------------------------------------------------- /dotnet/rubberband.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.31005.135 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rubberband-library", "rubberband-library.vcxproj", "{020CEB11-EF4E-400E-971D-A35DB69D7CF9}" 7 | EndProject 8 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rubberband-dll", "rubberband-dll.vcxproj", "{32C11C5C-3D27-4E57-B72C-161A48AAA95E}" 9 | ProjectSection(ProjectDependencies) = postProject 10 | {020CEB11-EF4E-400E-971D-A35DB69D7CF9} = {020CEB11-EF4E-400E-971D-A35DB69D7CF9} 11 | EndProjectSection 12 | EndProject 13 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "rubberband-sharp", "rubberband-sharp\rubberband-sharp.csproj", "{4A8CA129-DAC5-4550-87EB-80C92A92AAA3}" 14 | ProjectSection(ProjectDependencies) = postProject 15 | {32C11C5C-3D27-4E57-B72C-161A48AAA95E} = {32C11C5C-3D27-4E57-B72C-161A48AAA95E} 16 | EndProjectSection 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|Any CPU = Debug|Any CPU 21 | Debug|x64 = Debug|x64 22 | Debug|x86 = Debug|x86 23 | Release|Any CPU = Release|Any CPU 24 | Release|x64 = Release|x64 25 | Release|x86 = Release|x86 26 | EndGlobalSection 27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 28 | {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Debug|Any CPU.ActiveCfg = Debug|x64 29 | {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Debug|Any CPU.Build.0 = Debug|x64 30 | {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Debug|x64.ActiveCfg = Debug|x64 31 | {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Debug|x64.Build.0 = Debug|x64 32 | {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Debug|x86.ActiveCfg = Debug|Win32 33 | {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Debug|x86.Build.0 = Debug|Win32 34 | {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Release|Any CPU.ActiveCfg = Release|Win32 35 | {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Release|Any CPU.Build.0 = Release|Win32 36 | {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Release|x64.ActiveCfg = Release|x64 37 | {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Release|x64.Build.0 = Release|x64 38 | {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Release|x86.ActiveCfg = Release|Win32 39 | {020CEB11-EF4E-400E-971D-A35DB69D7CF9}.Release|x86.Build.0 = Release|Win32 40 | {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Debug|Any CPU.ActiveCfg = Debug|x64 41 | {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Debug|Any CPU.Build.0 = Debug|x64 42 | {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Debug|x64.ActiveCfg = Debug|x64 43 | {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Debug|x64.Build.0 = Debug|x64 44 | {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Debug|x86.ActiveCfg = Debug|Win32 45 | {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Debug|x86.Build.0 = Debug|Win32 46 | {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Release|Any CPU.ActiveCfg = Release|Win32 47 | {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Release|Any CPU.Build.0 = Release|Win32 48 | {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Release|x64.ActiveCfg = Release|x64 49 | {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Release|x64.Build.0 = Release|x64 50 | {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Release|x86.ActiveCfg = Release|Win32 51 | {32C11C5C-3D27-4E57-B72C-161A48AAA95E}.Release|x86.Build.0 = Release|Win32 52 | {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 53 | {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Debug|Any CPU.Build.0 = Debug|Any CPU 54 | {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Debug|x64.ActiveCfg = Debug|Any CPU 55 | {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Debug|x64.Build.0 = Debug|Any CPU 56 | {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Debug|x86.ActiveCfg = Debug|Any CPU 57 | {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Debug|x86.Build.0 = Debug|Any CPU 58 | {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Release|Any CPU.ActiveCfg = Release|Any CPU 59 | {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Release|Any CPU.Build.0 = Release|Any CPU 60 | {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Release|x64.ActiveCfg = Release|Any CPU 61 | {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Release|x64.Build.0 = Release|Any CPU 62 | {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Release|x86.ActiveCfg = Release|Any CPU 63 | {4A8CA129-DAC5-4550-87EB-80C92A92AAA3}.Release|x86.Build.0 = Release|Any CPU 64 | EndGlobalSection 65 | GlobalSection(SolutionProperties) = preSolution 66 | HideSolutionNode = FALSE 67 | EndGlobalSection 68 | GlobalSection(ExtensibilityGlobals) = postSolution 69 | SolutionGuid = {3CFE825B-BD44-4909-B002-AFE8DA45D614} 70 | EndGlobalSection 71 | EndGlobal 72 | -------------------------------------------------------------------------------- /src/test/TestVectorOpsComplex.cpp: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef BOOST_TEST_DYN_LINK 25 | #define BOOST_TEST_DYN_LINK 26 | #endif 27 | #include 28 | 29 | #include "../common/VectorOpsComplex.h" 30 | #include "../common/VectorOps.h" 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | using namespace RubberBand; 37 | 38 | BOOST_AUTO_TEST_SUITE(TestVectorOpsComplex) 39 | 40 | #ifdef USE_APPROXIMATE_ATAN2 41 | static const double eps = 5.0e-3; 42 | static const double eps_approx = eps; 43 | #else 44 | static const double eps = 1.0e-14; 45 | static const double eps_approx = 1.0e-8; 46 | #endif 47 | 48 | #define COMPARE_N(a, b, n) \ 49 | for (int cmp_i = 0; cmp_i < n; ++cmp_i) { \ 50 | BOOST_CHECK_SMALL(a[cmp_i] - b[cmp_i], eps); \ 51 | } 52 | 53 | BOOST_AUTO_TEST_CASE(cartesian_to_magnitudes) 54 | { 55 | double re[] = { 1.0, 3.0 }; 56 | double im[] = { 2.0, -4.0 }; 57 | double o[2]; 58 | double expected[] = { sqrt(5.0), 5.0 }; 59 | v_cartesian_to_magnitudes(o, re, im, 2); 60 | COMPARE_N(o, expected, 2); 61 | } 62 | 63 | BOOST_AUTO_TEST_CASE(cartesian_interleaved_to_magnitudes) 64 | { 65 | double a[] = { 1.0, 2.0, 3.0, -4.0 }; 66 | double o[2]; 67 | double expected[] = { sqrt(5.0), 5.0 }; 68 | v_cartesian_interleaved_to_magnitudes(o, a, 2); 69 | COMPARE_N(o, expected, 2); 70 | } 71 | 72 | BOOST_AUTO_TEST_CASE(cartesian_to_polar) 73 | { 74 | double re[] = { 0.0, 1.0, 0.0 }; 75 | double im[] = { 0.0, 1.0, -1.0 }; 76 | double mo[3], po[3]; 77 | double me[] = { 0.0, sqrt(2.0), 1.0 }; 78 | double pe[] = { 0.0, M_PI / 4.0, -M_PI * 0.5 }; 79 | v_cartesian_to_polar(mo, po, re, im, 3); 80 | COMPARE_N(mo, me, 3); 81 | COMPARE_N(po, pe, 3); 82 | } 83 | 84 | BOOST_AUTO_TEST_CASE(cartesian_to_polar_interleaved_inplace) 85 | { 86 | double a[] = { 0.0, 0.0, 1.0, 1.0, 0.0, -1.0 }; 87 | double e[] = { 0.0, 0.0, sqrt(2.0), M_PI / 4.0, 1.0, -M_PI * 0.5 }; 88 | v_cartesian_to_polar_interleaved_inplace(a, 3); 89 | COMPARE_N(a, e, 6); 90 | } 91 | 92 | BOOST_AUTO_TEST_CASE(cartesian_interleaved_to_polar) 93 | { 94 | double a[] = { 0.0, 0.0, 1.0, 1.0, 0.0, -1.0 }; 95 | double mo[3], po[3]; 96 | double me[] = { 0.0, sqrt(2.0), 1.0 }; 97 | double pe[] = { 0.0, M_PI / 4.0, -M_PI * 0.5 }; 98 | v_cartesian_interleaved_to_polar(mo, po, a, 3); 99 | COMPARE_N(mo, me, 3); 100 | COMPARE_N(po, pe, 3); 101 | } 102 | 103 | BOOST_AUTO_TEST_CASE(polar_to_cartesian) 104 | { 105 | double m[] = { 0.0, sqrt(2.0), 1.0 }; 106 | double p[] = { 0.0, M_PI / 4.0, -M_PI * 0.5 }; 107 | double ro[3], io[3]; 108 | double re[] = { 0.0, 1.0, 0.0 }; 109 | double ie[] = { 0.0, 1.0, -1.0 }; 110 | v_polar_to_cartesian(ro, io, m, p, 3); 111 | COMPARE_N(ro, re, 3); 112 | COMPARE_N(io, ie, 3); 113 | } 114 | 115 | BOOST_AUTO_TEST_CASE(polar_to_cartesian_interleaved_inplace) 116 | { 117 | double a[] = { 0.0, 0.0, sqrt(2.0), M_PI / 4.0, 1.0, -M_PI * 0.5 }; 118 | double e[] = { 0.0, 0.0, 1.0, 1.0, 0.0, -1.0 }; 119 | v_polar_interleaved_to_cartesian_inplace(a, 3); 120 | COMPARE_N(a, e, 6); 121 | } 122 | 123 | BOOST_AUTO_TEST_CASE(polar_to_cartesian_interleaved) 124 | { 125 | double m[] = { 0.0, sqrt(2.0), 1.0 }; 126 | double p[] = { 0.0, M_PI / 4.0, -M_PI * 0.5 }; 127 | double o[6]; 128 | double e[] = { 0.0, 0.0, 1.0, 1.0, 0.0, -1.0 }; 129 | v_polar_to_cartesian_interleaved(o, m, p, 3); 130 | COMPARE_N(o, e, 6); 131 | } 132 | 133 | BOOST_AUTO_TEST_SUITE_END() 134 | 135 | -------------------------------------------------------------------------------- /src/common/StretchCalculator.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_STRETCH_CALCULATOR_H 25 | #define RUBBERBAND_STRETCH_CALCULATOR_H 26 | 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include "Log.h" 34 | 35 | namespace RubberBand 36 | { 37 | 38 | class StretchCalculator 39 | { 40 | public: 41 | StretchCalculator(size_t sampleRate, 42 | size_t inputIncrement, 43 | bool useHardPeaks, 44 | Log log); 45 | virtual ~StretchCalculator(); 46 | 47 | /** 48 | * Provide a set of mappings from "before" to "after" sample 49 | * numbers so as to enforce a particular stretch profile. This 50 | * must be called before calculate(). The argument is a map from 51 | * audio sample frame number in the source material to the 52 | * corresponding sample frame number in the stretched output. 53 | */ 54 | void setKeyFrameMap(const std::map &mapping); 55 | 56 | /** 57 | * Calculate phase increments for a region of audio, given the 58 | * overall target stretch ratio, input duration in audio samples, 59 | * and the audio curves to use for identifying phase lock points. 60 | */ 61 | std::vector calculate(double ratio, size_t inputDuration, 62 | const std::vector &lockAudioCurve); 63 | 64 | /** 65 | * Calculate the phase increment for a single audio block, given 66 | * the overall target stretch ratio and the block's value on the 67 | * phase-lock audio curve. State is retained between calls in the 68 | * StretchCalculator object; call reset() to reset it. This uses 69 | * a less sophisticated method than the offline calculate(). 70 | * 71 | * If increment is non-zero, use it for the input increment for 72 | * this block in preference to m_increment. 73 | */ 74 | int calculateSingle(double timeRatio, 75 | double effectivePitchRatio, 76 | float curveValue, 77 | size_t increment, 78 | size_t analysisWindowSize, 79 | size_t synthesisWindowSize, 80 | bool alignFrameStarts); 81 | 82 | void setUseHardPeaks(bool use) { m_useHardPeaks = use; } 83 | 84 | void reset(); 85 | 86 | void setDebugLevel(int level) { m_debugLevel = level; } 87 | 88 | struct Peak { 89 | size_t chunk; 90 | bool hard; 91 | }; 92 | std::vector getLastCalculatedPeaks() const { return m_peaks; } 93 | 94 | std::vector smoothDF(const std::vector &df); 95 | 96 | protected: 97 | std::vector findPeaks(const std::vector &audioCurve); 98 | 99 | void mapPeaks(std::vector &peaks, std::vector &targets, 100 | size_t outputDuration, size_t totalCount); 101 | 102 | size_t m_sampleRate; 103 | size_t m_increment; 104 | float m_prevDf; 105 | double m_prevRatio; 106 | double m_prevTimeRatio; 107 | bool m_justReset; 108 | int m_transientAmnesty; // only in RT mode; handled differently offline 109 | int m_debugLevel; 110 | bool m_useHardPeaks; 111 | int64_t m_inFrameCounter; 112 | std::pair m_frameCheckpoint; 113 | int64_t expectedOutFrame(int64_t inFrame, double timeRatio); 114 | double m_outFrameCounter; 115 | Log m_log; 116 | 117 | std::map m_keyFrameMap; 118 | std::vector m_peaks; 119 | }; 120 | 121 | } 122 | 123 | #endif 124 | -------------------------------------------------------------------------------- /src/faster/CompoundAudioCurve.cpp: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #include "CompoundAudioCurve.h" 25 | 26 | #include "../common/MovingMedian.h" 27 | 28 | #include 29 | 30 | namespace RubberBand 31 | { 32 | 33 | 34 | CompoundAudioCurve::CompoundAudioCurve(Parameters parameters) : 35 | AudioCurveCalculator(parameters), 36 | m_percussive(parameters), 37 | m_hf(parameters), 38 | m_hfFilter(new MovingMedian(19, 85)), 39 | m_hfDerivFilter(new MovingMedian(19, 90)), 40 | m_type(CompoundDetector), 41 | m_lastHf(0.0), 42 | m_lastResult(0.0), 43 | m_risingCount(0) 44 | { 45 | } 46 | 47 | CompoundAudioCurve::~CompoundAudioCurve() 48 | { 49 | delete m_hfFilter; 50 | delete m_hfDerivFilter; 51 | } 52 | 53 | void 54 | CompoundAudioCurve::setType(Type type) 55 | { 56 | m_type = type; 57 | } 58 | 59 | void 60 | CompoundAudioCurve::reset() 61 | { 62 | m_percussive.reset(); 63 | m_hf.reset(); 64 | m_hfFilter->reset(); 65 | m_hfDerivFilter->reset(); 66 | m_lastHf = 0.0; 67 | m_lastResult = 0.0; 68 | } 69 | 70 | void 71 | CompoundAudioCurve::setFftSize(int newSize) 72 | { 73 | m_percussive.setFftSize(newSize); 74 | m_hf.setFftSize(newSize); 75 | m_fftSize = newSize; 76 | m_lastHf = 0.0; 77 | m_lastResult = 0.0; 78 | } 79 | 80 | float 81 | CompoundAudioCurve::processFloat(const float *R__ mag, int increment) 82 | { 83 | float percussive = 0.f; 84 | float hf = 0.f; 85 | switch (m_type) { 86 | case PercussiveDetector: 87 | percussive = m_percussive.processFloat(mag, increment); 88 | break; 89 | case CompoundDetector: 90 | percussive = m_percussive.processFloat(mag, increment); 91 | hf = m_hf.processFloat(mag, increment); 92 | break; 93 | case SoftDetector: 94 | hf = m_hf.processFloat(mag, increment); 95 | break; 96 | } 97 | return processFiltering(percussive, hf); 98 | } 99 | 100 | double 101 | CompoundAudioCurve::processDouble(const double *R__ mag, int increment) 102 | { 103 | double percussive = 0.0; 104 | double hf = 0.0; 105 | switch (m_type) { 106 | case PercussiveDetector: 107 | percussive = m_percussive.processDouble(mag, increment); 108 | break; 109 | case CompoundDetector: 110 | percussive = m_percussive.processDouble(mag, increment); 111 | hf = m_hf.processDouble(mag, increment); 112 | break; 113 | case SoftDetector: 114 | hf = m_hf.processDouble(mag, increment); 115 | break; 116 | } 117 | return processFiltering(percussive, hf); 118 | } 119 | 120 | double 121 | CompoundAudioCurve::processFiltering(double percussive, double hf) 122 | { 123 | if (m_type == PercussiveDetector) { 124 | return percussive; 125 | } 126 | 127 | double rv = 0.f; 128 | 129 | double hfDeriv = hf - m_lastHf; 130 | 131 | m_hfFilter->push(hf); 132 | m_hfDerivFilter->push(hfDeriv); 133 | 134 | double hfFiltered = m_hfFilter->get(); 135 | double hfDerivFiltered = m_hfDerivFilter->get(); 136 | 137 | m_lastHf = hf; 138 | 139 | double result = 0.f; 140 | 141 | double hfExcess = hf - hfFiltered; 142 | 143 | if (hfExcess > 0.0) { 144 | result = hfDeriv - hfDerivFiltered; 145 | } 146 | 147 | if (result < m_lastResult) { 148 | if (m_risingCount > 3 && m_lastResult > 0) rv = 0.5; 149 | m_risingCount = 0; 150 | } else { 151 | m_risingCount ++; 152 | } 153 | 154 | if (m_type == CompoundDetector) { 155 | if (percussive > 0.35 && percussive > rv) { 156 | rv = percussive; 157 | } 158 | } 159 | 160 | m_lastResult = result; 161 | 162 | return rv; 163 | } 164 | 165 | 166 | } 167 | 168 | -------------------------------------------------------------------------------- /src/test/TestStretchCalculator.cpp: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef BOOST_TEST_DYN_LINK 25 | #define BOOST_TEST_DYN_LINK 26 | #endif 27 | #include 28 | 29 | #include "../common/StretchCalculator.h" 30 | 31 | #include 32 | 33 | using namespace RubberBand; 34 | 35 | using std::cerr; 36 | using std::endl; 37 | 38 | using std::vector; 39 | 40 | namespace tt = boost::test_tools; 41 | 42 | static Log cerrLog( 43 | [](const char *message) { 44 | cerr << message << "\n"; 45 | }, 46 | [](const char *message, double arg) { 47 | cerr << message << ": " << arg << "\n"; 48 | }, 49 | [](const char *message, double arg0, double arg1) { 50 | cerr << message << ": (" << arg0 << ", " << arg1 << ")\n"; 51 | } 52 | ); 53 | 54 | BOOST_AUTO_TEST_SUITE(TestStretchCalculator) 55 | 56 | BOOST_AUTO_TEST_CASE(offline_linear_hp) 57 | { 58 | StretchCalculator sc(44100, 512, true, cerrLog); 59 | 60 | vector out, expected; 61 | 62 | out = sc.calculate(1.0, 5120, { 1.0, 1.0, 1.0, 1.0, 1.0, 63 | 1.0, 1.0, 1.0, 1.0, 1.0 }); 64 | expected = { 512, 512, 512, 512, 512, 65 | 512, 512, 512, 512, 512 }; 66 | BOOST_TEST(out == expected, tt::per_element()); 67 | 68 | out = sc.calculate(0.5, 5120, { 1.0, 1.0, 1.0, 1.0, 1.0, 69 | 1.0, 1.0, 1.0, 1.0, 1.0 }); 70 | expected = { 256, 256, 256, 256, 256, 71 | 256, 256, 256, 256, 256 }; 72 | BOOST_TEST(out == expected, tt::per_element()); 73 | } 74 | 75 | BOOST_AUTO_TEST_CASE(offline_linear_nohp) 76 | { 77 | StretchCalculator sc(44100, 512, false, cerrLog); 78 | 79 | vector out, expected; 80 | 81 | out = sc.calculate(1.0, 5120, { 1.0, 1.0, 1.0, 1.0, 1.0, 82 | 1.0, 1.0, 1.0, 1.0, 1.0 }); 83 | expected = { 512, 512, 512, 512, 512, 84 | 512, 512, 512, 512, 512 }; 85 | BOOST_TEST(out == expected, tt::per_element()); 86 | 87 | out = sc.calculate(0.5, 5120, { 1.0, 1.0, 1.0, 1.0, 1.0, 88 | 1.0, 1.0, 1.0, 1.0, 1.0 }); 89 | expected = { 256, 256, 256, 256, 256, 90 | 256, 256, 256, 256, 256 }; 91 | BOOST_TEST(out == expected, tt::per_element()); 92 | } 93 | 94 | BOOST_AUTO_TEST_CASE(offline_onep_hp) 95 | { 96 | StretchCalculator sc(44100, 512, true, cerrLog); 97 | 98 | vector out, expected; 99 | 100 | out = sc.calculate(1.0, 5120, { 1.0, 1.0, 1.0, 1.0, 2.0, 101 | 1.0, 1.0, 1.0, 1.0, 1.0 }); 102 | expected = { 512, 512, 512, 512, -512, 103 | 512, 512, 512, 512, 512 }; 104 | BOOST_TEST(out == expected, tt::per_element()); 105 | 106 | out = sc.calculate(0.5, 5120, { 1.0, 1.0, 1.0, 1.0, 2.0, 107 | 1.0, 1.0, 1.0, 1.0, 1.0 }); 108 | expected = { 256, 256, 256, 256, -512, 109 | 205, 205, 204, 205, 205 }; 110 | BOOST_TEST(out == expected, tt::per_element()); 111 | } 112 | 113 | BOOST_AUTO_TEST_CASE(offline_onep_nohp) 114 | { 115 | StretchCalculator sc(44100, 512, false, cerrLog); 116 | 117 | vector out, expected; 118 | 119 | out = sc.calculate(1.0, 5120, { 1.0, 1.0, 1.0, 1.0, 2.0, 120 | 1.0, 1.0, 1.0, 1.0, 1.0 }); 121 | expected = { 512, 512, 512, 512, 512, 122 | 512, 512, 512, 512, 512 }; 123 | BOOST_TEST(out == expected, tt::per_element()); 124 | 125 | out = sc.calculate(0.5, 5120, { 1.0, 1.0, 1.0, 1.0, 2.0, 126 | 1.0, 1.0, 1.0, 1.0, 1.0 }); 127 | expected = { 256, 256, 256, 256, 256, 128 | 256, 256, 256, 256, 256 }; 129 | BOOST_TEST(out == expected, tt::per_element()); 130 | } 131 | 132 | BOOST_AUTO_TEST_SUITE_END() 133 | 134 | -------------------------------------------------------------------------------- /ladspa-lv2/RubberBandLivePitchShifter.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2023 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBER_BAND_LIVE_SHIFTER_H 25 | #define RUBBER_BAND_LIVE_SHIFTER_H 26 | 27 | #ifdef RB_PLUGIN_LADSPA 28 | #ifdef RB_PLUGIN_LV2 29 | #error "Only one of RB_PLUGIN_LADSPA and RB_PLUGIN_LV2 may be defined at once" 30 | #endif 31 | #else 32 | #ifndef RB_PLUGIN_LV2 33 | #error "Including code must define either RB_PLUGIN_LADSPA or RB_PLUGIN_LV2" 34 | #endif 35 | #endif 36 | 37 | #ifdef RB_PLUGIN_LADSPA 38 | #include 39 | #else 40 | #include 41 | #endif 42 | 43 | #include "common/RingBuffer.h" 44 | 45 | namespace RubberBand { 46 | class RubberBandLiveShifter; 47 | } 48 | 49 | class RubberBandLivePitchShifter 50 | { 51 | public: 52 | #ifdef RB_PLUGIN_LADSPA 53 | static const LADSPA_Descriptor *getDescriptor(unsigned long index); 54 | #else 55 | static const LV2_Descriptor *getDescriptor(uint32_t index); 56 | #endif 57 | 58 | protected: 59 | RubberBandLivePitchShifter(int sampleRate, size_t channels); 60 | ~RubberBandLivePitchShifter(); 61 | 62 | enum { 63 | LatencyPort = 0, 64 | CentsPort = 1, 65 | SemitonesPort = 2, 66 | OctavesPort = 3, 67 | FormantPort = 4, 68 | WetDryPort = 5, 69 | InputPort1 = 6, 70 | OutputPort1 = 7, 71 | PortCountMono = OutputPort1 + 1, 72 | InputPort2 = 8, 73 | OutputPort2 = 9, 74 | PortCountStereo = OutputPort2 + 1 75 | }; 76 | 77 | #ifdef RB_PLUGIN_LADSPA 78 | static const char *const portNamesMono[PortCountMono]; 79 | static const LADSPA_PortDescriptor portsMono[PortCountMono]; 80 | static const LADSPA_PortRangeHint hintsMono[PortCountMono]; 81 | 82 | static const char *const portNamesStereo[PortCountStereo]; 83 | static const LADSPA_PortDescriptor portsStereo[PortCountStereo]; 84 | static const LADSPA_PortRangeHint hintsStereo[PortCountStereo]; 85 | 86 | static const LADSPA_Properties properties; 87 | 88 | static const LADSPA_Descriptor ladspaDescriptorMono; 89 | static const LADSPA_Descriptor ladspaDescriptorStereo; 90 | 91 | static LADSPA_Handle instantiate(const LADSPA_Descriptor *, unsigned long); 92 | static void connectPort(LADSPA_Handle, unsigned long, LADSPA_Data *); 93 | static void activate(LADSPA_Handle); 94 | static void run(LADSPA_Handle, unsigned long); 95 | static void deactivate(LADSPA_Handle); 96 | static void cleanup(LADSPA_Handle); 97 | 98 | #else 99 | 100 | static const LV2_Descriptor lv2DescriptorMono; 101 | static const LV2_Descriptor lv2DescriptorStereo; 102 | 103 | static LV2_Handle instantiate(const LV2_Descriptor *, double, 104 | const char *, const LV2_Feature *const *); 105 | static void connectPort(LV2_Handle, uint32_t, void *); 106 | static void activate(LV2_Handle); 107 | static void run(LV2_Handle, uint32_t); 108 | static void deactivate(LV2_Handle); 109 | static void cleanup(LV2_Handle); 110 | 111 | #endif 112 | 113 | void activateImpl(); 114 | void runImpl(uint32_t count); 115 | void process(); 116 | void updateRatio(); 117 | void updateFormant(); 118 | 119 | float **m_input; 120 | float **m_output; 121 | float *m_latency; 122 | float *m_cents; 123 | float *m_semitones; 124 | float *m_octaves; 125 | float *m_formant; 126 | float *m_wetDry; 127 | double m_ratio; 128 | double m_prevRatio; 129 | bool m_currentFormant; 130 | 131 | RubberBand::RubberBandLiveShifter *m_shifter; 132 | RubberBand::RingBuffer **m_irb; 133 | RubberBand::RingBuffer **m_orb; 134 | float **m_ib; 135 | float **m_ob; 136 | RubberBand::RingBuffer **m_delayMixBuffer; 137 | 138 | int m_sampleRate; 139 | int m_channels; 140 | int m_blockSize; 141 | int m_bufferSize; 142 | int m_delay; 143 | 144 | int getLatency() const; 145 | }; 146 | 147 | 148 | #endif 149 | -------------------------------------------------------------------------------- /src/finer/Peak.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_PEAK_H 25 | #define RUBBERBAND_PEAK_H 26 | 27 | #include 28 | 29 | namespace RubberBand 30 | { 31 | 32 | template > 33 | class Peak 34 | { 35 | public: 36 | /** Peak picker for array of length n. This allocates on 37 | construction an internal buffer for temporary values, to be 38 | used within the peak-picking functions, so that it does not 39 | have to allocate when used. It does not have persistent state. 40 | */ 41 | Peak(int n) : 42 | m_n(n), 43 | m_locations(n, 0) { } 44 | 45 | /** Find the nearest peak to each bin, and optionally the next 46 | highest peak above each bin, within an array v, where a peak 47 | is a value greater than the p nearest neighbours on each 48 | side. The array must have length n where n is the size passed 49 | the the constructor. 50 | */ 51 | void findNearestAndNextPeaks(const T *v, 52 | int p, 53 | int *nearest, 54 | int *next = nullptr) 55 | { 56 | findNearestAndNextPeaks(v, 0, m_n, p, nearest, next); 57 | } 58 | 59 | /** As above but consider only the range of size rangeCount from 60 | index rangeStart. Write rangeCount results into nearest and 61 | optionally next, starting to write at index rangeStart - so 62 | these arrays must have the full length even if rangeCount is 63 | shorter. Leave the rest of nearest and/or next unmodified. 64 | */ 65 | void findNearestAndNextPeaks(const T *v, 66 | int rangeStart, 67 | int rangeCount, 68 | int p, 69 | int *nearest, 70 | int *next = nullptr) 71 | { 72 | int nPeaks = 0; 73 | int n = rangeStart + rangeCount; 74 | GreaterThan greater; 75 | 76 | for (int i = rangeStart; i < n; ++i) { 77 | T x = v[i]; 78 | bool good = true; 79 | for (int k = i - p; k <= i + p; ++k) { 80 | if (k < rangeStart || k == i) continue; 81 | if (k >= n) break; 82 | if (k < i && !greater(x, v[k])) { 83 | good = false; 84 | break; 85 | } 86 | if (k > i && greater(v[k], x)) { 87 | good = false; 88 | break; 89 | } 90 | } 91 | if (good) { 92 | m_locations[nPeaks++] = i; 93 | } 94 | } 95 | 96 | int pp = rangeStart - 1; 97 | for (int i = rangeStart, j = 0; i < n; ++i) { 98 | int np = i; 99 | if (j < nPeaks) { 100 | np = m_locations[j]; 101 | } else if (nPeaks > 0) { 102 | np = m_locations[nPeaks-1]; 103 | } 104 | if (next) { 105 | if (pp == i || j >= nPeaks) { 106 | next[i] = i; 107 | } else { 108 | next[i] = np; 109 | } 110 | } 111 | if (nearest) { 112 | if (j == 0) { 113 | nearest[i] = np; 114 | } else { 115 | if (np - i <= i - pp) { 116 | nearest[i] = np; 117 | } else { 118 | nearest[i] = pp; 119 | } 120 | } 121 | } 122 | while (j < nPeaks && m_locations[j] <= i) { 123 | pp = np; 124 | ++j; 125 | } 126 | } 127 | } 128 | 129 | protected: 130 | int m_n; 131 | std::vector m_locations; 132 | }; 133 | 134 | 135 | } 136 | 137 | #endif 138 | -------------------------------------------------------------------------------- /ladspa-lv2/RubberBandR3PitchShifter.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_R3_PITCH_SHIFTER_H 25 | #define RUBBERBAND_R3_PITCH_SHIFTER_H 26 | 27 | #ifdef RB_PLUGIN_LADSPA 28 | #ifdef RB_PLUGIN_LV2 29 | #error "Only one of RB_PLUGIN_LADSPA and RB_PLUGIN_LV2 may be defined at once" 30 | #endif 31 | #else 32 | #ifndef RB_PLUGIN_LV2 33 | #error "Including code must define either RB_PLUGIN_LADSPA or RB_PLUGIN_LV2" 34 | #endif 35 | #endif 36 | 37 | #ifdef RB_PLUGIN_LADSPA 38 | #include 39 | #else 40 | #include 41 | #endif 42 | 43 | #include "common/RingBuffer.h" 44 | 45 | namespace RubberBand { 46 | class RubberBandStretcher; 47 | } 48 | 49 | class RubberBandR3PitchShifter 50 | { 51 | public: 52 | #ifdef RB_PLUGIN_LADSPA 53 | static const LADSPA_Descriptor *getDescriptor(unsigned long index); 54 | #else 55 | static const LV2_Descriptor *getDescriptor(uint32_t index); 56 | #endif 57 | 58 | protected: 59 | RubberBandR3PitchShifter(int sampleRate, size_t channels); 60 | ~RubberBandR3PitchShifter(); 61 | 62 | enum { 63 | LatencyPort = 0, 64 | CentsPort = 1, 65 | SemitonesPort = 2, 66 | OctavesPort = 3, 67 | FormantPort = 4, 68 | WetDryPort = 5, 69 | InputPort1 = 6, 70 | OutputPort1 = 7, 71 | PortCountMono = OutputPort1 + 1, 72 | InputPort2 = 8, 73 | OutputPort2 = 9, 74 | PortCountStereo = OutputPort2 + 1 75 | }; 76 | 77 | #ifdef RB_PLUGIN_LADSPA 78 | static const char *const portNamesMono[PortCountMono]; 79 | static const LADSPA_PortDescriptor portsMono[PortCountMono]; 80 | static const LADSPA_PortRangeHint hintsMono[PortCountMono]; 81 | 82 | static const char *const portNamesStereo[PortCountStereo]; 83 | static const LADSPA_PortDescriptor portsStereo[PortCountStereo]; 84 | static const LADSPA_PortRangeHint hintsStereo[PortCountStereo]; 85 | 86 | static const LADSPA_Properties properties; 87 | 88 | static const LADSPA_Descriptor ladspaDescriptorMono; 89 | static const LADSPA_Descriptor ladspaDescriptorStereo; 90 | 91 | static LADSPA_Handle instantiate(const LADSPA_Descriptor *, unsigned long); 92 | static void connectPort(LADSPA_Handle, unsigned long, LADSPA_Data *); 93 | static void activate(LADSPA_Handle); 94 | static void run(LADSPA_Handle, unsigned long); 95 | static void deactivate(LADSPA_Handle); 96 | static void cleanup(LADSPA_Handle); 97 | 98 | #else 99 | 100 | static const LV2_Descriptor lv2DescriptorMono; 101 | static const LV2_Descriptor lv2DescriptorStereo; 102 | 103 | static LV2_Handle instantiate(const LV2_Descriptor *, double, 104 | const char *, const LV2_Feature *const *); 105 | static void connectPort(LV2_Handle, uint32_t, void *); 106 | static void activate(LV2_Handle); 107 | static void run(LV2_Handle, uint32_t); 108 | static void deactivate(LV2_Handle); 109 | static void cleanup(LV2_Handle); 110 | 111 | #endif 112 | 113 | void activateImpl(); 114 | void runImpl(uint32_t count); 115 | void runImpl(uint32_t count, uint32_t offset); 116 | void updateRatio(); 117 | void updateFormant(); 118 | 119 | int getLatency() const; 120 | 121 | float **m_input; 122 | float **m_output; 123 | float *m_latency; 124 | float *m_cents; 125 | float *m_semitones; 126 | float *m_octaves; 127 | float *m_formant; 128 | float *m_wetDry; 129 | double m_ratio; 130 | double m_prevRatio; 131 | bool m_currentFormant; 132 | 133 | size_t m_blockSize; 134 | size_t m_reserve; 135 | size_t m_bufsize; 136 | size_t m_minfill; 137 | 138 | RubberBand::RubberBandStretcher *m_stretcher; 139 | RubberBand::RingBuffer **m_outputBuffer; 140 | RubberBand::RingBuffer **m_delayMixBuffer; 141 | float **m_scratch; 142 | float **m_inptrs; 143 | 144 | int m_sampleRate; 145 | size_t m_channels; 146 | }; 147 | 148 | 149 | #endif 150 | -------------------------------------------------------------------------------- /src/faster/AudioCurveCalculator.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_AUDIO_CURVE_CALCULATOR_H 25 | #define RUBBERBAND_AUDIO_CURVE_CALCULATOR_H 26 | 27 | #include 28 | 29 | #include "../common/sysutils.h" 30 | 31 | namespace RubberBand 32 | { 33 | 34 | /** 35 | * AudioCurveCalculator turns a sequence of audio "columns" -- 36 | * short-time spectrum magnitude blocks -- into a sequence of numbers 37 | * representing some quality of the input such as power or likelihood 38 | * of an onset occurring. 39 | * 40 | * These are typically low-level building-blocks: AudioCurveCalculator 41 | * is a simple causal interface in which each input column corresponds 42 | * to exactly one output value which is returned immediately. They 43 | * have far less power (because of the causal interface and 44 | * magnitude-only input) and flexibility (because of the limited 45 | * return types) than for example the Vamp plugin interface. 46 | * 47 | * AudioCurveCalculator implementations typically remember the history 48 | * of their processing data, and the caller must call reset() before 49 | * resynchronising to an unrelated piece of input audio. 50 | */ 51 | class AudioCurveCalculator 52 | { 53 | public: 54 | struct Parameters { 55 | Parameters(int _sampleRate, int _fftSize) : 56 | sampleRate(_sampleRate), 57 | fftSize(_fftSize) 58 | { } 59 | int sampleRate; 60 | int fftSize; 61 | }; 62 | 63 | AudioCurveCalculator(Parameters parameters); 64 | virtual ~AudioCurveCalculator(); 65 | 66 | int getSampleRate() const { return m_sampleRate; } 67 | int getFftSize() const { return m_fftSize; } 68 | 69 | virtual void setSampleRate(int newRate); 70 | virtual void setFftSize(int newSize); 71 | 72 | Parameters getParameters() const { 73 | return Parameters(m_sampleRate, m_fftSize); 74 | } 75 | void setParameters(Parameters p) { 76 | setSampleRate(p.sampleRate); 77 | setFftSize(p.fftSize); 78 | } 79 | 80 | // You may not mix calls to the various process functions on a 81 | // given instance 82 | 83 | 84 | /** 85 | * Process the given magnitude spectrum block and return the curve 86 | * value for it. The mag input contains (fftSize/2 + 1) values 87 | * corresponding to the magnitudes of the complex FFT output bins 88 | * for a windowed input of size fftSize. The hop (expressed in 89 | * time-domain audio samples) from the previous to the current 90 | * input block is given by increment. 91 | */ 92 | virtual float processFloat(const float *R__ mag, int increment) = 0; 93 | 94 | /** 95 | * Process the given magnitude spectrum block and return the curve 96 | * value for it. The mag input contains (fftSize/2 + 1) values 97 | * corresponding to the magnitudes of the complex FFT output bins 98 | * for a windowed input of size fftSize. The hop (expressed in 99 | * time-domain audio samples) from the previous to the current 100 | * input block is given by increment. 101 | */ 102 | virtual double processDouble(const double *R__ mag, int increment) = 0; 103 | 104 | /** 105 | * Obtain a confidence for the curve value (if applicable). A 106 | * value of 1.0 indicates perfect confidence in the curve 107 | * calculation, 0.0 indicates none. 108 | */ 109 | virtual double getConfidence() const { return 1.0; } 110 | 111 | /** 112 | * Reset the calculator, forgetting the history of the audio input 113 | * so far. 114 | */ 115 | virtual void reset() = 0; 116 | 117 | /** 118 | * If the output of this calculator has a known unit, return it as 119 | * text. For example, "Hz" or "V". 120 | */ 121 | virtual const char *getUnit() const { return ""; } 122 | 123 | protected: 124 | int m_sampleRate; 125 | int m_fftSize; 126 | int m_lastPerceivedBin; 127 | void recalculateLastPerceivedBin(); 128 | }; 129 | 130 | 131 | } 132 | 133 | #endif 134 | 135 | -------------------------------------------------------------------------------- /src/ext/kissfft/kiss_fft.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2003-2010, Mark Borgerding. All rights reserved. 3 | * This file is part of KISS FFT - https://github.com/mborgerding/kissfft 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | * See COPYING file for more information. 7 | */ 8 | 9 | #ifndef KISS_FFT_H 10 | #define KISS_FFT_H 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | // Define KISS_FFT_SHARED macro to properly export symbols 18 | #ifdef KISS_FFT_SHARED 19 | # ifdef _WIN32 20 | # ifdef KISS_FFT_BUILD 21 | # define KISS_FFT_API __declspec(dllexport) 22 | # else 23 | # define KISS_FFT_API __declspec(dllimport) 24 | # endif 25 | # else 26 | # define KISS_FFT_API __attribute__ ((visibility ("default"))) 27 | # endif 28 | #else 29 | # define KISS_FFT_API 30 | #endif 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | /* 37 | ATTENTION! 38 | If you would like a : 39 | -- a utility that will handle the caching of fft objects 40 | -- real-only (no imaginary time component ) FFT 41 | -- a multi-dimensional FFT 42 | -- a command-line utility to perform ffts 43 | -- a command-line utility to perform fast-convolution filtering 44 | 45 | Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c 46 | in the tools/ directory. 47 | */ 48 | 49 | /* User may override KISS_FFT_MALLOC and/or KISS_FFT_FREE. */ 50 | #ifdef USE_SIMD 51 | # include 52 | # define kiss_fft_scalar __m128 53 | # ifndef KISS_FFT_MALLOC 54 | # define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16) 55 | # define KISS_FFT_ALIGN_CHECK(ptr) 56 | # define KISS_FFT_ALIGN_SIZE_UP(size) ((size + 15UL) & ~0xFUL) 57 | # endif 58 | # ifndef KISS_FFT_FREE 59 | # define KISS_FFT_FREE _mm_free 60 | # endif 61 | #else 62 | # define KISS_FFT_ALIGN_CHECK(ptr) 63 | # define KISS_FFT_ALIGN_SIZE_UP(size) (size) 64 | # ifndef KISS_FFT_MALLOC 65 | # define KISS_FFT_MALLOC malloc 66 | # endif 67 | # ifndef KISS_FFT_FREE 68 | # define KISS_FFT_FREE free 69 | # endif 70 | #endif 71 | 72 | 73 | #ifdef FIXED_POINT 74 | #include 75 | # if (FIXED_POINT == 32) 76 | # define kiss_fft_scalar int32_t 77 | # else 78 | # define kiss_fft_scalar int16_t 79 | # endif 80 | #else 81 | # ifndef kiss_fft_scalar 82 | /* default is float */ 83 | # define kiss_fft_scalar float 84 | # endif 85 | #endif 86 | 87 | typedef struct { 88 | kiss_fft_scalar r; 89 | kiss_fft_scalar i; 90 | }kiss_fft_cpx; 91 | 92 | typedef struct kiss_fft_state* kiss_fft_cfg; 93 | 94 | /* 95 | * kiss_fft_alloc 96 | * 97 | * Initialize a FFT (or IFFT) algorithm's cfg/state buffer. 98 | * 99 | * typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL); 100 | * 101 | * The return value from fft_alloc is a cfg buffer used internally 102 | * by the fft routine or NULL. 103 | * 104 | * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc. 105 | * The returned value should be free()d when done to avoid memory leaks. 106 | * 107 | * The state can be placed in a user supplied buffer 'mem': 108 | * If lenmem is not NULL and mem is not NULL and *lenmem is large enough, 109 | * then the function places the cfg in mem and the size used in *lenmem 110 | * and returns mem. 111 | * 112 | * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough), 113 | * then the function returns NULL and places the minimum cfg 114 | * buffer size in *lenmem. 115 | * */ 116 | 117 | kiss_fft_cfg KISS_FFT_API kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem); 118 | 119 | /* 120 | * kiss_fft(cfg,in_out_buf) 121 | * 122 | * Perform an FFT on a complex input buffer. 123 | * for a forward FFT, 124 | * fin should be f[0] , f[1] , ... ,f[nfft-1] 125 | * fout will be F[0] , F[1] , ... ,F[nfft-1] 126 | * Note that each element is complex and can be accessed like 127 | f[k].r and f[k].i 128 | * */ 129 | void KISS_FFT_API kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); 130 | 131 | /* 132 | A more generic version of the above function. It reads its input from every Nth sample. 133 | * */ 134 | void KISS_FFT_API kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride); 135 | 136 | /* If kiss_fft_alloc allocated a buffer, it is one contiguous 137 | buffer and can be simply free()d when no longer needed*/ 138 | #define kiss_fft_free KISS_FFT_FREE 139 | 140 | /* 141 | Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up 142 | your compiler output to call this before you exit. 143 | */ 144 | void KISS_FFT_API kiss_fft_cleanup(void); 145 | 146 | 147 | /* 148 | * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5) 149 | */ 150 | int KISS_FFT_API kiss_fft_next_fast_size(int n); 151 | 152 | /* for real ffts, we need an even size */ 153 | #define kiss_fftr_next_fast_size_real(n) \ 154 | (kiss_fft_next_fast_size( ((n)+1)>>1)<<1) 155 | 156 | #ifdef __cplusplus 157 | } 158 | #endif 159 | 160 | #endif 161 | -------------------------------------------------------------------------------- /src/common/SingleThreadRingBuffer.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_SINGLE_THREAD_RINGBUFFER_H 25 | #define RUBBERBAND_SINGLE_THREAD_RINGBUFFER_H 26 | 27 | #include 28 | 29 | namespace RubberBand { 30 | 31 | /** 32 | * SingleThreadRingBuffer implements a ring buffer to be used to store 33 | * a sample type T, for reading and writing within a single 34 | * thread. SingleThreadRingBuffer is a simple container, not a 35 | * thread-safe lock-free structure: use RingBuffer for the situation 36 | * with reader and writer in separate threads. Currently this 37 | * implementation only supports reading and writing a single sample at 38 | * a time. 39 | */ 40 | template 41 | class SingleThreadRingBuffer 42 | { 43 | public: 44 | /** 45 | * Create a ring buffer with room to write n samples. 46 | * 47 | * Note that the internal storage size will actually be n+1 48 | * samples, as one element is unavailable for administrative 49 | * reasons. Since the ring buffer performs best if its size is a 50 | * power of two, this means n should ideally be some power of two 51 | * minus one. 52 | */ 53 | SingleThreadRingBuffer(int n) : 54 | m_buffer(n + 1, T()), 55 | m_writer(0), 56 | m_reader(0), 57 | m_size(n + 1) { } 58 | 59 | SingleThreadRingBuffer() : 60 | m_buffer(1, T()), 61 | m_writer(0), 62 | m_reader(0), 63 | m_size(1) { } 64 | 65 | SingleThreadRingBuffer (const SingleThreadRingBuffer &other) =default; 66 | SingleThreadRingBuffer &operator=(const SingleThreadRingBuffer &other) =default; 67 | 68 | virtual ~SingleThreadRingBuffer() { } 69 | 70 | /** 71 | * Return the total capacity of the ring buffer in samples. 72 | * (This is the argument n passed to the constructor.) 73 | */ 74 | int getSize() const { 75 | return m_size - 1; 76 | } 77 | 78 | /** 79 | * Reset read and write pointers, thus emptying the buffer. 80 | */ 81 | void reset() { 82 | m_writer = m_reader; 83 | } 84 | 85 | /** 86 | * Return the amount of data available for reading, in samples. 87 | */ 88 | int getReadSpace() const { 89 | if (m_writer > m_reader) return m_writer - m_reader; 90 | else if (m_writer < m_reader) return (m_writer + m_size) - m_reader; 91 | else return 0; 92 | } 93 | 94 | /** 95 | * Return the amount of space available for writing, in samples. 96 | */ 97 | int getWriteSpace() const { 98 | int space = (m_reader + m_size - m_writer - 1); 99 | if (space >= m_size) space -= m_size; 100 | return space; 101 | } 102 | 103 | /** 104 | * Read one sample from the buffer. If no sample is available, 105 | * silently return zero. 106 | */ 107 | T readOne() { 108 | if (m_writer == m_reader) { 109 | return {}; 110 | } 111 | auto value = m_buffer[m_reader]; 112 | if (++m_reader == m_size) m_reader = 0; 113 | return value; 114 | } 115 | 116 | /** 117 | * Pretend to read one sample from the buffer, without actually 118 | * returning it (i.e. discard the next sample). 119 | */ 120 | void skipOne() { 121 | if (m_writer == m_reader) { 122 | return; 123 | } 124 | if (++m_reader == m_size) m_reader = 0; 125 | } 126 | 127 | /** 128 | * Write one sample to the buffer. If insufficient space is 129 | * available, the sample will not be written. Returns the number 130 | * of samples actually written, i.e. 0 or 1. 131 | */ 132 | int writeOne(const T &value) { 133 | if (getWriteSpace() == 0) return 0; 134 | m_buffer[m_writer] = value; 135 | if (++m_writer == m_size) m_writer = 0; 136 | return 1; 137 | } 138 | 139 | protected: 140 | std::vector m_buffer; 141 | int m_writer; 142 | int m_reader; 143 | int m_size; 144 | }; 145 | 146 | } 147 | 148 | #endif 149 | 150 | -------------------------------------------------------------------------------- /ladspa-lv2/RubberBandPitchShifter.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_PITCH_SHIFTER_H 25 | #define RUBBERBAND_PITCH_SHIFTER_H 26 | 27 | #ifdef RB_PLUGIN_LADSPA 28 | #ifdef RB_PLUGIN_LV2 29 | #error "Only one of RB_PLUGIN_LADSPA and RB_PLUGIN_LV2 may be defined at once" 30 | #endif 31 | #else 32 | #ifndef RB_PLUGIN_LV2 33 | #error "Including code must define either RB_PLUGIN_LADSPA or RB_PLUGIN_LV2" 34 | #endif 35 | #endif 36 | 37 | #ifdef RB_PLUGIN_LADSPA 38 | #include 39 | #else 40 | #include 41 | #endif 42 | 43 | #include "common/RingBuffer.h" 44 | 45 | namespace RubberBand { 46 | class RubberBandStretcher; 47 | } 48 | 49 | class RubberBandPitchShifter 50 | { 51 | public: 52 | #ifdef RB_PLUGIN_LADSPA 53 | static const LADSPA_Descriptor *getDescriptor(unsigned long index); 54 | #else 55 | static const LV2_Descriptor *getDescriptor(uint32_t index); 56 | #endif 57 | 58 | protected: 59 | RubberBandPitchShifter(int sampleRate, size_t channels); 60 | ~RubberBandPitchShifter(); 61 | 62 | enum { 63 | LatencyPort = 0, 64 | CentsPort = 1, 65 | SemitonesPort = 2, 66 | OctavesPort = 3, 67 | CrispnessPort = 4, 68 | FormantPort = 5, 69 | WetDryPort = 6, 70 | InputPort1 = 7, 71 | OutputPort1 = 8, 72 | PortCountMono = OutputPort1 + 1, 73 | InputPort2 = 9, 74 | OutputPort2 = 10, 75 | PortCountStereo = OutputPort2 + 1 76 | }; 77 | 78 | #ifdef RB_PLUGIN_LADSPA 79 | static const char *const portNamesMono[PortCountMono]; 80 | static const LADSPA_PortDescriptor portsMono[PortCountMono]; 81 | static const LADSPA_PortRangeHint hintsMono[PortCountMono]; 82 | 83 | static const char *const portNamesStereo[PortCountStereo]; 84 | static const LADSPA_PortDescriptor portsStereo[PortCountStereo]; 85 | static const LADSPA_PortRangeHint hintsStereo[PortCountStereo]; 86 | 87 | static const LADSPA_Properties properties; 88 | 89 | static const LADSPA_Descriptor ladspaDescriptorMono; 90 | static const LADSPA_Descriptor ladspaDescriptorStereo; 91 | 92 | static LADSPA_Handle instantiate(const LADSPA_Descriptor *, unsigned long); 93 | static void connectPort(LADSPA_Handle, unsigned long, LADSPA_Data *); 94 | static void activate(LADSPA_Handle); 95 | static void run(LADSPA_Handle, unsigned long); 96 | static void deactivate(LADSPA_Handle); 97 | static void cleanup(LADSPA_Handle); 98 | 99 | #else 100 | 101 | static const LV2_Descriptor lv2DescriptorMono; 102 | static const LV2_Descriptor lv2DescriptorStereo; 103 | 104 | static LV2_Handle instantiate(const LV2_Descriptor *, double, 105 | const char *, const LV2_Feature *const *); 106 | static void connectPort(LV2_Handle, uint32_t, void *); 107 | static void activate(LV2_Handle); 108 | static void run(LV2_Handle, uint32_t); 109 | static void deactivate(LV2_Handle); 110 | static void cleanup(LV2_Handle); 111 | 112 | #endif 113 | 114 | void activateImpl(); 115 | void runImpl(uint32_t count); 116 | void runImpl(uint32_t count, uint32_t offset); 117 | void updateRatio(); 118 | void updateCrispness(); 119 | void updateFormant(); 120 | 121 | int getLatency() const; 122 | 123 | float **m_input; 124 | float **m_output; 125 | float *m_latency; 126 | float *m_cents; 127 | float *m_semitones; 128 | float *m_octaves; 129 | float *m_crispness; 130 | float *m_formant; 131 | float *m_wetDry; 132 | double m_ratio; 133 | double m_prevRatio; 134 | int m_currentCrispness; 135 | bool m_currentFormant; 136 | 137 | size_t m_blockSize; 138 | size_t m_reserve; 139 | size_t m_bufsize; 140 | size_t m_minfill; 141 | 142 | RubberBand::RubberBandStretcher *m_stretcher; 143 | RubberBand::RingBuffer **m_outputBuffer; 144 | RubberBand::RingBuffer **m_delayMixBuffer; 145 | float **m_scratch; 146 | float **m_inptrs; 147 | 148 | int m_sampleRate; 149 | size_t m_channels; 150 | }; 151 | 152 | 153 | #endif 154 | -------------------------------------------------------------------------------- /src/faster/SincWindow.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_SINC_WINDOW_H 25 | #define RUBBERBAND_SINC_WINDOW_H 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include "../common/sysutils.h" 33 | #include "../common/mathmisc.h" 34 | #include "../common/VectorOps.h" 35 | #include "../common/Allocators.h" 36 | 37 | namespace RubberBand { 38 | 39 | template 40 | class SincWindow 41 | { 42 | public: 43 | /** 44 | * Construct a sinc windower which produces a window of size n 45 | * containing the values of sinc(x) with x=0 at index n/2, such 46 | * that the distance from -pi to pi (the point at which the sinc 47 | * function first crosses zero, for negative and positive 48 | * arguments respectively) is p samples. 49 | */ 50 | SincWindow(int n, int p) : m_size(n), m_p(p), m_cache(0) { 51 | encache(); 52 | } 53 | SincWindow(const SincWindow &w) : m_size(w.m_size), m_p(w.m_p), m_cache(0) { 54 | encache(); 55 | } 56 | SincWindow &operator=(const SincWindow &w) { 57 | if (&w == this) return *this; 58 | m_size = w.m_size; 59 | m_p = w.m_p; 60 | m_cache = 0; 61 | encache(); 62 | return *this; 63 | } 64 | virtual ~SincWindow() { 65 | deallocate(m_cache); 66 | } 67 | 68 | /** 69 | * Regenerate the sinc window with the same size, but a new scale 70 | * (the p value is interpreted as for the argument of the same 71 | * name to the constructor). If p is unchanged from the previous 72 | * value, do nothing (quickly). 73 | */ 74 | inline void rewrite(int p) { 75 | if (m_p == p) return; 76 | m_p = p; 77 | encache(); 78 | } 79 | 80 | inline void cut(T *const R__ dst) const { 81 | v_multiply(dst, m_cache, m_size); 82 | } 83 | 84 | inline void cut(const T *const R__ src, T *const R__ dst) const { 85 | v_multiply(dst, src, m_cache, m_size); 86 | } 87 | 88 | inline void add(T *const R__ dst, T scale) const { 89 | v_add_with_gain(dst, m_cache, scale, m_size); 90 | } 91 | 92 | inline T getArea() const { return m_area; } 93 | inline T getValue(int i) const { return m_cache[i]; } 94 | 95 | inline int getSize() const { return m_size; } 96 | inline int getP() const { return m_p; } 97 | 98 | /** 99 | * Write a sinc window of size n with scale p (the p value is 100 | * interpreted as for the argument of the same name to the 101 | * constructor). 102 | */ 103 | static 104 | void write(T *const R__ dst, const int n, const int p) { 105 | const int half = n/2; 106 | writeHalf(dst, n, p); 107 | int target = half - 1; 108 | for (int i = half + 1; i < n; ++i) { 109 | dst[target--] = dst[i]; 110 | } 111 | const T twopi = T(2. * M_PI); 112 | T arg = T(half) * twopi / p; 113 | dst[0] = sin(arg) / arg; 114 | } 115 | 116 | protected: 117 | int m_size; 118 | int m_p; 119 | T *R__ m_cache; 120 | T m_area; 121 | 122 | /** 123 | * Write the positive half (i.e. n/2 to n-1) of a sinc window of 124 | * size n with scale p (the p value is interpreted as for the 125 | * argument of the same name to the constructor). The negative 126 | * half (indices 0 to n/2-1) of dst is left unchanged. 127 | */ 128 | static 129 | void writeHalf(T *const R__ dst, const int n, const int p) { 130 | const int half = n/2; 131 | const T twopi = T(2. * M_PI); 132 | dst[half] = T(1.0); 133 | for (int i = 1; i < half; ++i) { 134 | T arg = T(i) * twopi / p; 135 | dst[half+i] = sin(arg) / arg; 136 | } 137 | } 138 | 139 | void encache() { 140 | if (!m_cache) { 141 | m_cache = allocate(m_size); 142 | } 143 | 144 | write(m_cache, m_size, m_p); 145 | 146 | m_area = 0; 147 | for (int i = 0; i < m_size; ++i) { 148 | m_area += m_cache[i]; 149 | } 150 | m_area /= m_size; 151 | } 152 | }; 153 | 154 | } 155 | 156 | #endif 157 | -------------------------------------------------------------------------------- /src/faster/StretcherChannelData.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_STRETCHERCHANNELDATA_H 25 | #define RUBBERBAND_STRETCHERCHANNELDATA_H 26 | 27 | #include "R2Stretcher.h" 28 | 29 | #include 30 | #include 31 | 32 | namespace RubberBand 33 | { 34 | 35 | class Resampler; 36 | 37 | class R2Stretcher::ChannelData 38 | { 39 | public: 40 | /** 41 | * Construct a ChannelData structure. 42 | * 43 | * The sizes passed in here are for the time-domain analysis 44 | * window and FFT calculation, and most of the buffer sizes also 45 | * depend on them. In practice they are always powers of two, the 46 | * window and FFT sizes are either equal or generally in a 2:1 47 | * relationship either way, and except for very extreme stretches 48 | * the FFT size is either 1024, 2048 or 4096. 49 | * 50 | * The outbuf size depends on other factors as well, including 51 | * the pitch scale factor and any maximum processing block 52 | * size specified by the user of the code. 53 | */ 54 | ChannelData(size_t windowSize, 55 | size_t fftSize, 56 | size_t outbufSize); 57 | 58 | /** 59 | * Construct a ChannelData structure that can process at different 60 | * FFT sizes without requiring reallocation when the size changes. 61 | * The sizes can subsequently be changed with a call to setSizes. 62 | * Reallocation will only be necessary if setSizes is called with 63 | * values not equal to any of those passed in to the constructor. 64 | * 65 | * The outbufSize should be the maximum possible outbufSize to 66 | * avoid reallocation, which will happen if setOutbufSize is 67 | * called subsequently. 68 | */ 69 | ChannelData(const std::set &sizes, 70 | size_t initialWindowSize, 71 | size_t initialFftSize, 72 | size_t outbufSize); 73 | ~ChannelData(); 74 | 75 | /** 76 | * Reset buffers 77 | */ 78 | void reset(); 79 | 80 | /** 81 | * Set the FFT, analysis window, and buffer sizes. If this 82 | * ChannelData was constructed with a set of sizes and the given 83 | * window and FFT sizes here were among them, no reallocation will 84 | * be required. 85 | */ 86 | void setSizes(size_t windowSize, size_t fftSizes); 87 | 88 | /** 89 | * Set the outbufSize for the channel data. Reallocation will 90 | * occur. 91 | */ 92 | void setOutbufSize(size_t outbufSize); 93 | 94 | /** 95 | * Set the resampler buffer size. Default if not called is no 96 | * buffer allocated at all. 97 | */ 98 | void setResampleBufSize(size_t resamplebufSize); 99 | 100 | RingBuffer *inbuf; 101 | RingBuffer *outbuf; 102 | 103 | process_t *mag; 104 | process_t *phase; 105 | 106 | process_t *prevPhase; 107 | process_t *prevError; 108 | process_t *unwrappedPhase; 109 | 110 | float *accumulator; 111 | size_t accumulatorFill; 112 | float *windowAccumulator; 113 | float *ms; // only used when mid-side processing 114 | float *interpolator; // only used when time-domain smoothing is on 115 | int interpolatorScale; 116 | float unityResetLow; // for gradual phase-reset on unity ratio 117 | 118 | float *fltbuf; 119 | process_t *dblbuf; // owned by FFT object, only used for time domain FFT i/o 120 | process_t *envelope; // for cepstral formant shift 121 | bool unchanged; 122 | 123 | size_t prevIncrement; // only used in RT mode 124 | 125 | size_t chunkCount; 126 | size_t inCount; 127 | std::atomic inputSize; // set only after known (when data ended); -1 previously 128 | size_t outCount; 129 | 130 | std::atomic draining; 131 | std::atomic outputComplete; 132 | 133 | FFT *fft; 134 | std::map ffts; 135 | 136 | Resampler *resampler; 137 | float *resamplebuf; 138 | size_t resamplebufSize; 139 | 140 | private: 141 | void construct(const std::set &sizes, 142 | size_t initialWindowSize, size_t initialFftSize, 143 | size_t outbufSize); 144 | }; 145 | 146 | } 147 | 148 | #endif 149 | -------------------------------------------------------------------------------- /src/common/Thread.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_THREAD_H 25 | #define RUBBERBAND_THREAD_H 26 | 27 | #include 28 | 29 | #ifndef NO_THREADING 30 | 31 | #ifdef _WIN32 32 | #include 33 | #else /* !_WIN32 */ 34 | #ifdef USE_PTHREADS 35 | #include 36 | #else /* !USE_PTHREADS */ 37 | #error No thread implementation selected 38 | #endif /* !USE_PTHREADS */ 39 | #endif /* !_WIN32 */ 40 | 41 | //#define DEBUG_THREAD 1 42 | //#define DEBUG_MUTEX 1 43 | //#define DEBUG_CONDITION 1 44 | 45 | namespace RubberBand 46 | { 47 | 48 | class Thread 49 | { 50 | public: 51 | #ifdef _WIN32 52 | typedef HANDLE Id; 53 | #else 54 | #ifdef USE_PTHREADS 55 | typedef pthread_t Id; 56 | #endif 57 | #endif 58 | 59 | Thread(); 60 | virtual ~Thread(); 61 | 62 | Id id(); 63 | 64 | void start(); 65 | void wait(); 66 | 67 | static bool threadingAvailable(); 68 | 69 | protected: 70 | virtual void run() = 0; 71 | 72 | private: 73 | #ifdef _WIN32 74 | HANDLE m_id; 75 | bool m_extant; 76 | static DWORD WINAPI staticRun(LPVOID lpParam); 77 | #else 78 | #ifdef USE_PTHREADS 79 | pthread_t m_id; 80 | bool m_extant; 81 | static void *staticRun(void *); 82 | #endif 83 | #endif 84 | }; 85 | 86 | class Mutex 87 | { 88 | public: 89 | Mutex(); 90 | ~Mutex(); 91 | 92 | void lock(); 93 | void unlock(); 94 | bool trylock(); 95 | 96 | private: 97 | #ifdef _WIN32 98 | HANDLE m_mutex; 99 | #ifndef NO_THREAD_CHECKS 100 | DWORD m_lockedBy; 101 | #endif 102 | #else 103 | #ifdef USE_PTHREADS 104 | pthread_mutex_t m_mutex; 105 | #ifndef NO_THREAD_CHECKS 106 | pthread_t m_lockedBy; 107 | bool m_locked; 108 | #endif 109 | #endif 110 | #endif 111 | }; 112 | 113 | class MutexLocker 114 | { 115 | public: 116 | MutexLocker(Mutex *); 117 | ~MutexLocker(); 118 | 119 | private: 120 | Mutex *m_mutex; 121 | }; 122 | 123 | /** 124 | The Condition class bundles a condition variable and mutex. 125 | 126 | To wait on a condition, call lock(), test the termination condition 127 | if desired, then wait(). The condition will be unlocked during the 128 | wait and re-locked when wait() returns (which will happen when the 129 | condition is signalled or the timer times out). 130 | 131 | To signal a condition, call signal(). If the condition is signalled 132 | between lock() and wait(), the signal may be missed by the waiting 133 | thread. To avoid this, the signalling thread should also lock the 134 | condition before calling signal() and unlock it afterwards. 135 | */ 136 | 137 | class Condition 138 | { 139 | public: 140 | Condition(std::string name); 141 | ~Condition(); 142 | 143 | void lock(); 144 | void unlock(); 145 | void wait(int us = 0); 146 | 147 | void signal(); 148 | 149 | private: 150 | 151 | #ifdef _WIN32 152 | HANDLE m_mutex; 153 | HANDLE m_condition; 154 | bool m_locked; 155 | #else 156 | #ifdef USE_PTHREADS 157 | pthread_mutex_t m_mutex; 158 | pthread_cond_t m_condition; 159 | bool m_locked; 160 | #endif 161 | #endif 162 | #ifdef DEBUG_CONDITION 163 | std::string m_name; 164 | #endif 165 | }; 166 | 167 | } 168 | 169 | #else 170 | 171 | /* Stub threading interface. We do not have threading support in this code. */ 172 | 173 | namespace RubberBand 174 | { 175 | 176 | class Thread 177 | { 178 | public: 179 | typedef unsigned int Id; 180 | 181 | Thread() { } 182 | virtual ~Thread() { } 183 | 184 | Id id() { return 0; } 185 | 186 | void start() { } 187 | void wait() { } 188 | 189 | static bool threadingAvailable() { return false; } 190 | 191 | protected: 192 | virtual void run() = 0; 193 | 194 | private: 195 | }; 196 | 197 | class Mutex 198 | { 199 | public: 200 | Mutex() { } 201 | ~Mutex() { } 202 | 203 | void lock() { } 204 | void unlock() { } 205 | bool trylock() { return false; } 206 | }; 207 | 208 | class MutexLocker 209 | { 210 | public: 211 | MutexLocker(Mutex *) { } 212 | ~MutexLocker() { } 213 | }; 214 | 215 | class Condition 216 | { 217 | public: 218 | Condition(std::string) { } 219 | ~Condition() { } 220 | 221 | void lock() { } 222 | void unlock() { } 223 | void wait(int us = 0) { } 224 | 225 | void signal() { } 226 | }; 227 | 228 | } 229 | 230 | #endif /* NO_THREADING */ 231 | 232 | #endif 233 | -------------------------------------------------------------------------------- /src/ext/kissfft/kiss_fftr.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2003-2004, Mark Borgerding. All rights reserved. 3 | * This file is part of KISS FFT - https://github.com/mborgerding/kissfft 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | * See COPYING file for more information. 7 | */ 8 | 9 | #include "kiss_fftr.h" 10 | #include "_kiss_fft_guts.h" 11 | 12 | struct kiss_fftr_state{ 13 | kiss_fft_cfg substate; 14 | kiss_fft_cpx * tmpbuf; 15 | kiss_fft_cpx * super_twiddles; 16 | #ifdef USE_SIMD 17 | void * pad; 18 | #endif 19 | }; 20 | 21 | kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem) 22 | { 23 | KISS_FFT_ALIGN_CHECK(mem) 24 | 25 | int i; 26 | kiss_fftr_cfg st = NULL; 27 | size_t subsize = 0, memneeded; 28 | 29 | if (nfft & 1) { 30 | KISS_FFT_ERROR("Real FFT optimization must be even."); 31 | return NULL; 32 | } 33 | nfft >>= 1; 34 | 35 | kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize); 36 | memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 3 / 2); 37 | 38 | if (lenmem == NULL) { 39 | st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded); 40 | } else { 41 | if (*lenmem >= memneeded) 42 | st = (kiss_fftr_cfg) mem; 43 | *lenmem = memneeded; 44 | } 45 | if (!st) 46 | return NULL; 47 | 48 | st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */ 49 | st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize); 50 | st->super_twiddles = st->tmpbuf + nfft; 51 | kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize); 52 | 53 | for (i = 0; i < nfft/2; ++i) { 54 | double phase = 55 | -3.14159265358979323846264338327 * ((double) (i+1) / nfft + .5); 56 | if (inverse_fft) 57 | phase *= -1; 58 | kf_cexp (st->super_twiddles+i,phase); 59 | } 60 | return st; 61 | } 62 | 63 | void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata) 64 | { 65 | /* input buffer timedata is stored row-wise */ 66 | int k,ncfft; 67 | kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc; 68 | 69 | if ( st->substate->inverse) { 70 | KISS_FFT_ERROR("kiss fft usage error: improper alloc"); 71 | return;/* The caller did not call the correct function */ 72 | } 73 | 74 | ncfft = st->substate->nfft; 75 | 76 | /*perform the parallel fft of two real signals packed in real,imag*/ 77 | kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf ); 78 | /* The real part of the DC element of the frequency spectrum in st->tmpbuf 79 | * contains the sum of the even-numbered elements of the input time sequence 80 | * The imag part is the sum of the odd-numbered elements 81 | * 82 | * The sum of tdc.r and tdc.i is the sum of the input time sequence. 83 | * yielding DC of input time sequence 84 | * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1... 85 | * yielding Nyquist bin of input time sequence 86 | */ 87 | 88 | tdc.r = st->tmpbuf[0].r; 89 | tdc.i = st->tmpbuf[0].i; 90 | C_FIXDIV(tdc,2); 91 | CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i); 92 | CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i); 93 | freqdata[0].r = tdc.r + tdc.i; 94 | freqdata[ncfft].r = tdc.r - tdc.i; 95 | #ifdef USE_SIMD 96 | freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0); 97 | #else 98 | freqdata[ncfft].i = freqdata[0].i = 0; 99 | #endif 100 | 101 | for ( k=1;k <= ncfft/2 ; ++k ) { 102 | fpk = st->tmpbuf[k]; 103 | fpnk.r = st->tmpbuf[ncfft-k].r; 104 | fpnk.i = - st->tmpbuf[ncfft-k].i; 105 | C_FIXDIV(fpk,2); 106 | C_FIXDIV(fpnk,2); 107 | 108 | C_ADD( f1k, fpk , fpnk ); 109 | C_SUB( f2k, fpk , fpnk ); 110 | C_MUL( tw , f2k , st->super_twiddles[k-1]); 111 | 112 | freqdata[k].r = HALF_OF(f1k.r + tw.r); 113 | freqdata[k].i = HALF_OF(f1k.i + tw.i); 114 | freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r); 115 | freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i); 116 | } 117 | } 118 | 119 | void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata) 120 | { 121 | /* input buffer timedata is stored row-wise */ 122 | int k, ncfft; 123 | 124 | if (st->substate->inverse == 0) { 125 | KISS_FFT_ERROR("kiss fft usage error: improper alloc"); 126 | return;/* The caller did not call the correct function */ 127 | } 128 | 129 | ncfft = st->substate->nfft; 130 | 131 | st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r; 132 | st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r; 133 | C_FIXDIV(st->tmpbuf[0],2); 134 | 135 | for (k = 1; k <= ncfft / 2; ++k) { 136 | kiss_fft_cpx fk, fnkc, fek, fok, tmp; 137 | fk = freqdata[k]; 138 | fnkc.r = freqdata[ncfft - k].r; 139 | fnkc.i = -freqdata[ncfft - k].i; 140 | C_FIXDIV( fk , 2 ); 141 | C_FIXDIV( fnkc , 2 ); 142 | 143 | C_ADD (fek, fk, fnkc); 144 | C_SUB (tmp, fk, fnkc); 145 | C_MUL (fok, tmp, st->super_twiddles[k-1]); 146 | C_ADD (st->tmpbuf[k], fek, fok); 147 | C_SUB (st->tmpbuf[ncfft - k], fek, fok); 148 | #ifdef USE_SIMD 149 | st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0); 150 | #else 151 | st->tmpbuf[ncfft - k].i *= -1; 152 | #endif 153 | } 154 | kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata); 155 | } 156 | -------------------------------------------------------------------------------- /src/ext/kissfft/_kiss_fft_guts.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2003-2010, Mark Borgerding. All rights reserved. 3 | * This file is part of KISS FFT - https://github.com/mborgerding/kissfft 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | * See COPYING file for more information. 7 | */ 8 | 9 | /* kiss_fft.h 10 | defines kiss_fft_scalar as either short or a float type 11 | and defines 12 | typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */ 13 | 14 | #ifndef _kiss_fft_guts_h 15 | #define _kiss_fft_guts_h 16 | 17 | #include "kiss_fft.h" 18 | #include "kiss_fft_log.h" 19 | #include 20 | 21 | #define MAXFACTORS 32 22 | /* e.g. an fft of length 128 has 4 factors 23 | as far as kissfft is concerned 24 | 4*4*4*2 25 | */ 26 | 27 | struct kiss_fft_state{ 28 | int nfft; 29 | int inverse; 30 | int factors[2*MAXFACTORS]; 31 | kiss_fft_cpx twiddles[1]; 32 | }; 33 | 34 | /* 35 | Explanation of macros dealing with complex math: 36 | 37 | C_MUL(m,a,b) : m = a*b 38 | C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise 39 | C_SUB( res, a,b) : res = a - b 40 | C_SUBFROM( res , a) : res -= a 41 | C_ADDTO( res , a) : res += a 42 | * */ 43 | #ifdef FIXED_POINT 44 | #include 45 | #if (FIXED_POINT==32) 46 | # define FRACBITS 31 47 | # define SAMPPROD int64_t 48 | #define SAMP_MAX INT32_MAX 49 | #define SAMP_MIN INT32_MIN 50 | #else 51 | # define FRACBITS 15 52 | # define SAMPPROD int32_t 53 | #define SAMP_MAX INT16_MAX 54 | #define SAMP_MIN INT16_MIN 55 | #endif 56 | 57 | #if defined(CHECK_OVERFLOW) 58 | # define CHECK_OVERFLOW_OP(a,op,b) \ 59 | if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \ 60 | KISS_FFT_WARNING("overflow (%d " #op" %d) = %ld", (a),(b),(SAMPPROD)(a) op (SAMPPROD)(b)); } 61 | #endif 62 | 63 | 64 | # define smul(a,b) ( (SAMPPROD)(a)*(b) ) 65 | # define sround( x ) (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS ) 66 | 67 | # define S_MUL(a,b) sround( smul(a,b) ) 68 | 69 | # define C_MUL(m,a,b) \ 70 | do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \ 71 | (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0) 72 | 73 | # define DIVSCALAR(x,k) \ 74 | (x) = sround( smul( x, SAMP_MAX/k ) ) 75 | 76 | # define C_FIXDIV(c,div) \ 77 | do { DIVSCALAR( (c).r , div); \ 78 | DIVSCALAR( (c).i , div); }while (0) 79 | 80 | # define C_MULBYSCALAR( c, s ) \ 81 | do{ (c).r = sround( smul( (c).r , s ) ) ;\ 82 | (c).i = sround( smul( (c).i , s ) ) ; }while(0) 83 | 84 | #else /* not FIXED_POINT*/ 85 | 86 | # define S_MUL(a,b) ( (a)*(b) ) 87 | #define C_MUL(m,a,b) \ 88 | do{ (m).r = (a).r*(b).r - (a).i*(b).i;\ 89 | (m).i = (a).r*(b).i + (a).i*(b).r; }while(0) 90 | # define C_FIXDIV(c,div) /* NOOP */ 91 | # define C_MULBYSCALAR( c, s ) \ 92 | do{ (c).r *= (s);\ 93 | (c).i *= (s); }while(0) 94 | #endif 95 | 96 | #ifndef CHECK_OVERFLOW_OP 97 | # define CHECK_OVERFLOW_OP(a,op,b) /* noop */ 98 | #endif 99 | 100 | #define C_ADD( res, a,b)\ 101 | do { \ 102 | CHECK_OVERFLOW_OP((a).r,+,(b).r)\ 103 | CHECK_OVERFLOW_OP((a).i,+,(b).i)\ 104 | (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ 105 | }while(0) 106 | #define C_SUB( res, a,b)\ 107 | do { \ 108 | CHECK_OVERFLOW_OP((a).r,-,(b).r)\ 109 | CHECK_OVERFLOW_OP((a).i,-,(b).i)\ 110 | (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ 111 | }while(0) 112 | #define C_ADDTO( res , a)\ 113 | do { \ 114 | CHECK_OVERFLOW_OP((res).r,+,(a).r)\ 115 | CHECK_OVERFLOW_OP((res).i,+,(a).i)\ 116 | (res).r += (a).r; (res).i += (a).i;\ 117 | }while(0) 118 | 119 | #define C_SUBFROM( res , a)\ 120 | do {\ 121 | CHECK_OVERFLOW_OP((res).r,-,(a).r)\ 122 | CHECK_OVERFLOW_OP((res).i,-,(a).i)\ 123 | (res).r -= (a).r; (res).i -= (a).i; \ 124 | }while(0) 125 | 126 | 127 | #ifdef FIXED_POINT 128 | # define KISS_FFT_COS(phase) floor(.5+SAMP_MAX * cos (phase)) 129 | # define KISS_FFT_SIN(phase) floor(.5+SAMP_MAX * sin (phase)) 130 | # define HALF_OF(x) ((x)>>1) 131 | #elif defined(USE_SIMD) 132 | # define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) ) 133 | # define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) ) 134 | # define HALF_OF(x) ((x)*_mm_set1_ps(.5)) 135 | #else 136 | # define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase) 137 | # define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase) 138 | # define HALF_OF(x) ((x)*((kiss_fft_scalar).5)) 139 | #endif 140 | 141 | #define kf_cexp(x,phase) \ 142 | do{ \ 143 | (x)->r = KISS_FFT_COS(phase);\ 144 | (x)->i = KISS_FFT_SIN(phase);\ 145 | }while(0) 146 | 147 | 148 | /* a debugging function */ 149 | #define pcpx(c)\ 150 | KISS_FFT_DEBUG("%g + %gi\n",(double)((c)->r),(double)((c)->i)) 151 | 152 | 153 | #ifdef KISS_FFT_USE_ALLOCA 154 | // define this to allow use of alloca instead of malloc for temporary buffers 155 | // Temporary buffers are used in two case: 156 | // 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5 157 | // 2. "in-place" FFTs. Notice the quotes, since kissfft does not really do an in-place transform. 158 | #include 159 | #define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes) 160 | #define KISS_FFT_TMP_FREE(ptr) 161 | #else 162 | #define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes) 163 | #define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr) 164 | #endif 165 | 166 | #endif /* _kiss_fft_guts_h */ 167 | 168 | -------------------------------------------------------------------------------- /src/common/FFT.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_FFT_H 25 | #define RUBBERBAND_FFT_H 26 | 27 | #include "sysutils.h" 28 | 29 | #include 30 | #include 31 | 32 | namespace RubberBand { 33 | 34 | class FFTImpl; 35 | 36 | /** 37 | * Provide the basic FFT computations we need, using one of a set of 38 | * candidate FFT implementations (depending on compile flags). 39 | * 40 | * Implements real->complex FFTs of power-of-two sizes only. Note 41 | * that only the first half of the output signal is returned (the 42 | * complex conjugates half is omitted), so the "complex" arrays need 43 | * room for size/2+1 elements. 44 | * 45 | * The "interleaved" functions use the format sometimes called CCS -- 46 | * size/2+1 real+imaginary pairs. So, the array elements at indices 1 47 | * and size+1 will always be zero (since the signal is real). 48 | * 49 | * All pointer arguments must point to valid data. A NullArgument 50 | * exception is thrown if any argument is NULL. 51 | * 52 | * Neither forward nor inverse transform is scaled. 53 | * 54 | * This class is reentrant but not thread safe: use a separate 55 | * instance per thread, or use a mutex. 56 | */ 57 | class FFT 58 | { 59 | public: 60 | enum Exception { 61 | NullArgument, InvalidSize, InvalidImplementation, InternalError 62 | }; 63 | 64 | FFT(int size, int debugLevel = 0); // may throw InvalidSize 65 | ~FFT(); 66 | 67 | int getSize() const; 68 | 69 | void forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut); 70 | void forwardInterleaved(const double *R__ realIn, double *R__ complexOut); 71 | void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut); 72 | void forwardMagnitude(const double *R__ realIn, double *R__ magOut); 73 | 74 | void forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut); 75 | void forwardInterleaved(const float *R__ realIn, float *R__ complexOut); 76 | void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut); 77 | void forwardMagnitude(const float *R__ realIn, float *R__ magOut); 78 | 79 | void inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ realOut); 80 | void inverseInterleaved(const double *R__ complexIn, double *R__ realOut); 81 | void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut); 82 | void inverseCepstral(const double *R__ magIn, double *R__ cepOut); 83 | 84 | void inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOut); 85 | void inverseInterleaved(const float *R__ complexIn, float *R__ realOut); 86 | void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut); 87 | void inverseCepstral(const float *R__ magIn, float *R__ cepOut); 88 | 89 | // Calling one or both of these is optional -- if neither is 90 | // called, the first call to a forward or inverse method will call 91 | // init(). You only need call these if you don't want to risk 92 | // expensive allocations etc happening in forward or inverse. 93 | void initFloat(); 94 | void initDouble(); 95 | 96 | enum Precision { 97 | SinglePrecision = 0x1, 98 | DoublePrecision = 0x2 99 | }; 100 | typedef int Precisions; 101 | 102 | /** 103 | * Return the OR of all precisions supported by this 104 | * implementation. All of the functions (float and double) are 105 | * available regardless of the supported implementations, but they 106 | * will be calculated at the proper precision only if it is 107 | * available. (So float functions will be calculated using doubles 108 | * and then truncated if single-precision is unavailable, and 109 | * double functions will use single-precision arithmetic if double 110 | * is unavailable.) 111 | */ 112 | Precisions getSupportedPrecisions() const; 113 | 114 | static std::set getImplementations(); 115 | static std::string getDefaultImplementation(); 116 | static void setDefaultImplementation(std::string); 117 | 118 | #ifdef FFT_MEASUREMENT 119 | static std::string tune(); 120 | #endif 121 | 122 | protected: 123 | FFTImpl *d; 124 | static std::string m_implementation; 125 | static void pickDefaultImplementation(); 126 | 127 | private: 128 | FFT(const FFT &); // not provided 129 | FFT &operator=(const FFT &); // not provided 130 | }; 131 | 132 | } 133 | 134 | #endif 135 | 136 | -------------------------------------------------------------------------------- /src/finer/BinSegmenter.h: -------------------------------------------------------------------------------- 1 | /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 | 3 | /* 4 | Rubber Band Library 5 | An audio time-stretching and pitch-shifting library. 6 | Copyright 2007-2024 Particular Programs Ltd. 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of the 11 | License, or (at your option) any later version. See the file 12 | COPYING included with this distribution for more information. 13 | 14 | Alternatively, if you have a valid commercial licence for the 15 | Rubber Band Library obtained by agreement with the copyright 16 | holders, you may redistribute and/or modify it under the terms 17 | described in that licence. 18 | 19 | If you wish to distribute code using the Rubber Band Library 20 | under terms other than those of the GNU General Public License, 21 | you must obtain a valid commercial licence before doing so. 22 | */ 23 | 24 | #ifndef RUBBERBAND_BIN_SEGMENTER_H 25 | #define RUBBERBAND_BIN_SEGMENTER_H 26 | 27 | #include "BinClassifier.h" 28 | 29 | #include "../common/HistogramFilter.h" 30 | #include "../common/mathmisc.h" 31 | #include "../common/Profiler.h" 32 | 33 | #include 34 | 35 | namespace RubberBand { 36 | 37 | class BinSegmenter 38 | { 39 | public: 40 | struct Segmentation { 41 | double percussiveBelow; 42 | double percussiveAbove; 43 | double residualAbove; 44 | explicit Segmentation() : 45 | percussiveBelow(0.0), percussiveAbove(0.0), residualAbove(0.0) { } 46 | Segmentation(double _pb, double _pa, double _ra) : 47 | percussiveBelow(_pb), percussiveAbove(_pa), residualAbove(_ra) { } 48 | }; 49 | 50 | struct Parameters { 51 | int fftSize; 52 | int binCount; 53 | double sampleRate; 54 | int classFilterLength; 55 | Parameters(int _fftSize, int _binCount, double _sampleRate, 56 | int _classFilterLength) : 57 | fftSize(_fftSize), binCount(_binCount), sampleRate(_sampleRate), 58 | classFilterLength(_classFilterLength) { } 59 | }; 60 | 61 | BinSegmenter(Parameters parameters) : 62 | m_parameters(parameters), 63 | m_numeric(m_parameters.binCount, 0), 64 | m_classFilter(3, m_parameters.classFilterLength) 65 | { 66 | } 67 | 68 | Segmentation segment(const BinClassifier::Classification *classification) { 69 | 70 | Profiler profiler("BinSegmenter::segment"); 71 | 72 | int n = m_parameters.binCount; 73 | for (int i = 0; i < n; ++i) { 74 | switch (classification[i]) { 75 | case BinClassifier::Classification::Harmonic: 76 | m_numeric[i] = 0; break; 77 | case BinClassifier::Classification::Percussive: 78 | m_numeric[i] = 1; break; 79 | default: 80 | m_numeric[i] = 2; break; 81 | } 82 | } 83 | HistogramFilter::modalFilter(m_classFilter, m_numeric); 84 | /* 85 | std::cout << "c:"; 86 | for (int i = 0; i < n; ++i) { 87 | if (i > 0) std::cout << ","; 88 | std::cout << m_numeric[i]; 89 | } 90 | std::cout << std::endl; 91 | */ 92 | double f0 = 0.0; 93 | for (int i = 1; i < n; ++i) { 94 | if (m_numeric[i] != 1) { // percussive 95 | if (i == 1 && m_numeric[0] != 1) { // percussive 96 | f0 = 0.0; 97 | } else { 98 | f0 = frequencyForBin 99 | (i, m_parameters.fftSize, m_parameters.sampleRate); 100 | } 101 | break; 102 | } 103 | } 104 | double nyquist = m_parameters.sampleRate / 2.0; 105 | double f1 = nyquist; 106 | double f2 = nyquist; 107 | bool inPercussive = false; 108 | for (int i = n - 1; i > 0; --i) { 109 | int c = m_numeric[i]; 110 | if (!inPercussive) { 111 | if (c == 2) { // residual 112 | continue; 113 | } else if (c == 1) { // percussive 114 | inPercussive = true; 115 | f2 = frequencyForBin 116 | (i, m_parameters.fftSize, m_parameters.sampleRate); 117 | } else { // harmonic 118 | f1 = f2 = frequencyForBin 119 | (i, m_parameters.fftSize, m_parameters.sampleRate); 120 | break; 121 | } 122 | } else { // inPercussive 123 | if (c != 1) { // non-percussive 124 | f1 = frequencyForBin 125 | (i, m_parameters.fftSize, m_parameters.sampleRate); 126 | break; 127 | } 128 | } 129 | } 130 | if (f1 == nyquist && f2 < nyquist) { 131 | f1 = 0.0; 132 | } 133 | 134 | // std::cout << "f0 = " << f0 << ", f1 = " << f1 << ", f2 = " << f2 << std::endl; 135 | 136 | return Segmentation(f0, f1, f2); 137 | } 138 | 139 | protected: 140 | Parameters m_parameters; 141 | std::vector m_numeric; 142 | HistogramFilter m_classFilter; 143 | 144 | BinSegmenter(const BinSegmenter &) =delete; 145 | BinSegmenter &operator=(const BinSegmenter &) =delete; 146 | }; 147 | 148 | } 149 | 150 | #endif 151 | --------------------------------------------------------------------------------