Merged implementations with dynamic updates

This commit is contained in:
Paul Fd 2021-06-23 13:00:34 +02:00
parent 5da331cf18
commit 8563a1735f
5 changed files with 28 additions and 18 deletions

View file

@ -57,6 +57,7 @@ struct FlexEnvelope::Impl {
void process(absl::Span<float> out);
bool advanceToStage(unsigned stageNumber);
bool advanceToNextStage();
void updateCurrentTimeAndLevel();
};
FlexEnvelope::FlexEnvelope(Resources &resources)
@ -97,18 +98,8 @@ void FlexEnvelope::start(unsigned triggerDelay)
const FlexEGDescription& desc = *impl.desc_;
impl.delayFramesLeft_ = triggerDelay;
FlexEGPoint point;
if (!desc.points.empty())
point = desc.points[0];
//
impl.stageSourceLevel_ = 0.0;
impl.stageTargetLevel_ = point.level;
impl.stageTime_ = point.time;
impl.stageSustained_ = desc.sustain == 0;
impl.stageCurve_ = &point.curve();
impl.currentFramesUntilRelease_ = absl::nullopt;
impl.advanceToStage(0);
}
void FlexEnvelope::setFreeRunning(bool freeRunning)
@ -172,6 +163,10 @@ void FlexEnvelope::Impl::process(absl::Span<float> out)
const FlexEGDescription& desc = *desc_;
size_t numFrames = out.size();
const float samplePeriod = samplePeriod_;
if (desc.dynamic)
updateCurrentTimeAndLevel();
// Skip the initial delay, for frame-accurate trigger
size_t skipFrames = std::min(numFrames, delayFramesLeft_);
if (skipFrames > 0) {
@ -266,12 +261,11 @@ bool FlexEnvelope::Impl::advanceToStage(unsigned stageNumber)
const FlexEGPoint& point = desc.points[stageNumber];
stageSourceLevel_ = currentLevel_;
stageTargetLevel_ = point.getLevel(midiState);
stageTime_ = point.getTime(midiState);
currentTime_ = 0.0f;
updateCurrentTimeAndLevel();
stageSustained_ = int(stageNumber) == desc.sustain;
stageCurve_ = &point.curve();
currentTime_ = 0;
return true;
};
@ -280,4 +274,16 @@ bool FlexEnvelope::Impl::advanceToNextStage()
return advanceToStage(currentStageNumber_ + 1);
}
void FlexEnvelope::Impl::updateCurrentTimeAndLevel()
{
const FlexEGDescription& desc = *desc_;
if (currentStageNumber_ >= desc.points.size())
return;
const FlexEGPoint& point = desc.points[currentStageNumber_];
const MidiState& midiState = resources_->getMidiState();
stageTargetLevel_ = point.getLevel(midiState);
stageTime_ = point.getTime(midiState);
}
} // namespace sfz

View file

@ -5,6 +5,7 @@
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#pragma once
#include "MidiState.h"
#include <absl/types/span.h>
#include <memory>

View file

@ -70,7 +70,7 @@ Synth::Impl::Impl()
MidiState& midiState = resources_.getMidiState();
genController_.reset(new ControllerSource(resources_, voiceManager_));
genLFO_.reset(new LFOSource(voiceManager_));
genFlexEnvelope_.reset(new FlexEnvelopeSource(voiceManager_));
genFlexEnvelope_.reset(new FlexEnvelopeSource(voiceManager_, midiState));
genADSREnvelope_.reset(new ADSREnvelopeSource(voiceManager_, midiState));
genChannelAftertouch_.reset(new ChannelAftertouchSource(voiceManager_, midiState));
genPolyAftertouch_.reset(new PolyAftertouchSource(voiceManager_, midiState));

View file

@ -14,9 +14,10 @@
namespace sfz {
FlexEnvelopeSource::FlexEnvelopeSource(VoiceManager& manager)
: voiceManager_(manager)
FlexEnvelopeSource::FlexEnvelopeSource(VoiceManager& manager, MidiState& midiState)
: voiceManager_(manager), midiState_(midiState)
{
}
void FlexEnvelopeSource::init(const ModKey& sourceKey, NumericId<Voice> voiceId, unsigned delay)

View file

@ -7,13 +7,14 @@
#pragma once
#include "../ModGenerator.h"
#include "../../VoiceManager.h"
#include "../../MidiState.h"
namespace sfz {
class Synth;
class FlexEnvelopeSource : public ModGenerator {
public:
explicit FlexEnvelopeSource(VoiceManager& manager);
explicit FlexEnvelopeSource(VoiceManager& manager, MidiState& midiState);
void init(const ModKey& sourceKey, NumericId<Voice> voiceId, unsigned delay) override;
void release(const ModKey& sourceKey, NumericId<Voice> voiceId, unsigned delay) override;
void cancelRelease(const ModKey& sourceKey, NumericId<Voice> voiceId, unsigned delay) override;
@ -21,6 +22,7 @@ public:
private:
VoiceManager& voiceManager_;
MidiState& midiState_;
};
} // namespace sfz