diff --git a/src/sfizz/Voice.cpp b/src/sfizz/Voice.cpp index 3bd0253e..ce0ffd1d 100644 --- a/src/sfizz/Voice.cpp +++ b/src/sfizz/Voice.cpp @@ -135,7 +135,7 @@ void sfz::Voice::release(int delay, bool fastRelease) noexcept if (state != State::playing) return; - if (egEnvelope.getRemainingDelay() >= (delay - initialDelay)) { + if (egEnvelope.getRemainingDelay() > std::max(0, delay - initialDelay)) { reset(); } else { state = State::release; diff --git a/tests/SynthT.cpp b/tests/SynthT.cpp index 01788fb0..ecba9e80 100644 --- a/tests/SynthT.cpp +++ b/tests/SynthT.cpp @@ -220,3 +220,19 @@ TEST_CASE("[Synth] Releasing before the EG started smoothing (initial delay) kil synth.noteOff(1000, 1, 60, 63); REQUIRE( !synth.getVoiceView(0)->isFree() ); } + +TEST_CASE("[Synth] Releasing after the initial and normal mode does not trigger a fast release") +{ + sfz::Synth synth; + synth.setSamplesPerBlock(1024); + sfz::AudioBuffer buffer(2, 1024); + synth.setNumVoices(1); + synth.loadSfzFile(fs::current_path() / "tests/TestFiles/delay_release.sfz"); + synth.noteOn(200, 1, 60, 63); + REQUIRE( !synth.getVoiceView(0)->isFree() ); + synth.renderBlock(buffer); + REQUIRE( !synth.getVoiceView(0)->isFree() ); + synth.noteOff(0, 1, 60, 63); + synth.renderBlock(buffer); + REQUIRE( !synth.getVoiceView(0)->isFree() ); +} diff --git a/tests/TestFiles/delay_release.sfz b/tests/TestFiles/delay_release.sfz index f9882c23..33de8e8f 100644 --- a/tests/TestFiles/delay_release.sfz +++ b/tests/TestFiles/delay_release.sfz @@ -1 +1 @@ - delay=0.005 sample=dummy1.wav + ampeg_delay=0.005 ampeg_release=1 sample=dummy1.wav