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 #endif


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


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


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


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


pData->extNotes.append(extNote); pData->extNotes.append(extNote);


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


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

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


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


if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param <= 0x5F) 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 { union {
LV2_Atom_Buffer* atom; LV2_Atom_Buffer* atom;
LV2_Event_Buffer* event; LV2_Event_Buffer* event;
LV2_MIDI* midi;
void* _ptr; // value checking
LV2_MIDI midi;
}; };


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


~Lv2EventData() ~Lv2EventData()
{ {
@@ -166,35 +164,30 @@ struct Lv2EventData {
port = nullptr; 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,); CARLA_SAFE_ASSERT_RETURN(atom != nullptr,);


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


std::free(event); std::free(event);
event = nullptr; 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) CARLA_DECLARE_NON_COPY_STRUCT(Lv2EventData)
@@ -1383,82 +1376,74 @@ public:
FLOAT_CLEAR(fParamBuffers, params); 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); 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) 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) 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) 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); 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) 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) 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) 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()); const uint portNameSize(pData->engine->getMaxPortNameSize());
CarlaString portName; 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); const LV2_Property portTypes(fRdfDescriptor->Ports[i].Types);


portName.clear(); 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) if (processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
{ {
@@ -1501,7 +1486,6 @@ public:
else else
carla_stderr2("WARNING - Got a broken Port (Audio, but not input or output)"); carla_stderr2("WARNING - Got a broken Port (Audio, but not input or output)");
} }
#if 0
else if (LV2_IS_PORT_CV(portTypes)) else if (LV2_IS_PORT_CV(portTypes))
{ {
if (LV2_IS_PORT_INPUT(portTypes)) if (LV2_IS_PORT_INPUT(portTypes))
@@ -1601,6 +1585,7 @@ public:
else else
carla_stderr2("WARNING - Got a broken Port (Atom-Sequence, but not input or output)"); carla_stderr2("WARNING - Got a broken Port (Atom-Sequence, but not input or output)");
} }
#if 0
else if (LV2_IS_PORT_EVENT(portTypes)) else if (LV2_IS_PORT_EVENT(portTypes))
{ {
if (LV2_IS_PORT_INPUT(portTypes)) if (LV2_IS_PORT_INPUT(portTypes))
@@ -1682,16 +1667,17 @@ public:
else else
carla_stderr2("WARNING - Got a broken Port (Event, but not input or output)"); carla_stderr2("WARNING - Got a broken Port (Event, but not input or output)");
} }
#endif
else if (LV2_IS_PORT_MIDI_LL(portTypes)) else if (LV2_IS_PORT_MIDI_LL(portTypes))
{ {
if (LV2_IS_PORT_INPUT(portTypes)) if (LV2_IS_PORT_INPUT(portTypes))
{ {
uint32_t j = iEvIn++; 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) 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].type |= CARLA_EVENT_TYPE_MIDI;
fEventsIn.data[j].rindex = i; fEventsIn.data[j].rindex = i;
@@ -1717,10 +1703,10 @@ public:
{ {
uint32_t j = iEvOut++; 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) 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].type |= CARLA_EVENT_TYPE_MIDI;
fEventsOut.data[j].rindex = i; fEventsOut.data[j].rindex = i;
@@ -1745,7 +1731,6 @@ public:
else else
carla_stderr2("WARNING - Got a broken Port (MIDI, but not input or output)"); carla_stderr2("WARNING - Got a broken Port (MIDI, but not input or output)");
} }
#endif
else if (LV2_IS_PORT_CONTROL(portTypes)) else if (LV2_IS_PORT_CONTROL(portTypes))
{ {
const LV2_Property portProps(fRdfDescriptor->Ports[i].Properties); const LV2_Property portProps(fRdfDescriptor->Ports[i].Properties);
@@ -2248,46 +2233,53 @@ public:
return; return;
} }


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


LV2_Atom_Buffer_Iterator evInAtomIters[fEventsIn.count]; LV2_Atom_Buffer_Iterator evInAtomIters[fEventsIn.count];
#if 0
LV2_Event_Iterator evInEventIters[fEventsIn.count]; LV2_Event_Iterator evInEventIters[fEventsIn.count];
LV2_MIDIState evInMidiStates[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) if (fEventsIn.data[i].type & CARLA_EVENT_DATA_ATOM)
{ {
lv2_atom_buffer_reset(fEventsIn.data[i].atom, true); lv2_atom_buffer_reset(fEventsIn.data[i].atom, true);
lv2_atom_buffer_begin(&evInAtomIters[i], fEventsIn.data[i].atom); lv2_atom_buffer_begin(&evInAtomIters[i], fEventsIn.data[i].atom);
} }
#if 0
else if (fEventsIn.data[i].type & CARLA_EVENT_DATA_EVENT) 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_buffer_reset(fEventsIn.data[i].event, LV2_EVENT_AUDIO_STAMP, fEventsIn.data[i].event->data);
lv2_event_begin(&evInEventIters[i], fEventsIn.data[i].event); lv2_event_begin(&evInEventIters[i], fEventsIn.data[i].event);
} }
#endif
else if (fEventsIn.data[i].type & CARLA_EVENT_DATA_MIDI_LL) 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].frame_count = frames;
evInMidiStates[i].position = 0; 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) if (fEventsOut.data[i].type & CARLA_EVENT_DATA_ATOM)
{ {
lv2_atom_buffer_reset(fEventsOut.data[i].atom, false); lv2_atom_buffer_reset(fEventsOut.data[i].atom, false);
} }
#if 0
else if (fEventsOut.data[i].type & CARLA_EVENT_DATA_EVENT) 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); 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) else if (fEventsOut.data[i].type & CARLA_EVENT_DATA_MIDI_LL)
{ {
// not needed // not needed
@@ -2295,68 +2287,71 @@ public:
} }


