Browse Source

Keep at it; Don't try send some UI events if there's no UI

tags/1.9.4
falkTX 10 years ago
parent
commit
3d7d261724
4 changed files with 204 additions and 197 deletions
  1. +4
    -4
      source/backend/plugin/CarlaPlugin.cpp
  2. +1
    -1
      source/backend/plugin/DssiPlugin.cpp
  3. +197
    -186
      source/backend/plugin/Lv2Plugin.cpp
  4. +2
    -6
      source/utils/CarlaLv2Utils.hpp

+ 4
- 4
source/backend/plugin/CarlaPlugin.cpp View File

@@ -1016,7 +1016,7 @@ void CarlaPlugin::setParameterValue(const uint32_t parameterId, const float valu
#endif

#ifndef BUILD_BRIDGE
if (sendGui)
if (sendGui && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0)
uiParameterChange(parameterId, value);

if (sendOsc && pData->engine->isOscControlRegistered())
@@ -1232,7 +1232,7 @@ void CarlaPlugin::setProgram(const int32_t index, const bool sendGui, const bool
if (index >= 0)
{
#ifndef BUILD_BRIDGE
if (sendGui)
if (sendGui && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0)
uiProgramChange(static_cast<uint32_t>(index));
#endif

@@ -1294,7 +1294,7 @@ void CarlaPlugin::setMidiProgram(const int32_t index, const bool sendGui, const
if (index >= 0)
{
#ifndef BUILD_BRIDGE
if (sendGui)
if (sendGui && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0)
uiMidiProgramChange(static_cast<uint32_t>(index));
#endif

@@ -1700,7 +1700,7 @@ void CarlaPlugin::sendMidiSingleNote(const uint8_t channel, const uint8_t note,

pData->extNotes.append(extNote);

if (sendGui)
if (sendGui && (pData->hints & PLUGIN_HAS_CUSTOM_UI) != 0)
{
if (velo > 0)
uiNoteOn(channel, note, velo);


+ 1
- 1
source/backend/plugin/DssiPlugin.cpp View File

@@ -1183,7 +1183,7 @@ public:
}

// check if event is already handled
if (k == pData->param.count)
if (k != pData->param.count)
break;

if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param <= 0x5F)


+ 197
- 186
source/backend/plugin/Lv2Plugin.cpp View File

@@ -148,15 +148,13 @@ struct Lv2EventData {
union {
LV2_Atom_Buffer* atom;
LV2_Event_Buffer* event;
LV2_MIDI* midi;
void* _ptr; // value checking
LV2_MIDI midi;
};

Lv2EventData()
: type(0x0),
rindex(0),
port(nullptr),
_ptr(nullptr) {}
port(nullptr) {}

~Lv2EventData()
{
@@ -166,35 +164,30 @@ struct Lv2EventData {
port = nullptr;
}

const ScopedValueSetter<uint32_t> zeroType(type, type, 0x0);
const uint32_t rtype(type);
type = 0x0;

if (type & CARLA_EVENT_DATA_ATOM)
if (rtype & CARLA_EVENT_DATA_ATOM)
{
CARLA_SAFE_ASSERT_RETURN(atom != nullptr,);

std::free(atom);
atom = nullptr;
}
else if (type & CARLA_EVENT_DATA_EVENT)
else if (rtype & CARLA_EVENT_DATA_EVENT)
{
CARLA_SAFE_ASSERT_RETURN(event != nullptr,);

std::free(event);
event = nullptr;
}
else if (type & CARLA_EVENT_DATA_MIDI_LL)
else if (rtype & CARLA_EVENT_DATA_MIDI_LL)
{
CARLA_SAFE_ASSERT_RETURN(midi != nullptr,)
CARLA_SAFE_ASSERT_RETURN(midi->data != nullptr,);
CARLA_SAFE_ASSERT_RETURN(midi.data != nullptr,);

delete[] midi->data;
midi->data = nullptr;

delete midi;
midi = nullptr;
delete[] midi.data;
midi.data = nullptr;
}

CARLA_ASSERT(_ptr == nullptr);
}

CARLA_DECLARE_NON_COPY_STRUCT(Lv2EventData)
@@ -1383,82 +1376,74 @@ public:
FLOAT_CLEAR(fParamBuffers, params);
}

#if 0
if (evIns.count() > 0)
if (const uint32_t count = static_cast<uint32_t>(evIns.count()))
{
const size_t count(evIns.count());

fEventsIn.createNew(count);

for (j=0; j < count; ++j)
for (uint32_t i=0; i < count; ++i)
{
const uint32_t& type(evIns.getAt(j));
const uint32_t& type(evIns.getAt(i));

if (type == CARLA_EVENT_DATA_ATOM)
{
fEventsIn.data[j].type = CARLA_EVENT_DATA_ATOM;
fEventsIn.data[j].atom = lv2_atom_buffer_new(MAX_DEFAULT_BUFFER_SIZE, CARLA_URI_MAP_ID_ATOM_SEQUENCE, true);
fEventsIn.data[i].type = CARLA_EVENT_DATA_ATOM;
fEventsIn.data[i].atom = lv2_atom_buffer_new(MAX_DEFAULT_BUFFER_SIZE, CARLA_URI_MAP_ID_NULL, CARLA_URI_MAP_ID_ATOM_SEQUENCE, true);
}
else if (type == CARLA_EVENT_DATA_EVENT)
{
fEventsIn.data[j].type = CARLA_EVENT_DATA_EVENT;
fEventsIn.data[j].event = lv2_event_buffer_new(MAX_DEFAULT_BUFFER_SIZE, LV2_EVENT_AUDIO_STAMP);
fEventsIn.data[i].type = CARLA_EVENT_DATA_EVENT;
#if 0
fEventsIn.data[i].event = lv2_event_buffer_new(MAX_DEFAULT_BUFFER_SIZE, LV2_EVENT_AUDIO_STAMP);
#endif
}
else if (type == CARLA_EVENT_DATA_MIDI_LL)
{
fEventsIn.data[j].type = CARLA_EVENT_DATA_MIDI_LL;
fEventsIn.data[j].midi = new LV2_MIDI;
fEventsIn.data[j].midi->event_count = 0;
fEventsIn.data[j].midi->capacity = MAX_DEFAULT_BUFFER_SIZE;
fEventsIn.data[j].midi->size = 0;
fEventsIn.data[j].midi->data = new unsigned char[MAX_DEFAULT_BUFFER_SIZE];
fEventsIn.data[i].type = CARLA_EVENT_DATA_MIDI_LL;
fEventsIn.data[i].midi.capacity = MAX_DEFAULT_BUFFER_SIZE;
fEventsIn.data[i].midi.data = new unsigned char[MAX_DEFAULT_BUFFER_SIZE];
}
}
}

if (evOuts.count() > 0)
if (const uint32_t count = static_cast<uint32_t>(evOuts.count()))
{
const size_t count(evOuts.count());

fEventsOut.createNew(count);

for (j=0; j < count; ++j)
for (uint32_t i=0; i < count; ++i)
{
const uint32_t& type(evOuts.getAt(j));
const uint32_t& type(evOuts.getAt(i));

if (type == CARLA_EVENT_DATA_ATOM)
{
fEventsOut.data[j].type = CARLA_EVENT_DATA_ATOM;
fEventsOut.data[j].atom = lv2_atom_buffer_new(MAX_DEFAULT_BUFFER_SIZE, CARLA_URI_MAP_ID_ATOM_SEQUENCE, false);
fEventsOut.data[i].type = CARLA_EVENT_DATA_ATOM;
fEventsOut.data[i].atom = lv2_atom_buffer_new(MAX_DEFAULT_BUFFER_SIZE, CARLA_URI_MAP_ID_NULL, CARLA_URI_MAP_ID_ATOM_SEQUENCE, false);
}
else if (type == CARLA_EVENT_DATA_EVENT)
{
fEventsOut.data[j].type = CARLA_EVENT_DATA_EVENT;
fEventsOut.data[j].event = lv2_event_buffer_new(MAX_DEFAULT_BUFFER_SIZE, LV2_EVENT_AUDIO_STAMP);
fEventsOut.data[i].type = CARLA_EVENT_DATA_EVENT;
#if 0
fEventsOut.data[i].event = lv2_event_buffer_new(MAX_DEFAULT_BUFFER_SIZE, LV2_EVENT_AUDIO_STAMP);
#endif
}
else if (type == CARLA_EVENT_DATA_MIDI_LL)
{
fEventsOut.data[j].type = CARLA_EVENT_DATA_MIDI_LL;
fEventsOut.data[j].midi = new LV2_MIDI;
fEventsOut.data[j].midi->event_count = 0;
fEventsOut.data[j].midi->capacity = MAX_DEFAULT_BUFFER_SIZE;
fEventsOut.data[j].midi->size = 0;
fEventsOut.data[j].midi->data = new unsigned char[MAX_DEFAULT_BUFFER_SIZE];
fEventsOut.data[i].type = CARLA_EVENT_DATA_MIDI_LL;
fEventsOut.data[i].midi.capacity = MAX_DEFAULT_BUFFER_SIZE;
fEventsOut.data[i].midi.data = new unsigned char[MAX_DEFAULT_BUFFER_SIZE];
}
}
}
#endif

const uint portNameSize(pData->engine->getMaxPortNameSize());
CarlaString portName;

for (uint32_t i=0, iAudioIn=0, iAudioOut=0, /*iEvIn=0, iEvOut=0,*/ iCtrl=0; i < portCount; ++i)
for (uint32_t i=0, iAudioIn=0, iAudioOut=0, iEvIn=0, iEvOut=0, iCtrl=0; i < portCount; ++i)
{
const LV2_Property portTypes(fRdfDescriptor->Ports[i].Types);

portName.clear();

if (LV2_IS_PORT_AUDIO(portTypes) || LV2_IS_PORT_ATOM_SEQUENCE(portTypes) || LV2_IS_PORT_CV(portTypes) || LV2_IS_PORT_EVENT(portTypes) || LV2_IS_PORT_MIDI_LL(portTypes))
if (LV2_IS_PORT_AUDIO(portTypes) || LV2_IS_PORT_CV(portTypes) || LV2_IS_PORT_ATOM_SEQUENCE(portTypes) || LV2_IS_PORT_EVENT(portTypes) || LV2_IS_PORT_MIDI_LL(portTypes))
{
if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
{
@@ -1501,7 +1486,6 @@ public:
else
carla_stderr2("WARNING - Got a broken Port (Audio, but not input or output)");
}
#if 0
else if (LV2_IS_PORT_CV(portTypes))
{
if (LV2_IS_PORT_INPUT(portTypes))
@@ -1601,6 +1585,7 @@ public:
else
carla_stderr2("WARNING - Got a broken Port (Atom-Sequence, but not input or output)");
}
#if 0
else if (LV2_IS_PORT_EVENT(portTypes))
{
if (LV2_IS_PORT_INPUT(portTypes))
@@ -1682,16 +1667,17 @@ public:
else
carla_stderr2("WARNING - Got a broken Port (Event, but not input or output)");
}
#endif
else if (LV2_IS_PORT_MIDI_LL(portTypes))
{
if (LV2_IS_PORT_INPUT(portTypes))
{
uint32_t j = iEvIn++;

fDescriptor->connect_port(fHandle, i, fEventsIn.data[j].midi);
fDescriptor->connect_port(fHandle, i, &fEventsIn.data[j].midi);

if (fHandle2 != nullptr)
fDescriptor->connect_port(fHandle2, i, fEventsIn.data[j].midi);
fDescriptor->connect_port(fHandle2, i, &fEventsIn.data[j].midi);

fEventsIn.data[j].type |= CARLA_EVENT_TYPE_MIDI;
fEventsIn.data[j].rindex = i;
@@ -1717,10 +1703,10 @@ public:
{
uint32_t j = iEvOut++;

fDescriptor->connect_port(fHandle, i, fEventsOut.data[j].midi);
fDescriptor->connect_port(fHandle, i, &fEventsOut.data[j].midi);

if (fHandle2 != nullptr)
fDescriptor->connect_port(fHandle2, i, fEventsOut.data[j].midi);
fDescriptor->connect_port(fHandle2, i, &fEventsOut.data[j].midi);

fEventsOut.data[j].type |= CARLA_EVENT_TYPE_MIDI;
fEventsOut.data[j].rindex = i;
@@ -1745,7 +1731,6 @@ public:
else
carla_stderr2("WARNING - Got a broken Port (MIDI, but not input or output)");
}
#endif
else if (LV2_IS_PORT_CONTROL(portTypes))
{
const LV2_Property portProps(fRdfDescriptor->Ports[i].Properties);
@@ -2248,46 +2233,53 @@ public:
return;
}

#if 0
// --------------------------------------------------------------------------------------------------------
// Handle events from different APIs
// Event itenerators from different APIs (input)

LV2_Atom_Buffer_Iterator evInAtomIters[fEventsIn.count];
#if 0
LV2_Event_Iterator evInEventIters[fEventsIn.count];
LV2_MIDIState evInMidiStates[fEventsIn.count];
#endif

for (i=0; i < fEventsIn.count; ++i)
for (uint32_t i=0; i < fEventsIn.count; ++i)
{
if (fEventsIn.data[i].type & CARLA_EVENT_DATA_ATOM)
{
lv2_atom_buffer_reset(fEventsIn.data[i].atom, true);
lv2_atom_buffer_begin(&evInAtomIters[i], fEventsIn.data[i].atom);
}
#if 0
else if (fEventsIn.data[i].type & CARLA_EVENT_DATA_EVENT)
{
lv2_event_buffer_reset(fEventsIn.data[i].event, LV2_EVENT_AUDIO_STAMP, fEventsIn.data[i].event->data);
lv2_event_begin(&evInEventIters[i], fEventsIn.data[i].event);
}
#endif
else if (fEventsIn.data[i].type & CARLA_EVENT_DATA_MIDI_LL)
{
fEventsIn.data[i].midi->event_count = 0;
fEventsIn.data[i].midi->size = 0;
evInMidiStates[i].midi = fEventsIn.data[i].midi;
fEventsIn.data[i].midi.event_count = 0;
fEventsIn.data[i].midi.size = 0;
#if 0
evInMidiStates[i].midi = fEventsIn.data[i].midi;
evInMidiStates[i].frame_count = frames;
evInMidiStates[i].position = 0;
#endif
}
}

for (i=0; i < fEventsOut.count; ++i)
for (uint32_t i=0; i < fEventsOut.count; ++i)
{
if (fEventsOut.data[i].type & CARLA_EVENT_DATA_ATOM)
{
lv2_atom_buffer_reset(fEventsOut.data[i].atom, false);
}
#if 0
else if (fEventsOut.data[i].type & CARLA_EVENT_DATA_EVENT)
{
lv2_event_buffer_reset(fEventsOut.data[i].event, LV2_EVENT_AUDIO_STAMP, fEventsOut.data[i].event->data);
}
#endif
else if (fEventsOut.data[i].type & CARLA_EVENT_DATA_MIDI_LL)
{
// not needed
@@ -2295,68 +2287,71 @@ public:
}

CARLA_PROCESS_CONTINUE_CHECK;
#endif

// --------------------------------------------------------------------------------------------------------
// Check if needs reset

if (pData->needsReset)
{
#if 0
uint8_t midiData[3] = { 0 };

if (fEventsIn.ctrl != nullptr && (fEventsIn.ctrl->type & CARLA_EVENT_TYPE_MIDI) != 0)
{
k = fEventsIn.ctrlIndex;
const uint32_t j = fEventsIn.ctrlIndex;

if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
{
for (i=0; i < MAX_MIDI_CHANNELS; ++i)
for (uint8_t i=0; i < MAX_MIDI_CHANNELS; ++i)
{
midiData[0] = MIDI_STATUS_CONTROL_CHANGE + i;
midiData[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + i);
midiData[1] = MIDI_CONTROL_ALL_NOTES_OFF;

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

#if 0
else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
lv2_event_write(&evInEventIters[k], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 3, midiData);
lv2_event_write(&evInEventIters[j], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 3, midiData);

else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
lv2midi_put_event(&evInMidiStates[k], 0, 3, midiData);
lv2midi_put_event(&evInMidiStates[j], 0, 3, midiData);
#endif

midiData[0] = MIDI_STATUS_CONTROL_CHANGE + i;
midiData[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + i);
midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;

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

#if 0
else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
lv2_event_write(&evInEventIters[k], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 3, midiData);
lv2_event_write(&evInEventIters[j], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 3, midiData);

else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
lv2midi_put_event(&evInMidiStates[k], 0, 3, midiData);
lv2midi_put_event(&evInMidiStates[j], 0, 3, midiData);
#endif
}
}
else if (pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS)
{
for (k=0; k < MAX_MIDI_NOTE; ++k)
for (uint8_t k=0; k < MAX_MIDI_NOTE; ++k)
{
midiData[0] = MIDI_STATUS_NOTE_OFF + pData->ctrlChannel;
midiData[0] = static_cast<uint8_t>(MIDI_STATUS_NOTE_OFF + pData->ctrlChannel);
midiData[1] = k;

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

#if 0
else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
lv2_event_write(&evInEventIters[k], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 3, midiData);

else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
lv2midi_put_event(&evInMidiStates[k], 0, 3, midiData);
#endif
}
}
}
#endif

if (pData->latency > 0)
{
@@ -2403,7 +2398,7 @@ public:
case LV2_PORT_DESIGNATION_TIME_FRAME:
if (fLastTimeInfo.frame != timeInfo.frame)
{
fParamBuffers[k] = float(timeInfo.frame);
fParamBuffers[k] = static_cast<float>(timeInfo.frame);
doPostRt = true;
}
break;
@@ -2414,7 +2409,7 @@ public:
case LV2_PORT_DESIGNATION_TIME_BAR:
if ((timeInfo.valid & EngineTimeInfo::kValidBBT) != 0 && fLastTimeInfo.bbt.bar != timeInfo.bbt.bar)
{
fParamBuffers[k] = float(timeInfo.bbt.bar - 1);
fParamBuffers[k] = static_cast<float>(timeInfo.bbt.bar - 1);
doPostRt = true;
}
break;
@@ -2422,14 +2417,14 @@ public:
if ((timeInfo.valid & EngineTimeInfo::kValidBBT) != 0 && (fLastTimeInfo.bbt.tick != timeInfo.bbt.tick ||
fLastTimeInfo.bbt.ticksPerBeat != timeInfo.bbt.ticksPerBeat))
{
fParamBuffers[k] = float(double(timeInfo.bbt.beat) - 1.0 + (double(timeInfo.bbt.tick) / timeInfo.bbt.ticksPerBeat));
fParamBuffers[k] = static_cast<float>(static_cast<double>(timeInfo.bbt.beat) - 1.0 + (static_cast<double>(timeInfo.bbt.tick) / timeInfo.bbt.ticksPerBeat));
doPostRt = true;
}
break;
case LV2_PORT_DESIGNATION_TIME_BEAT:
if ((timeInfo.valid & EngineTimeInfo::kValidBBT) != 0 && fLastTimeInfo.bbt.beat != timeInfo.bbt.beat)
{
fParamBuffers[k] = float(timeInfo.bbt.beat - 1);
fParamBuffers[k] = static_cast<float>(timeInfo.bbt.beat - 1);
doPostRt = true;
}
break;
@@ -2450,7 +2445,7 @@ public:
case LV2_PORT_DESIGNATION_TIME_BEATS_PER_MINUTE:
if ((timeInfo.valid & EngineTimeInfo::kValidBBT) != 0 && fLastTimeInfo.bbt.beatsPerMinute != timeInfo.bbt.beatsPerMinute)
{
fParamBuffers[k] = float(timeInfo.bbt.beatsPerMinute);
fParamBuffers[k] = static_cast<float>(timeInfo.bbt.beatsPerMinute);
doPostRt = true;
}
break;
@@ -2460,13 +2455,12 @@ public:
pData->postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 1, fParamBuffers[k]);
}

#if 0
for (i = 0; i < fEventsIn.count; ++i)
for (uint32_t 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];
lv2_atom_forge_set_buffer(&fAtomForge, timeInfoBuf, sizeof(timeInfoBuf));

LV2_Atom_Forge_Frame forgeFrame;
@@ -2474,30 +2468,29 @@ public:
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);
lv2_atom_forge_long(&fAtomForge, static_cast<int64_t>(timeInfo.frame));

if (timeInfo.valid & EngineTimeInfo::kValidBBT)
{
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_float(&fAtomForge, static_cast<float>(static_cast<double>(timeInfo.bbt.beat) - 1.0 + (static_cast<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_double(&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_int(&fAtomForge, static_cast<int32_t>(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);
lv2_atom_forge_float(&fAtomForge, static_cast<float>(timeInfo.bbt.beatsPerMinute));
}

LV2_Atom* const 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, LV2_ATOM_BODY_CONST(atom));

CARLA_ASSERT(atom->size < 256);
}
#endif

pData->postRtEvents.trySplice();

@@ -2506,7 +2499,6 @@ public:
CARLA_PROCESS_CONTINUE_CHECK;
}

#if 0
// --------------------------------------------------------------------------------------------------------
// Event Input and Processing

@@ -2544,7 +2536,6 @@ public:
}
#endif

#if 0
// ----------------------------------------------------------------------------------------------------
// MIDI Input (External)

@@ -2557,67 +2548,67 @@ public:
}
else
{
k = fEventsIn.ctrlIndex;
const uint32_t j = fEventsIn.ctrlIndex;

while (! pData->extNotes.data.isEmpty())
for (; ! pData->extNotes.data.isEmpty();)
{
const ExternalMidiNote& note(pData->extNotes.data.getFirst(true));

CARLA_ASSERT(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
CARLA_SAFE_ASSERT_CONTINUE(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;
midiEvent[0] = static_cast<uint8_t>(note.channel + (note.velo > 0) ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF);
midiEvent[1] = note.note;
midiEvent[2] = note.velo;

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

#if 0
else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
lv2_event_write(&evInEventIters[k], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 3, midiEvent);
lv2_event_write(&evInEventIters[j], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 3, midiEvent);

else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
lv2midi_put_event(&evInMidiStates[k], 0, 3, midiEvent);
lv2midi_put_event(&evInMidiStates[j], 0, 3, midiEvent);
#endif
}
}

pData->extNotes.mutex.unlock();

} // End of MIDI Input (External)
#endif

// ----------------------------------------------------------------------------------------------------
// Event Input (System)

bool allNotesOffSent = false;
bool sampleAccurate = (pData->options & PLUGIN_OPTION_FIXED_BUFFER) == 0;
bool allNotesOffSent = false;
bool isSampleAccurate = (pData->options & PLUGIN_OPTION_FIXED_BUFFERS) == 0;

uint32_t time, nEvents = (fEventsIn.ctrl->port != nullptr) ? fEventsIn.ctrl->port->getEventCount() : 0;
uint32_t numEvents = (fEventsIn.ctrl->port != nullptr) ? fEventsIn.ctrl->port->getEventCount() : 0;
uint32_t startTime = 0;
uint32_t timeOffset = 0;
uint32_t nextBankId = 0;
uint32_t nextBankId;

if (pData->midiprog.current >= 0 && pData->midiprog.count > 0)
nextBankId = pData->midiprog.data[pData->midiprog.current].bank;
else
nextBankId = 0;

for (i=0; i < nEvents; ++i)
for (uint32_t i=0; i < numEvents; ++i)
{
const EngineEvent& event(fEventsIn.ctrl->port->getEvent(i));

time = event.time;

if (time >= frames)
if (event.time >= frames)
continue;

CARLA_ASSERT_INT2(time >= timeOffset, time, timeOffset);
CARLA_ASSERT_INT2(event.time >= timeOffset, event.time, timeOffset);

if (time > timeOffset && sampleAccurate)
if (isSampleAccurate && event.time > timeOffset)
{
if (processSingle(inBuffer, outBuffer, time - timeOffset, timeOffset))
if (processSingle(inBuffer, outBuffer, event.time - timeOffset, timeOffset))
{
startTime = 0;
timeOffset = time;
timeOffset = event.time;

if (pData->midiprog.current >= 0 && pData->midiprog.count > 0)
nextBankId = pData->midiprog.data[pData->midiprog.current].bank;
@@ -2625,37 +2616,37 @@ public:
nextBankId = 0;

// reset iters
k = fEventsIn.ctrlIndex;
const uint32_t j = fEventsIn.ctrlIndex;

if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
{
lv2_atom_buffer_reset(fEventsIn.data[k].atom, true);
lv2_atom_buffer_begin(&evInAtomIters[k], fEventsIn.data[k].atom);
lv2_atom_buffer_reset(fEventsIn.data[j].atom, true);
lv2_atom_buffer_begin(&evInAtomIters[j], fEventsIn.data[j].atom);
}
#if 0
else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
{
lv2_event_buffer_reset(fEventsIn.data[k].event, LV2_EVENT_AUDIO_STAMP, fEventsIn.data[k].event->data);
lv2_event_begin(&evInEventIters[k], fEventsIn.data[k].event);
lv2_event_buffer_reset(fEventsIn.data[j].event, LV2_EVENT_AUDIO_STAMP, fEventsIn.data[j].event->data);
lv2_event_begin(&evInEventIters[j], fEventsIn.data[j].event);
}
else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
{
fEventsIn.data[k].midi->event_count = 0;
fEventsIn.data[k].midi->size = 0;
evInMidiStates[k].position = time;
fEventsIn.data[j].midi.event_count = 0;
fEventsIn.data[j].midi.size = 0;
evInMidiStates[j].position = event.time;
}
#endif
}
else
startTime += timeOffset;
}

// Control change
switch (event.type)
{
case kEngineEventTypeNull:
break;

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

switch (ctrlEvent.type)
@@ -2663,29 +2654,30 @@ public:
case kEngineControlEventTypeNull:
break;

case kEngineControlEventTypeParameter:
{
case kEngineControlEventTypeParameter: {
#ifndef BUILD_BRIDGE
// Control backend stuff
if (event.channel == pData->ctrlChannel)
{
float value;

if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_DRYWET) > 0)
if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_DRYWET) != 0)
{
value = ctrlEvent.value;
setDryWet(value, false, false);
postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_DRYWET, 0, value);
pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_DRYWET, 0, value);
break;
}

if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_VOLUME) > 0)
if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_VOLUME) != 0)
{
value = ctrlEvent.value*127.0f/100.0f;
setVolume(value, false, false);
postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value);
pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_VOLUME, 0, value);
break;
}

if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_BALANCE) > 0)
if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (pData->hints & PLUGIN_CAN_BALANCE) != 0)
{
float left, right;
value = ctrlEvent.value/0.5f - 1.0f;
@@ -2708,13 +2700,15 @@ public:

setBalanceLeft(left, false, false);
setBalanceRight(right, false, false);
postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_LEFT, 0, left);
postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_RIGHT, 0, right);
pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_LEFT, 0, left);
pData->postponeRtEvent(kPluginPostRtEventParameterChange, PARAMETER_BALANCE_RIGHT, 0, right);
break;
}
}
#endif

// Control plugin parameters
uint32_t k;
for (k=0; k < pData->param.count; ++k)
{
if (pData->param.data[k].midiChannel != event.channel)
@@ -2734,35 +2728,42 @@ public:
}
else
{
value = pData->param.ranges[k].unnormalizeValue(ctrlEvent.value);
value = pData->param.ranges[k].getUnnormalizedValue(ctrlEvent.value);

if (pData->param.data[k].hints & PARAMETER_IS_INTEGER)
value = std::rint(value);
}

setParameterValue(k, value, false, false, false);
postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 0, value);
pData->postponeRtEvent(kPluginPostRtEventParameterChange, static_cast<int32_t>(k), 0, value);
break;
}

// check if event is already handled
if (k != pData->param.count)
break;

if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param <= 0x5F)
{
uint8_t midiData[3];
midiData[0] = MIDI_STATUS_CONTROL_CHANGE + i;
midiData[1] = ctrlEvent.param;
midiData[2] = ctrlEvent.value*127.0f;
midiData[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + i);
midiData[1] = static_cast<uint8_t>(ctrlEvent.param);
midiData[2] = uint8_t(ctrlEvent.value*127.0f);

if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
lv2_atom_buffer_write(&evInAtomIters[fEventsIn.ctrlIndex], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 3, midiData);

#if 0
else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
lv2_event_write(&evInEventIters[fEventsIn.ctrlIndex], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 3, midiData);

else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
lv2midi_put_event(&evInMidiStates[fEventsIn.ctrlIndex], 0, 3, midiData);
#endif
}

