diff --git a/TODO b/TODO index 17b8cff..226c9f1 100644 --- a/TODO +++ b/TODO @@ -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)? diff --git a/templates/android/src/data.h b/templates/android/src/data.h index 22837dd..9e8d5f8 100644 --- a/templates/android/src/data.h +++ b/templates/android/src/data.h @@ -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}} diff --git a/templates/android/src/jni.cpp b/templates/android/src/jni.cpp index 2679eb0..b490ba5 100644 --- a/templates/android/src/jni.cpp +++ b/templates/android/src/jni.cpp @@ -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(pInput); - float * out_buf = reinterpret_cast(pOutput); - ma_uint32 i = 0; #if NUM_CHANNELS_IN > 0 + const float * in_buf = reinterpret_cast(pInput); size_t ix = 0; +#else + (void)pInput; #endif #if NUM_CHANNELS_OUT > 0 + float * out_buf = reinterpret_cast(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(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); diff --git a/templates/cmd/src/data.h b/templates/cmd/src/data.h index f4ed680..57ba021 100644 --- a/templates/cmd/src/data.h +++ b/templates/cmd/src/data.h @@ -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}} diff --git a/templates/cmd/src/main.c b/templates/cmd/src/main.c index af958a2..3c36c20 100644 --- a/templates/cmd/src/main.c +++ b/templates/cmd/src/main.c @@ -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: diff --git a/templates/daisy-seed/src/data.h b/templates/daisy-seed/src/data.h index 77d78be..cfb47d3 100644 --- a/templates/daisy-seed/src/data.h +++ b/templates/daisy-seed/src/data.h @@ -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)}} diff --git a/templates/daisy-seed/src/main.cpp b/templates/daisy-seed/src/main.cpp index 5f5effb..d5c2bf5 100644 --- a/templates/daisy-seed/src/main.cpp +++ b/templates/daisy-seed/src/main.cpp @@ -1,10 +1,10 @@ #include #include -#include #include "data.h" #include "plugin.h" +#include #include #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 diff --git a/templates/ios/src/data.h b/templates/ios/src/data.h index f5fcdc6..bcb149e 100644 --- a/templates/ios/src/data.h +++ b/templates/ios/src/data.h @@ -1,14 +1,11 @@ -#include -#include - #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}} diff --git a/templates/ios/src/native.mm b/templates/ios/src/native.mm index 94c859b..55ea1cf 100644 --- a/templates/ios/src/native.mm +++ b/templates/ios/src/native.mm @@ -2,6 +2,9 @@ * Copyright (C) 2023, 2024 Orastron Srl unipersonale */ +#include +#include + #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(pInput); -#endif - float * out_buf = reinterpret_cast(pOutput); - ma_uint32 i = 0; #if NUM_CHANNELS_IN > 0 + const float * in_buf = reinterpret_cast(pInput); size_t ix = 0; +#else + (void)pInput; #endif #if NUM_CHANNELS_OUT > 0 + float * out_buf = reinterpret_cast(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(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); diff --git a/templates/lv2/src/data.h b/templates/lv2/src/data.h index ee7ced4..bbf03fc 100644 --- a/templates/lv2/src/data.h +++ b/templates/lv2/src/data.h @@ -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)}}