[SCM] calf/master: + LV2: added context extension header + Framework: allow adding event ports, arbitrary RDF-related enhancements, failed attempt at code reuse in port information classes + Small modules: added Print To Console for events and (work-in-progress) for events in message context
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:37:39 UTC 2013
The following commit has been merged in the master branch:
commit 7ffe7c27b8f44ec70f1365c12671b8e83673fa44
Author: kfoltman <kfoltman at 78b06b96-2940-0410-b7fc-879d825d01d8>
Date: Mon Sep 29 21:08:06 2008 +0000
+ LV2: added context extension header
+ Framework: allow adding event ports, arbitrary RDF-related enhancements, failed attempt at code reuse in port information classes
+ Small modules: added Print To Console for events and (work-in-progress) for events in message context
git-svn-id: https://calf.svn.sourceforge.net/svnroot/calf/trunk@310 78b06b96-2940-0410-b7fc-879d825d01d8
diff --git a/src/calf/lv2_contexts.h b/src/calf/lv2_contexts.h
new file mode 100644
index 0000000..8fd2e43
--- /dev/null
+++ b/src/calf/lv2_contexts.h
@@ -0,0 +1,42 @@
+/* LV2 OSC Messages Extension
+ * Copyright (C) 2007 Dave Robillard <dave at drobilla.net>
+ *
+ * This header is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This header 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 GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef LV2_CONTEXTS_H
+#define LV2_CONTEXTS_H
+
+#define LV2_CONTEXTS_URI "http://lv2plug.in/ns/dev/context"
+
+#define LV2_CONTEXT_MESSAGE "http://lv2plug.in/ns/dev/context#MessageContext"
+
+#define LV2_CONTEXTS_SET_OUTPUT_WRITTEN(flags, index) \
+ ((uint8_t*)flags)[(index) / 8] |= 1 << ((index) % 8)
+
+#define LV2_CONTEXTS_UNSET_OUTPUT_WRITTEN(flags, index) \
+ ((uint8_t*)flags)[(index) / 8] &= ~(1 << ((index) % 8))
+
+#include "lv2.h"
+#include <stdbool.h>
+
+
+typedef struct {
+ bool (*message_run)(LV2_Handle instance, uint32_t* outputs_written);
+ void (*message_connect_port)(LV2_Handle instance, uint32_t port, void* data);
+} LV2MessageContext;
+
+
+#endif // LV2_CONTEXTS_H
diff --git a/src/calf/lv2wrap.h b/src/calf/lv2wrap.h
index b8c5837..8c2a562 100644
--- a/src/calf/lv2wrap.h
+++ b/src/calf/lv2wrap.h
@@ -6,6 +6,7 @@
#include <calf/lv2-midiport.h>
#include <calf/lv2_event.h>
#include <calf/lv2_uri_map.h>
+#include <calf/lv2_contexts.h>
namespace synth {
@@ -306,7 +307,7 @@ struct lv2_small_wrapper
}
static const void *cb_ext_data(const char *URI) {
- return NULL;
+ return Module::ext_data(URI);
}
};
diff --git a/src/calf/modulelist.h b/src/calf/modulelist.h
index 8bd3b3d..2c9e1b1 100644
--- a/src/calf/modulelist.h
+++ b/src/calf/modulelist.h
@@ -28,6 +28,8 @@
PER_SMALL_MODULE_ITEM(pulse_lfo, "pulse_lfo")
PER_SMALL_MODULE_ITEM(print_a, "print_a")
PER_SMALL_MODULE_ITEM(print_c, "print_c")
+ PER_SMALL_MODULE_ITEM(print_e, "print_e")
+ PER_SMALL_MODULE_ITEM(print_em, "print_em")
PER_SMALL_MODULE_ITEM(quadpower_a, "quadpower_a")
PER_SMALL_MODULE_ITEM(quadpower_c, "quadpower_c")
PER_SMALL_MODULE_ITEM(crossfader2_a, "crossfader2_a")
diff --git a/src/calf/modules_small.h b/src/calf/modules_small.h
index 474a22c..d61ea98 100644
--- a/src/calf/modules_small.h
+++ b/src/calf/modules_small.h
@@ -34,6 +34,7 @@ public:
inline void deactivate() {}
/// Set sample rate for the plugin
inline void set_sample_rate(uint32_t sr) { srate = sr; odsr = 1.0 / sr; }
+ static inline const void *ext_data(const char *URI) { return NULL; }
};
/// Templatized version useful when the number of inputs and outputs is small
diff --git a/src/calf/plugininfo.h b/src/calf/plugininfo.h
index c605f7d..099011b 100644
--- a/src/calf/plugininfo.h
+++ b/src/calf/plugininfo.h
@@ -27,14 +27,14 @@
namespace synth {
/// A sink to send information about an audio port
-struct audio_port_info_iface
+struct plain_port_info_iface
{
/// Called if it's an input port
- virtual audio_port_info_iface& input() { return *this; }
+ virtual plain_port_info_iface& input() { return *this; }
/// Called if it's an output port
- virtual audio_port_info_iface& output() { return *this; }
- virtual audio_port_info_iface& lv2_ttl(const std::string &text) { return *this; }
- virtual ~audio_port_info_iface() {}
+ virtual plain_port_info_iface& output() { return *this; }
+ virtual plain_port_info_iface& lv2_ttl(const std::string &text) { return *this; }
+ virtual ~plain_port_info_iface() {}
};
/// A sink to send information about a control port (very incomplete, missing stuff: units, integer, boolean, toggled, notAutomatic, notGUI...)
@@ -61,9 +61,13 @@ struct plugin_info_iface
/// Set plugin names (ID, name and label)
virtual void names(const std::string &name, const std::string &label, const std::string &category, const std::string µname = std::string()) {}
/// Add an audio port (returns a sink which accepts further description)
- virtual audio_port_info_iface &audio_port(const std::string &id, const std::string &name, const std::string µname = std::string("N/A"))=0;
+ virtual plain_port_info_iface &audio_port(const std::string &id, const std::string &name, const std::string µname = std::string("N/A"))=0;
+ /// Add an event port (returns a sink which accepts further description)
+ virtual plain_port_info_iface &event_port(const std::string &id, const std::string &name, const std::string µname = std::string("N/A"))=0;
/// Add a control port (returns a sink which accepts further description)
virtual control_port_info_iface &control_port(const std::string &id, const std::string &name, double def_value, const std::string µname = "N/A")=0;
+ /// Add arbitrary TTL clauses
+ virtual void lv2_ttl(const std::string &text) {}
/// Called after plugin has reported all the information
virtual void finalize() {}
virtual ~plugin_info_iface() {}
diff --git a/src/makerdf.cpp b/src/makerdf.cpp
index d2b220d..7952326 100644
--- a/src/makerdf.cpp
+++ b/src/makerdf.cpp
@@ -171,71 +171,92 @@ static void add_ctl_port(string &ports, parameter_properties &pp, int pidx, gifa
}
struct lv2_port_base {
- virtual std::string to_string() = 0;
- virtual ~lv2_port_base() {}
-};
-
-struct lv2_audio_port_info: public lv2_port_base, public audio_port_info_iface
-{
int index;
- string symbol, name, extras, microname;
+ std::string symbol, name, extras, microname;
bool is_input;
-
- lv2_audio_port_info(int _index, const std::string &_symbol, const std::string &_name, const std::string &_microname)
- : index(_index)
- , symbol(_symbol)
- , name(_name)
- , microname(_microname)
- , is_input(true)
+
+ virtual std::string to_string() = 0;
+ virtual ~lv2_port_base() {}
+ void to_stream_base(stringstream &ss, string ind, string port_class)
{
- }
- /// Called if it's an input port
- virtual audio_port_info_iface& input() { is_input = true; return *this; }
- /// Called if it's an output port
- virtual audio_port_info_iface& output() { is_input = false; return *this; }
- virtual audio_port_info_iface& lv2_ttl(const std::string &text) { extras += text; return *this; }
-
- std::string to_string() {
- stringstream ss;
- const char *ind = " ";
- ss << "[\n";
ss << ind << (is_input ? "a lv2:InputPort ;\n" : "a lv2:OutputPort ;\n");
- ss << ind << "a lv2:AudioPort ;\n";
+ ss << ind << "a " << port_class << " ;\n";
ss << ind << "lv2:index " << index << " ;\n";
ss << ind << "lv2:symbol \"" << symbol << "\" ;\n";
ss << ind << "lv2:name \"" << name << "\" ;\n";
if (!extras.empty())
- ss << ind << extras << endl;
+ ss << ind << extras;
if (microname != "N/A")
ss << ind << "<http://lv2plug.in/ns/dev/tiny-name> \"" << microname << "\" ;\n";
+ }
+};
+
+struct lv2_audio_port_base: public lv2_port_base
+{
+ std::string to_string() {
+ stringstream ss;
+ const char *ind = " ";
+ ss << "[\n";
+ to_stream_base(ss, ind, "lv2:AudioPort");
ss << " ]\n";
return ss.str();
}
};
-struct lv2_control_port_info: public lv2_port_base, public control_port_info_iface
+struct lv2_event_port_base: public lv2_port_base
+{
+ std::string to_string() {
+ stringstream ss;
+ const char *ind = " ";
+ ss << "[\n";
+ to_stream_base(ss, ind, "lv2ev:EventPort");
+ ss << " ]\n";
+
+ return ss.str();
+ }
+};
+
+template<class base_iface, class base_data>
+struct lv2_port_impl: public base_iface, public base_data
+{
+ lv2_port_impl(int _index, const std::string &_symbol, const std::string &_name, const std::string &_microname)
+ {
+ this->index = _index;
+ this->symbol = _symbol;
+ this->name = _name;
+ this->microname = _microname;
+ this->is_input = true;
+ }
+ /// Called if it's an input port
+ virtual base_iface& input() { this->is_input = true; return *this; }
+ /// Called if it's an output port
+ virtual base_iface& output() { this->is_input = false; return *this; }
+ virtual base_iface& lv2_ttl(const std::string &text) { this->extras += text + "\n"; return *this; }
+};
+
+struct lv2_control_port_base: public lv2_port_base
{
- int index;
- string symbol, name, extras, microname;
bool is_input, is_log, is_toggle, is_trigger, is_integer;
double min, max, def_value;
bool has_min, has_max;
- lv2_control_port_info(int _index, const std::string &_symbol, const std::string &_name, double _default, const std::string &_microname)
- : index(_index)
- , symbol(_symbol)
- , name(_name)
- , microname(_microname)
- , is_input(true)
- , def_value(_default)
+ lv2_control_port_base()
{
has_min = has_max = is_log = is_toggle = is_trigger = is_integer = false;
+ def_value = 0.f;
+ }
+};
+
+typedef lv2_port_impl<plain_port_info_iface, lv2_audio_port_base> lv2_audio_port_info;
+typedef lv2_port_impl<plain_port_info_iface, lv2_event_port_base> lv2_event_port_info;
+
+struct lv2_control_port_info: public lv2_port_impl<control_port_info_iface, lv2_control_port_base>
+{
+ lv2_control_port_info(int _index, const std::string &_symbol, const std::string &_name, const std::string &_microname)
+ : lv2_port_impl<control_port_info_iface, lv2_control_port_base>(_index, _symbol, _name, _microname)
+ {
}
- /// Called if it's an input port
- virtual control_port_info_iface& input() { is_input = true; return *this; }
- /// Called if it's an output port
- virtual control_port_info_iface& output() { is_input = false; return *this; }
/// Called to mark the port as using linear range [from, to]
virtual control_port_info_iface& lin_range(double from, double to) { min = from, max = to, has_min = true, has_max = true, is_log = false; return *this; }
/// Called to mark the port as using log range [from, to]
@@ -243,21 +264,12 @@ struct lv2_control_port_info: public lv2_port_base, public control_port_info_ifa
virtual control_port_info_iface& toggle() { is_toggle = true; return *this; }
virtual control_port_info_iface& trigger() { is_trigger = true; return *this; }
virtual control_port_info_iface& integer() { is_integer = true; return *this; }
- virtual control_port_info_iface& lv2_ttl(const std::string &text) { extras += text; return *this; }
+ virtual control_port_info_iface& lv2_ttl(const std::string &text) { extras += text + "\n"; return *this; }
std::string to_string() {
stringstream ss;
const char *ind = " ";
ss << "[\n";
- ss << ind << (is_input ? "a lv2:InputPort ;\n" : "a lv2:OutputPort ;\n");
- ss << ind << "a lv2:ControlPort ;\n";
- ss << ind << "lv2:index " << index << " ;\n";
- ss << ind << "lv2:symbol \"" << symbol << "\" ;\n";
- ss << ind << "lv2:name \"" << name << "\" ;\n";
- if (!extras.empty())
- ss << ind << extras << endl;
- if (microname != "N/A")
- ss << ind << "<http://lv2plug.in/ns/dev/tiny-name> \"" << microname << "\" ;\n";
-
+ to_stream_base(ss, ind, "lv2:ControlPort");
if (is_toggle)
ss << ind << "lv2:portProperty lv2:toggled ;\n";
if (is_integer)
@@ -286,6 +298,8 @@ struct lv2_plugin_info: public plugin_info_iface
std::string category;
/// Plugin micro-name
std::string microname;
+ /// Extra declarations for LV2
+ std::string extras;
/// Vector of ports
vector<lv2_port_base *> ports;
/// Set plugin names (ID, name and label)
@@ -296,17 +310,26 @@ struct lv2_plugin_info: public plugin_info_iface
microname = _microname;
}
/// Add an audio port (returns a sink which accepts further description)
- virtual audio_port_info_iface &audio_port(const std::string &id, const std::string &name, const std::string &_microname) {
+ virtual plain_port_info_iface &audio_port(const std::string &id, const std::string &name, const std::string &_microname) {
lv2_audio_port_info *port = new lv2_audio_port_info(ports.size(), id, name, _microname);
ports.push_back(port);
return *port;
}
+ /// Add an eventport (returns a sink which accepts further description)
+ virtual plain_port_info_iface &event_port(const std::string &id, const std::string &name, const std::string &_microname) {
+ lv2_event_port_info *port = new lv2_event_port_info(ports.size(), id, name, _microname);
+ ports.push_back(port);
+ return *port;
+ }
/// Add a control port (returns a sink which accepts further description)
virtual control_port_info_iface &control_port(const std::string &id, const std::string &name, double def_value, const std::string &_microname) {
- lv2_control_port_info *port = new lv2_control_port_info(ports.size(), id, name, def_value, _microname);
+ lv2_control_port_info *port = new lv2_control_port_info(ports.size(), id, name, _microname);
+ port->def_value = def_value;
ports.push_back(port);
return *port;
}
+ /// Add extra TTL to plugin declaration
+ virtual void lv2_ttl(const std::string &text) { this->extras += " " + text + "\n"; }
/// Called after plugin has reported all the information
virtual void finalize() {
}
@@ -334,6 +357,7 @@ void make_ttl(string path_prefix)
"@prefix uiext: <http://lv2plug.in/ns/extensions/ui#> .\n"
"@prefix lv2ev: <http://lv2plug.in/ns/ext/event#> .\n"
"@prefix lv2midi: <http://lv2plug.in/ns/ext/midi#> .\n"
+ "@prefix lv2ctx: <http://lv2plug.in/ns/dev/contexts#> .\n"
"@prefix pg: <http://ll-plugins.nongnu.org/lv2/ext/portgroups#> .\n"
"@prefix ue: <http://lv2plug.in/ns/extensions/units#> .\n"
"@prefix epp: <http://lv2plug.in/ns/dev/extportinfo#> .\n"
@@ -439,6 +463,7 @@ void make_ttl(string path_prefix)
ttl += " doap:license <http://usefulinc.com/doap/licenses/lgpl> ;\n";
if (!pi->microname.empty())
ttl += " <http://lv2plug.in/ns/dev/tiny-name> \"" + pi->microname + "\" ;\n";
+ ttl += pi->extras;
if (!pi->ports.empty())
{
diff --git a/src/modules_small.cpp b/src/modules_small.cpp
index d02bea0..758c0be 100644
--- a/src/modules_small.cpp
+++ b/src/modules_small.cpp
@@ -780,6 +780,71 @@ public:
}
};
+class print_e_audio_module: public small_audio_module_base<1, 0>
+{
+public:
+ static void plugin_info(plugin_info_iface *pii)
+ {
+ pii->names("print_e", "Print To Console (E)", "lv2:UtilityPlugin");
+ pii->event_port("in", "In").input();
+ }
+ void process(uint32_t)
+ {
+ LV2_Event_Buffer *event_data = (LV2_Event_Buffer *)ins[0];
+ uint8_t *data = event_data->data;
+ for(uint32_t i = 0; i < event_data->event_count; i++)
+ {
+ LV2_Event *event = (LV2_Event *)data;
+ printf("Event at %d.%d, type %d, size %d:", event->frames, event->subframes, (int)event->type, (int)event->size);
+ uint32_t size = std::min((uint16_t)16, event->size);
+
+ for (uint32_t j = 0; j < size; j++)
+ printf(" %02X", (uint32_t)data[12 + j]);
+ if (event->size > size)
+ printf("...\n");
+ else
+ printf("\n");
+ data += (event->size + 19) &~ 7;
+ }
+ }
+};
+
+class print_em_audio_module: public print_e_audio_module
+{
+public:
+ static void plugin_info(plugin_info_iface *pii)
+ {
+ pii->names("print_e", "Print To Console (EM)", "lv2:UtilityPlugin");
+ pii->lv2_ttl("lv2:requiredFeature <http://lv2plug.in/ns/dev/contexts> ;");
+ pii->lv2_ttl("lv2:requiredContext lv2ctx:MessageContext ;");
+ pii->event_port("in", "In").input().lv2_ttl("lv2ctx:context lv2ctx:MessageContext ;");
+ }
+ void process(uint32_t)
+ {
+ }
+ static bool message_run(LV2_Handle instance, uint32_t *outputs_written)
+ {
+ printf("message_run\n");
+ ((print_e_audio_module *)instance)->process(0);
+ *outputs_written = 0;
+ return false;
+ }
+ static void message_connect_port(LV2_Handle instance, uint32_t port, void* data)
+ {
+ printf("message_connect_port %d\n", port);
+ ((print_e_audio_module *)instance)->ins[port] = (float *)data;
+ }
+ static inline const void *ext_data(const char *URI) {
+ static LV2MessageContext ctx_ext_data = { message_run, message_connect_port };
+ if (!strcmp(URI, LV2_CONTEXT_MESSAGE))
+ {
+ printf("URI=%s\n", URI);
+ return &ctx_ext_data;
+ }
+ return NULL;
+ }
+};
+
class print_a_audio_module: public small_audio_module_base<1, 0>
{
public:
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list