instrument: the filter's velocity depth knob returns and multiplies the bipolar curve; the pre-v12 lift is a pure domain re-tag

This commit is contained in:
2026-07-31 20:24:40 -04:00
parent cfb53aade3
commit 5e290119c5
22 changed files with 243 additions and 166 deletions
+10 -1
View File
@@ -63,6 +63,10 @@ static SampleData filteredSine() {
s.play.filter.settings.cutoffNorm = 0.8f;
s.play.filter.settings.resonanceNorm = 0.9f;
s.play.filter.settings.morphNorm = 1.0f;
// A drawn velocity curve, so the velocity-DEPTH knob has something to scale. It costs
// every other case nothing: the depth is 0 until a case moves it, so the product is 0.
s.play.filter.velocityCurve = VelocityCurve::fromPoints(
{{0.0, 0.0}, {127.0, -1.0}}, instrument::engine::CurveDomain::Bipolar);
return s;
}
@@ -601,6 +605,10 @@ static void testEveryLiveFilterControlMovesTheSoundingNote() {
{"morph", [](LiveValues& v) { v.filterSettings.morphNorm = 0.0f; }},
{"drive", [](LiveValues& v) { v.filterSettings.driveNorm = 1.0f; }},
{"mod", [](LiveValues& v) { v.filterModAmount = 1.0; }},
// The velocity DEPTH is live even though the velocity itself is latched: the depth is
// a control over the note's latched curve value, the same shape key-track has over the
// note's latched number (deck_groups.h).
{"velamount", [](LiveValues& v) { v.filterVelAmount = 1.0; }},
{"keytrack", [](LiveValues& v) { v.filterKeyTrack = 2.0; }},
};
@@ -644,7 +652,7 @@ static void testEveryLiveFilterControlMovesTheSoundingNote() {
// The window is a FRACTION OF THE GLIDE, not a frame count: kLiveRampSeconds is the
// full travel time, so at 1/240 of it a working glide has barely started when the
// window closes. kGlideMargin then puts the bound at the geometric middle of the two
// MEASURED populations — with the ramp in place these six controls ratio 0.0005..0.060;
// MEASURED populations — with the ramp in place these seven controls ratio 0.0005..0.060;
// with it defeated (every live move delivered as a snap, run) they ratio 0.52..1.10.
// The bound lands at 0.175: ~3x above the worst glide, ~3x below the tamest snap.
const std::size_t rampFrames =
@@ -745,6 +753,7 @@ static void testPitchRatioAndVelocityGainStayLatched() {
hostile.filterKeyTrack = 2.0;
hostile.filterSettings.cutoffNorm = 0.0f;
hostile.filterModAmount = 1.0;
hostile.filterVelAmount = 1.0;
hostile.pitchEnv.shape.attackFrames = 4800;
hostile.pitchEnv.shape.decayFrames = 4800;
hostile.pitchEnv.peakSemitones = 24.0;