Browse Source

Fully working LV2 time ports, including UI changes

tags/1.9.4
falkTX 11 years ago
parent
commit
141052bb19
3 changed files with 102 additions and 64 deletions
  1. +1
    -1
      source/backend/CarlaPlugin.hpp
  2. +8
    -5
      source/backend/plugin/CarlaPlugin.cpp
  3. +93
    -58
      source/backend/plugin/Lv2Plugin.cpp

+ 1
- 1
source/backend/CarlaPlugin.hpp View File

@@ -44,7 +44,7 @@ CARLA_BACKEND_START_NAMESPACE
enum PluginPostRtEventType { enum PluginPostRtEventType {
kPluginPostRtEventNull, kPluginPostRtEventNull,
kPluginPostRtEventDebug, kPluginPostRtEventDebug,
kPluginPostRtEventParameterChange, // param, N, value
kPluginPostRtEventParameterChange, // param, SP*, value (SP: if 1, don't report change to Callback and OSC)
kPluginPostRtEventProgramChange, // index kPluginPostRtEventProgramChange, // index
kPluginPostRtEventMidiProgramChange, // index kPluginPostRtEventMidiProgramChange, // index
kPluginPostRtEventNoteOn, // channel, note, velo kPluginPostRtEventNoteOn, // channel, note, velo


+ 8
- 5
source/backend/plugin/CarlaPlugin.cpp View File

@@ -1957,12 +1957,15 @@ void CarlaPlugin::postRtEventsRun()
uiParameterChange(event.value1, event.value3); uiParameterChange(event.value1, event.value3);


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
// Update OSC control client
if (kData->engine->isOscControlRegistered())
kData->engine->osc_send_control_set_parameter_value(fId, event.value1, event.value3);
if (event.value2 != 1)
{
// Update OSC control client
if (kData->engine->isOscControlRegistered())
kData->engine->osc_send_control_set_parameter_value(fId, event.value1, event.value3);


// Update Host
kData->engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, fId, event.value1, 0, event.value3, nullptr);
// Update Host
kData->engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, fId, event.value1, 0, event.value3, nullptr);
}
#endif #endif
break; break;




+ 93
- 58
source/backend/plugin/Lv2Plugin.cpp View File

@@ -384,7 +384,8 @@ public:
fRdfDescriptor(nullptr), fRdfDescriptor(nullptr),
fAudioInBuffers(nullptr), fAudioInBuffers(nullptr),
fAudioOutBuffers(nullptr), fAudioOutBuffers(nullptr),
fParamBuffers(nullptr)
fParamBuffers(nullptr),
fParamFreewheel(0.0f)
{ {
carla_debug("Lv2Plugin::Lv2Plugin(%p, %i)", engine, id); carla_debug("Lv2Plugin::Lv2Plugin(%p, %i)", engine, id);


@@ -1959,13 +1960,24 @@ public:
kData->param.ranges[j].stepSmall = stepSmall; kData->param.ranges[j].stepSmall = stepSmall;
kData->param.ranges[j].stepLarge = stepLarge; kData->param.ranges[j].stepLarge = stepLarge;


// Start parameters in their default values
fParamBuffers[j] = def;
if (kData->param.data[j].type != PARAMETER_LV2_FREEWHEEL)
{
// Start parameters in their default values
fParamBuffers[j] = def;


fDescriptor->connect_port(fHandle, i, &fParamBuffers[j]);
fDescriptor->connect_port(fHandle, i, &fParamBuffers[j]);


if (fHandle2 != nullptr)
fDescriptor->connect_port(fHandle2, i, &fParamBuffers[j]);
if (fHandle2 != nullptr)
fDescriptor->connect_port(fHandle2, i, &fParamBuffers[j]);
}
else
{
// freewheel param
fDescriptor->connect_port(fHandle, i, &fParamFreewheel);

if (fHandle2 != nullptr)
fDescriptor->connect_port(fHandle2, i, &fParamFreewheel);
}
} }
else else
{ {
@@ -2286,73 +2298,108 @@ public:
CARLA_PROCESS_CONTINUE_CHECK; CARLA_PROCESS_CONTINUE_CHECK;


// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// Special Parameters and TimeInfo
// Special Parameters


{ {
// TODO - there should be a callback for this
fParamFreewheel = kData->engine->isOffline() ? 1.0f : 0.0f;
}

// --------------------------------------------------------------------------------------------------------
// TimeInfo

{
bool doPostRt;
int32_t rindex; int32_t rindex;
const EngineTimeInfo& timeInfo(kData->engine->getTimeInfo()); const EngineTimeInfo& timeInfo(kData->engine->getTimeInfo());


for (k=0; k < kData->param.count; ++k)
if (fFirstActive || fLastTimeInfo != timeInfo)
{ {
if (kData->param.data[k].type == PARAMETER_LATENCY)
{
// nothing
}
else if (kData->param.data[k].type == PARAMETER_LV2_FREEWHEEL)
{
setParameterValue(k, kData->engine->isOffline() ? 1.0f : 0.0f, false, false, false);
}
else if (kData->param.data[k].type == PARAMETER_LV2_TIME)
// update input ports
for (k=0; k < kData->param.count; ++k)
{ {
if (kData->param.data[k].type != PARAMETER_LV2_TIME)
continue;

doPostRt = false;
rindex = kData->param.data[k].rindex; rindex = kData->param.data[k].rindex;

CARLA_ASSERT(rindex >= 0 && rindex < static_cast<int32_t>(fRdfDescriptor->PortCount)); CARLA_ASSERT(rindex >= 0 && rindex < static_cast<int32_t>(fRdfDescriptor->PortCount));


switch (fRdfDescriptor->Ports[rindex].Designation) switch (fRdfDescriptor->Ports[rindex].Designation)
{ {
// Non-BBT // Non-BBT
case LV2_PORT_DESIGNATION_TIME_SPEED:
if (fLastTimeInfo.playing != timeInfo.playing)
{
fParamBuffers[k] = timeInfo.playing ? 1.0f : 0.0f;
doPostRt = true;
}
break;
case LV2_PORT_DESIGNATION_TIME_FRAME: case LV2_PORT_DESIGNATION_TIME_FRAME:
setParameterValue(k, timeInfo.frame, false, false, false);
if (fLastTimeInfo.frame != timeInfo.frame)
{
fParamBuffers[k] = timeInfo.frame;
doPostRt = true;
}
break; break;
case LV2_PORT_DESIGNATION_TIME_SPEED:
setParameterValue(k, timeInfo.playing ? 1.0f : 0.0f, false, false, false);
case LV2_PORT_DESIGNATION_TIME_FRAMES_PER_SECOND:
break; break;
// BBT
// BBT
case LV2_PORT_DESIGNATION_TIME_BAR: case LV2_PORT_DESIGNATION_TIME_BAR:
if (timeInfo.valid & EngineTimeInfo::ValidBBT)
setParameterValue(k, timeInfo.bbt.bar - 1, false, false, false);
if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.bar != timeInfo.bbt.bar)
{
fParamBuffers[k] = timeInfo.bbt.bar - 1;
doPostRt = true;
}
break; break;
case LV2_PORT_DESIGNATION_TIME_BAR_BEAT: case LV2_PORT_DESIGNATION_TIME_BAR_BEAT:
if (timeInfo.valid & EngineTimeInfo::ValidBBT)
setParameterValue(k, timeInfo.bbt.beat - 1 + (double(timeInfo.bbt.tick) / timeInfo.bbt.ticksPerBeat), false, false, false);
if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && (fLastTimeInfo.bbt.tick != timeInfo.bbt.tick ||
fLastTimeInfo.bbt.ticksPerBeat != timeInfo.bbt.ticksPerBeat))
{
fParamBuffers[k] = timeInfo.bbt.beat - 1 + (double(timeInfo.bbt.tick) / timeInfo.bbt.ticksPerBeat);
doPostRt = true;
}
break; break;
case LV2_PORT_DESIGNATION_TIME_BEAT: case LV2_PORT_DESIGNATION_TIME_BEAT:
if (timeInfo.valid & EngineTimeInfo::ValidBBT)
setParameterValue(k, timeInfo.bbt.beat - 1, false, false, false);
if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.beat != timeInfo.bbt.beat)
{
fParamBuffers[k] = timeInfo.bbt.beat - 1;
doPostRt = true;
}
break; break;
case LV2_PORT_DESIGNATION_TIME_BEAT_UNIT: case LV2_PORT_DESIGNATION_TIME_BEAT_UNIT:
if (timeInfo.valid & EngineTimeInfo::ValidBBT)
setParameterValue(k, timeInfo.bbt.beatType, false, false, false);
if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.beatType != timeInfo.bbt.beatType)
{
fParamBuffers[k] = timeInfo.bbt.beatType;
doPostRt = true;
}
break; break;
case LV2_PORT_DESIGNATION_TIME_BEATS_PER_BAR: case LV2_PORT_DESIGNATION_TIME_BEATS_PER_BAR:
if (timeInfo.valid & EngineTimeInfo::ValidBBT)
setParameterValue(k, timeInfo.bbt.beatsPerBar, false, false, false);
if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.beatsPerBar != timeInfo.bbt.beatsPerBar)
{
fParamBuffers[k] = timeInfo.bbt.beatsPerBar;
doPostRt = true;
}
break; break;
case LV2_PORT_DESIGNATION_TIME_BEATS_PER_MINUTE: case LV2_PORT_DESIGNATION_TIME_BEATS_PER_MINUTE:
if (timeInfo.valid & EngineTimeInfo::ValidBBT)
setParameterValue(k, timeInfo.bbt.beatsPerMinute, false, false, false);
if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.beatsPerMinute != timeInfo.bbt.beatsPerMinute)
{
fParamBuffers[k] = timeInfo.bbt.beatsPerMinute;
doPostRt = true;
}
break; break;
} }
}
}


// find first port to send time info into
for (i = 0; i < fEventsIn.count; ++i)
{
if ((fEventsIn.data[i].type & CARLA_EVENT_DATA_ATOM) == 0 || (fEventsIn.data[i].type & CARLA_EVENT_TYPE_TIME) == 0)
continue;
if (doPostRt)
postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 1, fParamBuffers[k]);
}


if (fFirstActive || fLastTimeInfo != timeInfo)
for (i = 0; i < fEventsIn.count; ++i)
{ {
if ((fEventsIn.data[i].type & CARLA_EVENT_DATA_ATOM) == 0 || (fEventsIn.data[i].type & CARLA_EVENT_TYPE_TIME) == 0)
continue;

uint8_t timeInfoBuf[256] = { 0 }; uint8_t timeInfoBuf[256] = { 0 };
lv2_atom_forge_set_buffer(&fAtomForge, timeInfoBuf, sizeof(timeInfoBuf)); lv2_atom_forge_set_buffer(&fAtomForge, timeInfoBuf, sizeof(timeInfoBuf));


@@ -2382,26 +2429,12 @@ public:
LV2_Atom* atom = (LV2_Atom*)timeInfoBuf; LV2_Atom* atom = (LV2_Atom*)timeInfoBuf;
lv2_atom_buffer_write(&evInAtomIters[i], 0, 0, atom->type, atom->size, LV2NV_ATOM_BODY_CONST(atom)); lv2_atom_buffer_write(&evInAtomIters[i], 0, 0, atom->type, atom->size, LV2NV_ATOM_BODY_CONST(atom));


std::memcpy(&fLastTimeInfo, &timeInfo, sizeof(EngineTimeInfo));
CARLA_ASSERT(atom->size < 256);
} }


break;
kData->postRtEvents.trySplice();


//if (atom->type == CARLA_URI_MAP_ID_ATOM_WORKER)
//{
// const LV2_Atom_Worker* const atomWorker = (const LV2_Atom_Worker*)atom;
// fExt.worker->work_response(fHandle, atomWorker->body.size, atomWorker->body.data);
// continue;
//}

// LV2_Atom_Event* const aev(getLv2AtomEvent(fEventsIn.ctrl->atom, evInAtomOffsets[k]));
// aev->time.frames = 0;
// aev->body.type = atom->type;
// aev->body.size = atom->size;
// std::memcpy(LV2_ATOM_BODY(&aev->body), LV2_ATOM_BODY(atom), atom->size);

// evInAtomOffsets[k] += evInPadSize;
// fEventsIn.ctrl->atom->atom.size = evInAtomOffsets[k];
std::memcpy(&fLastTimeInfo, &timeInfo, sizeof(EngineTimeInfo));
} }
} }


@@ -3488,6 +3521,7 @@ protected:
fUi.descriptor->cleanup(fUi.handle); fUi.descriptor->cleanup(fUi.handle);


fUi.handle = nullptr; fUi.handle = nullptr;
fUi.widget = nullptr;
kData->engine->callback(CALLBACK_SHOW_GUI, fId, 0, 0, 0.0f, nullptr); kData->engine->callback(CALLBACK_SHOW_GUI, fId, 0, 0, 0.0f, nullptr);
} }


@@ -4398,6 +4432,7 @@ private:
float** fAudioInBuffers; float** fAudioInBuffers;
float** fAudioOutBuffers; float** fAudioOutBuffers;
float* fParamBuffers; float* fParamBuffers;
float fParamFreewheel;


Lv2AtomQueue fAtomQueueIn; Lv2AtomQueue fAtomQueueIn;
Lv2AtomQueue fAtomQueueOut; Lv2AtomQueue fAtomQueueOut;


Loading…
Cancel
Save