diff --git a/distrho/src/DistrhoPluginLV2.cpp b/distrho/src/DistrhoPluginLV2.cpp index 17b94035..ba3c1c7e 100644 --- a/distrho/src/DistrhoPluginLV2.cpp +++ b/distrho/src/DistrhoPluginLV2.cpp @@ -27,6 +27,7 @@ #include "lv2/time.h" #include "lv2/urid.h" #include "lv2/worker.h" +#include "lv2/lv2_kxstudio_properties.h" #include "lv2/lv2_programs.h" #ifdef noexcept @@ -127,6 +128,19 @@ public: fNeededUiSends = nullptr; } #endif + +#if DISTRHO_PLUGIN_WANT_TIMEPOS + // hosts may not send all values, resulting on some invalid ones + fTimePosition.bbt.valid = false; + fTimePosition.bbt.bar = 1; + fTimePosition.bbt.beat = 1; + fTimePosition.bbt.tick = 0; + fTimePosition.bbt.barStartTick = 0; + fTimePosition.bbt.beatsPerBar = 4; + fTimePosition.bbt.beatType = 4; + fTimePosition.bbt.ticksPerBeat = 960.0; + fTimePosition.bbt.beatsPerMinute = 120.0; +#endif } ~PluginLv2() @@ -298,6 +312,7 @@ public: LV2_Atom* beatUnit = nullptr; LV2_Atom* beatsPerBar = nullptr; LV2_Atom* beatsPerMinute = nullptr; + LV2_Atom* ticksPerBeat = nullptr; LV2_Atom* frame = nullptr; LV2_Atom* speed = nullptr; @@ -308,13 +323,11 @@ public: fURIDs.timeBeatUnit, &beatUnit, fURIDs.timeBeatsPerBar, &beatsPerBar, fURIDs.timeBeatsPerMinute, &beatsPerMinute, + fURIDs.timeTicksPerBeat, &ticksPerBeat, fURIDs.timeFrame, &frame, fURIDs.timeSpeed, &speed, nullptr); - // ticksPerBeat is not possible with LV2 - fTimePosition.bbt.ticksPerBeat = 960.0; - if (bar != nullptr) { /**/ if (bar->type == fURIDs.atomDouble) @@ -329,6 +342,20 @@ public: d_stderr("Unknown lv2 bar value type"); } + if (ticksPerBeat != nullptr) + { + /**/ if (ticksPerBeat->type == fURIDs.atomDouble) + fTimePosition.bbt.ticksPerBeat = ((LV2_Atom_Double*)ticksPerBeat)->body; + else if (ticksPerBeat->type == fURIDs.atomFloat) + fTimePosition.bbt.ticksPerBeat = ((LV2_Atom_Float*)ticksPerBeat)->body; + else if (ticksPerBeat->type == fURIDs.atomInt) + fTimePosition.bbt.ticksPerBeat = ((LV2_Atom_Int*)ticksPerBeat)->body; + else if (ticksPerBeat->type == fURIDs.atomLong) + fTimePosition.bbt.ticksPerBeat = ((LV2_Atom_Long*)ticksPerBeat)->body; + else + d_stderr("Unknown lv2 ticksPerBeat value type"); + } + if (barBeat != nullptr) { double barBeatValue = 0.0; @@ -781,6 +808,7 @@ private: LV2_URID timeBeatUnit; LV2_URID timeBeatsPerBar; LV2_URID timeBeatsPerMinute; + LV2_URID timeTicksPerBeat; LV2_URID timeFrame; LV2_URID timeSpeed; @@ -802,6 +830,7 @@ private: timeBeatUnit(uridMap->map(uridMap->handle, LV2_TIME__beatUnit)), timeBeatsPerBar(uridMap->map(uridMap->handle, LV2_TIME__beatsPerBar)), timeBeatsPerMinute(uridMap->map(uridMap->handle, LV2_TIME__beatsPerMinute)), + timeTicksPerBeat(uridMap->map(uridMap->handle, LV2_KXSTUDIO_PROPERTIES__TimePositionTicksPerBeat)), timeFrame(uridMap->map(uridMap->handle, LV2_TIME__frame)), timeSpeed(uridMap->map(uridMap->handle, LV2_TIME__speed)) {} } fURIDs; diff --git a/distrho/src/DistrhoPluginLV2export.cpp b/distrho/src/DistrhoPluginLV2export.cpp index 33ad8ecf..0fd0bc7f 100644 --- a/distrho/src/DistrhoPluginLV2export.cpp +++ b/distrho/src/DistrhoPluginLV2export.cpp @@ -22,6 +22,7 @@ #include "lv2/instance-access.h" #include "lv2/midi.h" #include "lv2/options.h" +#include "lv2/port-props.h" #include "lv2/resize-port.h" #include "lv2/state.h" #include "lv2/time.h" @@ -29,6 +30,7 @@ #include "lv2/units.h" #include "lv2/urid.h" #include "lv2/worker.h" +#include "lv2/lv2_kxstudio_properties.h" #include "lv2/lv2_programs.h" #include @@ -378,9 +380,10 @@ void lv2_generate_ttl(const char* const basename) if (hints & kParameterIsInteger) pluginString += " lv2:portProperty lv2:integer ;\n"; if (hints & kParameterIsLogarithmic) - pluginString += " lv2:portProperty ;\n"; + pluginString += " lv2:portProperty <" LV2_PORT_PROPS__logarithmic "> ;\n"; if ((hints & kParameterIsAutomable) == 0 && ! plugin.isParameterOutput(i)) - pluginString += " lv2:portProperty ;\n"; + pluginString += " lv2:portProperty <" LV2_PORT_PROPS__expensive "> ,\n"; + pluginString += " <" LV2_KXSTUDIO_PROPERTIES__NonAutomable "> ;\n"; } if (i+1 == count) diff --git a/distrho/src/DistrhoUILV2.cpp b/distrho/src/DistrhoUILV2.cpp index d525b5fe..4de5346c 100644 --- a/distrho/src/DistrhoUILV2.cpp +++ b/distrho/src/DistrhoUILV2.cpp @@ -25,6 +25,7 @@ #include "lv2/options.h" #include "lv2/ui.h" #include "lv2/urid.h" +#include "lv2/lv2_kxstudio_properties.h" #include "lv2/lv2_programs.h" START_NAMESPACE_DISTRHO @@ -62,21 +63,21 @@ public: DISTRHO_SAFE_ASSERT_RETURN(options != nullptr,); const LV2_URID uridWindowTitle(uridMap->map(uridMap->handle, LV2_UI__windowTitle)); - const LV2_URID uridFrontendWinId(uridMap->map(uridMap->handle, "http://kxstudio.sf.net/ns/carla/frontendWinId")); + const LV2_URID uridTransientWinId(uridMap->map(uridMap->handle, LV2_KXSTUDIO_PROPERTIES__TransientWindowId)); bool hasTitle = false; for (int i=0; options[i].key != 0; ++i) { - if (options[i].key == uridFrontendWinId) + if (options[i].key == uridTransientWinId) { if (options[i].type == uridMap->map(uridMap->handle, LV2_ATOM__Long)) { - if (const int64_t frontendWinId = *(const int64_t*)options[i].value) - fUI.setWindowTransientWinId(static_cast(frontendWinId)); + if (const int64_t transientWinId = *(const int64_t*)options[i].value) + fUI.setWindowTransientWinId(static_cast(transientWinId)); } else - d_stderr("Host provides frontendWinId but has wrong value type"); + d_stderr("Host provides transientWinId but has wrong value type"); } else if (options[i].key == uridWindowTitle) { diff --git a/distrho/src/lv2/lv2_kxstudio_properties.h b/distrho/src/lv2/lv2_kxstudio_properties.h new file mode 100644 index 00000000..e8b42a6c --- /dev/null +++ b/distrho/src/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 */