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;
|
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 sfz::Region::getBaseGain() const noexcept
|
||||||
{
|
{
|
||||||
float baseGain = amplitude;
|
float baseGain = amplitude;
|
||||||
|
|
|
||||||
|
|
@ -99,15 +99,6 @@ struct Region {
|
||||||
*/
|
*/
|
||||||
bool shouldLoop() const noexcept { return (loopMode == LoopMode::loop_continuous || loopMode == LoopMode::loop_sustain); }
|
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.
|
* @brief Get the base gain of the region.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -125,10 +125,40 @@ float velocityCurve(const Region& region, float velocity, const MidiState& midiS
|
||||||
else
|
else
|
||||||
gain = velocity * velocity;
|
gain = velocity * velocity;
|
||||||
|
|
||||||
gain = std::fabs(region.ampVeltrack) * (1.0f - gain);
|
float veltrack = region.ampVeltrack;
|
||||||
gain = (region.ampVeltrack < 0) ? gain : (1.0f - gain);
|
|
||||||
|
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;
|
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;
|
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();
|
Tuning& tuning = resources.getTuning();
|
||||||
const float numberRetuned = tuning.getKeyFractional12TET(impl.triggerEvent_.number);
|
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
|
// apply stretch tuning if set
|
||||||
if (absl::optional<StretchTuning>& stretch = resources.getStretch())
|
if (absl::optional<StretchTuning>& stretch = resources.getStretch())
|
||||||
|
|
|
||||||
|
|
@ -360,14 +360,16 @@ TEST_CASE("[Region] Offsets with CCs")
|
||||||
TEST_CASE("[Region] Pitch variation with veltrack")
|
TEST_CASE("[Region] Pitch variation with veltrack")
|
||||||
{
|
{
|
||||||
Region region { 0 };
|
Region region { 0 };
|
||||||
|
MidiState midiState;
|
||||||
|
CurveSet curveSet { CurveSet::createPredefined() };
|
||||||
|
|
||||||
REQUIRE(region.getBasePitchVariation(60.0, 0_norm) == 1.0);
|
REQUIRE(basePitchVariation(region, 60.0, 0_norm, midiState, curveSet) == 1.0);
|
||||||
REQUIRE(region.getBasePitchVariation(60.0, 64_norm) == 1.0);
|
REQUIRE(basePitchVariation(region, 60.0, 64_norm, midiState, curveSet) == 1.0);
|
||||||
REQUIRE(region.getBasePitchVariation(60.0, 127_norm) == 1.0);
|
REQUIRE(basePitchVariation(region, 60.0, 127_norm, midiState, curveSet) == 1.0);
|
||||||
region.parseOpcode({ "pitch_veltrack", "1200" });
|
region.parseOpcode({ "pitch_veltrack", "1200" });
|
||||||
REQUIRE(region.getBasePitchVariation(60.0, 0_norm) == 1.0);
|
REQUIRE(basePitchVariation(region, 60.0, 0_norm, midiState, curveSet) == 1.0);
|
||||||
REQUIRE(region.getBasePitchVariation(60.0, 64_norm) == Approx(centsFactor(600.0)).margin(0.01f));
|
REQUIRE(basePitchVariation(region, 60.0, 64_norm, midiState, curveSet) == 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, 127_norm, midiState, curveSet) == Approx(centsFactor(1200.0)).margin(0.01f));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("[Synth] velcurve")
|
TEST_CASE("[Synth] velcurve")
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue