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) * plugin_init and plugin_set_sample_rate to return char (can fail)
* daisy-seed and android: isolate C part from C++ * daisy-seed and android: isolate C part from C++
* cmd help and version * 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_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 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_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)}} #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_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) ? (it.product.buses.filter(x => x.type == "audio" && x.direction == "output" && !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 && !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_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_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_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")}} #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 { static struct {
size_t index;
char out; char out;
char optional; char optional;
char channels; char channels;
@ -25,7 +24,6 @@ static struct {
{{~it.product.buses :b:i}} {{~it.product.buses :b:i}}
{{?b.type == "audio"}} {{?b.type == "audio"}}
{ {
/* .index = */ {{=i}},
/* .out = */ {{=b.direction == "output" ? 1 : 0}}, /* .out = */ {{=b.direction == "output" ? 1 : 0}},
/* .optional = */ {{=b.optional ? 1 : 0}}, /* .optional = */ {{=b.optional ? 1 : 0}},
/* .channels = */ {{=b.channels == "mono" ? 1 : 2}} /* .channels = */ {{=b.channels == "mono" ? 1 : 2}}

View File

@ -38,22 +38,26 @@
static ma_device device; static ma_device device;
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) #if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
float zero[BLOCK_SIZE]; float zero[BLOCK_SIZE];
#endif #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];
float * x_in[NUM_CHANNELS_IN];
#endif #endif
#if NUM_ALL_CHANNELS_IN > 0 #if NUM_ALL_CHANNELS_IN > 0
const float * x[NUM_ALL_CHANNELS_IN]; const float * x[NUM_ALL_CHANNELS_IN];
#else #else
const float ** x; const float ** x;
#endif #endif
#if NUM_NON_OPT_CHANNELS_OUT > 0
float y_buf[NUM_NON_OPT_CHANNELS_OUT * BLOCK_SIZE];
#endif
#if NUM_CHANNELS_OUT > 0 #if NUM_CHANNELS_OUT > 0
float y_buf[NUM_CHANNELS_OUT * BLOCK_SIZE]; float * y_out[NUM_CHANNELS_OUT];
#endif #endif
#if NUM_ALL_CHANNELS_OUT > 0 #if NUM_ALL_CHANNELS_OUT > 0
float * y[NUM_ALL_CHANNELS_IN]; float * y[NUM_ALL_CHANNELS_OUT];
#else #else
float ** y; float ** y;
#endif #endif
@ -116,26 +120,26 @@ static void data_callback(ma_device* pDevice, void* pOutput, const void* pInput,
} }
#endif #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 #if NUM_CHANNELS_IN > 0
const float * in_buf = reinterpret_cast<const float *>(pInput);
size_t ix = 0; size_t ix = 0;
#else
(void)pInput;
#endif #endif
#if NUM_CHANNELS_OUT > 0 #if NUM_CHANNELS_OUT > 0
float * out_buf = reinterpret_cast<float *>(pOutput);
size_t iy = 0; size_t iy = 0;
#else
(void)pOutput;
#endif #endif
ma_uint32 i = 0;
while (i < frameCount) { while (i < frameCount) {
ma_uint32 n = std::min(frameCount - i, static_cast<ma_uint32>(BLOCK_SIZE)); ma_uint32 n = std::min(frameCount - i, static_cast<ma_uint32>(BLOCK_SIZE));
#if NUM_CHANNELS_IN > 0 #if NUM_CHANNELS_IN > 0
for (ma_uint32 j = 0; j < n; j++) for (ma_uint32 j = 0; j < n; j++)
for (size_t k = 0; k < NUM_CHANNELS_IN; k++, ix++) for (size_t k = 0; k < NUM_CHANNELS_IN; k++, ix++)
x_buf[BLOCK_SIZE * k + j] = in_buf[ix]; x_in[k][j] = in_buf[ix];
#endif
#if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
memset(zero, 0, BLOCK_SIZE * sizeof(float));
#endif #endif
plugin_process(&instance, x, y, n); 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 #if NUM_CHANNELS_OUT > 0
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++)
out_buf[iy] = y_buf[BLOCK_SIZE * k + j]; out_buf[iy] = y_out[k][j];
#elif NUM_CHANNELS_IN == 0 #elif NUM_CHANNELS_IN == 0
for (ma_uint32 j = 0; j < n; j++) for (ma_uint32 j = 0; j < n; j++)
out_buf[j] = 0; 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_FLUSH_ZERO_MODE(flush_zero_mode);
_MM_SET_DENORMALS_ZERO_MODE(denormals_zero_mode); _MM_SET_DENORMALS_ZERO_MODE(denormals_zero_mode);
#endif #endif
} }
extern "C" extern "C"
@ -229,58 +232,51 @@ JNI_FUNC(nativeAudioStart)(JNIEnv* env, jobject thiz) {
plugin_reset(&instance); plugin_reset(&instance);
#if NUM_ALL_CHANNELS_IN > 0 #if NUM_ALL_CHANNELS_IN > 0
# if AUDIO_BUS_IN >= 0 for (size_t i = 0, j = 0, k = 0; i < NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT; i++) {
size_t ix = 0; if (audio_bus_data[i].out)
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; continue;
if (audio_bus_data[j].index == AUDIO_BUS_IN) for (int l = 0; l < audio_bus_data[i].channels; l++, j++) {
for (char k = 0; k < audio_bus_data[j].channels; k++, ix++, ixb++) if (AUDIO_BUS_IN == i) {
x[ix] = x_buf + BLOCK_SIZE * ixb; 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 #if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
else if (!audio_bus_data[j].optional) x[j] = audio_bus_data[i].optional ? NULL : zero;
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 #else
for (size_t i = 0; i < NUM_ALL_CHANNELS_IN; i++) x[j] = NULL;
x[i] = NULL;
#endif #endif
}
}
#else #else
x = NULL; x = NULL;
#endif #endif
#if NUM_ALL_CHANNELS_OUT > 0 #if NUM_ALL_CHANNELS_OUT > 0
# if AUDIO_BUS_OUT >= 0 for (size_t i = 0, j = 0, k = 0; i < NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT; i++) {
size_t iy = 0; if (!audio_bus_data[i].out)
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; continue;
if (audio_bus_data[j].index == AUDIO_BUS_OUT) for (int l = 0; l < audio_bus_data[i].channels; l++, j++) {
for (char k = 0; k < audio_bus_data[j].channels; k++, iy++, iyb++) if (AUDIO_BUS_OUT == i) {
y[iy] = y_buf + BLOCK_SIZE * iyb; y[j] = y_buf + BLOCK_SIZE * k;
# if NUM_NON_OPT_CHANNELS_OUT > NUM_CHANNELS_OUT y_out[l] = y[j];
else if (!audio_bus_data[j].optional) k++;
for (char k = 0; k < audio_bus_data[j].channels; k++, iy++) } else if (!audio_bus_data[i].optional) {
y[iy] = zero; y[j] = y_buf + BLOCK_SIZE * k;
# endif k++;
else } else
for (char k = 0; k < audio_bus_data[j].channels; k++, iy++) y[j] = NULL;
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
#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 (ma_device_start(&device) != MA_SUCCESS) {
if (mem != NULL) if (mem != NULL)
free(mem); 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_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 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_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)}} #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_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) ? (it.product.buses.filter(x => x.type == "audio" && x.direction == "output" && !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 && !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_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_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_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")}} #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 { static struct {
size_t index;
char out; char out;
char optional; char optional;
char channels; char channels;
@ -25,7 +24,6 @@ static struct {
{{~it.product.buses :b:i}} {{~it.product.buses :b:i}}
{{?b.type == "audio"}} {{?b.type == "audio"}}
{ {
/* .index = */ {{=i}},
/* .out = */ {{=b.direction == "output" ? 1 : 0}}, /* .out = */ {{=b.direction == "output" ? 1 : 0}},
/* .optional = */ {{=b.optional ? 1 : 0}}, /* .optional = */ {{=b.optional ? 1 : 0}},
/* .channels = */ {{=b.channels == "mono" ? 1 : 2}} /* .channels = */ {{=b.channels == "mono" ? 1 : 2}}

View File

@ -23,18 +23,28 @@
plugin instance; plugin instance;
void * mem; 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]; float * zero;
#endif
#if NUM_CHANNELS_IN > 0
float * x_buf;
float * x_in[NUM_CHANNELS_IN];
#endif #endif
#if NUM_ALL_CHANNELS_IN > 0 #if NUM_ALL_CHANNELS_IN > 0
float * x[NUM_ALL_CHANNELS_IN]; const float * x[NUM_ALL_CHANNELS_IN];
#else #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 #endif
#if NUM_ALL_CHANNELS_OUT > 0 #if NUM_ALL_CHANNELS_OUT > 0
float * y[NUM_ALL_CHANNELS_OUT]; float * y[NUM_ALL_CHANNELS_OUT];
#else #else
float ** y = NULL; float ** y;
#endif #endif
float fs = 44100.f; float fs = 44100.f;
size_t bufsize = 128; size_t bufsize = 128;
@ -344,68 +354,69 @@ int main(int argc, char * argv[]) {
plugin_reset(&instance); 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 #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) { if (x_buf == NULL) {
fprintf(stderr, "Out of memory\n"); fprintf(stderr, "Out of memory\n");
goto err_x_buf; goto err_x_buf;
} }
#endif #endif
#if NUM_ALL_CHANNELS_IN > 0 #if NUM_ALL_CHANNELS_IN > 0
# if AUDIO_BUS_IN >= 0 for (size_t i = 0, j = 0, k = 0; i < NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT; i++) {
size_t ix = 0; if (audio_bus_data[i].out)
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; continue;
if (audio_bus_data[j].index == AUDIO_BUS_IN) for (int l = 0; l < audio_bus_data[i].channels; l++, j++) {
for (char k = 0; k < audio_bus_data[j].channels; k++, ix++, ixb++) if (AUDIO_BUS_IN == i) {
x[ix] = x_buf + bufsize * ixb; float * b = x_buf + bufsize * k;
x[j] = b;
x_in[l] = b;
k++;
} else
#if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN #if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
else if (!audio_bus_data[j].optional) x[j] = audio_bus_data[i].optional ? NULL : zero;
for (char k = 0; k < audio_bus_data[j].channels; k++, ix++) #else
x[ix] = zero; x[j] = NULL;
#endif #endif
else }
for (char k = 0; k < audio_bus_data[j].channels; k++, ix++)
x[ix] = NULL;
} }
#else #else
for (size_t i = 0; i < NUM_ALL_CHANNELS_IN; i++) x = NULL;
x[i] = NULL;
# endif
#endif #endif
#if NUM_CHANNELS_OUT > 0 #if NUM_NON_OPT_CHANNELS_OUT > 0
float * y_buf = malloc(NUM_CHANNELS_OUT * bufsize * sizeof(float)); y_buf = malloc(NUM_NON_OPT_CHANNELS_OUT * bufsize * sizeof(float));
if (y_buf == NULL) { if (y_buf == NULL) {
fprintf(stderr, "Out of memory\n"); fprintf(stderr, "Out of memory\n");
goto err_y_buf; goto err_y_buf;
} }
#endif #endif
#if NUM_ALL_CHANNELS_OUT > 0 #if NUM_ALL_CHANNELS_OUT > 0
# if AUDIO_BUS_OUT >= 0 for (size_t i = 0, j = 0, k = 0; i < NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT; i++) {
size_t iy = 0; if (!audio_bus_data[i].out)
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; continue;
if (audio_bus_data[j].index == AUDIO_BUS_OUT) for (int l = 0; l < audio_bus_data[i].channels; l++, j++) {
for (char k = 0; k < audio_bus_data[j].channels; k++, iy++, iyb++) if (AUDIO_BUS_OUT == i) {
y[iy] = y_buf + bufsize * iyb; y[j] = y_buf + bufsize * k;
# if NUM_NON_OPT_CHANNELS_OUT > NUM_CHANNELS_OUT y_out[l] = y[j];
else if (!audio_bus_data[j].optional) k++;
for (char k = 0; k < audio_bus_data[j].channels; k++, iy++) } else if (!audio_bus_data[i].optional) {
y[iy] = zero; y[j] = y_buf + bufsize * k;
# endif k++;
else } else
for (char k = 0; k < audio_bus_data[j].channels; k++, iy++) y[j] = NULL;
y[iy] = NULL; }
} }
#else #else
for (size_t i = 0; i < NUM_ALL_CHANNELS_OUT; i++) y = NULL;
y[i] = NULL;
# endif
#endif #endif
#if NUM_MIDI_INPUTS > 0 #if NUM_MIDI_INPUTS > 0
@ -453,24 +464,20 @@ int main(int argc, char * argv[]) {
goto err_outfile; goto err_outfile;
#endif #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; 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); size_t len = (size_t)(tw_in.h.SampleRate * length + 0.5f);
#endif
while (i < len) { while (i < len) {
size_t left = len - i; size_t left = len - i;
size_t n = left > bufsize ? bufsize : left; 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 #endif
#if NUM_MIDI_INPUTS > 0 #if NUM_MIDI_INPUTS > 0
while (1) { while (1) {
if (midi_next > 0.0) 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); midi_next -= 1e6 * ((double)n / (double)tw_in.h.SampleRate);
#endif #endif
plugin_process(&instance, (const float **)x, y, n); plugin_process(&instance, x, y, n);
#if PARAMETERS_N > 0 #if PARAMETERS_N > 0
for (size_t j = 0; j < PARAMETERS_N; j++) { for (size_t j = 0; j < PARAMETERS_N; j++) {
@ -520,12 +527,10 @@ int main(int argc, char * argv[]) {
#endif #endif
#if NUM_CHANNELS_OUT > 0 #if NUM_CHANNELS_OUT > 0
tinywav_write_f(&tw_out, y, n); tinywav_write_f(&tw_out, y_out, n);
#endif #endif
#if NUM_CHANNELS_IN == 0
i += n; i += n;
#endif
} }
exit_code = EXIT_SUCCESS; exit_code = EXIT_SUCCESS;
@ -542,12 +547,16 @@ err_midi_read:
#endif #endif
#if NUM_CHANNELS_OUT > 0 #if NUM_CHANNELS_OUT > 0
free(y_buf); free(y_buf);
#endif
err_y_buf: err_y_buf:
#endif
#if NUM_CHANNELS_IN > 0 #if NUM_CHANNELS_IN > 0
free(x_buf); free(x_buf);
#endif
err_x_buf: err_x_buf:
#endif
#if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
free(zero);
err_zero:
#endif
if (mem != NULL) if (mem != NULL)
free(mem); free(mem);
err_mem_alloc: 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_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 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_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)}} #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_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) ? (it.product.buses.filter(x => x.type == "audio" && x.direction == "output" && !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 && !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_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_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_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 <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <string.h>
#include "data.h" #include "data.h"
#include "plugin.h" #include "plugin.h"
#include <string.h>
#include <math.h> #include <math.h>
#include "daisy_seed.h" #include "daisy_seed.h"
@ -35,14 +35,14 @@ const float * x[NUM_ALL_CHANNELS_IN];
#else #else
const float ** x; const float ** x;
#endif #endif
#if NUM_CHANNELS_IN > 0
float * y_out[NUM_CHANNELS_OUT];
#endif
#if NUM_NON_OPT_CHANNELS_OUT > 0 #if NUM_NON_OPT_CHANNELS_OUT > 0
float y_buf[NUM_NON_OPT_CHANNELS_OUT * BLOCK_SIZE]; float y_buf[NUM_NON_OPT_CHANNELS_OUT * BLOCK_SIZE];
#endif #endif
#if NUM_CHANNELS_OUT > 0
float * y_out[NUM_CHANNELS_OUT];
#endif
#if NUM_ALL_CHANNELS_OUT > 0 #if NUM_ALL_CHANNELS_OUT > 0
float * y[NUM_ALL_CHANNELS_IN]; float * y[NUM_ALL_CHANNELS_OUT];
#else #else
float ** y; float ** y;
#endif #endif
@ -169,20 +169,21 @@ int main() {
plugin_reset(&instance); plugin_reset(&instance);
#if NUM_ALL_CHANNELS_IN > 0 #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) if (audio_bus_data[i].out)
continue; continue;
for (int l = 0; l < audio_bus_data[i].channels; l++) { for (int l = 0; l < audio_bus_data[i].channels; l++, j++) {
if (audio_bus_data[i].optional) if (AUDIO_BUS_IN == i) {
x[j] = NULL;
else {
float * b = x_buf + BLOCK_SIZE * k; float * b = x_buf + BLOCK_SIZE * k;
x[j] = b; x[j] = b;
if (AUDIO_BUS_IN == i)
x_in[l] = b; x_in[l] = b;
k++; k++;
} } else
j++; #if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
x[j] = audio_bus_data[i].optional ? NULL : zero;
#else
x[j] = NULL;
#endif
} }
} }
#else #else
@ -190,14 +191,19 @@ int main() {
#endif #endif
#if NUM_ALL_CHANNELS_OUT > 0 #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) if (!audio_bus_data[i].out)
continue; continue;
for (int k = 0; k < audio_bus_data[i].channels; k++) { for (int l = 0; l < audio_bus_data[i].channels; l++, j++) {
y[j] = y_buf + BLOCK_SIZE * j; if (AUDIO_BUS_OUT == i) {
if (AUDIO_BUS_OUT == i) y[j] = y_buf + BLOCK_SIZE * k;
y_out[k] = y[j]; y_out[l] = y[j];
j++; k++;
} else if (!audio_bus_data[i].optional) {
y[j] = y_buf + BLOCK_SIZE * k;
k++;
} else
y[j] = NULL;
} }
} }
#else #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_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 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_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)}} #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_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) ? (it.product.buses.filter(x => x.type == "audio" && x.direction == "output" && !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 && !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_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_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_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")}} #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 { static struct {
size_t index;
char out; char out;
char optional; char optional;
char channels; char channels;
@ -28,7 +24,6 @@ static struct {
{{~it.product.buses :b:i}} {{~it.product.buses :b:i}}
{{?b.type == "audio"}} {{?b.type == "audio"}}
{ {
/* .index = */ {{=i}},
/* .out = */ {{=b.direction == "output" ? 1 : 0}}, /* .out = */ {{=b.direction == "output" ? 1 : 0}},
/* .optional = */ {{=b.optional ? 1 : 0}}, /* .optional = */ {{=b.optional ? 1 : 0}},
/* .channels = */ {{=b.channels == "mono" ? 1 : 2}} /* .channels = */ {{=b.channels == "mono" ? 1 : 2}}

View File

@ -2,6 +2,9 @@
* Copyright (C) 2023, 2024 Orastron Srl unipersonale * Copyright (C) 2023, 2024 Orastron Srl unipersonale
*/ */
#include <stdlib.h>
#include <stdint.h>
#include "data.h" #include "data.h"
#include "plugin.h" #include "plugin.h"
#if PARAMETERS_N > 0 #if PARAMETERS_N > 0
@ -16,27 +19,29 @@
#include "miniaudio.h" #include "miniaudio.h"
#define BLOCK_SIZE 32 #define BLOCK_SIZE 32
#define NUM_BUFS (NUM_CHANNELS_IN > NUM_CHANNELS_OUT ? NUM_CHANNELS_IN : NUM_CHANNELS_OUT)
static ma_device device; static ma_device device;
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) #if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
float zero[BLOCK_SIZE]; float zero[BLOCK_SIZE];
#endif #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];
float * x_in[NUM_CHANNELS_IN];
#endif #endif
#if NUM_ALL_CHANNELS_IN > 0 #if NUM_ALL_CHANNELS_IN > 0
const float * x[NUM_ALL_CHANNELS_IN]; const float * x[NUM_ALL_CHANNELS_IN];
#else #else
const float ** x; const float ** x;
#endif #endif
#if NUM_NON_OPT_CHANNELS_OUT > 0
float y_buf[NUM_NON_OPT_CHANNELS_OUT * BLOCK_SIZE];
#endif
#if NUM_CHANNELS_OUT > 0 #if NUM_CHANNELS_OUT > 0
float y_buf[NUM_CHANNELS_OUT * BLOCK_SIZE]; float * y_out[NUM_CHANNELS_OUT];
#endif #endif
#if NUM_ALL_CHANNELS_OUT > 0 #if NUM_ALL_CHANNELS_OUT > 0
float *y[NUM_ALL_CHANNELS_IN]; float * y[NUM_ALL_CHANNELS_OUT];
#else #else
float ** y; float ** y;
#endif #endif
@ -89,31 +94,26 @@ static void data_callback(ma_device* pDevice, void* pOutput, const void* pInput,
} }
#endif #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 #if NUM_CHANNELS_IN > 0
const float * in_buf = reinterpret_cast<const float *>(pInput);
size_t ix = 0; size_t ix = 0;
#else
(void)pInput;
#endif #endif
#if NUM_CHANNELS_OUT > 0 #if NUM_CHANNELS_OUT > 0
float * out_buf = reinterpret_cast<float *>(pOutput);
size_t iy = 0; size_t iy = 0;
#else
(void)pOutput;
#endif #endif
ma_uint32 i = 0;
while (i < frameCount) { while (i < frameCount) {
ma_uint32 n = std::min(frameCount - i, static_cast<ma_uint32>(BLOCK_SIZE)); ma_uint32 n = std::min(frameCount - i, static_cast<ma_uint32>(BLOCK_SIZE));
#if NUM_CHANNELS_IN > 0 #if NUM_CHANNELS_IN > 0
for (ma_uint32 j = 0; j < n; j++) for (ma_uint32 j = 0; j < n; j++)
for (size_t k = 0; k < NUM_CHANNELS_IN; k++, ix++) for (size_t k = 0; k < NUM_CHANNELS_IN; k++, ix++)
x_buf[BLOCK_SIZE * k + j] = in_buf[ix]; x_in[k][j] = in_buf[ix];
#endif
#if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
memset(zero, 0, BLOCK_SIZE * sizeof(float));
#endif #endif
plugin_process(&instance, x, y, n); plugin_process(&instance, x, y, n);
@ -121,11 +121,12 @@ static void data_callback(ma_device* pDevice, void* pOutput, const void* pInput,
#if NUM_CHANNELS_OUT > 0 #if NUM_CHANNELS_OUT > 0
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++)
out_buf[iy] = y_buf[BLOCK_SIZE * k + j]; out_buf[iy] = y_out[k][j];
#elif NUM_CHANNELS_IN == 0 #elif NUM_CHANNELS_IN == 0
for (ma_uint32 j = 0; j < n; j++) for (ma_uint32 j = 0; j < n; j++)
out_buf[j] = 0.f; out_buf[j] = 0.f;
#endif #endif
i += n; i += n;
} }
@ -260,59 +261,51 @@ char audioStart() {
plugin_reset(&instance); plugin_reset(&instance);
#if NUM_ALL_CHANNELS_IN > 0 #if NUM_ALL_CHANNELS_IN > 0
# if AUDIO_BUS_IN >= 0 for (size_t i = 0, j = 0, k = 0; i < NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT; i++) {
size_t ix = 0; if (audio_bus_data[i].out)
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; continue;
if (audio_bus_data[j].index == AUDIO_BUS_IN) for (int l = 0; l < audio_bus_data[i].channels; l++, j++) {
for (char k = 0; k < audio_bus_data[j].channels; k++, ix++, ixb++) if (AUDIO_BUS_IN == i) {
x[ix] = x_buf + BLOCK_SIZE * ixb; 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 #if NUM_NON_OPT_CHANNELS_IN > NUM_CHANNELS_IN
else if (!audio_bus_data[j].optional) x[j] = audio_bus_data[i].optional ? NULL : zero;
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 #else
for (size_t i = 0; i < NUM_ALL_CHANNELS_IN; i++) x[j] = NULL;
x[i] = NULL;
#endif #endif
}
}
#else #else
x = NULL; x = NULL;
#endif #endif
#if NUM_ALL_CHANNELS_OUT > 0 #if NUM_ALL_CHANNELS_OUT > 0
# if AUDIO_BUS_OUT >= 0 for (size_t i = 0, j = 0, k = 0; i < NUM_AUDIO_BUSES_IN + NUM_AUDIO_BUSES_OUT; i++) {
size_t iy = 0; if (!audio_bus_data[i].out)
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; continue;
if (audio_bus_data[j].index == AUDIO_BUS_OUT) for (int l = 0; l < audio_bus_data[i].channels; l++, j++) {
for (char k = 0; k < audio_bus_data[j].channels; k++, iy++, iyb++) if (AUDIO_BUS_OUT == i) {
y[iy] = y_buf + BLOCK_SIZE * iyb; y[j] = y_buf + BLOCK_SIZE * k;
# if NUM_NON_OPT_CHANNELS_OUT > NUM_CHANNELS_OUT y_out[l] = y[j];
else if (!audio_bus_data[j].optional) k++;
for (char k = 0; k < audio_bus_data[j].channels; k++, iy++) } else if (!audio_bus_data[i].optional) {
y[iy] = zero; y[j] = y_buf + BLOCK_SIZE * k;
# endif k++;
else } else
for (char k = 0; k < audio_bus_data[j].channels; k++, iy++) y[j] = NULL;
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
#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 (ma_device_start(&device) != MA_SUCCESS) {
if (mem != NULL) if (mem != NULL)
free(mem); free(mem);