Add the FlexEG cancellation

This commit is contained in:
Paul Fd 2021-05-23 14:50:07 +02:00
parent 13be8c9ac1
commit 8721c34e14
4 changed files with 56 additions and 6 deletions

View file

@ -49,6 +49,7 @@ struct FlexEnvelope::Impl {
//
void process(absl::Span<float> out);
bool advanceToStage(unsigned stageNumber);
bool advanceToNextStage();
};
@ -114,6 +115,25 @@ void FlexEnvelope::release(unsigned releaseDelay)
impl.currentFramesUntilRelease_ = releaseDelay;
}
void FlexEnvelope::cancelRelease(unsigned delay)
{
Impl& impl = *impl_;
const FlexEGDescription& desc = *impl.desc_;
if (impl.currentFramesUntilRelease_) {
// Cancel the future release
impl.currentFramesUntilRelease_ = absl::nullopt;
return;
}
if (!impl.isReleased_)
return;
impl.isReleased_ = false;
impl.advanceToStage(desc.sustain);
impl.stageTargetLevel_ = impl.currentLevel_;
}
unsigned FlexEnvelope::getRemainingDelay() const noexcept
{
const Impl& impl = *impl_;
@ -226,25 +246,29 @@ void FlexEnvelope::Impl::process(absl::Span<float> out)
}
}
bool FlexEnvelope::Impl::advanceToNextStage()
bool FlexEnvelope::Impl::advanceToStage(unsigned stageNumber)
{
const FlexEGDescription& desc = *desc_;
unsigned nextStageNo = currentStageNumber_ + 1;
currentStageNumber_ = nextStageNo;
currentStageNumber_ = stageNumber;
if (nextStageNo >= desc.points.size())
if (stageNumber >= desc.points.size())
return false;
const FlexEGPoint& point = desc.points[nextStageNo];
const FlexEGPoint& point = desc.points[stageNumber];
stageSourceLevel_ = currentLevel_;
stageTargetLevel_ = point.level;
stageTime_ = point.time;
stageSustained_ = int(nextStageNo) == desc.sustain;
stageSustained_ = int(stageNumber) == desc.sustain;
stageCurve_ = &point.curve();
currentTime_ = 0;
return true;
};
bool FlexEnvelope::Impl::advanceToNextStage()
{
return advanceToStage(currentStageNumber_ + 1);
}
} // namespace sfz

View file

@ -47,6 +47,11 @@ public:
*/
void release(unsigned releaseDelay);
/**
Cancel the release
*/
void cancelRelease(unsigned delay);
/**
Get the remaining delay samples
*/

View file

@ -66,6 +66,26 @@ void FlexEnvelopeSource::release(const ModKey& sourceKey, NumericId<Voice> voice
eg->release(delay);
}
void FlexEnvelopeSource::cancelRelease(const ModKey& sourceKey, NumericId<Voice> voiceId, unsigned delay)
{
unsigned egIndex = sourceKey.parameters().N;
Voice* voice = voiceManager_.getVoiceById(voiceId);
if (!voice) {
ASSERTFALSE;
return;
}
const Region* region = voice->getRegion();
if (egIndex >= region->flexEGs.size()) {
ASSERTFALSE;
return;
}
FlexEnvelope* eg = voice->getFlexEG(egIndex);
eg->cancelRelease(delay);
}
void FlexEnvelopeSource::generate(const ModKey& sourceKey, NumericId<Voice> voiceId, absl::Span<float> buffer)
{
unsigned egIndex = sourceKey.parameters().N;

View file

@ -16,6 +16,7 @@ public:
explicit FlexEnvelopeSource(VoiceManager& manager);
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;
void generate(const ModKey& sourceKey, NumericId<Voice> voiceId, absl::Span<float> buffer) override;
private: