Merged implementations with dynamic updates
This commit is contained in:
parent
5da331cf18
commit
8563a1735f
5 changed files with 28 additions and 18 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue