[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