summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2016-10-29 19:21:48 +0200
committerRobin Gareus <robin@gareus.org>2016-10-29 19:57:43 +0200
commit3f739738062eb5fd646a1a88a61019b453bbda7f (patch)
tree20785d499e1bd18a99d8bc851989813c1ecced64 /libs
parentf8167ebe20ea5d6e4e8d376dfae1b211887977e9 (diff)
Prototype LV2 extension for plugins to provide Midnams
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/lv2_extensions.h38
-rw-r--r--libs/ardour/ardour/lv2_plugin.h6
-rw-r--r--libs/ardour/ardour/plugin.h5
-rw-r--r--libs/ardour/lv2_plugin.cc78
4 files changed, 126 insertions, 1 deletions
diff --git a/libs/ardour/ardour/lv2_extensions.h b/libs/ardour/ardour/lv2_extensions.h
index 64fc3bc615..f38ac8122a 100644
--- a/libs/ardour/ardour/lv2_extensions.h
+++ b/libs/ardour/ardour/lv2_extensions.h
@@ -171,4 +171,42 @@ typedef struct _LV2_License_Interface {
@}
*/
+/**
+ @defgroup midnam MIDI Naming
+
+ @{
+*/
+
+
+#define LV2_MIDNAM_URI "http://ardour.org/lv2/midnam"
+#define LV2_MIDNAM_PREFIX LV2_MIDNAM_URI "#"
+#define LV2_MIDNAM__interface LV2_MIDNAM_PREFIX "interface"
+#define LV2_MIDNAM__update LV2_MIDNAM_PREFIX "update"
+
+typedef void* LV2_Midnam_Handle;
+
+/** a LV2 Feature provided by the Host to the plugin */
+typedef struct {
+ /** Opaque host data */
+ LV2_Midnam_Handle handle;
+ /** Request from run() that the host should re-read the midnam */
+ void (*update)(LV2_Midnam_Handle handle);
+} LV2_Midnam;
+
+typedef struct {
+ /** query midnam document. The plugin
+ * is expected to return an allocated
+ * null-terminated XML text, which is
+ * safe for the host to pass to free().
+ *
+ * The midnam <Model> must be unique and
+ * specific for the given plugin-instance.
+ */
+ char* (*midnam)(LV2_Handle instance);
+ char* (*model)(LV2_Handle instance);
+} LV2_Midnam_Interface;
+
+/**
+ @}
+*/
#endif
diff --git a/libs/ardour/ardour/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h
index a1e38fda32..202ddbb240 100644
--- a/libs/ardour/ardour/lv2_plugin.h
+++ b/libs/ardour/ardour/lv2_plugin.h
@@ -278,6 +278,7 @@ class LIBARDOUR_API LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee
#ifdef LV2_EXTENDED
const LV2_Inline_Display_Interface* _display_interface;
+ const LV2_Midnam_Interface* _midname_interface;
#endif
typedef struct {
@@ -294,6 +295,7 @@ class LIBARDOUR_API LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee
LV2_Feature _def_state_feature;
#ifdef LV2_EXTENDED
LV2_Feature _queue_draw_feature;
+ LV2_Feature _midnam_feature;
#endif
// Options passed to plugin
@@ -321,6 +323,10 @@ class LIBARDOUR_API LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee
#ifdef LV2_EXTENDED
bool has_inline_display ();
Plugin::Display_Image_Surface* render_inline_display (uint32_t, uint32_t);
+
+ bool has_midnam ();
+ bool read_midnam ();
+ std::string midnam_model ();
#endif
void latency_compute_run ();
diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h
index 612091191e..7d35ac7c2e 100644
--- a/libs/ardour/ardour/plugin.h
+++ b/libs/ardour/ardour/plugin.h
@@ -166,6 +166,11 @@ class LIBARDOUR_API Plugin : public PBD::StatefulDestructible, public Latent
virtual Display_Image_Surface* render_inline_display (uint32_t, uint32_t) { return NULL; }
PBD::Signal0<void> QueueDraw;
+ virtual bool has_midnam () { return false; }
+ virtual bool read_midnam () { return false; }
+ virtual std::string midnam_model () { return ""; }
+ PBD::Signal0<void> UpdateMidnam;
+
struct PresetRecord {
PresetRecord () : valid (false) {}
PresetRecord (const std::string& u, const std::string& l, bool s = true) : uri (u), label (l), user (s), valid (true) {}
diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc
index 91ab6b43a4..7248dfeaa1 100644
--- a/libs/ardour/lv2_plugin.cc
+++ b/libs/ardour/lv2_plugin.cc
@@ -45,6 +45,7 @@
#include "ardour/audioengine.h"
#include "ardour/debug.h"
#include "ardour/lv2_plugin.h"
+#include "ardour/midi_patch_manager.h"
#include "ardour/session.h"
#include "ardour/tempo.h"
#include "ardour/types.h"
@@ -223,6 +224,13 @@ queue_draw (LV2_Inline_Display_Handle handle)
LV2Plugin* plugin = (LV2Plugin*)handle;
plugin->QueueDraw(); /* EMIT SIGNAL */
}
+
+static void
+midnam_update (LV2_Midnam_Handle handle)
+{
+ LV2Plugin* plugin = (LV2Plugin*)handle;
+ plugin->UpdateMidnam (); /* EMIT SIGNAL */
+}
#endif
/* log extension */
@@ -280,6 +288,7 @@ struct LV2Plugin::Impl {
#endif
#ifdef LV2_EXTENDED
, queue_draw(0)
+ , midnam(0)
#endif
{}
@@ -307,6 +316,7 @@ struct LV2Plugin::Impl {
#endif
#ifdef LV2_EXTENDED
LV2_Inline_Display* queue_draw;
+ LV2_Midnam* midnam;
#endif
};
@@ -399,7 +409,7 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
lilv_node_free(state_uri);
lilv_node_free(state_iface_uri);
- _features = (LV2_Feature**)calloc(12, sizeof(LV2_Feature*));
+ _features = (LV2_Feature**)calloc(13, sizeof(LV2_Feature*));
_features[0] = &_instance_access_feature;
_features[1] = &_data_access_feature;
_features[2] = &_make_path_feature;
@@ -425,6 +435,15 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
_queue_draw_feature.URI = LV2_INLINEDISPLAY__queue_draw;
_queue_draw_feature.data = _impl->queue_draw;
_features[n_features++] = &_queue_draw_feature;
+
+ _impl->midnam = (LV2_Midnam*)
+ malloc (sizeof(LV2_Midnam));
+ _impl->midnam->handle = this;
+ _impl->midnam->update = midnam_update;
+
+ _midnam_feature.URI = LV2_MIDNAM__update;
+ _midnam_feature.data = _impl->midnam;
+ _features[n_features++] = &_midnam_feature;
#endif
#ifdef HAVE_LV2_1_2_0
@@ -521,6 +540,16 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
#ifdef LV2_EXTENDED
_display_interface = (const LV2_Inline_Display_Interface*)
extension_data (LV2_INLINEDISPLAY__interface);
+
+ _midname_interface = (const LV2_Midnam_Interface*)
+ extension_data (LV2_MIDNAM__interface);
+ if (_midname_interface) {
+ if (read_midnam ()) {
+ printf ("READ MIDNAM FROM PLUGIN\n");
+ } else {
+ printf ("**FAILED TO ** READ MIDNAM FROM PLUGIN\n");
+ }
+ }
#endif
if (lilv_plugin_has_feature(plugin, _world.lv2_inPlaceBroken)) {
@@ -840,6 +869,15 @@ LV2Plugin::~LV2Plugin ()
deactivate();
cleanup();
+#ifdef LV2_EXTENDED
+ if (has_midnam ()) {
+ std::stringstream ss;
+ ss << (void*)this;
+ ss << unique_id();
+ MIDI::Name::MidiPatchManager::instance().remove_custom_midnam (ss.str());
+ }
+#endif
+
lilv_instance_free(_impl->instance);
lilv_state_free(_impl->state);
lilv_node_free(_impl->name);
@@ -849,6 +887,7 @@ LV2Plugin::~LV2Plugin ()
#endif
#ifdef LV2_EXTENDED
free(_impl->queue_draw);
+ free(_impl->midnam);
#endif
free(_features);
@@ -930,6 +969,43 @@ LV2Plugin::render_inline_display (uint32_t w, uint32_t h) {
}
return NULL;
}
+
+bool
+LV2Plugin::has_midnam () {
+ return _midname_interface ? true : false;
+}
+
+bool
+LV2Plugin::read_midnam () {
+ bool rv = false;
+ if (!_midname_interface) {
+ return rv;
+ }
+ char* midnam = _midname_interface->midnam ((void*)_impl->instance->lv2_handle);
+ if (midnam) {
+ std::stringstream ss;
+ ss << (void*)this;
+ ss << unique_id();
+ MIDI::Name::MidiPatchManager::instance().remove_custom_midnam (ss.str());
+ rv = MIDI::Name::MidiPatchManager::instance().add_custom_midnam (ss.str(), midnam);
+ }
+ free (midnam);
+ return rv;
+}
+
+std::string
+LV2Plugin::midnam_model () {
+ std::string rv;
+ if (!_midname_interface) {
+ return rv;
+ }
+ char* model = _midname_interface->model ((void*)_impl->instance->lv2_handle);
+ if (model) {
+ rv = model;
+ }
+ free (model);
+ return rv;
+}
#endif
string