G2.1: save full instrument state to disk (path/type/preset/transport)
This commit is contained in:
@@ -43,6 +43,7 @@ bool FluidSynthInstrument::loadSoundFontFile(const std::string& path, double sam
|
||||
// Reset all channels to font preset 0 (spec §VII: bank0/prog0 piano)
|
||||
for (uint32_t ch = 0; ch < 16; ++ch) {
|
||||
bank_[ch] = 0;
|
||||
program_[ch] = 0;
|
||||
fluid_synth_program_select(FS_SYNTH, ch, sfontId, 0, 0);
|
||||
}
|
||||
return true;
|
||||
@@ -55,6 +56,7 @@ bool FluidSynthInstrument::init(double sampleRate, uint32_t maxBlockSize) {
|
||||
void FluidSynthInstrument::selectProgram(uint32_t channel, uint32_t bank, uint32_t program) {
|
||||
if (!synth || channel >= 16) return;
|
||||
bank_[channel] = bank;
|
||||
program_[channel] = program;
|
||||
fluid_synth_program_select(FS_SYNTH, channel, sfontId, bank, program);
|
||||
}
|
||||
|
||||
@@ -81,6 +83,7 @@ void FluidSynthInstrument::programChange(uint32_t channel, uint32_t 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).
|
||||
program_[channel] = program;
|
||||
fluid_synth_program_select(FS_SYNTH, channel, sfontId, bank_[channel], program);
|
||||
}
|
||||
|
||||
@@ -96,6 +99,15 @@ bool FluidSynthInstrument::openGUI(void* parentWindowHandle) {
|
||||
|
||||
void FluidSynthInstrument::closeGUI() {}
|
||||
|
||||
// G2.1: expose last bank/program for the state snapshot.
|
||||
uint32_t FluidSynthInstrument::bankOf(uint32_t channel) const {
|
||||
return channel < 16 ? bank_[channel] : 0;
|
||||
}
|
||||
|
||||
uint32_t FluidSynthInstrument::programOf(uint32_t channel) const {
|
||||
return channel < 16 ? program_[channel] : 0;
|
||||
}
|
||||
|
||||
void FluidSynthInstrument::processAudioBlock(float* outputL, float* outputR, uint32_t numSamples) {
|
||||
if (!synth) return;
|
||||
fluid_synth_write_float(FS_SYNTH, numSamples, outputL, 0, 1, outputR, 0, 1);
|
||||
@@ -191,6 +203,7 @@ bool InstrumentEngineManager::assign(uint32_t channel, InstrumentType type,
|
||||
if (it != channels_.end()) oldInst = std::move(it->second);
|
||||
channels_[channel] = std::move(inst);
|
||||
paths_[channel] = path;
|
||||
types_[channel] = type;
|
||||
// Fresh instance is by construction not reloading — clear the channel
|
||||
// flag so real-time MIDI dispatch (which drops reloading channels)
|
||||
// flows to it again.
|
||||
@@ -221,6 +234,7 @@ void InstrumentEngineManager::unload(uint32_t channel) {
|
||||
if (it != channels_.end()) oldInst = std::move(it->second);
|
||||
channels_.erase(channel);
|
||||
paths_.erase(channel);
|
||||
types_.erase(channel);
|
||||
reloadingCh_[channel] = false;
|
||||
}
|
||||
if (oldInst) {
|
||||
@@ -242,6 +256,32 @@ std::string InstrumentEngineManager::pathOf(uint32_t channel) {
|
||||
return it == paths_.end() ? std::string() : it->second;
|
||||
}
|
||||
|
||||
bool InstrumentEngineManager::snapshot(BridgeStateSnapshot& out) {
|
||||
std::lock_guard<std::mutex> lock(mu_);
|
||||
out.instruments.clear();
|
||||
for (auto& kv : channels_) {
|
||||
uint32_t ch = kv.first;
|
||||
if (ch < 16 && reloadingCh_[ch]) continue; // old instance dying
|
||||
InstrumentStateEntry e;
|
||||
e.channel = ch;
|
||||
auto tp = types_.find(ch);
|
||||
e.type = tp == types_.end() ? 0 : (int)tp->second;
|
||||
auto pp = paths_.find(ch);
|
||||
e.path = pp == paths_.end() ? std::string() : pp->second;
|
||||
if (INativeInstrument* i = kv.second.get()) {
|
||||
// VST3: refresh the saved buffers then serialize them. Safe
|
||||
// here: mu_ is held, so the audio loop cannot be inside
|
||||
// process() on this instance while getState runs.
|
||||
i->captureState();
|
||||
e.presetBase64 = i->serializeState();
|
||||
e.bank = i->bankOf(ch);
|
||||
e.program = i->programOf(ch);
|
||||
}
|
||||
out.instruments.push_back(std::move(e));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
INativeInstrument* InstrumentEngineManager::get(uint32_t channel) {
|
||||
std::lock_guard<std::mutex> lock(mu_);
|
||||
auto it = channels_.find(channel);
|
||||
|
||||
Reference in New Issue
Block a user