[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 &microname = 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 &microname = std::string("N/A"))=0;
+    virtual plain_port_info_iface &audio_port(const std::string &id, const std::string &name, const std::string &microname = 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 &microname = 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 &microname = "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