Bake window derives itself: %-knob fold, declick pad, Gate held to exhaustion, preview velocity; Hold is the one knob a loop needs

This commit is contained in:
2026-08-01 20:26:04 -04:00
parent d3894dae6d
commit 19aeb92775
36 changed files with 1040 additions and 274 deletions
+17 -6
View File
@@ -30,6 +30,7 @@ using instrument::bake::resetAfterBake;
using instrument::map::SampleRefEntry;
using instrument::map::SelectedSample;
using instrument::note::Tempo;
using instrument::note::Velocity;
using instrument::note::resolveNote;
using wire::BakeOutcome;
using wire::BakeRequest;
@@ -127,13 +128,23 @@ BakeChainResult runBake(ReaSamplerProcessor& processor) {
std::optional<SampleData> snapshot = processor.bakeSnapshot();
if (!snapshot) return fail("the loaded capture could not be decoded for the render");
const auto plan = planBake(
resolveNote(defaultBakeProgram(*snapshot, sampleRate, *tempo), *tempo), sampleRate,
rootNote);
if (!plan) return fail("the programmed capture window is empty");
// The note fires at the velocity the user has been auditioning at: three velocity curves
// are live, so a sound dialed at 127 does not bake as one dialed at 40.
const Velocity velocity = Velocity::of(processor.previewVelocity());
const instrument::bake::PlannedBake planned = planBake(
resolveNote(defaultBakeProgram(*snapshot, sampleRate, *tempo, dialed.bakeHold,
velocity),
*tempo),
sampleRate, rootNote);
if (!planned.plan) {
return fail(planned.refusal == instrument::bake::BakeRefusal::PastFrameCeiling
? "the dialed sound is longer than one bake can hold"
: "the programmed capture window is empty");
}
const instrument::bake::BakePlan& plan = *planned.plan;
const instrument::bake::BakeAudio audio =
renderBake(std::move(*snapshot), *plan, processor.masterGainLinear());
renderBake(std::move(*snapshot), plan, processor.masterGainLinear());
if (audio.empty()) return fail("the offline pass produced no audio");
// buildFloat32Wav takes doubles and narrows; the narrowing back to float is the bank's
@@ -164,7 +175,7 @@ BakeChainResult runBake(ReaSamplerProcessor& processor) {
request.sourceRelativePath = source->relativePath;
request.sourceDisplayName = sourceEntry->displayName;
request.ownUsageKey = usageKeyFor(instanceGuid);
request.rootNote = plan->note;
request.rootNote = plan.note;
request.generation = stamp;
const std::string key = bakeKeyFor(instanceGuid);