Browse Source

Finish pending LV2 plugin fixes

tags/1.9.4
falkTX 11 years ago
parent
commit
c77d09a1e6
4 changed files with 231 additions and 191 deletions
  1. +11
    -10
      source/backend/engine/CarlaEngineInternal.hpp
  2. +8
    -6
      source/backend/native/midi-file.cpp
  3. +210
    -173
      source/backend/plugin/Lv2Plugin.cpp
  4. +2
    -2
      source/backend/plugin/NativePlugin.cpp

+ 11
- 10
source/backend/engine/CarlaEngineInternal.hpp View File

@@ -232,19 +232,11 @@ struct CarlaEngineProtectedData {
void doPluginRemove()
{
CARLA_ASSERT(curPluginCount > 0);
CARLA_ASSERT(nextAction.pluginId < curPluginCount);
--curPluginCount;

const unsigned int id(nextAction.pluginId);

// reset current plugin
plugins[id].plugin = nullptr;
plugins[id].insPeak[0] = 0.0f;
plugins[id].insPeak[1] = 0.0f;
plugins[id].outsPeak[0] = 0.0f;
plugins[id].outsPeak[1] = 0.0f;

// move all plugins 1 spot backwards
for (unsigned int i=id; i < curPluginCount; ++i)
for (unsigned int i=nextAction.pluginId; i < curPluginCount; ++i)
{
CarlaPlugin* const plugin(plugins[i+1].plugin);

@@ -261,6 +253,15 @@ struct CarlaEngineProtectedData {
plugins[i].outsPeak[0] = 0.0f;
plugins[i].outsPeak[1] = 0.0f;
}

const unsigned int id(curPluginCount);

// reset now last plugin
plugins[id].plugin = nullptr;
plugins[id].insPeak[0] = 0.0f;
plugins[id].insPeak[1] = 0.0f;
plugins[id].outsPeak[0] = 0.0f;
plugins[id].outsPeak[1] = 0.0f;
}

void doPluginsSwitch()


+ 8
- 6
source/backend/native/midi-file.cpp View File

@@ -55,7 +55,7 @@ protected:

void process(float**, float**, const uint32_t frames, const uint32_t, const MidiEvent* const) override
{
const TimeInfo* const timePos = getTimeInfo();
const TimeInfo* const timePos(getTimeInfo());

if (timePos->playing)
{
@@ -66,18 +66,20 @@ protected:
MidiEvent midiEvent;

midiEvent.port = 0;
midiEvent.time = timePos->frame;
midiEvent.time = 0;
midiEvent.data[0] = MIDI_STATUS_CONTROL_CHANGE;
midiEvent.data[1] = MIDI_CONTROL_ALL_NOTES_OFF;
midiEvent.data[2] = 0;
midiEvent.data[3] = 0;
midiEvent.size = 2;
midiEvent.size = 3;

for (int i=0; i < MAX_MIDI_CHANNELS; ++i)
{
midiEvent.data[0] += i;
midiEvent.data[0] = MIDI_STATUS_CONTROL_CHANGE+i;
PluginDescriptorClass::writeMidiEvent(&midiEvent);
}

carla_stdout("WAS PLAYING BEFORE, NOW STOPPED");
}

fWasPlayingBefore = timePos->playing;
@@ -128,7 +130,7 @@ private:
if (smf_t* const smf = smf_load(filename))
{
smf_event_t* event;
const double sampleRate = getSampleRate();
const double sampleRate(getSampleRate());

while ((event = smf_get_next_event(smf)) != nullptr)
{
@@ -143,7 +145,7 @@ private:
if (event->midi_buffer_length <= 0 || event->midi_buffer_length > MAX_EVENT_DATA_SIZE)
continue;

const uint32_t time = event->time_seconds*sampleRate;
const uint32_t time(event->time_seconds*sampleRate);

#if 1
fMidiOut.addRaw(time, event->midi_buffer, event->midi_buffer_length);


+ 210
- 173
source/backend/plugin/Lv2Plugin.cpp View File

@@ -15,7 +15,6 @@
* For a full copy of the GNU General Public License see the GPL.txt file
*/

#define WANT_LV2
#include "CarlaPluginInternal.hpp"

#ifdef WANT_LV2
@@ -511,7 +510,10 @@ public:
for (uint32_t i=0; i < kFeatureCount; ++i)
{
if (fFeatures[i] != nullptr)
{
delete fFeatures[i];
fFeatures[i] = nullptr;
}
}

for (NonRtList<const char*>::Itenerator it = fCustomURIDs.begin(); it.valid(); it.next())
@@ -2301,7 +2303,9 @@ public:
return;
}

// handle events from different APIs
// --------------------------------------------------------------------------------------------------------
// Handle events from different APIs

LV2_Atom_Buffer_Iterator evInAtomIters[fEventsIn.count];
LV2_Event_Iterator evInEventIters[fEventsIn.count];
LV2_MIDIState evInMidiStates[fEventsIn.count];
@@ -2405,16 +2409,16 @@ public:
}
}

if (kData->latency > 0)
//if (kData->latency > 0)
{
//for (i=0; i < kData->audioIn.count; ++i)
// carla_zeroFloat(kData->latencyBuffers[i], kData->latency);
}

kData->needsReset = false;
}

CARLA_PROCESS_CONTINUE_CHECK;
CARLA_PROCESS_CONTINUE_CHECK;
}

// --------------------------------------------------------------------------------------------------------
// Special Parameters
@@ -2427,134 +2431,136 @@ public:
// --------------------------------------------------------------------------------------------------------
// TimeInfo

const EngineTimeInfo& timeInfo(kData->engine->getTimeInfo());

if (fFirstActive || fLastTimeInfo != timeInfo)
{
bool doPostRt;
int32_t rindex;
const EngineTimeInfo& timeInfo(kData->engine->getTimeInfo());

if (fFirstActive || fLastTimeInfo != timeInfo)
// update input ports
for (k=0; k < kData->param.count; ++k)
{
// update input ports
for (k=0; k < kData->param.count; ++k)
{
if (kData->param.data[k].type != PARAMETER_LV2_TIME)
continue;
if (kData->param.data[k].type != PARAMETER_LV2_TIME)
continue;

doPostRt = false;
rindex = kData->param.data[k].rindex;
doPostRt = false;
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
case LV2_PORT_DESIGNATION_TIME_SPEED:
if (fLastTimeInfo.playing != timeInfo.playing)
{
// 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:
if (fLastTimeInfo.frame != timeInfo.frame)
{
fParamBuffers[k] = timeInfo.frame;
doPostRt = true;
}
break;
case LV2_PORT_DESIGNATION_TIME_FRAMES_PER_SECOND:
break;
// BBT
case LV2_PORT_DESIGNATION_TIME_BAR:
if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.bar != timeInfo.bbt.bar)
{
fParamBuffers[k] = timeInfo.bbt.bar - 1;
doPostRt = true;
}
break;
case LV2_PORT_DESIGNATION_TIME_BAR_BEAT:
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;
case LV2_PORT_DESIGNATION_TIME_BEAT:
if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.beat != timeInfo.bbt.beat)
{
fParamBuffers[k] = timeInfo.bbt.beat - 1;
doPostRt = true;
}
break;
case LV2_PORT_DESIGNATION_TIME_BEAT_UNIT:
if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.beatType != timeInfo.bbt.beatType)
{
fParamBuffers[k] = timeInfo.bbt.beatType;
doPostRt = true;
}
break;
case LV2_PORT_DESIGNATION_TIME_BEATS_PER_BAR:
if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.beatsPerBar != timeInfo.bbt.beatsPerBar)
{
fParamBuffers[k] = timeInfo.bbt.beatsPerBar;
doPostRt = true;
}
break;
case LV2_PORT_DESIGNATION_TIME_BEATS_PER_MINUTE:
if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.beatsPerMinute != timeInfo.bbt.beatsPerMinute)
{
fParamBuffers[k] = timeInfo.bbt.beatsPerMinute;
doPostRt = true;
}
break;
fParamBuffers[k] = timeInfo.playing ? 1.0f : 0.0f;
doPostRt = true;
}
break;
case LV2_PORT_DESIGNATION_TIME_FRAME:
if (fLastTimeInfo.frame != timeInfo.frame)
{
fParamBuffers[k] = timeInfo.frame;
doPostRt = true;
}
break;
case LV2_PORT_DESIGNATION_TIME_FRAMES_PER_SECOND:
break;

