diff --git a/templates/lv2/src/lv2.c b/templates/lv2/src/lv2.c index 19086b6..89b8088 100644 --- a/templates/lv2/src/lv2.c +++ b/templates/lv2/src/lv2.c @@ -23,6 +23,7 @@ typedef struct { #if DATA_PRODUCT_CONTROL_INPUTS_N > 0 float params[DATA_PRODUCT_CONTROL_INPUTS_N]; #endif + void * mem; } plugin_instance; static LV2_Handle instantiate(const struct LV2_Descriptor * descriptor, double sample_rate, const char * bundle_path, const LV2_Feature * const * features) { @@ -31,6 +32,16 @@ static LV2_Handle instantiate(const struct LV2_Descriptor * descriptor, double s return NULL; plugin_init(&instance->p); plugin_set_sample_rate(&instance->p, sample_rate); + size_t req = plugin_mem_req(&instance->p); + if (req != 0) { + instance->mem = malloc(req); + if (instance->mem == NULL) { + plugin_fini(&instance->p); + return NULL; + } + plugin_mem_set(&instance->p, instance->mem); + } else + instance->mem = NULL; #if DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N > 0 for (uint32_t i = 0; i < DATA_PRODUCT_AUDIO_INPUT_CHANNELS_N; i++) instance->x[i] = NULL; @@ -142,6 +153,8 @@ static void run(LV2_Handle instance, uint32_t sample_count) { static void cleanup(LV2_Handle instance) { plugin_instance * i = (plugin_instance *)instance; plugin_fini(&i->p); + if (i->mem) + free(i->mem); free(instance); } diff --git a/test/plugin.h b/test/plugin.h index c2b953d..7dd07dc 100644 --- a/test/plugin.h +++ b/test/plugin.h @@ -1,8 +1,16 @@ +#include #include typedef struct plugin { float gain; char bypass; + size_t delay; + + float sample_rate; + size_t delay_line_length; + + float * delay_line; + size_t delay_line_cur; } plugin; static void plugin_init(plugin *instance) { @@ -14,9 +22,21 @@ static void plugin_fini(plugin *instance) { } static void plugin_set_sample_rate(plugin *instance, float sample_rate) { + instance->sample_rate = sample_rate; + instance->delay_line_length = ceilf(sample_rate) + 1; +} + +static size_t plugin_mem_req(plugin *instance) { + return instance->delay_line_length * sizeof(float); +} + +static void plugin_mem_set(plugin *instance, void *mem) { + instance->delay_line = mem; } static void plugin_reset(plugin *instance) { + memset(instance->delay_line, 0, instance->delay_line_length * sizeof(float)); + instance->delay_line_cur = 0; } static void plugin_set_parameter(plugin *instance, size_t index, float value) { @@ -25,6 +45,9 @@ static void plugin_set_parameter(plugin *instance, size_t index, float value) { instance->gain = value; break; case 1: + instance->delay = roundf(instance->sample_rate * 0.001f * value); + break; + case 2: instance->bypass = value >= 0.5f; break; } @@ -35,8 +58,18 @@ static float plugin_get_parameter(plugin *instance, size_t index) { return 0.f; } -static void plugin_process(plugin *instance, const float **inputs, float **outputs, size_t n_samples) { - const float g = instance->bypass ? 1.f : powf(10.f, 0.05f * instance->gain); - for (size_t i = 0; i < n_samples; i++) - outputs[0][i] = g * inputs[0][i]; +static size_t calc_index(size_t cur, size_t delay, size_t len) { + return (cur < delay ? cur + len : cur) - delay; +} + +static void plugin_process(plugin *instance, const float **inputs, float **outputs, size_t n_samples) { + const float g = powf(10.f, 0.05f * instance->gain); + for (size_t i = 0; i < n_samples; i++) { + instance->delay_line[instance->delay_line_cur] = inputs[0][i]; + const float y = g * instance->delay_line[calc_index(instance->delay_line_cur, instance->delay, instance->delay_line_length)]; + instance->delay_line_cur++; + if (instance->delay_line_cur == instance->delay_line_length) + instance->delay_line_cur = 0; + outputs[0][i] = instance->bypass ? inputs[0][i] : y; + } } diff --git a/test/product.json b/test/product.json index e562204..1cfc4fc 100644 --- a/test/product.json +++ b/test/product.json @@ -48,6 +48,22 @@ "unit": "db", "map": "linear" }, + { + "name": "Delay", + "shortName": "Delay", + "direction": "input", + "isBypass": false, + "isLatency": false, + "defaultValue": 0.0, + "minimum": 0.0, + "maximum": 1000.0, + "toggled": false, + "optional": false, + "integer": false, + "list": false, + "unit": "ms", + "map": "linear" + }, { "name": "Bypass", "shortName": "Bypass",