diff --git a/templates/android/src/MainActivity.java b/templates/android/src/MainActivity.java
index f17aac8..bed1431 100644
--- a/templates/android/src/MainActivity.java
+++ b/templates/android/src/MainActivity.java
@@ -57,10 +57,6 @@ public class MainActivity extends Activity {
public void setParameter(int i, float v) {
nativeSetParameter(i, v);
}
-
- @JavascriptInterface
- public void dummyFunc() {
- }
}
public void onCreate(Bundle savedInstanceState) {
diff --git a/templates/android/src/data.h b/templates/android/src/data.h
index d58fb19..1705a7f 100644
--- a/templates/android/src/data.h
+++ b/templates/android/src/data.h
@@ -4,17 +4,30 @@
#define NUM_CHANNELS_IN {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain) ? (it.product.buses.filter(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain)[0].channels == "mono" ? 1 : 2) : 0}}
#define NUM_CHANNELS_OUT {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "output" && !x.cv && !x.sidechain) ? (it.product.buses.filter(x => x.type == "audio" && x.direction == "output" && !x.cv && !x.sidechain)[0].channels == "mono" ? 1 : 2) : 0}}
+#define NUM_MIDI_INPUTS {{=it.product.buses.filter(x => x.type == "midi" && x.direction == "input").length}}
+
#define PARAMETERS_N {{=it.product.parameters.length}}
#if PARAMETERS_N > 0
+
+# define PARAM_BYPASS 1
+# define PARAM_TOGGLED (1<<1)
+# define PARAM_INTEGER (1<<2)
+
static struct {
- char out;
- float def;
+ char out;
+ float def;
+ float min;
+ float max;
+ uint32_t flags;
} param_data[PARAMETERS_N] = {
{{~it.product.parameters :p}}
{
- /* .out = */ {{=p.direction == "output" ? 1 : 0}},
- /* .def = */ {{=p.defaultValue.toExponential()}}
+ /* .out = */ {{=p.direction == "output" ? 1 : 0}},
+ /* .def = */ {{=p.defaultValue.toExponential()}},
+ /* .min = */ {{=p.minimum.toExponential()}}f,
+ /* .max = */ {{=p.maximum.toExponential()}}f,
+ /* .flags = */ {{?p.isBypass}}PARAM_BYPASS{{??p.isLatency}}PARAM_INTEGER{{??}}0{{?p.toggled}} | PARAM_TOGGLED{{?}}{{?p.integer}} | PARAM_INTEGER{{?}}{{?}}
},
{{~}}
};
diff --git a/templates/android/src/index.html b/templates/android/src/index.html
index 3babf36..dc0f1dd 100644
--- a/templates/android/src/index.html
+++ b/templates/android/src/index.html
@@ -1,9 +1,65 @@
+
{{=it.product.name}}
+
+
- Prova
+
+
diff --git a/templates/android/src/jni.cpp b/templates/android/src/jni.cpp
index f46621f..b55e812 100644
--- a/templates/android/src/jni.cpp
+++ b/templates/android/src/jni.cpp
@@ -114,118 +114,6 @@ static void data_callback(ma_device* pDevice, void* pOutput, const void* pInput,
}
}
-extern "C"
-JNIEXPORT jboolean JNICALL
-Java_com_orastron_@JNI_NAME@_MainActivity_nativeAudioStart(JNIEnv* env, jobject thiz) {
- (void)env;
- (void)thiz;
-
-#if NUM_CHANNELS_IN == 0
- ma_device_config deviceConfig = ma_device_config_init(ma_device_type_playback);
-#else
- ma_device_config deviceConfig = ma_device_config_init(ma_device_type_duplex);
-#endif
- deviceConfig.periodSizeInFrames = BLOCK_SIZE;
- deviceConfig.periods = 1;
- deviceConfig.performanceProfile = ma_performance_profile_low_latency;
- deviceConfig.noPreSilencedOutputBuffer = 1;
- deviceConfig.noClip = 0;
- deviceConfig.noDisableDenormals = 0;
- deviceConfig.noFixedSizedCallback = 1;
- deviceConfig.dataCallback = data_callback;
- deviceConfig.capture.pDeviceID = NULL;
- deviceConfig.capture.format = ma_format_f32;
- deviceConfig.capture.channels = NUM_CHANNELS_IN;
- deviceConfig.capture.shareMode = ma_share_mode_shared;
- deviceConfig.playback.pDeviceID = NULL;
- deviceConfig.playback.format = ma_format_f32;
- deviceConfig.playback.channels = NUM_CHANNELS_OUT;
- deviceConfig.playback.shareMode = ma_share_mode_shared;
-
- if (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS)
- return false;
-
- P_INIT(&instance);
- P_SET_SAMPLE_RATE(&instance, (float)device.sampleRate);
-#ifdef P_MEM_REQ
- size_t req = P_MEM_REQ(&instance);
- if (req) {
- mem = malloc(req);
- if (mem == NULL) {
- ma_device_uninit(&device);
- return false;
- }
- P_MEM_SET(&instance, mem);
- } else
- mem = NULL;
-#endif
-
- for (int i = 0; i < NUM_PARAMETERS; i++) {
- paramValues[i] = config_parameters[i].defaultValueUnmapped;
- if (!config_parameters[i].out)
- P_SET_PARAMETER(&instance, i, paramValues[i]);
- }
-
- P_RESET(&instance);
-
-#if NUM_CHANNELS_IN != 0
- for (int i = 0; i < NUM_CHANNELS_IN; i++)
- inBufs[i] = bufs[i];
-#endif
- for (int i = 0; i < NUM_CHANNELS_OUT; i++)
- outBufs[i] = bufs[i];
-
- if (ma_device_start(&device) != MA_SUCCESS) {
-#ifdef P_MEM_REQ
- free(mem);
-#endif
- ma_device_uninit(&device);
- return false;
- }
-
- return true;
-}
-
-extern "C"
-JNIEXPORT void JNICALL
-Java_com_orastron_@JNI_NAME@_MainActivity_nativeAudioStop(JNIEnv* env, jobject thiz) {
- (void)env;
- (void)thiz;
-
-#ifdef P_MEM_REQ
- free(mem);
-#endif
-#ifdef P_FINI
- P_FINI(&instance);
-#endif
- ma_device_stop(&device);
- ma_device_uninit(&device);
-}
-
-extern "C"
-JNIEXPORT jfloat JNICALL
-Java_com_orastron_@JNI_NAME@_MainActivity_nativeGetParameter(JNIEnv* env, jobject thiz, jint i) {
- (void)env;
- (void)thiz;
-
- mutex.lock();
- float v = paramValues[i];
- mutex.unlock();
- return v;
-}
-
-
-extern "C"
-JNIEXPORT void JNICALL
-Java_com_orastron_@JNI_NAME@_MainActivity_nativeSetParameter(JNIEnv* env, jobject thiz, jint i, jfloat v) {
- (void)env;
- (void)thiz;
-
- mutex.lock();
- paramValues[i] = v;
- mutex.unlock();
-}
-
#ifdef P_NOTE_ON
extern "C"
JNIEXPORT void JNICALL
@@ -270,6 +158,12 @@ Java_com_orastron_@JNI_NAME@_MainActivity_removeMidiPort(JNIEnv* env, jobject th
#include "plugin.h"
#include
+#if PARAMETERS_N + NUM_MIDI_INPUTS > 0
+# include
+#endif
+#if PARAMETERS_N > 0
+# include
+#endif
#if NUM_CHANNELS_IN + NUM_CHANNELS_OUT > 0
# define MINIAUDIO_IMPLEMENTATION
# define MA_ENABLE_ONLY_SPECIFIC_BACKENDS
@@ -277,14 +171,71 @@ Java_com_orastron_@JNI_NAME@_MainActivity_removeMidiPort(JNIEnv* env, jobject th
# include
# define BLOCK_SIZE 32
-# define NUM_BUFS (NUM_CHANNELS_IN > NUM_CHANNELS_OUT ? NUM_CHANNELS_IN : NUM_CHANNELS_OUT)
+#endif
+#if NUM_CHANNELS_IN + NUM_CHANNELS_OUT > 0
static ma_device device;
#endif
static plugin instance;
static void * mem;
+#if NUM_CHANNELS_IN > 0
+float x_buf[NUM_CHANNELS_IN * BLOCK_SIZE];
+#endif
+#if NUM_CHANNELS_OUT > 0
+float y_buf[NUM_CHANNELS_OUT * BLOCK_SIZE];
+#endif
+const float ** x;
+float ** y;
+#if PARAMETERS_N > 0
+std::mutex mutex;
+float param_values[PARAMETERS_N];
+float param_values_prev[PARAMETERS_N];
+#endif
static void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount) {
+ (void)pDevice;
+
+#if PARAMETERS_N + NUM_MIDI_INPUTS > 0
+ if (mutex.try_lock()) {
+# if PARAMETERS_N > 0
+ for (size_t i = 0; i < PARAMETERS_N; i++) {
+ if (param_data[i].out)
+ param_values_prev[i] = param_values[i] = plugin_get_parameter(&instance, i);
+ else if (param_values_prev[i] != param_values[i]) {
+ plugin_set_parameter(&instance, i, param_values[i]);
+ param_values_prev[i] = param_values[i];
+ }
+ // TODO: midi
+ }
+# endif
+ mutex.unlock();
+ }
+#endif
+
+ const float * in_buf = reinterpret_cast(pInput);
+ float * out_buf = reinterpret_cast(pOutput);
+ ma_uint32 i = 0;
+ while (i < frameCount) {
+ ma_uint32 n = std::min(frameCount - i, static_cast(BLOCK_SIZE));
+
+#if NUM_CHANNELS_IN > 0
+ size_t ix = NUM_CHANNELS_IN * i;
+ for (ma_uint32 j = 0; j < n; j++)
+ for (size_t k = 0; k < NUM_CHANNELS_IN; k++, ix++)
+ x_buf[BLOCK_SIZE * k + j] = in_buf[ix];
+#endif
+
+ plugin_process(&instance, x, y, n);
+
+#if NUM_CHANNELS_OUT > 0
+ size_t iy = NUM_CHANNELS_OUT * i;
+ for (ma_uint32 j = 0; j < n; j++)
+ for (size_t k = 0; k < NUM_CHANNELS_OUT; k++, iy++)
+ y_buf[BLOCK_SIZE * k + j] = out_buf[ix];
+#endif
+
+ i += n;
+ }
}
extern "C"
@@ -325,9 +276,11 @@ JNI_FUNC(nativeAudioStart)(JNIEnv* env, jobject thiz) {
plugin_init(&instance);
#if PARAMETERS_N > 0
- for (size_t i = 0; i < PARAMETERS_N; i++)
+ for (size_t i = 0; i < PARAMETERS_N; i++) {
if (!param_data[i].out)
plugin_set_parameter(&instance, i, param_data[i].def);
+ param_values_prev[i] = param_values[i] = param_data[i].def;
+ }
#endif
plugin_set_sample_rate(&instance, (float)device.sampleRate);
@@ -347,6 +300,28 @@ JNI_FUNC(nativeAudioStart)(JNIEnv* env, jobject thiz) {
plugin_reset(&instance);
+#if NUM_CHANNELS_IN > 0
+ for (size_t i = 0; i < NUM_CHANNELS_IN; i++)
+ x[i] = x_buf + BLOCK_SIZE * i;
+#else
+ x = NULL;
+#endif
+#if NUM_CHANNELS_OUT > 0
+ for (size_t i = 0; i < NUM_CHANNELS_OUT; i++)
+ y[i] = y_buf + BLOCK_SIZE * i;
+#else
+ y = NULL;
+#endif
+
+#if NUM_CHANNELS_IN + NUM_CHANNELS_OUT > 0
+ if (ma_device_start(&device) != MA_SUCCESS) {
+ if (mem != NULL)
+ free(mem);
+ ma_device_uninit(&device);
+ return false;
+ }
+#endif
+
return true;
}
@@ -356,8 +331,9 @@ JNI_FUNC(nativeAudioStop)(JNIEnv* env, jobject thiz) {
(void)env;
(void)thiz;
+ if (mem != NULL)
+ free(mem);
plugin_fini(&instance);
-
#if NUM_CHANNELS_IN + NUM_CHANNELS_OUT > 0
ma_device_stop(&device);
ma_device_uninit(&device);
@@ -367,20 +343,51 @@ JNI_FUNC(nativeAudioStop)(JNIEnv* env, jobject thiz) {
extern "C"
JNIEXPORT jfloat JNICALL
JNI_FUNC(nativeGetParameter)(JNIEnv* env, jobject thiz, jint i) {
+ (void)env;
+ (void)thiz;
+
+#if PARAMETERS_N > 0
+ mutex.lock();
+ float v = param_values[i];
+ mutex.unlock();
+ return v;
+#else
return 0.f;
+#endif
}
extern "C"
JNIEXPORT void JNICALL
JNI_FUNC(nativeSetParameter)(JNIEnv* env, jobject thiz, jint i, jfloat v) {
+ (void)env;
+ (void)thiz;
+
+ if (param_data[i].flags & (PARAM_BYPASS | PARAM_TOGGLED))
+ v = v > 0.5f ? 1.f : 0.f;
+ else if (param_data[i].flags & PARAM_INTEGER)
+ v = (int32_t)(v + 0.5f);
+ v = std::min(std::max(v, param_data[i].min), param_data[i].max);
+#if PARAMETERS_N > 0
+ mutex.lock();
+ param_values[i] = v;
+ mutex.unlock();
+#endif
}
extern "C"
JNIEXPORT void JNICALL
JNI_FUNC(addMidiPort)(JNIEnv* env, jobject thiz, jobject d, jint p) {
+ (void)env;
+ (void)thiz;
+
+ //TBD
}
extern "C"
JNIEXPORT void JNICALL
JNI_FUNC(removeMidiPort)(JNIEnv* env, jobject thiz, jobject d, jint p) {
+ (void)env;
+ (void)thiz;
+
+ //TBD
}