|
@@ -52,13 +52,12 @@ typedef std::map<const String, String> StringMap; |
|
|
class PluginLv2 |
|
|
class PluginLv2 |
|
|
{ |
|
|
{ |
|
|
public: |
|
|
public: |
|
|
PluginLv2(const double sampleRate, const LV2_URID_Map* const uridMap, const LV2_Worker_Schedule* const worker) |
|
|
|
|
|
: fPortControls(nullptr), |
|
|
|
|
|
|
|
|
PluginLv2(const double sampleRate, const LV2_URID_Map* const uridMap, const LV2_Worker_Schedule* const worker, const bool usingNominal) |
|
|
|
|
|
: fUsingNominal(usingNominal), |
|
|
|
|
|
fPortControls(nullptr), |
|
|
fLastControlValues(nullptr), |
|
|
fLastControlValues(nullptr), |
|
|
fSampleRate(sampleRate), |
|
|
fSampleRate(sampleRate), |
|
|
#if DISTRHO_LV2_USE_EVENTS_IN || DISTRHO_LV2_USE_EVENTS_OUT |
|
|
|
|
|
fURIDs(uridMap), |
|
|
fURIDs(uridMap), |
|
|
#endif |
|
|
|
|
|
fUridMap(uridMap), |
|
|
fUridMap(uridMap), |
|
|
fWorker(worker) |
|
|
fWorker(worker) |
|
|
{ |
|
|
{ |
|
@@ -124,18 +123,6 @@ public: |
|
|
// unused |
|
|
// unused |
|
|
(void)fWorker; |
|
|
(void)fWorker; |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
#if DISTRHO_PLUGIN_WANT_TIMEPOS |
|
|
|
|
|
// hosts may not send all values, resulting on some invalid data |
|
|
|
|
|
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() |
|
|
~PluginLv2() |
|
@@ -167,6 +154,19 @@ public: |
|
|
|
|
|
|
|
|
void lv2_activate() |
|
|
void lv2_activate() |
|
|
{ |
|
|
{ |
|
|
|
|
|
#if DISTRHO_PLUGIN_WANT_TIMEPOS |
|
|
|
|
|
std::memset(&fTimePosition, 0, sizeof(TimePosition)); |
|
|
|
|
|
|
|
|
|
|
|
// hosts may not send all values, resulting on some invalid data |
|
|
|
|
|
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 |
|
|
fPlugin.activate(); |
|
|
fPlugin.activate(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@@ -321,7 +321,7 @@ public: |
|
|
else |
|
|
else |
|
|
d_stderr("Unknown lv2 ticksPerBeat value type"); |
|
|
d_stderr("Unknown lv2 ticksPerBeat value type"); |
|
|
|
|
|
|
|
|
if (fLastPositionData.ticksPerBeat > 0) |
|
|
|
|
|
|
|
|
if (fLastPositionData.ticksPerBeat > 0.0) |
|
|
fTimePosition.bbt.ticksPerBeat = fLastPositionData.ticksPerBeat; |
|
|
fTimePosition.bbt.ticksPerBeat = fLastPositionData.ticksPerBeat; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@@ -574,6 +574,8 @@ public: |
|
|
|
|
|
|
|
|
fTimePosition.bbt.beatsPerMinute = std::abs(beatsPerMinute); |
|
|
fTimePosition.bbt.beatsPerMinute = std::abs(beatsPerMinute); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fPlugin.setTimePosition(fTimePosition); |
|
|
} |
|
|
} |
|
|
#endif |
|
|
#endif |
|
|
} |
|
|
} |
|
@@ -660,31 +662,39 @@ public: |
|
|
{ |
|
|
{ |
|
|
if (options[i].key == fUridMap->map(fUridMap->handle, LV2_BUF_SIZE__nominalBlockLength)) |
|
|
if (options[i].key == fUridMap->map(fUridMap->handle, LV2_BUF_SIZE__nominalBlockLength)) |
|
|
{ |
|
|
{ |
|
|
if (options[i].type == fUridMap->map(fUridMap->handle, LV2_ATOM__Int)) |
|
|
|
|
|
|
|
|
if (options[i].type == fURIDs.atomInt) |
|
|
{ |
|
|
{ |
|
|
const int bufferSize(*(const int*)options[i].value); |
|
|
const int bufferSize(*(const int*)options[i].value); |
|
|
fPlugin.setBufferSize(bufferSize); |
|
|
fPlugin.setBufferSize(bufferSize); |
|
|
continue; |
|
|
|
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
|
d_stderr("Host changed nominalBlockLength but with wrong value type"); |
|
|
d_stderr("Host changed nominalBlockLength but with wrong value type"); |
|
|
continue; |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
else if (options[i].key == fUridMap->map(fUridMap->handle, LV2_BUF_SIZE__maxBlockLength) && ! fUsingNominal) |
|
|
|
|
|
{ |
|
|
|
|
|
if (options[i].type == fURIDs.atomInt) |
|
|
|
|
|
{ |
|
|
|
|
|
const int bufferSize(*(const int*)options[i].value); |
|
|
|
|
|
fPlugin.setBufferSize(bufferSize); |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
d_stderr("Host changed maxBlockLength but with wrong value type"); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
else if (options[i].key == fUridMap->map(fUridMap->handle, LV2_CORE__sampleRate)) |
|
|
else if (options[i].key == fUridMap->map(fUridMap->handle, LV2_CORE__sampleRate)) |
|
|
{ |
|
|
{ |
|
|
if (options[i].type == fUridMap->map(fUridMap->handle, LV2_ATOM__Double)) |
|
|
|
|
|
|
|
|
if (options[i].type == fURIDs.atomDouble) |
|
|
{ |
|
|
{ |
|
|
const double sampleRate(*(const double*)options[i].value); |
|
|
const double sampleRate(*(const double*)options[i].value); |
|
|
fSampleRate = sampleRate; |
|
|
fSampleRate = sampleRate; |
|
|
fPlugin.setSampleRate(sampleRate); |
|
|
fPlugin.setSampleRate(sampleRate); |
|
|
continue; |
|
|
|
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
|
d_stderr("Host changed sampleRate but with wrong value type"); |
|
|
d_stderr("Host changed sampleRate but with wrong value type"); |
|
|
continue; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@@ -812,6 +822,7 @@ public: |
|
|
|
|
|
|
|
|
private: |
|
|
private: |
|
|
PluginExporter fPlugin; |
|
|
PluginExporter fPlugin; |
|
|
|
|
|
const bool fUsingNominal; // if false use maxBlockLength |
|
|
|
|
|
|
|
|
// LV2 ports |
|
|
// LV2 ports |
|
|
#if DISTRHO_PLUGIN_NUM_INPUTS > 0 |
|
|
#if DISTRHO_PLUGIN_NUM_INPUTS > 0 |
|
@@ -852,7 +863,7 @@ private: |
|
|
float beatsPerMinute; |
|
|
float beatsPerMinute; |
|
|
int64_t frame; |
|
|
int64_t frame; |
|
|
double speed; |
|
|
double speed; |
|
|
int64_t ticksPerBeat; |
|
|
|
|
|
|
|
|
double ticksPerBeat; |
|
|
|
|
|
|
|
|
Lv2PositionData() |
|
|
Lv2PositionData() |
|
|
: bar(-1), |
|
|
: bar(-1), |
|
@@ -862,13 +873,12 @@ private: |
|
|
beatsPerMinute(0.0f), |
|
|
beatsPerMinute(0.0f), |
|
|
frame(-1), |
|
|
frame(-1), |
|
|
speed(0.0), |
|
|
speed(0.0), |
|
|
ticksPerBeat(-1) {} |
|
|
|
|
|
|
|
|
ticksPerBeat(-1.0) {} |
|
|
|
|
|
|
|
|
} fLastPositionData; |
|
|
} fLastPositionData; |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
// LV2 URIDs |
|
|
// LV2 URIDs |
|
|
#if DISTRHO_LV2_USE_EVENTS_IN || DISTRHO_LV2_USE_EVENTS_OUT |
|
|
|
|
|
struct URIDs { |
|
|
struct URIDs { |
|
|
LV2_URID atomBlank; |
|
|
LV2_URID atomBlank; |
|
|
LV2_URID atomObject; |
|
|
LV2_URID atomObject; |
|
@@ -911,7 +921,6 @@ private: |
|
|
timeFrame(uridMap->map(uridMap->handle, LV2_TIME__frame)), |
|
|
timeFrame(uridMap->map(uridMap->handle, LV2_TIME__frame)), |
|
|
timeSpeed(uridMap->map(uridMap->handle, LV2_TIME__speed)) {} |
|
|
timeSpeed(uridMap->map(uridMap->handle, LV2_TIME__speed)) {} |
|
|
} fURIDs; |
|
|
} fURIDs; |
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
// LV2 features |
|
|
// LV2 features |
|
|
const LV2_URID_Map* const fUridMap; |
|
|
const LV2_URID_Map* const fUridMap; |
|
@@ -1004,29 +1013,44 @@ static LV2_Handle lv2_instantiate(const LV2_Descriptor*, double sampleRate, cons |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
d_lastBufferSize = 0; |
|
|
d_lastBufferSize = 0; |
|
|
|
|
|
bool usingNominal = false; |
|
|
|
|
|
|
|
|
for (int i=0; options[i].key != 0; ++i) |
|
|
for (int i=0; options[i].key != 0; ++i) |
|
|
{ |
|
|
{ |
|
|
if (options[i].key == uridMap->map(uridMap->handle, LV2_BUF_SIZE__nominalBlockLength)) |
|
|
if (options[i].key == uridMap->map(uridMap->handle, LV2_BUF_SIZE__nominalBlockLength)) |
|
|
{ |
|
|
{ |
|
|
if (options[i].type == uridMap->map(uridMap->handle, LV2_ATOM__Int)) |
|
|
if (options[i].type == uridMap->map(uridMap->handle, LV2_ATOM__Int)) |
|
|
|
|
|
{ |
|
|
d_lastBufferSize = *(const int*)options[i].value; |
|
|
d_lastBufferSize = *(const int*)options[i].value; |
|
|
|
|
|
usingNominal = true; |
|
|
|
|
|
} |
|
|
else |
|
|
else |
|
|
|
|
|
{ |
|
|
d_stderr("Host provides nominalBlockLength but has wrong value type"); |
|
|
d_stderr("Host provides nominalBlockLength but has wrong value type"); |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (options[i].key == uridMap->map(uridMap->handle, LV2_BUF_SIZE__maxBlockLength)) |
|
|
|
|
|
{ |
|
|
|
|
|
if (options[i].type == uridMap->map(uridMap->handle, LV2_ATOM__Int)) |
|
|
|
|
|
d_lastBufferSize = *(const int*)options[i].value; |
|
|
|
|
|
else |
|
|
|
|
|
d_stderr("Host provides maxBlockLength but has wrong value type"); |
|
|
|
|
|
|
|
|
|
|
|
// no break, continue in case host supports nominalBlockLength |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (d_lastBufferSize == 0) |
|
|
if (d_lastBufferSize == 0) |
|
|
{ |
|
|
{ |
|
|
d_stderr("Host does not provide nominalBlockLength option"); |
|
|
|
|
|
|
|
|
d_stderr("Host does not provide nominalBlockLength or maxBlockLength options"); |
|
|
d_lastBufferSize = 2048; |
|
|
d_lastBufferSize = 2048; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
d_lastSampleRate = sampleRate; |
|
|
d_lastSampleRate = sampleRate; |
|
|
|
|
|
|
|
|
return new PluginLv2(sampleRate, uridMap, worker); |
|
|
|
|
|
|
|
|
return new PluginLv2(sampleRate, uridMap, worker, usingNominal); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#define instancePtr ((PluginLv2*)instance) |
|
|
#define instancePtr ((PluginLv2*)instance) |
|
|