more android
This commit is contained in:
parent
119c5cba9a
commit
906ecf4033
@ -1,12 +1,39 @@
|
|||||||
#define AUDIO_BUS_IN {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain)}}
|
#define NUM_AUDIO_BUSES_IN {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "input").length}}
|
||||||
#define AUDIO_BUS_OUT {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "output" && !x.cv && !x.sidechain)}}
|
#define NUM_AUDIO_BUSES_OUT {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "output").length}}
|
||||||
|
|
||||||
#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 AUDIO_BUS_IN {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain)}}
|
||||||
#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 AUDIO_BUS_OUT {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "output" && !x.cv && !x.sidechain)}}
|
||||||
|
|
||||||
#define NUM_MIDI_INPUTS {{=it.product.buses.filter(x => x.type == "midi" && x.direction == "input").length}}
|
#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_NON_OPT_CHANNELS_IN {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "input" && !x.optional).reduce((a, x) => a + (x.channels == "mono" ? 1 : 2), 0)}}
|
||||||
|
#define NUM_NON_OPT_CHANNELS_OUT {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "output" && !x.optional).reduce((a, x) => a + (x.channels == "mono" ? 1 : 2), 0)}}
|
||||||
|
#define NUM_ALL_CHANNELS_IN {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "input").reduce((a, x) => a + (x.channels == "mono" ? 1 : 2), 0)}}
|
||||||
|
#define NUM_ALL_CHANNELS_OUT {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "output").reduce((a, x) => a + (x.channels == "mono" ? 1 : 2), 0)}}
|
||||||
|
|
||||||
#define PARAMETERS_N {{=it.product.parameters.length}}
|
#define NUM_MIDI_INPUTS {{=it.product.buses.filter(x => x.type == "midi" && x.direction == "input").length}}
|
||||||
|
|
||||||
|
#if (AUDIO_BUS_IN >= 0) || (AUDIO_BUS_OUT >= 0)
|
||||||
|
static struct {
|
||||||
|
size_t index;
|
||||||
|
char out;
|
||||||
|
char optional;
|
||||||
|
char channels;
|
||||||
|
} audio_bus_data[NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT] = {
|
||||||
|
{{~it.product.buses :b:i}}
|
||||||
|
{{?b.type == "audio"}}
|
||||||
|
{
|
||||||
|
/* .index = */ {{=i}},
|
||||||
|
/* .out = */ {{=b.direction == "output" ? 1 : 0}},
|
||||||
|
/* .optional = */ {{=b.optional ? 1 : 0}},
|
||||||
|
/* .channels = */ {{=b.channels == "mono" ? 1 : 2}}
|
||||||
|
},
|
||||||
|
{{?}}
|
||||||
|
{{~}}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PARAMETERS_N {{=it.product.parameters.length}}
|
||||||
|
|
||||||
#if PARAMETERS_N > 0
|
#if PARAMETERS_N > 0
|
||||||
|
|
||||||
|
@ -9,8 +9,18 @@ var data = {
|
|||||||
parameters: {{=JSON.stringify(it.product.parameters, null, 2)}}
|
parameters: {{=JSON.stringify(it.product.parameters, null, 2)}}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function map(index, value) {
|
||||||
|
var p = data.parameters[index];
|
||||||
|
return p.map == "logarithmic" ? p.minimum * Math.exp((2.0 * Math.log(Math.sqrt(p.maximum * p.minimum) / Math.abs(p.minimum))) * value) : p.minimum + (p.maximum - p.minimum) * value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function unmap(index, value) {
|
||||||
|
var p = data.parameters[index];
|
||||||
|
return p.map == "logarithmic" ? Math.log(value / p.minimum) / (2.0 * Math.log(Math.sqrt(p.maximum * p.minimum) / Math.abs(p.minimum))) : (value - p.minimum) / (p.maximum - p.minimum);
|
||||||
|
}
|
||||||
|
|
||||||
var hasAudioPermission = true;
|
var hasAudioPermission = true;
|
||||||
for (var i = 0; i < buses.length; i++)
|
for (var i = 0; i < data.buses.length; i++)
|
||||||
if (!data.buses[i].output) {
|
if (!data.buses[i].output) {
|
||||||
hasAudioPermission = Android.hasAudioPermission();
|
hasAudioPermission = Android.hasAudioPermission();
|
||||||
break;
|
break;
|
||||||
@ -24,6 +34,77 @@ window.onload = function () {
|
|||||||
var paramsElem = document.getElementById("params");
|
var paramsElem = document.getElementById("params");
|
||||||
|
|
||||||
topButtonElem.value = hasAudioPermission ? "START" : "INIT";
|
topButtonElem.value = hasAudioPermission ? "START" : "INIT";
|
||||||
|
topButtonElem.addEventListener("click", function () {
|
||||||
|
if (!hasAudioPermission) {
|
||||||
|
Android.requestAudioPermission();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (audioStarted) {
|
||||||
|
clearInterval(outParamInterval);
|
||||||
|
Android.audioStop();
|
||||||
|
|
||||||
|
paramsElem.innerHTML = "";
|
||||||
|
|
||||||
|
topButtonElem.value = "START";
|
||||||
|
audioStarted = false;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Android.audioStart()) {
|
||||||
|
alert("Could not start audio");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < data.parameters.length; i++) {
|
||||||
|
var div = document.createElement("div");
|
||||||
|
|
||||||
|
var label = document.createElement("label");
|
||||||
|
label.setAttribute("for", "p" + i);
|
||||||
|
label.innerText = data.parameters[i].name;
|
||||||
|
|
||||||
|
var range = document.createElement("input");
|
||||||
|
range.classList.add("range");
|
||||||
|
range.setAttribute("type", "range");
|
||||||
|
range.setAttribute("id", "p" + i);
|
||||||
|
range.setAttribute("name", "p" + i);
|
||||||
|
if (data.parameters[i].isBypass || data.parameters[i].toggled) {
|
||||||
|
range.setAttribute("min", 0);
|
||||||
|
range.setAttribute("max", 1);
|
||||||
|
range.setAttribute("step", 1);
|
||||||
|
} else {
|
||||||
|
range.setAttribute("min", 0);
|
||||||
|
range.setAttribute("max", 1);
|
||||||
|
range.setAttribute("step", data.parameters[i].integer ? 1 / (data.parameters[i].maximum - data.parameters[i].minimum) : "any");
|
||||||
|
}
|
||||||
|
range.value = unmap(i, data.parameters[i].defaultValue);
|
||||||
|
if (data.parameters[i].direction == "output")
|
||||||
|
range.setAttribute("readonly", "true");
|
||||||
|
else {
|
||||||
|
let index = i;
|
||||||
|
range.addEventListener("input",
|
||||||
|
function (ev) {
|
||||||
|
Android.setParameter(index, map(index, parseFloat(ev.target.value)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
div.appendChild(label);
|
||||||
|
div.appendChild(document.createElement("br"));
|
||||||
|
div.appendChild(range);
|
||||||
|
paramsElem.appendChild(div);
|
||||||
|
}
|
||||||
|
|
||||||
|
outParamInterval = setInterval(
|
||||||
|
function () {
|
||||||
|
for (var i = 0; i < data.parameters.length; i++)
|
||||||
|
if (data.parameters[i].direction == "output")
|
||||||
|
document.getElementById("p" + i).value = unmap(i, Android.getParameter(i));
|
||||||
|
}, 50);
|
||||||
|
|
||||||
|
topButtonElem.value = "STOP";
|
||||||
|
audioStarted = true;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function gotAudioPermission() {
|
function gotAudioPermission() {
|
||||||
|
@ -3,32 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#include <algorithm>
|
|
||||||
#include <mutex>
|
|
||||||
#include <vector>
|
|
||||||
#include <jni.h>
|
|
||||||
#define MINIAUDIO_IMPLEMENTATION
|
|
||||||
#define MA_ENABLE_ONLY_SPECIFIC_BACKENDS
|
|
||||||
#define MA_ENABLE_AAUDIO
|
|
||||||
#include <miniaudio.h>
|
|
||||||
#include <amidi/AMidi.h>
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#define BLOCK_SIZE 32
|
|
||||||
#define NUM_BUFS (NUM_CHANNELS_IN > NUM_CHANNELS_OUT ? NUM_CHANNELS_IN : NUM_CHANNELS_OUT)
|
|
||||||
|
|
||||||
ma_device device;
|
|
||||||
P_TYPE instance;
|
|
||||||
float paramValues[NUM_PARAMETERS];
|
|
||||||
float bufs[NUM_BUFS][BLOCK_SIZE];
|
|
||||||
#if NUM_CHANNELS_IN != 0
|
|
||||||
const float *inBufs[NUM_CHANNELS_IN];
|
|
||||||
#endif
|
|
||||||
float *outBufs[NUM_CHANNELS_OUT];
|
|
||||||
std::mutex mutex;
|
|
||||||
#ifdef P_MEM_REQ
|
|
||||||
void *mem;
|
|
||||||
#endif
|
|
||||||
#ifdef P_NOTE_ON
|
#ifdef P_NOTE_ON
|
||||||
struct PortData {
|
struct PortData {
|
||||||
AMidiDevice *device;
|
AMidiDevice *device;
|
||||||
@ -157,6 +131,7 @@ Java_com_orastron_@JNI_NAME@_MainActivity_removeMidiPort(JNIEnv* env, jobject th
|
|||||||
#include "data.h"
|
#include "data.h"
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#if PARAMETERS_N + NUM_MIDI_INPUTS > 0
|
#if PARAMETERS_N + NUM_MIDI_INPUTS > 0
|
||||||
# include <mutex>
|
# include <mutex>
|
||||||
@ -178,14 +153,25 @@ static ma_device device;
|
|||||||
#endif
|
#endif
|
||||||
static plugin instance;
|
static plugin instance;
|
||||||
static void * mem;
|
static void * mem;
|
||||||
|
#if (NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN) || (NUM_NON_OPT_CHANNELS_OUT > NUM_CHANNELS_OUT)
|
||||||
|
float zero[BLOCK_SIZE];
|
||||||
|
#endif
|
||||||
#if NUM_CHANNELS_IN > 0
|
#if NUM_CHANNELS_IN > 0
|
||||||
float x_buf[NUM_CHANNELS_IN * BLOCK_SIZE];
|
float x_buf[NUM_CHANNELS_IN * BLOCK_SIZE];
|
||||||
#endif
|
#endif
|
||||||
|
#if NUM_ALL_CHANNELS_IN > 0
|
||||||
|
const float * x[NUM_ALL_CHANNELS_IN];
|
||||||
|
#else
|
||||||
|
const float ** x;
|
||||||
|
#endif
|
||||||
#if NUM_CHANNELS_OUT > 0
|
#if NUM_CHANNELS_OUT > 0
|
||||||
float y_buf[NUM_CHANNELS_OUT * BLOCK_SIZE];
|
float y_buf[NUM_CHANNELS_OUT * BLOCK_SIZE];
|
||||||
#endif
|
#endif
|
||||||
const float ** x;
|
#if NUM_ALL_CHANNELS_OUT > 0
|
||||||
|
float * y[NUM_ALL_CHANNELS_IN];
|
||||||
|
#else
|
||||||
float ** y;
|
float ** y;
|
||||||
|
#endif
|
||||||
#if PARAMETERS_N > 0
|
#if PARAMETERS_N > 0
|
||||||
std::mutex mutex;
|
std::mutex mutex;
|
||||||
float param_values[PARAMETERS_N];
|
float param_values[PARAMETERS_N];
|
||||||
@ -225,13 +211,17 @@ static void data_callback(ma_device* pDevice, void* pOutput, const void* pInput,
|
|||||||
x_buf[BLOCK_SIZE * k + j] = in_buf[ix];
|
x_buf[BLOCK_SIZE * k + j] = in_buf[ix];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN) || (NUM_NON_OPT_CHANNELS_OUT > NUM_CHANNELS_OUT)
|
||||||
|
memset(zero, 0, BLOCK_SIZE * sizeof(float));
|
||||||
|
#endif
|
||||||
|
|
||||||
plugin_process(&instance, x, y, n);
|
plugin_process(&instance, x, y, n);
|
||||||
|
|
||||||
#if NUM_CHANNELS_OUT > 0
|
#if NUM_CHANNELS_OUT > 0
|
||||||
size_t iy = NUM_CHANNELS_OUT * i;
|
size_t iy = NUM_CHANNELS_OUT * i;
|
||||||
for (ma_uint32 j = 0; j < n; j++)
|
for (ma_uint32 j = 0; j < n; j++)
|
||||||
for (size_t k = 0; k < NUM_CHANNELS_OUT; k++, iy++)
|
for (size_t k = 0; k < NUM_CHANNELS_OUT; k++, iy++)
|
||||||
y_buf[BLOCK_SIZE * k + j] = out_buf[ix];
|
out_buf[iy] = y_buf[BLOCK_SIZE * k + j];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
i += n;
|
i += n;
|
||||||
@ -300,15 +290,55 @@ JNI_FUNC(nativeAudioStart)(JNIEnv* env, jobject thiz) {
|
|||||||
|
|
||||||
plugin_reset(&instance);
|
plugin_reset(&instance);
|
||||||
|
|
||||||
#if NUM_CHANNELS_IN > 0
|
#if NUM_ALL_CHANNELS_IN > 0
|
||||||
for (size_t i = 0; i < NUM_CHANNELS_IN; i++)
|
# if AUDIO_BUS_IN >= 0
|
||||||
x[i] = x_buf + BLOCK_SIZE * i;
|
size_t ix = 0;
|
||||||
|
size_t ixb = 0;
|
||||||
|
for (size_t j = 0; j < NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT; j++) {
|
||||||
|
if (audio_bus_data[j].out)
|
||||||
|
continue;
|
||||||
|
if (audio_bus_data[j].index == AUDIO_BUS_IN)
|
||||||
|
for (char k = 0; k < audio_bus_data[j].channels; k++, ix++, ixb++)
|
||||||
|
x[ix] = x_buf + BLOCK_SIZE * ixb;
|
||||||
|
# if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
|
||||||
|
else if (!audio_bus_data[j].optional)
|
||||||
|
for (char k = 0; k < audio_bus_data[j].channels; k++, ix++)
|
||||||
|
x[ix] = zero;
|
||||||
|
# endif
|
||||||
|
else
|
||||||
|
for (char k = 0; k < audio_bus_data[j].channels; k++, ix++)
|
||||||
|
x[ix] = NULL;
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
for (size_t i = 0; i < NUM_ALL_CHANNELS_IN; i++)
|
||||||
|
x[i] = NULL;
|
||||||
|
# endif
|
||||||
#else
|
#else
|
||||||
x = NULL;
|
x = NULL;
|
||||||
#endif
|
#endif
|
||||||
#if NUM_CHANNELS_OUT > 0
|
#if NUM_ALL_CHANNELS_OUT > 0
|
||||||
for (size_t i = 0; i < NUM_CHANNELS_OUT; i++)
|
# if AUDIO_BUS_OUT >= 0
|
||||||
y[i] = y_buf + BLOCK_SIZE * i;
|
size_t iy = 0;
|
||||||
|
size_t iyb = 0;
|
||||||
|
for (size_t j = 0; j < NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT; j++) {
|
||||||
|
if (!audio_bus_data[j].out)
|
||||||
|
continue;
|
||||||
|
if (audio_bus_data[j].index == AUDIO_BUS_OUT)
|
||||||
|
for (char k = 0; k < audio_bus_data[j].channels; k++, iy++, iyb++)
|
||||||
|
y[iy] = y_buf + BLOCK_SIZE * iyb;
|
||||||
|
# if NUM_NON_OPT_CHANNELS_OUT > NUM_CHANNELS_OUT
|
||||||
|
else if (!audio_bus_data[j].optional)
|
||||||
|
for (char k = 0; k < audio_bus_data[j].channels; k++, iy++)
|
||||||
|
y[iy] = zero;
|
||||||
|
# endif
|
||||||
|
else
|
||||||
|
for (char k = 0; k < audio_bus_data[j].channels; k++, iy++)
|
||||||
|
y[iy] = NULL;
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
for (size_t i = 0; i < NUM_ALL_CHANNELS_OUT; i++)
|
||||||
|
y[i] = NULL;
|
||||||
|
# endif
|
||||||
#else
|
#else
|
||||||
y = NULL;
|
y = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user