[SCM] calf/master: + LV2: emit polymorphic port-related RDF for operator plugins, current port types API

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:38:46 UTC 2013


The following commit has been merged in the master branch:
commit 731384756257ca1376ba38e72aefc8b638f6dc53
Author: Krzysztof Foltman <wdev at foltman.com>
Date:   Wed Dec 31 13:55:01 2008 +0000

    + LV2: emit polymorphic port-related RDF for operator plugins, current port types API

diff --git a/src/calf/lv2helpers.h b/src/calf/lv2helpers.h
index 7f631b8..892f5b6 100644
--- a/src/calf/lv2helpers.h
+++ b/src/calf/lv2helpers.h
@@ -26,32 +26,48 @@
 #include <calf/lv2_event.h>
 #include <calf/lv2_uri_map.h>
 
-/// A mixin for adding the event feature and URI map to the small plugin
-template<class T>
-class event_mixin: public T
+class uri_map_access
 {
 public:
-    /// URI map feature pointer
+    /// URI map feature pointer (previously in a mixin, but polymorphic ports made it necessary for most plugins)
     LV2_URI_Map_Feature *uri_map;
-    /// Event feature pointer
-    LV2_Event_Feature *event_feature;
-    virtual uint32_t map_uri(const char *ns, const char *URI)
+
+    uri_map_access()
+    : uri_map(NULL)
+    {}
+
+    /// Map an URI through an URI map
+    uint32_t map_uri(const char *ns, const char *URI)
     {
-        return uri_map->uri_to_id(uri_map->callback_data, ns, URI);
+        if (uri_map)
+            return uri_map->uri_to_id(uri_map->callback_data, ns, URI);
+        return 0;
+    }
+    /// Called on instantiation for every LV2 feature sent by a host
+    void use_feature(const char *URI, void *data) {
+        if (!strcmp(URI, LV2_URI_MAP_URI))
+        {
+            uri_map = (LV2_URI_Map_Feature *)data;
+            map_uris();
+        }
     }
     virtual void map_uris()
     {
     }
+};
+    
+/// A mixin for adding the event feature and URI map to the small plugin
+template<class T>
+class event_mixin: public T
+{
+public:
+    /// Event feature pointer
+    LV2_Event_Feature *event_feature;
     virtual void use_feature(const char *URI, void *data) {
         if (!strcmp(URI, LV2_EVENT_URI))
         {
             event_feature = (LV2_Event_Feature *)data;
         }
-        if (!strcmp(URI, LV2_URI_MAP_URI))
-        {
-            uri_map = (LV2_URI_Map_Feature *)data;
-            map_uris();
-        }
         T::use_feature(URI, data);
     }
     /// Create a reference
@@ -70,6 +86,7 @@ public:
     virtual void map_uris() {
         midi_event_type = this->map_uri("http://lv2plug.in/ns/ext/event", "http://lv2plug.in/ns/ext/midi#MidiEvent");
         printf("MIDI event type = %d\n", midi_event_type);
+        event_mixin<T>::map_uris();
     }
 };
 
@@ -83,6 +100,7 @@ public:
     virtual void map_uris() {
         message_event_type = this->map_uri("http://lv2plug.in/ns/ext/event", "http://lv2plug.in/ns/dev/msg#MessageEvent");
         printf("Message event type = %d\n", message_event_type);
+        event_mixin<T>::map_uris();
     }
 };
 
diff --git a/src/calf/modules_small.h b/src/calf/modules_small.h
index 5c6b653..c28a1e7 100644
--- a/src/calf/modules_small.h
+++ b/src/calf/modules_small.h
@@ -23,28 +23,72 @@
 
 #if USE_LV2
 
-#include "giface.h"
+#include <lv2.h>
 #include "plugininfo.h"
