fixed buffer handling in android, cmd, daisy-seed, ios hopefully

This commit is contained in:
Stefano D'Angelo 2024-02-08 12:06:19 +01:00
parent d2b19e97e8
commit ccfb731147
10 changed files with 246 additions and 250 deletions

1
TODO
View File

@ -28,3 +28,4 @@
* plugin_init and plugin_set_sample_rate to return char (can fail)
* daisy-seed and android: isolate C part from C++
* cmd help and version
* common code... (eg buffer handling android ios cmd daisy-seed)?

View File

@ -1,11 +1,11 @@
#define NUM_AUDIO_BUSES_IN {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "input").length}}
#define NUM_AUDIO_BUSES_OUT {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "output").length}}
#define AUDIO_BUS_IN {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain)}}
#define AUDIO_BUS_OUT {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "output" && !x.cv && !x.sidechain)}}
#define AUDIO_BUS_IN {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain && !x.optional)}}
#define AUDIO_BUS_OUT {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "output" && !x.cv && !x.sidechain && !x.optional)}}
#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_CHANNELS_IN {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain && !x.optional) ? (it.product.buses.filter(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain && !x.optional)[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 && !x.optional) ? (it.product.buses.filter(x => x.type == "audio" && x.direction == "output" && !x.cv && !x.sidechain && !x.optional)[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)}}
@ -15,9 +15,8 @@
#define MIDI_BUS_IN {{=it.product.buses.findIndex(x => x.type == "midi" && x.direction == "input")}}
#if (AUDIO_BUS_IN >= 0) || (AUDIO_BUS_OUT >= 0)
#if NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT > 0
static struct {
size_t index;
char out;
char optional;
char channels;
@ -25,7 +24,6 @@ static struct {
{{~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}}

View File

@ -38,22 +38,26 @@
static ma_device device;
static plugin instance;
static void * mem;
#if (NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN) || (NUM_NON_OPT_CHANNELS_OUT > NUM_CHANNELS_OUT)
#if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
float zero[BLOCK_SIZE];
#endif
#if NUM_CHANNELS_IN > 0
float x_buf[NUM_CHANNELS_IN * BLOCK_SIZE];
float * x_in[NUM_CHANNELS_IN];
#endif
#if NUM_ALL_CHANNELS_IN > 0
const float * x[NUM_ALL_CHANNELS_IN];
#else
const float ** x;
#endif
#if NUM_NON_OPT_CHANNELS_OUT > 0
float y_buf[NUM_NON_OPT_CHANNELS_OUT * BLOCK_SIZE];
#endif
#if NUM_CHANNELS_OUT > 0
float y_buf[NUM_CHANNELS_OUT * BLOCK_SIZE];
float * y_out[NUM_CHANNELS_OUT];
#endif
#if NUM_ALL_CHANNELS_OUT > 0
float * y[NUM_ALL_CHANNELS_IN];
float * y[NUM_ALL_CHANNELS_OUT];
#else
float ** y;
#endif
@ -116,26 +120,26 @@ static void data_callback(ma_device* pDevice, void* pOutput, const void* pInput,
}
#endif
const float * in_buf = reinterpret_cast<const float *>(pInput);
float * out_buf = reinterpret_cast<float *>(pOutput);
ma_uint32 i = 0;
#if NUM_CHANNELS_IN > 0
const float * in_buf = reinterpret_cast<const float *>(pInput);
size_t ix = 0;
#else
(void)pInput;
#endif
#if NUM_CHANNELS_OUT > 0
float * out_buf = reinterpret_cast<float *>(pOutput);
size_t iy = 0;
#else
(void)pOutput;
#endif
ma_uint32 i = 0;
while (i < frameCount) {
ma_uint32 n = std::min(frameCount - i, static_cast<ma_uint32>(BLOCK_SIZE));
#if NUM_CHANNELS_IN > 0
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
#if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
memset(zero, 0, BLOCK_SIZE * sizeof(float));
x_in[k][j] = in_buf[ix];
#endif
plugin_process(&instance, x, y, n);
@ -143,7 +147,7 @@ static void data_callback(ma_device* pDevice, void* pOutput, const void* pInput,
#if NUM_CHANNELS_OUT > 0
for (ma_uint32 j = 0; j < n; j++)
for (size_t k = 0; k < NUM_CHANNELS_OUT; k++, iy++)
out_buf[iy] = y_buf[BLOCK_SIZE * k + j];
out_buf[iy] = y_out[k][j];
#elif NUM_CHANNELS_IN == 0
for (ma_uint32 j = 0; j < n; j++)
out_buf[j] = 0;
@ -158,7 +162,6 @@ static void data_callback(ma_device* pDevice, void* pOutput, const void* pInput,
_MM_SET_FLUSH_ZERO_MODE(flush_zero_mode);
_MM_SET_DENORMALS_ZERO_MODE(denormals_zero_mode);
#endif
}
extern "C"
@ -194,9 +197,9 @@ JNI_FUNC(nativeAudioStart)(JNIEnv* env, jobject thiz) {
deviceConfig.playback.pDeviceID = NULL;
deviceConfig.playback.format = ma_format_f32;
#if NUM_CHANNELS_IN + NUM_CHANNELS_OUT > 0
deviceConfig.playback.channels = NUM_CHANNELS_OUT;
deviceConfig.playback.channels = NUM_CHANNELS_OUT;
#else
deviceConfig.playback.channels = 1; // Fake & muted
deviceConfig.playback.channels = 1; // Fake & muted
#endif
deviceConfig.playback.shareMode = ma_share_mode_shared;
@ -229,58 +232,51 @@ JNI_FUNC(nativeAudioStart)(JNIEnv* env, jobject thiz) {
plugin_reset(&instance);
#if NUM_ALL_CHANNELS_IN > 0
# if AUDIO_BUS_IN >= 0
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)
for (size_t i = 0, j = 0, k = 0; i < NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT; i++) {
if (audio_bus_data[i].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;
for (int l = 0; l < audio_bus_data[i].channels; l++, j++) {
if (AUDIO_BUS_IN == i) {
float * b = x_buf + BLOCK_SIZE * k;
x[j] = b;
x_in[l] = b;
k++;
} else
#if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
x[j] = audio_bus_data[i].optional ? NULL : zero;
#else
x[j] = NULL;
#endif
}
}
# else
for (size_t i = 0; i < NUM_ALL_CHANNELS_IN; i++)
x[i] = NULL;
# endif
#else
x = NULL;
#endif
#if NUM_ALL_CHANNELS_OUT > 0
# if AUDIO_BUS_OUT >= 0
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)
for (size_t i = 0, j = 0, k = 0; i < NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT; i++) {
if (!audio_bus_data[i].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;
for (int l = 0; l < audio_bus_data[i].channels; l++, j++) {
if (AUDIO_BUS_OUT == i) {
y[j] = y_buf + BLOCK_SIZE * k;
y_out[l] = y[j];
k++;
} else if (!audio_bus_data[i].optional) {
y[j] = y_buf + BLOCK_SIZE * k;
k++;
} else
y[j] = NULL;
}
}
# else
for (size_t i = 0; i < NUM_ALL_CHANNELS_OUT; i++)
y[i] = NULL;
# endif
#else
y = NULL;
#endif
#if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
memset(zero, 0, BLOCK_SIZE * sizeof(float));
#endif
if (ma_device_start(&device) != MA_SUCCESS) {
if (mem != NULL)
free(mem);

View File

@ -1,11 +1,11 @@
#define NUM_AUDIO_BUSES_IN {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "input").length}}
#define NUM_AUDIO_BUSES_OUT {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "output").length}}
#define AUDIO_BUS_IN {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain)}}
#define AUDIO_BUS_OUT {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "output" && !x.cv && !x.sidechain)}}
#define AUDIO_BUS_IN {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain && !x.optional)}}
#define AUDIO_BUS_OUT {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "output" && !x.cv && !x.sidechain && !x.optional)}}
#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_CHANNELS_IN {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain && !x.optional) ? (it.product.buses.filter(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain && !x.optional)[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 && !x.optional) ? (it.product.buses.filter(x => x.type == "audio" && x.direction == "output" && !x.cv && !x.sidechain && !x.optional)[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)}}
@ -15,9 +15,8 @@
#define MIDI_BUS_IN {{=it.product.buses.findIndex(x => x.type == "midi" && x.direction == "input")}}
#if (AUDIO_BUS_IN >= 0) || (AUDIO_BUS_OUT >= 0)
#if NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT > 0
static struct {
size_t index;
char out;
char optional;
char channels;
@ -25,7 +24,6 @@ static struct {
{{~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}}

View File

@ -23,18 +23,28 @@
plugin instance;
void * mem;
#if (NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN) || (NUM_NON_OPT_CHANNELS_OUT > NUM_CHANNELS_OUT)
float zero[BLOCK_SIZE];
#if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
float * zero;
#endif
#if NUM_CHANNELS_IN > 0
float * x_buf;
float * x_in[NUM_CHANNELS_IN];
#endif
#if NUM_ALL_CHANNELS_IN > 0
float * x[NUM_ALL_CHANNELS_IN];
const float * x[NUM_ALL_CHANNELS_IN];
#else
const float ** x = NULL;
const float ** x;
#endif
#if NUM_NON_OPT_CHANNELS_OUT > 0
float * y_buf;
#endif
#if NUM_CHANNELS_OUT > 0
float * y_out[NUM_CHANNELS_OUT];
#endif
#if NUM_ALL_CHANNELS_OUT > 0
float * y[NUM_ALL_CHANNELS_OUT];
#else
float ** y = NULL;
float ** y;
#endif
float fs = 44100.f;
size_t bufsize = 128;
@ -344,68 +354,69 @@ int main(int argc, char * argv[]) {
plugin_reset(&instance);
#if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
zero = malloc(bufsize * sizeof(float));
if (zero == NULL) {
fprintf(stderr, "Out of memory\n");
goto err_zero;
}
memset(zero, 0, bufsize * sizeof(float));
#endif
#if NUM_CHANNELS_IN > 0
float * x_buf = malloc(NUM_CHANNELS_IN * bufsize * sizeof(float));
x_buf = malloc(NUM_CHANNELS_IN * bufsize * sizeof(float));
if (x_buf == NULL) {
fprintf(stderr, "Out of memory\n");
goto err_x_buf;
}
#endif
#if NUM_ALL_CHANNELS_IN > 0
# if AUDIO_BUS_IN >= 0
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)
for (size_t i = 0, j = 0, k = 0; i < NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT; i++) {
if (audio_bus_data[i].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 + bufsize * 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;
for (int l = 0; l < audio_bus_data[i].channels; l++, j++) {
if (AUDIO_BUS_IN == i) {
float * b = x_buf + bufsize * k;
x[j] = b;
x_in[l] = b;
k++;
} else
#if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
x[j] = audio_bus_data[i].optional ? NULL : zero;
#else
x[j] = NULL;
#endif
}
}
# else
for (size_t i = 0; i < NUM_ALL_CHANNELS_IN; i++)
x[i] = NULL;
# endif
#else
x = NULL;
#endif
#if NUM_CHANNELS_OUT > 0
float * y_buf = malloc(NUM_CHANNELS_OUT * bufsize * sizeof(float));
#if NUM_NON_OPT_CHANNELS_OUT > 0
y_buf = malloc(NUM_NON_OPT_CHANNELS_OUT * bufsize * sizeof(float));
if (y_buf == NULL) {
fprintf(stderr, "Out of memory\n");
goto err_y_buf;
}
#endif
#if NUM_ALL_CHANNELS_OUT > 0
# if AUDIO_BUS_OUT >= 0
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)
for (size_t i = 0, j = 0, k = 0; i < NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT; i++) {
if (!audio_bus_data[i].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 + bufsize * 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;
for (int l = 0; l < audio_bus_data[i].channels; l++, j++) {
if (AUDIO_BUS_OUT == i) {
y[j] = y_buf + bufsize * k;
y_out[l] = y[j];
k++;
} else if (!audio_bus_data[i].optional) {
y[j] = y_buf + bufsize * k;
k++;
} else
y[j] = NULL;
}
}
# else
for (size_t i = 0; i < NUM_ALL_CHANNELS_OUT; i++)
y[i] = NULL;
# endif
#else
y = NULL;
#endif
#if NUM_MIDI_INPUTS > 0
@ -453,24 +464,20 @@ int main(int argc, char * argv[]) {
goto err_outfile;
#endif
#if NUM_CHANNELS_IN > 0
while (1) {
int32_t n = tinywav_read_f(&tw_in, x, bufsize);
if (n == 0)
break;
# if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
memset(zero, 0, bufsize * sizeof(float));
# endif
#else
size_t i = 0;
#if NUM_CHANNELS_IN > 0
size_t len = tw_in.numFramesInHeader;
#else
size_t len = (size_t)(tw_in.h.SampleRate * length + 0.5f);
#endif
while (i < len) {
size_t left = len - i;
size_t n = left > bufsize ? bufsize : left;
#if NUM_CHANNELS_IN > 0
n = tinywav_read_f(&tw_in, x_in, n);
if (n == 0)
break;
#endif
#if NUM_MIDI_INPUTS > 0
while (1) {
if (midi_next > 0.0)
@ -508,7 +515,7 @@ int main(int argc, char * argv[]) {
midi_next -= 1e6 * ((double)n / (double)tw_in.h.SampleRate);
#endif
plugin_process(&instance, (const float **)x, y, n);
plugin_process(&instance, x, y, n);
#if PARAMETERS_N > 0
for (size_t j = 0; j < PARAMETERS_N; j++) {
@ -520,12 +527,10 @@ int main(int argc, char * argv[]) {
#endif
#if NUM_CHANNELS_OUT > 0
tinywav_write_f(&tw_out, y, n);
tinywav_write_f(&tw_out, y_out, n);
#endif
#if NUM_CHANNELS_IN == 0
i += n;
#endif
}
exit_code = EXIT_SUCCESS;
@ -542,12 +547,16 @@ err_midi_read:
#endif
#if NUM_CHANNELS_OUT > 0
free(y_buf);
#endif
err_y_buf:
#endif
#if NUM_CHANNELS_IN > 0
free(x_buf);
#endif
err_x_buf:
#endif
#if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
free(zero);
err_zero:
#endif
if (mem != NULL)
free(mem);
err_mem_alloc:

View File

@ -1,11 +1,11 @@
#define NUM_AUDIO_BUSES_IN {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "input").length}}
#define NUM_AUDIO_BUSES_OUT {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "output").length}}
#define AUDIO_BUS_IN {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain)}}
#define AUDIO_BUS_OUT {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "output" && !x.cv && !x.sidechain)}}
#define AUDIO_BUS_IN {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain && !x.optional)}}
#define AUDIO_BUS_OUT {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "output" && !x.cv && !x.sidechain && !x.optional)}}
#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_CHANNELS_IN {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain && !x.optional) ? (it.product.buses.filter(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain && !x.optional)[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 && !x.optional) ? (it.product.buses.filter(x => x.type == "audio" && x.direction == "output" && !x.cv && !x.sidechain && !x.optional)[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)}}

View File

@ -1,10 +1,10 @@
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "data.h"
#include "plugin.h"
#include <string.h>
#include <math.h>
#include "daisy_seed.h"
@ -35,14 +35,14 @@ const float * x[NUM_ALL_CHANNELS_IN];
#else
const float ** x;
#endif
#if NUM_CHANNELS_IN > 0
float * y_out[NUM_CHANNELS_OUT];
#endif
#if NUM_NON_OPT_CHANNELS_OUT > 0
float y_buf[NUM_NON_OPT_CHANNELS_OUT * BLOCK_SIZE];
#endif
#if NUM_CHANNELS_OUT > 0
float * y_out[NUM_CHANNELS_OUT];
#endif
#if NUM_ALL_CHANNELS_OUT > 0
float * y[NUM_ALL_CHANNELS_IN];
float * y[NUM_ALL_CHANNELS_OUT];
#else
float ** y;
#endif
@ -169,20 +169,21 @@ int main() {
plugin_reset(&instance);
#if NUM_ALL_CHANNELS_IN > 0
for (size_t i = 0, j = 0, k = 0; i < NUM_ALL_CHANNELS_IN + NUM_ALL_CHANNELS_OUT; i++) {
for (size_t i = 0, j = 0, k = 0; i < NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT; i++) {
if (audio_bus_data[i].out)
continue;
for (int l = 0; l < audio_bus_data[i].channels; l++) {
if (audio_bus_data[i].optional)
x[j] = NULL;
else {
for (int l = 0; l < audio_bus_data[i].channels; l++, j++) {
if (AUDIO_BUS_IN == i) {
float * b = x_buf + BLOCK_SIZE * k;
x[j] = b;
if (AUDIO_BUS_IN == i)
x_in[l] = b;
x_in[l] = b;
k++;
}
j++;
} else
#if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
x[j] = audio_bus_data[i].optional ? NULL : zero;
#else
x[j] = NULL;
#endif
}
}
#else
@ -190,14 +191,19 @@ int main() {
#endif
#if NUM_ALL_CHANNELS_OUT > 0
for (size_t i = 0, j = 0; i < NUM_ALL_CHANNELS_IN + NUM_ALL_CHANNELS_OUT; i++) {
for (size_t i = 0, j = 0, k = 0; i < NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT; i++) {
if (!audio_bus_data[i].out)
continue;
for (int k = 0; k < audio_bus_data[i].channels; k++) {
y[j] = y_buf + BLOCK_SIZE * j;
if (AUDIO_BUS_OUT == i)
y_out[k] = y[j];
j++;
for (int l = 0; l < audio_bus_data[i].channels; l++, j++) {
if (AUDIO_BUS_OUT == i) {
y[j] = y_buf + BLOCK_SIZE * k;
y_out[l] = y[j];
k++;
} else if (!audio_bus_data[i].optional) {
y[j] = y_buf + BLOCK_SIZE * k;
k++;
} else
y[j] = NULL;
}
}
#else

View File

@ -1,14 +1,11 @@
#include <stddef.h>
#include <stdint.h>
#define NUM_AUDIO_BUSES_IN {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "input").length}}
#define NUM_AUDIO_BUSES_OUT {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "output").length}}
#define AUDIO_BUS_IN {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain)}}
#define AUDIO_BUS_OUT {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "output" && !x.cv && !x.sidechain)}}
#define AUDIO_BUS_IN {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain && !x.optional)}}
#define AUDIO_BUS_OUT {{=it.product.buses.findIndex(x => x.type == "audio" && x.direction == "output" && !x.cv && !x.sidechain && !x.optional)}}
#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_CHANNELS_IN {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain && !x.optional) ? (it.product.buses.filter(x => x.type == "audio" && x.direction == "input" && !x.cv && !x.sidechain && !x.optional)[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 && !x.optional) ? (it.product.buses.filter(x => x.type == "audio" && x.direction == "output" && !x.cv && !x.sidechain && !x.optional)[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)}}
@ -18,9 +15,8 @@
#define MIDI_BUS_IN {{=it.product.buses.findIndex(x => x.type == "midi" && x.direction == "input")}}
#if (AUDIO_BUS_IN >= 0) || (AUDIO_BUS_OUT >= 0)
#if NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT > 0
static struct {
size_t index;
char out;
char optional;
char channels;
@ -28,7 +24,6 @@ static struct {
{{~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}}

View File

@ -2,6 +2,9 @@
* Copyright (C) 2023, 2024 Orastron Srl unipersonale
*/
#include <stdlib.h>
#include <stdint.h>
#include "data.h"
#include "plugin.h"
#if PARAMETERS_N > 0
@ -16,43 +19,45 @@
#include "miniaudio.h"
#define BLOCK_SIZE 32
#define NUM_BUFS (NUM_CHANNELS_IN > NUM_CHANNELS_OUT ? NUM_CHANNELS_IN : NUM_CHANNELS_OUT)
static ma_device device;
static plugin instance;
static void *mem;
#if (NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN) || (NUM_NON_OPT_CHANNELS_OUT > NUM_CHANNELS_OUT)
float zero[BLOCK_SIZE];
static ma_device device;
static plugin instance;
static void * mem;
#if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
float zero[BLOCK_SIZE];
#endif
#if NUM_CHANNELS_IN > 0
float x_buf[NUM_CHANNELS_IN * BLOCK_SIZE];
float x_buf[NUM_CHANNELS_IN * BLOCK_SIZE];
float * x_in[NUM_CHANNELS_IN];
#endif
#if NUM_ALL_CHANNELS_IN > 0
const float *x[NUM_ALL_CHANNELS_IN];
const float * x[NUM_ALL_CHANNELS_IN];
#else
const float **x;
const float ** x;
#endif
#if NUM_NON_OPT_CHANNELS_OUT > 0
float y_buf[NUM_NON_OPT_CHANNELS_OUT * BLOCK_SIZE];
#endif
#if NUM_CHANNELS_OUT > 0
float y_buf[NUM_CHANNELS_OUT * BLOCK_SIZE];
float * y_out[NUM_CHANNELS_OUT];
#endif
#if NUM_ALL_CHANNELS_OUT > 0
float *y[NUM_ALL_CHANNELS_IN];
float * y[NUM_ALL_CHANNELS_OUT];
#else
float **y;
float ** y;
#endif
#if PARAMETERS_N > 0
std::mutex mutex;
float param_values[PARAMETERS_N];
float param_values_prev[PARAMETERS_N];
std::mutex mutex;
float param_values[PARAMETERS_N];
float param_values_prev[PARAMETERS_N];
#endif
#if NUM_MIDI_INPUTS > 0
CFStringRef midiClientName = NULL;
MIDIClientRef midiClient = NULL;
CFStringRef midiInputName = NULL;
MIDIPortRef midiPort = NULL;
CFStringRef midiClientName = NULL;
MIDIClientRef midiClient = NULL;
CFStringRef midiInputName = NULL;
MIDIPortRef midiPort = NULL;
#define MIDIBUFFERLEN 1023
uint8_t midiBuffer[MIDIBUFFERLEN];
int midiBuffer_i = 0;
uint8_t midiBuffer[MIDIBUFFERLEN];
int midiBuffer_i = 0;
#endif
static void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount) {
@ -89,31 +94,26 @@ static void data_callback(ma_device* pDevice, void* pOutput, const void* pInput,
}
#endif
#if NUM_CHANNELS_IN == 0
(void)pInput;
#else
const float * in_buf = reinterpret_cast<const float *>(pInput);
#endif
float * out_buf = reinterpret_cast<float *>(pOutput);
ma_uint32 i = 0;
#if NUM_CHANNELS_IN > 0
const float * in_buf = reinterpret_cast<const float *>(pInput);
size_t ix = 0;
#else
(void)pInput;
#endif
#if NUM_CHANNELS_OUT > 0
float * out_buf = reinterpret_cast<float *>(pOutput);
size_t iy = 0;
#else
(void)pOutput;
#endif
ma_uint32 i = 0;
while (i < frameCount) {
ma_uint32 n = std::min(frameCount - i, static_cast<ma_uint32>(BLOCK_SIZE));
#if NUM_CHANNELS_IN > 0
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
#if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
memset(zero, 0, BLOCK_SIZE * sizeof(float));
x_in[k][j] = in_buf[ix];
#endif
plugin_process(&instance, x, y, n);
@ -121,12 +121,13 @@ static void data_callback(ma_device* pDevice, void* pOutput, const void* pInput,
#if NUM_CHANNELS_OUT > 0
for (ma_uint32 j = 0; j < n; j++)
for (size_t k = 0; k < NUM_CHANNELS_OUT; k++, iy++)
out_buf[iy] = y_buf[BLOCK_SIZE * k + j];
out_buf[iy] = y_out[k][j];
#elif NUM_CHANNELS_IN == 0
for (ma_uint32 j = 0; j < n; j++)
out_buf[j] = 0.f;
#endif
i += n;
i += n;
}
#if defined(__aarch64__)
@ -258,61 +259,53 @@ char audioStart() {
mem = NULL;
plugin_reset(&instance);
#if NUM_ALL_CHANNELS_IN > 0
# if AUDIO_BUS_IN >= 0
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)
for (size_t i = 0, j = 0, k = 0; i < NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT; i++) {
if (audio_bus_data[i].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;
for (int l = 0; l < audio_bus_data[i].channels; l++, j++) {
if (AUDIO_BUS_IN == i) {
float * b = x_buf + BLOCK_SIZE * k;
x[j] = b;
x_in[l] = b;
k++;
} else
#if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
x[j] = audio_bus_data[i].optional ? NULL : zero;
#else
x[j] = NULL;
#endif
}
}
# else
for (size_t i = 0; i < NUM_ALL_CHANNELS_IN; i++)
x[i] = NULL;
# endif
#else
x = NULL;
#endif
#if NUM_ALL_CHANNELS_OUT > 0
# if AUDIO_BUS_OUT >= 0
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)
for (size_t i = 0, j = 0, k = 0; i < NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT; i++) {
if (!audio_bus_data[i].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;
for (int l = 0; l < audio_bus_data[i].channels; l++, j++) {
if (AUDIO_BUS_OUT == i) {
y[j] = y_buf + BLOCK_SIZE * k;
y_out[l] = y[j];
k++;
} else if (!audio_bus_data[i].optional) {
y[j] = y_buf + BLOCK_SIZE * k;
k++;
} else
y[j] = NULL;
}
}
# else
for (size_t i = 0; i < NUM_ALL_CHANNELS_OUT; i++)
y[i] = NULL;
# endif
#else
y = NULL;
#endif
#if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
memset(zero, 0, BLOCK_SIZE * sizeof(float));
#endif
if (ma_device_start(&device) != MA_SUCCESS) {
if (mem != NULL)
free(mem);

View File

@ -1,4 +1,4 @@
#define DATA_LV2_URI "{{=it.tibia.CGetUTF8StringLiteral(it.tibia.lv2.expandURI(it.lv2.uri))}}"
#define DATA_LV2_URI "{{=it.tibia.CGetUTF8StringLiteral(it.tibia.lv2.expandURI(it.lv2.uri))}}"
#define DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "input").reduce((s, x) => s += x.channels == "mono" ? 1 : 2, 0)}}
#define DATA_PRODUCT_AUDIO_OUTPUT_CHANNELS_N {{=it.product.buses.filter(x => x.type == "audio" && x.direction == "output").reduce((s, x) => s += x.channels == "mono" ? 1 : 2, 0)}}