Merge from branch rblive
This commit is contained in:
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
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ jni_sources = [
|
||||
|
||||
java_sources = [
|
||||
'com/breakfastquay/rubberband/RubberBandStretcher.java',
|
||||
'com/breakfastquay/rubberband/RubberBandLiveShifter.java',
|
||||
]
|
||||
|
||||
java_test_sources = [
|
||||
|
||||
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 .
|
||||
|
||||
@@ -102,7 +102,7 @@ public:
|
||||
OptionFormantPreserved = 0x01000000,
|
||||
|
||||
OptionChannelsApart = 0x00000000,
|
||||
OptionChannelsTogether = 0x10000000,
|
||||
OptionChannelsTogether = 0x10000000
|
||||
|
||||
// n.b. Options is int, so we must stop before 0x80000000
|
||||
};
|
||||
@@ -293,6 +293,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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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