[SCM] calf/master: Add a crude incomplete implementation of persist extension support.

js at users.alioth.debian.org js at users.alioth.debian.org
Tue May 7 15:40:23 UTC 2013


The following commit has been merged in the master branch:
commit 3ec11c04799fc08fd408c4ef2350df65f88ccfde
Author: Krzysztof Foltman <wdev at foltman.com>
Date:   Sun Sep 19 23:14:40 2010 +0100

    Add a crude incomplete implementation of persist extension support.

diff --git a/src/calf/giface.h b/src/calf/giface.h
index 08954c6..7525197 100644
--- a/src/calf/giface.h
+++ b/src/calf/giface.h
@@ -28,6 +28,8 @@
 #include <string>
 #include <vector>
 
+// #define USE_PERSIST_EXTENSION 1
+
 namespace osctl {
     struct osc_client;
 }
@@ -299,6 +301,8 @@ struct plugin_metadata_iface
     virtual const char *get_label() const = 0;
     /// @return total number of parameters
     virtual int get_param_count() const = 0;
+    /// @return total number of parameters that aren't configure variables
+    virtual int get_nonstring_param_count() const = 0;
     /// Return custom XML
     virtual const char *get_gui_xml() const = 0;
     /// @return number of audio inputs
@@ -633,6 +637,12 @@ public:
                 ports.push_back(i);
         }
     }
+    int get_nonstring_param_count() const {
+        int i = Metadata::param_count;
+        while(i > 0 && (param_props[i - 1].flags & PF_TYPEMASK) == PF_STRING)
+            i--;
+        return i;
+    }
 };
 
 #define CALF_PORT_NAMES(name) template<> const char *::plugin_metadata<name##_metadata>::port_names[]
diff --git a/src/calf/lv2_persist.h b/src/calf/lv2_persist.h
index 56b9990..86ac865 100644
--- a/src/calf/lv2_persist.h
+++ b/src/calf/lv2_persist.h
@@ -17,7 +17,6 @@ extern "C" {
     The plugin should always expose this feature as optional.
 */
 #define LV2_PERSIST_URI "http://paniq.org/lv2/persist"
-
    
 /*
     Causes the host to store a binary blob in a map.
@@ -28,22 +27,23 @@ extern "C" {
     the binary blob to be stored. 'size' is the size of the binary blob in
     bytes.
     
-    The host must store a copy of the blob under the provided key in a map 
-    until returning from the save() call.
+    The host is expected store a copy of the blob under the provided key.
+    
+    A 'size' of 0 is valid. The host may choose to store nothing.
     
-    A size of 0 indicates that value points to a zero-terminated string.
+    A 'size' of -1 indicates that 'value' points to a zero-terminated string.
     This is a convenience function which requires the host to calculate the
-    length as strlen(value)+1.
+    size from strlen(value)+1.
 */
 typedef void (*LV2_Persist_Store_Function)(void *callback_data, const char *key, 
-                                           const void *value, size_t size);
+                                           const void *value, ssize_t size);
 
 /*
     Causes the host to retrieve a binary blob from the map.
     
     A callback provided by the host to LV2_Persist.restore(). 'callback_data'
     must be the callback_data argument passed to restore(). 'key' is a private
-    string or UI under which a blob has been previously stored.
+    string or URI under which a blob has been previously stored.
     
     When the blob could be successfully retrieved, retrieve() must return
     a pointer to the blob and set 'size' to the length of value in bytes.
@@ -91,7 +91,7 @@ struct LV2_Persist {
     
         The map on which save() operates must always be empty before
         the first call to store(). The plugin is expected to store all
-        blobs of interests.
+        blobs of interest.
     
         The callback data pointer and store function may not be used
         beyond the scope of save().
@@ -127,4 +127,4 @@ struct LV2_Persist {
 } /* extern "C" */
 #endif
 
-#endif /* __LV2_PERSIST_H__ */
+#endif /* __LV2_PERSIST_H__ */
\ No newline at end of file
diff --git a/src/calf/lv2wrap.h b/src/calf/lv2wrap.h
index 6a9bc40..d38b8ea 100644
--- a/src/calf/lv2wrap.h
+++ b/src/calf/lv2wrap.h
@@ -30,6 +30,7 @@
 #include <calf/lv2-midiport.h>
 #include <calf/lv2_contexts.h>
 #include <calf/lv2_event.h>
+#include <calf/lv2_persist.h>
 #include <calf/lv2_progress.h>
 #include <calf/lv2_string_port.h>
 #include <calf/lv2_uri_map.h>
@@ -52,6 +53,7 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface
     LV2_Progress *progress_report_feature;
     float **ins, **outs, **params;
     int out_count;
+    int real_param_count;
     lv2_instance(audio_module_iface *_module)
     {
         module = _module;
@@ -59,6 +61,11 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface
         metadata = module->get_metadata_iface();
         metadata->get_message_context_parameters(message_params);
         out_count = metadata->get_output_count();
+#if USE_PERSIST_EXTENSION
+        real_param_count = metadata->get_nonstring_param_count();
+#else
+        real_param_count = metadata->get_param_count();
+#endif
         
         uri_map = NULL;
         midi_data = NULL;
@@ -107,6 +114,27 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface
         }
         return module->message_run(valid_inputs, output_ports);
     }
