Allow simultaneous notes to choke properly

This commit is contained in:
Paul Ferrand 2023-12-26 17:39:43 +01:00 committed by Paul Ferrand
parent 5a51e0b985
commit 85832f2baf
2 changed files with 53 additions and 7 deletions

View file

@ -97,13 +97,15 @@ void ADSREnvelope::getBlockInternal(absl::Span<Float> output) noexcept
size_t count = 0;
size_t size = output.size();
if (shouldRelease && releaseDelay == 0) {
// release takes effect this frame
currentState = State::Release;
releaseDelay = -1;
} else if (shouldRelease && releaseDelay > 0) {
// prevent computing the segment further than release point
size = std::min<size_t>(size, releaseDelay);
if (shouldRelease) {
if (releaseDelay > 0) {
// prevent computing the segment further than release point
size = std::min<size_t>(size, releaseDelay);
} else if (releaseDelay == 0 && delay < 0) {
// release takes effect this frame
currentState = State::Release;
releaseDelay = -1;
}
}
Float previousValue;

View file

@ -588,3 +588,47 @@ TEST_CASE("[Polyphony] Choke same group and note if the region is switched off (
synth.renderBlock(buffer);
REQUIRE( playingSamples(synth) == std::vector<std::string> { "*sine" } );
}
TEST_CASE("[Polyphony] A note coming at the same time as another can choke it")
{
sfz::Synth synth;
sfz::AudioBuffer<float> buffer { 2, static_cast<unsigned>(synth.getSamplesPerBlock()) };
synth.loadSfzString(fs::current_path() / "tests/TestFiles/polyphony.sfz", R"(
<region> key=69 off_by=2 off_mode=normal tune=-3200 ampeg_release=1 sample=snare.wav
<region> key=81 group=2 sample=kick.wav
)");
synth.noteOn(1, 69, 63);
synth.noteOn(1, 81, 127);
synth.renderBlock(buffer);
REQUIRE( activeSamples(synth) == std::vector<std::string> { "snare.wav", "kick.wav" } );
REQUIRE( playingSamples(synth) == std::vector<std::string> { "kick.wav" } );
}
TEST_CASE("[Polyphony] A note coming one sample after another note can choke it")
{
sfz::Synth synth;
sfz::AudioBuffer<float> buffer { 2, static_cast<unsigned>(synth.getSamplesPerBlock()) };
synth.loadSfzString(fs::current_path() / "tests/TestFiles/polyphony.sfz", R"(
<region> key=69 off_by=2 off_mode=normal tune=-3200 ampeg_release=1 sample=snare.wav
<region> key=81 group=2 sample=kick.wav
)");
synth.noteOn(1, 69, 63);
synth.noteOn(2, 81, 127);
synth.renderBlock(buffer);
REQUIRE( activeSamples(synth) == std::vector<std::string> { "snare.wav", "kick.wav" } );
REQUIRE( playingSamples(synth) == std::vector<std::string> { "kick.wav" } );
}
TEST_CASE("[Polyphony] A note coming one sample before another note cannot choke it")
{
sfz::Synth synth;
sfz::AudioBuffer<float> buffer { 2, static_cast<unsigned>(synth.getSamplesPerBlock()) };
synth.loadSfzString(fs::current_path() / "tests/TestFiles/polyphony.sfz", R"(
<region> key=69 off_by=2 off_mode=normal tune=-3200 ampeg_release=1 sample=snare.wav
<region> key=81 group=2 sample=kick.wav
)");
synth.noteOn(1, 81, 127);
synth.noteOn(2, 69, 63);
synth.renderBlock(buffer);
REQUIRE( playingSamples(synth) == std::vector<std::string> { "kick.wav", "snare.wav" } );
}