Bake window: derived note lengths carry exact durations, not ladder rungs — a long take is no longer cut at 384 beats
Hold keeps its picker. Also: one home for the %-fold, duration-ordered Hold travel, and a corrupt tail degrades to absent rather than fabricating one.
This commit is contained in:
@@ -195,13 +195,29 @@ bool splineActive(const Play& p) {
|
||||
(p.filter.enabled && p.filterSpline.mode == EnvMode::Spline);
|
||||
}
|
||||
|
||||
// The one enforcement of splineActive's rule (see its doc above). Header-inline and
|
||||
// allocation-free: play_params.h sits on the per-voice-per-sample include path. Both callers —
|
||||
// resolvePlay (sample_map.cpp) and the editor's applyControl — route through here, so the two
|
||||
// cannot drift apart.
|
||||
// The mode the engine will actually run, and the one home of splineActive's rule (see its doc
|
||||
// above). Header-inline and allocation-free: play_params.h sits on the per-voice-per-sample
|
||||
// include path. Every caller — resolvePlay (sample_map.cpp), the editor's applyControl, and
|
||||
// the editor's read-only predicates — routes through one of these two, so none of them can
|
||||
// drift into a second reading of the fields.
|
||||
template <class Play>
|
||||
PlayMode effectivePlayMode(const Play& p) {
|
||||
return splineActive(p) ? PlayMode::Trigger : p.playMode;
|
||||
}
|
||||
|
||||
template <class Play>
|
||||
void enforceGateUnavailableWhileDrawn(Play& p) {
|
||||
if (splineActive(p)) p.playMode = PlayMode::Trigger;
|
||||
p.playMode = effectivePlayMode(p);
|
||||
}
|
||||
|
||||
// The %-length the voice ACTUALLY plays. Same rule family, same reason it is templated: a drawn
|
||||
// contour is a pure time function over the full sample length, so any active spline EG folds
|
||||
// the fraction to 1.0 while the stored knob goes inert — but the stored value survives, so a
|
||||
// pre-spline setting is still there to be read. Every consumer of the Trigger span must fold it
|
||||
// here or it silently plays/draws/bakes a fraction of the take.
|
||||
template <class Play>
|
||||
double effectiveLengthFraction(const Play& p) {
|
||||
return splineActive(p) ? 1.0 : p.trigger.lengthFraction;
|
||||
}
|
||||
|
||||
// [start, end) frames, half-open. A zero-length loop (start == end) is the "no sustain loop"
|
||||
|
||||
Reference in New Issue
Block a user