CARLA_PROCESS_CONTINUE_CHECK; CARLA_PROCESS_CONTINUE_CHECK;
#endif


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


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


if (fEventsIn.ctrl != nullptr && (fEventsIn.ctrl->type & CARLA_EVENT_TYPE_MIDI) != 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) 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; midiData[1] = MIDI_CONTROL_ALL_NOTES_OFF;


if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM) 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) 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) 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; midiData[1] = MIDI_CONTROL_ALL_SOUND_OFF;


if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM) 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) 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) 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) 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; midiData[1] = k;


if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM) 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[k], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 3, midiData);


#if 0
else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_EVENT) 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[k], 0, 0, CARLA_URI_MAP_ID_MIDI_EVENT, 3, midiData);


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


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


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


LV2_Atom_Forge_Frame forgeFrame; 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_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_SPEED, 0);
lv2_atom_forge_float(&fAtomForge, timeInfo.playing ? 1.0f : 0.0f); 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_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) if (timeInfo.valid & EngineTimeInfo::kValidBBT)
{ {
lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_BAR, 0); 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_long(&fAtomForge, timeInfo.bbt.bar - 1);
lv2_atom_forge_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_BAR_BEAT, 0); 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_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_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_property_head(&fAtomForge, CARLA_URI_MAP_ID_TIME_BEATS_PER_BAR, 0);
lv2_atom_forge_float(&fAtomForge, timeInfo.bbt.beatsPerBar); 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_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* 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); CARLA_ASSERT(atom->size < 256);
} }
#endif


pData->postRtEvents.trySplice(); pData->postRtEvents.trySplice();


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


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


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


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


@@ -2557,67 +2548,67 @@ public:
} }
else 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)); 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]; 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) 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) 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) 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(); pData->extNotes.mutex.unlock();


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


// ---------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------
// Event Input (System) // 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 startTime = 0;
uint32_t timeOffset = 0; uint32_t timeOffset = 0;
uint32_t nextBankId = 0;
uint32_t nextBankId;


if (pData->midiprog.current >= 0 && pData->midiprog.count > 0) if (pData->midiprog.current >= 0 && pData->midiprog.count > 0)
nextBankId = pData->midiprog.data[pData->midiprog.current].bank; 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)); const EngineEvent& event(fEventsIn.ctrl->port->getEvent(i));


time = event.time;

if (time >= frames)
if (event.time >= frames)
continue; 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; startTime = 0;
timeOffset = time;
timeOffset = event.time;


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


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


if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM) 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) 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) 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 else
startTime += timeOffset; startTime += timeOffset;
} }


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


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


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