+#if USE_PERSIST_EXTENSION
+    void impl_restore(LV2_Persist_Retrieve_Function retrieve, void *callback_data)
+    {
+        for (unsigned int i = 0; i < message_params.size(); i++)
+        {
+            int pn = message_params[i];
+            const parameter_properties &pp = *metadata->get_param_props(pn);
+            if ((pp.flags & PF_TYPEMASK) == PF_STRING) {
+                size_t len = 0;
+                const void *ptr = (*retrieve)(callback_data, pp.short_name, &len);
+                if (ptr)
+                {
+                    printf("Calling configure on %s\n", pp.short_name);
+                    configure(pp.short_name, std::string((const char *)ptr, len).c_str());
+                }
+                else
+                    configure(pp.short_name, pp.choices[0]);
+            }
+        }
+    }
+#endif
     char *configure(const char *key, const char *value) { 
         // disambiguation - the plugin_ctl_iface version is just a stub, so don't use it
         return module->configure(key, value);
@@ -150,14 +178,14 @@ struct lv2_instance: public plugin_ctl_iface, public progress_report_iface
     virtual float get_param_value(int param_no)
     {
         // XXXKF hack
-        if (param_no >= metadata->get_param_count())
+        if (param_no >= real_param_count)
             return 0;
         return (*params)[param_no];
     }
     virtual void set_param_value(int param_no, float value)
     {
         // XXXKF hack
-        if (param_no >= metadata->get_param_count())
+        if (param_no >= real_param_count)
             return;
         *params[param_no] = value;
     }
@@ -177,6 +205,7 @@ struct lv2_wrapper
     static LV2_Descriptor descriptor;
     static LV2_Calf_Descriptor calf_descriptor;
     static LV2MessageContext message_context;
+    static LV2_Persist persist;
     std::string uri;
     
     lv2_wrapper()
@@ -191,17 +220,26 @@ struct lv2_wrapper
         descriptor.deactivate = cb_deactivate;
         descriptor.cleanup = cb_cleanup;
         descriptor.extension_data = cb_ext_data;
+#if USE_PERSIST_EXTENSION
+        persist.save = cb_persist_save;
+        persist.restore = cb_persist_restore;
+#endif
         calf_descriptor.get_pci = cb_get_pci;
         message_context.message_connect_port = cb_connect;
         message_context.message_run = cb_message_run;
     }
 
-    static void cb_connect(LV2_Handle Instance, uint32_t port, void *DataLocation) {
+    static void cb_connect(LV2_Handle Instance, uint32_t port, void *DataLocation)
+    {
         instance *const mod = (instance *)Instance;
         const plugin_metadata_iface *md = mod->metadata;
         unsigned long ins = md->get_input_count();
         unsigned long outs = md->get_output_count();
+#if USE_PERSIST_EXTENSION
+        unsigned long params = md->get_nonstring_param_count();
+#else
         unsigned long params = md->get_param_count();
+#endif
         if (port < ins)
             mod->ins[port] = (float *)DataLocation;
         else if (port < ins + outs)
@@ -215,12 +253,14 @@ struct lv2_wrapper
         }
     }
 
