Allow simultaneous notes to choke properly
This commit is contained in:
parent
5a51e0b985
commit
85832f2baf
2 changed files with 53 additions and 7 deletions
|
|
@ -97,13 +97,15 @@ void ADSREnvelope::getBlockInternal(absl::Span<Float> output) noexcept
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
size_t size = output.size();
|
size_t size = output.size();
|
||||||
|
|
||||||
if (shouldRelease && releaseDelay == 0) {
|
if (shouldRelease) {
|
||||||
// release takes effect this frame
|
if (releaseDelay > 0) {
|
||||||
currentState = State::Release;
|
// prevent computing the segment further than release point
|
||||||
releaseDelay = -1;
|
size = std::min<size_t>(size, releaseDelay);
|
||||||
} else if (shouldRelease && releaseDelay > 0) {
|
} else if (releaseDelay == 0 && delay < 0) {
|
||||||
// prevent computing the segment further than release point
|
// release takes effect this frame
|
||||||
size = std::min<size_t>(size, releaseDelay);
|
currentState = State::Release;
|
||||||
|
releaseDelay = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Float previousValue;
|
Float previousValue;
|
||||||
|
|
|
||||||
|
|
@ -588,3 +588,47 @@ TEST_CASE("[Polyphony] Choke same group and note if the region is switched off (
|
||||||
synth.renderBlock(buffer);
|
synth.renderBlock(buffer);
|
||||||
REQUIRE( playingSamples(synth) == std::vector<std::string> { "*sine" } );
|
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" } );
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue