13
0

Prototype LV2 extension for plugins to provide Midnams

This commit is contained in:
Robin Gareus 2016-10-29 19:21:48 +02:00
parent f8167ebe20
commit 3f73973806
4 changed files with 126 additions and 1 deletions

View File

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

View File

@ -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 ();

View File

@ -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) {}

View File

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