From 5a10af74ed422d4d7f06f1947262b3056b402bef Mon Sep 17 00:00:00 2001 From: Paul Fd Date: Wed, 1 Apr 2020 09:57:59 +0200 Subject: [PATCH] Set the envelope free-running also when loopmode=one_shot --- src/sfizz/ADSREnvelope.cpp | 6 +++++- tests/SynthT.cpp | 23 +++++++++++++++++++++++ tests/TestFiles/envelope_one_shot.sfz | 12 ++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 tests/TestFiles/envelope_one_shot.sfz diff --git a/src/sfizz/ADSREnvelope.cpp b/src/sfizz/ADSREnvelope.cpp index e94fd046..9581ab7a 100644 --- a/src/sfizz/ADSREnvelope.cpp +++ b/src/sfizz/ADSREnvelope.cpp @@ -40,7 +40,11 @@ void ADSREnvelope::reset(const EGDescription& desc, const Region& region, releaseDelay = 0; shouldRelease = false; - freeRunning = ((region.trigger == SfzTrigger::release) || (region.trigger == SfzTrigger::release_key)); + freeRunning = ( + (region.trigger == SfzTrigger::release) + || (region.trigger == SfzTrigger::release_key) + || region.loopMode == SfzLoopMode::one_shot + ); currentValue = this->start; currentState = State::Delay; } diff --git a/tests/SynthT.cpp b/tests/SynthT.cpp index c911c0c7..0434d9ce 100644 --- a/tests/SynthT.cpp +++ b/tests/SynthT.cpp @@ -224,6 +224,29 @@ TEST_CASE("[Synth] Trigger=release_key and an envelope properly kills the voice REQUIRE( synth.getVoiceView(0)->isFree() ); } +TEST_CASE("[Synth] loopmode=one_shot and an envelope properly kills the voice at the end of the envelope") +{ + sfz::Synth synth; + synth.setSampleRate(48000); + synth.setSamplesPerBlock(480); + sfz::AudioBuffer buffer(2, 480); + synth.setNumVoices(1); + synth.loadSfzFile(fs::current_path() / "tests/TestFiles/envelope_one_shot.sfz"); + synth.noteOn(0, 60, 63); + synth.noteOff(0, 60, 63); + REQUIRE( !synth.getVoiceView(0)->isFree() ); + synth.renderBlock(buffer); // Attack (0.02) + synth.renderBlock(buffer); + synth.renderBlock(buffer); // Decay (0.02) + synth.renderBlock(buffer); + synth.renderBlock(buffer); // Release (0.1) + REQUIRE( synth.getVoiceView(0)->canBeStolen() ); + // Release is 0.1s + for (int i = 0; i < 10; ++i) + synth.renderBlock(buffer); + REQUIRE( synth.getVoiceView(0)->isFree() ); +} + TEST_CASE("[Synth] Number of effect buses and resetting behavior") { sfz::Synth synth; diff --git a/tests/TestFiles/envelope_one_shot.sfz b/tests/TestFiles/envelope_one_shot.sfz new file mode 100644 index 00000000..6d820825 --- /dev/null +++ b/tests/TestFiles/envelope_one_shot.sfz @@ -0,0 +1,12 @@ + + +lovel=0 +hivel=127 + + +sample=*noise +loop_mode=one_shot +ampeg_attack=0.02 +ampeg_decay=0.02 +ampeg_release=0.1 +ampeg_sustain=0