Add a crude incomplete implementation of persist extension support.

(cherry picked from commit 3ec11c04799fc08fd408c4ef2350df65f88ccfde)
This commit is contained in:
Krzysztof Foltman
2010-09-19 23:14:40 +01:00
committed by Tobias Doerffel
parent 48f9008f42
commit fbc364e68e
4 changed files with 107 additions and 20 deletions

View File

@@ -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[]

View File

@@ -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;
}
};

View File

@@ -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" {