mirror of
https://codeberg.org/armin/chromaflock.git
synced 2026-09-01 04:10:47 +02:00
Add per-note velocity routing to filter cutoff and resonance
This commit is contained in:
parent
9e84707f93
commit
9ef77e04ab
6 changed files with 63 additions and 20 deletions
|
|
@ -128,13 +128,19 @@ public:
|
|||
left *= noteVelocity * envSample;
|
||||
right *= noteVelocity * envSample;
|
||||
|
||||
// Filter cutoff with env + keytrack.
|
||||
// Filter cutoff with env + keytrack + velocity.
|
||||
// Unipolar modulation UP from the base cutoff: the envelope (0..1)
|
||||
// multiplied by env amount adds brightness on top of the cutoff
|
||||
// knob, never going below it. Every env knob (attack/decay/
|
||||
// sustain/release) shapes the response, and at env amount 0 the
|
||||
// cutoff equals the knob.
|
||||
float modCutoff = filterCutoff * std::pow(2.0f, fEnvSample * filterEnvAmount * 4.0f);
|
||||
// knob, never going below it. The env amount is also scaled by
|
||||
// note velocity, so harder hits open the filter more. Every env
|
||||
// knob (attack/decay/sustain/release) shapes the response, and at
|
||||
// env amount 0 the cutoff equals the knob. The independent VEL CUT
|
||||
// depth adds an envelope-free velocity path and VEL RES maps note
|
||||
// velocity to resonance; together they let cutoff and resonance be
|
||||
// drawn per note from the DAW sequencer (velocity is the only
|
||||
// per-note MIDI data a DAW sends).
|
||||
float modCutoff = filterCutoff * std::pow(2.0f, fEnvSample * filterEnvAmount * noteVelocity * 4.0f);
|
||||
modCutoff *= std::pow(2.0f, velToCutoff * noteVelocity * 4.0f);
|
||||
float keyTrackFactor = std::pow(2.0f, (static_cast<float>(currentMidiNote) - 60.0f) / 12.0f * keyTrack);
|
||||
modCutoff *= keyTrackFactor;
|
||||
|
||||
|
|
@ -146,8 +152,10 @@ public:
|
|||
|
||||
modCutoff = std::clamp(modCutoff, 20.0f, static_cast<float>(getSampleRate() * 0.49));
|
||||
|
||||
filter.setCoefficients(modCutoff, filterResonance, filterType);
|
||||
filterR.setCoefficients(modCutoff, filterResonance, filterType);
|
||||
float noteRes = std::clamp(filterResonance * (1.0f + velToResonance * noteVelocity), 0.0f, 1.0f);
|
||||
|
||||
filter.setCoefficients(modCutoff, noteRes, filterType);
|
||||
filterR.setCoefficients(modCutoff, noteRes, filterType);
|
||||
|
||||
left = filter.process(left);
|
||||
right = filterR.process(right);
|
||||
|
|
@ -180,7 +188,8 @@ public:
|
|||
float fAtt, float fDec, float fSus, float fRel,
|
||||
float p, float drv, float outLvl,
|
||||
float l1Rate, float l1Depth, int l1Shape, int l1Dest,
|
||||
float l2Rate, float l2Depth, int l2Shape, int l2Dest) {
|
||||
float l2Rate, float l2Depth, int l2Shape, int l2Dest,
|
||||
float velCut, float velRes) {
|
||||
waveform1 = wf1;
|
||||
waveform2 = wf2;
|
||||
octave1 = oct1;
|
||||
|
|
@ -197,6 +206,8 @@ public:
|
|||
filterType = ft;
|
||||
filterEnvAmount = fEnvAmt;
|
||||
keyTrack = kTrack;
|
||||
velToCutoff = velCut;
|
||||
velToResonance = velRes;
|
||||
pan = p;
|
||||
drive = std::max(drv, 1.001f);
|
||||
outputLevel = outLvl * outLvl;
|
||||
|
|
@ -251,6 +262,8 @@ private:
|
|||
FilterType filterType = FilterType::LowPass12;
|
||||
float filterEnvAmount = 0.0f;
|
||||
float keyTrack = 0.5f;
|
||||
float velToCutoff = 0.0f;
|
||||
float velToResonance = 0.0f;
|
||||
float pan = 0.0f;
|
||||
float drive = 1.5f;
|
||||
float outputLevel = 0.8f;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue