diff --git a/tests/PolyphonyT.cpp b/tests/PolyphonyT.cpp index afa38523..0a966da9 100644 --- a/tests/PolyphonyT.cpp +++ b/tests/PolyphonyT.cpp @@ -528,3 +528,45 @@ TEST_CASE("[Polyphony] Bi-directional choking (with note_polyphony)") synth.renderBlock(buffer); REQUIRE( playingSamples(synth) == std::vector { "kick.wav" } ); } + +TEST_CASE("[Polyphony] Choke long release tails") +{ + sfz::Synth synth; + sfz::AudioBuffer buffer { 2, static_cast(synth.getSamplesPerBlock()) }; + synth.loadSfzString(fs::current_path() / "tests/TestFiles/polyphony.sfz", R"( + sample=*saw ampeg_attack=0.1 ampeg_release=10 polyphony=1 + )"); + int attackBlocks = static_cast(0.1f / synth.getSamplesPerBlock() * 48000.0f) + 1; + synth.noteOn(0, 60, 63 ); + for (int i = 0; i < attackBlocks; ++i) + synth.renderBlock(buffer); + synth.noteOff(10, 60, 63 ); + synth.renderBlock(buffer); + REQUIRE( numPlayingVoices(synth) == 0 ); // Released + REQUIRE( numActiveVoices(synth) == 1 ); + synth.noteOn(0, 60, 63 ); + synth.renderBlock(buffer); + REQUIRE( numPlayingVoices(synth) == 1 ); // Not released, attack phase + REQUIRE( numActiveVoices(synth) == 1 ); +} + +TEST_CASE("[Polyphony] Choke long release tails with note_polyphony") +{ + sfz::Synth synth; + sfz::AudioBuffer buffer { 2, static_cast(synth.getSamplesPerBlock()) }; + synth.loadSfzString(fs::current_path() / "tests/TestFiles/polyphony.sfz", R"( + sample=*saw ampeg_attack=0.1 ampeg_release=10 note_polyphony=1 + )"); + int attackBlocks = static_cast(0.1f / synth.getSamplesPerBlock() * 48000.0f) + 1; + synth.noteOn(0, 60, 63 ); + for (int i = 0; i < attackBlocks; ++i) + synth.renderBlock(buffer); + synth.noteOff(10, 60, 63 ); + synth.renderBlock(buffer); + REQUIRE( numPlayingVoices(synth) == 0 ); // Released + REQUIRE( numActiveVoices(synth) == 1 ); + synth.noteOn(0, 60, 63 ); + synth.renderBlock(buffer); + REQUIRE( numPlayingVoices(synth) == 1 ); // Not released, attack phase + REQUIRE( numActiveVoices(synth) == 1 ); +} diff --git a/tests/TestHelpers.cpp b/tests/TestHelpers.cpp index 92b52630..4a81175e 100644 --- a/tests/TestHelpers.cpp +++ b/tests/TestHelpers.cpp @@ -82,6 +82,13 @@ unsigned numPlayingVoices(const sfz::Synth& synth) }); } +unsigned numActiveVoices(const sfz::Synth& synth) +{ + return absl::c_count_if(getActiveVoices(synth), [](const sfz::Voice* v) { + return !v->offedOrFree(); + }); +} + const std::vector playingSamples(const sfz::Synth& synth) { std::vector samples; diff --git a/tests/TestHelpers.h b/tests/TestHelpers.h index 454f221d..2145555e 100644 --- a/tests/TestHelpers.h +++ b/tests/TestHelpers.h @@ -78,6 +78,14 @@ const std::vector getPlayingVoices(const sfz::Synth& synth); */ unsigned numPlayingVoices(const sfz::Synth& synth); +/** + * @brief Count the number of active (not free or offed) voices from the synth + * + * @param synth + * @return unsigned + */ +unsigned numActiveVoices(const sfz::Synth& synth); + /** * @brief Get the playing samples *