S4 Tier 0: the bank plays — VST3 marshals MIDI to the S3 core, reads the live bank + resolves WAV the M4 way, mono downmix, lock-free load handoff, LICE sample-pick

This commit is contained in:
2026-07-26 16:43:04 -04:00
parent b0fc052113
commit 0cde457224
24 changed files with 1239 additions and 302 deletions
+14 -3
View File
@@ -236,9 +236,20 @@ public:
// the older tail to ring — matches hardware behavior). No-op if none match.
void noteOff(int note);
// Renders `frameCount` mono output frames, summing all active voices, appending to
// `out` (does not clear it — the caller owns mixing/clearing). Voices that finish
// mid-block go idle and stop contributing.
// REAL-TIME render (S4): sums all active voices into the caller-provided buffer
// `out[0..frameCount)`, ADDING to whatever is there (the caller clears or mixes —
// this never touches memory it does not own and NEVER allocates). This is the
// audio-thread entry point: the VST3 process callback passes the host's own output
// channel buffer, so no allocation, resize, or heap traffic happens under process.
// Voices that finish mid-block go idle and stop contributing. `out` must point at
// at least `frameCount` writable samples; a null `out` or zero count is a no-op.
void render(AudioSample* out, std::size_t frameCount);
// TEST / off-thread convenience: appends `frameCount` summed frames to `out`
// (grows it — DO NOT call on the audio thread; it allocates). Delegates to the
// real-time overload after sizing the buffer, so both paths share one mix loop.
// Does not clear existing contents — appends, matching the pre-S4 contract the
// unit tests rely on.
void render(std::vector<AudioSample>& out, std::size_t frameCount);
// Count of currently active voices (for tests / diagnostics).