Add LV2 extension to notify host about midi-bank/pgm state.
authorRobin Gareus <robin@gareus.org>
Fri, 8 Sep 2017 17:26:08 +0000 (19:26 +0200)
committerRobin Gareus <robin@gareus.org>
Fri, 8 Sep 2017 21:35:00 +0000 (23:35 +0200)
libs/ardour/ardour/lv2_extensions.h
libs/ardour/ardour/lv2_plugin.h
libs/ardour/ardour/plugin.h
libs/ardour/lv2_plugin.cc

index 26432b54d740c47b9423b40dd9dd7a3fc0f99449..027eb0391b9a3e18870c88a8b1ceba82c93b7dc2 100644 (file)
@@ -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;
+
 /**
    @}
 */
index b17de51928487916f13aa05b6f46b56100063981..d4b6ca819fa1adb0a96ce5872b4949e195e17520 100644 (file)
@@ -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
index 4e7f45bc8a39bd118d374190e7cd91caa72282db..419e33e5fa0d911b7ed1ce4d1166293cd70dd0de 100644 (file)
@@ -180,6 +180,10 @@ class LIBARDOUR_API Plugin : public PBD::StatefulDestructible, public Latent
        virtual std::string midnam_model () { return ""; }
        PBD::Signal0<void> UpdateMidnam;
 
+       virtual bool knows_bank_patch () { return false; }
+       virtual uint32_t bank_patch (uint8_t chn) { return UINT32_MAX; }
+       PBD::Signal1<void, uint8_t> 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)  {}
index 5e02997fe98c9e873f7148a1198d15ce974a10b0..5311136afcd6c25142eb312fec89ec65e0124d44 100644 (file)
@@ -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);