-#include <string.h>
+#include "lv2_polymorphic_port.h"
+#include "lv2helpers.h"
 
 namespace calf_plugins {
 
-/// Empty implementations for plugin functions. Note, that functions aren't virtual, because they're called via the particular
-/// subclass via template wrappers (ladspa_small_wrapper<> etc), not via base class pointer/reference
-class null_small_audio_module
+/// Empty implementations for plugin functions. Note, that some functions aren't virtual, because they're called via the particular
+/// subclass via template wrappers (ladspa_small_wrapper<> etc), not via base class pointer/reference. On the other hand,
+/// other functions are virtual when overhead is acceptable (instantiation time functions etc.)
+class null_small_audio_module: public uri_map_access
 {
 public:
     uint32_t srate;
     double odsr;
+    uint32_t poly_type_control, poly_type_audio;
+    /// for polymorphic ports: "is audio" flags for first 32 ports (should be sufficient for most plugins)
+    uint32_t poly_port_types;
+
+    null_small_audio_module()
+    : srate((uint32_t)-1)
+    , odsr(0.)
+    , poly_type_control(0)
+    , poly_type_audio(0)
+    , poly_port_types(0)
+    {
+    }
+
+    /// Called when host changes type of the polymorphic port
+    inline void set_port_type(uint32_t port, uint32_t type, void *type_data) {
+        if (port >= 32)
+            return;
+        uint32_t port_mask = 1 << port;
+        if (type == poly_type_control)
+            poly_port_types &= ~port_mask;
+        else if (type == poly_type_audio)
+            poly_port_types |= port_mask;
+        on_port_types_changed();
+    }
+    
+    /// Returns 1 for audio ports and 0 for control ports
+    inline unsigned int port_is_audio(unsigned int port) {
+        return (poly_port_types >> port) & 1;
+    }
+        
+    /// Returns (unsigned)-1 for audio ports and 0 for control ports
+    inline unsigned int port_audio_mask(unsigned int port) {
+        return 0 - ((poly_port_types >> port) & 1);
+    }
+        
+    virtual void on_port_types_changed() {}
     inline void set_bundle_path(const char *path) {}
-    inline void use_features(const LV2_Feature *const *features) {
+    /// Called to map all the necessary URIs
+    virtual void map_uris()
+    {
+        poly_type_control = map_uri(LV2_POLYMORPHIC_PORT_URI, "http://lv2plug.in/ns/lv2core#ControlPort");
+        poly_type_audio = map_uri(LV2_POLYMORPHIC_PORT_URI, "http://lv2plug.in/ns/lv2core#AudioPort");
+    }
+    /// Called on instantiation with the list of LV2 features called
+    virtual void use_features(const LV2_Feature *const *features) {
         while(*features)
         {
             use_feature((*features)->URI, (*features)->data);
             features++;
         }
     }
-    virtual void use_feature(const char *URI, void *data) {}
     /// LADSPA-esque activate function, except it is called after ports are connected, not before
     inline void activate() {}
     /// LADSPA-esque deactivate function
@@ -72,7 +116,7 @@ struct lv2_small_wrapper
     typedef Module instance;
     static LV2_Descriptor descriptor;
     std::string uri;
-    char *types;
+    static uint32_t poly_port_types;
     
     lv2_small_wrapper(const char *id)
     {
@@ -86,10 +130,8 @@ struct lv2_small_wrapper
         descriptor.cleanup = cb_cleanup;
         descriptor.extension_data = cb_ext_data;
         
-        std::string types_tmp;
-        plugin_port_type_grabber ptg(types_tmp);
+        plugin_port_type_grabber ptg(poly_port_types);
         Module::plugin_info(&ptg);
-        types = strdup(types_tmp.c_str());
     }
 
     static void cb_connect(LV2_Handle Instance, uint32_t port, void *DataLocation) {
@@ -112,10 +154,18 @@ struct lv2_small_wrapper
         instance *const mod = (instance *)Instance;
         mod->deactivate();
     }
+    
+    static uint32_t cb_set_type(LV2_Handle Instance, uint32_t port, uint32_t type, void *type_data)
+    {
+        instance *const mod = (instance *)Instance;
+        mod->set_port_type(port, type, type_data);
+        return 0;
+    }
 
     static LV2_Handle cb_instantiate(const LV2_Descriptor * Descriptor, double sample_rate, const char *bundle_path, const LV2_Feature *const *features)
     {
         instance *mod = new instance();
+        mod->poly_port_types = poly_port_types;
         // XXXKF some people use fractional sample rates; we respect them ;-)
         mod->set_bundle_path(bundle_path);
         mod->use_features(features);
diff --git a/src/calf/plugininfo.h b/src/calf/plugininfo.h
index e934bcd..8f61137 100644
--- a/src/calf/plugininfo.h
+++ b/src/calf/plugininfo.h
@@ -52,6 +52,8 @@ struct control_port_info_iface
     virtual control_port_info_iface& trigger() { return *this; }
     virtual control_port_info_iface& integer() { return *this; }
     virtual control_port_info_iface& lv2_ttl(const std::string &text) { return *this; }
+    virtual control_port_info_iface& polymorphic() { return lv2_ttl("a poly:PolymorphicPort ;"); }
+    virtual control_port_info_iface& poly_audio() { return lv2_ttl("poly:supportsType lv2:AudioPort ;"); }
     virtual ~control_port_info_iface() {}
 };
 
@@ -77,34 +79,17 @@ struct plugin_info_iface
 
 struct plugin_port_type_grabber: public plugin_info_iface, public control_port_info_iface
 {
-    std::string &dest;
+    uint32_t ⌖
+    uint32_t index;
     
-    struct ppii: public plain_port_info_iface {
-        std::string ⌖
-        ppii(std::string &_target) : target (_target) {}
-        virtual plain_port_info_iface& output() {
-            target[target.length() - 1] &= ~32;
-            return *this;
-        }
-    };
+    plain_port_info_iface pp;
+    control_port_info_iface cp;
     
-    struct cpii: public control_port_info_iface {
-        std::string ⌖
-        cpii(std::string &_target) : target (_target) {}
-        virtual control_port_info_iface& output() {
-            target[target.length() - 1] &= ~32;
-            return *this;
-        }
-    };
-    
-    ppii pp;
-    cpii cp;
-    
-    plugin_port_type_grabber(std::string &_dest) : dest(_dest), pp(_dest), cp(_dest) {}
+    plugin_port_type_grabber(uint32_t &_target) : target(_target), index(0) { target = 0; }
         
-    virtual plain_port_info_iface &audio_port(const std::string &id, const std::string &name, const std::string &microname = std::string("N/A")) { dest += 'a'; return pp; }
-    virtual plain_port_info_iface &event_port(const std::string &id, const std::string &name, const std::string &microname = std::string("N/A")) { dest += 'e'; return pp; }
-    virtual control_port_info_iface &control_port(const std::string &id, const std::string &name, double def_value, const std::string &microname = "N/A") { dest += 'c'; return cp; }
+    virtual plain_port_info_iface &audio_port(const std::string &id, const std::string &name, const std::string &microname = std::string("N/A")) { target |= (1 << index); index++; return pp; }
+    virtual plain_port_info_iface &event_port(const std::string &id, const std::string &name, const std::string &microname = std::string("N/A")) { index++; return pp; }
+    virtual control_port_info_iface &control_port(const std::string &id, const std::string &name, double def_value, const std::string &microname = "N/A") { index++; return cp; }
 };
 
 /// A sink to send information about plugins
diff --git a/src/lv2gui.cpp b/src/lv2gui.cpp
index bc98bf7..e50602f 100644
--- a/src/lv2gui.cpp
+++ b/src/lv2gui.cpp
@@ -287,7 +287,7 @@ void store_preset(GtkWindow *toplevel, plugin_gui *gui)
 
 ///////////////////////////////////////////////////////////////////////////////////////
 
-class small_plugin_gui
+class small_plugin_gui: public uri_map_access
 {
 public:
     LV2UI_Write_Function write_function;
diff --git a/src/makerdf.cpp b/src/makerdf.cpp
index 5a2e29e..187ca6b 100644
--- a/src/makerdf.cpp
+++ b/src/makerdf.cpp
@@ -286,8 +286,9 @@ struct lv2_port_base {
         ss << ind << "lv2:index " << index << " ;\n";
         ss << ind << "lv2:symbol \"" << symbol << "\" ;\n";
         ss << ind << "lv2:name \"" << name << "\" ;\n";
-        if (!extras.empty())
-            ss << ind << extras;
+        if (!extras.empty()) {
+            ss << calf_utils::indent(extras, ind);
+        }
         if (microname != "N/A")
             ss << ind << "<http://lv2plug.in/ns/dev/tiny-name> \"" << microname << "\" ;\n";
     }
@@ -472,6 +473,7 @@ void make_ttl(string path_prefix)
         "@prefix epp: <http://lv2plug.in/ns/dev/extportinfo#> .\n"
         "@prefix kf: <http://foltman.com/ns/> .\n"
         "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n"
+        "@prefix poly: <http://lv2plug.in/ns/dev/polymorphic-port#> .\n"
 
         "\n"
     ;
diff --git a/src/modules_small.cpp b/src/modules_small.cpp
index 47e1be2..352b530 100644
--- a/src/modules_small.cpp
+++ b/src/modules_small.cpp
@@ -49,6 +49,7 @@ using namespace dsp;
 using namespace std;
 
 template<class Module> LV2_Descriptor lv2_small_wrapper<Module>::descriptor;
+template<class Module> uint32_t lv2_small_wrapper<Module>::poly_port_types;
 
 namespace small_plugins
 {
@@ -302,13 +303,13 @@ public:
     {
         int idx = 0;
         if (Inputs == 1)
-            cports[idx++] = &pii->control_port("in", "In", in1, "").input();
+            cports[idx++] = &pii->control_port("in", "In", in1, "").polymorphic().poly_audio().input();
         else
         {
-            cports[idx++] = &pii->control_port("in_1", "In 1", in1, "").input();
-            cports[idx++] = &pii->control_port("in_2", "In 2", in2, "").input();
+            cports[idx++] = &pii->control_port("in_1", "In 1", in1, "").polymorphic().poly_audio().input();
+            cports[idx++] = &pii->control_port("in_2", "In 2", in2, "").polymorphic().poly_audio().input();
         }
-        cports[idx++] = &pii->control_port("out", "Out", 0, "").output();
+        cports[idx++] = &pii->control_port("out", "Out", 0, "").poly_audio().output();
     }
 };
 

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list