break;
}
} // case kEngineControlEventTypeParameter

case kEngineControlEventTypeMidiBank:
if (event.channel == pData->ctrlChannel && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
@@ -2774,12 +2775,13 @@ public:
{
const uint32_t nextProgramId = ctrlEvent.param;

for (k=0; k < pData->midiprog.count; ++k)
for (uint32_t k=0; k < pData->midiprog.count; ++k)
{
if (pData->midiprog.data[k].bank == nextBankId && pData->midiprog.data[k].program == nextProgramId)
{
setMidiProgram(k, false, false, false);
postponeRtEvent(kPluginPostRtEventMidiProgramChange, k, 0, 0.0f);
const int32_t index(static_cast<int32_t>(k));
setMidiProgram(index, false, false, false);
pData->postponeRtEvent(kPluginPostRtEventMidiProgramChange, index, 0, 0.0f);
break;
}
}
@@ -2789,21 +2791,23 @@ public:
case kEngineControlEventTypeAllSoundOff:
if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
{
const uint32_t mtime(sampleAccurate ? startTime : time);
const uint32_t mtime(isSampleAccurate ? startTime : event.time);

uint8_t midiData[3];
midiData[0] = MIDI_STATUS_CONTROL_CHANGE + i;
midiData[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + i);
midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;
midiData[2] = 0;

if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
lv2_atom_buffer_write(&evInAtomIters[fEventsIn.ctrlIndex], mtime, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 3, midiData);

#if 0
else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
lv2_event_write(&evInEventIters[fEventsIn.ctrlIndex], mtime, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 3, midiData);

else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
lv2midi_put_event(&evInMidiStates[fEventsIn.ctrlIndex], mtime, 3, midiData);
#endif
}
break;

@@ -2816,68 +2820,71 @@ public:
sendMidiAllNotesOffToCallback();
}

const uint32_t mtime(sampleAccurate ? startTime : time);
const uint32_t mtime(isSampleAccurate ? startTime : event.time);

uint8_t midiData[3];
midiData[0] = MIDI_STATUS_CONTROL_CHANGE + i;
midiData[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + i);
midiData[1] = MIDI_CONTROL_ALL_NOTES_OFF;
midiData[2] = 0;

if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
lv2_atom_buffer_write(&evInAtomIters[fEventsIn.ctrlIndex], mtime, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 3, midiData);

#if 0
else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
lv2_event_write(&evInEventIters[fEventsIn.ctrlIndex], mtime, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 3, midiData);

else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
lv2midi_put_event(&evInMidiStates[fEventsIn.ctrlIndex], mtime, 3, midiData);
#endif
}
break;
}

} // switch (ctrlEvent.type)
break;
}
} // case kEngineEventTypeControl

case kEngineEventTypeMidi:
{
const EngineMidiEvent& midiEvent(event.midi);

uint8_t status = MIDI_GET_STATUS_FROM_DATA(midiEvent.data);
uint8_t status = uint8_t(MIDI_GET_STATUS_FROM_DATA(midiEvent.data));
uint8_t channel = event.channel;
uint32_t mtime = sampleAccurate ? startTime : time;
uint32_t mtime = isSampleAccurate ? startTime : event.time;

// Fix bad note-off (per LV2 spec)
if (MIDI_IS_STATUS_NOTE_ON(status) && midiEvent.data[2] == 0)
status = MIDI_STATUS_NOTE_OFF;

if (MIDI_IS_STATUS_AFTERTOUCH(status) && (pData->options & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) == 0)
if (status == MIDI_STATUS_CHANNEL_PRESSURE && (pData->options & PLUGIN_OPTION_SEND_CHANNEL_PRESSURE) == 0)
continue;
if (MIDI_IS_STATUS_CONTROL_CHANGE(status) && (pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) == 0)
if (status == MIDI_STATUS_CONTROL_CHANGE && (pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) == 0)
continue;
if (MIDI_IS_STATUS_POLYPHONIC_AFTERTOUCH(status) && (pData->options & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) == 0)
if (status == MIDI_STATUS_POLYPHONIC_AFTERTOUCH && (pData->options & PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH) == 0)
continue;
if (MIDI_IS_STATUS_PITCH_WHEEL_CONTROL(status) && (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) == 0)
if (status == MIDI_STATUS_PITCH_WHEEL_CONTROL && (pData->options & PLUGIN_OPTION_SEND_PITCHBEND) == 0)
continue;

// Fix bad note-off
if (status == MIDI_STATUS_NOTE_ON && midiEvent.data[2] == 0)
status -= 0x10;

k = fEventsIn.ctrlIndex;
const uint32_t j = fEventsIn.ctrlIndex;

if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM)
lv2_atom_buffer_write(&evInAtomIters[k], mtime, 0, CARLA_URI_MAP_ID_MIDI_EVENT, midiEvent.size, midiEvent.data);
lv2_atom_buffer_write(&evInAtomIters[j], mtime, 0, CARLA_URI_MAP_ID_MIDI_EVENT, midiEvent.size, midiEvent.data);

