V45.6 fix solo Q3: bo stopAllPlayback+restart 60ms khi solo main-session (track solo giu nguyen tieng, het wobble re-attack); GIU timelinePitchesRef qua stop - kill branch NOTE_OFF tung pitch (Qin im khi solo track khac, truoc day tset=0); C++ allNotesOff sandbox VST2 qua control 7 (child panic local CC64/CC123+128 noteOff) thay 128 note-off flood queue 64-cap (Qin het treo sau STOP); IPC toggleSolo tu applyAllTrackMuteSolo (ref patch + kill); v=202608292138

This commit is contained in:
2026-08-29 21:39:59 +07:00
parent 72ae22f865
commit 945e63918d
12 changed files with 80 additions and 30 deletions
+1 -1
View File
@@ -483,7 +483,7 @@ void InstrumentEngineManager::allNotesOff() {
std::lock_guard<std::mutex> lock(mu_);
for (auto& [ch, inst] : channels_) {
if (channelQuiet(ch)) continue; // mid-rebuild / editor open: do not touch the instance
for (uint32_t n = 0; n < 128; ++n) inst->noteOff(ch, n, 0);
inst->allNotesOff(ch);
}
}
+6
View File
@@ -228,6 +228,12 @@ void SandboxVst2Host::pitchBend(uint32_t channel, uint32_t bend14) {
(uint8_t)(bend14 & 0x7F), (uint8_t)((bend14 >> 7) & 0x7F));
}
void SandboxVst2Host::allNotesOff(uint32_t /*channel*/) {
if (!alive_.load() || !ipc_) return;
std::cerr << "[Vst2Sandbox] ALL_NOTES_OFF ch=" << channel_ << std::endl;
pushControl(7); // plugin_host panics locally - no 64-cap MIDI flood
}
bool SandboxVst2Host::openGUI(void* parentWindowHandle) {
(void)parentWindowHandle; // child owns its window
if (!alive_.load() || !ipc_) return false;
+4
View File
@@ -33,6 +33,10 @@ public:
void controlChange(uint32_t channel, uint32_t cc, uint32_t value) override;
void programChange(uint32_t channel, uint32_t program) override;
void pitchBend(uint32_t channel, uint32_t bend14) override;
// Control 7 (ALL_NOTES_OFF): the child runs the local panic
// (CC64/CC123 + 128 note-offs) - a 128-note MIDI sweep would
// overflow the child's 64-cap queue and Qin would keep ringing.
void allNotesOff(uint32_t channel) override;
// The child owns its GUI window (plugin_host opens it on OPEN_GUI control).
bool openGUI(void* parentWindowHandle) override;
bool canOpenGUI() const override { return true; }
+9
View File
@@ -269,6 +269,15 @@ int main(int argc, char* argv[]) {
if (g_hostHwnd) ShowWindow(g_hostHwnd, SW_HIDE);
} else if (c.type == 6) {
quit = true;
} else if (c.type == 7) { // ALL_NOTES_OFF: runtime panic (STOP/solo)
panicAfterPreset();
// absorb the panic-mutated chunk so the ~2s periodic
// republish never overwrites presetOut with it
inst.captureState();
std::string postPanic = inst.serializeState();
if (!postPanic.empty()) lastOut = postPanic;
printf("[plugin_host] ALL_NOTES_OFF ch=%u\n", channel);
fflush(stdout);
}
}
ipc->base.controlQueueCount = 0;