aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-05-31 06:23:57 +0000
committerDavid Robillard <d@drobilla.net>2012-05-31 06:23:57 +0000
commit7b20413c84b14d2c2bc1037bb08134dcdf152ddb (patch)
treec7c339d6c4d0d26b01e654163e7a8a203f62baf4
parent46caaf6b96f185a4a25d1d12fc85720a03220e97 (diff)
downloadblop.lv2-7b20413c84b14d2c2bc1037bb08134dcdf152ddb.tar.gz
blop.lv2-7b20413c84b14d2c2bc1037bb08134dcdf152ddb.tar.bz2
blop.lv2-7b20413c84b14d2c2bc1037bb08134dcdf152ddb.zip
Umm... commit pretty much all the work of the past few days. Again.
git-svn-id: http://svn.drobilla.net/lad/trunk/plugins/blop.lv2@4488 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/adsr.c11
-rw-r--r--src/adsr_gt.c14
-rw-r--r--src/amp.c77
-rw-r--r--src/branch.c2
-rw-r--r--src/dahdsr.c450
-rw-r--r--src/difference.c169
-rw-r--r--src/fmod.c164
-rw-r--r--src/include/common.h6
-rw-r--r--src/include/interpolate.h8
-rw-r--r--src/include/lp4pole_filter.h6
-rw-r--r--src/include/math_func.h2
-rw-r--r--src/include/wavedata.h14
-rw-r--r--src/include/wdatutil.h6
-rw-r--r--src/interpolator.c11
-rw-r--r--src/lp4pole.c97
-rw-r--r--src/product.c126
-rw-r--r--src/pulse.c208
-rw-r--r--src/quantiser.c66
-rw-r--r--src/random.c253
-rw-r--r--src/ratio.c150
-rw-r--r--src/sawtooth.c81
-rw-r--r--src/sequencer.c29
-rw-r--r--src/square.c79
-rw-r--r--src/sum.c121
-rw-r--r--src/sync_pulse.c118
-rw-r--r--src/sync_square.c111
-rw-r--r--src/tracker.c158
-rw-r--r--src/triangle.c234
-rw-r--r--src/wavedata.c4
-rw-r--r--src/wdatutil.c14
30 files changed, 1192 insertions, 1597 deletions
diff --git a/src/adsr.c b/src/adsr.c
index 227dca7..c50951d 100644
--- a/src/adsr.c
+++ b/src/adsr.c
@@ -98,6 +98,9 @@ instantiate(const LV2_Descriptor* descriptor,
const LV2_Feature* const* features)
{
Adsr* plugin = (Adsr*)malloc(sizeof(Adsr));
+ if (!plugin) {
+ return NULL;
+ }
plugin->srate = (float)sample_rate;
plugin->inv_srate = 1.0f / plugin->srate;
@@ -117,8 +120,8 @@ activate(LV2_Handle instance)
}
static void
-runAdsr(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
Adsr* plugin = (Adsr*)instance;
@@ -236,11 +239,11 @@ runAdsr(LV2_Handle instance,
}
static const LV2_Descriptor descriptor = {
- "http://drobilla.net/plugins/blip/adsr",
+ "http://drobilla.net/plugins/blop/adsr",
instantiate,
connect_port,
activate,
- runAdsr,
+ run,
NULL,
cleanup,
NULL,
diff --git a/src/adsr_gt.c b/src/adsr_gt.c
index 77bec65..de0b0e7 100644
--- a/src/adsr_gt.c
+++ b/src/adsr_gt.c
@@ -100,8 +100,10 @@ instantiate(const LV2_Descriptor* descriptor,
{
Adsr* plugin = (Adsr*)malloc(sizeof(Adsr));
- plugin->srate = (float)sample_rate;
- plugin->inv_srate = 1.0f / plugin->srate;
+ if (plugin) {
+ plugin->srate = (float)sample_rate;
+ plugin->inv_srate = 1.0f / plugin->srate;
+ }
return (LV2_Handle)plugin;
}
@@ -119,8 +121,8 @@ activate(LV2_Handle instance)
}
static void
-runAdsr(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
Adsr* plugin = (Adsr*)instance;
@@ -244,11 +246,11 @@ runAdsr(LV2_Handle instance,
}
static const LV2_Descriptor descriptor = {
- "http://drobilla.net/plugins/blip/adsr_gt",
+ "http://drobilla.net/plugins/blop/adsr_gt",
instantiate,
connect_port,
activate,
- runAdsr,
+ run,
NULL,
cleanup,
NULL,
diff --git a/src/amp.c b/src/amp.c
index edb9291..dac6bb0 100644
--- a/src/amp.c
+++ b/src/amp.c
@@ -18,8 +18,10 @@
*/
#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
#include "math_func.h"
+#include "uris.h"
#define AMP_GAIN 0
#define AMP_INPUT 1
@@ -29,6 +31,8 @@ typedef struct {
const float* gain;
const float* input;
float* output;
+ URIs uris;
+ uint32_t gain_is_cv;
} Amp;
static void
@@ -57,6 +61,28 @@ 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)
+{
+ Amp* plugin = (Amp*)instance;
+ switch (port) {
+ case AMP_GAIN:
+ if (type == plugin->uris.lv2_ControlPort) {
+ plugin->gain_is_cv = 0;
+ } else if (type == plugin->uris.lv2_CVPort) {
+ plugin->gain_is_cv = 1;
+ } else {
+ return LV2_MORPH_ERR_BAD_TYPE;
+ }
+ return LV2_MORPH_SUCCESS;
+ default:
+ return LV2_MORPH_ERR_BAD_PORT;
+ }
+}
+
static LV2_Handle
instantiate(const LV2_Descriptor* descriptor,
double sample_rate,
@@ -64,13 +90,19 @@ instantiate(const LV2_Descriptor* descriptor,
const LV2_Feature* const* features)
{
Amp* plugin = (Amp*)malloc(sizeof(Amp));
+ if (!plugin) {
+ return NULL;
+ }
+
+ plugin->gain_is_cv = 0;
+ map_uris(&plugin->uris, features);
return (LV2_Handle)plugin;
}
static void
-runAmp_gaia_oa(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
Amp* plugin = (Amp*)instance;
@@ -83,50 +115,33 @@ runAmp_gaia_oa(LV2_Handle instance,
/* Output */
float* output = plugin->output;
- float gn;
- float in;
- float scale;
-
for (uint32_t s = 0; s < sample_count; ++s) {
- gn = gain[s];
- in = input[s];
+ const float gn = gain[s * plugin->gain_is_cv];
+ const float scale = (float)EXPF(M_LN10 * gn * 0.05f);
- scale = (float)EXPF(M_LN10 * gn * 0.05f);
-
- output[s] = scale * in;
+ output[s] = scale * input[s];
}
}
-static void
-runAmp_gcia_oa(LV2_Handle instance,
- uint32_t sample_count)
+static const void*
+extension_data(const char* uri)
{
- Amp* plugin = (Amp*)instance;
-
- /* Gain (dB) */
- const float gain = *(plugin->gain);
-
- /* Input */
- const float* input = plugin->input;
-
- /* Output */
- float* output = plugin->output;
-
- const float scale = (float)EXPF(M_LN10 * gain * 0.05f);
- for (uint32_t s = 0; s < sample_count; s++) {
- output[s] = scale * input[s];
+ static const LV2_Morph_Interface morph = { morph_port, NULL };
+ if (!strcmp(uri, LV2_MORPH__interface)) {
+ return &morph;
}
+ return NULL;
}
static const LV2_Descriptor descriptor = {
- "http://drobilla.net/plugins/blip/amp",
+ "http://drobilla.net/plugins/blop/amp",
instantiate,
connect_port,
NULL,
- runAmp_gcia_oa,
+ run,
NULL,
cleanup,
- NULL,
+ extension_data,
};
LV2_SYMBOL_EXPORT const LV2_Descriptor*
diff --git a/src/branch.c b/src/branch.c
index 4625e5c..f4c92a0 100644
--- a/src/branch.c
+++ b/src/branch.c
@@ -113,7 +113,7 @@ runBranch_ic_ococ(LV2_Handle instance,
}
static const LV2_Descriptor descriptor = {
- "http://drobilla.net/plugins/blip/branch",
+ "http://drobilla.net/plugins/blop/branch",
instantiate,
connect_port,
NULL,
diff --git a/src/dahdsr.c b/src/dahdsr.c
index cfddb6b..97cd373 100644
--- a/src/dahdsr.c
+++ b/src/dahdsr.c
@@ -18,8 +18,10 @@
*/
#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
#include "common.h"
+#include "uris.h"
#define DAHDSR_GATE 0
#define DAHDSR_TRIGGER 1
@@ -57,8 +59,15 @@ typedef struct {
float last_trigger;
float from_level;
float level;
+ uint32_t delay_is_cv;
+ uint32_t attack_is_cv;
+ uint32_t hold_is_cv;
+ uint32_t decay_is_cv;
+ uint32_t sustain_is_cv;
+ uint32_t release_is_cv;
DAHDSRState state;
uint32_t samples;
+ URIs uris;
} Dahdsr;
static void
@@ -105,6 +114,45 @@ 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)
+{
+ Dahdsr* plugin = (Dahdsr*)instance;
+
+ if (type != plugin->uris.lv2_ControlPort &&
+ type != plugin->uris.lv2_CVPort) {
+ return LV2_MORPH_ERR_BAD_TYPE;
+ }
+
+ switch (port) {
+ case DAHDSR_DELAY:
+ plugin->delay_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ case DAHDSR_ATTACK:
+ plugin->attack_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ case DAHDSR_HOLD:
+ plugin->hold_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ case DAHDSR_DECAY:
+ plugin->decay_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ case DAHDSR_SUSTAIN:
+ plugin->sustain_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ case DAHDSR_RELEASE:
+ plugin->release_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,
@@ -112,10 +160,22 @@ instantiate(const LV2_Descriptor* descriptor,
const LV2_Feature* const* features)
{
Dahdsr* plugin = (Dahdsr*)malloc(sizeof(Dahdsr));
+ if (!plugin) {
+ return NULL;
+ }
plugin->srate = (float)sample_rate;
plugin->inv_srate = 1.0f / plugin->srate;
+ plugin->delay_is_cv = 0;
+ plugin->attack_is_cv = 0;
+ plugin->hold_is_cv = 0;
+ plugin->decay_is_cv = 0;
+ plugin->sustain_is_cv = 0;
+ plugin->release_is_cv = 0;
+
+ map_uris(&plugin->uris, features);
+
return (LV2_Handle)plugin;
}
@@ -133,8 +193,8 @@ activate(LV2_Handle instance)
}
static void
-runDahdsr_Audio(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
Dahdsr* plugin = (Dahdsr*)instance;
@@ -175,20 +235,26 @@ runDahdsr_Audio(LV2_Handle instance,
DAHDSRState state = plugin->state;
uint32_t samples = plugin->samples;
- float gat, trg, del, att, hld, dec, sus, rel;
float elapsed;
for (uint32_t s = 0; s < sample_count; ++s) {
+ const float dl = delay[s * plugin->delay_is_cv];
+ const float at = attack[s * plugin->attack_is_cv];
+ const float hl = hold[s * plugin->hold_is_cv];
+ const float dc = decay[s * plugin->decay_is_cv];
+ const float st = sustain[s * plugin->sustain_is_cv];
+ const float rl = release[s * plugin->release_is_cv];
+
/* Convert times into rates */
- del = delay[s] > 0.0f ? inv_srate / delay[s] : srate;
- att = attack[s] > 0.0f ? inv_srate / attack[s] : srate;
- hld = hold[s] > 0.0f ? inv_srate / hold[s] : srate;
- dec = decay[s] > 0.0f ? inv_srate / decay[s] : srate;
- rel = release[s] > 0.0f ? inv_srate / release[s] : srate;
+ const float del = dl > 0.0f ? inv_srate / dl : srate;
+ const float att = at > 0.0f ? inv_srate / at : srate;
+ const float hld = hl > 0.0f ? inv_srate / hl : srate;
+ const float dec = dc > 0.0f ? inv_srate / dc : srate;
+ const float rel = rl > 0.0f ? inv_srate / rl : srate;
- gat = gate[s];
- trg = trigger[s];
- sus = f_clip(sustain[s], 0.0f, 1.0f);
+ const float gat = gate[s];
+ const float trg = trigger[s];
+ const float sus = f_clip(st, 0.0f, 1.0f);
/* Initialise delay phase if gate is opened and was closed, or
we received a trigger */
@@ -310,369 +376,25 @@ runDahdsr_Audio(LV2_Handle instance,
plugin->samples = samples;
}
-static void
-runDahdsr_Control(LV2_Handle instance,
- uint32_t sample_count)
-{
- Dahdsr* plugin = (Dahdsr*)instance;
-
- /* Gate */
- const float* gate = plugin->gate;
-
- /* Trigger */
- const float* trigger = plugin->trigger;
-
- /* Delay Time (s) */
- const float delay = *(plugin->delay);
-
- /* Attack Time (s) */
- const float attack = *(plugin->attack);
-
- /* Hold Time (s) */
- const float hold = *(plugin->hold);
-
- /* Decay Time (s) */
- const float decay = *(plugin->decay);
-
- /* Sustain Level */
- const float sustain = *(plugin->sustain);
-
- /* Release Time (s) */
- const float release = *(plugin->release);
-
- /* Envelope Out */
- float* output = plugin->output;
-
- /* Instance Data */
- float srate = plugin->srate;
- float inv_srate = plugin->inv_srate;
- float last_gate = plugin->last_gate;
- float last_trigger = plugin->last_trigger;
- float from_level = plugin->from_level;
- float level = plugin->level;
- DAHDSRState state = plugin->state;
- uint32_t samples = plugin->samples;
-
- float gat, trg, del, att, hld, dec, sus, rel;
- float elapsed;
-
- /* Convert times into rates */
- del = delay > 0.0f ? inv_srate / delay : srate;
- att = attack > 0.0f ? inv_srate / attack : srate;
- hld = hold > 0.0f ? inv_srate / hold : srate;
- dec = decay > 0.0f ? inv_srate / decay : srate;
- rel = release > 0.0f ? inv_srate / release : srate;
-
- sus = f_clip(sustain, 0.0f, 1.0f);
-
- for (uint32_t s = 0; s < sample_count; ++s) {
- gat = gate[s];
- trg = trigger[s];
-
- /* Initialise delay phase if gate is opened and was closed, or
- we received a trigger */
- if ((trg > 0.0f && !(last_trigger > 0.0f))
- || (gat > 0.0f && !(last_gate > 0.0f))) {
- if (del < srate) {
- state = DELAY;
- } else if (att < srate) {
- state = ATTACK;
- } else {
- state = hld < srate ? HOLD
- : (dec < srate ? DECAY
- : (gat > 0.0f ? SUSTAIN
- : (rel < srate ? RELEASE
- : IDLE)));
- level = 1.0f;
- }
- samples = 0;
- }
-
- /* Release if gate was open and now closed */
- if (state != IDLE && state != RELEASE
- && last_gate > 0.0f && !(gat > 0.0f)) {
- state = rel < srate ? RELEASE : IDLE;
- samples = 0;
- }
-
- if (samples == 0) {
- from_level = level;
- }
-
- /* Calculate level of envelope from current state */
- switch (state) {
- case IDLE:
- level = 0;
- break;
- case DELAY:
- samples++;
- elapsed = (float)samples * del;
- if (elapsed > 1.0f) {
- state = att < srate ? ATTACK
- : (hld < srate ? HOLD
- : (dec < srate ? DECAY
- : (gat > 0.0f ? SUSTAIN
- : (rel < srate ? RELEASE
- : IDLE))));
- samples = 0;
- }
- break;
- case ATTACK:
- samples++;
- elapsed = (float)samples * att;
- if (elapsed > 1.0f) {
- state = hld < srate ? HOLD
- : (dec < srate ? DECAY
- : (gat > 0.0f ? SUSTAIN
- : (rel < srate ? RELEASE
- : IDLE)));
- level = 1.0f;
- samples = 0;
- } else {
- level = from_level + elapsed * (1.0f - from_level);
- }
- break;
- case HOLD:
- samples++;
- elapsed = (float)samples * hld;
- if (elapsed > 1.0f) {
- state = dec < srate ? DECAY
- : (gat > 0.0f ? SUSTAIN
- : (rel < srate ? RELEASE
- : IDLE));
- samples = 0;
- }
- break;
- case DECAY:
- samples++;
- elapsed = (float)samples * dec;
- if (elapsed > 1.0f) {
- state = gat > 0.0f ? SUSTAIN
- : (rel < srate ? RELEASE
- : IDLE);
- level = sus;
- samples = 0;
- } else {
- level = from_level + elapsed * (sus - from_level);
- }
- break;
- case SUSTAIN:
- level = sus;
- break;
- case RELEASE:
- samples++;
- elapsed = (float)samples * rel;
- if (elapsed > 1.0f) {
- state = IDLE;
- level = 0.0f;
- samples = 0;
- } else {
- level = from_level - elapsed * from_level;
- }
- break;
- default:
- /* Should never happen */
- level = 0.0f;
- }
-
- output[s] = level;
-
- last_gate = gat;
- last_trigger = trg;
- }
-
- plugin->last_gate = last_gate;
- plugin->last_trigger = last_trigger;
- plugin->from_level = from_level;
- plugin->level = level;
- plugin->state = state;
- plugin->samples = samples;
-}
-
-static void
-runDahdsr_CGT_Control(LV2_Handle instance,
- uint32_t sample_count)
+static const void*
+extension_data(const char* uri)
{
- Dahdsr* plugin = (Dahdsr*)instance;
-
- /* Gate */
- const float gate = *(plugin->gate);
-
- /* Trigger */
- const float trigger = *(plugin->trigger);
-
- /* Delay Time (s) */
- const float delay = *(plugin->delay);
-
- /* Attack Time (s) */
- const float attack = *(plugin->attack);
-
- /* Hold Time (s) */
- const float hold = *(plugin->hold);
-
- /* Decay Time (s) */
- const float decay = *(plugin->decay);
-
- /* Sustain Level */
- const float sustain = *(plugin->sustain);
-
- /* Release Time (s) */
- const float release = *(plugin->release);
-
- /* Envelope Out */
- float* output = plugin->output;
-
- /* Instance Data */
- float srate = plugin->srate;
- float inv_srate = plugin->inv_srate;
- float last_gate = plugin->last_gate;
- float last_trigger = plugin->last_trigger;
- float from_level = plugin->from_level;
- float level = plugin->level;
- DAHDSRState state = plugin->state;
- uint32_t samples = plugin->samples;
-
- float gat, trg, del, att, hld, dec, sus, rel;
- float elapsed;
-
- /* Convert times into rates */
- del = delay > 0.0f ? inv_srate / delay : srate;
- att = attack > 0.0f ? inv_srate / attack : srate;
- hld = hold > 0.0f ? inv_srate / hold : srate;
- dec = decay > 0.0f ? inv_srate / decay : srate;
- rel = release > 0.0f ? inv_srate / release : srate;
-
- gat = gate;
- trg = trigger;
- sus = f_clip(sustain, 0.0f, 1.0f);
-
- /* Initialise delay phase if gate is opened and was closed, or
- we received a trigger */
- if ((trg > 0.0f && !(last_trigger > 0.0f))
- || (gat > 0.0f && !(last_gate > 0.0f))) {
- if (del < srate) {
- state = DELAY;
- } else if (att < srate) {
- state = ATTACK;
- } else {
- state = hld < srate ? HOLD
- : (dec < srate ? DECAY
- : (gat > 0.0f ? SUSTAIN
- : (rel < srate ? RELEASE
- : IDLE)));
- level = 1.0f;
- }
- samples = 0;
- }
-
- /* Release if gate was open and now closed */
- if (state != IDLE && state != RELEASE
- && last_gate > 0.0f && !(gat > 0.0f)) {
- state = rel < srate ? RELEASE : IDLE;
- samples = 0;
- }
-
- for (uint32_t s = 0; s < sample_count; ++s) {
- if (samples == 0) {
- from_level = level;
- }
-
- /* Calculate level of envelope from current state */
- switch (state) {
- case IDLE:
- level = 0;
- break;
- case DELAY:
- samples++;
- elapsed = (float)samples * del;
- if (elapsed > 1.0f) {
- state = att < srate ? ATTACK
- : (hld < srate ? HOLD
- : (dec < srate ? DECAY
- : (gat > 0.0f ? SUSTAIN
- : (rel < srate ? RELEASE
- : IDLE))));
- samples = 0;
- }
- break;
- case ATTACK:
- samples++;
- elapsed = (float)samples * att;
- if (elapsed > 1.0f) {
- state = hld < srate ? HOLD
- : (dec < srate ? DECAY
- : (gat > 0.0f ? SUSTAIN
- : (rel < srate ? RELEASE
- : IDLE)));
- level = 1.0f;
- samples = 0;
- } else {
- level = from_level + elapsed * (1.0f - from_level);
- }
- break;
- case HOLD:
- samples++;
- elapsed = (float)samples * hld;
- if (elapsed > 1.0f) {
- state = dec < srate ? DECAY
- : (gat > 0.0f ? SUSTAIN
- : (rel < srate ? RELEASE
- : IDLE));
- samples = 0;
- }
- break;
- case DECAY:
- samples++;
- elapsed = (float)samples * dec;
- if (elapsed > 1.0f) {
- state = gat > 0.0f ? SUSTAIN
- : (rel < srate ? RELEASE
- : IDLE);
- level = sus;
- samples = 0;
- } else {
- level = from_level + elapsed * (sus - from_level);
- }
- break;
- case SUSTAIN:
- level = sus;
- break;
- case RELEASE:
- samples++;
- elapsed = (float)samples * rel;
- if (elapsed > 1.0f) {
- state = IDLE;
- level = 0.0f;
- samples = 0;
- } else {
- level = from_level - elapsed * from_level;
- }
- break;
- default:
- /* Should never happen */
- level = 0.0f;
- }
-
- output[s] = level;
+ static const LV2_Morph_Interface morph = { morph_port, NULL };
+ if (!strcmp(uri, LV2_MORPH__interface)) {
+ return &morph;
}
-
- plugin->last_gate = gat;
- plugin->last_trigger = trg;
- plugin->from_level = from_level;
- plugin->level = level;
- plugin->state = state;
- plugin->samples = samples;
+ return NULL;
}
static const LV2_Descriptor descriptor = {
- "http://drobilla.net/plugins/blip/dahdsr",
+ "http://drobilla.net/plugins/blop/dahdsr",
instantiate,
connect_port,
activate,
- runDahdsr_Control,
+ run,
NULL,
cleanup,
- NULL,
+ extension_data,
};
LV2_SYMBOL_EXPORT const LV2_Descriptor*
diff --git a/src/difference.c b/src/difference.c
index bee9552..92e9a26 100644
--- a/src/difference.c
+++ b/src/difference.c
@@ -18,16 +18,22 @@
*/
#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "uris.h"
-#define DIFFERENCE_INPUT 0
-#define DIFFERENCE_MINUS 1
-#define DIFFERENCE_OUTPUT 2
+#define DIFFERENCE_MINUEND 0
+#define DIFFERENCE_SUBTRAHEND 1
+#define DIFFERENCE_DIFFERENCE 2
typedef struct {
- float* input;
- float* minus;
- float* output;
+ float* minuend;
+ float* subtrahend;
+ float* difference;
+ uint32_t minuend_is_cv;
+ uint32_t subtrahend_is_cv;
+ uint32_t difference_is_cv;
+ URIs uris;
} Difference;
static void
@@ -44,116 +50,131 @@ connect_port(LV2_Handle instance,
Difference* plugin = (Difference*)instance;
switch (port) {
- case DIFFERENCE_INPUT:
- plugin->input = data;
+ case DIFFERENCE_MINUEND:
+ plugin->minuend = data;
break;
- case DIFFERENCE_MINUS:
- plugin->minus = data;
+ case DIFFERENCE_SUBTRAHEND:
+ plugin->subtrahend = data;
break;
- case DIFFERENCE_OUTPUT:
- plugin->output = data;
+ case DIFFERENCE_DIFFERENCE:
+ plugin->difference = data;
break;
}
}
-static LV2_Handle
-instantiate(const LV2_Descriptor* descriptor,
- double sample_rate,
- const char* bundle_path,
- const LV2_Feature* const* features)
-{
- Difference* plugin = (Difference*)malloc(sizeof(Difference));
-
- return (LV2_Handle)plugin;
-}
-
-static void
-runDifference_iama_oa(LV2_Handle instance,
- uint32_t sample_count)
+static LV2_Morph_Status
+morph_port(LV2_Handle instance,
+ uint32_t port,
+ LV2_URID type,
+ const LV2_Morph_Property*const* properties)
{
Difference* plugin = (Difference*)instance;
- /* Input (array of floats of length sample_count) */
- const float* input = plugin->input;
+ if (type != plugin->uris.lv2_ControlPort &&
+ type != plugin->uris.lv2_CVPort) {
+ return LV2_MORPH_ERR_BAD_TYPE;
+ }
- /* Input to Subtract (array of floats of length sample_count) */
- const float* minus = plugin->minus;
+ switch (port) {
+ case DIFFERENCE_MINUEND:
+ plugin->minuend_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ case DIFFERENCE_SUBTRAHEND:
+ plugin->subtrahend_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ return LV2_MORPH_ERR_BAD_PORT;
+ }
- /* Output (array of floats of length sample_count) */
- float* output = plugin->output;
+ plugin->difference_is_cv = (plugin->minuend_is_cv ||
+ plugin->subtrahend_is_cv);
- for (uint32_t s = 0; s < sample_count; ++s) {
- output[s] = input[s] - minus[s];
- }
+ return LV2_MORPH_SUCCESS;
}
-static void
-runDifference_iamc_oa(LV2_Handle instance,
- uint32_t sample_count)
+static LV2_URID
+port_type(LV2_Handle instance,
+ uint32_t port,
+ LV2_Morph_Property*const* properties)
{
Difference* plugin = (Difference*)instance;
- /* Input (array of floats of length sample_count) */
- const float* input = plugin->input;
+ switch (port) {
+ case DIFFERENCE_DIFFERENCE:
+ return (plugin->difference_is_cv
+ ? plugin->uris.lv2_CVPort
+ : plugin->uris.lv2_ControlPort);
+ default:
+ return 0;
+ }
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Difference* plugin = (Difference*)malloc(sizeof(Difference));
+ if (!plugin) {
+ return NULL;
+ }
- /* Input to Subtract (float value) */
- const float minus = *(plugin->minus);
+ plugin->minuend_is_cv = 0;
+ plugin->subtrahend_is_cv = 0;
+ plugin->difference_is_cv = 0;
- /* Output (array of floats of length sample_count) */
- float* output = plugin->output;
+ map_uris(&plugin->uris, features);
- for (uint32_t s = 0; s < sample_count; ++s) {
- output[s] = input[s] - minus;
- }
+ return (LV2_Handle)plugin;
}
static void
-runDifference_icma_oa(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
Difference* plugin = (Difference*)instance;
- /* Input (float value) */
- const float input = *(plugin->input);
+ /* Minuend (array of floats of length 1 or sample_count) */
+ const float* minuend = plugin->minuend;
- /* Input to Subtract (array of floats of length sample_count) */
- const float* minus = plugin->minus;
+ /* Subtrahend (array of floats of length 1 or sample_count) */
+ const float* subtrahend = plugin->subtrahend;
- /* Output (array of floats of length sample_count) */
- float* output = plugin->output;
+ /* Difference (array of floats of length 1 or sample_count) */
+ float* difference = plugin->difference;
+
+ if (!plugin->difference_is_cv) { /* TODO: Avoid this branch */
+ sample_count = 1;
+ }
for (uint32_t s = 0; s < sample_count; ++s) {
- output[s] = input - minus[s];
+ const float min = minuend[s * plugin->minuend_is_cv];
+ const float sub = subtrahend[s * plugin->subtrahend_is_cv];
+
+ difference[s] = min - sub;
}
}
-static void
-runDifference_icmc_oc(LV2_Handle instance,
- uint32_t sample_count)
+static const void*
+extension_data(const char* uri)
{
- Difference* plugin = (Difference*)instance;
-
- /* Input (float value) */
- const float input = *(plugin->input);
-
- /* Input to Subtract (float value) */
- const float minus = *(plugin->minus);
-
- /* Output Frequency (pointer to float value) */
- float* output = plugin->output;
-
- output[0] = input - minus;
+ static const LV2_Morph_Interface morph = { morph_port, port_type };
+ if (!strcmp(uri, LV2_MORPH__interface)) {
+ return &morph;
+ }
+ return NULL;
}
static const LV2_Descriptor descriptor = {
- "http://drobilla.net/plugins/blip/difference",
+ "http://drobilla.net/plugins/blop/difference",
instantiate,
connect_port,
NULL,
- runDifference_icmc_oc,
+ run,
NULL,
cleanup,
- NULL,
+ extension_data,
};
LV2_SYMBOL_EXPORT const LV2_Descriptor*
diff --git a/src/fmod.c b/src/fmod.c
index ee14a87..d566418 100644
--- a/src/fmod.c
+++ b/src/fmod.c
@@ -18,17 +18,23 @@
*/
#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
#include "math_func.h"
+#include "uris.h"
#define FMOD_FREQUENCY 0
#define FMOD_MODULATOR 1
#define FMOD_OUTPUT 2
typedef struct {
- float* frequency;
- float* modulator;
- float* output;
+ float* frequency;
+ float* modulator;
+ float* output;
+ uint32_t frequency_is_cv;
+ uint32_t modulator_is_cv;
+ uint32_t output_is_cv;
+ URIs uris;
} Fmod;
static void
@@ -57,129 +63,113 @@ connect_port(LV2_Handle instance,
}
}
-static LV2_Handle
-instantiate(const LV2_Descriptor* descriptor,
- double sample_rate,
- const char* bundle_path,
- const LV2_Feature* const* features)
-{
- Fmod* plugin = (Fmod*)malloc(sizeof(Fmod));
-
- return (LV2_Handle)plugin;
-}
-
-static void
-runFmod_fama_oa(LV2_Handle instance,
- uint32_t sample_count)
+static LV2_Morph_Status
+morph_port(LV2_Handle instance,
+ uint32_t port,
+ LV2_URID type,
+ const LV2_Morph_Property*const* properties)
{
Fmod* plugin = (Fmod*)instance;
- /* Frequency to Modulate (array of floats of length sample_count) */
- const float* frequency = plugin->frequency;
-
- /* LFO Input (array of floats of length sample_count) */
- const float* modulator = plugin->modulator;
-
- /* Output Frequency (array of floats of length sample_count) */
- float* output = plugin->output;
-
- float freq;
- float mod;
- float scale;
-
- for (uint32_t s = 0; s < sample_count; ++s) {
- freq = frequency[s];
- mod = modulator[s];
-
- scale = (float)EXPF(M_LN2 * mod);
+ if (type != plugin->uris.lv2_ControlPort &&
+ type != plugin->uris.lv2_CVPort) {
+ return LV2_MORPH_ERR_BAD_TYPE;
+ }
- output[s] = scale * freq;
+ switch (port) {
+ case FMOD_FREQUENCY:
+ plugin->frequency_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ case FMOD_MODULATOR:
+ plugin->modulator_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ return LV2_MORPH_ERR_BAD_PORT;
}
+
+ return LV2_MORPH_SUCCESS;
}
-static void
-runFmod_famc_oa(LV2_Handle instance,
- uint32_t sample_count)
+static LV2_URID
+port_type(LV2_Handle instance,
+ uint32_t port,
+ LV2_Morph_Property*const* properties)
{
Fmod* plugin = (Fmod*)instance;
- /* Frequency to Modulate (array of floats of length sample_count) */
- const float* frequency = plugin->frequency;
-
- /* Shift (Octaves) (float value) */
- const float modulator = *(plugin->modulator);
-
- /* Output Frequency (array of floats of length sample_count) */
- float* output = plugin->output;
-
- float freq;
- float scale = (float)EXPF(M_LN2 * modulator);
+ switch (port) {
+ case FMOD_FREQUENCY:
+ return (plugin->output_is_cv
+ ? plugin->uris.lv2_CVPort
+ : plugin->uris.lv2_ControlPort);
+ default:
+ return 0;
+ }
+}
- for (uint32_t s = 0; s < sample_count; ++s) {
- freq = frequency[s];
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double sample_rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ Fmod* plugin = (Fmod*)malloc(sizeof(Fmod));
- output[s] = scale * freq;
+ if (plugin) {
+ plugin->frequency_is_cv = 0;
+ plugin->modulator_is_cv = 0;
}
+
+ return (LV2_Handle)plugin;
}
static void
-runFmod_fcma_oa(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
Fmod* plugin = (Fmod*)instance;
- /* Frequency to Modulate (float value) */
- const float frequency = *(plugin->frequency);
+ /* Frequency to Modulate (array of floats of length 1 or sample_count) */
+ const float* frequency = plugin->frequency;
- /* LFO Input (array of floats of length sample_count) */
+ /* LFO Input (array of floats of length 1 or sample_count) */
const float* modulator = plugin->modulator;
- /* Output Frequency (array of floats of length sample_count) */
+ /* Output Frequency (array of floats of length 1 or sample_count) */
float* output = plugin->output;
- float mod;
- float scale;
+ if (!plugin->output_is_cv) { /* TODO: Avoid this branch */
+ sample_count = 1;
+ }
for (uint32_t s = 0; s < sample_count; ++s) {
- mod = modulator[s];
-
- scale = (float)EXPF(M_LN2 * mod);
+ const float freq = frequency[s * plugin->frequency_is_cv];
+ const float mod = modulator[s * plugin->modulator_is_cv];
+ const float scale = (float)EXPF(M_LN2 * mod);
- output[s] = scale * frequency;
+ output[s] = scale * freq;
}
}
-static void
-runFmod_fcmc_oc(LV2_Handle instance,
- uint32_t sample_count)
+static const void*
+extension_data(const char* uri)
{
- Fmod* plugin = (Fmod*)instance;
-
- /* Frequency to Modulate (float value) */
- const float frequency = *(plugin->frequency);
-
- /* Shift (Octaves) (float value) */
- const float modulator = *(plugin->modulator);
-
- /* Output Frequency (pointer to float value) */
- float* output = plugin->output;
-
- float scale;
-
- scale = (float)EXPF(M_LN2 * modulator);
-
- output[0] = scale * frequency;
+ static const LV2_Morph_Interface morph = { morph_port, port_type };
+ if (!strcmp(uri, LV2_MORPH__interface)) {
+ return &morph;
+ }
+ return NULL;
}
static const LV2_Descriptor descriptor = {
- "http://drobilla.net/plugins/blip/fmod",
+ "http://drobilla.net/plugins/blop/fmod",
instantiate,
connect_port,
NULL,
- runFmod_fcmc_oc,
+ run,
NULL,
cleanup,
- NULL,
+ extension_data,
};
LV2_SYMBOL_EXPORT const LV2_Descriptor*
diff --git a/src/include/common.h b/src/include/common.h
index 0f30aa1..26a405a 100644
--- a/src/include/common.h
+++ b/src/include/common.h
@@ -17,8 +17,8 @@
along with this software. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef blip_common_h
-#define blip_common_h
+#ifndef blop_common_h
+#define blop_common_h
#include "math_func.h"
@@ -51,4 +51,4 @@ f_clip (float x, float a, float b)
return 0.5f * (FABSF (x - a) + a + b - FABSF (x - b));
}
-#endif /* blip_common_h */
+#endif /* blop_common_h */
diff --git a/src/include/interpolate.h b/src/include/interpolate.h
index 5fba16a..304a817 100644
--- a/src/include/interpolate.h
+++ b/src/include/interpolate.h
@@ -1,8 +1,8 @@
-#ifndef blip_interpolate_h
-#define blip_interpolate_h
+#ifndef blop_interpolate_h
+#define blop_interpolate_h
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
-#include "blip_config.h"
+#include "blop_config.h"
#include "math_func.h"
/**
@@ -72,4 +72,4 @@ f_lerp (float value,
return value;
}
-#endif /* blip_interpolate_h */
+#endif /* blop_interpolate_h */
diff --git a/src/include/lp4pole_filter.h b/src/include/lp4pole_filter.h
index adc5cba..a6b27f1 100644
--- a/src/include/lp4pole_filter.h
+++ b/src/include/lp4pole_filter.h
@@ -30,8 +30,8 @@
along with this software. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef blip_lp4pole_filter_h
-#define blip_lp4pole_filter_h
+#ifndef blop_lp4pole_filter_h
+#define blop_lp4pole_filter_h
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
#include "common.h"
@@ -134,4 +134,4 @@ lp4pole_run(LP4PoleFilter* lpf,
return lpf->out4;
}
-#endif /* blip_lp4pole_filter_h */
+#endif /* blop_lp4pole_filter_h */
diff --git a/src/include/math_func.h b/src/include/math_func.h
index 2e4b6e4..60f7ce0 100644
--- a/src/include/math_func.h
+++ b/src/include/math_func.h
@@ -7,7 +7,7 @@
#define math_func_h
#include <math.h>
-#include "blip_config.h"
+#include "blop_config.h"
#ifndef M_PI
# define M_PI 3.14159265358979323846 /* pi */
diff --git a/src/include/wavedata.h b/src/include/wavedata.h
index 9bd313c..9d24823 100644
--- a/src/include/wavedata.h
+++ b/src/include/wavedata.h
@@ -17,19 +17,19 @@
along with this software. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef blip_wavedata_h
-#define blip_wavedata_h
+#ifndef blop_wavedata_h
+#define blop_wavedata_h
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
-#include "blip_config.h"
+#include "blop_config.h"
#include "math_func.h"
#include "interpolate.h"
#include "common.h"
/* Functions identifying wavedata dlls */
-#define BLOP_DLSYM_SAWTOOTH "blip_get_sawtooth"
-#define BLOP_DLSYM_SQUARE "blip_get_square"
-#define BLOP_DLSYM_PARABOLA "blip_get_parabola"
+#define BLOP_DLSYM_SAWTOOTH "blop_get_sawtooth"
+#define BLOP_DLSYM_SQUARE "blop_get_square"
+#define BLOP_DLSYM_PARABOLA "blop_get_parabola"
/*
* Structure holding a single segment of sample data
@@ -191,4 +191,4 @@ wavedata_get_table(Wavedata* w,
} /* extern "C" { */
#endif
-#endif /* blip_wavedata_h */
+#endif /* blop_wavedata_h */
diff --git a/src/include/wdatutil.h b/src/include/wdatutil.h
index 931a7f3..a084c7a 100644
--- a/src/include/wdatutil.h
+++ b/src/include/wdatutil.h
@@ -17,8 +17,8 @@
along with this software. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef blip_wdatutil_h
-#define blip_wdatutil_h
+#ifndef blop_wdatutil_h
+#define blop_wdatutil_h
#include <stdio.h>
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
@@ -138,4 +138,4 @@ int wavedata_write(Wavedata* w,
} /* extern "C" { */
#endif
-#endif /* blip_wdatutil_h */
+#endif /* blop_wdatutil_h */
diff --git a/src/interpolator.c b/src/interpolator.c
index 52a6c37..24fa927 100644
--- a/src/interpolator.c
+++ b/src/interpolator.c
@@ -79,6 +79,9 @@ instantiate(const LV2_Descriptor* descriptor,
const LV2_Feature* const* features)
{
Interpolator* plugin = (Interpolator*)malloc(sizeof(Interpolator));
+ if (!plugin) {
+ return NULL;
+ }
return (LV2_Handle)plugin;
}
@@ -93,8 +96,8 @@ activate(LV2_Handle instance)
}
static void
-runInterpolator(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
Interpolator* plugin = (Interpolator*)instance;
@@ -121,11 +124,11 @@ runInterpolator(LV2_Handle instance,
}
static const LV2_Descriptor descriptor = {
- "http://drobilla.net/plugins/blip/interpolator",
+ "http://drobilla.net/plugins/blop/interpolator",
instantiate,
connect_port,
activate,
- runInterpolator,
+ run,
NULL,
cleanup,
NULL,
diff --git a/src/lp4pole.c b/src/lp4pole.c
index a00ca5b..1997ae3 100644
--- a/src/lp4pole.c
+++ b/src/lp4pole.c
@@ -18,9 +18,11 @@
*/
#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
#include "lp4pole_filter.h"
#include "common.h"
+#include "uris.h"
#define LP4POLE_CUTOFF 0
#define LP4POLE_RESONANCE 1
@@ -33,6 +35,9 @@ typedef struct {
float* input;
float* output;
LP4PoleFilter* lpf;
+ uint32_t cutoff_is_cv;
+ uint32_t resonance_is_cv;
+ URIs uris;
} Lp4pole;
static void
@@ -68,6 +73,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)
+{
+ Lp4pole* plugin = (Lp4pole*)instance;
+
+ if (type != plugin->uris.lv2_ControlPort &&
+ type != plugin->uris.lv2_CVPort) {
+ return LV2_MORPH_ERR_BAD_TYPE;
+ }
+
+ switch (port) {
+ case LP4POLE_CUTOFF:
+ plugin->cutoff_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ case LP4POLE_RESONANCE:
+ plugin->resonance_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,
@@ -80,9 +112,12 @@ instantiate(const LV2_Descriptor* descriptor,
plugin->lpf = lp4pole_new(sample_rate);
if (!plugin->lpf) {
free(plugin);
- plugin = 0;
+ return NULL;
}
+ plugin->cutoff_is_cv = 0;
+ plugin->resonance_is_cv = 0;
}
+
return (LV2_Handle)plugin;
}
@@ -95,15 +130,15 @@ activate(LV2_Handle instance)
}
static void
-runLp4pole_faraia_oa(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
Lp4pole* plugin = (Lp4pole*)instance;
- /* Cutoff Frequency (array of floats of length sample_count) */
+ /* Cutoff Frequency (array of floats of length 1 or sample_count) */
const float* cutoff = plugin->cutoff;
- /* Resonance (array of floats of length sample_count) */
+ /* Resonance (array of floats of length 1 or sample_count) */
const float* resonance = plugin->resonance;
/* Input (array of floats of length sample_count) */
@@ -115,61 +150,39 @@ runLp4pole_faraia_oa(LV2_Handle instance,
/* Instance data */
LP4PoleFilter* lpf = plugin->lpf;
- float in;
- float co;
- float res;
-
for (uint32_t s = 0; s < sample_count; ++s) {
- co = cutoff[s];
- res = resonance[s];
- in = input[s];
+ const float co = cutoff[s * plugin->cutoff_is_cv];
+ const float res = resonance[s * plugin->resonance_is_cv];
+ const float in = input[s];
+ /* TODO: There is no branching in this function.
+ Would it actually be faster to check if co or res has changed?
+ */
lp4pole_set_params(lpf, co, res);
output[s] = lp4pole_run(lpf, in);
}
}
-static void
-runLp4pole_fcrcia_oa(LV2_Handle instance,
- uint32_t sample_count)
+static const void*
+extension_data(const char* uri)
{
- Lp4pole* plugin = (Lp4pole*)instance;
-
- /* Cutoff Frequency (float value) */
- const float cutoff = *(plugin->cutoff);
-
- /* Resonance (float value) */
- const float resonance = *(plugin->resonance);
-
- /* Input (array of floats of length sample_count) */
- const float* input = plugin->input;
-
- /* Output (pointer to float value) */
- float* output = plugin->output;
-
- /* Instance data */
- LP4PoleFilter* lpf = plugin->lpf;
-
- float in;
-
- lp4pole_set_params(lpf, cutoff, resonance);
-
- for (uint32_t s = 0; s < sample_count; ++s) {
- in = input[s];
- output[s] = lp4pole_run(lpf, in);
+ static const LV2_Morph_Interface morph = { morph_port, NULL };
+ if (!strcmp(uri, LV2_MORPH__interface)) {
+ return &morph;
}
+ return NULL;
}
static const LV2_Descriptor descriptor = {
- "http://drobilla.net/plugins/blip/lp4pole",
+ "http://drobilla.net/plugins/blop/lp4pole",
instantiate,
connect_port,
activate,
- runLp4pole_fcrcia_oa,
+ run,
NULL,
cleanup,
- NULL,
+ extension_data,
};
LV2_SYMBOL_EXPORT const LV2_Descriptor*
diff --git a/src/product.c b/src/product.c
index 0b892a1..3f83af9 100644
--- a/src/product.c
+++ b/src/product.c
@@ -18,16 +18,22 @@
*/
#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "uris.h"
#define PRODUCT_MULTIPLICAND 0
#define PRODUCT_MULTIPLIER 1
#define PRODUCT_PRODUCT 2
typedef struct {
- float* input1;
- float* input2;
- float* output;
+ float* input1;
+ float* input2;
+ float* output;
+ uint32_t input1_is_cv;
+ uint32_t input2_is_cv;
+ uint32_t output_is_cv;
+ URIs uris;
} Product;
static void
@@ -56,6 +62,51 @@ 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)
+{
+ Product* plugin = (Product*)instance;
+
+ if (type != plugin->uris.lv2_ControlPort &&
+ type != plugin->uris.lv2_CVPort) {
+ return LV2_MORPH_ERR_BAD_TYPE;
+ }
+
+ switch (port) {
+ case PRODUCT_MULTIPLICAND:
+ plugin->input1_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ case PRODUCT_MULTIPLIER:
+ plugin->input2_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ return LV2_MORPH_ERR_BAD_PORT;
+ }
+
+ plugin->output_is_cv = plugin->input1_is_cv || plugin->input2_is_cv;
+ return LV2_MORPH_SUCCESS;
+}
+
+static LV2_URID
+port_type(LV2_Handle instance,
+ uint32_t port,
+ LV2_Morph_Property*const* properties)
+{
+ Product* plugin = (Product*)instance;
+
+ switch (port) {
+ case PRODUCT_PRODUCT:
+ return (plugin->output_is_cv
+ ? plugin->uris.lv2_CVPort
+ : plugin->uris.lv2_ControlPort);
+ default:
+ return 0;
+ }
+}
+
static LV2_Handle
instantiate(const LV2_Descriptor* descriptor,
double sample_rate,
@@ -63,77 +114,64 @@ instantiate(const LV2_Descriptor* descriptor,
const LV2_Feature* const* features)
{
Product* plugin = (Product*)malloc(sizeof(Product));
+ if (!plugin) {
+ return NULL;
+ }
+
+ plugin->input1_is_cv = 0;
+ plugin->input2_is_cv = 0;
+ plugin->output_is_cv = 0;
+
+ map_uris(&plugin->uris, features);
return (LV2_Handle)plugin;
}
static void
-runProduct_iaia_oa(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
Product* plugin = (Product*)instance;
- /* First Input (array of floats of length sample_count) */
+ /* First Input (array of floats of length 1 or sample_count) */
const float* input1 = plugin->input1;
- /* Second Input (array of floats of length sample_count) */
+ /* Second Input (array of floats of length 1 or sample_count) */
const float* input2 = plugin->input2;
/* Output (array of floats of length sample_count) */
float* output = plugin->output;
- for (uint32_t s = 0; s < sample_count; ++s) {
- output[s] = input1[s] * input2[s];
+ if (!plugin->output_is_cv) { /* TODO: Avoid this branch */
+ sample_count = 1;
}
-}
-
-static void
-runProduct_iaic_oa(LV2_Handle instance,
- uint32_t sample_count)
-{
- Product* plugin = (Product*)instance;
-
- /* First Input (array of floats of length sample_count) */
- const float* input1 = plugin->input1;
-
- /* Second Input (float value) */
- const float input2 = *(plugin->input2);
-
- /* Output (array of floats of length sample_count) */
- float* output = plugin->output;
for (uint32_t s = 0; s < sample_count; ++s) {
- output[s] = input1[s] * input2;
+ const float in1 = input1[s * plugin->input1_is_cv];
+ const float in2 = input2[s * plugin->input2_is_cv];
+ output[s] = in1 * in2;
}
}
-static void
-runProduct_icic_oc(LV2_Handle instance,
- uint32_t sample_count)
+static const void*
+extension_data(const char* uri)
{
- Product* plugin = (Product*)instance;
-
- /* First Input (float value) */
- const float input1 = *(plugin->input1);
-
- /* Second Input (float value) */
- const float input2 = *(plugin->input2);
-
- /* Output (pointer to float value) */
- float* output = plugin->output;
-
- output[0] = input1 * input2;
+ static const LV2_Morph_Interface morph = { morph_port, port_type };
+ if (!strcmp(uri, LV2_MORPH__interface)) {
+ return &morph;
+ }
+ return NULL;
}
static const LV2_Descriptor descriptor = {
- "http://drobilla.net/plugins/blip/product",
+ "http://drobilla.net/plugins/blop/product",
instantiate,
connect_port,
NULL,
- runProduct_iaia_oa,
+ run,
NULL,
cleanup,
- NULL,
+ extension_data,
};
LV2_SYMBOL_EXPORT const LV2_Descriptor*
diff --git a/src/pulse.c b/src/pulse.c
index 8890fbd..c4d857b 100644
--- a/src/pulse.c
+++ b/src/pulse.c
@@ -18,7 +18,9 @@
*/
#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "uris.h"
#include "wavedata.h"
#define PULSE_FREQUENCY 0
@@ -30,7 +32,10 @@ typedef struct {
float* pulsewidth;
float* output;
float phase;
+ uint32_t frequency_is_cv;
+ uint32_t pulsewidth_is_cv;
Wavedata wdat;
+ URIs uris;
} Pulse;
static void
@@ -53,6 +58,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)
+{
+ Pulse* plugin = (Pulse*)instance;
+
+ if (type != plugin->uris.lv2_ControlPort &&
+ type != plugin->uris.lv2_CVPort) {
+ return LV2_MORPH_ERR_BAD_TYPE;
+ }
+
+ switch (port) {
+ case PULSE_FREQUENCY:
+ plugin->frequency_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ case PULSE_PULSEWIDTH:
+ plugin->pulsewidth_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,
@@ -60,6 +92,9 @@ instantiate(const LV2_Descriptor* descriptor,
const LV2_Feature* const* features)
{
Pulse* plugin = (Pulse*)malloc(sizeof(Pulse));
+ if (!plugin) {
+ return NULL;
+ }
if (wavedata_load(&plugin->wdat, bundle_path, "sawtooth_data",
BLOP_DLSYM_SAWTOOTH, sample_rate)) {
@@ -67,6 +102,11 @@ instantiate(const LV2_Descriptor* descriptor,
return 0;
}
+ plugin->frequency_is_cv = 0;
+ plugin->pulsewidth_is_cv = 0;
+ map_uris(&plugin->uris, features);
+ wavedata_get_table(&plugin->wdat, 440.0);
+
return (LV2_Handle)plugin;
}
@@ -88,8 +128,8 @@ activate(LV2_Handle instance)
}
static void
-runPulse_fapa_oa(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
Pulse* plugin = (Pulse*)instance;
@@ -106,114 +146,32 @@ runPulse_fapa_oa(LV2_Handle instance,
Wavedata* wdat = &plugin->wdat;
float phase = plugin->phase;
- float freq;
- float pwidth;
- float phase_shift;
+ float last_pwidth = pulsewidth[0];
+ float pwidth = f_clip(last_pwidth, 0.0f, 1.0f);
+ float dc_shift = 1.0 - (2.0 * pwidth);
+ float phase_shift = pwidth * wdat->sample_rate;
for (uint32_t s = 0; s < sample_count; ++s) {
- freq = frequency[s];
- pwidth = f_clip(pulsewidth[s], 0.0f, 1.0f);
- phase_shift = pwidth * wdat->sample_rate;
-
- /* Lookup which table to use from frequency */
- wavedata_get_table(wdat, freq);
-
- /* Get samples from sawtooth and phase shifted inverted sawtooth,
- with approriate DC offset */
- output[s] = wavedata_get_sample(wdat, phase)
- - wavedata_get_sample(wdat, phase + phase_shift)
- + 1.0f - (2.0f * pwidth);
-
- /* 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
-runPulse_fapc_oa(LV2_Handle instance,
- uint32_t sample_count)
-{
- Pulse* plugin = (Pulse*)instance;
-
- /* Frequency (array of float of length sample_count) */
- const float* frequency = plugin->frequency;
-
- /* Pulse Width (float value) */
- const float pulsewidth = f_clip(*(plugin->pulsewidth), 0.0f, 1.0f);
-
- /* Output (pointer to float value) */
- float* output = plugin->output;
- /* Instance data */
- Wavedata* wdat = &plugin->wdat;
- float phase = plugin->phase;
-
- float freq;
- float dc_shift = 1.0 - (2.0 * pulsewidth);
- float phase_shift = pulsewidth * 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 sawtooth and phase shifted inverted sawtooth,
- with approriate DC offset */
- output[s] = wavedata_get_sample(wdat, phase)
- - wavedata_get_sample(wdat, phase + phase_shift)
- + dc_shift;
-
- /* 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_pwidth = pulsewidth[s * plugin->pulsewidth_is_cv];
+ if (this_pwidth != last_pwidth) {
+ /* Pulsewidth changed, recalculate */
+ last_pwidth = this_pwidth;
+ pwidth = f_clip(this_pwidth, 0.0f, 1.0f);
+ dc_shift = 1.0f - (2.0f * pwidth);
+ phase_shift = pwidth * wdat->sample_rate;
}
- }
- plugin->phase = phase;
-}
-
-static void
-runPulse_fcpa_oa(LV2_Handle instance,
- uint32_t sample_count)
-{
- Pulse* plugin = (Pulse*)instance;
-
- /* Frequency (float value) */
- const float frequency = *(plugin->frequency);
-
- /* Pulse Width (array of float of length sample_count) */
- const float* pulsewidth = plugin->pulsewidth;
-
- /* Output (pointer to float value) */
- float* output = plugin->output;
-
- /* Instance data */
- Wavedata* wdat = &plugin->wdat;
- float phase = plugin->phase;
-
- float pwidth;
- float phase_shift;
-
- wavedata_get_table(wdat, frequency);
-
- for (uint32_t s = 0; s < sample_count; ++s) {
- pwidth = f_clip(pulsewidth[s], 0.0f, 1.0f);
- phase_shift = pwidth * wdat->sample_rate;
/* Get samples from sawtooth and phase shifted inverted sawtooth,
with approriate DC offset */
output[s] = wavedata_get_sample(wdat, phase)
- wavedata_get_sample(wdat, phase + phase_shift)
- + 1.0f - (2.0f * pwidth);
+ + dc_shift;
/* Update phase, wrapping if necessary */
phase += wdat->frequency;
@@ -226,57 +184,25 @@ runPulse_fcpa_oa(LV2_Handle instance,
plugin->phase = phase;
}
-static void
-runPulse_fcpc_oa(LV2_Handle instance,
- uint32_t sample_count)
+static const void*
+extension_data(const char* uri)
{
- Pulse* plugin = (Pulse*)instance;
-
- /* Frequency (float value) */
- const float frequency = *(plugin->frequency);
-
- /* Pulse Width (float value) */
- const float pulsewidth = f_clip(*(plugin->pulsewidth), 0.0f, 1.0f);
-
- /* Output (pointer to float value) */
- float* output = plugin->output;
-
- /* Instance data */
- Wavedata* wdat = &plugin->wdat;
- float phase = plugin->phase;
-
- float dc_shift = 1.0f - (2.0f * pulsewidth);
- float phase_shift = pulsewidth * wdat->sample_rate;
-
- wavedata_get_table(wdat, frequency);
-
- for (uint32_t s = 0; s < sample_count; ++s) {
- /* Get samples from sawtooth and phase shifted inverted sawtooth,
- with approriate DC offset */
- output[s] = wavedata_get_sample(wdat, phase)
- - wavedata_get_sample(wdat, phase + phase_shift)
- + dc_shift;
-
- /* 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/pulse",
+ "http://drobilla.net/plugins/blop/pulse",
instantiate,
connect_port,
activate,
- runPulse_fcpc_oa,
+ run,
NULL,
cleanup,
- NULL,
+ extension_data,
};
LV2_SYMBOL_EXPORT const LV2_Descriptor*
diff --git a/src/quantiser.c b/src/quantiser.c
index 793da32..419467f 100644
--- a/src/quantiser.c
+++ b/src/quantiser.c
@@ -205,54 +205,16 @@ instantiate(const LV2_Descriptor* descriptor,
}
static void
-runQuantiser_audio(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
Quantiser* plugin = (Quantiser*)instance;
/* Range Min (float value) */
- const float min = *(plugin->min);
+ float min = *(plugin->min);
/* Range Max (float value) */
- const float max = *(plugin->max);
-
- /* Match Range (float value) */
- const float match_range = *(plugin->match_range);
-
- /* Mode (float value) */
- const float mode = *(plugin->mode);
-
- /* Count (float value) */
- const float count = *(plugin->count);
-
- /* Input (array of float of length sample_count) */
- const float* input = plugin->input;
-
- /* Values */
- float* values[QUANTISER_MAX_INPUTS];
-
- /* Output (array of float of length sample_count) */
- float* output = plugin->output;
-
- /* Output Changed (array of float of length sample_count) */
- float* output_changed = plugin->output_changed;
-
- for (uint32_t s = 0; s < sample_count; s++) {
- output[s] = input[s];
- }
-}
-
-static void
-runQuantiser_control(LV2_Handle instance,
- uint32_t sample_count)
-{
- Quantiser* plugin = (Quantiser*)instance;
-
- /* Range Min (float value) */
- const float min = *(plugin->min);
-
- /* Range Max (float value) */
- const float max = *(plugin->max);
+ float max = *(plugin->max);
/* Match Range (float value) */
const float match_range = FABSF(*(plugin->match_range));
@@ -469,3 +431,23 @@ runQuantiser_control(LV2_Handle instance,
}
plugin->last_found = last_found;
}
+
+static const LV2_Descriptor descriptor = {
+ QUANTISER_URI,
+ instantiate,
+ connect_port,
+ NULL,
+ run,
+ NULL,
+ cleanup,
+ NULL
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/random.c b/src/random.c
index 4a6f5b8..1671854 100644
--- a/src/random.c
+++ b/src/random.c
@@ -18,24 +18,29 @@
*/
#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
#include <time.h>
#include "math_func.h"
#include "common.h"
+#include "uris.h"
#define RANDOM_FREQUENCY 0
#define RANDOM_SMOOTH 1
#define RANDOM_OUTPUT 2
typedef struct {
- float* frequency;
- float* smooth;
- float* output;
- float nyquist;
- float inv_nyquist;
- float phase;
- float value1;
- float value2;
+ float* frequency;
+ float* smooth;
+ float* output;
+ float nyquist;
+ float inv_nyquist;
+ float phase;
+ float value1;
+ float value2;
+ uint32_t frequency_is_cv;
+ uint32_t smooth_is_cv;
+ URIs uris;
} Random;
float inv_rand_max;
@@ -66,6 +71,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)
+{
+ Random* plugin = (Random*)instance;
+
+ if (type != plugin->uris.lv2_ControlPort &&
+ type != plugin->uris.lv2_CVPort) {
+ return LV2_MORPH_ERR_BAD_TYPE;
+ }
+
+ switch (port) {
+ case RANDOM_FREQUENCY:
+ plugin->frequency_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ case RANDOM_SMOOTH:
+ plugin->smooth_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,
@@ -73,6 +105,9 @@ instantiate(const LV2_Descriptor* descriptor,
const LV2_Feature* const* features)
{
Random* plugin = (Random*)malloc(sizeof(Random));
+ if (!plugin) {
+ return NULL;
+ }
srand((int)time((time_t*)0));
@@ -84,6 +119,9 @@ instantiate(const LV2_Descriptor* descriptor,
plugin->value1 = rand() * inv_rand_max - 1.0f;
plugin->value2 = rand() * inv_rand_max - 1.0f;
+ plugin->frequency_is_cv = 0;
+ plugin->smooth_is_cv = 0;
+
return (LV2_Handle)plugin;
}
@@ -96,15 +134,15 @@ activate(LV2_Handle instance)
}
static void
-runRandom_fasa_oa(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
Random* plugin = (Random*)instance;
- /* Frequency (Hz) (array of floats of length sample_count) */
+ /* Frequency (Hz) (array of floats of length 1 or sample_count) */
const float* frequency = plugin->frequency;
- /* Wave smoothness (array of floats of length sample_count) */
+ /* Wave smoothness (array of floats of length 1 or sample_count) */
const float* smooth = plugin->smooth;
/* Output (array of floats of length sample_count) */
@@ -117,132 +155,16 @@ runRandom_fasa_oa(LV2_Handle instance,
float value1 = plugin->value1;
float value2 = plugin->value2;
- float freq;
- float smth;
- float interval;
float result;
for (uint32_t s = 0; s < sample_count; ++s) {
- freq = f_clip(frequency[s], 0.0f, nyquist);
-
- smth = f_clip(smooth[s], 0.0f, 1.0f);
- interval = (1.0f - smth) * 0.5f;
-
- if (phase < interval) {
- result = 1.0f;
- } else if (phase > (1.0f - interval)) {
- result = -1.0f;
- } else if (interval > 0.0f) {
- result = COSF((phase - interval) / smth * M_PI);
- } else {
- result = COSF(phase * M_PI);
- }
-
- result *= (value2 - value1) * 0.5f;
- result -= (value2 + value1) * 0.5f;
-
- output[s] = result;
-
- phase += freq * inv_nyquist;
- if (phase > 1.0f) {
- phase -= 1.0f;
- value1 = value2;
- value2 = (float)rand() * inv_rand_max - 1.0f;
- }
- }
-
- plugin->phase = phase;
- plugin->value1 = value1;
- plugin->value2 = value2;
-}
-
-static void
-runRandom_fasc_oa(LV2_Handle instance,
- uint32_t sample_count)
-{
- Random* plugin = (Random*)instance;
-
- /* Frequency (Hz) (array of floats of length sample_count) */
- const float* frequency = plugin->frequency;
-
- /* Wave smoothness (float value) */
- const float smooth = f_clip(*(plugin->smooth), 0.0f, 1.0f);
-
- /* Output (array of floats of length sample_count) */
- float* output = plugin->output;
-
- /* Instance data */
- float nyquist = plugin->nyquist;
- float inv_nyquist = plugin->inv_nyquist;
- float phase = plugin->phase;
- float value1 = plugin->value1;
- float value2 = plugin->value2;
-
- float freq;
- float interval = (1.0f - smooth) * 0.5f;
- float result;
-
- for (uint32_t s = 0; s < sample_count; ++s) {
- freq = f_clip(frequency[s], 0.0f, nyquist);
-
- if (phase < interval) {
- result = 1.0f;
- } else if (phase > (1.0f - interval)) {
- result = -1.0f;
- } else if (interval > 0.0f) {
- result = COSF((phase - interval) / smooth * M_PI);
- } else {
- result = COSF(phase * M_PI);
- }
-
- result *= (value2 - value1) * 0.5f;
- result -= (value2 + value1) * 0.5f;
-
- output[s] = result;
-
- phase += freq * inv_nyquist;
- if (phase > 1.0f) {
- phase -= 1.0f;
- value1 = value2;
- value2 = (float)rand() * inv_rand_max - 1.0f;
- }
- }
-
- plugin->phase = phase;
- plugin->value1 = value1;
- plugin->value2 = value2;
-}
+ const float freq = f_clip(frequency[s * plugin->frequency_is_cv],
+ 0.0f, nyquist);
-static void
-runRandom_fcsa_oa(LV2_Handle instance,
- uint32_t sample_count)
-{
- Random* plugin = (Random*)instance;
+ const float smth = f_clip(smooth[s * plugin->smooth_is_cv],
+ 0.0f, 1.0f);
- /* Frequency (Hz) (float value) */
- const float frequency = *(plugin->frequency);
-
- /* Wave smoothness (array of floats of length sample_count) */
- const float* smooth = plugin->smooth;
-
- /* Output (pointer to float value) */
- float* output = plugin->output;
-
- /* Instance data */
- float nyquist = plugin->nyquist;
- float inv_nyquist = plugin->inv_nyquist;
- float phase = plugin->phase;
- float value1 = plugin->value1;
- float value2 = plugin->value2;
-
- float phase_scale = f_clip(frequency, 0.0f, nyquist) * inv_nyquist;
- float smth;
- float interval;
- float result;
-
- for (uint32_t s = 0; s < sample_count; ++s) {
- smth = f_clip(smooth[s], 0.0f, 1.0f);
- interval = (1.0f - smth) * 0.5f;
+ const float interval = (1.0f - smth) * 0.5f;
if (phase < interval) {
result = 1.0f;
@@ -259,7 +181,7 @@ runRandom_fcsa_oa(LV2_Handle instance,
output[s] = result;
- phase += phase_scale;
+ phase += freq * inv_nyquist;
if (phase > 1.0f) {
phase -= 1.0f;
value1 = value2;
@@ -272,70 +194,25 @@ runRandom_fcsa_oa(LV2_Handle instance,
plugin->value2 = value2;
}
-static void
-runRandom_fcsc_oa(LV2_Handle instance,
- uint32_t sample_count)
+static const void*
+extension_data(const char* uri)
{
- Random* plugin = (Random*)instance;
-
- /* Frequency (Hz) (float value) */
- const float frequency = *(plugin->frequency);
-
- /* Wave smoothness (float value) */
- const float smooth = f_clip(*(plugin->smooth), 0.0f, 1.0f);
-
- /* Output (array of floats of length sample_count) */
- float* output = plugin->output;
-
- /* Instance data */
- float nyquist = plugin->nyquist;
- float inv_nyquist = plugin->inv_nyquist;
- float phase = plugin->phase;
- float value1 = plugin->value1;
- float value2 = plugin->value2;
-
- float phase_scale = f_clip(frequency, 0.0f, nyquist) * inv_nyquist;
- float interval = (1.0f - smooth) * 0.5f;
- float result;
-
- for (uint32_t s = 0; s < sample_count; ++s) {
- if (phase < interval) {
- result = 1.0f;
- } else if (phase > (1.0f - interval)) {
- result = -1.0f;
- } else if (interval > 0.0f) {
- result = COSF((phase - interval) / smooth * M_PI);
- } else {
- result = COSF(phase * M_PI);
- }
-
- result *= (value2 - value1) * 0.5f;
- result -= (value2 + value1) * 0.5f;
-
- output[s] = result;
-
- phase += phase_scale;
- if (phase > 1.0f) {
- phase -= 1.0f;
- value1 = value2;
- value2 = (float)rand() * inv_rand_max - 1.0f;
- }
+ static const LV2_Morph_Interface morph = { morph_port, NULL };
+ if (!strcmp(uri, LV2_MORPH__interface)) {
+ return &morph;
}
-
- plugin->phase = phase;
- plugin->value1 = value1;
- plugin->value2 = value2;
+ return NULL;
}
static const LV2_Descriptor descriptor = {
- "http://drobilla.net/plugins/blip/random",
+ "http://drobilla.net/plugins/blop/random",
instantiate,
connect_port,
activate,
- runRandom_fcsc_oa,
+ run,
NULL,
cleanup,
- NULL,
+ extension_data,
};
LV2_SYMBOL_EXPORT const LV2_Descriptor*
diff --git a/src/ratio.c b/src/ratio.c
index 4659f4f..0bb3f1f 100644
--- a/src/ratio.c
+++ b/src/ratio.c
@@ -18,18 +18,24 @@
*/
#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
#include "math_func.h"
#include "common.h"
+#include "uris.h"
#define RATIO_NUMERATOR 0
#define RATIO_DENOMINATOR 1
#define RATIO_OUTPUT 2
typedef struct {
- float* numerator;
- float* denominator;
- float* output;
+ float* numerator;
+ float* denominator;
+ float* output;
+ uint32_t numerator_is_cv;
+ uint32_t denominator_is_cv;
+ uint32_t output_is_cv;
+ URIs uris;
} Ratio;
static void
@@ -58,6 +64,51 @@ 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)
+{
+ Ratio* plugin = (Ratio*)instance;
+
+ if (type != plugin->uris.lv2_ControlPort &&
+ type != plugin->uris.lv2_CVPort) {
+ return LV2_MORPH_ERR_BAD_TYPE;
+ }
+
+ switch (port) {
+ case RATIO_NUMERATOR:
+ plugin->numerator_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ case RATIO_DENOMINATOR:
+ plugin->denominator_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ return LV2_MORPH_ERR_BAD_PORT;
+ }
+
+ plugin->output_is_cv = plugin->numerator_is_cv || plugin->denominator_is_cv;
+ return LV2_MORPH_SUCCESS;
+}
+
+static LV2_URID
+port_type(LV2_Handle instance,
+ uint32_t port,
+ LV2_Morph_Property*const* properties)
+{
+ Ratio* plugin = (Ratio*)instance;
+
+ switch (port) {
+ case RATIO_OUTPUT:
+ return (plugin->output_is_cv
+ ? plugin->uris.lv2_CVPort
+ : plugin->uris.lv2_ControlPort);
+ default:
+ return 0;
+ }
+}
+
static LV2_Handle
instantiate(const LV2_Descriptor* descriptor,
double sample_rate,
@@ -66,12 +117,20 @@ instantiate(const LV2_Descriptor* descriptor,
{
Ratio* plugin = (Ratio*)malloc(sizeof(Ratio));
+ if (plugin) {
+ plugin->numerator_is_cv = 0;
+ plugin->denominator_is_cv = 0;
+ plugin->output_is_cv = 0;
+
+ map_uris(&plugin->uris, features);
+ }
+
return (LV2_Handle)plugin;
}
static void
-runRatio_nada_oa(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
Ratio* plugin = (Ratio*)instance;
@@ -84,90 +143,39 @@ runRatio_nada_oa(LV2_Handle instance,
/* Output (array of floats of length sample_count) */
float* output = plugin->output;
- for (uint32_t s = 0; s < sample_count; ++s) {
- const float n = numerator[s];
- float d = denominator[s];
-
- d = COPYSIGNF(f_max(FABSF(d), 1e-16f), d);
-
- output[s] = n / d;
+ if (!plugin->output_is_cv) { /* TODO: Avoid this branch */
+ sample_count = 1;
}
-}
-
-static void
-runRatio_nadc_oa(LV2_Handle instance,
- uint32_t sample_count)
-{
- Ratio* plugin = (Ratio*)instance;
-
- /* Numerator (array of floats of length sample_count) */
- const float* numerator = plugin->numerator;
-
- /* Denominator (float value) */
- float denominator = *(plugin->denominator);
-
- /* Output (array of floats of length sample_count) */
- float* output = plugin->output;
-
- denominator = COPYSIGNF(f_max(FABSF(denominator), 1e-16f), denominator);
for (uint32_t s = 0; s < sample_count; ++s) {
- output[s] = numerator[s] / denominator;
- }
-}
-
-static void
-runRatio_ncda_oa(LV2_Handle instance,
- uint32_t sample_count)
-{
- Ratio* plugin = (Ratio*)instance;
+ const float n = numerator[s * plugin->numerator_is_cv];
+ float d = denominator[s * plugin->denominator_is_cv];
- /* Numerator (float value) */
- const float numerator = *(plugin->numerator);
-
- /* Denominator (array of floats of length sample_count) */
- const float* denominator = plugin->denominator;
-
- /* Output (array of floats of length sample_count) */
- float* output = plugin->output;
-
- for (uint32_t s = 0; s < sample_count; ++s) {
- float d = denominator[s];
d = COPYSIGNF(f_max(FABSF(d), 1e-16f), d);
- output[s] = numerator / d;
+ output[s] = n / d;
}
}
-static void
-runRatio_ncdc_oc(LV2_Handle instance,
- uint32_t sample_count)
+static const void*
+extension_data(const char* uri)
{
- Ratio* plugin = (Ratio*)instance;
-
- /* Numerator (float value) */
- const float numerator = *(plugin->numerator);
-
- /* Denominator (float value) */
- float denominator = *(plugin->denominator);
-
- /* Output Frequency (pointer to float value) */
- float* output = plugin->output;
-
- denominator = COPYSIGNF(f_max(FABSF(denominator), 1e-16f), denominator);
-
- output[0] = numerator / denominator;
+ static const LV2_Morph_Interface morph = { morph_port, port_type };
+ if (!strcmp(uri, LV2_MORPH__interface)) {
+ return &morph;
+ }
+ return NULL;
}
static const LV2_Descriptor descriptor = {
- "http://drobilla.net/plugins/blip/ratio",
+ "http://drobilla.net/plugins/blop/ratio",
instantiate,
connect_port,
NULL,
- runRatio_nada_oa,
+ run,
NULL,
cleanup,
- NULL,
+ extension_data,
};
LV2_SYMBOL_EXPORT const LV2_Descriptor*
diff --git a/src/sawtooth.c b/src/sawtooth.c
index 3c242e1..35db21f 100644
--- a/src/sawtooth.c
+++ b/src/sawtooth.c
@@ -18,7 +18,9 @@
*/
#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "uris.h"
#include "wavedata.h"
#define SAWTOOTH_FREQUENCY 0
@@ -28,7 +30,9 @@ typedef struct {
float* frequency;
float* output;
float phase;
+ uint32_t frequency_is_cv;
Wavedata wdat;
+ URIs uris;
} Sawtooth;
static void
@@ -48,6 +52,23 @@ 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)
+{
+ Sawtooth* plugin = (Sawtooth*)instance;
+ if (type == plugin->uris.lv2_ControlPort) {
+ plugin->frequency_is_cv = 0;
+ } else if (type == plugin->uris.lv2_CVPort) {
+ plugin->frequency_is_cv = 1;
+ } else {
+ return LV2_MORPH_ERR_BAD_TYPE;
+ }
+ return LV2_MORPH_SUCCESS;
+}
+
static LV2_Handle
instantiate(const LV2_Descriptor* descriptor,
double sample_rate,
@@ -55,6 +76,9 @@ instantiate(const LV2_Descriptor* descriptor,
const LV2_Feature* const* features)
{
Sawtooth* plugin = (Sawtooth*)malloc(sizeof(Sawtooth));
+ if (!plugin) {
+ return NULL;
+ }
if (wavedata_load(&plugin->wdat, bundle_path, "sawtooth_data",
BLOP_DLSYM_SAWTOOTH, sample_rate)) {
@@ -62,6 +86,10 @@ instantiate(const LV2_Descriptor* descriptor,
return 0;
}
+ plugin->frequency_is_cv = 0;
+ map_uris(&plugin->uris, features);
+ wavedata_get_table(&plugin->wdat, 440.0);
+
return (LV2_Handle)plugin;
}
@@ -83,12 +111,12 @@ activate(LV2_Handle instance)
}
static void
-runSawtooth_fa_oa(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
Sawtooth* plugin = (Sawtooth*)instance;
- /* Frequency (array of float of length sample_count) */
+ /* Frequency (array of float of length 1 or sample_count) */
const float* frequency = plugin->frequency;
/* Output (pointer to float value) */
@@ -99,8 +127,11 @@ runSawtooth_fa_oa(LV2_Handle instance,
float phase = plugin->phase;
for (uint32_t s = 0; s < sample_count; s++) {
- /* Lookup table to play */
- wavedata_get_table(wdat, frequency[s]);
+ 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);
+ }
output[s] = wavedata_get_sample(wdat, phase);
@@ -115,47 +146,25 @@ runSawtooth_fa_oa(LV2_Handle instance,
plugin->phase = phase;
}
-static void
-runSawtooth_fc_oa(LV2_Handle instance,
- uint32_t sample_count)
+static const void*
+extension_data(const char* uri)
{
- Sawtooth* plugin = (Sawtooth*)instance;
-
- /* Frequency (float value) */
- const float frequency = *(plugin->frequency);
-
- /* Output (pointer to float value) */
- float* output = plugin->output;
-
- /* Instance data */
- Wavedata* wdat = &plugin->wdat;
- float phase = plugin->phase;
-
- wavedata_get_table(wdat, frequency);
-
- for (uint32_t s = 0; s < sample_count; s++) {
- output[s] = wavedata_get_sample(wdat, phase);
-
- /* 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/sawtooth",
+ "http://drobilla.net/plugins/blop/sawtooth",
instantiate,
connect_port,
activate,
- runSawtooth_fc_oa,
+ run,
NULL,
cleanup,
- NULL,
+ extension_data,
};
LV2_SYMBOL_EXPORT const LV2_Descriptor*
diff --git a/src/sequencer.c b/src/sequencer.c
index ef22a8a..e5c97c7 100644
--- a/src/sequencer.c
+++ b/src/sequencer.c
@@ -94,6 +94,9 @@ instantiate(const LV2_Descriptor* descriptor,
const LV2_Feature* const* features)
{
Sequencer* plugin = (Sequencer*)malloc(sizeof(Sequencer));
+ if (!plugin) {
+ return NULL;
+ }
plugin->srate = (float)sample_rate;
plugin->inv_srate = 1.0f / plugin->srate;
@@ -113,8 +116,8 @@ activate(LV2_Handle instance)
}
static void
-runSequencer(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
Sequencer* plugin = (Sequencer*)instance;
@@ -145,7 +148,7 @@ runSequencer(LV2_Handle instance,
unsigned int step_index = plugin->step_index;
unsigned int loop_index = LRINTF(loop_steps);
- int rst = LRINTF(reset);
+ int rst = reset > 0.0f;
int i;
loop_index = loop_index == 0 ? 1 : loop_index;
@@ -191,3 +194,23 @@ runSequencer(LV2_Handle instance,
plugin->last_value = last_value;
plugin->step_index = step_index;
}
+
+static const LV2_Descriptor descriptor = {
+ SEQUENCER_URI,
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ NULL,
+ cleanup,
+ NULL
+};
+
+LV2_SYMBOL_EXPORT const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
diff --git a/src/square.c b/src/square.c
index fb78859..59dd22f 100644
--- a/src/square.c
+++ b/src/square.c
@@ -18,7 +18,9 @@
*/
#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "uris.h"
#include "wavedata.h"
#define SQUARE_FREQUENCY 0
@@ -28,7 +30,9 @@ typedef struct {
float* frequency;
float* output;
float phase;
+ uint32_t frequency_is_cv;
Wavedata wdat;
+ URIs uris;
} Square;
static void
@@ -48,6 +52,23 @@ 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)
+{
+ Square* plugin = (Square*)instance;
+ if (type == plugin->uris.lv2_ControlPort) {
+ plugin->frequency_is_cv = 0;
+ } else if (type == plugin->uris.lv2_CVPort) {
+ plugin->frequency_is_cv = 1;
+ } else {
+ return LV2_MORPH_ERR_BAD_TYPE;
+ }
+ return LV2_MORPH_SUCCESS;
+}
+
static LV2_Handle
instantiate(const LV2_Descriptor* descriptor,
double sample_rate,
@@ -55,6 +76,9 @@ instantiate(const LV2_Descriptor* descriptor,
const LV2_Feature* const* features)
{
Square* plugin = (Square*)malloc(sizeof(Square));
+ if (!plugin) {
+ return NULL;
+ }
if (wavedata_load(&plugin->wdat, bundle_path, "square_data",
BLOP_DLSYM_SQUARE, sample_rate)) {
@@ -62,6 +86,10 @@ instantiate(const LV2_Descriptor* descriptor,
return NULL;
}
+ plugin->frequency_is_cv = 0;
+ map_uris(&plugin->uris, features);
+ wavedata_get_table(&plugin->wdat, 440.0);
+
return (LV2_Handle)plugin;
}
@@ -83,8 +111,8 @@ activate(LV2_Handle instance)
}
static void
-runSquare_fa_oa(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
Square* plugin = (Square*)instance;
@@ -99,8 +127,11 @@ runSquare_fa_oa(LV2_Handle instance,
float phase = plugin->phase;
for (uint32_t s = 0; s < sample_count; ++s) {
- /* Get table to play */
- wavedata_get_table(wdat, frequency[s]);
+ 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);
+ }
/* Get interpolated sample */
output[s] = wavedata_get_sample(wdat, phase);
@@ -116,47 +147,25 @@ runSquare_fa_oa(LV2_Handle instance,
plugin->phase = phase;
}
-static void
-runSquare_fc_oa(LV2_Handle instance,
- uint32_t sample_count)
+static const void*
+extension_data(const char* uri)
{
- Square* plugin = (Square*)instance;
-
- /* Frequency (float value) */
- const float frequency = *(plugin->frequency);
-
- /* Output (pointer to float value) */
- float* output = plugin->output;
-
- /* Instance data */
- Wavedata* wdat = &plugin->wdat;
- float phase = plugin->phase;
-
- wavedata_get_table(wdat, frequency);
-
- for (uint32_t s = 0; s < sample_count; ++s) {
- output[s] = wavedata_get_sample(wdat, phase);
-
- /* 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/square",
+ "http://drobilla.net/plugins/blop/square",
instantiate,
connect_port,
activate,
- runSquare_fc_oa,
+ run,
NULL,
cleanup,
- NULL,
+ extension_data,
};
LV2_SYMBOL_EXPORT const LV2_Descriptor*
diff --git a/src/sum.c b/src/sum.c
index 2384d73..4eb9182 100644
--- a/src/sum.c
+++ b/src/sum.c
@@ -18,16 +18,22 @@
*/
#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "uris.h"
#define SUM_INPUT1 0
#define SUM_INPUT2 1
#define SUM_OUTPUT 2
typedef struct {
- float* input1;
- float* input2;
- float* output;
+ float* input1;
+ float* input2;
+ float* output;
+ uint32_t input1_is_cv;
+ uint32_t input2_is_cv;
+ uint32_t output_is_cv;
+ URIs uris;
} Sum;
static void
@@ -56,6 +62,51 @@ 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)
+{
+ Sum* plugin = (Sum*)instance;
+
+ if (type != plugin->uris.lv2_ControlPort &&
+ type != plugin->uris.lv2_CVPort) {
+ return LV2_MORPH_ERR_BAD_TYPE;
+ }
+
+ switch (port) {
+ case SUM_INPUT1:
+ plugin->input1_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ case SUM_INPUT2:
+ plugin->input2_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ default:
+ return LV2_MORPH_ERR_BAD_PORT;
+ }
+
+ plugin->output_is_cv = plugin->input1_is_cv || plugin->input2_is_cv;
+ return LV2_MORPH_SUCCESS;
+}
+
+static LV2_URID
+port_type(LV2_Handle instance,
+ uint32_t port,
+ LV2_Morph_Property*const* properties)
+{
+ Sum* plugin = (Sum*)instance;
+
+ switch (port) {
+ case SUM_OUTPUT:
+ return (plugin->output_is_cv
+ ? plugin->uris.lv2_CVPort
+ : plugin->uris.lv2_ControlPort);
+ default:
+ return 0;
+ }
+}
+
static LV2_Handle
instantiate(const LV2_Descriptor* descriptor,
double sample_rate,
@@ -64,12 +115,20 @@ instantiate(const LV2_Descriptor* descriptor,
{
Sum* plugin = (Sum*)malloc(sizeof(Sum));
+ if (plugin) {
+ plugin->input1_is_cv = 0;
+ plugin->input2_is_cv = 0;
+ plugin->output_is_cv = 0;
+
+ map_uris(&plugin->uris, features);
+ }
+
return (LV2_Handle)plugin;
}
static void
-runSum_iaia_oa(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
Sum* plugin = (Sum*)instance;
@@ -82,58 +141,36 @@ runSum_iaia_oa(LV2_Handle instance,
/* Output (array of floats of length sample_count) */
float* output = plugin->output;
- for (uint32_t s = 0; s < sample_count; ++s) {
- output[s] = input1[s] + input2[s];
+ if (!plugin->output_is_cv) { /* TODO: Avoid this branch */
+ sample_count = 1;
}
-}
-
-static void
-runSum_iaic_oa(LV2_Handle instance,
- uint32_t sample_count)
-{
- Sum* plugin = (Sum*)instance;
-
- /* First Input (array of floats of length sample_count) */
- const float* input1 = plugin->input1;
-
- /* Second Input (float value) */
- const float input2 = *(plugin->input2);
-
- /* Output (array of floats of length sample_count) */
- float* output = plugin->output;
for (uint32_t s = 0; s < sample_count; ++s) {
- output[s] = input1[s] + input2;
+ const float in1 = input1[s * plugin->input1_is_cv];
+ const float in2 = input2[s * plugin->input2_is_cv];
+ output[s] = in1 + in2;
}
}
-static void
-runSum_icic_oc(LV2_Handle instance,
- uint32_t sample_count)
+static const void*
+extension_data(const char* uri)
{
- Sum* plugin = (Sum*)instance;
-
- /* First Input (float value) */
- const float input1 = *(plugin->input1);
-
- /* Second Input (float value) */
- const float input2 = *(plugin->input2);
-
- /* Output (pointer to float value) */
- float* output = plugin->output;
-
- output[0] = input1 + input2;
+ static const LV2_Morph_Interface morph = { morph_port, port_type };
+ if (!strcmp(uri, LV2_MORPH__interface)) {
+ return &morph;
+ }
+ return NULL;
}
static const LV2_Descriptor descriptor = {
- "http://drobilla.net/plugins/blip/sum",
+ "http://drobilla.net/plugins/blop/sum",
instantiate,
connect_port,
NULL,
- runSum_iaia_oa,
+ run,
NULL,
cleanup,
- NULL,
+ extension_data,
};
LV2_SYMBOL_EXPORT const LV2_Descriptor*
diff --git a/src/sync_pulse.c b/src/sync_pulse.c
index 96f90c7..732faa9 100644
--- a/src/sync_pulse.c
+++ b/src/sync_pulse.c
@@ -19,7 +19,9 @@
*/
#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "uris.h"
#include "common.h"
#define SYNCPULSE_FREQUENCY 0
@@ -28,12 +30,15 @@
#define SYNCPULSE_OUTPUT 3
typedef struct {
- float* frequency;
- float* pulsewidth;
- float* gate;
- float* output;
- float srate;
- float phase;
+ float* frequency;
+ float* pulsewidth;
+ float* gate;
+ float* output;
+ float srate;
+ float phase;
+ uint32_t frequency_is_cv;
+ uint32_t pulsewidth_is_cv;
+ URIs uris;
} SyncPulse;
static void
@@ -65,6 +70,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)
+{
+ SyncPulse* plugin = (SyncPulse*)instance;
+
+ if (type != plugin->uris.lv2_ControlPort &&
+ type != plugin->uris.lv2_CVPort) {
+ return LV2_MORPH_ERR_BAD_TYPE;
+ }
+
+ switch (port) {
+ case SYNCPULSE_FREQUENCY:
+ plugin->frequency_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ case SYNCPULSE_PULSEWIDTH:
+ plugin->pulsewidth_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,
@@ -73,7 +105,12 @@ instantiate(const LV2_Descriptor* descriptor,
{
SyncPulse* plugin = (SyncPulse*)malloc(sizeof(SyncPulse));
- plugin->srate = (float)sample_rate;
+ if (plugin) {
+ plugin->srate = (float)sample_rate;
+ plugin->frequency_is_cv = 0;
+ plugin->pulsewidth_is_cv = 0;
+ map_uris(&plugin->uris, features);
+ }
return (LV2_Handle)plugin;
}
@@ -87,8 +124,8 @@ activate(LV2_Handle instance)
}
static void
-runSyncPulse_fapaga_oa(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
SyncPulse* plugin = (SyncPulse*)instance;
@@ -108,13 +145,11 @@ runSyncPulse_fapaga_oa(LV2_Handle instance,
float phase = plugin->phase;
float srate = plugin->srate;
- float freq;
- float pwidth;
-
for (uint32_t s = 0; s < sample_count; ++s) {
if (gate[s] > 0.0f) {
- freq = frequency[s];
- pwidth = f_clip(pulsewidth[s], 0.0f, 1.0f) * srate;
+ const float freq = frequency[s * plugin->frequency_is_cv];
+ const float pw = pulsewidth[s * plugin->pulsewidth_is_cv];
+ const float pwidth = f_clip(pw, 0.0f, 1.0f) * srate;
if (phase < pwidth) {
output[s] = 1.0f;
@@ -137,62 +172,25 @@ runSyncPulse_fapaga_oa(LV2_Handle instance,
plugin->phase = phase;
}
-static void
-runSyncPulse_fcpcga_oa(LV2_Handle instance,
- uint32_t sample_count)
+static const void*
+extension_data(const char* uri)
{
- SyncPulse* plugin = (SyncPulse*)instance;
-
- /* Frequency (float value) */
- const float frequency = *(plugin->frequency);
-
- /* Pulse Width (float value) */
- float pulsewidth = f_clip(*(plugin->pulsewidth), 0.0f, 1.0f);
-
- /* Gate (array of float of length sample_count) */
- const float* gate = plugin->gate;
-
- /* Output (pointer to float value) */
- float* output = plugin->output;
-
- /* Instance Data */
- float phase = plugin->phase;
- float srate = plugin->srate;
-
- pulsewidth *= srate;
-
- for (uint32_t s = 0; s < sample_count; ++s) {
- if (gate[s] > 0.0f) {
- if (phase < pulsewidth) {
- output[s] = 1.0f;
- } else {
- output[s] = -1.0f;
- }
-
- phase += frequency;
- if (phase < 0.0f) {
- phase += srate;
- } else if (phase > srate) {
- phase -= srate;
- }
- } else {
- output[s] = 0.0f;
- phase = 0.0f;
- }
+ 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/sync_pulse",
+ "http://drobilla.net/plugins/blop/sync_pulse",
instantiate,
connect_port,
activate,
- runSyncPulse_fcpcga_oa,
+ run,
NULL,
cleanup,
- NULL,
+ extension_data,
};
LV2_SYMBOL_EXPORT const LV2_Descriptor*
diff --git a/src/sync_square.c b/src/sync_square.c
index 51ceac5..19fbcc1 100644
--- a/src/sync_square.c
+++ b/src/sync_square.c
@@ -19,19 +19,23 @@
*/
#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "uris.h"
#define SYNCSQUARE_FREQUENCY 0
#define SYNCSQUARE_GATE 1
#define SYNCSQUARE_OUTPUT 2
typedef struct {
- float* frequency;
- float* gate;
- float* output;
- float srate;
- float nyquist;
- float phase;
+ float* frequency;
+ float* gate;
+ float* output;
+ float srate;
+ float nyquist;
+ float phase;
+ uint32_t frequency_is_cv;
+ URIs uris;
} SyncSquare;
static void
@@ -60,6 +64,31 @@ 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)
+{
+ SyncSquare* plugin = (SyncSquare*)instance;
+
+ switch (port) {
+ case SYNCSQUARE_FREQUENCY:
+ if (type == plugin->uris.lv2_ControlPort) {
+ plugin->frequency_is_cv = 0;
+ } else if (type == plugin->uris.lv2_CVPort) {
+ plugin->frequency_is_cv = 1;
+ } else {
+ return LV2_MORPH_ERR_BAD_TYPE;
+ }
+ return LV2_MORPH_SUCCESS;
+ default:
+ return LV2_MORPH_ERR_BAD_PORT;
+ }
+
+ return LV2_MORPH_SUCCESS;
+}
+
static LV2_Handle
instantiate(const LV2_Descriptor* descriptor,
double sample_rate,
@@ -67,9 +96,14 @@ instantiate(const LV2_Descriptor* descriptor,
const LV2_Feature* const* features)
{
SyncSquare* plugin = (SyncSquare*)malloc(sizeof(SyncSquare));
+ if (!plugin) {
+ return NULL;
+ }
- plugin->srate = (float)sample_rate;
- plugin->nyquist = (float)(sample_rate / 2);
+ plugin->srate = (float)sample_rate;
+ plugin->nyquist = (float)(sample_rate / 2.0f);
+ plugin->frequency_is_cv = 0;
+ map_uris(&plugin->uris, features);
return (LV2_Handle)plugin;
}
@@ -83,12 +117,12 @@ activate(LV2_Handle instance)
}
static void
-runSyncSquare_faga_oa(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
SyncSquare* plugin = (SyncSquare*)instance;
- /* Frequency (array of float of length sample_count) */
+ /* Frequency (array of float of length 1 or sample_count) */
const float* frequency = plugin->frequency;
/* Gate (array of float of length sample_count) */
@@ -102,11 +136,9 @@ runSyncSquare_faga_oa(LV2_Handle instance,
float srate = plugin->srate;
float nyquist = plugin->nyquist;
- float freq;
-
for (uint32_t s = 0; s < sample_count; ++s) {
if (gate[s] > 0.0f) {
- freq = frequency[s];
+ const float freq = frequency[s * plugin->frequency_is_cv];
if (phase < nyquist) {
output[s] = 1.0f;
@@ -129,58 +161,25 @@ runSyncSquare_faga_oa(LV2_Handle instance,
plugin->phase = phase;
}
-static void
-runSyncSquare_fcga_oa(LV2_Handle instance,
- uint32_t sample_count)
+static const void*
+extension_data(const char* uri)
{
- SyncSquare* plugin = (SyncSquare*)instance;
-
- /* Frequency (float value) */
- const float frequency = *(plugin->frequency);
-
- /* Gate (array of float of length sample_count) */
- const float* gate = plugin->gate;
-
- /* Output (pointer to float value) */
- float* output = plugin->output;
-
- /* Instance Data */
- float phase = plugin->phase;
- float srate = plugin->srate;
- float nyquist = plugin->nyquist;
-
- for (uint32_t s = 0; s < sample_count; ++s) {
- if (gate[s] > 0.0f) {
- if (phase < nyquist) {
- output[s] = 1.0f;
- } else {
- output[s] = -1.0f;
- }
-
- phase += frequency;
- if (phase < 0.0f) {
- phase += srate;
- } else if (phase > srate) {
- phase -= srate;
- }
- } else {
- output[s] = 0.0f;
- phase = 0.0f;
- }
+ 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/sync_square",
+ "http://drobilla.net/plugins/blop/sync_square",
instantiate,
connect_port,
activate,
- runSyncSquare_fcga_oa,
+ run,
NULL,
cleanup,
- NULL,
+ extension_data,
};
LV2_SYMBOL_EXPORT const LV2_Descriptor*
diff --git a/src/tracker.c b/src/tracker.c
index cb93bf8..0df74df 100644
--- a/src/tracker.c
+++ b/src/tracker.c
@@ -18,8 +18,10 @@
*/
#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
#include "common.h"
+#include "uris.h"
#define TRACKER_GATE 0
#define TRACKER_HATTACK 1
@@ -30,15 +32,20 @@
#define TRACKER_OUTPUT 6
typedef struct {
- float* gate;
- float* hattack;
- float* hdecay;
- float* lattack;
- float* ldecay;
- float* input;
- float* output;
- float coeff;
- float last_value;
+ float* gate;
+ float* hattack;
+ float* hdecay;
+ float* lattack;
+ float* ldecay;
+ float* input;
+ float* output;
+ float coeff;
+ float last_value;
+ uint32_t hattack_is_cv;
+ uint32_t hdecay_is_cv;
+ uint32_t lattack_is_cv;
+ uint32_t ldecay_is_cv;
+ URIs uris;
} Tracker;
static void
@@ -79,6 +86,39 @@ 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)
+{
+ Tracker* plugin = (Tracker*)instance;
+
+ if (type != plugin->uris.lv2_ControlPort &&
+ type != plugin->uris.lv2_CVPort) {
+ return LV2_MORPH_ERR_BAD_TYPE;
+ }
+
+ switch (port) {
+ case TRACKER_HATTACK:
+ plugin->hattack_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ case TRACKER_HDECAY:
+ plugin->hdecay_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ case TRACKER_LATTACK:
+ plugin->lattack_is_cv = (type == plugin->uris.lv2_CVPort);
+ break;
+ case TRACKER_LDECAY:
+ plugin->ldecay_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,
@@ -86,9 +126,19 @@ instantiate(const LV2_Descriptor* descriptor,
const LV2_Feature* const* features)
{
Tracker* plugin = (Tracker*)malloc(sizeof(Tracker));
+ if (!plugin) {
+ return NULL;
+ }
plugin->coeff = 2.0f * M_PI / (float)sample_rate;
+ plugin->hattack_is_cv = 0;
+ plugin->hdecay_is_cv = 0;
+ plugin->lattack_is_cv = 0;
+ plugin->ldecay_is_cv = 0;
+
+ map_uris(&plugin->uris, features);
+
return (LV2_Handle)plugin;
}
@@ -101,24 +151,24 @@ activate(LV2_Handle instance)
}
static void
-runTracker_gaaadaia_oa(LV2_Handle instance,
- uint32_t sample_count)
+run(LV2_Handle instance,
+ uint32_t sample_count)
{
Tracker* plugin = (Tracker*)instance;
/* Gate (array of floats of length sample_count) */
const float* gate = plugin->gate;
- /* Gate High Attack Rate (array of floats of length sample_count) */
+ /* Gate High Attack Rate (array of floats of length 1 or sample_count) */
const float* hattack = plugin->hattack;
- /* Gate High Decay Rate (array of floats of length sample_count) */
+ /* Gate High Decay Rate (array of floats of length 1 or sample_count) */
const float* hdecay = plugin->hdecay;
- /* Gate Low Attack Rate (array of floats of length sample_count) */
+ /* Gate Low Attack Rate (array of floats of length 1 or sample_count) */
const float* lattack = plugin->lattack;
- /* Gate Low Decay Rate (array of floats of length sample_count) */
+ /* Gate Low Decay Rate (array of floats of length 1 or sample_count) */
const float* ldecay = plugin->ldecay;
/* Input (array of floats of length sample_count) */
@@ -131,16 +181,18 @@ runTracker_gaaadaia_oa(LV2_Handle instance,
float coeff = plugin->coeff;
float last_value = plugin->last_value;
- float rate;
- float in;
-
for (uint32_t s = 0; s < sample_count; ++s) {
- in = input[s];
+ const float in = input[s];
+ const float ha = hattack[s * plugin->hattack_is_cv];
+ const float hd = hdecay[s * plugin->hdecay_is_cv];
+ const float la = lattack[s * plugin->lattack_is_cv];
+ const float ld = ldecay[s * plugin->ldecay_is_cv];
+ float rate;
if (gate[s] > 0.0f) {
- rate = in > last_value ? hattack[s] : hdecay[s];
+ rate = in > last_value ? ha : hd;
} else {
- rate = in > last_value ? lattack[s] : ldecay[s];
+ rate = in > last_value ? la : ld;
}
rate = f_min(1.0f, rate * coeff);
@@ -152,71 +204,25 @@ runTracker_gaaadaia_oa(LV2_Handle instance,
plugin->last_value = last_value;
}
-static void
-runTracker_gaacdcia_oa(LV2_Handle instance,
- uint32_t sample_count)
+static const void*
+extension_data(const char* uri)
{
- Tracker* plugin = (Tracker*)instance;
-
- /* Gate (array of floats of length sample_count) */
- const float* gate = plugin->gate;
-
- /* Gate High Attack Rate (float value) */
- float hattack = *(plugin->hattack);
-
- /* Gate High Decay Rate (float value) */
- float hdecay = *(plugin->hdecay);
-
- /* Gate Low Attack Rate (float value) */
- float lattack = *(plugin->lattack);
-
- /* Gate Low Decay Rate (float value) */
- float ldecay = *(plugin->ldecay);
-
- /* Input (array of floats of length sample_count) */
- const float* input = plugin->input;
-
- /* Output (array of floats of length sample_count) */
- float* output = plugin->output;
-
- /* Instance Data */
- float coeff = plugin->coeff;
- float last_value = plugin->last_value;
-
- float in;
- float rate;
-
- hattack = f_min(1.0f, hattack * coeff);
- hdecay = f_min(1.0f, hdecay * coeff);
- lattack = f_min(1.0f, lattack * coeff);
- ldecay = f_min(1.0f, ldecay * coeff);
-
- for (uint32_t s = 0; s < sample_count; ++s) {
- in = input[s];
-
- if (gate[s] > 0.0f) {
- rate = in > last_value ? hattack : hdecay;
- } else {
- rate = in > last_value ? lattack : ldecay;
- }
-
- last_value = last_value * (1.0f - rate) + in * rate;
-
- output[s] = last_value;
+ static const LV2_Morph_Interface morph = { morph_port, NULL };
+ if (!strcmp(uri, LV2_MORPH__interface)) {
+ return &morph;
}
-
- plugin->last_value = last_value;
+ return NULL;
}
static const LV2_Descriptor descriptor = {
- "http://drobilla.net/plugins/blip/tracker",
+ "http://drobilla.net/plugins/blop/tracker",
instantiate,
connect_port,
activate,
- runTracker_gaacdcia_oa,
+ run,
NULL,
cleanup,
- NULL,
+ extension_data,
};
LV2_SYMBOL_EXPORT const LV2_Descriptor*
diff --git a/src/triangle.c b/src/triangle.c
index 0a06f6c..f42e84c 100644
--- a/src/triangle.c
+++ b/src/triangle.c
@@ -18,7 +18,9 @@
*/
#include <stdlib.h>
+#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,
@@ -62,6 +94,9 @@ instantiate(const LV2_Descriptor* descriptor,
const LV2_Feature* const* features)
{
Triangle* plugin = (Triangle*)malloc(sizeof(Triangle));
+ if (!plugin) {
+ return NULL;
+ }
if (wavedata_load(&plugin->wdat, bundle_path, "parabola_data",
BLOP_DLSYM_PARABOLA, sample_rate)) {
@@ -72,6 +107,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 +134,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 +191,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*
diff --git a/src/wavedata.c b/src/wavedata.c
index ff955a1..e76047e 100644
--- a/src/wavedata.c
+++ b/src/wavedata.c
@@ -25,7 +25,7 @@
#include <stdlib.h>
#include <stdio.h>
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
-#include "blip_config.h"
+#include "blop_config.h"
#include "wavedata.h"
int
@@ -46,6 +46,7 @@ wavedata_load(Wavedata* w,
bundle_path, lib_name, BLIP_SHLIB_EXT);
void* handle = dlopen(lib_path, RTLD_NOW);
+ free(lib_path);
if (handle) {
int (*desc_func)(Wavedata*, unsigned long);
@@ -57,7 +58,6 @@ wavedata_load(Wavedata* w,
}
}
- free(lib_path);
return retval;
}
diff --git a/src/wdatutil.c b/src/wdatutil.c
index f7a277d..636981b 100644
--- a/src/wdatutil.c
+++ b/src/wdatutil.c
@@ -328,7 +328,7 @@ wavedata_write(Wavedata* w,
fprintf(wdat_fp, "int\n");
fprintf(
wdat_fp,
- "blip_get_%s (Wavedata * w, double sample_rate, const char* bundle_path, const LV2_Feature* const* features)\n",
+ "blop_get_%s (Wavedata * w, double sample_rate, const char* bundle_path, const LV2_Feature* const* features)\n",
data_name);
fprintf(wdat_fp, "{\n");
fprintf(wdat_fp, "\tWavetable * t;\n");
@@ -611,18 +611,18 @@ generate_parabola(float* samples,
float scale = 2.0f / (M_PI * M_PI);
unsigned long i;
unsigned long h;
- double mhf;
+ //double mhf;
double hf;
- double k;
- double m;
+ //double k;
+ //double m;
double phase;
double partial;
double sign;
if (gibbs_comp > 0.0f) {
/* Degree of Gibbs Effect compensation */
- mhf = (double)harmonics;
- k = M_PI * (double)gibbs_comp / mhf;
+ //mhf = (double)harmonics;
+ //k = M_PI * (double)gibbs_comp / mhf;
for (i = 0; i < sample_count; i++) {
samples[i] = 0.0f;
@@ -635,7 +635,7 @@ generate_parabola(float* samples,
/* Gibbs Effect compensation - Hamming window */
/* Modified slightly for smoother fade at highest frequencies */
- m = 0.54 + 0.46 * cos((hf - 0.5 / mhf) * k);
+ //m = 0.54 + 0.46 * cos((hf - 0.5 / mhf) * k);
for (i = 0; i < sample_count; i++) {
phase = (double)i * phase_scale;