#if 0
else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT)
lv2_event_write(&evInEventIters[k], mtime, 0, CARLA_URI_MAP_ID_MIDI_EVENT, midiEvent.size, midiEvent.data);
lv2_event_write(&evInEventIters[j], mtime, 0, CARLA_URI_MAP_ID_MIDI_EVENT, midiEvent.size, midiEvent.data);

else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
lv2midi_put_event(&evInMidiStates[k], mtime, midiEvent.size, midiEvent.data);
lv2midi_put_event(&evInMidiStates[j], mtime, midiEvent.size, midiEvent.data);
#endif

if (status == MIDI_STATUS_NOTE_ON)
postponeRtEvent(kPluginPostRtEventNoteOn, channel, midiEvent.data[1], midiEvent.data[2]);
pData->postponeRtEvent(kPluginPostRtEventNoteOn, channel, midiEvent.data[1], midiEvent.data[2]);
else if (status == MIDI_STATUS_NOTE_OFF)
postponeRtEvent(kPluginPostRtEventNoteOff, channel, midiEvent.data[1], 0.0f);
pData->postponeRtEvent(kPluginPostRtEventNoteOff, channel, midiEvent.data[1], 0.0f);

break;
}
}
} // case kEngineEventTypeMidi
} // switch (event.type)
}

