diff --git a/config.mk b/config.mk index a5982d9..cca65a9 100644 --- a/config.mk +++ b/config.mk @@ -2,7 +2,7 @@ # Configuration for Makefile # -PROJECT := dummy_delfx +PROJECT := veryshort PROJECT_TYPE := delfx ############################################################################## diff --git a/header.c b/header.c index 232e36e..d996306 100644 --- a/header.c +++ b/header.c @@ -50,7 +50,7 @@ const __unit_header unit_header_t unit_header = { .unit_id = 0x02020000, // Product number(02),Unit type(02=Delay),reserved .version = 0x00010000U, .name = "Very Short", - .num_params = 2, + .num_params = 3, .params = { // Format: min, max, center, default, type, frac. bits, frac. mode, , name @@ -61,7 +61,9 @@ const __unit_header unit_header_t unit_header = { // B knob {0, 1023, 0, 256, k_unit_param_type_none, 1, 0, 0, {"DPTH"}}, - {0, 0, 0, 0, k_unit_param_type_none, 0, 0, 0, {""}}, + // DELAY switch + B knob + {-100, 100, 0, 0, k_unit_param_type_drywet, 0, 0, 0, {"MIX"}}, + {0, 0, 0, 0, k_unit_param_type_none, 0, 0, 0, {""}}, {0, 0, 0, 0, k_unit_param_type_none, 0, 0, 0, {""}}, {0, 0, 0, 0, k_unit_param_type_none, 0, 0, 0, {""}}, diff --git a/veryshort.cc b/veryshort.cc index dfe058e..814f6f4 100644 --- a/veryshort.cc +++ b/veryshort.cc @@ -5,9 +5,12 @@ * */ -#include "userdelfx.h" -#include "delayline.hpp" -#include "float_math.h" +//#include "userdelfx.h" +#include "unit_delfx.h" +#include "dsp/delayline.hpp" +#include "utils/float_math.h" +#include "utils/buffer_ops.h" // for buf_clr_f32() +#include "utils/int_math.h" // for clipminmaxi32() #define BUF_LEN 2401 #define MAX_DELAY 2400 @@ -15,30 +18,96 @@ #define MAX_DEPTH 0.98f static dsp::DelayLine s_delay_r; -static __sdram float s_delay_ram_r[BUF_LEN]; +static float *s_delay_ram_r; static dsp::DelayLine s_delay_l; -static __sdram float s_delay_ram_l[BUF_LEN]; +static float *s_delay_ram_l; // depth between -MAX_DEPTH and MAX_DEPTH static float s_depth; // time between MIN_DELAY and MAX_DELAY static float s_time; static float s_len_z; +static float s_mix = 0.f; -void DELFX_INIT(uint32_t platform, uint32_t api) -{ +unit_runtime_desc_t s_desc; +int32_t p_[11]; + +enum { + TIME = 0U, + DEPTH, + MIX, + NUM_PARAMS +}; + +inline float *sdram_alloc_f32(size_t bufsize) { + float *m = (float *)s_desc.hooks.sdram_alloc(bufsize * sizeof(float)); + if (m) { + buf_clr_f32(m, bufsize); + } + return m; +} + +//void DELFX_INIT(uint32_t platform, uint32_t api) +//{ +__unit_callback int8_t unit_init(const unit_runtime_desc_t * desc) { + if (!desc) + return k_unit_err_undef; + + s_desc = *desc; + + if (desc->target != unit_header.target) + return k_unit_err_target; + + if (!UNIT_API_IS_COMPAT(desc->api)) + return k_unit_err_api_version; + + if (desc->samplerate != 48000) + return k_unit_err_samplerate; + + if (desc->input_channels != 2 || desc->output_channels != 2) + return k_unit_err_geometry; + + // If SDRAM buffers are required they must be allocated here + if (!desc->hooks.sdram_alloc) + return k_unit_err_memory; + +/* + float *m = (float *)desc->hooks.sdram_alloc(BUF_LEN * sizeof(float)); + if (!m) + return k_unit_err_memory; + + buf_clr_f32(m, BUF_LEN); + +*/ + s_delay_ram_r = sdram_alloc_f32(BUF_LEN); s_delay_r.setMemory(s_delay_ram_r, BUF_LEN); +/* + m = (float *)desc->hooks.sdram_alloc(BUF_LEN * sizeof(float)); + if (!m) + return k_unit_err_memory; + + buf_clr_f32(m, BUF_LEN); + +*/ + s_delay_ram_l = sdram_alloc_f32(BUF_LEN); s_delay_l.setMemory(s_delay_ram_l, BUF_LEN); + + s_len_z = 1.f; s_depth = 0.f; s_time = 0; + + return k_unit_err_none; } -void DELFX_PROCESS(float *main_xn, - uint32_t frames) +//void DELFX_PROCESS(float *main_xn, +// uint32_t frames) +__unit_callback void unit_render(const float * in, float * out, uint32_t frames) { - float * __restrict my = main_xn; +// float * __restrict my = main_xn; + const float * __restrict in_p = in; + float * __restrict my = out; const float * my_e = my + 2 * frames; const float len = s_time; @@ -48,33 +117,70 @@ void DELFX_PROCESS(float *main_xn, float dry; for (; my != my_e; ) { len_z = linintf(0.001f, len_z, len); - dry = *my; + dry = *in_p++; r = s_depth * s_delay_l.readFrac(len_z); s_delay_l.write(dry + r); - *(my++) = dry + r; + *(my++) = (s_mix < 0 ? dry : dry * (1 - s_mix)) + \ + (s_mix > 0 ? r : r * (1 + s_mix)); - dry = *my; + dry = *in_p++; r = s_depth * s_delay_r.readFrac(len_z); s_delay_r.write(dry + r); - *(my++) = dry + r; +// *(my++) = dry + r; + *(my++) = (s_mix < 0 ? dry : dry * (1 - s_mix)) + \ + (s_mix > 0 ? r : r * (1 + s_mix)); } s_len_z = len_z; } -void DELFX_PARAM(uint8_t index, int32_t value) -{ - const float valf = q31_to_f32(value); - switch (index) { - case k_user_delfx_param_time: +// void DELFX_PARAM(uint8_t index, int32_t value) +//{ +__unit_callback void unit_set_param_value(uint8_t id, int32_t value) { +// const float valf = q31_to_f32(value); + float valf; + switch (id) { + case TIME: + value = clipminmaxi32(0, value, 1023); + valf = param_10bit_to_f32(value); s_time = MIN_DELAY + valf * valf * (MAX_DELAY - MIN_DELAY); break; - case k_user_delfx_param_depth: + case DEPTH: + value = clipminmaxi32(0, value, 1023); + valf = param_10bit_to_f32(value); s_depth = valf * MAX_DEPTH * 2 - MAX_DEPTH; break; - case k_user_delfx_param_shift_depth: + case MIX: + value = clipminmaxi32(-100, value, 100); + s_mix = value / 100.f; break; default: break; } } + +__unit_callback void unit_teardown() { +} + +__unit_callback void unit_reset() { +} + +__unit_callback void unit_resume() { +} + +__unit_callback void unit_suspend() { +} + +__unit_callback int32_t unit_get_param_value(uint8_t id) { + return p_[id]; +} + +__unit_callback const char * unit_get_param_str_value(uint8_t id, int32_t value) { + return nullptr; +} + +__unit_callback void unit_set_tempo(uint32_t tempo) { +} + +__unit_callback void unit_tempo_4ppqn_tick(uint32_t counter) { +}