Compare commits

..

17 Commits

Author SHA1 Message Date
4e1bb95234 build: simple build using CMake (manually add src/ext/libsndfile)
Some checks failed
macOS and iOS CI / build (push) Has been cancelled
Windows CI / build (push) Has been cancelled
2026-03-07 00:20:05 +01:00
Chris Cannam
e4296ac80b Additional IPP path 2025-02-27 11:04:40 +00:00
Chris Cannam
a19a891b36 Added tag v4.0.0 for changeset 1ea255850558 2024-10-25 21:37:48 +01:00
Chris Cannam
1d95888bec Versions 2024-10-25 17:26:08 +01:00
Chris Cannam
8c4dc5cbb0 Doc updates 2024-10-25 17:23:38 +01:00
Chris Cannam
cdde17c3dc Update CHANGELOG 2024-10-25 16:45:13 +01:00
Chris Cannam
4febe52001 Update for VS2022 2024-10-25 16:10:35 +01:00
Chris Cannam
7d32166d2a Avoid compiler warning 2024-10-25 16:10:13 +01:00
Chris Cannam
ce06adba87 Add reference to RubberBandLiveShifter 2024-10-11 17:20:58 +01:00
Chris Cannam
48e08a5113 Merge from branch rblive 2024-10-03 09:33:24 +01:00
Chris Cannam
28fa720e93 More output 2024-10-03 09:21:12 +01:00
Chris Cannam
05acd21738 Exercise JNI in the CI build as well 2024-10-03 09:21:07 +01:00
Chris Cannam
ab27a6485d Use a newer Meson 2024-10-03 09:20:53 +01:00
Chris Cannam
1d28a7c43b Get JNI build working in test 2024-10-03 09:14:35 +01:00
Chris Cannam
923a196f8f Add live shifter to JNI 2024-10-02 18:22:06 +01:00
Chris Cannam
4353ddd78d Add live shifter to C API 2024-10-02 11:29:01 +01:00
Chris Cannam
a28c9e4909 Merge from default branch 2024-10-02 11:17:11 +01:00
30 changed files with 699 additions and 66 deletions

View File

@@ -8,11 +8,18 @@ packages:
- lv2-dev
- vamp-plugin-sdk
- libboost-test-dev
- meson
- ninja-build
- openjdk-21-jdk
- wget
sources:
- hg+https://hg.sr.ht/~breakfastquay/rubberband
tasks:
- install-meson: |
mkdir -p tmp/meson
cd tmp/meson
wget https://github.com/mesonbuild/meson/releases/download/1.5.2/meson-1.5.2.tar.gz
tar xvf meson-1.5.2.tar.gz
sudo ln -s $(pwd)/meson-1.5.2/meson.py /usr/bin/meson
- setup: |
cd rubberband
meson setup build
@@ -24,6 +31,7 @@ tasks:
cd rubberband
ninja -C build
meson test -C build
java -Djava.library.path=build -cp build/rubberband-test.jar com.breakfastquay.rubberband.test.RubberBandTest
build/rubberband -V
ninja -C build_speex
meson test -C build_speex

View File

@@ -31,3 +31,4 @@ playlist-out/*
formant-out-*/
out*.wav
packages/
otherbuilds/docker/Dockerfile

View File

@@ -37,3 +37,4 @@ d2aebfc83e21e7ce597cdb59029eb8500e53c24c v3.1.2
46d8430844d6454ed140d4e8631372a6c65e856a v3.2.0
83d096887e1b9042f9e4a8f1b975d18539e82f22 v3.2.1
55367f2e76c9ee79582c8bebdd63b14c98e459be v3.3.0
1ea2558505589ca7dab9fd6dd6facd97cd119aaf v4.0.0

View File

@@ -1,4 +1,23 @@
Changes in Rubber Band v4.0
This release adds a new API that is simpler than the existing one in
cases where only pitch-shifting is required.
* Add a new API, RubberBandLiveShifter, which is simpler to use
than the general RubberBandStretcher interface in cases where only
pitch-shifting is required. For more general purposes the original
interface is still the proper one.
* Fix incorrect URIs in LV2 plugins
* Fix stack overflow in seldom used R2 time-domain smoothing code
* Add support for key-frame maps (and the live shifter) to JNI interface
* Fix some compatibility issues and warnings with certain compilers
Apart from this entirely new class, the rest of the API is unchanged
and the library is binary compatible with existing code back to
version 1.7.
Changes in Rubber Band v3.3
This is a bug-fix release with no changes to audio quality.

61
CMakeLists.txt Normal file
View File

