commit 087afb6134acaedf270d10fc482e2df50b7d43e3
parent c8e754caafefa8cb736386cbd0a813856d21f7c8
Author: falkTX <falktx@gmail.com>
Date: Fri, 22 Aug 2014 02:57:01 +0100
Several fixes to LV2 time code; Misc changes
Diffstat:
4 files changed, 177 insertions(+), 58 deletions(-)
diff --git a/distrho/src/DistrhoPluginJack.cpp b/distrho/src/DistrhoPluginJack.cpp
@@ -203,10 +203,7 @@ protected:
if (pos.unique_1 == pos.unique_2)
{
- if (pos.valid & JackTransportPosition)
- fTimePosition.frame = pos.frame;
- else
- fTimePosition.frame = 0;
+ fTimePosition.frame = pos.frame;
if (pos.valid & JackTransportBBT)
{
diff --git a/distrho/src/DistrhoPluginLV2.cpp b/distrho/src/DistrhoPluginLV2.cpp
@@ -55,12 +55,13 @@ typedef std::map<const d_string,d_string> StringMap;
class PluginLv2
{
public:
- PluginLv2(const LV2_URID_Map* const uridMap, const LV2_Worker_Schedule* const worker)
+ PluginLv2(const double sampleRate, const LV2_URID_Map* const uridMap, const LV2_Worker_Schedule* const worker)
: fPortControls(nullptr),
fLastControlValues(nullptr),
+ fSampleRate(sampleRate),
#if DISTRHO_LV2_USE_EVENTS_IN || DISTRHO_LV2_USE_EVENTS_OUT
# if DISTRHO_PLUGIN_WANT_TIMEPOS
- fLastTimeSpeed(0.0f),
+ fLastTimeSpeed(0.0),
# endif
fURIDs(uridMap),
#endif
@@ -256,9 +257,6 @@ public:
# if DISTRHO_PLUGIN_HAS_MIDI_INPUT
uint32_t midiEventCount = 0;
# endif
-# if DISTRHO_PLUGIN_WANT_TIMEPOS
- bool needsFrameIncrement = true;
-# endif
LV2_ATOM_SEQUENCE_FOREACH(fPortEventsIn, event)
{
if (event == nullptr)
@@ -287,7 +285,7 @@ public:
}
# endif
# if DISTRHO_PLUGIN_WANT_TIMEPOS
- if (event->body.type == fURIDs.atomBlank)
+ if (event->body.type == fURIDs.atomBlank || event->body.type == fURIDs.atomObject)
{
const LV2_Atom_Object* const obj((const LV2_Atom_Object*)&event->body);
@@ -314,42 +312,71 @@ public:
fURIDs.timeSpeed, &speed,
nullptr);
- // TODO:
- // - tick
- // - barStartTick
- // - ticksPerBeat
+ // Not possible with LV2:
+ // -> barStartTick
+ // -> ticksPerBeat
+ fTimePosition.bbt.barStartTick = 0.0;
+ fTimePosition.bbt.ticksPerBeat = 960.0;
if (bar != nullptr)
{
- if (bar->type == fURIDs.atomDouble)
- fTimePosition.bbt.bar = ((LV2_Atom_Double*)bar)->body + 1.0f;
+ /**/ if (bar->type == fURIDs.atomDouble)
+ fTimePosition.bbt.bar = ((LV2_Atom_Double*)bar)->body + 1.0;
else if (bar->type == fURIDs.atomFloat)
fTimePosition.bbt.bar = ((LV2_Atom_Float*)bar)->body + 1.0f;
else if (bar->type == fURIDs.atomInt)
fTimePosition.bbt.bar = ((LV2_Atom_Int*)bar)->body + 1;
else if (bar->type == fURIDs.atomLong)
fTimePosition.bbt.bar = ((LV2_Atom_Long*)bar)->body + 1;
+ else
+ d_stderr("Unknown lv2 bar value type");
}
- /*if (barBeat != nullptr && barBeat->type == fURIDs.atomFloat)
+ if (barBeat != nullptr)
{
- }*/
-
- if (beat != nullptr)
+ double barBeatValue = 0.0;
+
+ /**/ if (barBeat->type == fURIDs.atomDouble)
+ barBeatValue = ((LV2_Atom_Double*)barBeat)->body + 1.0;
+ else if (barBeat->type == fURIDs.atomFloat)
+ barBeatValue = ((LV2_Atom_Float*)barBeat)->body + 1.0f;
+ else if (barBeat->type == fURIDs.atomInt)
+ barBeatValue = ((LV2_Atom_Int*)barBeat)->body + 1;
+ else if (barBeat->type == fURIDs.atomLong)
+ barBeatValue = ((LV2_Atom_Long*)barBeat)->body + 1;
+ else
+ d_stderr("Unknown lv2 barBeat value type");
+
+ if (barBeatValue != 0.0)
+ {
+ const double beat = std::floor(barBeatValue);
+ fTimePosition.bbt.beat = beat;
+ fTimePosition.bbt.tick = (barBeatValue-beat)*fTimePosition.bbt.ticksPerBeat;
+ }
+ else
+ {
+ fTimePosition.bbt.beat = 0;
+ fTimePosition.bbt.tick = 0;
+ }
+ }
+ // barBeat includes beat
+ else if (beat != nullptr)
{
- if (beat->type == fURIDs.atomDouble)
- fTimePosition.bbt.beat = ((LV2_Atom_Double*)beat)->body + 1.0f;
+ /**/ if (beat->type == fURIDs.atomDouble)
+ fTimePosition.bbt.beat = ((LV2_Atom_Double*)beat)->body + 1.0;
else if (beat->type == fURIDs.atomFloat)
fTimePosition.bbt.beat = ((LV2_Atom_Float*)beat)->body + 1.0f;
else if (beat->type == fURIDs.atomInt)
fTimePosition.bbt.beat = ((LV2_Atom_Int*)beat)->body + 1;
else if (beat->type == fURIDs.atomLong)
fTimePosition.bbt.beat = ((LV2_Atom_Long*)beat)->body + 1;
+ else
+ d_stderr("Unknown lv2 beat value type");
}
if (beatUnit != nullptr)
{
- if (beatUnit->type == fURIDs.atomDouble)
+ /**/ if (beatUnit->type == fURIDs.atomDouble)
fTimePosition.bbt.beatType = ((LV2_Atom_Double*)beatUnit)->body;
else if (beatUnit->type == fURIDs.atomFloat)
fTimePosition.bbt.beatType = ((LV2_Atom_Float*)beatUnit)->body;
@@ -357,11 +384,13 @@ public:
fTimePosition.bbt.beatType = ((LV2_Atom_Int*)beatUnit)->body;
else if (beatUnit->type == fURIDs.atomLong)
fTimePosition.bbt.beatType = ((LV2_Atom_Long*)beatUnit)->body;
+ else
+ d_stderr("Unknown lv2 beatUnit value type");
}
if (beatsPerBar != nullptr)
{
- if (beatsPerBar->type == fURIDs.atomDouble)
+ /**/ if (beatsPerBar->type == fURIDs.atomDouble)
fTimePosition.bbt.beatsPerBar = ((LV2_Atom_Double*)beatsPerBar)->body;
else if (beatsPerBar->type == fURIDs.atomFloat)
fTimePosition.bbt.beatsPerBar = ((LV2_Atom_Float*)beatsPerBar)->body;
@@ -369,11 +398,13 @@ public:
fTimePosition.bbt.beatsPerBar = ((LV2_Atom_Int*)beatsPerBar)->body;
else if (beatsPerBar->type == fURIDs.atomLong)
fTimePosition.bbt.beatsPerBar = ((LV2_Atom_Long*)beatsPerBar)->body;
+ else
+ d_stderr("Unknown lv2 beatsPerBar value type");
}
if (beatsPerMinute != nullptr)
{
- if (beatsPerMinute->type == fURIDs.atomDouble)
+ /**/ if (beatsPerMinute->type == fURIDs.atomDouble)
fTimePosition.bbt.beatsPerMinute = ((LV2_Atom_Double*)beatsPerMinute)->body;
else if (beatsPerMinute->type == fURIDs.atomFloat)
fTimePosition.bbt.beatsPerMinute = ((LV2_Atom_Float*)beatsPerMinute)->body;
@@ -381,23 +412,20 @@ public:
fTimePosition.bbt.beatsPerMinute = ((LV2_Atom_Int*)beatsPerMinute)->body;
else if (beatsPerMinute->type == fURIDs.atomLong)
fTimePosition.bbt.beatsPerMinute = ((LV2_Atom_Long*)beatsPerMinute)->body;
+ else
+ d_stderr("Unknown lv2 beatsPerMinute value type");
}
if (frame != nullptr && frame->type == fURIDs.atomLong)
- {
fTimePosition.frame = ((LV2_Atom_Long*)frame)->body;
- needsFrameIncrement = false;
- }
if (speed != nullptr && speed->type == fURIDs.atomFloat)
{
fLastTimeSpeed = ((LV2_Atom_Float*)speed)->body;
- fTimePosition.playing = (fLastTimeSpeed == 1.0f);
+ fTimePosition.playing = (fLastTimeSpeed == 1.0);
}
- if ((! fTimePosition.bbt.valid) && beatsPerMinute != nullptr && beatsPerBar != nullptr && beatUnit != nullptr)
- fTimePosition.bbt.valid = true;
-
+ fTimePosition.bbt.valid = (beatsPerMinute != nullptr && beatsPerBar != nullptr && beatUnit != nullptr);
continue;
}
# endif
@@ -425,8 +453,6 @@ public:
#endif
# if DISTRHO_PLUGIN_WANT_TIMEPOS
- if (needsFrameIncrement && fLastTimeSpeed != 0.0f)
- fTimePosition.frame += fLastTimeSpeed*sampleCount;
fPlugin.setTimePosition(fTimePosition);
# endif
@@ -436,6 +462,42 @@ public:
fPlugin.run(fPortAudioIns, fPortAudioOuts, sampleCount);
#endif
+# if DISTRHO_PLUGIN_WANT_TIMEPOS
+ // update timePos for next callback
+ if (fLastTimeSpeed != 0.0)
+ {
+ const double newFrames = fLastTimeSpeed*sampleCount;
+
+ fTimePosition.frame += newFrames;
+
+ if (fTimePosition.bbt.valid)
+ {
+ const double samplesPerBeat = 60.0 / fTimePosition.bbt.beatsPerMinute * fSampleRate;
+ const double ticksPerSample = fTimePosition.bbt.ticksPerBeat / samplesPerBeat;
+
+ double newTickPos = double(fTimePosition.bbt.tick) + ticksPerSample*newFrames;
+ double newBeatPos = double(fTimePosition.bbt.beat)-1.0;
+ double newBarPos = double(fTimePosition.bbt.bar)-1.0;
+
+ for (; newTickPos >= fTimePosition.bbt.ticksPerBeat;)
+ {
+ ++newBeatPos;
+ newTickPos -= fTimePosition.bbt.ticksPerBeat;
+ }
+
+ for (; newBeatPos >= fTimePosition.bbt.beatsPerBar;)
+ {
+ ++newBarPos;
+ newBeatPos -= fTimePosition.bbt.beatsPerBar;
+ }
+
+ fTimePosition.bbt.bar = newBarPos+1.0;
+ fTimePosition.bbt.beat = newBeatPos+1.0;
+ fTimePosition.bbt.tick = newTickPos;
+ }
+ }
+# endif
+
updateParameterOutputs();
#if DISTRHO_LV2_USE_EVENTS_OUT
@@ -538,6 +600,7 @@ public:
if (options[i].type == fUridMap->map(fUridMap->handle, LV2_ATOM__Double))
{
const double sampleRate(*(const double*)options[i].value);
+ fSampleRate = sampleRate;
fPlugin.setSampleRate(sampleRate);
continue;
}
@@ -697,18 +760,20 @@ private:
// Temporary data
float* fLastControlValues;
+ double fSampleRate;
#if DISTRHO_PLUGIN_HAS_MIDI_INPUT
MidiEvent fMidiEvents[kMaxMidiEvents];
#endif
#if DISTRHO_PLUGIN_WANT_TIMEPOS
TimePosition fTimePosition;
- float fLastTimeSpeed;
+ double fLastTimeSpeed;
#endif
// LV2 URIDs
#if DISTRHO_LV2_USE_EVENTS_IN || DISTRHO_LV2_USE_EVENTS_OUT
struct URIDs {
LV2_URID atomBlank;
+ LV2_URID atomObject;
LV2_URID atomDouble;
LV2_URID atomFloat;
LV2_URID atomInt;
@@ -729,6 +794,7 @@ private:
URIDs(const LV2_URID_Map* const uridMap)
: atomBlank(uridMap->map(uridMap->handle, LV2_ATOM__Blank)),
+ atomObject(uridMap->map(uridMap->handle, LV2_ATOM__Object)),
atomDouble(uridMap->map(uridMap->handle, LV2_ATOM__Double)),
atomFloat(uridMap->map(uridMap->handle, LV2_ATOM__Float)),
atomInt(uridMap->map(uridMap->handle, LV2_ATOM__Int)),
@@ -862,7 +928,7 @@ static LV2_Handle lv2_instantiate(const LV2_Descriptor*, double sampleRate, cons
d_lastSampleRate = sampleRate;
- return new PluginLv2(uridMap, worker);
+ return new PluginLv2(sampleRate, uridMap, worker);
}
#define instancePtr ((PluginLv2*)instance)
diff --git a/distrho/src/DistrhoPluginVST.cpp b/distrho/src/DistrhoPluginVST.cpp
@@ -16,8 +16,6 @@
#include "DistrhoPluginInternal.hpp"
-#define DISTRHO_PLUGIN_HAS_UI 1
-
#if DISTRHO_PLUGIN_HAS_UI
# include "DistrhoUIInternal.hpp"
#endif
@@ -153,6 +151,11 @@ public:
return fUI.getHeight();
}
+ void setSampleRate(const double newSampleRate)
+ {
+ fUI.setSampleRate(newSampleRate, true);
+ }
+
// -------------------------------------------------------------------
// functions called from the plugin side, may block
@@ -279,7 +282,7 @@ public:
#endif
#if DISTRHO_PLUGIN_HAS_UI
- fVstUi = nullptr;
+ fVstUI = nullptr;
fVstRect.top = 0;
fVstRect.left = 0;
fVstRect.bottom = 0;
@@ -363,6 +366,9 @@ public:
case effSetSampleRate:
fPlugin.setSampleRate(opt, true);
+
+ if (fVstUI != nullptr)
+ fVstUI->setSampleRate(opt);
break;
case effSetBlockSize:
@@ -385,10 +391,10 @@ public:
#if DISTRHO_PLUGIN_HAS_UI
case effEditGetRect:
- if (fVstUi != nullptr)
+ if (fVstUI != nullptr)
{
- fVstRect.right = fVstUi->getWidth();
- fVstRect.bottom = fVstUi->getHeight();
+ fVstRect.right = fVstUI->getWidth();
+ fVstRect.bottom = fVstUI->getHeight();
}
else
{
@@ -403,7 +409,7 @@ public:
return 1;
case effEditOpen:
- if (fVstUi == nullptr)
+ if (fVstUI == nullptr)
{
# if DISTRHO_OS_MAC && ! defined(__LP64__)
if ((fEffect->dispatcher(fEffect, effCanDo, 0, 0, (void*)"hasCockosViewAsConfig", 0.0f) & 0xffff0000) != 0xbeef0000)
@@ -411,7 +417,7 @@ public:
# endif
d_lastUiSampleRate = fPlugin.getSampleRate();
- fVstUi = new UIVst(fAudioMaster, fEffect, this, &fPlugin, (intptr_t)ptr);
+ fVstUI = new UIVst(fAudioMaster, fEffect, this, &fPlugin, (intptr_t)ptr);
# if DISTRHO_PLUGIN_WANT_STATE
for (StringMap::const_iterator cit=fStateMap.cbegin(), cite=fStateMap.cend(); cit != cite; ++cit)
@@ -419,30 +425,30 @@ public:
const d_string& key = cit->first;
const d_string& value = cit->second;
- fVstUi->setStateFromPlugin(key, value);
+ fVstUI->setStateFromPlugin(key, value);
}
# endif
for (uint32_t i=0, count=fPlugin.getParameterCount(); i < count; ++i)
setParameterValueFromPlugin(i, fPlugin.getParameterValue(i));
- fVstUi->idle();
+ fVstUI->idle();
return 1;
}
break;
case effEditClose:
- if (fVstUi != nullptr)
+ if (fVstUI != nullptr)
{
- delete fVstUi;
- fVstUi = nullptr;
+ delete fVstUI;
+ fVstUI = nullptr;
return 1;
}
break;
//case effIdle:
case effEditIdle:
- if (fVstUi != nullptr)
- fVstUi->idle();
+ if (fVstUI != nullptr)
+ fVstUI->idle();
break;
#endif // DISTRHO_PLUGIN_HAS_UI
@@ -517,8 +523,8 @@ public:
setStateFromUI(key, value);
- if (fVstUi != nullptr)
- fVstUi->setStateFromPlugin(key, value);
+ if (fVstUI != nullptr)
+ fVstUI->setStateFromPlugin(key, value);
// get next key
key = value+(std::strlen(value)+1);
@@ -610,7 +616,7 @@ public:
fPlugin.setParameterValue(index, realValue);
#if DISTRHO_PLUGIN_HAS_UI
- if (fVstUi != nullptr)
+ if (fVstUI != nullptr)
setParameterValueFromPlugin(index, realValue);
#endif
}
@@ -648,7 +654,7 @@ public:
#endif
#if DISTRHO_PLUGIN_HAS_UI
- if (fVstUi == nullptr)
+ if (fVstUI == nullptr)
return;
for (uint32_t i=0, count=fPlugin.getParameterCount(); i < count; ++i)
@@ -685,7 +691,7 @@ private:
// UI stuff
#if DISTRHO_PLUGIN_HAS_UI
- UIVst* fVstUi;
+ UIVst* fVstUI;
ERect fVstRect;
#endif
diff --git a/distrho/src/DistrhoUILV2.cpp b/distrho/src/DistrhoUILV2.cpp
@@ -27,6 +27,8 @@
#include "lv2/urid.h"
#include "lv2/lv2_programs.h"
+// TODO - UI setSampleRate changes
+
START_NAMESPACE_DISTRHO
// -----------------------------------------------------------------------
@@ -147,6 +149,37 @@ public:
// -------------------------------------------------------------------
+ uint32_t lv2_get_options(LV2_Options_Option* const /*options*/)
+ {
+ // currently unused
+ return LV2_OPTIONS_ERR_UNKNOWN;
+ }
+
+ uint32_t lv2_set_options(const LV2_Options_Option* const options)
+ {
+ for (int i=0; options[i].key != 0; ++i)
+ {
+ if (options[i].key == fUridMap->map(fUridMap->handle, LV2_CORE__sampleRate))
+ {
+ if (options[i].type == fUridMap->map(fUridMap->handle, LV2_ATOM__Double))
+ {
+ const double sampleRate(*(const double*)options[i].value);
+ fUI.setSampleRate(sampleRate);
+ continue;
+ }
+ else
+ {
+ d_stderr("Host changed sampleRate but with wrong value type");
+ continue;
+ }
+ }
+ }
+
+ return LV2_OPTIONS_SUCCESS;
+ }
+
+ // -------------------------------------------------------------------
+
#if DISTRHO_PLUGIN_WANT_PROGRAMS
void lv2ui_select_program(const uint32_t bank, const uint32_t program)
{
@@ -403,6 +436,20 @@ static int lv2ui_hide(LV2UI_Handle ui)
return uiPtr->lv2ui_hide();
}
+// -----------------------------------------------------------------------
+
+static uint32_t lv2_get_options(LV2UI_Handle ui, LV2_Options_Option* options)
+{
+ return uiPtr->lv2_get_options(options);
+}
+
+static uint32_t lv2_set_options(LV2UI_Handle ui, const LV2_Options_Option* options)
+{
+ return uiPtr->lv2_set_options(options);
+}
+
+// -----------------------------------------------------------------------
+
#if DISTRHO_PLUGIN_WANT_PROGRAMS
static void lv2ui_select_program(LV2UI_Handle ui, uint32_t bank, uint32_t program)
{
@@ -414,9 +461,12 @@ static void lv2ui_select_program(LV2UI_Handle ui, uint32_t bank, uint32_t progra
static const void* lv2ui_extension_data(const char* uri)
{
- static const LV2UI_Idle_Interface uiIdle = { lv2ui_idle };
- static const LV2UI_Show_Interface uiShow = { lv2ui_show, lv2ui_hide };
+ static const LV2_Options_Interface options = { lv2_get_options, lv2_set_options };
+ static const LV2UI_Idle_Interface uiIdle = { lv2ui_idle };
+ static const LV2UI_Show_Interface uiShow = { lv2ui_show, lv2ui_hide };
+ if (std::strcmp(uri, LV2_OPTIONS__interface) == 0)
+ return &options;
if (std::strcmp(uri, LV2_UI__idleInterface) == 0)
return &uiIdle;
if (std::strcmp(uri, LV2_UI__showInterface) == 0)