instrument: one VELOCITY deck for all three velocity curves, bipolar and off by default for pitch and filter
Payload v12 appends the new velocity->pitch curve and folds the retired filter velAmount into its now-bipolar curve, so pre-v12 projects reopen sounding identical. Preview button takes a drawn play triangle.
This commit is contained in:
@@ -49,12 +49,14 @@ void Voice::start(int note, int velocity, const SampleData& sample, bool declick
|
||||
// Velocity->amp mapped once at note-on; the per-frame render just multiplies the cached
|
||||
// velocityGain_.
|
||||
velocityGain_ = sample.velocityCurve.eval(static_cast<double>(velocity));
|
||||
// Feeds both engines through baseRatio_ (Varispeed read-rate bias and Preserve shift
|
||||
// amount both derive from it below).
|
||||
baseRatio_ = keyTrackedRatio(note, sample.rootNote, sample.keyTrack);
|
||||
sample_ = &sample;
|
||||
|
||||
const PlayParams& p = sample.play;
|
||||
// Velocity->pitch is fixed for the note's lifetime, so it folds into baseRatio_ here rather
|
||||
// than costing a per-frame multiply. Feeds both engines through baseRatio_ (Varispeed
|
||||
// read-rate bias and Preserve shift amount both derive from it below).
|
||||
velPitchRatio_ = velocityPitchRatio(p.pitchVelocityCurve, velocity);
|
||||
baseRatio_ = keyTrackedRatio(note, sample.rootNote, sample.keyTrack) * velPitchRatio_;
|
||||
playMode_ = p.playMode;
|
||||
pitchEngine_ = p.pitchEngine;
|
||||
|
||||
@@ -129,8 +131,7 @@ void Voice::start(int note, int velocity, const SampleData& sample, bool declick
|
||||
filterCutoffNorm_ = static_cast<double>(p.filter.settings.cutoffNorm);
|
||||
filterModAmount_ = p.filter.modAmount;
|
||||
filterKeyTrack_ = p.filter.keyTrack;
|
||||
filterVelOffset_ =
|
||||
p.filter.velAmount * p.filter.velocityCurve.eval(static_cast<double>(velocity));
|
||||
filterVelOffset_ = p.filter.velocityCurve.eval(static_cast<double>(velocity));
|
||||
filterRate_ = static_cast<double>(sample.sampleRate);
|
||||
rModAmount_.set(p.filter.modAmount);
|
||||
rResonance_.set(static_cast<double>(p.filter.settings.resonanceNorm));
|
||||
@@ -281,7 +282,9 @@ void Voice::retune(int note) {
|
||||
// Changes baseRatio_ without re-converting pitchEnv_'s already-configured span (the
|
||||
// baseRatio_ division in the note-on setup above), so a slide leaves that envelope on the
|
||||
// first note's domain — consistent with "touch nothing else," but the drift lives here.
|
||||
baseRatio_ = keyTrackedRatio(note, sample_->rootNote, sample_->keyTrack);
|
||||
// The velocity->pitch factor rides through the slide unchanged, matching velocityGain_ —
|
||||
// one gesture, one strike.
|
||||
baseRatio_ = keyTrackedRatio(note, sample_->rootNote, sample_->keyTrack) * velPitchRatio_;
|
||||
// Filter key-tracking follows the pitch: it is a function of the note, so a slide moves it
|
||||
// too. The velocity offset deliberately stays the first note's, matching velocityGain_.
|
||||
if (filterOn_) updateFilterCutoffBase(note);
|
||||
|
||||
Reference in New Issue
Block a user