if (doPostRt)
postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 1, fParamBuffers[k]);
// BBT
case LV2_PORT_DESIGNATION_TIME_BAR:
if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.bar != timeInfo.bbt.bar)
{
fParamBuffers[k] = timeInfo.bbt.bar - 1;
doPostRt = true;
}
break;
case LV2_PORT_DESIGNATION_TIME_BAR_BEAT:
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;
case LV2_PORT_DESIGNATION_TIME_BEAT:
if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.beat != timeInfo.bbt.beat)
{
fParamBuffers[k] = timeInfo.bbt.beat - 1;
doPostRt = true;
}
break;
case LV2_PORT_DESIGNATION_TIME_BEAT_UNIT:
if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.beatType != timeInfo.bbt.beatType)
{
fParamBuffers[k] = timeInfo.bbt.beatType;
doPostRt = true;
}
break;
case LV2_PORT_DESIGNATION_TIME_BEATS_PER_BAR:
if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.beatsPerBar != timeInfo.bbt.beatsPerBar)
{
fParamBuffers[k] = timeInfo.bbt.beatsPerBar;
doPostRt = true;
}
break;
case LV2_PORT_DESIGNATION_TIME_BEATS_PER_MINUTE:
if ((timeInfo.valid & EngineTimeInfo::ValidBBT) != 0 && fLastTimeInfo.bbt.beatsPerMinute != timeInfo.bbt.beatsPerMinute)
{
fParamBuffers[k] = timeInfo.bbt.beatsPerMinute;
doPostRt = true;
}
break;
}

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 };
lv2_atom_forge_set_buffer(&fAtomForge, timeInfoBuf, sizeof(timeInfoBuf));
if (doPostRt)
postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 1, fParamBuffers[k]);
}

LV2_Atom_Forge_Frame forgeFrame;
lv2_atom_forge_blank(&fAtomForge, &forgeFrame, 1, CARLA_URI_MAP_ID_TIME_POSITION);
lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_SPEED, 0);
lv2_atom_forge_float(&fAtomForge, timeInfo.playing ? 1.0f : 0.0f);
lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_FRAME, 0);
lv2_atom_forge_long(&fAtomForge, timeInfo.frame);
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 (timeInfo.valid & EngineTimeInfo::ValidBBT)
{
lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_BAR, 0);
lv2_atom_forge_long(&fAtomForge, timeInfo.bbt.bar - 1);
lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_BAR_BEAT, 0);
lv2_atom_forge_float(&fAtomForge, timeInfo.bbt.beat - 1 + (double(timeInfo.bbt.tick) / timeInfo.bbt.ticksPerBeat));
lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_BEAT, 0);
lv2_atom_forge_long(&fAtomForge, timeInfo.bbt.beat -1);
lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_BEAT_UNIT, 0);
lv2_atom_forge_float(&fAtomForge, timeInfo.bbt.beatType);
lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_BEATS_PER_BAR, 0);
lv2_atom_forge_float(&fAtomForge, timeInfo.bbt.beatsPerBar);
lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_BEATS_PER_MINUTE, 0);
lv2_atom_forge_float(&fAtomForge, timeInfo.bbt.beatsPerMinute);
}
uint8_t timeInfoBuf[256] = { 0 };
lv2_atom_forge_set_buffer(&fAtomForge, timeInfoBuf, sizeof(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_Forge_Frame forgeFrame;
lv2_atom_forge_blank(&fAtomForge, &forgeFrame, 1, CARLA_URI_MAP_ID_TIME_POSITION);
lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_SPEED, 0);
lv2_atom_forge_float(&fAtomForge, timeInfo.playing ? 1.0f : 0.0f);
lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_FRAME, 0);
lv2_atom_forge_long(&fAtomForge, timeInfo.frame);

CARLA_ASSERT(atom->size < 256);
if (timeInfo.valid & EngineTimeInfo::ValidBBT)
{
lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_BAR, 0);
lv2_atom_forge_long(&fAtomForge, timeInfo.bbt.bar - 1);
lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_BAR_BEAT, 0);
lv2_atom_forge_float(&fAtomForge, timeInfo.bbt.beat - 1 + (double(timeInfo.bbt.tick) / timeInfo.bbt.ticksPerBeat));
lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_BEAT, 0);
lv2_atom_forge_long(&fAtomForge, timeInfo.bbt.beat -1);
lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_BEAT_UNIT, 0);
lv2_atom_forge_float(&fAtomForge, timeInfo.bbt.beatType);
lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_BEATS_PER_BAR, 0);
lv2_atom_forge_float(&fAtomForge, timeInfo.bbt.beatsPerBar);
lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_BEATS_PER_MINUTE, 0);
lv2_atom_forge_float(&fAtomForge, timeInfo.bbt.beatsPerMinute);
}

kData->postRtEvents.trySplice();
LV2_Atom* const atom((LV2_Atom*)timeInfoBuf);
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);
}

kData->postRtEvents.trySplice();

std::memcpy(&fLastTimeInfo, &timeInfo, sizeof(EngineTimeInfo));

CARLA_PROCESS_CONTINUE_CHECK;
}

// --------------------------------------------------------------------------------------------------------
@@ -2576,10 +2582,10 @@ public:

while (fAtomQueueIn.get(&portIndex, &atom))
{
carla_stdout("Event input message sent to plugin DSP, type %i:\"%s\", size:%i/%i",
atom->type, carla_lv2_urid_unmap(this, atom->type),
atom->size, lv2_atom_total_size(atom)
);
carla_debug("Event input message sent to plugin DSP, type %i:\"%s\", size:%i/%i",
atom->type, carla_lv2_urid_unmap(this, atom->type),
atom->size, lv2_atom_total_size(atom)
);

if (! lv2_atom_buffer_write(&evInAtomIters[k], 0, 0, atom->type, atom->size, LV2NV_ATOM_BODY_CONST(atom)))
{
@@ -2597,22 +2603,27 @@ public:

if (kData->extNotes.mutex.tryLock())
{
k = fEventsIn.ctrlIndex;

while (! kData->extNotes.data.isEmpty())
if ((fEventsIn.ctrl->type & CARLA_EVENT_TYPE_MIDI) == 0)
{
const ExternalMidiNote& note(kData->extNotes.data.getFirst(true));
// does not handle MIDI
kData->extNotes.data.clear();
}
else
{
k = fEventsIn.ctrlIndex;

CARLA_ASSERT(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
while (! kData->extNotes.data.isEmpty())
{
const ExternalMidiNote& note(kData->extNotes.data.getFirst(true));

uint8_t midiEvent[3];
midiEvent[0] = (note.velo > 0) ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF;
midiEvent[0] += note.channel;
midiEvent[1] = note.note;
midiEvent[2] = note.velo;
CARLA_ASSERT(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);

uint8_t midiEvent[3];
midiEvent[0] = (note.velo > 0) ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF;
midiEvent[0] += note.channel;
midiEvent[1] = note.note;
midiEvent[2] = note.velo;

if (fEventsIn.ctrl->type & CARLA_EVENT_TYPE_MIDI)
{
if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
lv2_atom_buffer_write(&evInAtomIters[k], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 3, midiEvent);

@@ -2697,7 +2708,7 @@ public:

case kEngineEventTypeControl:
{
const EngineControlEvent& ctrlEvent = event.ctrl;
const EngineControlEvent& ctrlEvent(event.ctrl);

switch (ctrlEvent.type)
{
@@ -2941,10 +2952,12 @@ public:
break;

if (ev->body.type == CARLA_URI_MAP_ID_MIDI_EVENT && fEventsOut.ctrl->port != nullptr)
{
fEventsOut.ctrl->port->writeMidiEvent(ev->time.frames, data, ev->body.size);
}
else if (ev->body.type == CARLA_URI_MAP_ID_ATOM_BLANK)
{
//carla_stdout("Event OUTPUT message TO BE SENT TO UI, type blank");
carla_debug("Event OUTPUT message TO BE SENT TO UI, type blank");

fAtomQueueOut.put(rindex, &ev->body);
}
@@ -3293,6 +3306,15 @@ public:
fExt.options->set(fHandle, &fLv2Options.optSampleRate);
}

for (uint32_t k=0; k < kData->param.count; ++k)
{
if (kData->param.data[k].type == PARAMETER_SAMPLE_RATE)
{
fParamBuffers[k] = newSampleRate;
postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 1, fParamBuffers[k]);
}
}

carla_debug("Lv2Plugin::sampleRateChanged(%g) - end", newSampleRate);
}

@@ -4084,66 +4106,64 @@ public:
// ---------------------------------------------------------------
// initialize features (part 2)

fFeatures[kFeatureIdBufSizeBounded] = new LV2_Feature;
for (uint32_t i=0; i < kFeatureIdWorker+1; ++i)
fFeatures[i] = new LV2_Feature;

fFeatures[kFeatureIdBufSizeBounded]->URI = LV2_BUF_SIZE__boundedBlockLength;
fFeatures[kFeatureIdBufSizeBounded]->data = nullptr;

fFeatures[kFeatureIdBufSizeFixed] = new LV2_Feature;
fFeatures[kFeatureIdBufSizeFixed]->URI = LV2_BUF_SIZE__fixedBlockLength;
fFeatures[kFeatureIdBufSizeFixed]->data = nullptr;

fFeatures[kFeatureIdBufSizePowerOf2] = new LV2_Feature;
fFeatures[kFeatureIdBufSizePowerOf2]->URI = LV2_BUF_SIZE__powerOf2BlockLength;
fFeatures[kFeatureIdBufSizePowerOf2]->data = nullptr;

fFeatures[kFeatureIdEvent] = new LV2_Feature;
fFeatures[kFeatureIdEvent]->URI = LV2_EVENT_URI;
fFeatures[kFeatureIdEvent]->data = eventFt;
fFeatures[kFeatureIdEvent]->URI = LV2_EVENT_URI;
fFeatures[kFeatureIdEvent]->data = eventFt;

fFeatures[kFeatureIdLogs] = new LV2_Feature;
fFeatures[kFeatureIdLogs]->URI = LV2_LOG__log;
fFeatures[kFeatureIdLogs]->data = logFt;
fFeatures[kFeatureIdHardRtCapable]->URI = LV2_CORE__hardRTCapable;
fFeatures[kFeatureIdHardRtCapable]->data = nullptr;

fFeatures[kFeatureIdOptions] = new LV2_Feature;
fFeatures[kFeatureIdOptions]->URI = LV2_OPTIONS__options;
fFeatures[kFeatureIdOptions]->data = fLv2Options.opts;
fFeatures[kFeatureIdInPlaceBroken]->URI = LV2_CORE__inPlaceBroken;
fFeatures[kFeatureIdInPlaceBroken]->data = nullptr;

fFeatures[kFeatureIdPrograms] = new LV2_Feature;
fFeatures[kFeatureIdPrograms]->URI = LV2_PROGRAMS__Host;
fFeatures[kFeatureIdPrograms]->data = programsFt;
fFeatures[kFeatureIdIsLive]->URI = LV2_CORE__isLive;
fFeatures[kFeatureIdIsLive]->data = nullptr;

fFeatures[kFeatureIdLogs]->URI = LV2_LOG__log;
fFeatures[kFeatureIdLogs]->data = logFt;

fFeatures[kFeatureIdOptions]->URI = LV2_OPTIONS__options;
fFeatures[kFeatureIdOptions]->data = fLv2Options.opts;

fFeatures[kFeatureIdPrograms]->URI = LV2_PROGRAMS__Host;
fFeatures[kFeatureIdPrograms]->data = programsFt;

fFeatures[kFeatureIdRtMemPool] = new LV2_Feature;
fFeatures[kFeatureIdRtMemPool]->URI = LV2_RTSAFE_MEMORY_POOL__Pool;
fFeatures[kFeatureIdRtMemPool]->data = rtMemPoolFt;

fFeatures[kFeatureIdStateMakePath] = new LV2_Feature;
fFeatures[kFeatureIdStateMakePath]->URI = LV2_STATE__makePath;
fFeatures[kFeatureIdStateMakePath]->data = stateMakePathFt;

fFeatures[kFeatureIdStateMapPath] = new LV2_Feature;
fFeatures[kFeatureIdStateMapPath]->URI = LV2_STATE__mapPath;
fFeatures[kFeatureIdStateMapPath]->data = stateMapPathFt;

fFeatures[kFeatureIdStrictBounds] = new LV2_Feature;
fFeatures[kFeatureIdStrictBounds]->URI = LV2_PORT_PROPS__supportsStrictBounds;
fFeatures[kFeatureIdStrictBounds]->data = nullptr;
fFeatures[kFeatureIdStrictBounds]->URI = LV2_PORT_PROPS__supportsStrictBounds;
fFeatures[kFeatureIdStrictBounds]->data = nullptr;

fFeatures[kFeatureIdUriMap] = new LV2_Feature;
fFeatures[kFeatureIdUriMap]->URI = LV2_URI_MAP_URI;
fFeatures[kFeatureIdUriMap]->data = uriMapFt;

fFeatures[kFeatureIdUridMap] = new LV2_Feature;
fFeatures[kFeatureIdUridMap]->URI = LV2_URID__map;
fFeatures[kFeatureIdUridMap]->data = uridMapFt;

fFeatures[kFeatureIdUridUnmap] = new LV2_Feature;
fFeatures[kFeatureIdUridUnmap]->URI = LV2_URID__unmap;
fFeatures[kFeatureIdUridUnmap]->data = uridUnmapFt;

fFeatures[kFeatureIdWorker] = new LV2_Feature;
fFeatures[kFeatureIdWorker]->URI = LV2_WORKER__schedule;
fFeatures[kFeatureIdWorker]->data = workerFt;
fFeatures[kFeatureIdWorker]->URI = LV2_WORKER__schedule;
fFeatures[kFeatureIdWorker]->data = workerFt;

// check if it's possible to use non-fixed buffer size
if (! needsFixedBuffer())
fFeatures[kFeatureIdBufSizeFixed]->URI = LV2_BUF_SIZE__boundedBlockLength;

@@ -4601,7 +4621,7 @@ public:
}

// -------------------------------------------------------
// initialize ui features
// initialize ui features (part 1)

QString guiTitle(QString("%1 (GUI)").arg((const char*)fName));

@@ -4620,31 +4640,48 @@ public:
uiExternalHostFt->ui_closed = carla_lv2_external_ui_closed;
uiExternalHostFt->plugin_human_id = carla_strdup(guiTitle.toUtf8().constData());

fFeatures[kFeatureIdUiDataAccess] = new LV2_Feature;
// -------------------------------------------------------
// initialize ui features (part 2)

for (uint32_t i=kFeatureIdUiDataAccess; i < kFeatureCount; ++i)
fFeatures[i] = new LV2_Feature;

fFeatures[kFeatureIdUiDataAccess]->URI = LV2_DATA_ACCESS_URI;
fFeatures[kFeatureIdUiDataAccess]->data = uiDataFt;

fFeatures[kFeatureIdUiInstanceAccess] = new LV2_Feature;
fFeatures[kFeatureIdUiInstanceAccess]->URI = LV2_INSTANCE_ACCESS_URI;
fFeatures[kFeatureIdUiInstanceAccess]->data = fHandle;

fFeatures[kFeatureIdUiParent] = new LV2_Feature;
fFeatures[kFeatureIdUiParent]->URI = LV2_UI__parent;
fFeatures[kFeatureIdUiParent]->data = nullptr;
fFeatures[kFeatureIdUiIdle]->URI = LV2_UI__idle;
fFeatures[kFeatureIdUiIdle]->data = nullptr;

fFeatures[kFeatureIdUiFixedSize]->URI = LV2_UI__fixedSize;
fFeatures[kFeatureIdUiFixedSize]->data = nullptr;

fFeatures[kFeatureIdUiMakeResident]->URI = LV2_UI__makeResident;
fFeatures[kFeatureIdUiMakeResident]->data = nullptr;

fFeatures[kFeatureIdUiNoUserResize]->URI = LV2_UI__noUserResize;
fFeatures[kFeatureIdUiNoUserResize]->data = nullptr;

fFeatures[kFeatureIdUiParent]->URI = LV2_UI__parent;
fFeatures[kFeatureIdUiParent]->data = nullptr;

fFeatures[kFeatureIdUiPortMap]->URI = LV2_UI__portMap;
fFeatures[kFeatureIdUiPortMap]->data = uiPortMapFt;

fFeatures[kFeatureIdUiPortSubscribe]->URI = LV2_UI__portSubscribe;
fFeatures[kFeatureIdUiPortSubscribe]->data = nullptr;

fFeatures[kFeatureIdUiPortMap] = new LV2_Feature;
fFeatures[kFeatureIdUiPortMap]->URI = LV2_UI__portMap;
fFeatures[kFeatureIdUiPortMap]->data = uiPortMapFt;
fFeatures[kFeatureIdUiResize]->URI = LV2_UI__resize;
fFeatures[kFeatureIdUiResize]->data = uiResizeFt;

fFeatures[kFeatureIdUiResize] = new LV2_Feature;
fFeatures[kFeatureIdUiResize]->URI = LV2_UI__resize;
fFeatures[kFeatureIdUiResize]->data = uiResizeFt;
fFeatures[kFeatureIdUiTouch]->URI = LV2_UI__touch;
fFeatures[kFeatureIdUiTouch]->data = nullptr;

fFeatures[kFeatureIdExternalUi] = new LV2_Feature;
fFeatures[kFeatureIdExternalUi]->URI = LV2_EXTERNAL_UI__Host;
fFeatures[kFeatureIdExternalUi]->data = uiExternalHostFt;
fFeatures[kFeatureIdExternalUi]->URI = LV2_EXTERNAL_UI__Host;
fFeatures[kFeatureIdExternalUi]->data = uiExternalHostFt;

fFeatures[kFeatureIdExternalUiOld] = new LV2_Feature;
fFeatures[kFeatureIdExternalUiOld]->URI = LV2_EXTERNAL_UI_DEPRECATED_URI;
fFeatures[kFeatureIdExternalUiOld]->data = uiExternalHostFt;
}


+ 2
- 2
source/backend/plugin/NativePlugin.cpp View File

@@ -543,7 +543,7 @@ public:

void setCtrlChannel(const int8_t channel, const bool sendOsc, const bool sendCallback) override
{
if (channel < MAX_MIDI_CHANNELS)
if (channel < MAX_MIDI_CHANNELS && kData->midiprog.count > 0)
kData->midiprog.current = fCurMidiProgs[channel];

CarlaPlugin::setCtrlChannel(channel, sendOsc, sendCallback);
@@ -719,7 +719,7 @@ public:

if (fDescriptor->ui_set_midi_program != nullptr && kData->midiprog.current >= 0)
{
const MidiProgramData& mpData = kData->midiprog.getCurrent();
const MidiProgramData& mpData(kData->midiprog.getCurrent());
fDescriptor->ui_set_midi_program(fHandle, 0, mpData.bank, mpData.program); // TODO
}



Loading…
Cancel
Save