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:
@@ -23,6 +23,9 @@ BakeAudio renderBake(SampleData sample, const BakePlan& plan, double masterGainL
|
||||
bool limiterEnabled) {
|
||||
BakeAudio out;
|
||||
if (!sample.playable() || plan.totalFrames <= 0 || plan.sampleRate <= 0) return out;
|
||||
// The snapshot's frame counts were resolved at ITS output rate; rendered at another, every
|
||||
// stage time and the filter corner would print off by the ratio.
|
||||
if (sample.outputRate() > 0 && sample.outputRate() != plan.sampleRate) return out;
|
||||
// Each field bounded BEFORE the sum: renderFrames() adds them, and a hand-built plan
|
||||
// (planBake already bounds both — bake_plan.cpp) could otherwise carry leadInFrames
|
||||
// near INT64_MAX and signed-overflow inside the guard meant to catch exactly that.
|
||||
@@ -51,11 +54,9 @@ BakeAudio renderBake(SampleData sample, const BakePlan& plan, double masterGainL
|
||||
|
||||
// Pre-size the Preserve shifters here, off any audio thread, exactly as the processor
|
||||
// does for its live engine — a cold shifter would smear the onset.
|
||||
std::int64_t preserveWindow = static_cast<std::int64_t>(
|
||||
kPreserveWindowMs * static_cast<double>(plan.sampleRate) / 1000.0 + 0.5);
|
||||
if (preserveWindow < 2) preserveWindow = 2;
|
||||
VoiceEngine engine(/*maxVoices=*/1, sample, /*preserveVoiceCap=*/0, preserveWindow,
|
||||
VoiceMode::Poly, MonoTrigger::Retrigger, /*takeoverDeclick=*/false);
|
||||
VoiceEngine engine(/*maxVoices=*/1, sample, /*preserveVoiceCap=*/0,
|
||||
preserveWindowFrames(sample), VoiceMode::Poly, MonoTrigger::Retrigger,
|
||||
/*takeoverDeclick=*/false);
|
||||
|
||||
for (std::int64_t pos = 0; pos < plan.renderFrames();) {
|
||||
if (pos == plan.noteOnFrame) engine.noteOn(plan.note, plan.velocity);
|
||||
|
||||
Reference in New Issue
Block a user