From 8b46fd1ff51b29cded517c9c2d166611e8c453fc Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 31 May 2012 06:03:45 +0000 Subject: Blip => Blop. I give up trying to give ports new names. git-svn-id: http://svn.drobilla.net/lad/trunk/plugins/blop.lv2@4484 a436a847-0d15-0410-975c-d299462d15a1 --- src/triangle.c | 231 ++++++++++++++++++--------------------------------------- 1 file changed, 71 insertions(+), 160 deletions(-) (limited to 'src/triangle.c') diff --git a/src/triangle.c b/src/triangle.c index 0a06f6c..8cb32a6 100644 --- a/src/triangle.c +++ b/src/triangle.c @@ -18,7 +18,9 @@ */ #include +#include "lv2/lv2plug.in/ns/ext/morph/morph.h" #include "lv2/lv2plug.in/ns/lv2core/lv2.h" +#include "uris.h" #include "wavedata.h" #define TRIANGLE_FREQUENCY 0 @@ -32,7 +34,10 @@ typedef struct { float phase; float min_slope; float max_slope; + uint32_t frequency_is_cv; + uint32_t slope_is_cv; Wavedata wdat; + URIs uris; } Triangle; static void @@ -55,6 +60,33 @@ connect_port(LV2_Handle instance, } } +static LV2_Morph_Status +morph_port(LV2_Handle instance, + uint32_t port, + LV2_URID type, + const LV2_Morph_Property*const* properties) +{ + Triangle* plugin = (Triangle*)instance; + + if (type != plugin->uris.lv2_ControlPort && + type != plugin->uris.lv2_CVPort) { + return LV2_MORPH_ERR_BAD_TYPE; + } + + switch (port) { + case TRIANGLE_FREQUENCY: + plugin->frequency_is_cv = (type == plugin->uris.lv2_CVPort); + break; + case TRIANGLE_SLOPE: + plugin->slope_is_cv = (type == plugin->uris.lv2_CVPort); + break; + default: + return LV2_MORPH_ERR_BAD_PORT; + } + + return LV2_MORPH_SUCCESS; +} + static LV2_Handle instantiate(const LV2_Descriptor* descriptor, double sample_rate, @@ -72,6 +104,12 @@ instantiate(const LV2_Descriptor* descriptor, plugin->min_slope = 2.0f / plugin->wdat.sample_rate; plugin->max_slope = 1.0f - plugin->min_slope; + plugin->frequency_is_cv = 0; + plugin->slope_is_cv = 0; + + map_uris(&plugin->uris, features); + wavedata_get_table(&plugin->wdat, 440.0); + return (LV2_Handle)plugin; } @@ -93,141 +131,51 @@ activate(LV2_Handle instance) } static void -runTriangle_fasa_oa(LV2_Handle instance, - uint32_t sample_count) +run(LV2_Handle instance, + uint32_t sample_count) { Triangle* plugin = (Triangle*)instance; - /* Frequency (array of float of length sample_count) */ + /* Frequency (array of float of length 1 or sample_count) */ const float* frequency = plugin->frequency; - /* Slope (array of float of length sample_count) */ + /* Slope (array of float of length 1 or sample_count) */ const float* slope = plugin->slope; /* Output (pointer to float value) */ float* output = plugin->output; /* Instance data */ - Wavedata* wdat = &plugin->wdat; - float phase = plugin->phase; - float min_slope = plugin->min_slope; - float max_slope = plugin->max_slope; + Wavedata* wdat = &plugin->wdat; + float phase = plugin->phase; + const float min_slope = plugin->min_slope; + const float max_slope = plugin->max_slope; - float freq; - float slp; - float phase_shift; + float last_slope = slope[0]; + float slp = f_clip(last_slope, min_slope, max_slope); + float phase_shift = slp * wdat->sample_rate; + float scale = 1.0f / (8.0f * (slp - (slp * slp))); for (uint32_t s = 0; s < sample_count; ++s) { - freq = frequency[s]; - slp = f_clip(slope[s], min_slope, max_slope); - phase_shift = slp * wdat->sample_rate; - - /* Lookup which table to use from frequency */ - wavedata_get_table(wdat, freq); - - /* Get samples from parabola and phase shifted inverted parabola, - and scale to compensate */ - output[s] = (wavedata_get_sample(wdat, phase) - - wavedata_get_sample(wdat, phase + phase_shift)) - / (8.0f * (slp - (slp * slp))); - - /* Update phase, wrapping if necessary */ - phase += wdat->frequency; - if (phase < 0.0f) { - phase += wdat->sample_rate; - } else if (phase > wdat->sample_rate) { - phase -= wdat->sample_rate; + const float freq = frequency[s * plugin->frequency_is_cv]; + if (freq != wdat->frequency) { + /* Frequency changed, look up table to play */ + wavedata_get_table(wdat, freq); } - } - plugin->phase = phase; -} - -static void -runTriangle_fasc_oa(LV2_Handle instance, - uint32_t sample_count) -{ - Triangle* plugin = (Triangle*)instance; - - /* Frequency (array of float of length sample_count) */ - const float* frequency = plugin->frequency; - - /* Slope (float value) */ - float slope = *(plugin->slope); - - /* Output (pointer to float value) */ - float* output = plugin->output; - /* Instance data */ - Wavedata* wdat = &plugin->wdat; - float phase = plugin->phase; - float min_slope = plugin->min_slope; - float max_slope = plugin->max_slope; - - float freq; - float phase_shift; - float scale; - - slope = f_clip(slope, min_slope, max_slope); - scale = 1.0f / (8.0f * (slope - (slope * slope))); - phase_shift = slope * wdat->sample_rate; - - for (uint32_t s = 0; s < sample_count; ++s) { - freq = frequency[s]; - - /* Lookup which table to use from frequency */ - wavedata_get_table(wdat, freq); - - /* Get samples from parabola and phase shifted inverted parabola, - and scale to compensate */ - output[s] = (wavedata_get_sample(wdat, phase) - - wavedata_get_sample(wdat, phase + phase_shift)) * scale; - - /* Update phase, wrapping if necessary */ - phase += wdat->frequency; - if (phase < 0.0f) { - phase += wdat->sample_rate; - } else if (phase > wdat->sample_rate) { - phase -= wdat->sample_rate; + const float this_slope = slope[s * plugin->slope_is_cv]; + if (this_slope != last_slope) { + /* Slope changed, recalculate */ + last_slope = this_slope; + slp = f_clip(this_slope, min_slope, max_slope); + phase_shift = slp * wdat->sample_rate; + scale = 1.0f / (8.0f * (slp - (slp * slp))); } - } - plugin->phase = phase; -} - -static void -runTriangle_fcsa_oa(LV2_Handle instance, - uint32_t sample_count) -{ - Triangle* plugin = (Triangle*)instance; - - /* Frequency (float value) */ - const float frequency = *(plugin->frequency); - - /* Slope (array of float of length sample_count) */ - const float* slope = plugin->slope; - - /* Output (pointer to float value) */ - float* output = plugin->output; - - /* Instance data */ - Wavedata* wdat = &plugin->wdat; - float phase = plugin->phase; - float min_slope = plugin->min_slope; - float max_slope = plugin->max_slope; - - float slp; - float phase_shift; - - wavedata_get_table(wdat, frequency); - - for (uint32_t s = 0; s < sample_count; ++s) { - slp = f_clip(slope[s], min_slope, max_slope); - phase_shift = slp * wdat->sample_rate; /* Get samples from parabola and phase shifted inverted parabola, and scale to compensate */ output[s] = (wavedata_get_sample(wdat, phase) - - wavedata_get_sample(wdat, phase + phase_shift)) - / (8.0f * (slp - (slp * slp))); + - wavedata_get_sample(wdat, phase + phase_shift)) * scale; /* Update phase, wrapping if necessary */ phase += wdat->frequency; @@ -240,62 +188,25 @@ runTriangle_fcsa_oa(LV2_Handle instance, plugin->phase = phase; } -static void -runTriangle_fcsc_oa(LV2_Handle instance, - uint32_t sample_count) +static const void* +extension_data(const char* uri) { - Triangle* plugin = (Triangle*)instance; - - /* Frequency (float value) */ - const float frequency = *(plugin->frequency); - - /* Slope (float value) */ - float slope = *(plugin->slope); - - /* Output (pointer to float value) */ - float* output = plugin->output; - - /* Instance data */ - Wavedata* wdat = &plugin->wdat; - float phase = plugin->phase; - float min_slope = plugin->min_slope; - float max_slope = plugin->max_slope; - - float scale; - float phase_shift; - - slope = f_clip(slope, min_slope, max_slope); - scale = 1.0f / (8.0f * (slope - (slope * slope))); - phase_shift = slope * wdat->sample_rate; - - wavedata_get_table(wdat, frequency); - - for (uint32_t s = 0; s < sample_count; ++s) { - /* Get samples from parabola and phase shifted inverted parabola, - and scale to compensate */ - output[s] = (wavedata_get_sample(wdat, phase) - - wavedata_get_sample(wdat, phase + phase_shift)) * scale; - - /* Update phase, wrapping if necessary */ - phase += wdat->frequency; - if (phase < 0.0f) { - phase += wdat->sample_rate; - } else if (phase > wdat->sample_rate) { - phase -= wdat->sample_rate; - } + static const LV2_Morph_Interface morph = { morph_port, NULL }; + if (!strcmp(uri, LV2_MORPH__interface)) { + return &morph; } - plugin->phase = phase; + return NULL; } static const LV2_Descriptor descriptor = { - "http://drobilla.net/plugins/blip/triangle", + "http://drobilla.net/plugins/blop/triangle", instantiate, connect_port, activate, - runTriangle_fcsc_oa, + run, NULL, cleanup, - NULL, + extension_data, }; LV2_SYMBOL_EXPORT const LV2_Descriptor* -- cgit v1.2.1