Compare commits
17 Commits
e55f7aaadc
...
4e1bb95234
| Author | SHA1 | Date | |
|---|---|---|---|
| 4e1bb95234 | |||
|
|
e4296ac80b | ||
|
|
a19a891b36 | ||
|
|
1d95888bec | ||
|
|
8c4dc5cbb0 | ||
|
|
cdde17c3dc | ||
|
|
4febe52001 | ||
|
|
7d32166d2a | ||
|
|
ce06adba87 | ||
|
|
48e08a5113 | ||
|
|
28fa720e93 | ||
|
|
05acd21738 | ||
|
|
ab27a6485d | ||
|
|
1d28a7c43b | ||
|
|
923a196f8f | ||
|
|
4353ddd78d | ||
|
|
a28c9e4909 |
10
.build.yml
10
.build.yml
@@ -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
|
||||
|
||||
@@ -31,3 +31,4 @@ playlist-out/*
|
||||
formant-out-*/
|
||||
out*.wav
|
||||
packages/
|
||||
otherbuilds/docker/Dockerfile
|
||||
|
||||
1
.hgtags
1
.hgtags
@@ -37,3 +37,4 @@ d2aebfc83e21e7ce597cdb59029eb8500e53c24c v3.1.2
|
||||
46d8430844d6454ed140d4e8631372a6c65e856a v3.2.0
|
||||
83d096887e1b9042f9e4a8f1b975d18539e82f22 v3.2.1
|
||||
55367f2e76c9ee79582c8bebdd63b14c98e459be v3.3.0
|
||||
1ea2558505589ca7dab9fd6dd6facd97cd119aaf v4.0.0
|
||||
|
||||
19
CHANGELOG
19
CHANGELOG
@@ -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
61
CMakeLists.txt
Normal 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)
|
||||
2
Doxyfile
2
Doxyfile
@@ -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.
|
||||
|
||||
22
README.md
22
README.md
@@ -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.
|
||||
|
||||
70
com/breakfastquay/rubberband/RubberBandLiveShifter.java
Normal file
70
com/breakfastquay/rubberband/RubberBandLiveShifter.java
Normal 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");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 += [
|
||||
|
||||
@@ -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
|
||||
|
||||
39
otherbuilds/docker/Dockerfile.in
Normal file
39
otherbuilds/docker/Dockerfile.in
Normal 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
8
otherbuilds/docker/run.sh
Executable 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 .
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#include "VectorOpsComplex.h"
|
||||
|
||||
#include "system/sysutils.h"
|
||||
//#include "system/sysutils.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "sysutils.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define NOMINMAX
|
||||
#include <windows.h>
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user