aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/branch.c98
-rw-r--r--src/include/uris.h4
2 files changed, 97 insertions, 5 deletions
diff --git a/src/branch.c b/src/branch.c
index 5ec0fff..a4de320 100644
--- a/src/branch.c
+++ b/src/branch.c
@@ -1,7 +1,6 @@
/*
An LV2 plugin to split a signal into two.
- Copyright 2011 David Robillard
-
+ Copyright 2011-2014 David Robillard
Copyright 2002 Mike Rawes
This is free software: you can redistribute it and/or modify it
@@ -18,8 +17,13 @@
along with this software. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <stdio.h>
+
#include <stdlib.h>
+#include "lv2/lv2plug.in/ns/ext/morph/morph.h"
+#include "lv2/lv2plug.in/ns/ext/options/options.h"
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
+#include "uris.h"
#define BRANCH_INPUT 0
#define BRANCH_OUTPUT1 1
@@ -29,6 +33,8 @@ typedef struct {
const float* input;
float* output1;
float* output2;
+ LV2_URID input_type;
+ URIs uris;
} Branch;
static void
@@ -57,6 +63,63 @@ connect_port(LV2_Handle instance,
}
}
+static uint32_t
+options_set(LV2_Handle instance,
+ const LV2_Options_Option* options)
+{
+ Branch* plugin = (Branch*)instance;
+ uint32_t ret = 0;
+ for (const LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT) {
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else if (o->type != plugin->uris.atom_URID) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ } else {
+ LV2_URID port_type = *(const LV2_URID*)(o->value);
+ if (port_type != plugin->uris.lv2_AudioPort &&
+ port_type != plugin->uris.lv2_CVPort &&
+ port_type != plugin->uris.lv2_ControlPort) {
+ ret |= LV2_OPTIONS_ERR_BAD_VALUE;
+ continue;
+ }
+ switch (o->subject) {
+ case BRANCH_INPUT:
+ plugin->input_type = port_type;
+ break;
+ default:
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ }
+ }
+ }
+ return ret;
+}
+
+static uint32_t
+options_get(LV2_Handle instance,
+ LV2_Options_Option* options)
+{
+ const Branch* plugin = (const Branch*)instance;
+ uint32_t ret = 0;
+ for (LV2_Options_Option* o = options; o->key; ++o) {
+ if (o->context != LV2_OPTIONS_PORT &&
+ o->subject != BRANCH_OUTPUT1 &&
+ o->subject != BRANCH_OUTPUT2) {
+ fprintf(stderr, "Bad subject %d\n", o->subject);
+ ret |= LV2_OPTIONS_ERR_BAD_SUBJECT;
+ } else if (o->key != plugin->uris.morph_currentType) {
+ fprintf(stderr, "Bad key %d\n", o->subject);
+ ret |= LV2_OPTIONS_ERR_BAD_KEY;
+ } else {
+ o->size = sizeof(LV2_URID);
+ o->type = plugin->uris.atom_URID;
+ o->value = &plugin->input_type;
+ }
+ }
+ return ret;
+}
+
static LV2_Handle
instantiate(const LV2_Descriptor* descriptor,
double sample_rate,
@@ -65,6 +128,9 @@ instantiate(const LV2_Descriptor* descriptor,
{
Branch* plugin = (Branch*)malloc(sizeof(Branch));
+ map_uris(&plugin->uris, features);
+ plugin->input_type = plugin->uris.lv2_ControlPort;
+
return (LV2_Handle)plugin;
}
@@ -112,15 +178,39 @@ runBranch_ic_ococ(LV2_Handle instance,
output2[0] = input;
}
+static void
+run(LV2_Handle instance,
+ uint32_t sample_count)
+{
+ Branch* plugin = (Branch*)instance;
+
+ if (plugin->input_type == plugin->uris.lv2_AudioPort ||
+ plugin->input_type == plugin->uris.lv2_CVPort) {
+ runBranch_ia_oaoa(instance, sample_count);
+ } else {
+ runBranch_ic_ococ(instance, sample_count);
+ }
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ static const LV2_Options_Interface options = { options_get, options_set };
+ if (!strcmp(uri, LV2_OPTIONS__interface)) {
+ return &options;
+ }
+ return NULL;
+}
+
static const LV2_Descriptor descriptor = {
"http://drobilla.net/plugins/blop/branch",
instantiate,
connect_port,
NULL,
- runBranch_ic_ococ,
+ run,
NULL,
cleanup,
- NULL,
+ extension_data,
};
LV2_SYMBOL_EXPORT const LV2_Descriptor*
diff --git a/src/include/uris.h b/src/include/uris.h
index 9797e0e..0c35628 100644
--- a/src/include/uris.h
+++ b/src/include/uris.h
@@ -27,6 +27,7 @@
typedef struct {
LV2_URID atom_URID;
+ LV2_URID lv2_AudioPort;
LV2_URID lv2_CVPort;
LV2_URID lv2_ControlPort;
LV2_URID morph_currentType;
@@ -46,8 +47,9 @@ map_uris(URIs* uris,
if (map) {
uris->atom_URID = map->map(map->handle, LV2_ATOM__URID);
- uris->lv2_ControlPort = map->map(map->handle, LV2_CORE__ControlPort);
+ uris->lv2_AudioPort = map->map(map->handle, LV2_CORE__AudioPort);
uris->lv2_CVPort = map->map(map->handle, LV2_CORE__CVPort);
+ uris->lv2_ControlPort = map->map(map->handle, LV2_CORE__ControlPort);
uris->morph_currentType = map->map(map->handle, LV2_MORPH__currentType);
} else {
memset(uris, 0, sizeof(*uris));