fix: SF2 bank select, midi multi-key cut, VSTi reopen hang, multi-track stuck
- NativeInstrumentEngine: track GM bank per channel (CC0/CC32), use bank in programChange - app.jsx: send CC0/CC32+PROGRAM before notes via __ensureBridgeProgram, dedupe, clear dedupe after async LOAD - audioRoutingEngine/bridgeAudioNode: idempotent connect (no disconnect-flush on re-connect), fixes note cut & multi-track stuck - main.cpp: remove 10s poll in OPEN_GUI control job (blocked realtime loop, watchdog race), VstWindowProc stores channel not inst pointer, cleanup gui maps on WM_DESTROY
This commit is contained in:
@@ -16,7 +16,9 @@
|
||||
// 1. SOUNDFONT ENGINE (.SF2 / .SF3) VIA FLUIDSYNTH C API
|
||||
// -----------------------------------------------------------------
|
||||
FluidSynthInstrument::FluidSynthInstrument()
|
||||
: settings(nullptr), synth(nullptr), sfontId(-1) {}
|
||||
: settings(nullptr), synth(nullptr), sfontId(-1) {
|
||||
for (uint32_t i = 0; i < 16; ++i) bank_[i] = 0;
|
||||
}
|
||||
|
||||
FluidSynthInstrument::~FluidSynthInstrument() {
|
||||
if (synth) delete_fluid_synth(FS_SYNTH);
|
||||
@@ -36,6 +38,7 @@ bool FluidSynthInstrument::loadSoundFontFile(const std::string& path, double sam
|
||||
if (sfontId == -1) return false;
|
||||
// Reset all channels to font preset 0 (spec §VII: bank0/prog0 piano)
|
||||
for (uint32_t ch = 0; ch < 16; ++ch) {
|
||||
bank_[ch] = 0;
|
||||
fluid_synth_program_select(FS_SYNTH, ch, sfontId, 0, 0);
|
||||
}
|
||||
return true;
|
||||
@@ -46,7 +49,8 @@ bool FluidSynthInstrument::init(double sampleRate, uint32_t maxBlockSize) {
|
||||
}
|
||||
|
||||
void FluidSynthInstrument::selectProgram(uint32_t channel, uint32_t bank, uint32_t program) {
|
||||
if (!synth) return;
|
||||
if (!synth || channel >= 16) return;
|
||||
bank_[channel] = bank;
|
||||
fluid_synth_program_select(FS_SYNTH, channel, sfontId, bank, program);
|
||||
}
|
||||
|
||||
@@ -62,13 +66,18 @@ void FluidSynthInstrument::noteOff(uint32_t channel, uint32_t pitch, uint32_t sa
|
||||
}
|
||||
|
||||
void FluidSynthInstrument::controlChange(uint32_t channel, uint32_t cc, uint32_t value) {
|
||||
if (!synth) return;
|
||||
if (!synth || channel >= 16) return;
|
||||
// Bank select MSB/LSB (A12): CC0 = (bank>>7)&0x7F, CC32 = bank&0x7F
|
||||
if (cc == 0) bank_[channel] = (bank_[channel] & 0x7Fu) | ((value & 0x7Fu) << 7);
|
||||
else if (cc == 32) bank_[channel] = (bank_[channel] & ~0x7Fu) | (value & 0x7Fu);
|
||||
fluid_synth_cc(FS_SYNTH, channel, cc, value);
|
||||
}
|
||||
|
||||
void FluidSynthInstrument::programChange(uint32_t channel, uint32_t program) {
|
||||
if (!synth) return;
|
||||
fluid_synth_program_select(FS_SYNTH, channel, sfontId, 0, program);
|
||||
if (!synth || channel >= 16) return;
|
||||
// Dung bank da nhan tu CC0/CC32 — bank hardcode 0 lam preset o bank != 0
|
||||
// khong duoc chon (fluid giu preset cu -> ra piano sai).
|
||||
fluid_synth_program_select(FS_SYNTH, channel, sfontId, bank_[channel], program);
|
||||
}
|
||||
|
||||
void FluidSynthInstrument::pitchBend(uint32_t channel, uint32_t bend14) {
|
||||
|
||||
Reference in New Issue
Block a user