From e452ba0fe1f6087c5145625be5a55c2fb60c1f67 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 8 Sep 2017 19:26:08 +0200 Subject: Add LV2 extension to notify host about midi-bank/pgm state. --- libs/ardour/ardour/lv2_extensions.h | 25 +++++++++++++++++++++ libs/ardour/ardour/lv2_plugin.h | 17 +++++++++++++- libs/ardour/ardour/plugin.h | 4 ++++ libs/ardour/lv2_plugin.cc | 44 ++++++++++++++++++++++++++++++++----- 4 files changed, 84 insertions(+), 6 deletions(-) diff --git a/libs/ardour/ardour/lv2_extensions.h b/libs/ardour/ardour/lv2_extensions.h index 26432b54d7..027eb0391b 100644 --- a/libs/ardour/ardour/lv2_extensions.h +++ b/libs/ardour/ardour/lv2_extensions.h @@ -225,6 +225,31 @@ typedef struct { void (*free)(char*); } LV2_Midnam_Interface; +/** + @} +*/ + +/** + @defgroup bankpatch + + @{ +*/ + + +#define LV2_BANKPATCH_URI "http://ardour.org/lv2/bankpatch" +#define LV2_BANKPATCH_PREFIX LV2_BANKPATCH_URI "#" +#define LV2_BANKPATCH__notify LV2_BANKPATCH_PREFIX "notify" + +typedef void* LV2_BankPatch_Handle; + +/** a LV2 Feature provided by the Host to the plugin */ +typedef struct { + /** Opaque host data */ + LV2_BankPatch_Handle handle; + /** Info from plugin's run(), notify host that bank/program changed */ + void (*notify)(LV2_BankPatch_Handle handle, uint8_t channel, uint32_t bank, uint8_t pgm); +} LV2_BankPatch; + /** @} */ diff --git a/libs/ardour/ardour/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h index b17de51928..d4b6ca819f 100644 --- a/libs/ardour/ardour/lv2_plugin.h +++ b/libs/ardour/ardour/lv2_plugin.h @@ -277,9 +277,23 @@ class LIBARDOUR_API LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee Glib::Threads::Mutex _work_mutex; #ifdef LV2_EXTENDED + static void queue_draw (LV2_Inline_Display_Handle); + static void midnam_update (LV2_Midnam_Handle); + static void bankpatch_notify (LV2_BankPatch_Handle, uint8_t, uint32_t, uint8_t); + const LV2_Inline_Display_Interface* _display_interface; bool _inline_display_in_gui; - const LV2_Midnam_Interface* _midname_interface; + const LV2_Midnam_Interface* _midname_interface; + + uint32_t _bankpatch[16]; + bool seen_bankpatch; + bool knows_bank_patch () { return seen_bankpatch; } + uint32_t bank_patch (uint8_t chn) { + assert (chn < 16); + if (chn > 15) return UINT32_MAX; + return _bankpatch[chn]; + } + #endif typedef struct { @@ -297,6 +311,7 @@ class LIBARDOUR_API LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee #ifdef LV2_EXTENDED LV2_Feature _queue_draw_feature; LV2_Feature _midnam_feature; + LV2_Feature _bankpatch_feature; #endif // Options passed to plugin diff --git a/libs/ardour/ardour/plugin.h b/libs/ardour/ardour/plugin.h index 4e7f45bc8a..419e33e5fa 100644 --- a/libs/ardour/ardour/plugin.h +++ b/libs/ardour/ardour/plugin.h @@ -180,6 +180,10 @@ class LIBARDOUR_API Plugin : public PBD::StatefulDestructible, public Latent virtual std::string midnam_model () { return ""; } PBD::Signal0 UpdateMidnam; + virtual bool knows_bank_patch () { return false; } + virtual uint32_t bank_patch (uint8_t chn) { return UINT32_MAX; } + PBD::Signal1 BankPatchChange; + 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 5e02997fe9..5311136afc 100644 --- a/libs/ardour/lv2_plugin.cc +++ b/libs/ardour/lv2_plugin.cc @@ -230,19 +230,35 @@ work_respond(LV2_Worker_Respond_Handle handle, #ifdef LV2_EXTENDED /* inline display extension */ -static void -queue_draw (LV2_Inline_Display_Handle handle) +void +LV2Plugin::queue_draw (LV2_Inline_Display_Handle handle) { LV2Plugin* plugin = (LV2Plugin*)handle; plugin->QueueDraw(); /* EMIT SIGNAL */ } -static void -midnam_update (LV2_Midnam_Handle handle) +void +LV2Plugin::midnam_update (LV2_Midnam_Handle handle) { LV2Plugin* plugin = (LV2Plugin*)handle; plugin->UpdateMidnam (); /* EMIT SIGNAL */ } + +void +LV2Plugin::bankpatch_notify (LV2_BankPatch_Handle handle, uint8_t chn, uint32_t bank, uint8_t pgm) +{ + LV2Plugin* plugin = (LV2Plugin*)handle; + if (chn > 15) { + return; + } + plugin->seen_bankpatch = true; + if (pgm > 127 || bank > 16383) { + plugin->_bankpatch[chn] = UINT32_MAX; + } else { + plugin->_bankpatch[chn] = (bank << 7) | pgm; + } + plugin->BankPatchChange (chn); /* EMIT SIGNAL */ +} #endif /* log extension */ @@ -329,6 +345,7 @@ struct LV2Plugin::Impl { #ifdef LV2_EXTENDED LV2_Inline_Display* queue_draw; LV2_Midnam* midnam; + LV2_BankPatch* bankpatch; #endif }; @@ -422,7 +439,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(13, sizeof(LV2_Feature*)); + _features = (LV2_Feature**)calloc(14, sizeof(LV2_Feature*)); _features[0] = &_instance_access_feature; _features[1] = &_data_access_feature; _features[2] = &_make_path_feature; @@ -457,6 +474,15 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate) _midnam_feature.URI = LV2_MIDNAM__update; _midnam_feature.data = _impl->midnam; _features[n_features++] = &_midnam_feature; + + _impl->bankpatch = (LV2_BankPatch*) + malloc (sizeof(LV2_BankPatch)); + _impl->bankpatch->handle = this; + _impl->bankpatch->notify = bankpatch_notify; + + _bankpatch_feature.URI = LV2_BANKPATCH__notify; + _bankpatch_feature.data = _impl->bankpatch; + _features[n_features++] = &_bankpatch_feature; #endif #ifdef HAVE_LV2_1_2_0 @@ -490,6 +516,13 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate) _features[n_features++] = &_options_feature; #endif +#ifdef LV2_EXTENDED + seen_bankpatch = false; + for (uint32_t chn = 0; chn < 16; ++chn) { + _bankpatch[chn] = UINT32_MAX; + } +#endif + LV2_State_Make_Path* make_path = (LV2_State_Make_Path*)malloc( sizeof(LV2_State_Make_Path)); make_path->handle = this; @@ -900,6 +933,7 @@ LV2Plugin::~LV2Plugin () #ifdef LV2_EXTENDED free(_impl->queue_draw); free(_impl->midnam); + free(_impl->bankpatch); #endif free(_features); -- cgit v1.2.3