Browse Source

Rework how AU midi out works, do it properly this time

Signed-off-by: falkTX <falktx@falktx.com>
pull/480/head
falkTX 4 months ago
parent
commit
64a99a7b0a
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
1 changed files with 44 additions and 22 deletions
  1. +44
    -22
      distrho/src/DistrhoPluginAU.cpp

+ 44
- 22
distrho/src/DistrhoPluginAU.cpp View File

@@ -276,12 +276,18 @@ struct RenderListener {
typedef std::vector<PropertyListener> PropertyListeners; typedef std::vector<PropertyListener> PropertyListeners;
typedef std::vector<RenderListener> RenderListeners; typedef std::vector<RenderListener> RenderListeners;


// --------------------------------------------------------------------------------------------------------------------
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
// useful definitions
static constexpr const uint32_t kMIDIPacketNonDataSize = sizeof(MIDIPacket) - sizeof(MIDIPacket::data);
static constexpr const uint32_t kMIDIPacketListNonDataSize = sizeof(MIDIPacketList) - sizeof(MIDIPacketList::packet);

// size of data used for midi events
static constexpr const uint32_t kMIDIPacketListMaxDataSize = kMIDIPacketNonDataSize * kMaxMidiEvents
+ sizeof(Byte) * MidiEvent::kDataSize * kMaxMidiEvents;


typedef struct {
UInt32 numPackets;
MIDIPacket packets[kMaxMidiEvents];
} d_MIDIPacketList;
// size of midi list + data
static constexpr const uint32_t kMIDIPacketListSize = kMIDIPacketListNonDataSize + kMIDIPacketListMaxDataSize;
#endif


// -------------------------------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------------------------------


@@ -335,6 +341,9 @@ public:
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT #if DISTRHO_PLUGIN_WANT_MIDI_INPUT
, fMidiEventCount(0) , fMidiEventCount(0)
#endif #endif
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
, fMidiOutputDataOffset(0)
#endif
#if DISTRHO_PLUGIN_WANT_PROGRAMS #if DISTRHO_PLUGIN_WANT_PROGRAMS
, fCurrentProgram(-1) , fCurrentProgram(-1)
, fLastFactoryProgram(0) , fLastFactoryProgram(0)
@@ -370,8 +379,10 @@ public:
#endif #endif


#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
if ((fMidiOutputPackets = static_cast<MIDIPacketList*>(std::malloc(kMIDIPacketListSize))) != nullptr)
std::memset(fMidiOutputPackets, 0, kMIDIPacketListSize);

std::memset(&fMidiOutput, 0, sizeof(fMidiOutput)); std::memset(&fMidiOutput, 0, sizeof(fMidiOutput));
std::memset(&fMidiOutputPackets, 0, sizeof(fMidiOutputPackets));
#endif #endif


#if DISTRHO_PLUGIN_WANT_PROGRAMS #if DISTRHO_PLUGIN_WANT_PROGRAMS
@@ -428,6 +439,10 @@ public:
reallocAudioBufferList(false); reallocAudioBufferList(false);
#endif #endif


#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
std::free(fMidiOutputPackets);
#endif

#if DISTRHO_PLUGIN_WANT_PROGRAMS #if DISTRHO_PLUGIN_WANT_PROGRAMS
for (uint32_t i=0; i<fProgramCount; ++i) for (uint32_t i=0; i<fProgramCount; ++i)
CFRelease(fFactoryPresetsData[i].presetName); CFRelease(fFactoryPresetsData[i].presetName);
@@ -451,7 +466,8 @@ public:
fMidiEventCount = 0; fMidiEventCount = 0;
#endif #endif
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
fMidiOutputPackets.numPackets = 0;
fMidiOutputDataOffset = 0;
fMidiOutputPackets->numPackets = 0;
#endif #endif
#if DISTRHO_PLUGIN_WANT_TIMEPOS #if DISTRHO_PLUGIN_WANT_TIMEPOS
fTimePosition.clear(); fTimePosition.clear();
@@ -1787,7 +1803,8 @@ public:
fMidiEventCount = 0; fMidiEventCount = 0;
#endif #endif
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
fMidiOutputPackets.numPackets = 0;
fMidiOutputDataOffset = 0;
fMidiOutputPackets->numPackets = 0;
#endif #endif
#if DISTRHO_PLUGIN_WANT_TIMEPOS #if DISTRHO_PLUGIN_WANT_TIMEPOS
fTimePosition.clear(); fTimePosition.clear();
@@ -2143,8 +2160,9 @@ private:
#endif #endif


#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
uint32_t fMidiOutputDataOffset;
MIDIPacketList* fMidiOutputPackets;
AUMIDIOutputCallbackStruct fMidiOutput; AUMIDIOutputCallbackStruct fMidiOutput;
d_MIDIPacketList fMidiOutputPackets;
#endif #endif


#if DISTRHO_PLUGIN_WANT_PROGRAMS #if DISTRHO_PLUGIN_WANT_PROGRAMS
@@ -2219,7 +2237,8 @@ private:
#endif #endif


#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
fMidiOutputPackets.numPackets = 0;
fMidiOutputDataOffset = 0;
fMidiOutputPackets->numPackets = 0;
#endif #endif


#if DISTRHO_PLUGIN_WANT_TIMEPOS #if DISTRHO_PLUGIN_WANT_TIMEPOS
@@ -2296,12 +2315,11 @@ private:
#endif #endif


#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
if (fMidiOutputPackets.numPackets != 0 && fMidiOutput.midiOutputCallback != nullptr)
if (fMidiOutputPackets != nullptr &&
fMidiOutputPackets->numPackets != 0 &&
fMidiOutput.midiOutputCallback != nullptr)
{ {
fMidiOutput.midiOutputCallback(fMidiOutput.userData,
inTimeStamp,
0,
reinterpret_cast<const ::MIDIPacketList*>(&fMidiOutputPackets));
fMidiOutput.midiOutputCallback(fMidiOutput.userData, inTimeStamp, 0, fMidiOutputPackets);
} }
#else #else
// unused // unused
@@ -2718,17 +2736,21 @@ private:
bool writeMidi(const MidiEvent& midiEvent) bool writeMidi(const MidiEvent& midiEvent)
{ {
DISTRHO_CUSTOM_SAFE_ASSERT_ONCE_RETURN("MIDI output unsupported", fMidiOutput.midiOutputCallback != nullptr, false); DISTRHO_CUSTOM_SAFE_ASSERT_ONCE_RETURN("MIDI output unsupported", fMidiOutput.midiOutputCallback != nullptr, false);
DISTRHO_CUSTOM_SAFE_ASSERT_ONCE_RETURN("Out of memory", fMidiOutputPackets != nullptr, false);


if (midiEvent.size > sizeof(MIDIPacket::data))
return true;
if (fMidiOutputPackets.numPackets == kMaxMidiEvents)
if (fMidiOutputDataOffset + kMIDIPacketNonDataSize + midiEvent.size >= kMIDIPacketListMaxDataSize)
return false; return false;


const uint8_t* const midiData = midiEvent.size > MidiEvent::kDataSize ? midiEvent.dataExt : midiEvent.data; const uint8_t* const midiData = midiEvent.size > MidiEvent::kDataSize ? midiEvent.dataExt : midiEvent.data;
MIDIPacket& packet(fMidiOutputPackets.packets[fMidiOutputPackets.numPackets++]);
packet.timeStamp = midiEvent.frame;
packet.length = midiEvent.size;
std::memcpy(packet.data, midiData, midiEvent.size);
MIDIPacket* const packet = reinterpret_cast<MIDIPacket*>(
reinterpret_cast<uint8_t*>(fMidiOutputPackets->packet) + fMidiOutputDataOffset);

packet->timeStamp = midiEvent.frame;
packet->length = midiEvent.size;
std::memcpy(packet->data, midiData, midiEvent.size);

++fMidiOutputPackets->numPackets;
fMidiOutputDataOffset += kMIDIPacketNonDataSize + midiEvent.size;
return true; return true;
} }




Loading…
Cancel
Save