case kEngineControlEventTypeParameter:
{
case kEngineControlEventTypeParameter: {
#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
// Control backend stuff // Control backend stuff
if (event.channel == pData->ctrlChannel) if (event.channel == pData->ctrlChannel)
{ {
float value; 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; value = ctrlEvent.value;
setDryWet(value, false, false); 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; value = ctrlEvent.value*127.0f/100.0f;
setVolume(value, false, false); 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; float left, right;
value = ctrlEvent.value/0.5f - 1.0f; value = ctrlEvent.value/0.5f - 1.0f;
@@ -2708,13 +2700,15 @@ public:


setBalanceLeft(left, false, false); setBalanceLeft(left, false, false);
setBalanceRight(right, 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 #endif


// Control plugin parameters // Control plugin parameters
uint32_t k;
for (k=0; k < pData->param.count; ++k) for (k=0; k < pData->param.count; ++k)
{ {
if (pData->param.data[k].midiChannel != event.channel) if (pData->param.data[k].midiChannel != event.channel)
@@ -2734,35 +2728,42 @@ public:
} }
else 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) if (pData->param.data[k].hints & PARAMETER_IS_INTEGER)
value = std::rint(value); value = std::rint(value);
} }


setParameterValue(k, value, false, false, false); 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) if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param <= 0x5F)
{ {
uint8_t midiData[3]; 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) 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); 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) 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); 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) else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
lv2midi_put_event(&evInMidiStates[fEventsIn.ctrlIndex], 0, 3, midiData); lv2midi_put_event(&evInMidiStates[fEventsIn.ctrlIndex], 0, 3, midiData);
#endif
} }


break; break;
}
} // case kEngineControlEventTypeParameter


case kEngineControlEventTypeMidiBank: case kEngineControlEventTypeMidiBank:
if (event.channel == pData->ctrlChannel && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0) if (event.channel == pData->ctrlChannel && (pData->options & PLUGIN_OPTION_MAP_PROGRAM_CHANGES) != 0)
@@ -2774,12 +2775,13 @@ public:
{ {
const uint32_t nextProgramId = ctrlEvent.param; 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) 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; break;
} }
} }
@@ -2789,21 +2791,23 @@ public:
case kEngineControlEventTypeAllSoundOff: case kEngineControlEventTypeAllSoundOff:
if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF) 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]; 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[1] = MIDI_CONTROL_ALL_SOUND_OFF;
midiData[2] = 0; midiData[2] = 0;


if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM) 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); 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) 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); 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) else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
lv2midi_put_event(&evInMidiStates[fEventsIn.ctrlIndex], mtime, 3, midiData); lv2midi_put_event(&evInMidiStates[fEventsIn.ctrlIndex], mtime, 3, midiData);
#endif
} }
break; break;


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


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


uint8_t midiData[3]; 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[1] = MIDI_CONTROL_ALL_NOTES_OFF;
midiData[2] = 0; midiData[2] = 0;


if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_ATOM) 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); 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) 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); 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) else if (fEventsIn.ctrl->type & CARLA_EVENT_DATA_MIDI_LL)
lv2midi_put_event(&evInMidiStates[fEventsIn.ctrlIndex], mtime, 3, midiData); lv2midi_put_event(&evInMidiStates[fEventsIn.ctrlIndex], mtime, 3, midiData);
#endif
} }
break; break;
}

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


case kEngineEventTypeMidi: case kEngineEventTypeMidi:
{ {
const EngineMidiEvent& midiEvent(event.midi); 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; 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; 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; 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; 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; 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) 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) 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) 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) 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) 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; break;
}
}
} // case kEngineEventTypeMidi
} // switch (event.type)
} }


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


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


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


CARLA_PROCESS_CONTINUE_CHECK; CARLA_PROCESS_CONTINUE_CHECK;


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


@@ -2907,14 +2912,14 @@ public:
{ {
if (fEventsOut.ctrl->type & CARLA_EVENT_DATA_ATOM) 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; const LV2_Atom_Event* ev;
LV2_Atom_Buffer_Iterator iter; LV2_Atom_Buffer_Iterator iter;


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


while (true)
for (;;)
{ {
data = nullptr; data = nullptr;
ev = lv2_atom_buffer_get(&iter, &data); ev = lv2_atom_buffer_get(&iter, &data);
@@ -2922,15 +2927,21 @@ public:
if (ev == nullptr || data == nullptr) if (ev == nullptr || data == nullptr)
break; 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) else if (ev->body.type == CARLA_URI_MAP_ID_ATOM_BLANK)
{
fAtomQueueOut.put(rindex, &ev->body); fAtomQueueOut.put(rindex, &ev->body);

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


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


if (ev->type == CARLA_URI_MAP_ID_MIDI_EVENT) 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); lv2_event_increment(&iter);
} }
@@ -2961,17 +2972,17 @@ public:
double eventTime; double eventTime;
unsigned char* eventData; 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) if (eventData == nullptr || eventSize == 0)
break; break;


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


// -------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------
// Control Output // 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; return true;
if (LV2_IS_PORT_AUDIO(types)) if (LV2_IS_PORT_AUDIO(types))
return true; return true;

// TODO
return false;

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


Loading…
Cancel
Save