@@ -0,0 +1,61 @@
cmake_minimum_required(VERSION 4.1)
project(rubberband)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_FLAGS "-DUSE_BQRESAMPLER -DHAVE_KISSFFT")
#include_directories(mpg123/lib/x86_64/include)
include_directories(
./dotnet/rubberband-dll
./ladspa-lv2
./rubberband
./src/common
./src/ext/float_cast
./src/ext/getopt
./src/ext/kissfft
./src/ext/pommier
./src/ext/speex
./src/faster
./src/finer
./vamp
)
add_executable(rubberband
./src/ext/getopt/getopt.c
./src/ext/getopt/getopt_long.c
./src/ext/kissfft/kiss_fft.c
./src/ext/kissfft/kiss_fftr.c
./src/ext/speex/resample.c
./main/main.cpp
./src/common/Allocators.cpp
./src/common/BQResampler.cpp
./src/common/FFT.cpp
./src/common/Log.cpp
./src/common/mathmisc.cpp
./src/common/Profiler.cpp
./src/common/Resampler.cpp
./src/common/StretchCalculator.cpp
./src/common/sysutils.cpp
./src/common/Thread.cpp
./src/common/VectorOpsComplex.cpp
./src/faster/AudioCurveCalculator.cpp
./src/faster/CompoundAudioCurve.cpp
./src/faster/HighFrequencyAudioCurve.cpp
./src/faster/PercussiveAudioCurve.cpp
./src/faster/R2Stretcher.cpp
./src/faster/SilentAudioCurve.cpp
./src/faster/StretcherChannelData.cpp
./src/faster/StretcherProcess.cpp
./src/finer/R3LiveShifter.cpp
./src/finer/R3Stretcher.cpp
./src/rubberband-c.cpp
./src/RubberBandLiveShifter.cpp
./src/RubberBandStretcher.cpp
)
#target_link_directories(rubberband PRIVATE mpg123/lib/x86_64)
#target_link_libraries(test_lockstep mpg123-0)
#target_link_libraries(rubberband ${CMAKE_SOURCE_DIR}/mpg123/lib/x86_64/libmpg123.dll.a)
add_subdirectory(src/ext/libsndfile)
target_link_libraries(rubberband sndfile)

View File

@@ -31,7 +31,7 @@ PROJECT_NAME = "Rubber Band Library"
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = 3.3.0
PROJECT_NUMBER = 4.0.0
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.

View File

@@ -146,25 +146,29 @@ numerical argument from 0 to 6).
## 3. Using Rubber Band Library
Rubber Band has a public API that consists of one C++ class, called
`RubberBandStretcher` in the `RubberBand` namespace. You should
`#include <rubberband/RubberBandStretcher.h>` to use this class.
There is extensive documentation in the class header.
Rubber Band has a public API that consists of two C++ classes living
in the `RubberBand` namespace, called `RubberBandStretcher` and
`RubberBandLiveShifter`. The former is the main Rubber Band class for
general time and pitch manipulation, the latter a simpler API for
block-by-block pitch-shifting. You should `#include
<rubberband/RubberBandStretcher.h>` or
`<rubberband/RubberBandLiveShifter.h>` to use these classes. There is
extensive documentation in the headers.
A header with C language bindings is also provided in
`<rubberband/rubberband-c.h>`. This is a wrapper around the C++
implementation, and as the implementation is the same, it also
requires linkage against the C++ standard libraries. It is not yet
documented separately from the C++ header. You should include only
one of the two headers, not both.
documented separately from the C++ headers. You should include either
C++ or C headers, not both.
A .NET interface is also included, contributed by Jonathan Gilbert;
see the files in the `dotnet` directory for details.
The source code for the command-line utility (`main/main.cpp`)
provides a good example of how to use Rubber Band in offline mode; the
pitch shifter plugin (`ladspa-lv2/RubberBandPitchShifter.cpp`) may be
used as an example of Rubber Band in real-time mode.
provides an example of how to use Rubber Band in offline mode; the
pitch shifter plugins (in `ladspa-lv2`) may be used examples of Rubber
Band in real-time mode.
**IMPORTANT:** Please ensure you have read and understood the
licensing terms for Rubber Band before using it in your application.

View File

@@ -0,0 +1,70 @@
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
/*
Rubber Band Library
An audio time-stretching and pitch-shifting library.
Copyright 2007-2022 Particular Programs Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version. See the file
COPYING included with this distribution for more information.
Alternatively, if you have a valid commercial licence for the
Rubber Band Library obtained by agreement with the copyright
holders, you may redistribute and/or modify it under the terms
described in that licence.
If you wish to distribute code using the Rubber Band Library
under terms other than those of the GNU General Public License,
you must obtain a valid commercial licence before doing so.
*/
package com.breakfastquay.rubberband;
public class RubberBandLiveShifter
{
public RubberBandLiveShifter(int sampleRate, int channels,
int options) {
handle = 0;
initialise(sampleRate, channels, options);
}
public native void dispose();
public native void reset();
public native void setPitchScale(double scale);
public native int getChannelCount();
public native double getPitchScale();
public native int getStartDelay();
public native void setFormantOption(int options);
public native int getBlockSize();
public native void shift(float[][] input, int inOffset, float[][] output, int outOffset);
public void shift(float[][] input, float[][] output) {
shift(input, 0, output, 0);
}
private native void initialise(int sampleRate, int channels, int options);
private long handle;
public static final int OptionWindowShort = 0x00000000;
public static final int OptionWindowMedium = 0x00100000;
public static final int OptionFormantShifted = 0x00000000;
public static final int OptionFormantPreserved = 0x01000000;
public static final int OptionChannelsApart = 0x00000000;
public static final int OptionChannelsTogether = 0x10000000;
static {
System.loadLibrary("rubberband-jni");
}
};

View File

