From afefb725b5e35882fb06f2b5da57b1502ea1597c Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Fri, 23 Apr 2021 01:03:57 +0200 Subject: [PATCH] Postpone clearing old MIDI events until next event This fixes Native Instrument's FM7 crashing on MIDI input. The plugin expects the last received MIDI event to always be alive during audio processing, even if there have not been any new events in this processing cycle. --- CHANGELOG.md | 6 ++++++ src/wine-host/bridges/vst2.cpp | 12 +++++++++++- src/wine-host/bridges/vst2.h | 10 ++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4df291e..79373e61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,12 @@ Versioning](https://semver.org/spec/v2.0.0.html). at configure-time. This can make it a bit easier to diagnose Wine-related compilation issues. +### Fixed + +- Prevent _Native Instruments' FM7_ from crashing when processing MIDI. As a + fix, MIDI events are now deallocated later then when they normally would have + to be. + ## [3.1.0] - 2021-04-15 ### Added diff --git a/src/wine-host/bridges/vst2.cpp b/src/wine-host/bridges/vst2.cpp index c660098c..1c47ca82 100644 --- a/src/wine-host/bridges/vst2.cpp +++ b/src/wine-host/bridges/vst2.cpp @@ -278,7 +278,9 @@ Vst2Bridge::Vst2Bridge(MainContext& main_context, }}, request.buffers); - next_audio_buffer_midi_events.clear(); + // See the docstrong on `should_clear_midi_events` for why we + // don't just clear `next_buffer_midi_events` here + should_clear_midi_events = true; }); }); } @@ -303,6 +305,14 @@ void Vst2Bridge::run() { // plugin. std::lock_guard lock(next_buffer_midi_events_mutex); + // See the docstring on `should_clear_midi_events` for why we + // only deallocate old MIDI events here instead of a at the end + // of every processing cycle + if (should_clear_midi_events) { + next_audio_buffer_midi_events.clear(); + should_clear_midi_events = false; + } + next_audio_buffer_midi_events.push_back( std::get(event.payload)); DynamicVstEvents& events = next_audio_buffer_midi_events.back(); diff --git a/src/wine-host/bridges/vst2.h b/src/wine-host/bridges/vst2.h index 83ec6491..c765e1f1 100644 --- a/src/wine-host/bridges/vst2.h +++ b/src/wine-host/bridges/vst2.h @@ -168,6 +168,16 @@ class Vst2Bridge : public HostBridge { * at least until the next audio buffer gets processed. */ std::vector next_audio_buffer_midi_events; + /** + * Whether `next_audio_buffer_midi_events` should be cleared before + * inserting new events. + * + * HACK: Normally we should be able to clear these immediately after the + * processing call, but Native Instruments' FM7 requires the last MIDI + * event to stay alive if there have not been any new MIDI events + * during the current processing cycle. + */ + bool should_clear_midi_events = false; /** * Mutex for locking the above event queue, since recieving and processing * now happens in two different threads.