Browse Source

Implement VST3 midi output

Signed-off-by: falkTX <falktx@falktx.com>
pull/1961/merge
falkTX 3 months ago
parent
commit
3aadaa554f
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
1 changed files with 81 additions and 13 deletions
  1. +81
    -13
      source/backend/plugin/CarlaPluginVST3.cpp

+ 81
- 13
source/backend/plugin/CarlaPluginVST3.cpp View File

@@ -895,7 +895,12 @@ private:
// --------------------------------------------------------------------------------------------------------------------

struct carla_v3_output_event_list : v3_event_list_cpp {
v3_event* const events;
uint16_t numEvents;

carla_v3_output_event_list()
: events(new v3_event[kPluginMaxMidiEvents]),
numEvents(0)
{
query_interface = v3_query_interface_static<v3_event_list_iid>;
ref = v3_ref_static;
@@ -905,6 +910,11 @@ struct carla_v3_output_event_list : v3_event_list_cpp {
list.add_event = add_event;
}

~carla_v3_output_event_list()
{
delete[] events;
}

private:
static uint32_t V3_API get_event_count(void*)
{
@@ -920,10 +930,13 @@ private:
return V3_NOT_IMPLEMENTED;
}

static v3_result V3_API add_event(void*, v3_event*)
static v3_result V3_API add_event(void* const self, v3_event* const event)
{
carla_debug("TODO %s", __PRETTY_FUNCTION__);
return V3_NOT_IMPLEMENTED;
carla_v3_output_event_list* const me = *static_cast<carla_v3_output_event_list**>(self);
if (me->numEvents >= kPluginMaxMidiEvents)
return V3_NOMEM;
std::memcpy(&me->events[me->numEvents++], event, sizeof(v3_event));
return V3_OK;
}

CARLA_DECLARE_NON_COPYABLE(carla_v3_output_event_list)
@@ -3016,15 +3029,6 @@ public:

} // End of Plugin processing (no events)

// ------------------------------------------------------------------------------------------------------------
// MIDI Output

if (pData->event.portOut != nullptr)
{
// TODO

} // End of MIDI Output

fFirstActive = false;

// ------------------------------------------------------------------------------------------------------------
@@ -3131,6 +3135,67 @@ public:
v3_cpp_obj(fV3.processor)->process(fV3.processor, &processData);
} CARLA_SAFE_EXCEPTION("process");

// ------------------------------------------------------------------------------------------------------------
// Handle MIDI output

int32_t minPortOutOffset = 0;

if (fEvents.eventOutputs != nullptr)
{
uint8_t midiData[3], midiSize;

for (uint32_t i=0; i < fEvents.eventOutputs->numEvents; ++i)
{
v3_event& v3event(fEvents.eventOutputs->events[i]);

if (v3event.bus_index != 0)
continue;

switch (v3event.type)
{
case V3_EVENT_NOTE_OFF:
midiData[0] = MIDI_STATUS_NOTE_OFF | (v3event.note_off.channel & MIDI_CHANNEL_BIT);
midiData[1] = v3event.note_off.pitch;
midiData[2] = carla_fixedValue<uint8_t>(0,
MAX_MIDI_VALUE - 1,
v3event.note_off.velocity * MAX_MIDI_VALUE);
midiSize = 3;
break;
case V3_EVENT_NOTE_ON:
midiData[0] = MIDI_STATUS_NOTE_ON | (v3event.note_on.channel & MIDI_CHANNEL_BIT);
midiData[1] = v3event.note_on.pitch;
midiData[2] = carla_fixedValue<uint8_t>(0,
MAX_MIDI_VALUE - 1,
v3event.note_on.velocity * MAX_MIDI_VALUE);
midiSize = 3;
break;
case V3_EVENT_POLY_PRESSURE:
midiData[0] = MIDI_STATUS_POLYPHONIC_AFTERTOUCH | (v3event.poly_pressure.channel & MIDI_CHANNEL_BIT);
midiData[1] = v3event.poly_pressure.pitch;
midiData[2] = carla_fixedValue<uint8_t>(0,
MAX_MIDI_VALUE - 1,
v3event.poly_pressure.pressure * MAX_MIDI_VALUE);
midiSize = 3;
break;
case V3_EVENT_LEGACY_MIDI_CC_OUT:
midiData[0] = MIDI_STATUS_CONTROL_CHANGE | (v3event.midi_cc_out.channel & MIDI_CHANNEL_BIT);
midiData[1] = v3event.midi_cc_out.cc_number;
midiData[2] = v3event.midi_cc_out.value;
midiSize = 3;
break;
default:
continue;
}

if (! pData->event.portOut->writeMidiEvent(static_cast<uint32_t>(v3event.sample_offset),
midiSize,
midiData))
break;

minPortOutOffset = v3event.sample_offset;
}
}

// ------------------------------------------------------------------------------------------------------------
// Handle parameter outputs

@@ -3157,7 +3222,7 @@ public:
channel = pData->param.data[i].midiChannel;
param = static_cast<uint16_t>(pData->param.data[i].mappedControlIndex);

pData->event.portOut->writeControlEvent(queue->offset,
pData->event.portOut->writeControlEvent(std::max(minPortOutOffset, queue->offset),
channel,
kEngineControlEventTypeParameter,
param,
@@ -4168,6 +4233,9 @@ private:

if (eventInputs != nullptr)
eventInputs->numEvents = 0;

if (eventOutputs != nullptr)
eventOutputs->numEvents = 0;
}

void prepare()


Loading…
Cancel
Save