aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHanspeter Portner <dev@open-music-kontrollers.ch>2015-06-19 00:45:57 +0200
committerHanspeter Portner <dev@open-music-kontrollers.ch>2015-06-19 00:45:57 +0200
commitcc0ba8ef5de469027ea3ead1dfc6659afda9652b (patch)
treeaf88cdad3b0a30f1684067c712ff79e08ed7f006
parentf97ba9906ba3f09f594c35f6dd24f3bd1bbf9ba4 (diff)
downloadsynthpod-cc0ba8ef5de469027ea3ead1dfc6659afda9652b.tar.xz
add cv2atom and atom2cv converter plugs.
-rw-r--r--plugins/CMakeLists.txt4
-rw-r--r--plugins/manifest.ttl.in16
-rw-r--r--plugins/synthpod.ttl78
-rw-r--r--plugins/synthpod_atom2cv.c155
-rw-r--r--plugins/synthpod_cv2atom.c170
-rw-r--r--plugins/synthpod_lv2.c4
-rw-r--r--plugins/synthpod_lv2.h4
7 files changed, 428 insertions, 3 deletions
diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
index 3df7a541..6a57f7ac 100644
--- a/plugins/CMakeLists.txt
+++ b/plugins/CMakeLists.txt
@@ -36,7 +36,9 @@ add_library(synthpod.lv2 MODULE
synthpod_stereo.c
synthpod_keyboard.c
synthpod_cv2control.c
- synthpod_control2cv.c)
+ synthpod_control2cv.c
+ synthpod_cv2atom.c
+ synthpod_atom2cv.c)
target_link_libraries(synthpod.lv2 synthpod.lib)
set_target_properties(synthpod.lv2 PROPERTIES PREFIX "" OUTPUT_NAME "synthpod")
install(TARGETS synthpod.lv2 DESTINATION ${SYNTHPOD_PLUGIN_DIR})
diff --git a/plugins/manifest.ttl.in b/plugins/manifest.ttl.in
index 50583a6a..bd748069 100644
--- a/plugins/manifest.ttl.in
+++ b/plugins/manifest.ttl.in
@@ -97,14 +97,26 @@ synthpod:keyboard_x11
ui:binary <synthpod_ui@LIB_EXT@> ;
rdfs:seeAlso <synthpod.ttl> .
-# CV2Control Keyboard
+# CV2Control
synthpod:cv2control
a lv2:Plugin ;
lv2:binary <synthpod@LIB_EXT@> ;
rdfs:seeAlso <synthpod.ttl> .
-# Control2CV Keyboard
+# Control2CV
synthpod:control2cv
a lv2:Plugin ;
lv2:binary <synthpod@LIB_EXT@> ;
rdfs:seeAlso <synthpod.ttl> .
+
+# CV2Atom
+synthpod:cv2atom
+ a lv2:Plugin ;
+ lv2:binary <synthpod@LIB_EXT@> ;
+ rdfs:seeAlso <synthpod.ttl> .
+
+# Atom2CV
+synthpod:atom2cv
+ a lv2:Plugin ;
+ lv2:binary <synthpod@LIB_EXT@> ;
+ rdfs:seeAlso <synthpod.ttl> .
diff --git a/plugins/synthpod.ttl b/plugins/synthpod.ttl
index 9a281799..60335b6c 100644
--- a/plugins/synthpod.ttl
+++ b/plugins/synthpod.ttl
@@ -419,3 +419,81 @@ synthpod:control2cv
lv2:name "CV Out" ;
pg:group synthpod:group_out ;
] .
+
+# CV2Atom Plugin
+synthpod:cv2atom
+ a lv2:Plugin ,
+ lv2:ConverterPlugin ;
+ doap:name "Synthpod CV2Atom" ;
+ doap:license lic:Artistic-2.0 ;
+ lv2:project proj:synthpod ;
+ lv2:requiredFeature bufsz:boundedBlockLength, urid:map ;
+ lv2:optionalFeature lv2:isLive , lv2:hardRTCapable ;
+
+ lv2:port [
+ # cv_in
+ a lv2:InputPort ,
+ lv2:CVPort ;
+ lv2:index 0 ;
+ lv2:symbol "cv_in" ;
+ lv2:name "CV In" ;
+ pg:group synthpod:group_in ;
+ ] , [
+ # type
+ a lv2:InputPort ,
+ lv2:ControlPort ;
+ lv2:index 1 ;
+ lv2:symbol "type" ;
+ lv2:name "Type" ;
+ pg:group synthpod:group_in ;
+ lv2:default 2 ;
+ lv2:minimum 0 ;
+ lv2:maximum 3 ;
+ lv2:portProperty lv2:integer, lv2:enumeration ;
+ lv2:scalePoint [ rdfs:label "Int" ; rdf:value 0 ] ;
+ lv2:scalePoint [ rdfs:label "Long" ; rdf:value 1 ] ;
+ lv2:scalePoint [ rdfs:label "Float" ; rdf:value 2 ] ;
+ lv2:scalePoint [ rdfs:label "Double" ; rdf:value 3 ] ;
+ ] , [
+ # control_out
+ a lv2:OutputPort ,
+ atom:AtomPort ;
+ atom:bufferType atom:Sequence ;
+ atom:supports atom:Int, atom:Long, atom:Float, atom:Double ;
+ lv2:index 2 ;
+ lv2:symbol "atom_out" ;
+ lv2:name "Atom Out" ;
+ lv2:designation lv2:control ;
+ pg:group synthpod:group_out ;
+ ] .
+
+# Atom2CV Plugin
+synthpod:atom2cv
+ a lv2:Plugin ,
+ lv2:ConverterPlugin ;
+ doap:name "Synthpod Atom2CV" ;
+ doap:license lic:Artistic-2.0 ;
+ lv2:project proj:synthpod ;
+ lv2:requiredFeature bufsz:boundedBlockLength, urid:map ;
+ lv2:optionalFeature lv2:isLive , lv2:hardRTCapable ;
+
+ lv2:port [
+ # control_out
+ a lv2:InputPort ,
+ atom:AtomPort ;
+ atom:bufferType atom:Sequence ;
+ atom:supports atom:Int, atom:Long, atom:Float, atom:Double ;
+ lv2:index 0 ;
+ lv2:symbol "atom_in" ;
+ lv2:name "Atom In" ;
+ lv2:designation lv2:control ;
+ pg:group synthpod:group_in ;
+ ] , [
+ # cv_out
+ a lv2:OutputPort ,
+ lv2:CVPort ;
+ lv2:index 1 ;
+ lv2:symbol "cv_out" ;
+ lv2:name "CV Out" ;
+ pg:group synthpod:group_out ;
+ ] .
diff --git a/plugins/synthpod_atom2cv.c b/plugins/synthpod_atom2cv.c
new file mode 100644
index 00000000..0a839a93
--- /dev/null
+++ b/plugins/synthpod_atom2cv.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2015 Hanspeter Portner (dev@open-music-kontrollers.ch)
+ *
+ * This is free software: you can redistribute it and/or modify
+ * it under the terms of the Artistic License 2.0 as published by
+ * The Perl Foundation.
+ *
+ * This source is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Artistic License 2.0 for more details.
+ *
+ * You should have received a copy of the Artistic License 2.0
+ * along the source as a COPYING file. If not, obtain it from
+ * http://www.perlfoundation.org/artistic_license_2_0.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <synthpod_lv2.h>
+
+#include <lv2/lv2plug.in/ns/ext/atom/atom.h>
+#include <lv2/lv2plug.in/ns/ext/atom/forge.h>
+#include <lv2/lv2plug.in/ns/ext/atom/util.h>
+#include <lv2/lv2plug.in/ns/ext/midi/midi.h>
+
+typedef struct _plughandle_t plughandle_t;
+
+struct _plughandle_t {
+ const LV2_Atom_Sequence *atom_in;
+ float *cv_out;
+ float last;
+
+ LV2_URID_Map *map;
+ LV2_Atom_Forge forge;
+};
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor, double rate,
+ const char *bundle_path, const LV2_Feature *const *features)
+{
+ plughandle_t *handle = calloc(1, sizeof(plughandle_t));
+ if(!handle)
+ return NULL;
+
+ for(int i=0; features[i]; i++)
+ {
+ if(!strcmp(features[i]->URI, LV2_URID__map))
+ handle->map = (LV2_URID_Map *)features[i]->data;
+ }
+
+ if(!handle->map)
+ {
+ free(handle);
+ return NULL;
+ }
+
+ lv2_atom_forge_init(&handle->forge, handle->map);
+
+ return handle;
+}
+
+static void
+connect_port(LV2_Handle instance, uint32_t port, void *data)
+{
+ plughandle_t *handle = instance;
+
+ switch(port)
+ {
+ case 0:
+ handle->atom_in = (const LV2_Atom_Sequence *)data;
+ break;
+ case 1:
+ handle->cv_out = (float *)data;
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ //plughandle_t *handle = instance;
+
+ // nothing
+}
+
+static void
+run(LV2_Handle instance, uint32_t nsamples)
+{
+ plughandle_t *handle = instance;
+
+ int i = 0;
+ LV2_ATOM_SEQUENCE_FOREACH(handle->atom_in, ev)
+ {
+ const LV2_Atom *atom = &ev->body;
+ float val;
+
+ if(atom->type == handle->forge.Int)
+ val = ((LV2_Atom_Int *)atom)->body;
+ else if(atom->type == handle->forge.Long)
+ val = ((LV2_Atom_Long *)atom)->body;
+ else if(atom->type == handle->forge.Float)
+ val = ((LV2_Atom_Float *)atom)->body;
+ else if(atom->type == handle->forge.Double)
+ val = ((LV2_Atom_Double *)atom)->body;
+ else
+ continue; // unsupported type
+
+ for( ; i<ev->time.frames; i++)
+ handle->cv_out[i] = handle->last;
+
+ handle->last = val;
+ }
+
+ for( ; i<nsamples; i++)
+ handle->cv_out[i] = handle->last;
+}
+
+static void
+deactivate(LV2_Handle instance)
+{
+ //plughandle_t *handle = instance;
+
+ // nothing
+}
+
+static void
+cleanup(LV2_Handle instance)
+{
+ plughandle_t *handle = instance;
+
+ free(handle);
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ return NULL;
+}
+
+const LV2_Descriptor synthpod_atom2cv = {
+ .URI = SYNTHPOD_ATOM2CV_URI,
+ .instantiate = instantiate,
+ .connect_port = connect_port,
+ .activate = activate,
+ .run = run,
+ .deactivate = deactivate,
+ .cleanup = cleanup,
+ .extension_data = extension_data
+};
diff --git a/plugins/synthpod_cv2atom.c b/plugins/synthpod_cv2atom.c
new file mode 100644
index 00000000..c6484cc9
--- /dev/null
+++ b/plugins/synthpod_cv2atom.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2015 Hanspeter Portner (dev@open-music-kontrollers.ch)
+ *
+ * This is free software: you can redistribute it and/or modify
+ * it under the terms of the Artistic License 2.0 as published by
+ * The Perl Foundation.
+ *
+ * This source is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * Artistic License 2.0 for more details.
+ *
+ * You should have received a copy of the Artistic License 2.0
+ * along the source as a COPYING file. If not, obtain it from
+ * http://www.perlfoundation.org/artistic_license_2_0.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <synthpod_lv2.h>
+
+#include <lv2/lv2plug.in/ns/ext/atom/atom.h>
+#include <lv2/lv2plug.in/ns/ext/atom/forge.h>
+#include <lv2/lv2plug.in/ns/ext/atom/util.h>
+#include <lv2/lv2plug.in/ns/ext/midi/midi.h>
+
+typedef struct _plughandle_t plughandle_t;
+
+struct _plughandle_t {
+ const float *cv_in;
+ const float *type;
+ LV2_Atom_Sequence *atom_out;
+ float last;
+
+ LV2_URID_Map *map;
+ LV2_Atom_Forge forge;
+};
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor, double rate,
+ const char *bundle_path, const LV2_Feature *const *features)
+{
+ plughandle_t *handle = calloc(1, sizeof(plughandle_t));
+ if(!handle)
+ return NULL;
+
+ for(int i=0; features[i]; i++)
+ {
+ if(!strcmp(features[i]->URI, LV2_URID__map))
+ handle->map = (LV2_URID_Map *)features[i]->data;
+ }
+
+ if(!handle->map)
+ {
+ free(handle);
+ return NULL;
+ }
+
+ lv2_atom_forge_init(&handle->forge, handle->map);
+
+ return handle;
+}
+
+static void
+connect_port(LV2_Handle instance, uint32_t port, void *data)
+{
+ plughandle_t *handle = instance;
+
+ switch(port)
+ {
+ case 0:
+ handle->cv_in = (const float *)data;
+ break;
+ case 1:
+ handle->type = (const float *)data;
+ break;
+ case 2:
+ handle->atom_out = (LV2_Atom_Sequence *)data;
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ //plughandle_t *handle = instance;
+
+ // nothing
+}
+
+static void
+run(LV2_Handle instance, uint32_t nsamples)
+{
+ plughandle_t *handle = instance;
+
+ int type = floor(*handle->type);
+
+ uint32_t capacity = handle->atom_out->atom.size;
+ LV2_Atom_Forge *forge = &handle->forge;
+ LV2_Atom_Forge_Frame frame;
+ lv2_atom_forge_set_buffer(forge, (uint8_t *)handle->atom_out, capacity);
+ lv2_atom_forge_sequence_head(forge, &frame, 0);
+
+ for(int i=0; i<nsamples; i++)
+ {
+ const float *val = &handle->cv_in[i];
+
+ if(*val != handle->last)
+ {
+ lv2_atom_forge_frame_time(forge, i);
+ switch(type)
+ {
+ case 0:
+ lv2_atom_forge_int(forge, floor(*val));
+ break;
+ case 1:
+ lv2_atom_forge_long(forge, floor(*val));
+ break;
+ case 2:
+ lv2_atom_forge_float(forge, *val);
+ break;
+ case 3:
+ lv2_atom_forge_double(forge, *val);
+ break;
+ }
+
+ handle->last = *val;
+ }
+ }
+
+ lv2_atom_forge_pop(forge, &frame);
+}
+
+static void
+deactivate(LV2_Handle instance)
+{
+ //plughandle_t *handle = instance;
+
+ // nothing
+}
+
+static void
+cleanup(LV2_Handle instance)
+{
+ plughandle_t *handle = instance;
+
+ free(handle);
+}
+
+static const void*
+extension_data(const char* uri)
+{
+ return NULL;
+}
+
+const LV2_Descriptor synthpod_cv2atom = {
+ .URI = SYNTHPOD_CV2ATOM_URI,
+ .instantiate = instantiate,
+ .connect_port = connect_port,
+ .activate = activate,
+ .run = run,
+ .deactivate = deactivate,
+ .cleanup = cleanup,
+ .extension_data = extension_data
+};
diff --git a/plugins/synthpod_lv2.c b/plugins/synthpod_lv2.c
index 0f976237..fc13ad60 100644
--- a/plugins/synthpod_lv2.c
+++ b/plugins/synthpod_lv2.c
@@ -32,6 +32,10 @@ lv2_descriptor(uint32_t index)
return &synthpod_cv2control;
case 3:
return &synthpod_control2cv;
+ case 4:
+ return &synthpod_cv2atom;
+ case 5:
+ return &synthpod_atom2cv;
default:
return NULL;
}
diff --git a/plugins/synthpod_lv2.h b/plugins/synthpod_lv2.h
index f59f924b..1f31fe71 100644
--- a/plugins/synthpod_lv2.h
+++ b/plugins/synthpod_lv2.h
@@ -34,11 +34,15 @@
#define SYNTHPOD_KEYBOARD_URI SYNTHPOD_URI"#keyboard"
#define SYNTHPOD_CV2CONTROL_URI SYNTHPOD_URI"#cv2control"
#define SYNTHPOD_CONTROL2CV_URI SYNTHPOD_URI"#control2cv"
+#define SYNTHPOD_CV2ATOM_URI SYNTHPOD_URI"#cv2atom"
+#define SYNTHPOD_ATOM2CV_URI SYNTHPOD_URI"#atom2cv"
extern const LV2_Descriptor synthpod_stereo;
extern const LV2_Descriptor synthpod_keyboard;
extern const LV2_Descriptor synthpod_cv2control;
extern const LV2_Descriptor synthpod_control2cv;
+extern const LV2_Descriptor synthpod_cv2atom;
+extern const LV2_Descriptor synthpod_atom2cv;
// common UI uris
#define SYNTHPOD_COMMON_EO_URI SYNTHPOD_URI"#common_eo"