pData->postRtEvents.trySplice();
@@ -2891,7 +2898,6 @@ public:
// Plugin processing (no events)

else
#endif
{
processSingle(inBuffer, outBuffer, frames, 0);

@@ -2899,7 +2905,6 @@ public:

CARLA_PROCESS_CONTINUE_CHECK;

#if 0
// --------------------------------------------------------------------------------------------------------
// MIDI Output

@@ -2907,14 +2912,14 @@ public:
{
if (fEventsOut.ctrl->type & CARLA_EVENT_DATA_ATOM)
{
const uint32_t rindex(fEventsOut.ctrl->rindex);
//const uint32_t rindex(fEventsOut.ctrl->rindex);
const LV2_Atom_Event* ev;
LV2_Atom_Buffer_Iterator iter;

uint8_t* data;
lv2_atom_buffer_begin(&iter, fEventsOut.ctrl->atom);

while (true)
for (;;)
{
data = nullptr;
ev = lv2_atom_buffer_get(&iter, &data);
@@ -2922,15 +2927,21 @@ public:
if (ev == nullptr || data == nullptr)
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);

if (ev->body.type == CARLA_URI_MAP_ID_MIDI_EVENT)
{
if (fEventsOut.ctrl->port != nullptr && ev->time.frames >= 0 && ev->body.size <= 0xFF)
fEventsOut.ctrl->port->writeMidiEvent(static_cast<uint32_t>(ev->time.frames), static_cast<uint8_t>(ev->body.size), data);
}
#if 0
else if (ev->body.type == CARLA_URI_MAP_ID_ATOM_BLANK)
{
fAtomQueueOut.put(rindex, &ev->body);

}
#endif
lv2_atom_buffer_increment(&iter);
}
}
#if 0
else if ((fEventsOut.ctrl->type & CARLA_EVENT_DATA_EVENT) != 0 && fEventsOut.ctrl->port != nullptr)
{
const LV2_Event* ev;
@@ -2939,7 +2950,7 @@ public:
uint8_t* data;
lv2_event_begin(&iter, fEventsOut.ctrl->event);

while (true)
for (;;)
{
data = nullptr;
ev = lv2_event_get(&iter, &data);
@@ -2948,7 +2959,7 @@ public:
break;

if (ev->type == CARLA_URI_MAP_ID_MIDI_EVENT)
fEventsOut.ctrl->port->writeMidiEvent(ev->frames, data, ev->size);
fEventsOut.ctrl->port->writeMidiEvent(ev->frames, ev->size, data);

lv2_event_increment(&iter);
}
@@ -2961,17 +2972,17 @@ public:
double eventTime;
unsigned char* eventData;

while (lv2midi_get_event(&state, &eventTime, &eventSize, &eventData) < frames)
for (; lv2midi_get_event(&state, &eventTime, &eventSize, &eventData) < frames;)
{
if (eventData == nullptr || eventSize == 0)
break;

fEventsOut.ctrl->port->writeMidiEvent(eventTime, eventData, eventSize);
fEventsOut.ctrl->port->writeMidiEvent(eventTime, eventSize, eventData);
lv2midi_step(&state);
}
}
}
#endif
}

// --------------------------------------------------------------------------------------------------------
// Control Output


+ 2
- 6
source/utils/CarlaLv2Utils.hpp View File

@@ -1250,13 +1250,9 @@ bool is_lv2_port_supported(const LV2_Property types)
return true;
if (LV2_IS_PORT_AUDIO(types))
return true;

// TODO
return false;

if (LV2_IS_PORT_ATOM_SEQUENCE(types))
return true;
if (LV2_IS_PORT_CV(types))
return false; // TODO
if (LV2_IS_PORT_ATOM_SEQUENCE(types))
return true;
if (LV2_IS_PORT_EVENT(types))
return true;


Loading…
Cancel
Save