Add amp and pitch veltrack oncc
This commit is contained in:
parent
f84cacebf6
commit
3658de4497
6 changed files with 54 additions and 31 deletions
|
|
@ -1724,19 +1724,6 @@ bool sfz::Region::processGenericCc(const Opcode& opcode, OpcodeSpec<float> spec,
|
|||
return true;
|
||||
}
|
||||
|
||||
float sfz::Region::getBasePitchVariation(float noteNumber, float velocity) const noexcept
|
||||
{
|
||||
ASSERT(velocity >= 0.0f && velocity <= 1.0f);
|
||||
|
||||
fast_real_distribution<float> pitchDistribution { 0.0f, pitchRandom };
|
||||
float pitchVariationInCents = pitchKeytrack * (noteNumber - float(pitchKeycenter)); // note difference with pitch center
|
||||
pitchVariationInCents += pitch; // sample tuning
|
||||
pitchVariationInCents += config::centPerSemitone * transpose; // sample transpose
|
||||
pitchVariationInCents += velocity * pitchVeltrack; // track velocity
|
||||
pitchVariationInCents += pitchDistribution(Random::randomGenerator); // random pitch changes
|
||||
return centsFactor(pitchVariationInCents);
|
||||
}
|
||||
|
||||
float sfz::Region::getBaseGain() const noexcept
|
||||
{
|
||||
float baseGain = amplitude;
|
||||
|
|
|
|||
|
|
@ -99,15 +99,6 @@ struct Region {
|
|||
*/
|
||||
bool shouldLoop() const noexcept { return (loopMode == LoopMode::loop_continuous || loopMode == LoopMode::loop_sustain); }
|
||||
|
||||
/**
|
||||
* @brief Get the base pitch of the region depending on which note has been
|
||||
* pressed and at which velocity.
|
||||
*
|
||||
* @param noteNumber
|
||||
* @param velocity
|
||||
* @return float
|
||||
*/
|
||||
float getBasePitchVariation(float noteNumber, float velocity) const noexcept;
|
||||
/**
|
||||
* @brief Get the base gain of the region.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -125,10 +125,40 @@ float velocityCurve(const Region& region, float velocity, const MidiState& midiS
|
|||
else
|
||||
gain = velocity * velocity;
|
||||
|
||||
gain = std::fabs(region.ampVeltrack) * (1.0f - gain);
|
||||
gain = (region.ampVeltrack < 0) ? gain : (1.0f - gain);
|
||||
float veltrack = region.ampVeltrack;
|
||||
|
||||
for (const auto& mod : region.ampVeltrackCC) {
|
||||
const auto& curve = curveSet.getCurve(mod.data.curve);
|
||||
const float value = midiState.getCCValue(mod.cc);
|
||||
veltrack += curve.evalNormalized(value) * mod.data.modifier;
|
||||
}
|
||||
|
||||
gain = std::fabs(veltrack) * (1.0f - gain);
|
||||
gain = (veltrack < 0) ? gain : (1.0f - gain);
|
||||
|
||||
return gain;
|
||||
}
|
||||
|
||||
float basePitchVariation(const Region& region, float noteNumber, float velocity, const MidiState& midiState, const CurveSet& curveSet) noexcept
|
||||
{
|
||||
ASSERT(velocity >= 0.0f && velocity <= 1.0f);
|
||||
|
||||
fast_real_distribution<float> pitchDistribution { 0.0f, region.pitchRandom };
|
||||
float pitchVariationInCents = region.pitchKeytrack * (noteNumber - float(region.pitchKeycenter)); // note difference with pitch center
|
||||
pitchVariationInCents += region.pitch; // sample tuning
|
||||
pitchVariationInCents += config::centPerSemitone * region.transpose; // sample transpose
|
||||
|
||||
float veltrack = region.pitchVeltrack;
|
||||
|
||||
for (const auto& mod : region.pitchVeltrackCC) {
|
||||
const auto& curve = curveSet.getCurve(mod.data.curve);
|
||||
const float value = midiState.getCCValue(mod.cc);
|
||||
veltrack += curve.evalNormalized(value) * mod.data.modifier;
|
||||
}
|
||||
|
||||
pitchVariationInCents += velocity * veltrack; // track velocity
|
||||
pitchVariationInCents += pitchDistribution(Random::randomGenerator); // random pitch changes
|
||||
return centsFactor(pitchVariationInCents);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,4 +94,17 @@ uint32_t loopStart(const Region& region, MidiState& midiState) noexcept;
|
|||
*/
|
||||
uint32_t loopEnd(const Region& region, MidiState& midiState) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Get the base pitch of the region depending on which note has been
|
||||
* pressed and at which velocity.
|
||||
*
|
||||
* @param region
|
||||
* @param noteNumber
|
||||
* @param velocity
|
||||
* @param midiState
|
||||
* @param curveSet
|
||||
* @return float
|
||||
*/
|
||||
float basePitchVariation(const Region& region, float noteNumber, float velocity, const MidiState& midiState, const CurveSet& curveSet) noexcept;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -483,7 +483,7 @@ bool Voice::startVoice(Layer* layer, int delay, const TriggerEvent& event) noexc
|
|||
Tuning& tuning = resources.getTuning();
|
||||
const float numberRetuned = tuning.getKeyFractional12TET(impl.triggerEvent_.number);
|
||||
|
||||
impl.pitchRatio_ = region.getBasePitchVariation(numberRetuned, impl.triggerEvent_.value);
|
||||
impl.pitchRatio_ = basePitchVariation(region, numberRetuned, impl.triggerEvent_.value, midiState, curveSet);
|
||||
|
||||
// apply stretch tuning if set
|
||||
if (absl::optional<StretchTuning>& stretch = resources.getStretch())
|
||||
|
|
|
|||
|
|
@ -360,14 +360,16 @@ TEST_CASE("[Region] Offsets with CCs")
|
|||
TEST_CASE("[Region] Pitch variation with veltrack")
|
||||
{
|
||||
Region region { 0 };
|
||||
MidiState midiState;
|
||||
CurveSet curveSet { CurveSet::createPredefined() };
|
||||
|
||||
REQUIRE(region.getBasePitchVariation(60.0, 0_norm) == 1.0);
|
||||
REQUIRE(region.getBasePitchVariation(60.0, 64_norm) == 1.0);
|
||||
REQUIRE(region.getBasePitchVariation(60.0, 127_norm) == 1.0);
|
||||
REQUIRE(basePitchVariation(region, 60.0, 0_norm, midiState, curveSet) == 1.0);
|
||||
REQUIRE(basePitchVariation(region, 60.0, 64_norm, midiState, curveSet) == 1.0);
|
||||
REQUIRE(basePitchVariation(region, 60.0, 127_norm, midiState, curveSet) == 1.0);
|
||||
region.parseOpcode({ "pitch_veltrack", "1200" });
|
||||
REQUIRE(region.getBasePitchVariation(60.0, 0_norm) == 1.0);
|
||||
REQUIRE(region.getBasePitchVariation(60.0, 64_norm) == Approx(centsFactor(600.0)).margin(0.01f));
|
||||
REQUIRE(region.getBasePitchVariation(60.0, 127_norm) == Approx(centsFactor(1200.0)).margin(0.01f));
|
||||
REQUIRE(basePitchVariation(region, 60.0, 0_norm, midiState, curveSet) == 1.0);
|
||||
REQUIRE(basePitchVariation(region, 60.0, 64_norm, midiState, curveSet) == Approx(centsFactor(600.0)).margin(0.01f));
|
||||
REQUIRE(basePitchVariation(region, 60.0, 127_norm, midiState, curveSet) == Approx(centsFactor(1200.0)).margin(0.01f));
|
||||
}
|
||||
|
||||
TEST_CASE("[Synth] velcurve")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue