Add a crude incomplete implementation of persist extension support.
(cherry picked from commit 3ec11c04799fc08fd408c4ef2350df65f88ccfde)
This commit is contained in:
committed by
Tobias Doerffel
parent
48f9008f42
commit
fbc364e68e
@@ -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[]
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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" {
|
||||
|
||||
|
||||
@@ -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 indicates that value points to a zero-terminated string.
|
||||
A 'size' of 0 is valid. The host may choose to store nothing.
|
||||
|
||||
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__ */
|
||||
Reference in New Issue
Block a user