Pitch envelope in cents, bend_smooth linear in pitch
This commit is contained in:
parent
5ec58b4bba
commit
8809a9db97
1 changed files with 25 additions and 25 deletions
|
|
@ -268,7 +268,6 @@ struct Voice::Impl
|
||||||
ADSREnvelope egAmplitude_;
|
ADSREnvelope egAmplitude_;
|
||||||
std::unique_ptr<ADSREnvelope> egPitch_;
|
std::unique_ptr<ADSREnvelope> egPitch_;
|
||||||
std::unique_ptr<ADSREnvelope> egFilter_;
|
std::unique_ptr<ADSREnvelope> egFilter_;
|
||||||
float bendStepFactor_ { centsFactor(1) };
|
|
||||||
|
|
||||||
WavetableOscillator waveOscillators_[config::oscillatorsPerVoice];
|
WavetableOscillator waveOscillators_[config::oscillatorsPerVoice];
|
||||||
|
|
||||||
|
|
@ -501,9 +500,8 @@ bool Voice::startVoice(Layer* layer, int delay, const TriggerEvent& event) noexc
|
||||||
impl.baseFrequency_ = resources.tuning.getFrequencyOfKey(impl.triggerEvent_.number);
|
impl.baseFrequency_ = resources.tuning.getFrequencyOfKey(impl.triggerEvent_.number);
|
||||||
impl.sampleEnd_ = int(region.getSampleEnd(resources.midiState, resources.filePool.getOversamplingFactor()));
|
impl.sampleEnd_ = int(region.getSampleEnd(resources.midiState, resources.filePool.getOversamplingFactor()));
|
||||||
impl.sampleSize_ = impl.sampleEnd_- impl.sourcePosition_ - 1;
|
impl.sampleSize_ = impl.sampleEnd_- impl.sourcePosition_ - 1;
|
||||||
impl.bendStepFactor_ = centsFactor(region.bendStep);
|
|
||||||
impl.bendSmoother_.setSmoothing(region.bendSmooth, impl.sampleRate_);
|
impl.bendSmoother_.setSmoothing(region.bendSmooth, impl.sampleRate_);
|
||||||
impl.bendSmoother_.reset(centsFactor(region.getBendInCents(resources.midiState.getPitchBend())));
|
impl.bendSmoother_.reset(region.getBendInCents(resources.midiState.getPitchBend()));
|
||||||
|
|
||||||
resources.modMatrix.initVoice(impl.id_, region.getId(), impl.initialDelay_);
|
resources.modMatrix.initVoice(impl.id_, region.getId(), impl.initialDelay_);
|
||||||
impl.saveModulationTargets(®ion);
|
impl.saveModulationTargets(®ion);
|
||||||
|
|
@ -1022,7 +1020,7 @@ void Voice::Impl::filterStageStereo(AudioSpan<float> buffer) noexcept
|
||||||
|
|
||||||
void Voice::Impl::fillWithData(AudioSpan<float> buffer) noexcept
|
void Voice::Impl::fillWithData(AudioSpan<float> buffer) noexcept
|
||||||
{
|
{
|
||||||
const auto numSamples = buffer.getNumFrames();
|
const size_t numSamples = buffer.getNumFrames();
|
||||||
if (numSamples == 0)
|
if (numSamples == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -1045,14 +1043,17 @@ void Voice::Impl::fillWithData(AudioSpan<float> buffer) noexcept
|
||||||
if (!jumps)
|
if (!jumps)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fill(*jumps, pitchRatio_ * speedRatio_);
|
absl::Span<float> pitch = *jumps; // temporary
|
||||||
|
pitchEnvelope(pitch);
|
||||||
|
|
||||||
|
float baseRatio = pitchRatio_ * speedRatio_;
|
||||||
|
for (size_t i = 0; i < numSamples; ++i)
|
||||||
|
(*jumps)[i] = baseRatio * centsFactor(pitch[i]);
|
||||||
|
|
||||||
// Take the first sample if the voice just started
|
// Take the first sample if the voice just started
|
||||||
if (age_ == 0)
|
if (age_ == 0)
|
||||||
jumps->front() = 0.0f;
|
jumps->front() = 0.0f;
|
||||||
|
|
||||||
pitchEnvelope(*jumps);
|
|
||||||
|
|
||||||
jumps->front() += floatPositionOffset_;
|
jumps->front() += floatPositionOffset_;
|
||||||
cumsum<float>(*jumps, *jumps);
|
cumsum<float>(*jumps, *jumps);
|
||||||
sfzInterpolationCast<float>(*jumps, *indices, *coeffs);
|
sfzInterpolationCast<float>(*jumps, *indices, *coeffs);
|
||||||
|
|
@ -1461,15 +1462,20 @@ void Voice::Impl::fillWithGenerator(AudioSpan<float> buffer) noexcept
|
||||||
absl::c_generate(leftSpan, gen);
|
absl::c_generate(leftSpan, gen);
|
||||||
absl::c_generate(rightSpan, gen);
|
absl::c_generate(rightSpan, gen);
|
||||||
} else {
|
} else {
|
||||||
const auto numFrames = buffer.getNumFrames();
|
const size_t numFrames = buffer.getNumFrames();
|
||||||
|
|
||||||
auto frequencies = resources_.bufferPool.getBuffer(numFrames);
|
auto frequencies = resources_.bufferPool.getBuffer(numFrames);
|
||||||
if (!frequencies)
|
if (!frequencies)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float keycenterFrequency = midiNoteFrequency(pitchKeycenter_);
|
absl::Span<float> pitch = *frequencies; // temporary
|
||||||
fill(*frequencies, pitchRatio_ * keycenterFrequency);
|
pitchEnvelope(pitch);
|
||||||
pitchEnvelope(*frequencies);
|
|
||||||
|
const float keycenterFrequency = midiNoteFrequency(pitchKeycenter_);
|
||||||
|
const float baseRatio = pitchRatio_ * keycenterFrequency;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < numFrames; ++i)
|
||||||
|
(*frequencies)[i] = baseRatio * centsFactor(pitch[i]);
|
||||||
|
|
||||||
auto detuneSpan = resources_.bufferPool.getBuffer(numFrames);
|
auto detuneSpan = resources_.bufferPool.getBuffer(numFrames);
|
||||||
if (!detuneSpan)
|
if (!detuneSpan)
|
||||||
|
|
@ -1901,34 +1907,28 @@ void Voice::Impl::switchState(State s)
|
||||||
|
|
||||||
void Voice::Impl::pitchEnvelope(absl::Span<float> pitchSpan) noexcept
|
void Voice::Impl::pitchEnvelope(absl::Span<float> pitchSpan) noexcept
|
||||||
{
|
{
|
||||||
const auto numFrames = pitchSpan.size();
|
const size_t numFrames = pitchSpan.size();
|
||||||
auto bends = resources_.bufferPool.getBuffer(numFrames);
|
|
||||||
if (!bends)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const EventVector& events = resources_.midiState.getPitchEvents();
|
const EventVector& events = resources_.midiState.getPitchEvents();
|
||||||
const auto bendLambda = [this](float bend) {
|
const auto bendLambda = [this](float bend) {
|
||||||
return centsFactor(region_->getBendInCents(bend));
|
return region_->getBendInCents(bend);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (region_->bendStep > 1.0f)
|
if (region_->bendStep > 1.0f)
|
||||||
pitchBendEnvelope(events, *bends, bendLambda, bendStepFactor_);
|
linearEnvelope(events, pitchSpan, bendLambda, region_->bendStep);
|
||||||
else
|
else
|
||||||
pitchBendEnvelope(events, *bends, bendLambda);
|
linearEnvelope(events, pitchSpan, bendLambda);
|
||||||
bendSmoother_.process(*bends, *bends);
|
bendSmoother_.process(pitchSpan, pitchSpan);
|
||||||
applyGain<float>(*bends, pitchSpan);
|
|
||||||
|
|
||||||
ModMatrix& mm = resources_.modMatrix;
|
ModMatrix& mm = resources_.modMatrix;
|
||||||
|
|
||||||
if (float* mod = mm.getModulation(pitchTarget_)) {
|
if (float* mod = mm.getModulation(pitchTarget_))
|
||||||
for (size_t i = 0; i < numFrames; ++i)
|
add<float>(absl::MakeSpan(mod, numFrames), pitchSpan);
|
||||||
pitchSpan[i] *= centsFactor(mod[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Voice::Impl::resetSmoothers() noexcept
|
void Voice::Impl::resetSmoothers() noexcept
|
||||||
{
|
{
|
||||||
bendSmoother_.reset(1.0f);
|
bendSmoother_.reset(0.0f);
|
||||||
gainSmoother_.reset(0.0f);
|
gainSmoother_.reset(0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue