fix(voice): Trigger legato keys on held-stack depth, CC123 allNotesOff clears mono stack, voice-param edits rebuild from decoded PCM (no re-decode), mono sizes 1 shifter ring
This commit is contained in:
@@ -200,8 +200,9 @@ public:
|
||||
// --- Phase S voice-system parameters (per-instance, persisted in component state v7) ---
|
||||
// Read/written on the UI thread (the editor's voice deck) and by getState/setState; guarded
|
||||
// by voiceParamsMutex_. NOT read on the audio thread — each setter rebuilds the VoiceEngine
|
||||
// OFF-thread through reloadFromBank's drain-slot swap, so changing polyphony / mode / the
|
||||
// retrigger toggle never cuts a ringing tail (the same path FA1 added for curve edits).
|
||||
// OFF-thread via rebuildVoiceEngine (a LIGHT rebuild around the already-decoded keymap; no
|
||||
// bridge read, no WAV re-decode) published through the same tail-preserving drain-slot swap,
|
||||
// so changing polyphony / mode / the retrigger toggle never cuts a ringing tail.
|
||||
int voiceCount();
|
||||
void setVoiceCount(int count); // clamped to kMinVoiceCount..kMaxVoiceCount
|
||||
VoiceMode voiceMode();
|
||||
@@ -240,6 +241,24 @@ private:
|
||||
// proof (see below) covers the free.
|
||||
void retireIdleDrain();
|
||||
|
||||
// Phase S voice-param LIGHT rebuild (voice-review Major #3): rebuild the engine + preview
|
||||
// card around a COPY of the LIVE instrument's already-decoded Keymap — no bridge read, no
|
||||
// filesystem, no WAV re-decode — and publish through the same tail-preserving drain-slot
|
||||
// swap as a full reload. A polyphony/mode/trigger change touches no audio data, so the
|
||||
// full reloadFromBank (which re-decodes every zone WAV from disk on the UI thread) was
|
||||
// pure waste — a visible UI stall on a many-zone instrument. Copying the keymap is safe:
|
||||
// it is immutable after construction and, under reloadMutex_, the live instrument can
|
||||
// neither be swapped nor freed while we read it. When nothing is loaded this is a no-op —
|
||||
// the new params bake into the next real reload. Off the audio thread only.
|
||||
void rebuildVoiceEngine();
|
||||
|
||||
// Publish `built` (null = install silence) into live_: prune the graveyard by the last
|
||||
// process()-published generation, swap `built` into live_, displace the previous live into
|
||||
// the drain slot, and park the drain-evicted instrument in the graveyard. REQUIRES
|
||||
// reloadMutex_ held — factored out so reloadFromBank and rebuildVoiceEngine share the ONE
|
||||
// safety-critical swap dance (see the handoff proof below).
|
||||
void publishBuiltLocked(std::unique_ptr<LoadedInstrument> built);
|
||||
|
||||
ReaperBridge bridge_;
|
||||
|
||||
// --- The audio-thread handoff (S4 real-time discipline, FA1 drain slot) --
|
||||
|
||||
Reference in New Issue
Block a user