diff --git a/source/backend/plugin/CarlaPluginLV2.cpp b/source/backend/plugin/CarlaPluginLV2.cpp index be7ff3991..0309a37f2 100644 --- a/source/backend/plugin/CarlaPluginLV2.cpp +++ b/source/backend/plugin/CarlaPluginLV2.cpp @@ -4716,6 +4716,7 @@ public: switch (format) { case kUridNull: { + CARLA_SAFE_ASSERT_RETURN(rindex < fRdfDescriptor->PortCount,); CARLA_SAFE_ASSERT_RETURN(bufferSize == sizeof(float),); for (uint32_t i=0; i < pData->param.count; ++i) @@ -4730,8 +4731,36 @@ public: const float value(*(const float*)buffer); - //if (carla_isNotEqual(fParamBuffers[index], value)) - setParameterValue(index, value, false, true, true); + // check if we should feedback message back to UI + bool sendGui = false; + + if (const uint32_t notifCount = fUI.rdfDescriptor->PortNotificationCount) + { + const char* const portSymbol = fRdfDescriptor->Ports[rindex].Symbol; + + for (uint32_t i=0; i < notifCount; ++i) + { + const LV2_RDF_UI_PortNotification& portNotif(fUI.rdfDescriptor->PortNotifications[i]); + + if (portNotif.Protocol != LV2_UI_PORT_PROTOCOL_FLOAT) + continue; + + if (portNotif.Symbol != nullptr) + { + if (std::strcmp(portNotif.Symbol, portSymbol) != 0) + continue; + } + else if (portNotif.Index != rindex) + { + continue; + } + + sendGui = true; + break; + } + } + + setParameterValue(index, value, sendGui, true, true); } break; @@ -5800,11 +5829,11 @@ private: ~UI() { - CARLA_ASSERT(handle == nullptr); - CARLA_ASSERT(widget == nullptr); - CARLA_ASSERT(descriptor == nullptr); - CARLA_ASSERT(rdfDescriptor == nullptr); - CARLA_ASSERT(window == nullptr); + CARLA_SAFE_ASSERT(handle == nullptr); + CARLA_SAFE_ASSERT(widget == nullptr); + CARLA_SAFE_ASSERT(descriptor == nullptr); + CARLA_SAFE_ASSERT(rdfDescriptor == nullptr); + CARLA_SAFE_ASSERT(window == nullptr); } CARLA_DECLARE_NON_COPY_STRUCT(UI); diff --git a/source/includes/lv2_rdf.hpp b/source/includes/lv2_rdf.hpp index 46f038c9c..74a7c4b70 100644 --- a/source/includes/lv2_rdf.hpp +++ b/source/includes/lv2_rdf.hpp @@ -1,6 +1,6 @@ /* * Custom types to store LV2 information - * Copyright (C) 2011-2014 Filipe Coelho + * Copyright (C) 2011-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -29,6 +29,7 @@ // Base Types typedef const char* LV2_URI; typedef uint32_t LV2_Property; +#define LV2UI_INVALID_PORT_INDEX ((uint32_t)-1) // Port Midi Map Types #define LV2_PORT_MIDI_MAP_CC 1 @@ -485,10 +486,12 @@ struct LV2_RDF_Feature { // Port Notification struct LV2_RDF_UI_PortNotification { const char* Symbol; + uint32_t Index; LV2_Property Protocol; LV2_RDF_UI_PortNotification() noexcept : Symbol(nullptr), + Index(LV2UI_INVALID_PORT_INDEX), Protocol(0) {} ~LV2_RDF_UI_PortNotification() noexcept diff --git a/source/utils/CarlaLv2Utils.hpp b/source/utils/CarlaLv2Utils.hpp index 0b07a7f13..38767aa93 100644 --- a/source/utils/CarlaLv2Utils.hpp +++ b/source/utils/CarlaLv2Utils.hpp @@ -1,6 +1,6 @@ /* * Carla LV2 utils - * Copyright (C) 2011-2017 Filipe Coelho + * Copyright (C) 2011-2018 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -247,6 +247,7 @@ public: Lilv::Node state_state; + Lilv::Node ui_portIndex; Lilv::Node ui_portNotif; Lilv::Node ui_protocol; @@ -376,6 +377,7 @@ public: state_state (new_uri(LV2_STATE__state)), + ui_portIndex (new_uri(LV2_UI__portIndex)), ui_portNotif (new_uri(LV2_UI__portNotification)), ui_protocol (new_uri(LV2_UI__protocol)), @@ -2495,8 +2497,6 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool loadPresets) rdfUI->PortNotificationCount = portNotifNodes.size(); rdfUI->PortNotifications = new LV2_RDF_UI_PortNotification[rdfUI->PortNotificationCount]; - carla_stdout("got port notifications!! %u", rdfUI->PortNotificationCount); - uint32_t h2 = 0; LILV_FOREACH(nodes, it2, portNotifNodes) { @@ -2505,20 +2505,11 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool loadPresets) Lilv::Node portNotifNode(portNotifNodes.get(it2)); LV2_RDF_UI_PortNotification* const rdfPortNotif(&rdfUI->PortNotifications[h2++]); - LilvNode* const symbolNode = lilv_world_get(lv2World.me, portNotifNode, - lv2World.symbol.me, nullptr); - CARLA_SAFE_ASSERT_CONTINUE(symbolNode != nullptr); - LilvNode* const protocolNode = lilv_world_get(lv2World.me, portNotifNode, lv2World.ui_protocol.me, nullptr); CARLA_SAFE_ASSERT_CONTINUE(protocolNode != nullptr); - - CARLA_SAFE_ASSERT_CONTINUE(lilv_node_is_string(symbolNode)); CARLA_SAFE_ASSERT_CONTINUE(lilv_node_is_uri(protocolNode)); - const char* const symbol = lilv_node_as_string(symbolNode); - CARLA_SAFE_ASSERT_CONTINUE(symbol != nullptr && symbol[0] != '\0'); - const char* const protocol = lilv_node_as_uri(protocolNode); CARLA_SAFE_ASSERT_CONTINUE(protocol != nullptr && protocol[0] != '\0'); @@ -2527,7 +2518,32 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool loadPresets) else if (std::strcmp(protocol, LV2_UI__peakProtocol) == 0) rdfPortNotif->Protocol = LV2_UI_PORT_PROTOCOL_PEAK; - rdfPortNotif->Symbol = carla_strdup_safe(symbol); + /**/ if (LilvNode* const symbolNode = lilv_world_get(lv2World.me, portNotifNode, + lv2World.symbol.me, nullptr)) + { + CARLA_SAFE_ASSERT_CONTINUE(lilv_node_is_string(symbolNode)); + + const char* const symbol = lilv_node_as_string(symbolNode); + CARLA_SAFE_ASSERT_CONTINUE(symbol != nullptr && symbol[0] != '\0'); + + rdfPortNotif->Symbol = carla_strdup(symbol); + + lilv_node_free(symbolNode); + } + else if (LilvNode* const indexNode = lilv_world_get(lv2World.me, portNotifNode, + lv2World.ui_portIndex.me, nullptr)) + { + CARLA_SAFE_ASSERT_CONTINUE(lilv_node_is_int(indexNode)); + + const int index = lilv_node_as_int(indexNode); + CARLA_SAFE_ASSERT_CONTINUE(index >= 0); + + rdfPortNotif->Index = static_cast(index); + + lilv_node_free(indexNode); + } + + lilv_node_free(protocolNode); } }