From 101b703b0c411c6341a5e22fc1b057c76b0436b7 Mon Sep 17 00:00:00 2001 From: falkTX Date: Sun, 7 Sep 2014 10:58:47 +0100 Subject: [PATCH] Implement some custom kxstudio lv2 properties --- source/backend/plugin/Lv2Plugin.cpp | 44 +++++++++++++------ source/includes/lv2/lv2_kxstudio_properties.h | 33 ++++++++++++++ source/modules/lv2_rdf.hpp | 6 ++- source/utils/CarlaLv2Utils.hpp | 7 +++ 4 files changed, 75 insertions(+), 15 deletions(-) create mode 100644 source/includes/lv2/lv2_kxstudio_properties.h diff --git a/source/backend/plugin/Lv2Plugin.cpp b/source/backend/plugin/Lv2Plugin.cpp index d8bda5a85..4dc353fb7 100644 --- a/source/backend/plugin/Lv2Plugin.cpp +++ b/source/backend/plugin/Lv2Plugin.cpp @@ -38,8 +38,7 @@ extern "C" { using juce::File; -#define URI_CARLA_ATOM_WORKER "http://kxstudio.sf.net/ns/carla/atomWorker" -#define URI_CARLA_FRONTEND_WIN_ID "http://kxstudio.sf.net/ns/carla/frontendWinId" +#define URI_CARLA_ATOM_WORKER "http://kxstudio.sf.net/ns/carla/atomWorker" CARLA_BACKEND_START_NAMESPACE @@ -108,12 +107,13 @@ const uint32_t CARLA_URI_MAP_ID_TIME_BEATS_PER_MINUTE = 37; const uint32_t CARLA_URI_MAP_ID_TIME_FRAME = 38; const uint32_t CARLA_URI_MAP_ID_TIME_FRAMES_PER_SECOND = 39; const uint32_t CARLA_URI_MAP_ID_TIME_SPEED = 40; -const uint32_t CARLA_URI_MAP_ID_MIDI_EVENT = 41; -const uint32_t CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE = 42; -const uint32_t CARLA_URI_MAP_ID_UI_WINDOW_TITLE = 43; -const uint32_t CARLA_URI_MAP_ID_CARLA_ATOM_WORKER = 44; -const uint32_t CARLA_URI_MAP_ID_CARLA_FRONTEND_WIN_ID = 45; -const uint32_t CARLA_URI_MAP_ID_COUNT = 46; +const uint32_t CARLA_URI_MAP_ID_TIME_TICKS_PER_BEAT = 41; +const uint32_t CARLA_URI_MAP_ID_MIDI_EVENT = 42; +const uint32_t CARLA_URI_MAP_ID_PARAM_SAMPLE_RATE = 43; +const uint32_t CARLA_URI_MAP_ID_UI_WINDOW_TITLE = 44; +const uint32_t CARLA_URI_MAP_ID_CARLA_ATOM_WORKER = 45; +const uint32_t CARLA_URI_MAP_ID_CARLA_TRANSIENT_WIN_ID = 46; +const uint32_t CARLA_URI_MAP_ID_COUNT = 47; // LV2 Feature Ids const uint32_t kFeatureIdBufSizeBounded = 0; @@ -339,7 +339,7 @@ struct Lv2PluginOptions { LV2_Options_Option& optFrontendWinId(opts[FrontendWinId]); optFrontendWinId.context = LV2_OPTIONS_INSTANCE; optFrontendWinId.subject = 0; - optFrontendWinId.key = CARLA_URI_MAP_ID_CARLA_FRONTEND_WIN_ID; + optFrontendWinId.key = CARLA_URI_MAP_ID_CARLA_TRANSIENT_WIN_ID; optFrontendWinId.size = sizeof(int64_t); optFrontendWinId.type = CARLA_URI_MAP_ID_ATOM_LONG; optFrontendWinId.value = &frontendWinId; @@ -2079,7 +2079,9 @@ public: // check if parameter is not enabled or automable if (LV2_IS_PORT_NOT_ON_GUI(portProps)) pData->param.data[j].hints &= ~(PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE); - else if (LV2_IS_PORT_CAUSES_ARTIFACTS(portProps) || LV2_IS_PORT_EXPENSIVE(portProps) || LV2_IS_PORT_NOT_AUTOMATIC(portProps)) + else if (LV2_IS_PORT_CAUSES_ARTIFACTS(portProps) || LV2_IS_PORT_EXPENSIVE(portProps)) + pData->param.data[j].hints &= ~PARAMETER_IS_AUTOMABLE; + else if (LV2_IS_PORT_NOT_AUTOMATIC(portProps) || LV2_IS_PORT_NON_AUTOMABLE(portProps)) pData->param.data[j].hints &= ~PARAMETER_IS_AUTOMABLE; pData->param.ranges[j].min = min; @@ -2667,6 +2669,13 @@ public: doPostRt = true; } break; + case LV2_PORT_DESIGNATION_TIME_TICKS_PER_BEAT: + if ((timeInfo.valid & EngineTimeInfo::kValidBBT) != 0 && ! carla_compareFloats(fLastTimeInfo.bbt.ticksPerBeat, timeInfo.bbt.ticksPerBeat)) + { + fParamBuffers[k] = static_cast(timeInfo.bbt.ticksPerBeat); + doPostRt = true; + } + break; } if (doPostRt) @@ -2709,6 +2718,9 @@ public: lv2_atom_forge_key(&fAtomForge, CARLA_URI_MAP_ID_TIME_BEATS_PER_MINUTE); lv2_atom_forge_float(&fAtomForge, static_cast(timeInfo.bbt.beatsPerMinute)); + + lv2_atom_forge_key(&fAtomForge, CARLA_URI_MAP_ID_TIME_TICKS_PER_BEAT); + lv2_atom_forge_double(&fAtomForge, static_cast(timeInfo.bbt.ticksPerBeat)); } lv2_atom_forge_pop(&fAtomForge, &forgeFrame); @@ -5617,6 +5629,8 @@ private: return CARLA_URI_MAP_ID_TIME_FRAMES_PER_SECOND; if (std::strcmp(uri, LV2_TIME__speed) == 0) return CARLA_URI_MAP_ID_TIME_SPEED; + if (std::strcmp(uri, LV2_KXSTUDIO_PROPERTIES__TimePositionTicksPerBeat) == 0) + return CARLA_URI_MAP_ID_TIME_TICKS_PER_BEAT; // Others if (std::strcmp(uri, LV2_MIDI__MidiEvent) == 0) @@ -5627,10 +5641,10 @@ private: return CARLA_URI_MAP_ID_UI_WINDOW_TITLE; // Custom + if (std::strcmp(uri, LV2_KXSTUDIO_PROPERTIES__TransientWindowId) == 0) + return CARLA_URI_MAP_ID_CARLA_TRANSIENT_WIN_ID; if (std::strcmp(uri, URI_CARLA_ATOM_WORKER) == 0) return CARLA_URI_MAP_ID_CARLA_ATOM_WORKER; - if (std::strcmp(uri, URI_CARLA_FRONTEND_WIN_ID) == 0) - return CARLA_URI_MAP_ID_CARLA_FRONTEND_WIN_ID; // Custom types return ((Lv2Plugin*)handle)->getCustomURID(uri); @@ -5729,6 +5743,8 @@ private: return LV2_TIME__framesPerSecond; if (urid == CARLA_URI_MAP_ID_TIME_SPEED) return LV2_TIME__speed; + if (urid == CARLA_URI_MAP_ID_TIME_TICKS_PER_BEAT) + return LV2_KXSTUDIO_PROPERTIES__TimePositionTicksPerBeat; // Others if (urid == CARLA_URI_MAP_ID_MIDI_EVENT) @@ -5741,8 +5757,8 @@ private: // Custom if (urid == CARLA_URI_MAP_ID_CARLA_ATOM_WORKER) return URI_CARLA_ATOM_WORKER; - if (urid == CARLA_URI_MAP_ID_CARLA_FRONTEND_WIN_ID) - return URI_CARLA_FRONTEND_WIN_ID; + if (urid == CARLA_URI_MAP_ID_CARLA_TRANSIENT_WIN_ID) + return LV2_KXSTUDIO_PROPERTIES__TransientWindowId; // Custom types return ((Lv2Plugin*)handle)->getCustomURIDString(urid); diff --git a/source/includes/lv2/lv2_kxstudio_properties.h b/source/includes/lv2/lv2_kxstudio_properties.h new file mode 100644 index 000000000..e8b42a6c3 --- /dev/null +++ b/source/includes/lv2/lv2_kxstudio_properties.h @@ -0,0 +1,33 @@ +/* + LV2 KXStudio Properties Extension + Copyright 2014 Filipe Coelho + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +/** + @file lv2_kxstudio_properties.h + C header for the LV2 KXStudio Properties extension . +*/ + +#ifndef LV2_KXSTUDIO_PROPERTIES_H +#define LV2_KXSTUDIO_PROPERTIES_H + +#define LV2_KXSTUDIO_PROPERTIES_URI "http://kxstudio.sf.net/ns/lv2ext/props" +#define LV2_KXSTUDIO_PROPERTIES_PREFIX LV2_KXSTUDIO_PROPERTIES_URI "#" + +#define LV2_KXSTUDIO_PROPERTIES__NonAutomable LV2_KXSTUDIO_PROPERTIES_PREFIX "NonAutomable" +#define LV2_KXSTUDIO_PROPERTIES__TimePositionTicksPerBeat LV2_KXSTUDIO_PROPERTIES_PREFIX "TimePositionTicksPerBeat" +#define LV2_KXSTUDIO_PROPERTIES__TransientWindowId LV2_KXSTUDIO_PROPERTIES_PREFIX "TransientWindowId" + +#endif /* LV2_KXSTUDIO_PROPERTIES_H */ diff --git a/source/modules/lv2_rdf.hpp b/source/modules/lv2_rdf.hpp index 6f9b481bb..54e59e479 100644 --- a/source/modules/lv2_rdf.hpp +++ b/source/modules/lv2_rdf.hpp @@ -154,6 +154,7 @@ typedef uint32_t LV2_Property; #define LV2_PORT_NOT_AUTOMATIC 0x0800 #define LV2_PORT_NOT_ON_GUI 0x1000 #define LV2_PORT_TRIGGER 0x2000 +#define LV2_PORT_NON_AUTOMABLE 0x4000 #define LV2_IS_PORT_OPTIONAL(x) ((x) & LV2_PORT_OPTIONAL) #define LV2_IS_PORT_ENUMERATION(x) ((x) & LV2_PORT_ENUMERATION) @@ -169,6 +170,7 @@ typedef uint32_t LV2_Property; #define LV2_IS_PORT_NOT_AUTOMATIC(x) ((x) & LV2_PORT_NOT_AUTOMATIC) #define LV2_IS_PORT_NOT_ON_GUI(x) ((x) & LV2_PORT_NOT_ON_GUI) #define LV2_IS_PORT_TRIGGER(x) ((x) & LV2_PORT_TRIGGER) +#define LV2_IS_PORT_NON_AUTOMABLE(x) ((x) & LV2_PORT_NON_AUTOMABLE) // Port Designation #define LV2_PORT_DESIGNATION_CONTROL 1 @@ -184,6 +186,7 @@ typedef uint32_t LV2_Property; #define LV2_PORT_DESIGNATION_TIME_FRAME 11 #define LV2_PORT_DESIGNATION_TIME_FRAMES_PER_SECOND 12 #define LV2_PORT_DESIGNATION_TIME_SPEED 13 +#define LV2_PORT_DESIGNATION_TIME_TICKS_PER_BEAT 14 #define LV2_IS_PORT_DESIGNATION_CONTROL(x) ((x) == LV2_PORT_DESIGNATION_CONTROL) #define LV2_IS_PORT_DESIGNATION_FREEWHEELING(x) ((x) == LV2_PORT_DESIGNATION_FREEWHEELING) @@ -198,7 +201,8 @@ typedef uint32_t LV2_Property; #define LV2_IS_PORT_DESIGNATION_TIME_FRAME(x) ((x) == LV2_PORT_DESIGNATION_TIME_FRAME) #define LV2_IS_PORT_DESIGNATION_TIME_FRAMES_PER_SECOND(x) ((x) == LV2_PORT_DESIGNATION_TIME_FRAMES_PER_SECOND) #define LV2_IS_PORT_DESIGNATION_TIME_SPEED(x) ((x) == LV2_PORT_DESIGNATION_TIME_SPEED) -#define LV2_IS_PORT_DESIGNATION_TIME(x) ((x) >= LV2_PORT_DESIGNATION_TIME_BAR && (x) <= LV2_PORT_DESIGNATION_TIME_SPEED) +#define LV2_IS_PORT_DESIGNATION_TIME_TICKS_PER_BEAT(x) ((x) == LV2_PORT_DESIGNATION_TIME_TICKS_PER_BEAT) +#define LV2_IS_PORT_DESIGNATION_TIME(x) ((x) >= LV2_PORT_DESIGNATION_TIME_BAR && (x) <= LV2_PORT_DESIGNATION_TIME_TICKS_PER_BEAT) // Feature Types #define LV2_FEATURE_OPTIONAL 1 diff --git a/source/utils/CarlaLv2Utils.hpp b/source/utils/CarlaLv2Utils.hpp index fb2577e7a..2999cba6c 100644 --- a/source/utils/CarlaLv2Utils.hpp +++ b/source/utils/CarlaLv2Utils.hpp @@ -64,6 +64,7 @@ #include "lv2/lv2-miditype.h" #include "lv2/lv2-midifunctions.h" #include "lv2/lv2_external_ui.h" +#include "lv2/lv2_kxstudio_properties.h" #include "lv2/lv2_programs.h" #include "lv2/lv2_rtmempool.h" @@ -185,6 +186,7 @@ public: Lilv::Node pprop_notAutomatic; Lilv::Node pprop_notOnGUI; Lilv::Node pprop_trigger; + Lilv::Node pprop_nonAutomable; // Unit Hints Lilv::Node unit_name; @@ -309,6 +311,7 @@ public: pprop_notAutomatic (new_uri(LV2_PORT_PROPS__notAutomatic)), pprop_notOnGUI (new_uri(LV2_PORT_PROPS__notOnGUI)), pprop_trigger (new_uri(LV2_PORT_PROPS__trigger)), + pprop_nonAutomable (new_uri(LV2_KXSTUDIO_PROPERTIES__NonAutomable)), unit_name (new_uri(LV2_UNITS__name)), unit_render (new_uri(LV2_UNITS__render)), @@ -783,6 +786,8 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool loadPresets) rdfPort->Properties |= LV2_PORT_NOT_ON_GUI; if (lilvPort.has_property(lv2World.pprop_trigger)) rdfPort->Properties |= LV2_PORT_TRIGGER; + if (lilvPort.has_property(lv2World.pprop_nonAutomable)) + rdfPort->Properties |= LV2_PORT_NON_AUTOMABLE; if (lilvPort.has_property(lv2World.reportsLatency)) rdfPort->Designation = LV2_PORT_DESIGNATION_LATENCY; @@ -881,6 +886,8 @@ const LV2_RDF_Descriptor* lv2_rdf_new(const LV2_URI uri, const bool loadPresets) rdfPort->Designation = LV2_PORT_DESIGNATION_TIME_FRAMES_PER_SECOND; else if (std::strcmp(designation, LV2_TIME__speed) == 0) rdfPort->Designation = LV2_PORT_DESIGNATION_TIME_SPEED; + else if (std::strcmp(designation, LV2_KXSTUDIO_PROPERTIES__TimePositionTicksPerBeat) == 0) + rdfPort->Designation = LV2_PORT_DESIGNATION_TIME_TICKS_PER_BEAT; else if (std::strncmp(designation, LV2_PARAMETERS_PREFIX, std::strlen(LV2_PARAMETERS_PREFIX)) == 0) pass(); else if (std::strncmp(designation, LV2_PORT_GROUPS_PREFIX, std::strlen(LV2_PORT_GROUPS_PREFIX)) == 0)