-    static void cb_activate(LV2_Handle Instance) {
+    static void cb_activate(LV2_Handle Instance)
+    {
         instance *const mod = (instance *)Instance;
         mod->set_srate = true;
     }
     
-    static void cb_deactivate(LV2_Handle Instance) {
+    static void cb_deactivate(LV2_Handle Instance)
+    {
         instance *const mod = (instance *)Instance;
         mod->module->deactivate();
     }
@@ -259,11 +299,13 @@ struct lv2_wrapper
         return static_cast<plugin_ctl_iface *>(Instance);
     }
 
-    static uint32_t cb_message_run(LV2_Handle Instance, const void *valid_inputs, void *outputs_written) {
+    static uint32_t cb_message_run(LV2_Handle Instance, const void *valid_inputs, void *outputs_written)
+    {
         instance *mod = (instance *)Instance;
         return mod->impl_message_run(valid_inputs, outputs_written);
     }
-    static void cb_run(LV2_Handle Instance, uint32_t SampleCount) {
+    static void cb_run(LV2_Handle Instance, uint32_t SampleCount)
+    {
         instance *const inst = (instance *)Instance;
         audio_module_iface *mod = inst->module;
         if (inst->set_srate) {
@@ -279,20 +321,52 @@ struct lv2_wrapper
         }
         inst->module->process_slice(offset, SampleCount);
     }
-    static void cb_cleanup(LV2_Handle Instance) {
+    static void cb_cleanup(LV2_Handle Instance)
+    {
         instance *const mod = (instance *)Instance;
         delete mod;
     }
-    static const void *cb_ext_data(const char *URI) {
+    static const void *cb_ext_data(const char *URI)
+    {
         if (!strcmp(URI, "http://foltman.com/ns/calf-plugin-instance"))
             return &calf_descriptor;
         if (!strcmp(URI, LV2_CONTEXT_MESSAGE))
             return &message_context;
+#if USE_PERSIST_EXTENSION
+        if (!strcmp(URI, LV2_PERSIST_URI))
+            return &persist;
+#endif
         return NULL;
     }
+#if USE_PERSIST_EXTENSION
+    static void cb_persist_save(LV2_Handle Instance, LV2_Persist_Store_Function store, void *callback_data)
+    {
+        instance *const inst = (instance *)Instance;
+        struct store_state: public send_configure_iface
+        {
+            LV2_Persist_Store_Function store;
+            void *callback_data;
+            
+            virtual void send_configure(const char *key, const char *value)
+            {
+                (*store)(callback_data, key, value, strlen(value));
+            }
+        };
+        store_state s;
+        s.store = store;
+        s.callback_data = callback_data;
+        inst->send_configures(&s);
+    }
+    static void cb_persist_restore(LV2_Handle Instance, LV2_Persist_Retrieve_Function retrieve, void *callback_data)
+    {
+        instance *const inst = (instance *)Instance;
+        inst->impl_restore(retrieve, callback_data);
+    }
+#endif
+    
     static lv2_wrapper &get() { 
-        static lv2_wrapper instance;
-        return instance;
+        static lv2_wrapper *instance = new lv2_wrapper;
+        return *instance;
     }
 };
 
diff --git a/src/makerdf.cpp b/src/makerdf.cpp
index 63979b6..9b755c1 100644
--- a/src/makerdf.cpp
+++ b/src/makerdf.cpp
@@ -23,6 +23,7 @@
 #if USE_LV2
 #include <calf/lv2_contexts.h>
 #include <calf/lv2_event.h>
+#include <calf/lv2_persist.h>
 #include <calf/lv2_uri_map.h>
 #endif
 #include <getopt.h>
@@ -205,12 +206,16 @@ static const char *units[] = {
 
 //////////////// To all haters: calm down, I'll rewrite it to use the new interface one day
 
-static void add_ctl_port(string &ports, const parameter_properties &pp, int pidx, const plugin_metadata_iface *pmi, int param)
+static bool add_ctl_port(string &ports, const parameter_properties &pp, int pidx, const plugin_metadata_iface *pmi, int param)
 {
     stringstream ss;
     const char *ind = "        ";
 
     parameter_flags type = (parameter_flags)(pp.flags & PF_TYPEMASK);
+#if USE_PERSIST_EXTENSION
+    if (type == PF_STRING)
+        return false;
+#endif
     uint8_t unit = (pp.flags & PF_UNITMASK) >> 24;
     
     if (ports != "") ports += " , ";
@@ -278,6 +283,7 @@ static void add_ctl_port(string &ports, const parameter_properties &pp, int pidx
     
     ss << "    ]";
     ports += ss.str();
+    return true;
 }
 
 void make_ttl(string path_prefix)
@@ -417,7 +423,13 @@ void make_ttl(string path_prefix)
             ttl += "    lv2ctx:requiredContext lv2ctx:MessageContext ;\n";
         }
         if (pi->requires_string_ports())
+        {
+#if USE_PERSIST_EXTENSION
+            ttl += "    lv2:requiredFeature <" LV2_PERSIST_URI "> ;\n";
+#else
             ttl += "    lv2:requiredFeature <http://lv2plug.in/ns/dev/string-port#StringTransfer> ;\n";
+#endif
+        }
         
         string ports = "";
         int pn = 0;
@@ -434,7 +446,8 @@ void make_ttl(string path_prefix)
             else
                 add_port(ports, out_names[i], out_names[i], "Output", pn++, "lv2:AudioPort", true);
         for (int i = 0; i < pi->get_param_count(); i++)
-            add_ctl_port(ports, *pi->get_param_props(i), pn++, pi, i);
+            if (add_ctl_port(ports, *pi->get_param_props(i), pn, pi, i))
+                pn++;
         if (pi->get_midi()) {
             add_port(ports, "event_in", "Event", "Input", pn++, "lv2ev:EventPort", true);
         }
diff --git a/src/plugin.cpp b/src/plugin.cpp
index 9a4b976..6588f67 100644
--- a/src/plugin.cpp
+++ b/src/plugin.cpp
@@ -485,6 +485,9 @@ ladspa_plugin_metadata_set::~ladspa_plugin_metadata_set()
 template<class Module> LV2_Descriptor calf_plugins::lv2_wrapper<Module>::descriptor;
 template<class Module> LV2_Calf_Descriptor calf_plugins::lv2_wrapper<Module>::calf_descriptor;
 template<class Module> LV2MessageContext calf_plugins::lv2_wrapper<Module>::message_context;
+#if USE_PERSIST_EXTENSION
+template<class Module> LV2_Persist calf_plugins::lv2_wrapper<Module>::persist;
+#endif
 
 extern "C" {
 

-- 
calf audio plugins packaging



More information about the pkg-multimedia-commits mailing list