@@ -2,13 +2,13 @@
package com.breakfastquay.rubberband.test;
import com.breakfastquay.rubberband.RubberBandStretcher;
import com.breakfastquay.rubberband.RubberBandLiveShifter;
import java.util.TreeMap;
public class RubberBandTest
{
public static void main(String[] args) {
public static void exerciseStretcher() {
int channels = 1;
int rate = 44100;
@@ -24,7 +24,7 @@ public class RubberBandTest
stretcher.setTimeRatio(1.5);
stretcher.setPitchScale(0.8);
System.err.println
System.out.println
(String.format("Channel count: %d\n" +
"Time ratio: %f\n" +
"Pitch scale: %f\n" +
@@ -72,6 +72,9 @@ public class RubberBandTest
i0 = 0;
double sqrtotal = 0.0;
int n = 0;
for (int block = 0; block < blocks; ++block) {
for (int c = 0; c < channels; ++c) {
@@ -98,13 +101,91 @@ public class RubberBandTest
}
int obtained = stretcher.retrieve(buffer, 0, requested);
for (int i = 0; i < obtained; ++i) {
System.out.println(Float.toString(buffer[0][i]));
sqrtotal += (double)(buffer[0][i] * buffer[0][i]);
++n;
}
}
}
System.out.println
(String.format("in = %d, out = %d, rms = %f",
blocksize * blocks, n,
Math.sqrt(sqrtotal / (double)n)));
stretcher.dispose();
}
public static void exerciseLiveShifter() {
int channels = 1;
int rate = 44100;
RubberBandLiveShifter shifter = new RubberBandLiveShifter
(rate,
channels,
0);
shifter.setPitchScale(0.8);
System.out.println
(String.format("Channel count: %d\n" +
"Pitch scale: %f\n" +
"Block size: %d\n" +
"Start delay: %d",
shifter.getChannelCount(),
shifter.getPitchScale(),
shifter.getBlockSize(),
shifter.getStartDelay()
));
int blocksize = shifter.getBlockSize();
int blocks = 400;
double freq = 440.0;
float[][] inbuf = new float[channels][blocksize];
float[][] outbuf = new float[channels][blocksize];
int i0 = 0;
double sqrtotal = 0.0;
int n = 0;
for (int block = 0; block < blocks; ++block) {
for (int c = 0; c < channels; ++c) {
for (int i = 0; i < blocksize; ++i) {
inbuf[c][i] = (float)Math.sin
((double)i0 * freq * Math.PI * 2.0 / (double)rate);
if (i0 % rate == 0) {
inbuf[c][i] = 1.f;
}
++i0;
}
}
shifter.shift(inbuf, outbuf);
for (int i = 0; i < blocksize; ++i) {
sqrtotal += (double)(outbuf[0][i] * outbuf[0][i]);
++n;
}
}
System.out.println
(String.format("in = %d, out = %d, rms = %f",
blocksize * blocks, n,
Math.sqrt(sqrtotal / (double)n)));
shifter.dispose();
}
public static void main(String[] args) {
System.out.println("Exercising RubberBandStretcher through JNI...");
exerciseStretcher();
System.out.println("Exercising RubberBandLiveShifter through JNI...");
exerciseLiveShifter();
System.out.println("Done");
}
}

View File

@@ -134,8 +134,8 @@ rubberband:mono
doap:developer :maker ;
doap:maintainer :maker ;
# Minor version will be 2x the Rubber Band API minor version
lv2:minorVersion 4 ;
lv2:microVersion 2 ;
lv2:minorVersion 6 ;
lv2:microVersion 1 ;
lv2:optionalFeature lv2:hardRTCapable ;
pg:mainInput rubberband:mono_in_group ;
pg:mainOutput rubberband:mono_out_group ;
@@ -172,8 +172,8 @@ rubberband:r3mono
doap:developer :maker ;
doap:maintainer :maker ;
# Minor version will be 2x the Rubber Band API minor version
lv2:minorVersion 4 ;
lv2:microVersion 2 ;
lv2:minorVersion 6 ;
lv2:microVersion 1 ;
lv2:optionalFeature lv2:hardRTCapable ;
pg:mainInput rubberband:mono_in_group ;
pg:mainOutput rubberband:mono_out_group ;
@@ -209,7 +209,7 @@ rubberband:livemono
doap:developer :maker ;
doap:maintainer :maker ;
# Minor version will be 2x the Rubber Band API minor version
lv2:minorVersion 4 ;
lv2:minorVersion 6 ;
lv2:microVersion 1 ;
lv2:optionalFeature lv2:hardRTCapable ;
pg:mainInput rubberband:mono_in_group ;
@@ -246,8 +246,8 @@ rubberband:stereo
doap:developer :maker ;
doap:maintainer :maker ;
# Minor version will be 2x the Rubber Band API minor version
lv2:minorVersion 4 ;
lv2:microVersion 2 ;
lv2:minorVersion 6 ;
lv2:microVersion 1 ;
lv2:optionalFeature lv2:hardRTCapable ;
pg:mainInput rubberband:stereo_in_group ;
pg:mainOutput rubberband:stereo_out_group ;
@@ -299,8 +299,8 @@ rubberband:r3stereo
doap:developer :maker ;
doap:maintainer :maker ;
# Minor version will be 2x the Rubber Band API minor version
lv2:minorVersion 4 ;
lv2:microVersion 2 ;
lv2:minorVersion 6 ;
lv2:microVersion 1 ;
lv2:optionalFeature lv2:hardRTCapable ;
pg:mainInput rubberband:stereo_in_group ;
pg:mainOutput rubberband:stereo_out_group ;
@@ -351,7 +351,7 @@ rubberband:livestereo
doap:developer :maker ;
doap:maintainer :maker ;
# Minor version will be 2x the Rubber Band API minor version
lv2:minorVersion 4 ;
lv2:minorVersion 6 ;
lv2:microVersion 1 ;
lv2:optionalFeature lv2:hardRTCapable ;
pg:mainInput rubberband:stereo_in_group ;

View File

@@ -49,6 +49,7 @@ using RubberBand::gettimeofday;
#endif
#ifdef _MSC_VER
#define NOMINMAX
#include <windows.h>
static void usleep(unsigned long usec) {
::Sleep(usec == 0 ? 0 : usec < 1000 ? 1 : usec / 1000);

View File

@@ -63,6 +63,7 @@ jni_sources = [
java_sources = [
'com/breakfastquay/rubberband/RubberBandStretcher.java',
'com/breakfastquay/rubberband/RubberBandLiveShifter.java',
]
java_test_sources = [
@@ -371,7 +372,8 @@ if ipp_needed
feature_defines += [
'-DHAVE_IPP',
'-DUSE_IPP_STATIC',
'-I' + ipp_path / 'include'
'-I' + ipp_path / 'include',
'-I' + ipp_path / 'include/ipp',
]
if architecture == 'x86'
feature_libraries += [

View File

@@ -5,7 +5,7 @@ set STARTPWD=%CD%
set ORIGINALPATH=%PATH%
set PATH=C:\Program Files (x86)\Windows Kits\10\bin\x64;%PATH%
set vcvarsall="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat"
set vcvarsall="C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat"
if not exist %vcvarsall% (
@ echo "Could not find MSVC vars batch file"
@@ -26,7 +26,7 @@ if errorlevel 1 exit /b %errorlevel%
del /q /s build
meson build --buildtype release "-Dextra_include_dirs=C:\Program Files\libsndfile\include" "-Dextra_lib_dirs=C:\Program Files\libsndfile\lib" "-Db_vscrt=mt"
meson setup build --buildtype release "-Dextra_include_dirs=C:\Program Files\libsndfile\include" "-Dextra_lib_dirs=C:\Program Files\libsndfile\lib" "-Db_vscrt=mt"
if errorlevel 1 exit /b %errorlevel%
ninja -C build

View File

@@ -0,0 +1,39 @@
FROM ubuntu:22.04
MAINTAINER Chris Cannam <cannam@all-day-breakfast.com>
RUN apt-get update && \
apt-get install -y \
software-properties-common \
build-essential \
pkg-config \
libsamplerate0-dev \
libsndfile1-dev \
libfftw3-dev \
ladspa-sdk \
lv2-dev \
vamp-plugin-sdk \
libboost-test-dev \
mercurial \
ninja-build \
plocate
RUN apt-get install -y \
openjdk-21-jdk
WORKDIR /root
ADD https://github.com/mesonbuild/meson/releases/download/1.5.2/meson-1.5.2.tar.gz .
RUN tar xvf meson-1.5.2.tar.gz
RUN ln -s $(pwd)/meson-1.5.2/meson.py /usr/bin/meson
RUN hg clone -u [[REVISION]] https://hg.sr.ht/~breakfastquay/rubberband
WORKDIR rubberband
RUN meson setup build
RUN ninja -C build
RUN meson test -C build
WORKDIR build
RUN java -Djava.library.path=$(pwd) -cp rubberband-test.jar com.breakfastquay.rubberband.test.RubberBandTest

8
otherbuilds/docker/run.sh Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/sh
revision=$(hg id | sed 's/[^0-9a-z].*$//')
cat Dockerfile.in | perl -p -e "s/\[\[REVISION\]\]/$revision/g" > Dockerfile
sudo docker build -f Dockerfile .

View File

@@ -51,9 +51,10 @@ namespace RubberBand
* Band Library designed for applications that need to perform
* pitch-shifting only, without time-stretching, and to do so in a
* straightforward block-by-block process with the shortest available
* processing delay.
* processing delay. For the more general interface, see
* RubberBand::RubberBandStretcher.
*
* RubberBandLiveShifter has a much simpler API than the general
* RubberBandLiveShifter has a much simpler API than
* RubberBandStretcher. Its process function, called
* RubberBandLiveShifter::shift(), accepts a fixed number of sample
* frames on each call and always returns exactly the same number of
@@ -61,12 +62,12 @@ namespace RubberBand
* process/available/retrieve call sequence that RubberBandStretcher
* requires as a result of its variable output rate.
*
* The number of frames RubberBandLiveShifter::shift() accepts and
* returns is not under the caller's control: it always requires
* exactly the number given by RubberBandLiveShifter::getBlockSize().
* However, that number is fixed for the lifetime of the shifter, so
* it only needs to be queried once and then fixed-size buffers may be
* passed.
* The number of frames accepted by and returned from
* RubberBandLiveShifter::shift() are not under the caller's control:
* they must always be exactly the number given by
* RubberBandLiveShifter::getBlockSize(). But this number is fixed for
* the lifetime of the shifter, so it only needs to be queried once
* after construction and then fixed-size buffers may be used.
*
* Using RubberBandLiveShifter also gives a shorter processing delay
* than a typical buffering setup using RubberBandStretcher, making it
@@ -102,7 +103,7 @@ public:
OptionFormantPreserved = 0x01000000,
OptionChannelsApart = 0x00000000,
OptionChannelsTogether = 0x10000000,
OptionChannelsTogether = 0x10000000
// n.b. Options is int, so we must stop before 0x80000000
};
@@ -293,6 +294,9 @@ public:
* array having enough room to store n samples where n is the value
* returned by getBlockSize().
*
* The input and output must be separate arrays; they cannot alias
* one another or overlap.
*
* Sample values are conventionally expected to be in the range
* -1.0f to +1.0f.
*/

View File

@@ -56,13 +56,13 @@ namespace RubberBand
* The primary Rubber Band Library API is contained in the class
* RubberBand::RubberBandStretcher. This class can perform both pitch
* shifting and time stretching and supports every feature of the
* library. A simpler, more limited alternative API that supports only
* library. A simpler, more limited API that supports only
* pitch-shifting can be found in RubberBand::RubberBandLiveShifter.
*
* RubberBandStretcher supports two processing modes, offline and
* real-time, and two processing "engines", known as the R2 or Faster
* engine and the R3 or Finer engine. The choices of processing mode
* and engine are fixed on construction: see
* and engine are fixed on construction: see the constructor
* RubberBandStretcher::RubberBandStretcher. The two engines work
* identically in API terms, and both of them support both offline and
* real-time modes as described below.

View File

@@ -48,11 +48,13 @@ extern "C" {
* This is a C-linkage interface to the Rubber Band time stretcher.
*
* This is a wrapper interface: the primary interface is in C++ and is
* defined and documented in RubberBandStretcher.h. The library
* itself is implemented in C++, and requires C++ standard library
* support even when using the C-linkage API.
* defined and documented in RubberBandStretcher.h and
* RubberBandLiveShifter.h. The library itself is implemented in C++,
* and requires C++ standard library support even when using the
* C-linkage API.
*
* Please see RubberBandStretcher.h for documentation.
* Please see RubberBandStretcher.h and RubberBandLiveShifter.h for
* documentation.
*
* If you are writing to the C++ API, do not include this header.
*/
@@ -107,10 +109,10 @@ struct RubberBandState_;
typedef struct RubberBandState_ *RubberBandState;
RB_EXTERN RubberBandState rubberband_new(unsigned int sampleRate,
unsigned int channels,
RubberBandOptions options,
double initialTimeRatio,
double initialPitchScale);
unsigned int channels,
RubberBandOptions options,
double initialTimeRatio,
double initialPitchScale);
RB_EXTERN void rubberband_delete(RubberBandState);
@@ -159,6 +161,52 @@ RB_EXTERN void rubberband_calculate_stretch(RubberBandState);
RB_EXTERN void rubberband_set_debug_level(RubberBandState, int level);
RB_EXTERN void rubberband_set_default_debug_level(int level);
enum RubberBandLiveOption {
RubberBandLiveOptionWindowShort = 0x00000000,
RubberBandLiveOptionWindowMedium = 0x00100000,
RubberBandLiveOptionFormantShifted = 0x00000000,
RubberBandLiveOptionFormantPreserved = 0x01000000,
RubberBandLiveOptionChannelsApart = 0x00000000,
RubberBandLiveOptionChannelsTogether = 0x10000000
};
typedef int RubberBandLiveOptions;
struct RubberBandLiveState_;
typedef struct RubberBandLiveState_ *RubberBandLiveState;
RB_EXTERN RubberBandLiveState rubberband_live_new(unsigned int sampleRate,
unsigned int channels,
RubberBandOptions options);
RB_EXTERN void rubberband_live_delete(RubberBandLiveState);
RB_EXTERN void rubberband_live_reset(RubberBandLiveState);
RB_EXTERN void rubberband_live_set_pitch_scale(RubberBandLiveState, double scale);
RB_EXTERN double rubberband_live_get_pitch_scale(const RubberBandLiveState);
RB_EXTERN void rubberband_live_set_formant_scale(RubberBandLiveState, double scale);
RB_EXTERN double rubberband_live_get_formant_scale(const RubberBandLiveState);
RB_EXTERN unsigned int rubberband_live_get_start_delay(const RubberBandLiveState);
RB_EXTERN void rubberband_live_set_formant_option(RubberBandLiveState, RubberBandOptions options);
RB_EXTERN unsigned int rubberband_live_get_block_size(RubberBandLiveState);
RB_EXTERN void rubberband_live_shift(RubberBandLiveState, const float *const *input, float *const *output);
RB_EXTERN unsigned int rubberband_live_get_channel_count(const RubberBandLiveState);
RB_EXTERN void rubberband_live_set_debug_level(RubberBandLiveState, int level);
RB_EXTERN void rubberband_live_set_default_debug_level(int level);
#ifdef __cplusplus
}
#endif

View File

@@ -1,4 +1,5 @@
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
#define NOMINMAX
/*
Rubber Band Library

View File

@@ -20,6 +20,7 @@
under terms other than those of the GNU General Public License,
you must obtain a valid commercial licence before doing so.
*/
#define NOMINMAX
#include "BQResampler.h"

View File

@@ -1,4 +1,5 @@
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
#define NOMINMAX
/*
Rubber Band Library

View File

@@ -23,7 +23,7 @@
#include "VectorOpsComplex.h"
#include "system/sysutils.h"
//#include "system/sysutils.h"
#include <cassert>

View File

@@ -24,6 +24,7 @@
#include "sysutils.h"
#ifdef _WIN32
#define NOMINMAX
#include <windows.h>
#include <fcntl.h>
#include <io.h>

View File

@@ -1,5 +1,7 @@
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
#define NOMINMAX
/*
Rubber Band Library
An audio time-stretching and pitch-shifting library.

View File

@@ -20,6 +20,7 @@
under terms other than those of the GNU General Public License,
you must obtain a valid commercial licence before doing so.
*/
#define NOMINMAX
#include "StretcherChannelData.h"
@@ -27,6 +28,9 @@
#include "../common/Allocators.h"
#include <algorithm>
#include <utility>
using std::max;
namespace RubberBand
{
@@ -114,7 +118,7 @@ void
R2Stretcher::ChannelData::setSizes(size_t windowSize,
size_t fftSize)
{
size_t maxSize = 2 * std::max(windowSize, fftSize);
size_t maxSize = 2*std::max(windowSize, fftSize);
size_t realSize = maxSize / 2 + 1;
size_t oldMax = inbuf->getSize();
size_t oldReal = oldMax / 2 + 1;

View File

@@ -1,4 +1,5 @@
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
#define NOMINMAX
/*
Rubber Band Library

View File

@@ -1,4 +1,5 @@
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
#define NOMINMAX
/*
Rubber Band Library
@@ -489,7 +490,7 @@ R3LiveShifter::generate(int requiredInOutbuf)
for (int hop = 0; hop < hops; ++hop) {
Profiler profiler("R3LiveShifter::generate/loop");
Profiler profiler2("R3LiveShifter::generate/loop");
if (toConsume <= 0) {
m_log.log(2, "R3LiveShifter::generate: ERROR: toConsume is zero at top of loop, hop and hops", hop, hops);

View File

@@ -1,4 +1,5 @@
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
#define NOMINMAX
/*
Rubber Band Library

View File

@@ -22,6 +22,7 @@
*/
#include "rubberband/RubberBandStretcher.h"
#include "rubberband/RubberBandLiveShifter.h"
#include "common/Allocators.h"
@@ -231,6 +232,86 @@ JNIEXPORT jint JNICALL Java_com_breakfastquay_rubberband_RubberBandStretcher_ret
JNIEXPORT void JNICALL Java_com_breakfastquay_rubberband_RubberBandStretcher_initialise
(JNIEnv *, jobject, jint, jint, jint, jdouble, jdouble);
/*
* Class: com_breakfastquay_rubberband_RubberBandLiveShifter
* Method: dispose
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_breakfastquay_rubberband_RubberBandLiveShifter_dispose
(JNIEnv *, jobject);
/*
* Class: com_breakfastquay_rubberband_RubberBandLiveShifter
* Method: reset
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_breakfastquay_rubberband_RubberBandLiveShifter_reset
(JNIEnv *, jobject);
/*
* Class: com_breakfastquay_rubberband_RubberBandLiveShifter
* Method: setPitchScale
* Signature: (D)V
*/
JNIEXPORT void JNICALL Java_com_breakfastquay_rubberband_RubberBandLiveShifter_setPitchScale
(JNIEnv *, jobject, jdouble);
/*
* Class: com_breakfastquay_rubberband_RubberBandLiveShifter
* Method: getChannelCount
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_breakfastquay_rubberband_RubberBandLiveShifter_getChannelCount
(JNIEnv *, jobject);
/*
* Class: com_breakfastquay_rubberband_RubberBandLiveShifter
* Method: getPitchScale
* Signature: ()D
*/
JNIEXPORT jdouble JNICALL Java_com_breakfastquay_rubberband_RubberBandLiveShifter_getPitchScale
(JNIEnv *, jobject);
/*
* Class: com_breakfastquay_rubberband_RubberBandLiveShifter
* Method: getStartDelay
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_breakfastquay_rubberband_RubberBandLiveShifter_getStartDelay
(JNIEnv *, jobject);
/*
* Class: com_breakfastquay_rubberband_RubberBandLiveShifter
* Method: setFormantOption
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_com_breakfastquay_rubberband_RubberBandLiveShifter_setFormantOption
(JNIEnv *, jobject, jint);
/*
* Class: com_breakfastquay_rubberband_RubberBandLiveShifter
* Method: getBlockSize
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_breakfastquay_rubberband_RubberBandLiveShifter_getBlockSize
(JNIEnv *, jobject);
/*
* Class: com_breakfastquay_rubberband_RubberBandLiveShifter
* Method: shift
* Signature: ([[FI[[FI)V
*/
JNIEXPORT void JNICALL Java_com_breakfastquay_rubberband_RubberBandLiveShifter_shift
(JNIEnv *, jobject, jobjectArray, jint, jobjectArray, jint);
/*
* Class: com_breakfastquay_rubberband_RubberBandLiveShifter
* Method: initialise
* Signature: (III)V
*/
JNIEXPORT void JNICALL Java_com_breakfastquay_rubberband_RubberBandLiveShifter_initialise
(JNIEnv *, jobject, jint, jint, jint);
}
RubberBandStretcher *
@@ -390,45 +471,48 @@ Java_com_breakfastquay_rubberband_RubberBandStretcher_setKeyFrameMap(JNIEnv *env
}
JNIEXPORT void JNICALL
Java_com_breakfastquay_rubberband_RubberBandStretcher_study(JNIEnv *env, jobject obj, jobjectArray data, jint offset, jint n, jboolean final)
Java_com_breakfastquay_rubberband_RubberBandStretcher_study(JNIEnv *env, jobject obj, jobjectArray input, jint offset, jint n, jboolean final)
{
int channels = env->GetArrayLength(data);
int channels = env->GetArrayLength(input);
float **arr = allocate<float *>(channels);
float **input = allocate<float *>(channels);
float **inbuf = allocate<float *>(channels);
for (int c = 0; c < channels; ++c) {
jfloatArray cdata = (jfloatArray)env->GetObjectArrayElement(data, c);
jfloatArray cdata = (jfloatArray)env->GetObjectArrayElement(input, c);
arr[c] = env->GetFloatArrayElements(cdata, 0);
input[c] = arr[c] + offset;
inbuf[c] = arr[c] + offset;
}
getStretcher(env, obj)->study(input, n, final);
getStretcher(env, obj)->study(inbuf, n, final);
for (int c = 0; c < channels; ++c) {
jfloatArray cdata = (jfloatArray)env->GetObjectArrayElement(data, c);
jfloatArray cdata = (jfloatArray)env->GetObjectArrayElement(input, c);
env->ReleaseFloatArrayElements(cdata, arr[c], 0);
}
deallocate(inbuf);
deallocate(arr);
}
JNIEXPORT void JNICALL
Java_com_breakfastquay_rubberband_RubberBandStretcher_process(JNIEnv *env, jobject obj, jobjectArray data, jint offset, jint n, jboolean final)
Java_com_breakfastquay_rubberband_RubberBandStretcher_process(JNIEnv *env, jobject obj, jobjectArray input, jint offset, jint n, jboolean final)
{
int channels = env->GetArrayLength(data);
int channels = env->GetArrayLength(input);
float **arr = allocate<float *>(channels);
float **input = allocate<float *>(channels);
float **inbuf = allocate<float *>(channels);
for (int c = 0; c < channels; ++c) {
jfloatArray cdata = (jfloatArray)env->GetObjectArrayElement(data, c);
jfloatArray cdata = (jfloatArray)env->GetObjectArrayElement(input, c);
arr[c] = env->GetFloatArrayElements(cdata, 0);
input[c] = arr[c] + offset;
inbuf[c] = arr[c] + offset;
}
getStretcher(env, obj)->process(input, n, final);
getStretcher(env, obj)->process(inbuf, n, final);
for (int c = 0; c < channels; ++c) {
jfloatArray cdata = (jfloatArray)env->GetObjectArrayElement(data, c);
jfloatArray cdata = (jfloatArray)env->GetObjectArrayElement(input, c);
env->ReleaseFloatArrayElements(cdata, arr[c], 0);
}
deallocate(input);
deallocate(inbuf);
deallocate(arr);
}
@@ -456,3 +540,111 @@ Java_com_breakfastquay_rubberband_RubberBandStretcher_retrieve(JNIEnv *env, jobj
return retrieved;
}
RubberBandLiveShifter *
getLiveShifter(JNIEnv *env, jobject obj)
{
jclass c = env->GetObjectClass(obj);
jfieldID fid = env->GetFieldID(c, "handle", "J");
jlong handle = env->GetLongField(obj, fid);
return (RubberBandLiveShifter *)handle;
}
void
setLiveShifter(JNIEnv *env, jobject obj, RubberBandLiveShifter *stretcher)
{
jclass c = env->GetObjectClass(obj);
jfieldID fid = env->GetFieldID(c, "handle", "J");
jlong handle = (jlong)stretcher;
env->SetLongField(obj, fid, handle);
}
JNIEXPORT void JNICALL
Java_com_breakfastquay_rubberband_RubberBandLiveShifter_initialise(JNIEnv *env, jobject obj, jint sampleRate, jint channels, jint options)
{
setLiveShifter(env, obj, new RubberBandLiveShifter
(sampleRate, channels, options));
}
JNIEXPORT void JNICALL
Java_com_breakfastquay_rubberband_RubberBandLiveShifter_dispose(JNIEnv *env, jobject obj)
{
delete getLiveShifter(env, obj);
setLiveShifter(env, obj, 0);
}
JNIEXPORT void JNICALL
Java_com_breakfastquay_rubberband_RubberBandLiveShifter_reset(JNIEnv *env, jobject obj)
{
getLiveShifter(env, obj)->reset();
}
JNIEXPORT void JNICALL
Java_com_breakfastquay_rubberband_RubberBandLiveShifter_setPitchScale(JNIEnv *env, jobject obj, jdouble scale)
{
getLiveShifter(env, obj)->setPitchScale(scale);
}
JNIEXPORT jint JNICALL
Java_com_breakfastquay_rubberband_RubberBandLiveShifter_getChannelCount(JNIEnv *env, jobject obj)
{
return getLiveShifter(env, obj)->getChannelCount();
}
JNIEXPORT jdouble JNICALL
Java_com_breakfastquay_rubberband_RubberBandLiveShifter_getPitchScale(JNIEnv *env, jobject obj)
{
return getLiveShifter(env, obj)->getPitchScale();
}
JNIEXPORT jint JNICALL
Java_com_breakfastquay_rubberband_RubberBandLiveShifter_getStartDelay(JNIEnv *env, jobject obj)
{
return getLiveShifter(env, obj)->getStartDelay();
}
JNIEXPORT void JNICALL
Java_com_breakfastquay_rubberband_RubberBandLiveShifter_setFormantOption(JNIEnv *env, jobject obj, jint options)
{
getLiveShifter(env, obj)->setFormantOption(options);
}
JNIEXPORT jint JNICALL
Java_com_breakfastquay_rubberband_RubberBandLiveShifter_getBlockSize(JNIEnv *env, jobject obj)
{
return getLiveShifter(env, obj)->getBlockSize();
}
JNIEXPORT void JNICALL
Java_com_breakfastquay_rubberband_RubberBandLiveShifter_shift(JNIEnv *env, jobject obj, jobjectArray input, jint inOffset, jobjectArray output, jint outOffset)
{
int channels = env->GetArrayLength(input);
float **inarr = allocate<float *>(channels);
float **inbuf = allocate<float *>(channels);
float **outarr = allocate<float *>(channels);
float **outbuf = allocate<float *>(channels);
for (int c = 0; c < channels; ++c) {
jfloatArray cdata = (jfloatArray)env->GetObjectArrayElement(input, c);
inarr[c] = env->GetFloatArrayElements(cdata, 0);
inbuf[c] = inarr[c] + inOffset;
cdata = (jfloatArray)env->GetObjectArrayElement(output, c);
outarr[c] = env->GetFloatArrayElements(cdata, 0);
outbuf[c] = outarr[c] + outOffset;
}
getLiveShifter(env, obj)->shift(inbuf, outbuf);
for (int c = 0; c < channels; ++c) {
jfloatArray cdata = (jfloatArray)env->GetObjectArrayElement(input, c);
env->ReleaseFloatArrayElements(cdata, inarr[c], 0);
cdata = (jfloatArray)env->GetObjectArrayElement(output, c);
env->ReleaseFloatArrayElements(cdata, outarr[c], 0);
}
deallocate(inbuf);
deallocate(inarr);
deallocate(outbuf);
deallocate(outarr);
}

View File

@@ -23,6 +23,7 @@
#include "../rubberband/rubberband-c.h"
#include "../rubberband/RubberBandStretcher.h"
#include "../rubberband/RubberBandLiveShifter.h"
struct RubberBandState_
{
@@ -197,3 +198,83 @@ void rubberband_set_default_debug_level(int level)
RubberBand::RubberBandStretcher::setDefaultDebugLevel(level);
}
struct RubberBandLiveState_
{
RubberBand::RubberBandLiveShifter *m_s;
};
RubberBandLiveState rubberband_live_new(unsigned int sampleRate,
unsigned int channels,
RubberBandOptions options)
{
RubberBandLiveState_ *state = new RubberBandLiveState_();
state->m_s = new RubberBand::RubberBandLiveShifter
(sampleRate, channels, options);
return state;
}
void rubberband_live_delete(RubberBandLiveState state)
{
delete state->m_s;
delete state;
}
void rubberband_live_reset(RubberBandLiveState state)
{
state->m_s->reset();
}
void rubberband_live_set_pitch_scale(RubberBandLiveState state, double scale)
{
state->m_s->setPitchScale(scale);
}
double rubberband_live_get_pitch_scale(const RubberBandLiveState state)
{
return state->m_s->getPitchScale();
}
void rubberband_live_set_formant_scale(RubberBandLiveState state, double scale)
{
state->m_s->setFormantScale(scale);
}
double rubberband_live_get_formant_scale(const RubberBandLiveState state)
{
return state->m_s->getFormantScale();
}
unsigned int rubberband_live_get_start_delay(const RubberBandLiveState state)
{
return (unsigned int)state->m_s->getStartDelay();
}
void rubberband_live_set_formant_option(RubberBandLiveState state, RubberBandOptions options)
{
state->m_s->setFormantOption(options);
}
unsigned int rubberband_live_get_block_size(RubberBandLiveState state)
{
return (unsigned int)state->m_s->getBlockSize();
}
void rubberband_live_shift(RubberBandLiveState state, const float *const *input, float *const *output)
{
state->m_s->shift(input, output);
}
unsigned int rubberband_live_get_channel_count(const RubberBandLiveState state)
{
return (unsigned int)state->m_s->getChannelCount();
}
void rubberband_live_set_debug_level(RubberBandLiveState state, int level)
{
state->m_s->setDebugLevel(level);
}
void rubberband_live_set_default_debug_level(int level)
{
RubberBand::RubberBandStretcher::setDefaultDebugLevel(level);
}