fix(bridge): stop leaves sound looping — EventList maxSize=50 drops STOP sweep note-offs

Root cause: Steinberg EventList defaults to maxSize=50 events. The STOP
all-notes-off sweep queues 128 note-offs per channel (16ch x 128 pitch),
so addEvent beyond 50 fails silently and the plugin never receives the
remaining note-offs — voices keep sustaining and the transport loops
forever until the bridge process is killed.

Fix: raise eventList.setMaxSize(4096) in loadPlugin. Also assign unique
noteIds per overlapping note-on (stack per pitch) so note-off releases
every voice at that pitch, and log addEvent result + channel in debug
output for verification.
This commit is contained in:
2026-08-14 09:45:50 +07:00
parent 29f7fecb35
commit f7f20e3a0a
3 changed files with 76 additions and 21 deletions
@@ -168,6 +168,8 @@ bool InstrumentEngineManager::assign(uint32_t channel, InstrumentType type,
loaded = static_cast<SfizzInstrument*>(inst.get())->loadSfzFile(path, sampleRate);
else if (type == InstrumentType::VST3)
loaded = static_cast<Vst3Instrument*>(inst.get())->loadPlugin(path, sampleRate);
if (type == InstrumentType::VST3)
static_cast<Vst3Instrument*>(inst.get())->setChannel(channel);
if (!loaded) return false;
// init() AFTER load: FluidSynth creates its synth inside loadSoundFontFile.
if (!inst->init(sampleRate, blockSize)) return false;