Browse Source

Several fixes to LV2 time code; Misc changes

gh-pages
falkTX 10 years ago
parent
commit
087afb6134
4 changed files with 177 additions and 58 deletions
  1. +1
    -4
      distrho/src/DistrhoPluginJack.cpp
  2. +98
    -32
      distrho/src/DistrhoPluginLV2.cpp
  3. +26
    -20
      distrho/src/DistrhoPluginVST.cpp
  4. +52
    -2
      distrho/src/DistrhoUILV2.cpp

+ 1
- 4
distrho/src/DistrhoPluginJack.cpp View File

@@ -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)
{


+ 98
- 32
distrho/src/DistrhoPluginLV2.cpp View File

@@ -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
@@ -255,9 +256,6 @@ public:
#if DISTRHO_LV2_USE_EVENTS_IN
# 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)
{
@@ -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)


+ 26
- 20
distrho/src/DistrhoPluginVST.cpp View File

@@ -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



+ 52
- 2
distrho/src/DistrhoUILV2.cpp View File

@@ -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)


Loading…
Cancel
Save