Skip to content

Commit 64a99a7

Browse files
committed
Rework how AU midi out works, do it properly this time
Signed-off-by: falkTX <[email protected]>
1 parent df621e8 commit 64a99a7

File tree

1 file changed

+44
-22
lines changed

1 file changed

+44
-22
lines changed

distrho/src/DistrhoPluginAU.cpp

+44-22
Original file line numberDiff line numberDiff line change
@@ -276,12 +276,18 @@ struct RenderListener {
276276
typedef std::vector<PropertyListener> PropertyListeners;
277277
typedef std::vector<RenderListener> RenderListeners;
278278

279-
// --------------------------------------------------------------------------------------------------------------------
279+
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
280+
// useful definitions
281+
static constexpr const uint32_t kMIDIPacketNonDataSize = sizeof(MIDIPacket) - sizeof(MIDIPacket::data);
282+
static constexpr const uint32_t kMIDIPacketListNonDataSize = sizeof(MIDIPacketList) - sizeof(MIDIPacketList::packet);
283+
284+
// size of data used for midi events
285+
static constexpr const uint32_t kMIDIPacketListMaxDataSize = kMIDIPacketNonDataSize * kMaxMidiEvents
286+
+ sizeof(Byte) * MidiEvent::kDataSize * kMaxMidiEvents;
280287

281-
typedef struct {
282-
UInt32 numPackets;
283-
MIDIPacket packets[kMaxMidiEvents];
284-
} d_MIDIPacketList;
288+
// size of midi list + data
289+
static constexpr const uint32_t kMIDIPacketListSize = kMIDIPacketListNonDataSize + kMIDIPacketListMaxDataSize;
290+
#endif
285291

286292
// --------------------------------------------------------------------------------------------------------------------
287293

@@ -335,6 +341,9 @@ class PluginAU
335341
#if DISTRHO_PLUGIN_WANT_MIDI_INPUT
336342
, fMidiEventCount(0)
337343
#endif
344+
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
345+
, fMidiOutputDataOffset(0)
346+
#endif
338347
#if DISTRHO_PLUGIN_WANT_PROGRAMS
339348
, fCurrentProgram(-1)
340349
, fLastFactoryProgram(0)
@@ -370,8 +379,10 @@ class PluginAU
370379
#endif
371380

372381
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
382+
if ((fMidiOutputPackets = static_cast<MIDIPacketList*>(std::malloc(kMIDIPacketListSize))) != nullptr)
383+
std::memset(fMidiOutputPackets, 0, kMIDIPacketListSize);
384+
373385
std::memset(&fMidiOutput, 0, sizeof(fMidiOutput));
374-
std::memset(&fMidiOutputPackets, 0, sizeof(fMidiOutputPackets));
375386
#endif
376387

377388
#if DISTRHO_PLUGIN_WANT_PROGRAMS
@@ -428,6 +439,10 @@ class PluginAU
428439
reallocAudioBufferList(false);
429440
#endif
430441

442+
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
443+
std::free(fMidiOutputPackets);
444+
#endif
445+
431446
#if DISTRHO_PLUGIN_WANT_PROGRAMS
432447
for (uint32_t i=0; i<fProgramCount; ++i)
433448
CFRelease(fFactoryPresetsData[i].presetName);
@@ -451,7 +466,8 @@ class PluginAU
451466
fMidiEventCount = 0;
452467
#endif
453468
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
454-
fMidiOutputPackets.numPackets = 0;
469+
fMidiOutputDataOffset = 0;
470+
fMidiOutputPackets->numPackets = 0;
455471
#endif
456472
#if DISTRHO_PLUGIN_WANT_TIMEPOS
457473
fTimePosition.clear();
@@ -1787,7 +1803,8 @@ class PluginAU
17871803
fMidiEventCount = 0;
17881804
#endif
17891805
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
1790-
fMidiOutputPackets.numPackets = 0;
1806+
fMidiOutputDataOffset = 0;
1807+
fMidiOutputPackets->numPackets = 0;
17911808
#endif
17921809
#if DISTRHO_PLUGIN_WANT_TIMEPOS
17931810
fTimePosition.clear();
@@ -2143,8 +2160,9 @@ class PluginAU
21432160
#endif
21442161

21452162
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
2163+
uint32_t fMidiOutputDataOffset;
2164+
MIDIPacketList* fMidiOutputPackets;
21462165
AUMIDIOutputCallbackStruct fMidiOutput;
2147-
d_MIDIPacketList fMidiOutputPackets;
21482166
#endif
21492167

21502168
#if DISTRHO_PLUGIN_WANT_PROGRAMS
@@ -2219,7 +2237,8 @@ class PluginAU
22192237
#endif
22202238

22212239
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
2222-
fMidiOutputPackets.numPackets = 0;
2240+
fMidiOutputDataOffset = 0;
2241+
fMidiOutputPackets->numPackets = 0;
22232242
#endif
22242243

22252244
#if DISTRHO_PLUGIN_WANT_TIMEPOS
@@ -2296,12 +2315,11 @@ class PluginAU
22962315
#endif
22972316

22982317
#if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT
2299-
if (fMidiOutputPackets.numPackets != 0 && fMidiOutput.midiOutputCallback != nullptr)
2318+
if (fMidiOutputPackets != nullptr &&
2319+
fMidiOutputPackets->numPackets != 0 &&
2320+
fMidiOutput.midiOutputCallback != nullptr)
23002321
{
2301-
fMidiOutput.midiOutputCallback(fMidiOutput.userData,
2302-
inTimeStamp,
2303-
0,
2304-
reinterpret_cast<const ::MIDIPacketList*>(&fMidiOutputPackets));
2322+
fMidiOutput.midiOutputCallback(fMidiOutput.userData, inTimeStamp, 0, fMidiOutputPackets);
23052323
}
23062324
#else
23072325
// unused
@@ -2718,17 +2736,21 @@ class PluginAU
27182736
bool writeMidi(const MidiEvent& midiEvent)
27192737
{
27202738
DISTRHO_CUSTOM_SAFE_ASSERT_ONCE_RETURN("MIDI output unsupported", fMidiOutput.midiOutputCallback != nullptr, false);
2739+
DISTRHO_CUSTOM_SAFE_ASSERT_ONCE_RETURN("Out of memory", fMidiOutputPackets != nullptr, false);
27212740

2722-
if (midiEvent.size > sizeof(MIDIPacket::data))
2723-
return true;
2724-
if (fMidiOutputPackets.numPackets == kMaxMidiEvents)
2741+
if (fMidiOutputDataOffset + kMIDIPacketNonDataSize + midiEvent.size >= kMIDIPacketListMaxDataSize)
27252742
return false;
27262743

27272744
const uint8_t* const midiData = midiEvent.size > MidiEvent::kDataSize ? midiEvent.dataExt : midiEvent.data;
2728-
MIDIPacket& packet(fMidiOutputPackets.packets[fMidiOutputPackets.numPackets++]);
2729-
packet.timeStamp = midiEvent.frame;
2730-
packet.length = midiEvent.size;
2731-
std::memcpy(packet.data, midiData, midiEvent.size);
2745+
MIDIPacket* const packet = reinterpret_cast<MIDIPacket*>(
2746+
reinterpret_cast<uint8_t*>(fMidiOutputPackets->packet) + fMidiOutputDataOffset);
2747+
2748+
packet->timeStamp = midiEvent.frame;
2749+
packet->length = midiEvent.size;
2750+
std::memcpy(packet->data, midiData, midiEvent.size);
2751+
2752+
++fMidiOutputPackets->numPackets;
2753+
fMidiOutputDataOffset += kMIDIPacketNonDataSize + midiEvent.size;
27322754
return true;
27332755
}
27342756

0 commit comments

Comments
 (0)