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

View file

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

View file

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

View file

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

View file

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