Play cross-rate captures at their own pitch and length

The voice now converts the file's rate to the host's at note-on instead of assuming they match. Stage times resolve at the host rate, the filter solves at it, and the bake follows. Same-rate renders are unchanged bit for bit.
This commit is contained in:
2026-09-25 13:44:39 -04:00
parent 9ff34b0a9e
commit ec60cf78c6
25 changed files with 749 additions and 137 deletions
+1 -1
View File
@@ -79,7 +79,7 @@ static void testDetectedPeriodReachesAndMovesThePreserveRender() {
ref.relativePath = "b/a.wav";
ref.rootNote = 60;
SampleData on = buildSampleData(resolveCapture(ref, InstrumentParams{}),
DecodedPcm{pcm, rate, {}});
DecodedPcm{pcm, rate, {}}, rate);
CHECK(std::fabs(on.sourcePeriodFrames - 1470.0) < 2.0); // 44100 / 30 Hz, real detection
on.play.adsr = flatAdsr();