Add live shifter to JNI
This commit is contained in:
@@ -31,3 +31,4 @@ playlist-out/*
|
|||||||
formant-out-*/
|
formant-out-*/
|
||||||
out*.wav
|
out*.wav
|
||||||
packages/
|
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,14 +2,14 @@
|
|||||||
package com.breakfastquay.rubberband.test;
|
package com.breakfastquay.rubberband.test;
|
||||||
|
|
||||||
import com.breakfastquay.rubberband.RubberBandStretcher;
|
import com.breakfastquay.rubberband.RubberBandStretcher;
|
||||||
|
import com.breakfastquay.rubberband.RubberBandLiveShifter;
|
||||||
|
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
public class RubberBandTest
|
public class RubberBandTest
|
||||||
{
|
{
|
||||||
|
public static void exerciseStretcher() {
|
||||||
public static void main(String[] args) {
|
|
||||||
|
|
||||||
int channels = 1;
|
int channels = 1;
|
||||||
int rate = 44100;
|
int rate = 44100;
|
||||||
|
|
||||||
@@ -72,6 +72,9 @@ public class RubberBandTest
|
|||||||
|
|
||||||
i0 = 0;
|
i0 = 0;
|
||||||
|
|
||||||
|
double sqrtotal = 0.0;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
for (int block = 0; block < blocks; ++block) {
|
for (int block = 0; block < blocks; ++block) {
|
||||||
|
|
||||||
for (int c = 0; c < channels; ++c) {
|
for (int c = 0; c < channels; ++c) {
|
||||||
@@ -98,13 +101,88 @@ public class RubberBandTest
|
|||||||
}
|
}
|
||||||
int obtained = stretcher.retrieve(buffer, 0, requested);
|
int obtained = stretcher.retrieve(buffer, 0, requested);
|
||||||
for (int i = 0; i < obtained; ++i) {
|
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.err.println
|
||||||
|
(String.format("in = %d, out = %d, rms = %f",
|
||||||
|
blocksize * blocks, n,
|
||||||
|
Math.sqrt(sqrtotal / (double)n)));
|
||||||
|
|
||||||
stretcher.dispose();
|
stretcher.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void exerciseLiveShifter() {
|
||||||
|
|
||||||
|
int channels = 1;
|
||||||
|
int rate = 44100;
|
||||||
|
|
||||||
|
RubberBandLiveShifter shifter = new RubberBandLiveShifter
|
||||||
|
(rate,
|
||||||
|
channels,
|
||||||
|
0);
|
||||||
|
|
||||||
|
shifter.setPitchScale(0.8);
|
||||||
|
|
||||||
|
System.err.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.err.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) {
|
||||||
|
exerciseStretcher();
|
||||||
|
exerciseLiveShifter();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ jni_sources = [
|
|||||||
|
|
||||||
java_sources = [
|
java_sources = [
|
||||||
'com/breakfastquay/rubberband/RubberBandStretcher.java',
|
'com/breakfastquay/rubberband/RubberBandStretcher.java',
|
||||||
|
'com/breakfastquay/rubberband/RubberBandLiveShifter.java',
|
||||||
]
|
]
|
||||||
|
|
||||||
java_test_sources = [
|
java_test_sources = [
|
||||||
|
|||||||
32
otherbuilds/docker/Dockerfile.in
Normal file
32
otherbuilds/docker/Dockerfile.in
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
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 \
|
||||||
|
meson \
|
||||||
|
ninja-build \
|
||||||
|
openjdk-8-jre \
|
||||||
|
openjdk-8-jdk
|
||||||
|
|
||||||
|
WORKDIR /root
|
||||||
|
|
||||||
|
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 .
|
||||||
|
|
||||||
@@ -293,6 +293,9 @@ public:
|
|||||||
* array having enough room to store n samples where n is the value
|
* array having enough room to store n samples where n is the value
|
||||||
* returned by getBlockSize().
|
* 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
|
* Sample values are conventionally expected to be in the range
|
||||||
* -1.0f to +1.0f.
|
* -1.0f to +1.0f.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ RB_EXTERN unsigned int rubberband_live_get_start_delay(const RubberBandLiveState
|
|||||||
|
|
||||||
RB_EXTERN void rubberband_live_set_formant_option(RubberBandLiveState, RubberBandOptions options);
|
RB_EXTERN void rubberband_live_set_formant_option(RubberBandLiveState, RubberBandOptions options);
|
||||||
|
|
||||||
RB_EXTERN unsigned int rubberband_live_get_block_size(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 void rubberband_live_shift(RubberBandLiveState, const float *const *input, float *const *output);
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "rubberband/RubberBandStretcher.h"
|
#include "rubberband/RubberBandStretcher.h"
|
||||||
|
#include "rubberband/RubberBandLiveShifter.h"
|
||||||
|
|
||||||
#include "common/Allocators.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
|
JNIEXPORT void JNICALL Java_com_breakfastquay_rubberband_RubberBandStretcher_initialise
|
||||||
(JNIEnv *, jobject, jint, jint, jint, jdouble, jdouble);
|
(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 *
|
RubberBandStretcher *
|
||||||
@@ -390,45 +471,48 @@ Java_com_breakfastquay_rubberband_RubberBandStretcher_setKeyFrameMap(JNIEnv *env
|
|||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
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 **arr = allocate<float *>(channels);
|
||||||
float **input = allocate<float *>(channels);
|
float **inbuf = allocate<float *>(channels);
|
||||||
for (int c = 0; c < channels; ++c) {
|
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);
|
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) {
|
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);
|
env->ReleaseFloatArrayElements(cdata, arr[c], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deallocate(inbuf);
|
||||||
|
deallocate(arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
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 **arr = allocate<float *>(channels);
|
||||||
float **input = allocate<float *>(channels);
|
float **inbuf = allocate<float *>(channels);
|
||||||
for (int c = 0; c < channels; ++c) {
|
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);
|
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) {
|
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);
|
env->ReleaseFloatArrayElements(cdata, arr[c], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
deallocate(input);
|
deallocate(inbuf);
|
||||||
deallocate(arr);
|
deallocate(arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,3 +540,111 @@ Java_com_breakfastquay_rubberband_RubberBandStretcher_retrieve(JNIEnv *env, jobj
|
|||||||
return retrieved;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -254,6 +254,11 @@ void rubberband_live_set_formant_option(RubberBandLiveState state, RubberBandOpt
|
|||||||
state->m_s->setFormantOption(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)
|
void rubberband_live_shift(RubberBandLiveState state, const float *const *input, float *const *output)
|
||||||
{
|
{
|
||||||
state->m_s->shift(input, output);
|
state->m_s->shift(input, output);
|
||||||
|
|||||||
Reference in New Issue
Block a user